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

Removing currsys as global parameter #364

Merged
merged 10 commits into from
Feb 6, 2024
Merged

Conversation

astronomyk
Copy link
Collaborator

Remove the cursed rc.currsys object from the global namespace.

Rational:

In order to allow multi-core processing, we cannot rely on global properties.
Most Effect objects make a call to the utility function from_currsys in order to resolve an !-strings.
This function tracks down the value(s) that any (chain of) bang-strings refers to.
The current system (__currsys__) acts as a member of the rc submodule, and acts essentially as a global variable.
This gets in when generating sub-processes to split up the workload of the loops found in the OpticalTrain.observe function.
An additional side-effect of having a global-esque commands dictionary, is that instances of OpticalTrain are not self-contained.
As such a user cannot reliably use multiple instances of an OpticalTrain in a script of notebook.
This prohibits efficient re-use of an already created system, and means ScopeSim fails to achieve the goal of enabling single Source objects to be observed with multiple instruments in the same session.
Facit: Not User Freindly

Implemention

The work around here contains two parts:

  1. Add the option to pass a commands object, i.e. the self.cmds object from the top-level of a OpticalTrain object to the from_currsys function, and bypass the call to the global dict stored in rc.__currsys__.
  2. Propogate the UserCommands object down through all layers such that each Effect object also references the top-level self.cmds dict.

Goal

Ideally if I have done this correctly, the rc.__currsys__ dict should not be needed now, and can therefore be deleted.

How to test this:

  • Delete rc.__currsys__
  • Remove the fallback option to use rc.__currsys__ from from_currsys()
  • Remove the set_focus method from OpticalTrain

Exceptions

There are occasional calls to !SIM keywords. These should be kept in a global level dictionary as they pertain to how scopesim runs. There should be no instrument specific parameters in the !SIM dict.

Copy link

codecov bot commented Feb 6, 2024

Codecov Report

Attention: 92 lines in your changes are missing coverage. Please review.

Comparison is base (0920760) 75.12% compared to head (16209bd) 72.57%.

❗ Current head 16209bd differs from pull request most recent head 65b9014. Consider uploading reports for the commit 65b9014 to get more accurate results

Files Patch % Lines
scopesim/optics/optical_train.py 44.23% 29 Missing ⚠️
scopesim/effects/psfs.py 47.82% 24 Missing ⚠️
scopesim/effects/electronic.py 60.00% 12 Missing ⚠️
scopesim/effects/apertures.py 33.33% 6 Missing ⚠️
scopesim/effects/ter_curves.py 70.00% 6 Missing ⚠️
scopesim/effects/spectral_trace_list.py 28.57% 5 Missing ⚠️
scopesim/optics/optics_manager.py 73.33% 4 Missing ⚠️
scopesim/utils.py 76.92% 3 Missing ⚠️
scopesim/effects/data_container.py 75.00% 1 Missing ⚠️
scopesim/effects/spectral_trace_list_utils.py 75.00% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@              Coverage Diff               @@
##           dev_master     #364      +/-   ##
==============================================
- Coverage       75.12%   72.57%   -2.55%     
==============================================
  Files              58       58              
  Lines            8005     8052      +47     
==============================================
- Hits             6014     5844     -170     
- Misses           1991     2208     +217     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@teutoburg teutoburg added the refactor Implementation improvement label Feb 6, 2024
@teutoburg teutoburg mentioned this pull request Feb 6, 2024
2 tasks
scopesim/effects/psfs.py Outdated Show resolved Hide resolved
@teutoburg teutoburg changed the title DRAFT: Removing currsys as global parameter Removing currsys as global parameter Feb 6, 2024
@teutoburg
Copy link
Contributor

Only the coverage is now failing, so fine to merge, to avoid further complications (discussed with @astronomyk).

@teutoburg teutoburg merged commit b98f39f into dev_master Feb 6, 2024
23 of 24 checks passed
@hugobuddel
Copy link
Collaborator

I think this PR broke the IRDB tests. See https://github.com/AstarVienna/irdb/actions/runs/7806706394 and https://github.com/AstarVienna/ScopeSim_Data/actions/runs/7810201424/job/21303256121 👍

FAILED ELT/tests/test_TER_properties.py::test_eso_vs_scopesim_throughput - ValueError: !TEL.temperature was not found in rc.__currsys__
FAILED OSIRIS/tests/test_compiles.py::TestOsirisLongSlitCompiles::test_run_lss_simulation - TypeError: scopesim.effects.spectral_trace_list.SpectralTraceList() got multiple values for keyword argument 'cmds'
FAILED OSIRIS/tests/test_compiles.py::TestOsirisMaatCompiles::test_run_maat_simulation - TypeError: scopesim.effects.spectral_trace_list.SpectralTraceList() got multiple values for keyword argument 'cmds'
FAILED OSIRIS/tests/test_maat_daves_tests.py::test_maat_runs_with_point_source - TypeError: scopesim.effects.spectral_trace_list.SpectralTraceList() got multiple values for keyword argument 'cmds'
FAILED OSIRIS/tests/test_maat_daves_tests.py::test_maat_runs_with_extended_source - TypeError: scopesim.effects.spectral_trace_list.SpectralTraceList() got multiple values for keyword argument 'cmds'
FAILED OSIRIS/tests/test_maat_daves_tests.py::test_maat_runs_with_line_list_source - TypeError: scopesim.effects.spectral_trace_list.SpectralTraceList() got multiple values for keyword argument 'cmds'
FAILED OSIRIS/tests/test_maat_traces.py::TestMaatTraces::test_plot_traces - TypeError: scopesim.effects.spectral_trace_list.SpectralTraceList() got multiple values for keyword argument 'cmds'
FAILED OSIRIS/tests/test_maat_traces.py::TestMaatOperations::test_basic_trace_image - TypeError: scopesim.effects.spectral_trace_list.SpectralTraceList() got multiple values for keyword argument 'cmds'
FAILED WFC3/test_wfc3/test_full_package_wfc3_ir.py::TestObserveOpticalTrain::test_actually_produces_stars - assert 1032.9545687957511 == 7965343.479197175 ± 8.0e+04
  comparison failed
  Obtained: 1032.9545687957511
  Expected: 7965343.479197175 ± 8.0e+04
