Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
path: backend/dist/

publish-to-pypi:
name: Publish IMAS-IBEX distribution to PyPI
Expand Down
2 changes: 1 addition & 1 deletion backend/ibex/core/ibex_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def get_data(uri: str, downsampling_method: str | None, downsampled_size: int, r
occurrence=uri_obj.occurrence,
downsampling_method=downsampling_method,
downsampled_size=downsampled_size,
range=range
range=range,
)


Expand Down
11 changes: 5 additions & 6 deletions backend/ibex/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,19 @@ class DownsamplingMethods(Enum):
"name": "Min-Max",
"description": "Selects the minimum and maximum value in each bin",
"function": MinMaxDownsampler().downsample,
"validation" : (lambda target_size : target_size%2 == 0, "Min-Max downsampling target size must be even"),
"validation": (lambda target_size: target_size % 2 == 0, "Min-Max downsampling target size must be even"),
}
M4 = {
"name": "M4",
"description": "Selects the minimum, maximum, first, and last value in each bin",
"function": M4Downsampler().downsample,
"validation": (lambda target_size: target_size%4 == 0, "M4 downsampling target size must be divisible by 4"),
"validation": (lambda target_size: target_size % 4 == 0, "M4 downsampling target size must be divisible by 4"),
}
LTTB = {
"name": "LTTB",
"description": "Implements the Largest Triangle Three Buckets (LTTB) algorithm",
"function": LTTBDownsampler().downsample,
"validation": (lambda target_size: target_size>=3, "Minimum downsampling size for LTTB is 3"),
"validation": (lambda target_size: target_size >= 3, "Minimum downsampling size for LTTB is 3"),
}
MIN_MAX_LTTB = {
"name": "Min-Max LTTB",
Expand All @@ -146,13 +146,12 @@ def _missing_(cls, name):
raise ValueError(f"Downsampling method: {name} is not recognised by IBEX backend")

@classmethod
def validate_downsampling_target_size(cls, method : dict, target_size : int):
if "validation" in method.keys():
def validate_downsampling_target_size(cls, method: dict, target_size: int):
if "validation" in method.keys():
if not method["validation"][0](target_size):
raise InvalidParametersException(method["validation"][1])



def downsample_data(data: List, target_size: int, method: str | None = None, x=None, single_x_axis=True):
"""
Downsamples list of values
Expand Down
10 changes: 6 additions & 4 deletions backend/ibex/data_source/imas_python_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def _get_raw_data(self, ids_obj: IDSBase, path_elements: List[IDSPath] | None):
new_ids_obj = ids_obj[f"{path_node_name}[{path_index}]"]
except AttributeError as e:
raise NodeNotFoundException(e)
except IndexError as e:
except IndexError:
message = f"Index out of range: {path_node_name} has no index {path_index}"
raise NodeNotFoundException(message)
return self._get_raw_data(new_ids_obj, path_elements[1:])
Expand Down Expand Up @@ -822,7 +822,6 @@ def get_plot_data(
coordinate["coordinates"] = new_shape_factors_list
return result


def _is_empty(self, seq):
"""Checks if list is essentially empty (contains only empty lists or empty strings)"""
if isinstance(seq, (IDSNumericArray, IDSString0D, IDSString1D, IDSComplex0D, IDSFloat0D, IDSInt0D)):
Expand All @@ -841,11 +840,14 @@ def _replace_empty_numbers(self, arr, replace_to=np.nan):
if isinstance(x, list):
self._replace_empty_numbers(x, replace_to)
else:

try:
if not x.has_value:
arr[i] = replace_to
# exception occurs for numpy values e.g. numpy.float64
except AttributeError:
if x == imas.ids_defs.EMPTY_FLOAT or x == imas.ids_defs.EMPTY_INT or x == imas.ids_defs.EMPTY_COMPLEX:
if (
x == imas.ids_defs.EMPTY_FLOAT
or x == imas.ids_defs.EMPTY_INT
or x == imas.ids_defs.EMPTY_COMPLEX
):
arr[i] = replace_to
2 changes: 1 addition & 1 deletion backend/ibex/setup_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class _PrettyFormatter(logging.Formatter):
white = "[white]"
reset = "[/]"

formatstr = "%(asctime)s %(levelname)-8s %(message)s " f"{light_grey}@%(filename)s:%(lineno)d{reset}"
formatstr = f"%(asctime)s %(levelname)-8s %(message)s {light_grey}@%(filename)s:%(lineno)d{reset}"
time_format = "%H:%M:%S"

FORMATS = {
Expand Down
4 changes: 2 additions & 2 deletions backend/tests/response_times.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def wrap(*args, **kw):
te = time.time()
print(f"============= {f.__name__} =============")
print(f" ARGS: {args}{kw}")
print(f" EXECUTION_TIME: {te-ts} sec")
print(f" EXECUTION_TIME: {te - ts} sec")
print(f" RECEIVED ARRAY SHAPE: {result}")
print(f" STATUS CODE: {status_code}")
print("==========================")
Expand Down Expand Up @@ -84,5 +84,5 @@ def field_value(uri):
ts = time.time()
field_value(f"{uri}{node_path.replace('[:]', slice)}")
te = time.time()
print(f" {round(te-ts,2)}".ljust(7), end="")
print(f" {round(te - ts, 2)}".ljust(7), end="")
print()
30 changes: 15 additions & 15 deletions backend/tests/test_error_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,33 @@
def test_non_existing_ids_node_info():
parameters = {"uri": "imas:hdf5?path=non_existing_path"}
response = pytest.test_client.get("/ids_info/node_info", params=parameters)
assert (
response.status_code == 404
), "node_info endpoint should return 404 when trying to open non existing pulsefile"
assert response.status_code == 404, (
"node_info endpoint should return 404 when trying to open non existing pulsefile"
)


def test_non_existing_ids_field_value():
parameters = {"uri": "imas:hdf5?path=non_existing_path"}
response = pytest.test_client.get("/data/field_value", params=parameters)
assert (
response.status_code == 404
), "node_info endpoint should return 404 when trying to open non existing pulsefile"
assert response.status_code == 404, (
"node_info endpoint should return 404 when trying to open non existing pulsefile"
)


def test_non_existing_node_ids_info(entry_path):
parameters = {"uri": f"imas:hdf5?path={entry_path}#core_profiles/non_existing_node"}
response = pytest.test_client.get("/ids_info/node_info", params=parameters)
assert (
response.status_code == 404
), "node_info endpoint should return 404 when trying to open non existing node path"
assert response.status_code == 404, (
"node_info endpoint should return 404 when trying to open non existing node path"
)


def test_non_existing_node_field_value(entry_path):
parameters = {"uri": f"imas:hdf5?path={entry_path}#core_profiles/non_existing_node"}
response = pytest.test_client.get("/data/field_value", params=parameters)
assert (
response.status_code == 404
), "node_info endpoint should return 404 when trying to open non existing node path"
assert response.status_code == 404, (
"node_info endpoint should return 404 when trying to open non existing node path"
)


def test_result_too_long(entry_path):
Expand All @@ -56,6 +56,6 @@ def test_node_is_not_leaf_array_summary(entry_path):
def test_node_is_not_array(entry_path):
parameters = {"uri": f"imas:hdf5?path={entry_path}#core_profiles/ids_properties/version_put/access_layer"}
response = pytest.test_client.get("/ids_info/array_summary", params=parameters)
assert (
response.status_code == 462
), "array_summary endpoint should return 462 when trying to get summary of non array node"
assert response.status_code == 462, (
"array_summary endpoint should return 462 when trying to get summary of non array node"
)
12 changes: 6 additions & 6 deletions backend/tests/test_ids_info_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ def test_show_error_bars_option(entry_path):

assert response.status_code == 200
for child in response.json()["children"]:
assert not any(
x in child["name"] for x in ["_error_upper", "_error_lower", "_error_index"]
), f"Error bars filtering failed. Node {child['name']} should not be returned."
assert not any(x in child["name"] for x in ["_error_upper", "_error_lower", "_error_index"]), (
f"Error bars filtering failed. Node {child['name']} should not be returned."
)

parameters = {"uri": f"imas:hdf5?path={entry_path}#core_profiles/vacuum_toroidal_field", "show_error_bars": True}
response = pytest.test_client.get("/ids_info/node_info", params=parameters)
assert response.status_code == 200
assert "r0_error_upper" in [
child["name"] for child in response.json()["children"]
], "Error bars filtering failed. 'r0_error_upper' nodes was not returned, but it should be."
assert "r0_error_upper" in [child["name"] for child in response.json()["children"]], (
"Error bars filtering failed. 'r0_error_upper' nodes was not returned, but it should be."
)
Loading