asimov
Advanced tools
+25
-20
@@ -39,22 +39,2 @@ image: python:3.9 | ||
| test-python-36: | ||
| stage: test | ||
| image: python:3.6 | ||
| script: | ||
| - git config --global user.email "you@example.com" | ||
| - git config --global user.name "Your Name" | ||
| - pip install -r requirements.txt | ||
| - python setup.py install | ||
| - python -m unittest discover tests/ | ||
| test-python-37: | ||
| stage: test | ||
| image: python:3.7 | ||
| script: | ||
| - git config --global user.email "you@example.com" | ||
| - git config --global user.name "Your Name" | ||
| - pip install -r requirements.txt | ||
| - python setup.py install | ||
| - python -m unittest discover tests/ | ||
| test-python-38: | ||
@@ -105,2 +85,27 @@ stage: test | ||
| test-python-311: | ||
| stage: test | ||
| allow_failure: True | ||
| image: python:3.11 | ||
| script: | ||
| - git config --global user.email "you@example.com" | ||
| - git config --global user.name "Your Name" | ||
| - pip install -r requirements.txt | ||
| - pip install coverage | ||
| - python setup.py install | ||
| - python -m unittest discover tests/ | ||
| test-python-312: | ||
| stage: test | ||
| allow_failure: True | ||
| image: python:3.12 | ||
| script: | ||
| - git config --global user.email "you@example.com" | ||
| - git config --global user.name "Your Name" | ||
| - pip install -r requirements.txt | ||
| - pip install coverage | ||
| - python setup.py install | ||
| - python -m unittest discover tests/ | ||
| # Build docs for multiple code versions | ||
@@ -107,0 +112,0 @@ pages: |
| Metadata-Version: 2.1 | ||
| Name: asimov | ||
| Version: 0.5.7 | ||
| Version: 0.5.8 | ||
| Summary: A Python package for managing and interacting with data analysis jobs. | ||
@@ -5,0 +5,0 @@ Home-page: https://git.ligo.org/asimov/asimov |
@@ -107,4 +107,16 @@ """ | ||
| hook.load()(ledger).run(event) | ||
| click.echo( | ||
| click.style("●", fg="green") | ||
| + f"{event} has been applied." | ||
| ) | ||
| break | ||
| else: | ||
| click.echo( | ||
| click.style("●", fg="red") | ||
| + f"No hook found matching {hookname}. " | ||
| f"Installed hooks are {', '.join(discovered_hooks.names)}" | ||
| ) | ||
| @click.command() | ||
@@ -111,0 +123,0 @@ @click.option("--file", "-f", help="Location of the file containing the ledger items.") |
@@ -123,3 +123,3 @@ import shutil | ||
| for event in ledger.get_event(event): | ||
| for event in sorted(ledger.get_event(event), key=lambda e: e.name): | ||
| stuck = 0 | ||
@@ -126,0 +126,0 @@ running = 0 |
@@ -165,3 +165,3 @@ """ | ||
| """ | ||
| for event in current_ledger.get_event(event): | ||
| for event in sorted(current_ledger.get_event(event), key=lambda e: e.name): | ||
| click.secho(f"{event.name:30}", bold=True) | ||
@@ -168,0 +168,0 @@ if len(event.productions) > 0: |
+37
-17
| """ | ||
| Review functions for asimov events. | ||
| """ | ||
| import os | ||
@@ -28,16 +29,37 @@ | ||
| """ | ||
| valid = {"REJECTED", "APPROVED", "PREFERRED", "DEPRECATED"} | ||
| events = current_ledger.get_event(event) | ||
| if events is None: | ||
| click.echo( | ||
| click.style("●", fg="red") + f" Could not find an event called {event}" | ||
| ) | ||
| else: | ||
| for event in events: | ||
| production = [ | ||
| production_o | ||
| for production_o in event.productions | ||
| if production_o.name == production | ||
| ][0] | ||
| click.secho(event.name, bold=True) | ||
| for event in current_ledger.get_event(event): | ||
| production = [ | ||
| production_o | ||
| for production_o in event.productions | ||
| if production_o.name == production | ||
| ][0] | ||
| click.secho(event.name, bold=True) | ||
| click.secho(production.name) | ||
| message = ReviewMessage(message=message, status=status, production=production) | ||
| production.review.add(message) | ||
| if status.upper() in valid: | ||
| message = ReviewMessage( | ||
| message=message, status=status, production=production | ||
| ) | ||
| production.review.add(message) | ||
| else: | ||
| click.echo( | ||
| click.style("●", fg="red") | ||
| + f" Did not understand the review status {status.lower()}." | ||
| + " The review status must be one of " | ||
| + "{APPROVED, REJECTED, PREFERRED, DEPRECATED}" | ||
| ) | ||
| if hasattr(event, "issue_object"): | ||
| production.event.update_data() | ||
| if hasattr(event, "issue_object"): | ||
| production.event.update_data() | ||
| current_ledger.update_event(event) | ||
| click.echo( | ||
| click.style("●", fg="green") | ||
| + f" {event.name}/{production.name} {status.lower()}" | ||
| ) | ||
@@ -52,6 +74,4 @@ | ||
| """ | ||
| if isinstance(event, str): | ||
| event = [event] | ||
| for event in current_ledger.get_event(event): | ||
| click.secho(event.title, bold=True) | ||
| click.secho(event.name, bold=True) | ||
| if production: | ||
@@ -66,4 +86,4 @@ productions = [ | ||
| click.secho(f"\t{production.name}", bold=True) | ||
| if "review" in production.meta: | ||
| click.echo(production.meta["review"]) | ||
| if production.review: | ||
| click.echo(f"\t\t {production.review.status.lower()}") | ||
| else: | ||
@@ -70,0 +90,0 @@ click.secho("\t\tNo review information exists for this production.") |
@@ -30,3 +30,3 @@ ; | ||
| [engine] | ||
| install_path={{ config["pipelines"]["environment"] }} | ||
| install_path={{ scheduler['environment'] | default: config["pipelines"]["environment"] }} | ||
| megaplot=%(install_path)s/bin/megaplot.py | ||
@@ -33,0 +33,0 @@ bayeswave=%(install_path)s/bin/BayesWave |
@@ -177,3 +177,3 @@ {%- if production.event.repository -%} | ||
| ################################################################################ | ||
| analysis-executable={{ config['pipelines']['environment'] }}/bin/bilby_pipe_analysis | ||
| analysis-executable={{ scheduler['environment'] | default: config['pipelines']['environment'] }}/bin/bilby_pipe_analysis | ||
| environment-variables={{ scheduler['environment variables'] | default: "{'HDF5_USE_FILE_LOCKING': False, 'OMP_NUM_THREADS'=1, 'OMP_PROC_BIND'=False}" }} | ||
@@ -180,0 +180,0 @@ |
+6
-1
@@ -612,2 +612,4 @@ """ | ||
| # Update with the event and project defaults | ||
| if "ledger" in self.event.meta: | ||
| self.event.meta.pop("ledger") | ||
| self.meta = update(self.meta, deepcopy(self.event.meta)) | ||
@@ -714,3 +716,3 @@ if "productions" in self.meta: | ||
| if "reference frequency" in self.meta["likelihood"]: | ||
| self.logger.warn( | ||
| self.logger.warning( | ||
| "Found deprecated ref freq information, " | ||
@@ -887,2 +889,5 @@ "moving to waveform area of ledger" | ||
| if "ledger" in self.event.meta: | ||
| self.event.meta.pop("ledger") | ||
| defaults = update(defaults, deepcopy(self.event.meta)) | ||
@@ -889,0 +894,0 @@ |
+5
-3
@@ -55,2 +55,6 @@ """ | ||
| self.events = {ev["name"]: ev for ev in self.data["events"]} | ||
| self._all_events = [ | ||
| Event(**self.events[event], ledger=self) | ||
| for event in self.events.keys() | ||
| ] | ||
| self.data.pop("events") | ||
@@ -151,5 +155,3 @@ | ||
| else: | ||
| return [ | ||
| Event(**self.events[event], ledger=self) for event in self.events.keys() | ||
| ] | ||
| return self._all_events | ||
@@ -156,0 +158,0 @@ def get_productions(self, event=None, filters=None): |
+18
-4
| """Defines the interface with generic analysis pipelines.""" | ||
| import configparser | ||
@@ -334,5 +335,9 @@ import os | ||
| calibration = [ | ||
| os.path.abspath(os.path.join(self.production.repository.directory, cal)) | ||
| if not cal[0] == "/" | ||
| else cal | ||
| ( | ||
| os.path.abspath( | ||
| os.path.join(self.production.repository.directory, cal) | ||
| ) | ||
| if not cal[0] == "/" | ||
| else cal | ||
| ) | ||
| for cal in self.production.meta["data"]["calibration"].values() | ||
@@ -419,2 +424,11 @@ ] | ||
| if "keywords" in self.meta: | ||
| for key, argument in self.meta["keywords"]: | ||
| if argument is not None and len(key) > 1: | ||
| command += [f"--{key}", f"{argument}"] | ||
| elif argument is not None and len(key) == 1: | ||
| command += [f"-{key}", f"{argument}"] | ||
| else: | ||
| command += [f"{key}"] | ||
| with utils.set_directory(self.production.rundir): | ||
@@ -433,3 +447,3 @@ with open(f"{self.production.name}_pesummary.sh", "w") as bash_file: | ||
| print("-----------------") | ||
| print(command) | ||
| print(" ".join(command)) | ||
@@ -436,0 +450,0 @@ submit_description = { |
+24
-0
@@ -0,1 +1,25 @@ | ||
| 0.5.8 | ||
| ===== | ||
| This is a bug-fix release, which does not introduce any new backwards-incompatible features, but provides a number of small quality-of-life improvements. | ||
| These include bug-fixes to various aspects of the CLI, and improvements to make using the CLI easier. | ||
| This release also allows keyword arguments to be specified more easily to PESummary, and allows the environment of bilby and bayeswave executables to be specified on a per-analysis basis. | ||
| We have ceased testing 0.5.8 against python 3.6 and python 3.7, and will drop support for these entirely after the next release. | ||
| Breaking changes | ||
| ---------------- | ||
| This release is not believed to introduce any backwards-incompatible changes. | ||
| Merges | ||
| ------ | ||
| + `ligo!140 <https://git.ligo.org/asimov/asimov/-/merge_requests/140>`_: Change CLI outputs to list events in alphanumeric order. | ||
| + `ligo!145 <https://git.ligo.org/asimov/asimov/-/merge_requests/145>`_: Adds an error message if an unavailable pipeline is requested by an analysis. | ||
| + `ligo!149 <https://git.ligo.org/asimov/asimov/-/merge_requests/149>`_: Fixes errors with various parts of the analysis review CLI, and improves error and information messages. | ||
| + `ligo!151 <https://git.ligo.org/asimov/asimov/-/merge_requests/151>`_: Adds a confirmation message when a plugin is used to apply a new event to a project. | ||
| + `ligo!152 <https://git.ligo.org/asimov/asimov/-/merge_requests/152>`_: Allows keyword arguments to be specified for summarypages jobs via a blueprint. | ||
| + `ligo!153 <https://git.ligo.org/asimov/asimov/-/merge_requests/153>`_: Allows the analysis executable to be explicitly set from a blueprint for bilby and bayeswave. | ||
| 0.5.7 | ||
@@ -2,0 +26,0 @@ ===== |
+1
-1
| Metadata-Version: 2.1 | ||
| Name: asimov | ||
| Version: 0.5.7 | ||
| Version: 0.5.8 | ||
| Summary: A Python package for managing and interacting with data analysis jobs. | ||
@@ -5,0 +5,0 @@ Home-page: https://git.ligo.org/asimov/asimov |
@@ -163,3 +163,3 @@ """ | ||
| for event in EVENTS: | ||
| output = """bayeswave_pipe --trigger-time=1126259462.391 -r """ | ||
| output = """bayeswave_pipe --trigger-time=1126259462.391 --copy-frames --transfer-files -r """ | ||
| self.assertTrue(output in result.output) | ||
@@ -166,0 +166,0 @@ |
+107
-0
@@ -5,2 +5,14 @@ import unittest | ||
| import git | ||
| from importlib import reload | ||
| import contextlib | ||
| import io | ||
| from unittest.mock import patch | ||
| from click.testing import CliRunner | ||
| import asimov | ||
| from asimov.event import Production | ||
| from asimov.cli import review, project | ||
| from asimov.ledger import YAMLLedger | ||
| import asimov.event | ||
@@ -11,2 +23,4 @@ from asimov.cli.project import make_project | ||
| EVENTS = ["GW150914_095045", "GW190924_021846", "GW190929_012149", "GW191109_010717"] | ||
| pipelines = {"bayeswave"} | ||
@@ -102,1 +116,94 @@ TEST_YAML = """ | ||
| self.assertEqual(self.event.productions[0].review.to_dicts()[0]['status'], 'REJECTED') | ||
| class ReviewCliTests(unittest.TestCase): | ||
| """Test the CLI interfaces for review.""" | ||
| @classmethod | ||
| def setUpClass(cls): | ||
| cls.cwd = os.getcwd() | ||
| def tearDown(self): | ||
| os.chdir(self.cwd) | ||
| shutil.rmtree(f"{self.cwd}/tests/tmp/") | ||
| def setUp(self): | ||
| os.makedirs(f"{self.cwd}/tests/tmp/project") | ||
| os.chdir(f"{self.cwd}/tests/tmp/project") | ||
| runner = CliRunner() | ||
| result = runner.invoke(project.init, | ||
| ['Test Project', '--root', f"{self.cwd}/tests/tmp/project"]) | ||
| assert result.exit_code == 0 | ||
| assert result.output == '● New project created successfully!\n' | ||
| self.ledger = YAMLLedger(".asimov/ledger.yml") | ||
| f = io.StringIO() | ||
| with contextlib.redirect_stdout(f): | ||
| apply_page(file = "https://git.ligo.org/asimov/data/-/raw/main/defaults/production-pe.yaml", event=None, ledger=self.ledger) | ||
| apply_page(file = "https://git.ligo.org/asimov/data/-/raw/main/defaults/production-pe-priors.yaml", event=None, ledger=self.ledger) | ||
| for event in EVENTS: | ||
| for pipeline in pipelines: | ||
| apply_page(file = f"https://git.ligo.org/asimov/data/-/raw/main/tests/{event}.yaml", event=None, ledger=self.ledger) | ||
| apply_page(file = f"https://git.ligo.org/asimov/data/-/raw/main/tests/{pipeline}.yaml", event=event, ledger=self.ledger) | ||
| def test_add_review_to_event_reject(self): | ||
| """Check that the CLI can add an event review""" | ||
| with patch("asimov.current_ledger", new=YAMLLedger(".asimov/ledger.yml")): | ||
| reload(asimov) | ||
| reload(review) | ||
| runner = CliRunner() | ||
| for event in EVENTS: | ||
| result = runner.invoke(review.review, | ||
| ['add', event, "Prod0", "Rejected"]) | ||
| self.assertTrue(f"{event}/Prod0 rejected" in result.output) | ||
| def test_add_review_to_event_reject(self): | ||
| """Check that the CLI can add an event review""" | ||
| with patch("asimov.current_ledger", new=YAMLLedger(".asimov/ledger.yml")): | ||
| reload(asimov) | ||
| reload(review) | ||
| runner = CliRunner() | ||
| for event in EVENTS: | ||
| result = runner.invoke(review.review, | ||
| ['add', event, "Prod0", "Approved"]) | ||
| self.assertTrue(f"{event}/Prod0 approved" in result.output) | ||
| def test_add_review_to_event_unknown(self): | ||
| """Check that the CLI rejects an unknown review status""" | ||
| with patch("asimov.current_ledger", new=YAMLLedger(".asimov/ledger.yml")): | ||
| reload(asimov) | ||
| reload(review) | ||
| runner = CliRunner() | ||
| for event in EVENTS: | ||
| result = runner.invoke(review.review, | ||
| ['add', event, "Prod0", "Splorg"]) | ||
| self.assertTrue(f"Did not understand the review status splorg" in result.output) | ||
| def test_show_review_no_review(self): | ||
| """Check that the CLI can show a review report with no reviews""" | ||
| with patch("asimov.current_ledger", new=YAMLLedger(".asimov/ledger.yml")): | ||
| reload(asimov) | ||
| reload(review) | ||
| runner = CliRunner() | ||
| for event in EVENTS: | ||
| result = runner.invoke(review.review, | ||
| ['status', event]) | ||
| self.assertTrue(f"No review information exists for this production." in result.output) | ||
| def test_show_review_with_review(self): | ||
| """Check that the CLI can show a review report with no reviews""" | ||
| with patch("asimov.current_ledger", new=YAMLLedger(".asimov/ledger.yml")): | ||
| reload(asimov) | ||
| reload(review) | ||
| runner = CliRunner() | ||
| for event in EVENTS: | ||
| result = runner.invoke(review.review, | ||
| ['add', event, "Prod0", "Approved"]) | ||
| result = runner.invoke(review.review, | ||
| ['status', event]) | ||
| self.assertTrue(f"approved" in result.output) |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
792637
1.08%9930
1.39%