Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opencv dependency in stcal being optional causes uncaught error in jump step #7409

Closed
m-samland opened this issue Dec 21, 2022 · 8 comments · Fixed by #7499 · May be fixed by spacetelescope/stcal#138
Closed

Opencv dependency in stcal being optional causes uncaught error in jump step #7409

m-samland opened this issue Dec 21, 2022 · 8 comments · Fixed by #7499 · May be fixed by spacetelescope/stcal#138
Assignees

Comments

@m-samland
Copy link

After a clean install of the newest version (1.8.5), running the Detector1 pipeline now crashes if parameter jump.use_ellipses = True. This is because stcal requires opencv-python to work, which is now an optional requirement and not automatically installed. I'm not sure why this packages was made optional, but since it was, I think there should either be a fallback that does not require opencv, or proper error handling that tells JWST pipeline users why the pipeline is failing if functions are used that require opencv. Right now it simply fails throwing a generic NameError on the line the function is called. (Or maybe it should just be added in again as a requirement, but I am not privy to the reasons it was removed in the first place.)

There is a warning that is raised when opencv cannot be imported in stcal, but it doesn't actually cause an Exceptions when an opencv function is called and opencv is not installed.

@zacharyburnett zacharyburnett self-assigned this Dec 22, 2022
@zacharyburnett
Copy link
Collaborator

I made opencv optional because certain users had difficulty building it on their platforms (spacetelescope/stcal#126) which was blocking installation; you are right, however, that the warning is not descriptive enough. I'll work on a better exception flow, and also a fallback to analogous scikit-image ellipse functions

@zacharyburnett
Copy link
Collaborator

zacharyburnett commented Dec 29, 2022

spacetelescope/stcal#136 adds better / more descriptive warnings to this situation.

I am currently working on porting analogous functionality to scikit-image (which should already be installed alongside jwst) in spacetelescope/stcal#138

@jdavies-st
Copy link
Collaborator

This is still broken on the latest release. My workflow on MacOS 10.15 Catalina:

$ conda create -n jwst python=3.10 -qy
$ conda activate jwst
(jwst) $ pip install jwst
...
Successfully installed BayesicFitting-3.0.1 PyWavelets-1.4.1 asdf-2.14.3 asdf-astropy-0.3.0 asdf-coordinates-schemas-0.1.0 asdf-standard-1.0.3 asdf-transform-schemas-0.3.0 asdf-unit-schemas-0.1.0 asdf-wcs-schemas-0.1.1 astropy-5.2.1 attrs-22.2.0 charset-normalizer-3.0.1 ci-watson-0.6.1 codecov-2.1.12 colorama-0.4.6 contourpy-1.0.7 coverage-7.1.0 crds-11.16.20 cycler-0.11.0 drizzle-1.13.6 exceptiongroup-1.1.0 filelock-3.9.0 fonttools-4.38.0 future-0.18.3 gwcs-0.18.3 idna-3.4 imageio-2.25.0 importlib-metadata-6.0.0 iniconfig-2.0.0 jmespath-1.0.1 jsonschema-4.17.3 jwst-1.9.4 kiwisolver-1.4.4 lxml-4.9.2 matplotlib-3.6.3 networkx-3.0 numpy-1.24.1 packaging-23.0 parsley-1.3 photutils-1.6.0 pillow-9.4.0 pluggy-1.0.0 poppy-1.0.3 psutil-5.9.4 pyerfa-2.0.0.1 pyparsing-3.0.9 pyrsistent-0.19.3 pytest-7.2.1 pytest-cov-4.0.0 pytest-doctestplus-0.12.1 pytest-openfiles-0.5.0 python-dateutil-2.8.2 pyyaml-6.0 readchar-4.0.3 requests-2.28.2 requests-mock-1.10.0 ruff-0.0.240 scikit-image-0.19.3 scipy-1.9.3 semantic-version-2.10.0 six-1.16.0 spherical-geometry-1.2.23 stcal-1.3.3 stdatamodels-0.4.5 stpipe-0.4.5 stsci.image-2.3.5 stsci.imagestats-1.6.3 stsci.stimage-0.2.6 tifffile-2023.2.2 tomli-2.0.1 tweakwcs-0.8.1 urllib3-1.26.14 wiimatch-0.3.1 zipp-3.12.0
(jwst) $ pip install stcal[opencv]
...
Installing collected packages: opencv-python
Successfully installed opencv-python-4.7.0.68

And now run the pipeline, turning on the code that needs opencv:

(jwst) $ strun calwebb_detector1 jw01031001001_02101_00001_mirifulong_uncal.fits --steps.jump.expand_large_events=True
...
2023-02-03 11:59:48,464 - stpipe.Detector1Pipeline.jump - INFO - Step jump running with args (<RampModel(8, 12, 1024, 1032) from jw01031001001_02101_00001_mirifulong_uncal.fits>,).
2023-02-03 11:59:48,466 - stpipe.Detector1Pipeline.jump - INFO - Step jump parameters are: {'pre_hooks': [], 'post_hooks': [], 'output_file': None, 'output_dir': None, 'output_ext': '.fits', 'output_use_model': False, 'output_use_index': True, 'save_results': False, 'skip': False, 'suffix': None, 'search_output_file': True, 'input_dir': '', 'rejection_threshold': 4.0, 'three_group_rejection_threshold': 6.0, 'four_group_rejection_threshold': 5.0, 'maximum_cores': 'none', 'flag_4_neighbors': True, 'max_jump_to_flag_neighbors': 1000.0, 'min_jump_to_flag_neighbors': 10.0, 'after_jump_flag_dn1': 0.0, 'after_jump_flag_time1': 0.0, 'after_jump_flag_dn2': 0.0, 'after_jump_flag_time2': 0.0, 'min_sat_area': 1.0, 'min_jump_area': 5.0, 'expand_factor': 2.0, 'use_ellipses': False, 'sat_required_snowball': True, 'expand_large_events': True}
2023-02-03 11:59:48,486 - stpipe.Detector1Pipeline.jump - INFO - CR rejection threshold = 4 sigma
2023-02-03 11:59:48,500 - stpipe.Detector1Pipeline.jump - INFO - Using GAIN reference file: /Users/jdavies/crds_cache/references/jwst/miri/jwst_miri_gain_0006.fits
2023-02-03 11:59:48,554 - stpipe.Detector1Pipeline.jump - INFO - Using READNOISE reference file: /Users/jdavies/crds_cache/references/jwst/miri/jwst_miri_readnoise_0086.fits
2023-02-03 11:59:49,280 - stpipe.Detector1Pipeline.jump - INFO - Executing two-point difference method
2023-02-03 11:59:49,529 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 1:
2023-02-03 11:59:50,663 - stpipe.Detector1Pipeline.jump - WARNING - /Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stcal/jump/twopoint_difference.py:154: RuntimeWarning: All-NaN slice encountered
  max_ratio = np.nanmax(ratio, axis=0)

2023-02-03 11:59:50,700 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 12776 pixels with at least one CR from five or more groups.
2023-02-03 11:59:56,210 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 2:
2023-02-03 11:59:57,617 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 12712 pixels with at least one CR from five or more groups.
2023-02-03 12:00:01,181 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 3:
2023-02-03 12:00:02,280 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 12174 pixels with at least one CR from five or more groups.
2023-02-03 12:00:05,729 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 4:
2023-02-03 12:00:07,038 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 12192 pixels with at least one CR from five or more groups.
2023-02-03 12:00:11,162 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 5:
2023-02-03 12:00:12,446 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 11604 pixels with at least one CR from five or more groups.
2023-02-03 12:00:17,825 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 6:
2023-02-03 12:00:19,599 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 11597 pixels with at least one CR from five or more groups.
2023-02-03 12:00:22,850 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 7:
2023-02-03 12:00:24,374 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 11800 pixels with at least one CR from five or more groups.
2023-02-03 12:00:27,551 - stpipe.Detector1Pipeline.jump - INFO - Working on integration 8:
2023-02-03 12:00:28,694 - stpipe.Detector1Pipeline.jump - INFO - From highest outlier, two-point found 11911 pixels with at least one CR from five or more groups.
2023-02-03 12:00:31,769 - stpipe.Detector1Pipeline.jump - INFO - Flagging large events (snowballs, showers).
----------------------------------------------------------------------
ERROR RUNNING STEP 'Detector1Pipeline':
    `opencv-python` must be installed (`pip install stcal[opencv]`) in
    order to use ellipses
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jdavies/miniconda3/envs/jwst/bin/strun", line 28, in <module>
    step = Step.from_cmdline(sys.argv[1:])
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stpipe/step.py", line 179, in from_cmdline
    return cmdline.step_from_cmdline(args)
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stpipe/cmdline.py", line 343, in step_from_cmdline
    step.run(*positional)
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stpipe/step.py", line 454, in run
    step_result = self.process(*args)
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/jwst/pipeline/calwebb_detector1.py", line 119, in process
    input = self.jump(input)
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stpipe/step.py", line 454, in run
    step_result = self.process(*args)
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/jwst/jump/jump_step.py", line 89, in process
    result = run_detect_jumps(input_model, gain_model, readnoise_model,
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/jwst/jump/jump.py", line 55, in run_detect_jumps
    new_gdq, new_pdq = detect_jumps(frames_per_group, data, gdq, pdq, err,
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stcal/jump/jump.py", line 221, in detect_jumps
    flag_large_events(gdq, jump_flag, sat_flag, min_sat_area=min_sat_area,
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stcal/jump/jump.py", line 359, in flag_large_events
    sat_circles = find_circles(new_flagged_pixels, sat_flag, min_sat_area)
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/stcal/jump/jump.py", line 458, in find_circles
    raise ModuleNotFoundError(ELLIPSE_PACKAGE_WARNING)
ModuleNotFoundError: `opencv-python` must be installed (`pip install stcal[opencv]`) in order to use ellipses
(jwst) $ pip install opencv-python
Requirement already satisfied: opencv-python in /Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages (4.7.0.68)
Requirement already satisfied: numpy>=1.21.4 in /Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages (from opencv-python) (1.24.1)

So the message is not very useful. If I actually try doing what stcal.jump does:

>>> import cv2 as cv
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/cv2/__init__.py", line 181, in <module>
    bootstrap()
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/cv2/__init__.py", line 153, in bootstrap
    native_module = importlib.import_module("cv2")
  File "/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: dlopen(/Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/cv2/cv2.abi3.so, 2): Symbol not found: _VTRegisterSupplementalVideoDecoderIfAvailable
  Referenced from: /Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/cv2/.dylibs/libavcodec.59.37.100.dylib (which was built for Mac OS X 11.0)
  Expected in: /System/Library/Frameworks/VideoToolbox.framework/Versions/A/VideoToolbox
 in /Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages/cv2/.dylibs/libavcodec.59.37.100.dylib

I get a useful message, but again, not one that is immediately clear how to solve.

@jdavies-st
Copy link
Collaborator

It looks like it is looking for some library in a later version of MacOS which mine does not have. If I install a slightly older version of opencv, I don't get that error, and the snowball flagging in jump step runs to completion:

(jwst) $ pip install opencv-python~=4.6.0
Collecting opencv-python~=4.6.0
  Using cached opencv_python-4.6.0.66-cp36-abi3-macosx_10_15_x86_64.whl (46.4 MB)
Requirement already satisfied: numpy>=1.14.5 in /Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages (from opencv-python~=4.6.0) (1.24.1)
Installing collected packages: opencv-python
  Attempting uninstall: opencv-python
    Found existing installation: opencv-python 4.7.0.68
    Uninstalling opencv-python-4.7.0.68:
      Successfully uninstalled opencv-python-4.7.0.68
Successfully installed opencv-python-4.6.0.66

@zacharyburnett
Copy link
Collaborator

It looks like it is looking for some library in a later version of MacOS which mine does not have. If I install a slightly older version of opencv, I don't get that error, and the snowball flagging in jump step runs to completion:

(jwst) $ pip install opencv-python~=4.6.0
Collecting opencv-python~=4.6.0
  Using cached opencv_python-4.6.0.66-cp36-abi3-macosx_10_15_x86_64.whl (46.4 MB)
Requirement already satisfied: numpy>=1.14.5 in /Users/jdavies/miniconda3/envs/jwst/lib/python3.10/site-packages (from opencv-python~=4.6.0) (1.24.1)
Installing collected packages: opencv-python
  Attempting uninstall: opencv-python
    Found existing installation: opencv-python 4.7.0.68
    Uninstalling opencv-python-4.7.0.68:
      Successfully uninstalled opencv-python-4.7.0.68
Successfully installed opencv-python-4.6.0.66

Do you think this merits pinning opencv to ~=4.6.0 for MacOS?

@jdavies-st
Copy link
Collaborator

jdavies-st commented Feb 3, 2023

I don't know if early versions of opencv work on the latest MacOS versions. One would have to test.

But perhaps opencv is too much of a headache dependency for simply creating a pixel mask from a circle or ellipse? Astropy regions can do this easily. You can make ellipses and circles and then export them as pixel masks. And also interface with shapely if needed.

https://astropy-regions.readthedocs.io/

https://astropy-regions.readthedocs.io/en/stable/masks.html

I would expect it to be a drop-in replacement for all the opencv functionality that is used here.

Perhaps going too far, a much simpler approach would be to not fit circles and ellipses at all (which can lead to fitting errors and masking half the image), but to use scipy.ndimage.binary_dilation instead. Just grow regions. And select regions of a minimum area to grow using scipy.ndimage.binary_erosion. This is vastly simpler and probably more robust. And handles shapes that are not exactly circles or ellipses.

@zacharyburnett
Copy link
Collaborator

But perhaps opencv is too much of a headache dependency for simply creating a pixel mask from a circle or ellipse? Astropy regions can do this easily. You can make ellipses and circles and then export them as pixel masks. And also interface with shapely if needed.

https://astropy-regions.readthedocs.io/

https://astropy-regions.readthedocs.io/en/stable/masks.html

I would expect it to be a drop-in replacement for all the opencv functionality that is used here.

That is good to know; I experimented with using analogous scikit-image functions, but there are some key differences in how the ellipses are constructed.

Perhaps going too far, a much simpler approach would be to not fit circles and ellipses at all (which can lead to fitting errors and masking half the image), but to use scipy.ndimage.binary_dilation instead. Just grow regions. And select regions of a minimum area to grow using scipy.ndimage.binary_erosion. This is vastly simpler and probably more robust. And handles shapes that are not exactly circles or ellipses.

Binary operations make a lot more sense as it's a pixel image. I apologize, I don't have a lot of context on how this fits into the greater pipeline as a whole so I was focusing on recreating the ellipses; I'll look into the feasibility of using the ndimage functions instead.

@hbushouse
Copy link
Collaborator

This is being fixed by restoring "opencv" to the list of hard dependencies for the jwst package (see #7499 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants