python-microscopy / python-microscopy

The python-microscopy environment - an open-source package for light microscopy
http://www.python-microscopy.org
GNU General Public License v3.0
83 stars 25 forks source link

[ENHANCEMENT] PYMEAcquire histogram #1270

Closed d-perez-1 closed 2 years ago

d-perez-1 commented 2 years ago

Is your feature request related to a problem? Please describe. I want to be able to quickly tell if I'm saturating the camera on the fly, so I can adjust settings appropriately. Generally more histogram control would also be nice.

Is the histogram calculated the same way as in PYMEImage, i.e. using subset of pixels and not the entire frame? If I have one bright emitter in an otherwise dark field of view, and I check auto on the histogram scaling, then read off the top bound, can I use that to determine if I'm bellow saturation? Or is it possible the brightest pixels aren't included in the the histogram, or auto scaling does not set bounds to max and min?

Describe the solution you'd like An option to use the full frame in the histogram, if this isn't already how its done. Also live scale image to max and min, unless that's what auto already does. Additionally, display some sort of non-obtrusive warning if some pixels are above threshold. Would also be nice to highlight a region and use just that for setting bounds.

David-Baddeley commented 2 years ago

The "auto" scaling in PYMEAcquire does min-max scaling, but still on a subsampled image (1000 pixels). The whole subsampling thing actually started with PYMEAcquire as the histogram calculation etc ... was slowing down data acquisition. This is probably around 10 years ago though, so might not be as big an issue. The way it's written it would also be fairly easy to calculate the min and max on the full image and still do the histogram on the subsampled data.

Will do a quick check on how long min and max actually take on a typical 4MP sCMOS frame and see if we still need to worry. If they are fast enough, it should be a simple change. I think the histograming was expensive enough however, that it might make sense to still do that on a subset even if we set the scaling using min/max of the full frame.

As to actually detecting saturation, there have been various thoughts in the past about, e.g., turning the histogram red if saturation is detected, (could also look into using an overflow LUT, although this gets complex when the scaling is not maxed out). There is also some saturation checking code (which now seems to be commented out, although is potentially activated in specific init scripts) which automatically turned EMCCD gain down if saturation was detected, and a corresponding camera property SaturationThreshold (which is effectively the bit depth of the camera).

David-Baddeley commented 2 years ago

Timing results (4MP uint16 camera frame, mac M1):

.min() : 3.8 ms .max() : 3.8 ms np.histogram(...) : 183 ms

With a display refresh rate of 10Hz (at higher acquisition rates, intervening frames get streamed without ever being shown), everything involved with displaying a frame / display scaling etc must take less than 100 ms (ideally less than around 50ms to let the rest of the GUI do it's thing). In addition to any autoscaling there is also a significant cost involved in doing the LUT transformation and actually displaying the data. Based on this, the full histogram is definitely out. Min-max scaling on the full frame might just be possible, but would still represent a decent fraction of our 50ms window.

barentine commented 2 years ago

Any thoughts on exposing some configuration options, David? I think an expandable menu to e.g. select which auto mode you are using, whether you're subsampling the hist, your LUT, etc. would be really nice.

At the moment I find myself typing pa.currentFrame.max() in the shell when an overflow LUT with camera-based (ADO to saturation) bounds is exactly what I want on one of my cameras - would be more convenient.

I know some folks are acquiring rather slowly (e.g. slower than the 10 Hz display refresh) - if you are acquiring at 0.5 Hz, maybe you'd rather have the full histogram and additionally don't need a display refresh rate faster than a couple Hz?

Thanks for doing these tests @David-Baddeley , and for raising something that's also been bugging me, @d-perez-1

David-Baddeley commented 2 years ago

I'm leaning pretty strongly towards making min-max on the whole frame the default as the benefit from having decent saturation detection is really significant. Would argue for leaving the histogram subsampled though. Will do a quick test on an older computer to see if we need to make the current behaviour available as a PYME.config option. I'd be reluctant to write too much extra GUI stuff as it's time consuming and adds to the clutter on what is already a pretty cluttered interface. The one possible exception here is allowing the LUT to be set without using the command line.

Unresolved questions:

David-Baddeley commented 2 years ago

More timing info (Intel i7-3930K, 4Mp sCMOS frame):

.min() : 13.5 ms .max(): 10 ms

This machine is probably indicative of / at the slower end of the generation still commonly used for data acquisition. At these timings it's getting close to 50% of our window, so probably problematic from a performance perspective. I was really hoping the difference would be less and I could just switch the default behaviour.

d-perez-1 commented 2 years ago

Regardless of default behavior, it would be great to have on option to turn these sorts of things on/off. My use is a bit different, typically 10Hz is the fastest I'll image, more often 2 or 3 Hz. I'm also using a 512x512 EMCCD, so I'd have plenty of time for these operations. Maybe keep the default fast but have options for the more complete calculations, and a warning if they're taking a lot of the timing window?

barentine commented 2 years ago

calculating the min and max in the same loop with cython might help

David-Baddeley commented 2 years ago

Agreed ...

Mac M1, 4Mp:

c-coded minmax_uint16: 3.9 ms

David-Baddeley commented 2 years ago

(Intel i7-3930K, 4Mp sCMOS frame):

minmax_uint16 : 2.33 ms

Which is actually better than the M1!, and and order of mag better than numpy (which is super wierd - suggests a broken numpy install).

David-Baddeley commented 2 years ago

I'm a little reluctant to have lots of different options due to the associated maintenance and documentation cost / overhead. It's better, when possible, to have a good default behaviour. #1271 might be most of what we need to have sensible default behaviour for acquisition:

The one remaining oddity is that clicking the "optimize" button functions identically to the optimize in PYMEImage (uses percentiles rather than min-max, and a different subsampling than the histogram display).

barentine commented 2 years ago

Ran into an issue trying the latest histogram stuff

``` (base) C:\Userfiles\code\python-microscopy>python setup.py develop Appending PYME.Analysis.points.QuadTree configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.QuadTree') Appending PYME.Analysis.points.SoftRend configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.SoftRend') Appending PYME.Analysis.points.DistHist configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.DistHist') Appending PYME.Analysis.points.DeClump configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.DeClump') Appending PYME.Analysis.points.EdgeDB configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.EdgeDB') Appending PYME.Analysis.points.arcfit configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.arcfit') Appending PYME.Analysis.points.astigmatism configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.astigmatism') Appending PYME.Analysis.points.traveling_salesperson configuration to PYME.Analysis.points Ignoring attempt to set 'name' (from 'PYME.Analysis.points' to 'PYME.Analysis.points.traveling_salesperson') Appending PYME.Analysis.points configuration to PYME.Analysis Ignoring attempt to set 'name' (from 'PYME.Analysis' to 'PYME.Analysis.points') Appending PYME.Analysis.BleachProfile configuration to PYME.Analysis Ignoring attempt to set 'name' (from 'PYME.Analysis' to 'PYME.Analysis.BleachProfile') Appending PYME.Analysis.Colocalisation configuration to PYME.Analysis Ignoring attempt to set 'name' (from 'PYME.Analysis' to 'PYME.Analysis.Colocalisation') Appending PYME.Analysis.Tracking configuration to PYME.Analysis Ignoring attempt to set 'name' (from 'PYME.Analysis' to 'PYME.Analysis.Tracking') Appending PYME.Analysis.PSFEst configuration to PYME.Analysis Ignoring attempt to set 'name' (from 'PYME.Analysis' to 'PYME.Analysis.PSFEst') Appending PYME.Analysis.PSFGen configuration to PYME.Analysis Ignoring attempt to set 'name' (from 'PYME.Analysis' to 'PYME.Analysis.PSFGen') Appending PYME.Analysis configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.Analysis') Appending PYME.Acquire.Hardware.AndorIXon configuration to PYME.Acquire.Hardware Ignoring attempt to set 'name' (from 'PYME.Acquire.Hardware' to 'PYME.Acquire.Hardware.AndorIXon') Appending PYME.Acquire.Hardware.AndorNeo configuration to PYME.Acquire.Hardware Ignoring attempt to set 'name' (from 'PYME.Acquire.Hardware' to 'PYME.Acquire.Hardware.AndorNeo') Appending PYME.Acquire.Hardware.DigiData configuration to PYME.Acquire.Hardware Ignoring attempt to set 'name' (from 'PYME.Acquire.Hardware' to 'PYME.Acquire.Hardware.DigiData') Appending PYME.Acquire.Hardware.Simulator configuration to PYME.Acquire.Hardware Ignoring attempt to set 'name' (from 'PYME.Acquire.Hardware' to 'PYME.Acquire.Hardware.Simulator') Appending PYME.Acquire.Hardware.Old configuration to PYME.Acquire.Hardware Ignoring attempt to set 'name' (from 'PYME.Acquire.Hardware' to 'PYME.Acquire.Hardware.Old') Appending PYME.Acquire.Hardware.Piezos configuration to PYME.Acquire.Hardware Ignoring attempt to set 'name' (from 'PYME.Acquire.Hardware' to 'PYME.Acquire.Hardware.Piezos') Appending PYME.Acquire.Hardware configuration to PYME.Acquire Ignoring attempt to set 'name' (from 'PYME.Acquire' to 'PYME.Acquire.Hardware') Appending PYME.Acquire.Protocols configuration to PYME.Acquire Ignoring attempt to set 'name' (from 'PYME.Acquire' to 'PYME.Acquire.Protocols') Appending PYME.Acquire.ui configuration to PYME.Acquire Ignoring attempt to set 'name' (from 'PYME.Acquire' to 'PYME.Acquire.ui') Appending PYME.Acquire.Utils configuration to PYME.Acquire Ignoring attempt to set 'name' (from 'PYME.Acquire' to 'PYME.Acquire.Utils') Appending PYME.Acquire.webui configuration to PYME.Acquire Ignoring attempt to set 'name' (from 'PYME.Acquire' to 'PYME.Acquire.webui') Appending PYME.Acquire configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.Acquire') Appending PYME.DSView.LUT configuration to PYME.DSView Ignoring attempt to set 'name' (from 'PYME.DSView' to 'PYME.DSView.LUT') Appending PYME.DSView.modules configuration to PYME.DSView Ignoring attempt to set 'name' (from 'PYME.DSView' to 'PYME.DSView.modules') Appending PYME.DSView configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.DSView') Appending PYME.ParallelTasks configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.ParallelTasks') Appending PYME.IO.FileUtils configuration to PYME.IO Ignoring attempt to set 'name' (from 'PYME.IO' to 'PYME.IO.FileUtils') Appending PYME.IO.DataSources configuration to PYME.IO Ignoring attempt to set 'name' (from 'PYME.IO' to 'PYME.IO.DataSources') Appending PYME.IO.countdir configuration to PYME.IO Ignoring attempt to set 'name' (from 'PYME.IO' to 'PYME.IO.countdir') Appending PYME.IO configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.IO') Appending PYME.Deconv configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.Deconv') Appending PYME.simulation configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.simulation') Appending PYME.misc configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.misc') Appending PYME.LMVis.Extras configuration to PYME.LMVis Ignoring attempt to set 'name' (from 'PYME.LMVis' to 'PYME.LMVis.Extras') Appending PYME.LMVis.layers configuration to PYME.LMVis Ignoring attempt to set 'name' (from 'PYME.LMVis' to 'PYME.LMVis.layers') Appending PYME.LMVis.shader_programs configuration to PYME.LMVis Ignoring attempt to set 'name' (from 'PYME.LMVis' to 'PYME.LMVis.shader_programs') Appending PYME.LMVis configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.LMVis') Appending PYME.ui configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.ui') Appending PYME.util configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.util') Appending PYME.util.shmarray configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.util.shmarray') Appending PYME.util.mProfile configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.util.mProfile') Appending PYME.util.fProfile configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.util.fProfile') Appending PYME.localization.cModels configuration to PYME.localization Ignoring attempt to set 'name' (from 'PYME.localization' to 'PYME.localization.cModels') Appending PYME.localization.cInterp configuration to PYME.localization Ignoring attempt to set 'name' (from 'PYME.localization' to 'PYME.localization.cInterp') Appending PYME.localization.FitFactories configuration to PYME.localization Ignoring attempt to set 'name' (from 'PYME.localization' to 'PYME.localization.FitFactories') Appending PYME.localization.FitFactories.Interpolators configuration to PYME.localization Ignoring attempt to set 'name' (from 'PYME.localization' to 'PYME.localization.FitFactories.Interpolators') Appending PYME.localization.FitFactories.zEstimators configuration to PYME.localization Ignoring attempt to set 'name' (from 'PYME.localization' to 'PYME.localization.FitFactories.zEstimators') Appending PYME.localization.autopsf configuration to PYME.localization Ignoring attempt to set 'name' (from 'PYME.localization' to 'PYME.localization.autopsf') Appending PYME.localization configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.localization') non-existing path in 'PYME\\recipes': 'templates' Appending PYME.recipes configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.recipes') Appending PYME.cluster configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.cluster') Appending PYME.resources configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.resources') Appending PYME.contrib.pad configuration to PYME.contrib Ignoring attempt to set 'name' (from 'PYME.contrib' to 'PYME.contrib.pad') Appending PYME.contrib.gohlke configuration to PYME.contrib Ignoring attempt to set 'name' (from 'PYME.contrib' to 'PYME.contrib.gohlke') Appending PYME.contrib.dispatch configuration to PYME.contrib Ignoring attempt to set 'name' (from 'PYME.contrib' to 'PYME.contrib.dispatch') Appending PYME.contrib.aniso configuration to PYME.contrib Ignoring attempt to set 'name' (from 'PYME.contrib' to 'PYME.contrib.aniso') Appending PYME.contrib configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.contrib') Compiling PYME\experimental\_octree.pyx because it changed. Compiling PYME\experimental\_triangle_mesh.pyx because it changed. [1/2] Cythonizing PYME\experimental\_octree.pyx C:\ProgramData\Miniconda3\lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: C:\Userfiles\code\python-microscopy\PYME\experimental\_octree.pyx tree = Parsing.p_module(s, pxd, full_module_name) warning: PYME\experimental\_octree.pyx:260:20: Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). Each pointer declaration should be on its own line. warning: PYME\experimental\_octree.pyx:260:31: Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). Each pointer declaration should be on its own line. [2/2] Cythonizing PYME\experimental\_triangle_mesh.pyx C:\ProgramData\Miniconda3\lib\site-packages\Cython\Compiler\Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: C:\Userfiles\code\python-microscopy\PYME\experimental\_triangle_mesh.pxd tree = Parsing.p_module(s, pxd, full_module_name) warning: PYME\experimental\_triangle_mesh.pyx:2123:24: Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). Each pointer declaration should be on its own line. warning: PYME\experimental\_triangle_mesh.pyx:2123:36: Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). Each pointer declaration should be on its own line. Appending PYME.experimental configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.experimental') Appending PYME.tileviewer configuration to PYME Ignoring attempt to set 'name' (from 'PYME' to 'PYME.tileviewer') Detected a .git folder, assuming a development install Appending PYME configuration to Ignoring attempt to set 'name' (from '' to 'PYME') Ignoring attempt to set 'version' (from None to '22.05.25.post0.dev') Detected a .git folder, assuming a development install C:\ProgramData\Miniconda3\lib\site-packages\setuptools\dist.py:461: UserWarning: Normalizing '22.05.25.post0.dev' to '22.5.25.post0.dev0' warnings.warn(tmpl.format(**locals())) running develop running build_scripts running egg_info running build_src build_src building extension "PYME.Analysis.points.SoftRend.triRend" sources building extension "PYME.Analysis.points.DistHist.distHist" sources building extension "PYME.Analysis.points.DeClump.deClump" sources building extension "PYME.Analysis.points.EdgeDB.edgeDB" sources building extension "PYME.Analysis.points.arcfit.arcmf" sources building extension "PYME.Analysis.points.astigmatism.astiglookup" sources building extension "PYME.Analysis.points.traveling_salesperson.two_opt_utils" sources building extension "PYME.Analysis.PSFGen.ps_app" sources building extension "PYME.Acquire.Hardware.Simulator.illuminate" sources building extension "PYME.DSView.LUT.lut" sources building extension "PYME.IO.buffer_helpers" sources building extension "PYME.localization.cModels.gauss_app" sources building extension "PYME.localization.cInterp.cInterp" sources building extension "PYME.contrib.gohlke._tifffile" sources building extension "PYME.experimental._octree" sources building extension "PYME.experimental._treap" sources building extension "PYME.experimental._triangle_mesh" sources building extension "PYME.experimental.triangle_mesh_utils" sources building data_files sources build_src: building npy-pkg config files writing python_microscopy.egg-info\PKG-INFO writing dependency_links to python_microscopy.egg-info\dependency_links.txt writing entry points to python_microscopy.egg-info\entry_points.txt writing requirements to python_microscopy.egg-info\requires.txt writing top-level names to python_microscopy.egg-info\top_level.txt reading manifest file 'python_microscopy.egg-info\SOURCES.txt' writing manifest file 'python_microscopy.egg-info\SOURCES.txt' running build_ext No module named 'numpy.distutils._msvccompiler' in numpy.distutils; trying from distutils customize MSVCCompiler customize MSVCCompiler using build_ext building 'PYME.DSView.LUT.lut' extension compiling C sources C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\ProgramData\Miniconda3\lib\site-packages\numpy\core\include -IC:\ProgramData\Miniconda3\lib\site-packages\numpy\core\include -IC:\ProgramData\Miniconda3\include -IC:\ProgramData\Miniconda3\include -IC:\ProgramData\Miniconda3\include -IC:\ProgramData\Miniconda3\include -IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\include -IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include -IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um -IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt -IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared -IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um -IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt -IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt /TcPYME\DSView\LUT\lut.c /Fobuild\temp.win-amd64-3.7\Release\PYME\DSView\LUT\lut.obj -O3 -fno-exceptions cl : Command line warning D9002 : ignoring unknown option '-O3' cl : Command line warning D9002 : ignoring unknown option '-fno-exceptions' C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\ProgramData\Miniconda3\libs /LIBPATH:C:\ProgramData\Miniconda3\PCbuild\amd64 /LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64 /LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x64 /EXPORT:PyInit_lut build\temp.win-amd64-3.7\Release\PYME\DSView\LUT\lut.obj /OUT:PYME\DSView\LUT\lut.cp37-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.7\Release\PYME\DSView\LUT\lut.cp37-win_amd64.lib -static-libgcc LINK : warning LNK4044: unrecognized option '/static-libgcc'; ignored LINK : fatal error LNK1104: cannot open file 'PYME\DSView\LUT\lut.cp37-win_amd64.pyd' error: Command "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\ProgramData\Miniconda3\libs /LIBPATH:C:\ProgramData\Miniconda3\PCbuild\amd64 /LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\ATLMFC\lib\x64 /LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x64 /EXPORT:PyInit_lut build\temp.win-amd64-3.7\Release\PYME\DSView\LUT\lut.obj /OUT:PYME\DSView\LUT\lut.cp37-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.7\Release\PYME\DSView\LUT\lut.cp37-win_amd64.lib -static-libgcc" failed with exit status 1104 ```

on Win10

conda list ``` # packages in environment at C:\ProgramData\Miniconda3: # # Name Version Build Channel alabaster 0.7.12 py37_0 argcomplete 1.12.3 pyhd3eb1b0_0 argon2-cffi 20.1.0 py37h2bbff1b_1 async_generator 1.10 py37h28b3542_0 attrs 21.2.0 pyhd3eb1b0_0 babel 2.9.1 pyhd3eb1b0_0 backcall 0.2.0 pyhd3eb1b0_0 blas 1.0 mkl bleach 4.0.0 pyhd3eb1b0_0 blosc 1.19.0 h7bd577a_0 bottleneck 1.3.2 py37h2a96729_1 brotlipy 0.7.0 py37h2bbff1b_1003 bzip2 1.0.8 he774522_0 ca-certificates 2021.10.26 haa95532_4 cairo 1.14.12 hf171d8a_3 certifi 2021.10.8 py37haa95532_2 cffi 1.14.6 py37h2bbff1b_0 chardet 4.0.0 py37haa95532_1003 cheroot 8.5.2 py37haa95532_1 cherrypy 18.6.0 py37haa95532_0 cloudpickle 2.0.0 pyhd3eb1b0_0 colorama 0.4.4 pyhd3eb1b0_0 conda 4.11.0 py37haa95532_0 conda-package-handling 1.7.3 py37h8cc25b3_1 console_shortcut 0.1.1 4 cryptography 3.4.7 py37h71e12ea_0 cycler 0.11.0 pyhd3eb1b0_0 cython 0.29.24 py37h604cdb4_0 cytoolz 0.11.0 py37he774522_0 dask-core 2021.10.0 pyhd3eb1b0_0 debugpy 1.5.1 py37hd77b12b_0 decorator 5.1.0 pyhd3eb1b0_0 defusedxml 0.7.1 pyhd3eb1b0_0 docutils 0.17.1 py37haa95532_1 entrypoints 0.3 py37_0 enum-compat 0.0.3 pypi_0 pypi fftw 3.3.4 0 david_baddeley freetype 2.10.4 hd328e21_0 fsspec 2021.10.1 pyhd3eb1b0_0 future 0.18.2 py37_1 hdf5 1.10.4 h7ebc959_0 icc_rt 2019.0.0 h0cc432a_1 icu 58.2 ha925a31_3 idna 2.10 pyhd3eb1b0_0 ifaddr 0.1.6 py_0 david_baddeley imageio 2.9.0 pyhd3eb1b0_0 imagesize 1.3.0 pyhd3eb1b0_0 importlib-metadata 4.8.1 py37haa95532_0 importlib_metadata 4.8.1 hd3eb1b0_0 intel-openmp 2021.4.0 haa95532_3556 ipykernel 6.4.1 py37haa95532_1 ipython 7.29.0 py37hd4e2768_0 ipython_genutils 0.2.0 pyhd3eb1b0_1 ipywidgets 7.6.5 pyhd3eb1b0_1 jaraco.classes 3.2.1 pyhd3eb1b0_0 jaraco.collections 3.3.0 pyhd3eb1b0_0 jaraco.functools 3.3.0 pyhd3eb1b0_0 jaraco.text 3.5.1 py37haa95532_2 jedi 0.18.0 py37haa95532_1 jinja2 3.0.2 pyhd3eb1b0_0 joblib 1.1.0 pyhd3eb1b0_0 jpeg 9d h2bbff1b_0 jsonschema 3.2.0 pyhd3eb1b0_2 jupyter 1.0.0 py37_7 jupyter_client 7.0.6 pyhd3eb1b0_0 jupyter_console 6.4.0 pyhd3eb1b0_0 jupyter_core 4.9.1 py37haa95532_0 jupyterlab_pygments 0.1.2 py_0 jupyterlab_widgets 1.0.0 pyhd3eb1b0_1 kiwisolver 1.3.1 py37hd77b12b_0 libpng 1.6.37 h2a8f88b_0 libtiff 4.2.0 hd0e1b90_0 libwebp 1.2.0 h2bbff1b_0 locket 0.2.1 py37haa95532_1 lz4-c 1.9.3 h2bbff1b_1 lzo 2.10 he774522_2 m2w64-gcc-libgfortran 5.3.0 6 m2w64-gcc-libs 5.3.0 7 m2w64-gcc-libs-core 5.3.0 7 m2w64-gmp 6.1.0 2 m2w64-libwinpthread-git 5.0.0.4634.697f757 2 markupsafe 2.0.1 py37h2bbff1b_0 matplotlib 3.2.2 0 matplotlib-base 3.2.2 py37h64f37c6_0 matplotlib-inline 0.1.2 pyhd3eb1b0_2 menuinst 1.4.16 py37he774522_1 mistune 0.8.4 py37hfa6e2cd_1001 mkl 2020.2 256 mkl-service 2.3.0 py37h196d8e1_0 mkl_fft 1.3.0 py37h46781fe_0 mkl_random 1.1.1 py37h47e9c7a_0 mock 4.0.3 pyhd3eb1b0_0 more-itertools 8.12.0 pyhd3eb1b0_0 mpld3 v0.3 py37_0 david_baddeley msys2-conda-epoch 20160418 1 nbclient 0.5.3 pyhd3eb1b0_0 nbconvert 6.1.0 py37haa95532_0 nbformat 5.1.3 pyhd3eb1b0_0 nest-asyncio 1.5.1 pyhd3eb1b0_0 networkx 2.6.3 pyhd3eb1b0_0 notebook 6.4.6 py37haa95532_0 numexpr 2.7.3 py37hcbcaa1e_0 numpy 1.19.2 py37hadc3359_0 numpy-base 1.19.2 py37ha3acd2a_0 olefile 0.46 py37_0 openssl 1.1.1m h2bbff1b_0 packaging 21.3 pyhd3eb1b0_0 pandas 1.3.4 py37h6214cd6_0 pandocfilters 1.4.3 py37haa95532_1 parso 0.8.2 pyhd3eb1b0_0 partd 1.2.0 pyhd3eb1b0_0 pickleshare 0.7.5 pyhd3eb1b0_1003 pillow 8.4.0 py37hd45dc43_0 pip 21.1.3 py37haa95532_0 pixman 0.40.0 h2bbff1b_1 portend 2.7.1 pyhd3eb1b0_0 powershell_shortcut 0.0.1 3 prometheus_client 0.12.0 pyhd3eb1b0_0 prompt-toolkit 3.0.20 pyhd3eb1b0_0 prompt_toolkit 3.0.20 hd3eb1b0_0 psutil 5.8.0 py37h2bbff1b_1 pycairo 1.19.1 py37hb2538c6_0 pycosat 0.6.3 py37h2bbff1b_0 pycparser 2.20 py_2 pyface 7.1.0 py37_1 pyfftw 0.11.1+26.g101c792 pypi_0 pypi pygments 2.10.0 pyhd3eb1b0_0 pyjwt 2.1.0 py37haa95532_0 pyme-depends 1.17 py37_0 david_baddeley pymecompress 0.2.0 py37_0 david_baddeley pyopengl 3.1.1a1 py37haa95532_0 pyopenssl 20.0.1 pyhd3eb1b0_1 pyparsing 3.0.4 pyhd3eb1b0_0 pyqt 5.9.2 py37h6538335_2 pyrsistent 0.18.0 py37h196d8e1_0 pyserial 3.5 py37haa95532_0 pysocks 1.7.1 py37_1 pytables 3.6.1 py37h1da0976_0 python 3.7.10 h6244533_0 python-dateutil 2.8.2 pyhd3eb1b0_0 python-microscopy 22.5.25.post0.dev0 dev_0 pytz 2021.3 pyhd3eb1b0_0 pyueye 4.95.0 pypi_0 pypi pywavelets 1.1.1 py37he774522_2 pywin32 227 py37he774522_1 pywinpty 0.5.7 py37_0 pyyaml 6.0 py37h2bbff1b_1 pyzmq 22.3.0 py37hd77b12b_2 qt 5.9.7 vc14h73c81de_0 qtconsole 5.1.1 pyhd3eb1b0_0 qtpy 1.10.0 pyhd3eb1b0_0 repoze.lru 0.7 py37haa95532_0 requests 2.25.1 pyhd3eb1b0_0 routes 2.5.1 py37haa95532_0 ruamel_yaml 0.15.100 py37h2bbff1b_0 scikit-image 0.16.2 py37h47e9c7a_0 scikit-learn 1.0.1 py37hf11a4ad_0 scipy 1.3.0 py37h29ff71c_0 send2trash 1.8.0 pyhd3eb1b0_1 setuptools 52.0.0 py37haa95532_0 simplejson 3.17.3 py37h2bbff1b_2 sip 4.19.8 py37h6538335_0 six 1.16.0 pyhd3eb1b0_0 snappy 1.1.8 h33f27b4_0 snowballstemmer 2.2.0 pyhd3eb1b0_0 sphinx 4.2.0 pyhd3eb1b0_1 sphinxcontrib-applehelp 1.0.2 pyhd3eb1b0_0 sphinxcontrib-devhelp 1.0.2 pyhd3eb1b0_0 sphinxcontrib-htmlhelp 2.0.0 pyhd3eb1b0_0 sphinxcontrib-jsmath 1.0.1 pyhd3eb1b0_0 sphinxcontrib-qthelp 1.0.3 pyhd3eb1b0_0 sphinxcontrib-serializinghtml 1.1.5 pyhd3eb1b0_0 sqlite 3.36.0 h2bbff1b_0 tempora 4.1.1 pyhd3eb1b0_0 terminado 0.9.4 py37haa95532_0 testpath 0.5.0 pyhd3eb1b0_0 threadpoolctl 2.2.0 pyh0d69192_0 tk 8.6.11 h2bbff1b_0 toolz 0.11.2 pyhd3eb1b0_0 toposort 1.5 py37_3 david_baddeley tornado 6.1 py37h2bbff1b_0 tqdm 4.61.2 pyhd3eb1b0_1 traitlets 5.1.1 pyhd3eb1b0_0 traits 6.2.0 py37h2bbff1b_0 traitsui 7.1.0 py_0 typing_extensions 3.10.0.2 pyh06a4308_0 ujson 4.0.2 py37hd77b12b_0 urllib3 1.26.6 pyhd3eb1b0_1 vc 14.2 h21ff451_1 vs2015_runtime 14.27.29016 h5e58377_2 wcwidth 0.2.5 pyhd3eb1b0_0 webencodings 0.5.1 py37_1 wheel 0.36.2 pyhd3eb1b0_0 widgetsnbextension 3.5.1 py37_0 win_inet_pton 1.1.0 py37haa95532_0 wincertstore 0.2 py37_0 winpty 0.4.3 4 wxpython 4.0.4 py37ha925a31_0 xz 5.2.5 h62dcd97_0 yaml 0.2.5 he774522_0 zc.lockfile 2.0 pyhd3eb1b0_0 zeroconf 0.24.0 py37_3 david_baddeley zipp 3.6.0 pyhd3eb1b0_0 zlib 1.2.11 h62dcd97_4 zstd 1.4.9 h19a0ad4_0 ```
David-Baddeley commented 2 years ago

Odd ... can you do a dev install on the main branch? Suggests a broken compiler install of some description, as it seems to be a linker error, rather than anything to do with the code itself ...

David

David-Baddeley commented 2 years ago

Actually, on second thoughts the error is fairly clear - do you have any PYME components open? You typically get that error when trying to write to a dll / .pyd that is in use.

Relevant bit of the trace is:

LINK : fatal error LNK1104: cannot open file 'PYME\DSView\LUT\lut.cp37-win_amd64.pyd'
barentine commented 2 years ago

Ahhh, David you caught me right when I realized it - sorry for the miscue, Install works fine. Will test the histogram shortly

barentine commented 2 years ago

@d-perez-1 if this is satisfactory feel free to close the issue - thanks!

d-perez-1 commented 2 years ago

Yeah this is perfect, thanks! Sorry new to github not used to all this...