= 9 failed, 459 passed, 9 skipped, 64 xfailed, 61 xpassed, 150 warnings in 484.29s (0:08:04) =

It is important to locally run the test suite and notebooks of the irdb before making such large changes.

@teutoburg
Copy link
Contributor

It is important to locally run the test suite and notebooks of the irdb before making such large changes.

@astronomyk 👀

@hugobuddel
Copy link
Collaborator

Simple things like this is now broken:

import scopesim as sim
sim.effects.SurfaceList(filename="ELT/LIST_mirrors_ELT.tbl")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[...]/ScopeSim/scopesim/effects/surface_list.py", line 24, in __init__
    tbl = from_currsys(self.table, self.cmds)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/ScopeSim/scopesim/utils.py", line 853, in from_currsys
    tbl_dict = from_currsys(tbl_dict, cmds)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/ScopeSim/scopesim/utils.py", line 867, in from_currsys
    item[key] = from_currsys(item[key], cmds)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/ScopeSim/scopesim/utils.py", line 860, in from_currsys
    item = np.array([from_currsys(x, cmds) for x in item])
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "[...]/ScopeSim/scopesim/utils.py", line 860, in <listcomp>
    item = np.array([from_currsys(x, cmds) for x in item])
                     ^^^^^^^^^^^^^^^^^^^^^
  File "[...]/ScopeSim/scopesim/utils.py", line 882, in from_currsys
    raise ValueError(f"{item} was not found in rc.__currsys__")
ValueError: !TEL.temperature was not found in rc.__currsys__

@astronomyk do you have an opportunity to look into this?

@@ -646,7 +649,8 @@ def get_meta_quantity(meta_dict, name, fallback_unit=""):

"""
if isinstance(meta_dict[name], str) and meta_dict[name].startswith("!"):
meta_dict[name] = from_currsys(meta_dict[name])
raise ValueError(f"!-strings should be resolved upstream: "
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that we now want to resolve all !-strings upon initialization, but is this really a good idea? There is something to be said to evaluate all !-strings only when they are actually needed.

In particular, would this new scheme mean that it is not possible to easily change the values later? Say the telescope refers to !ATMO.temperature, which is then resolved upon initialization to, say, 7˘C. Then the user changes !ATMO.temperature to, say, 8. Would the telescope temperature then stay on 7?

I'm asking, because I'm not sure I understand the new design. (Not sure I understand the old design properly either though.)

Practically though, most files refer to other files (which is the point), but those other files might not yet be loaded. E.g. https://github.com/AstarVienna/irdb/blob/dev_master/ELT/LIST_ELT_combined.tbl refers to !TEL.temperature. So it is only possible to instantiate SurfaceList(filename="ELT/LIST_mirrors_ELT.tbl") if the atmosphere has been instantiated.

There could also be cyclic dependencies, because https://github.com/AstarVienna/irdb/blob/dev_master/Armazones/Armazones.yaml refers to !INST.pixel_scale, but https://github.com/AstarVienna/irdb/blob/dev_master/MICADO/MICADO_IMG_wide.yaml which defines !INST.pixel_scale refers to !ATMO.altitude.

Or does this actually work? I'm confused.

@hugobuddel
Copy link
Collaborator

So not everything is apparently evaluated early.

Apparently !-values are only evaluated early if they occur in a table, but not when they are regular properties (of an optical element) of attributes (of an effect)?

E.g. !TEL.temperature is evaluated early if it appears in a table, but is not evaluated if it is a normal property in a yaml file?

That does not seem right.

Comment on lines 481 to +484
if filename.startswith("!"):
filename = from_currsys(filename)
raise ValueError(f"!-string filename should be resolved upstream: "
f"{filename}")
# filename = from_currsys(filename)
Copy link
Collaborator

Choose a reason for hiding this comment

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

The call to from_currsys has been removed from find_file(), so every caller of find_file() should now do the resolving of !-values themselves. But this has not been done, SpectralSurface.__init__() in particular does not resolve !-values.

Copy link
Collaborator

Choose a reason for hiding this comment

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

But it seems quite some work to properly propagate cmd, e.g. through this traceback:

../ScopeSim/scopesim/effects/surface_list.py:26: in __init__
    self.surfaces = rad_utils.make_surface_dict_from_table(tbl)
../ScopeSim/scopesim/optics/radiometry_utils.py:161: in make_surface_dict_from_table
    surf_dict[names[ii]] = make_surface_from_row(row, **tbl.meta)
../ScopeSim/scopesim/optics/radiometry_utils.py:169: in make_surface_from_row
    surface = SpectralSurface(**kwargs)
../ScopeSim/scopesim/optics/surface.py:50: in __init__
    filename = find_file(filename)

OTOH, at first glance it seems that make_surface_dict_from_table() and make_surface_from_row() don't do anything surface-specific. Similar functionality should exist for the DetectorArray for example, so if we generalize those functions, then things might become easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor Implementation improvement
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants