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

JP-2675: Bug in setting SKIPPED for cal_step keywords, when input is ModelContainer #62

Merged
merged 3 commits into from Jul 14, 2022

Conversation

tapastro
Copy link
Collaborator

Addresses #61
Addresses JP-2675

Recent code added by yours truly tried to catch errors in meta keyword assignment of cal_step values to SKIPPED, but missed the possibliity of the first step in a pipeline being skipped, exposing this code to a ModelContainer. Code is added to "broadcast" behavior initially applied to a single input DataModel to all DataModel enclosed within the ModelContainer.

NB: This reinforces the need for an stdatamodels issue to add a parent class to ModelContainer that provides for a robust isinstance() check, e.g. @stscieisenhamer's suggested ModelList.

@codecov
Copy link

codecov bot commented Jul 13, 2022

Codecov Report

Merging #62 (8c51f1b) into master (27b4430) will not change coverage.
The diff coverage is 0.00%.

@@          Coverage Diff           @@
##           master     #62   +/-   ##
======================================
  Coverage    0.00%   0.00%           
======================================
  Files          25      25           
  Lines        3060    3067    +7     
======================================
- Misses       3060    3067    +7     
Impacted Files Coverage Δ
src/stpipe/step.py 0.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 27b4430...8c51f1b. Read the comment docs.

Copy link
Collaborator

@hbushouse hbushouse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hbushouse
Copy link
Collaborator

Have you been able to do some semi-comprehensive testing on a range of use cases?

@tapastro
Copy link
Collaborator Author

Have you been able to do some semi-comprehensive testing on a range of use cases?

Full disclosure: I made this PR and left for dinner. I'll start a regression set against it, but besides testing on David's example data, it's not clear we have something to catch this. I'm also not convinced it warrants a test of its own, but this PR may suggest otherwise...

@hbushouse
Copy link
Collaborator

@ddavis-stsci is it possible for someone to test this PR against Roman before we merge it?

@zacharyburnett
Copy link
Collaborator

zacharyburnett commented Jul 14, 2022

I ran regtests in Romancal against this PR from a clean environment:

pip install -e ".[test]" pytest-xdist
pip install git+https://github.com/tapastro/stpipe@jp-2675-cal-step-skip-bug
export CRDS_SERVER_URL=https://roman-crds-test.stsci.edu
pytest -n auto --bigdata romancal/regtest

and had the following failures:

`test_level2_image_processing_pipeline`
----------------------------------------------------------------------
ERROR PARSING CONFIGURATION:
    'roman_elp' is not a path to a config file or a Python Step class
----------------------------------------------------------------------
usage: -c [--logcfg LOGCFG] [--verbose] [--debug]
          [--save-parameters SAVE_PARAMETERS] [--disable-crds-steppars]
          cfg_file_or_class

Run an stpipe Step or Pipeline

positional arguments:
  cfg_file_or_class     The configuration file or Python class to run

options:
  --logcfg LOGCFG       The logging configuration file to load
  --verbose, -v         Turn on all logging messages
  --debug               When an exception occurs, invoke the Python debugger,
                        pdb
  --save-parameters SAVE_PARAMETERS
                        Save step parameters to specified file.
  --disable-crds-steppars
                        Disable retrieval of step parameter references files
                        from CRDS

romancal/regtest/test_wfi_pipeline.py:20 (test_level2_image_processing_pipeline)
identifier = 'roman_elp'

    def _get_config_and_class(identifier):
        """
        Given a file path to a config file or Python module path, return a
        Step class and a configuration object.
        """
        if os.path.exists(identifier):
            config_file = identifier
            config = config_parser.load_config_file(config_file)
            step_class, name = Step._parse_class_and_name(
                config, config_file=config_file)
        else:
            try:
>               step_class = utilities.import_class(utilities.resolve_step_class_alias(identifier), Step)

/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:40: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

full_name = 'roman_elp', subclassof = <class 'stpipe.step.Step'>
config_file = None

    def import_class(full_name, subclassof=object, config_file=None):
        """
        Import the Python class `full_name` given in full Python package format,
        e.g.::
    
            package.another_package.class_name
    
        Return the imported class. Optionally, if `subclassof` is not None
        and is a Python class, make sure that the imported class is a
        subclass of `subclassof`.
        """
        # Understand which class we need to instantiate. The class name is given in
        # full Python package notation, e.g.
        #   package.subPackage.subsubpackage.className
        # in the input parameter `full_name`. This means that
        #   1. We HAVE to be able to say
        #       from package.subPackage.subsubpackage import className
        #   2. If `subclassof` is defined, the newly imported Python class MUST be a
        #      subclass of `subclassof`, which HAS to be a Python class.
    
        if config_file is not None:
            sys.path.insert(0, os.path.dirname(config_file))
    
        try:
            full_name = full_name.strip()
            package_name, sep, class_name = full_name.rpartition('.')
            if not package_name:
