Skip to content

Commit 5d9c7ab

Browse files
authored
Merge pull request #30 from AEONplus/25-add-soar-facility-to-aeonlib
25 add soar facility to aeonlib
2 parents c88af42 + b2dc187 commit 5d9c7ab

11 files changed

Lines changed: 511 additions & 294 deletions

File tree

README.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,14 @@ curl https://observe.lco.global/api/instruments/ | codegen/lco/generator.py > sr
109109

110110
This list is a work in progress.
111111

112-
## OCS (Las Cumbres Observatory)
113-
114-
Full documentation: TODO
115-
112+
## Las Cumbres Observatory (LCO)
116113

117114
### Dependency group
118-
The OCS requires no additional dependency groups to be installed.
115+
Las Cumbres Observatory requires no additional dependency groups to be installed.
119116

120117
### Configuration Values
121118
See [configuration](#configuration) for instructions on setting these values.
122119

123-
For LCO:
124-
125120
```python
126121
lco_token: str = ""
127122
lco_api_root: str = "https://observe.lco.global/api/"
@@ -132,6 +127,22 @@ lco_api_root: str = "https://observe.lco.global/api/"
132127
* [LCO Developer Documentation](https://developers.lco.global/)
133128
* [OCS API Documentation](https://observatorycontrolsystem.github.io/api/observation_portal/)
134129

130+
## SOAR
131+
132+
SOAR is functionally the same as LCO, but has its own set of instruments and can be configured seperately.
133+
134+
### Dependency group
135+
SOAR requires no additional dependency groups to be installed.
136+
137+
### Configuration Values
138+
See [configuration](#configuration) for instructions on setting these values.
139+
140+
```python
141+
soar_token: str = ""
142+
soar_api_root: str = "https://observe.lco.global/api/"
143+
```
144+
Note: the soar API token will default to the same value as lco_token, if it is set.
145+
135146
## ESO (European Southern Observatory)
136147

137148
Full documentation: TODO

codegen/lco/generator.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ def get_modes(ins: dict, type: str) -> list[str]:
1515
return []
1616

1717

18-
def generate_instrument_configs(ins_s: str) -> str:
18+
def generate_instrument_configs(ins_s: str, soar: bool = False) -> str:
1919
"""
2020
Generate instrument models based on the output of the OCS
2121
instrument data endpoint. For LCO, this endpoint resides
2222
at https://observe.lco.global/api/instruments/
2323
2424
Args:
2525
ins_s (str): The input json containing instrument data.
26+
soar (bool): Whether to generate SOAR instruments.
2627
2728
Returns:
2829
str: Generated Python Pydantic models as a string.
@@ -36,13 +37,20 @@ def generate_instrument_configs(ins_s: str) -> str:
3637
template = j_env.get_template("instruments.jinja")
3738
ins_data = json.loads(ins_s)
3839
instruments = []
40+
if soar:
41+
prefix = ""
42+
filtered = {k: v for k, v in ins_data.items() if "soar" in k.lower()}
43+
else:
44+
prefix = "Lco"
45+
filtered = {k: v for k, v in ins_data.items() if "soar" not in k.lower()}
46+
3947
# Instruments endpoint seems inconsistent, this should keep our output consistent
40-
ordered = dict(sorted(ins_data.items()))
48+
ordered = dict(sorted(filtered.items()))
4149
for instrument_type, ins in ordered.items():
4250
instruments.append(
4351
{
4452
"instrument_type": instrument_type,
45-
"class_name": f"Lco{textcase.pascal(instrument_type)}",
53+
"class_name": f"{prefix}{textcase.pascal(instrument_type)}",
4654
"config_types": [
4755
c["code"] for c in ins["configuration_types"].values()
4856
],
@@ -58,11 +66,15 @@ def generate_instrument_configs(ins_s: str) -> str:
5866
}
5967
)
6068

61-
return template.render(instruments=instruments)
69+
return template.render(instruments=instruments, soar=soar)
6270

6371

6472
if __name__ == "__main__":
73+
try:
74+
soar = sys.argv.pop(1) == "soar"
75+
except IndexError:
76+
soar = False
6577
# Accepts input from stdin or a file argument
6678
with fileinput.input() as f:
6779
ins_json = "".join(list(f))
68-
sys.stdout.write(generate_instrument_configs(ins_json))
80+
sys.stdout.write(generate_instrument_configs(ins_json, soar=soar))

codegen/lco/templates/instruments.jinja

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ from aeonlib.models import SiderealTarget, NonSiderealTarget
88
from aeonlib.ocs.target_models import Constraints
99
from aeonlib.ocs.config_models import Roi
1010

11+
{% if soar %}
12+
{% set obs = "SOAR" %}
13+
{% else %}
14+
{% set obs = "LCO" %}
15+
{% endif %}
1116

1217
{% for ctx in instruments %}
1318
class {{ ctx.class_name }}OpticalElements(BaseModel):
@@ -70,7 +75,7 @@ class {{ ctx.class_name }}(BaseModel):
7075

7176
{% endfor %}
7277
# Export a type that encompasses all instruments
73-
LCO_INSTRUMENTS = Union[
78+
{{ obs }}_INSTRUMENTS = Union[
7479
{% for ctx in instruments %}
7580
{{ ctx.class_name }},
7681
{% endfor %}

src/aeonlib/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ class Settings(BaseSettings):
88
lco_token: str = ""
99
lco_api_root: str = "https://observe.lco.global/api/"
1010

11+
# SOAR
12+
soar_token: str = ""
13+
soar_api_root: str = "https://observe.lco.global/api/"
14+
1115
# European Southern Observatory
1216
eso_environment: str = "demo"
1317
eso_username: str = ""

src/aeonlib/ocs/lco/facility.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ def validate_request_group(
6565
response = self.client.post("/requestgroups/validate/", json=payload)
6666
response = response.json()
6767
logger.debug("<- %s", response)
68-
if response["request_durations"]:
68+
if response.get("request_durations"):
6969
return True, []
7070
else:
71-
return False, response["errors"]
71+
return False, response.get("errors", [str(response)])
7272

7373
def submit_request_group(
7474
self, request_group: RequestGroup

0 commit comments

Comments
 (0)