>               raise ImportError("{0} is not a Python class".format(full_name))
E               ImportError: roman_elp is not a Python class

/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/utilities.py:59: ImportError

During handling of the above exception, another exception occurred:

rtdata = {'input': '/private/var/folders/bv/nnh6jr1553jcv2pxbt8hyw6c00053_/T/pytest-of-zburnett/pytest-3/popen-gw6/test_level2_...cal.asdf',
 'remote_results_path': None,
 'test_name': None,
 'traceback': None,
 'truth': None,
 'truth_remote': None}
ignore_asdf_paths = {'ignore': ['meta.[date, filename]', 'asdf_library', 'history', 'cal_logs']}

    @pytest.mark.bigdata
    @pytest.mark.soctests
    def test_level2_image_processing_pipeline(rtdata, ignore_asdf_paths):
        """Tests for flat field imaging processing requirements DMS86 & DMS 87 """
        input_data = "r0000101001001001001_01101_0001_WFI01_uncal.asdf"
        rtdata.get_data(f"WFI/image/{input_data}")
        rtdata.input = input_data
    
        # Test Pipeline
        output = "r0000101001001001001_01101_0001_WFI01_cal.asdf"
        rtdata.output = output
        args = ["--disable-crds-steppars",
                "--steps.jump.rejection_threshold=180.0",
                "--steps.jump.three_group_rejection_threshold=185.0",
                "--steps.jump.four_group_rejection_threshold=190",
                "roman_elp", rtdata.input,
                ]
>       ExposurePipeline.from_cmdline(args)

/Users/zburnett/projects/romancal/romancal/regtest/test_wfi_pipeline.py:38: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/step.py:179: in from_cmdline
    return cmdline.step_from_cmdline(args)
/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:341: in step_from_cmdline
    just_the_step_from_cmdline(args, cls)
/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:198: in just_the_step_from_cmdline
    _get_config_and_class(known.cfg_file_or_class[0])
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

identifier = 'roman_elp'

    def _get_config_and_class(identifier):
        """
        Given a file path to a config file or Python module path, return a
        Step class and a configuration object.
        """
        if os.path.exists(identifier):
            config_file = identifier
            config = config_parser.load_config_file(config_file)
            step_class, name = Step._parse_class_and_name(
                config, config_file=config_file)
        else:
            try:
                step_class = utilities.import_class(utilities.resolve_step_class_alias(identifier), Step)
            except (ImportError, AttributeError, TypeError):
>               raise ValueError(
                    '{0!r} is not a path to a config file or a Python Step '
                    'class'.format(identifier))
E               ValueError: 'roman_elp' is not a path to a config file or a Python Step class

/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:42: ValueError
`test_level2_grism_processing_pipeline`
----------------------------------------------------------------------
ERROR PARSING CONFIGURATION:
    'roman_elp' is not a path to a config file or a Python Step class
----------------------------------------------------------------------
usage: -c [--logcfg LOGCFG] [--verbose] [--debug]
          [--save-parameters SAVE_PARAMETERS] [--disable-crds-steppars]
          cfg_file_or_class

Run an stpipe Step or Pipeline

positional arguments:
  cfg_file_or_class     The configuration file or Python class to run

options:
  --logcfg LOGCFG       The logging configuration file to load
  --verbose, -v         Turn on all logging messages
  --debug               When an exception occurs, invoke the Python debugger,
                        pdb
  --save-parameters SAVE_PARAMETERS
                        Save step parameters to specified file.
  --disable-crds-steppars
                        Disable retrieval of step parameter references files
                        from CRDS

romancal/regtest/test_wfi_pipeline.py:170 (test_level2_grism_processing_pipeline)
identifier = 'roman_elp'

    def _get_config_and_class(identifier):
        """
        Given a file path to a config file or Python module path, return a
        Step class and a configuration object.
        """
        if os.path.exists(identifier):
            config_file = identifier
            config = config_parser.load_config_file(config_file)
            step_class, name = Step._parse_class_and_name(
                config, config_file=config_file)
        else:
            try:
>               step_class = utilities.import_class(utilities.resolve_step_class_alias(identifier), Step)

/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:40: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

full_name = 'roman_elp', subclassof = <class 'stpipe.step.Step'>
config_file = None

    def import_class(full_name, subclassof=object, config_file=None):
        """
        Import the Python class `full_name` given in full Python package format,
        e.g.::
    
            package.another_package.class_name
    
        Return the imported class. Optionally, if `subclassof` is not None
        and is a Python class, make sure that the imported class is a
        subclass of `subclassof`.
        """
        # Understand which class we need to instantiate. The class name is given in
        # full Python package notation, e.g.
        #   package.subPackage.subsubpackage.className
        # in the input parameter `full_name`. This means that
        #   1. We HAVE to be able to say
        #       from package.subPackage.subsubpackage import className
        #   2. If `subclassof` is defined, the newly imported Python class MUST be a
        #      subclass of `subclassof`, which HAS to be a Python class.
    
        if config_file is not None:
            sys.path.insert(0, os.path.dirname(config_file))
    
        try:
            full_name = full_name.strip()
            package_name, sep, class_name = full_name.rpartition('.')
            if not package_name:
>               raise ImportError("{0} is not a Python class".format(full_name))
E               ImportError: roman_elp is not a Python class

/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/utilities.py:59: ImportError

During handling of the above exception, another exception occurred:

rtdata = {'input': '/private/var/folders/bv/nnh6jr1553jcv2pxbt8hyw6c00053_/T/pytest-of-zburnett/pytest-3/popen-gw7/test_level2_...cal.asdf',
 'remote_results_path': None,
 'test_name': None,
 'traceback': None,
 'truth': None,
 'truth_remote': None}
ignore_asdf_paths = {'ignore': ['meta.[date, filename]', 'asdf_library', 'history', 'cal_logs']}

    @pytest.mark.bigdata
    @pytest.mark.soctests
    def test_level2_grism_processing_pipeline(rtdata, ignore_asdf_paths):
        """Tests for flat field grism processing requirements DMS90 & DMS 91 """
        input_data = "r0000201001001001002_01101_0001_WFI01_uncal.asdf"
        rtdata.get_data(f"WFI/grism/{input_data}")
        rtdata.input = input_data
    
        # Test Pipeline
        output = "r0000201001001001002_01101_0001_WFI01_cal.asdf"
        rtdata.output = output
        args = ["--disable-crds-steppars",
                "--steps.jump.rejection_threshold=180.0",
                "--steps.jump.three_group_rejection_threshold=185.0",
                "--steps.jump.four_group_rejection_threshold=190",
                "roman_elp", rtdata.input,
                ]
>       ExposurePipeline.from_cmdline(args)

/Users/zburnett/projects/romancal/romancal/regtest/test_wfi_pipeline.py:188: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/step.py:179: in from_cmdline
    return cmdline.step_from_cmdline(args)
/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:341: in step_from_cmdline
    just_the_step_from_cmdline(args, cls)
/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:198: in just_the_step_from_cmdline
    _get_config_and_class(known.cfg_file_or_class[0])
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

identifier = 'roman_elp'

    def _get_config_and_class(identifier):
        """
        Given a file path to a config file or Python module path, return a
        Step class and a configuration object.
        """
        if os.path.exists(identifier):
            config_file = identifier
            config = config_parser.load_config_file(config_file)
            step_class, name = Step._parse_class_and_name(
                config, config_file=config_file)
        else:
            try:
                step_class = utilities.import_class(utilities.resolve_step_class_alias(identifier), Step)
            except (ImportError, AttributeError, TypeError):
>               raise ValueError(
                    '{0!r} is not a path to a config file or a Python Step '
                    'class'.format(identifier))
E               ValueError: 'roman_elp' is not a path to a config file or a Python Step class

/opt/miniconda3/envs/romancal_20220714_JP-2675/lib/python3.10/site-packages/stpipe/cmdline.py:42: ValueError

@tapastro
Copy link
Collaborator Author

To my eye, those error traces point to an issue occurring in cmdline, while this change is a pretty narrow keyword update change in step.py. Are those errors not present when tested on 0.4.0 or master?

@zacharyburnett
Copy link
Collaborator

zacharyburnett commented Jul 14, 2022

To my eye, those error traces point to an issue occurring in cmdline, while this change is a pretty narrow keyword update change in step.py. Are those errors not present when tested on 0.4.0 or master?

You're right, I thought I had tested on master previously (and had green tests) but I had actually overrode that control test with the PyPI release on accident, so I was actually testing 0.4.0. When I reinstalled from master to the control environment I got the same failing tests; no difference in tests between master and this PR.

@zacharyburnett
Copy link
Collaborator

it seems, then, that there aren't any new failures in the regtests introduced by this PR from what I can see

@hbushouse
Copy link
Collaborator

So is that my green light to go ahead and merge this, and then have someone create a new stpipe release?

@nden
Copy link
Collaborator

nden commented Jul 14, 2022

I ran one romancal test with this branch (corrected for the problem in #54 and it passed.

@zacharyburnett
Copy link
Collaborator

So is that my green light to go ahead and merge this, and then have someone create a new stpipe release?

I would think so, but I'll defer to @ddavis-stsci and @nden. I'm currently testing against the 0.4.0 PyPI distribution, and it seems like all tests pass, so I'm thinking the failing regtests might just be an artifact of how pip install git+ installs stpipe.

@nden
Copy link
Collaborator

nden commented Oct 11, 2022 via email

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

Successfully merging this pull request may close these issues.

None yet

4 participants