diff --git a/CMakeLists.txt b/CMakeLists.txt index f5d8fdd1..c1971ef7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,11 +60,11 @@ include(cmake/Installation.cmake) # Allow the maximum label sizes to be tuned if(STRING_LENGTH) if(STRING_LENGTH GREATER_EQUAL 100) - message(STATUS "Max caliper label length is ${STRING_LENGTH}") + message(STATUS "Max calliper label length is ${STRING_LENGTH}") target_compile_definitions(${CMAKE_PROJECT_NAME} INTERFACE PROF_STRING_BUFFER_LENGTH=${STRING_LENGTH}) else() - message(WARNING "Max caliper label length is too small - using 100") + message(WARNING "Max calliper label length is too small - using 100") endif() endif() diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 49d30270..2836b94a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -3,3 +3,4 @@ | GitHub user | Real Name | Affiliation | Date | |-----------------|------------------|-------------|------------| | andrewcoughtrie | Andrew Coughtrie | Met Office | 2026-03-05 | +| mo-marqh | mark Hedley | Met Office | 2026-03-10 | diff --git a/documentation/Sphinx/user_guide/build-guide/build-guide.rst b/documentation/Sphinx/user_guide/build-guide/build-guide.rst index 94229035..af9b643b 100644 --- a/documentation/Sphinx/user_guide/build-guide/build-guide.rst +++ b/documentation/Sphinx/user_guide/build-guide/build-guide.rst @@ -97,7 +97,7 @@ up a terminal wherein the user can change build options interactively. dynamically (``ON``). * - ``-DSTRING_LENGTH`` - *INTEGER* - - Maximum length of a caliper label. This defaults to 100 + - Maximum length of a calliper label. This defaults to 100 characters. If the maximum length is exceeded, Vernier will cause the application to exit with an error. * - ``-DENABLE_MPI`` diff --git a/post-processing/tests/test_vernier_caliper.py b/post-processing/tests/test_vernier_caliper.py deleted file mode 100644 index a868e01c..00000000 --- a/post-processing/tests/test_vernier_caliper.py +++ /dev/null @@ -1,60 +0,0 @@ -# ------------------------------------------------------------------------------ -# (c) Crown copyright Met Office. All rights reserved. -# The file LICENCE, distributed with this code, contains details of the terms -# under which the code may be used. -# ------------------------------------------------------------------------------ -import unittest -from pathlib import Path -import sys -sys.path.append(str(Path(__file__).parent.parent)) -from vernier.vernier_data import VernierCaliper - -class TestVernierCaliper(unittest.TestCase): - - def setUp(self): - self.caliper_a = VernierCaliper("test_caliper_a") - self.caliper_b = VernierCaliper("test_caliper_b") - - def test_init(self): - self.assertEqual(self.caliper_a.name, "test_caliper_a") - self.assertEqual(self.caliper_a.time_percent, []) - self.assertEqual(self.caliper_a.cumul_time, []) - self.assertEqual(self.caliper_a.self_time, []) - self.assertEqual(self.caliper_a.total_time, []) - self.assertEqual(self.caliper_a.n_calls, []) - - def test_reduce(self): - self.caliper_a.time_percent = [10.0, 20.0] - self.caliper_a.cumul_time = [30.0, 40.0] - self.caliper_a.self_time = [5.0, 15.0] - self.caliper_a.total_time = [25.0, 35.0] - self.caliper_a.n_calls = [2, 2] - - reduced_data = self.caliper_a.reduce() - self.assertEqual(reduced_data[0], "test_caliper_a") - self.assertEqual(reduced_data[1], 30.0) - self.assertEqual(reduced_data[2], 10.0) - self.assertEqual(reduced_data[3], 35.0) - self.assertEqual(reduced_data[4], 2) - self.assertEqual(reduced_data[5], 15.0) - self.assertEqual(reduced_data[6], 15.0) - - def test_compare(self): - self.caliper_a.time_percent = [10.0, 20.0] - self.caliper_a.cumul_time = [30.0, 40.0] - self.caliper_a.self_time = [5.0, 15.0] - self.caliper_a.total_time = [25.0, 35.0] - self.caliper_a.n_calls = [2, 2] - - self.caliper_b.time_percent = [12.0, 25.0] - self.caliper_b.cumul_time = [35.0, 46.0] - self.caliper_b.self_time = [6.0, 19.0] - self.caliper_b.total_time = [28.0, 39.0] - self.caliper_b.n_calls = [2, 2] - - self.assertTrue(self.caliper_a < self.caliper_b) - self.assertFalse(self.caliper_a > self.caliper_b) - self.assertFalse(self.caliper_a == self.caliper_b) - -if __name__ == '__main__': - unittest.main() diff --git a/post-processing/tests/test_vernier_calliper.py b/post-processing/tests/test_vernier_calliper.py new file mode 100644 index 00000000..a69a9225 --- /dev/null +++ b/post-processing/tests/test_vernier_calliper.py @@ -0,0 +1,60 @@ +# ------------------------------------------------------------------------------ +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +# ------------------------------------------------------------------------------ +import unittest +from pathlib import Path +import sys +sys.path.append(str(Path(__file__).parent.parent)) +from vernier.vernier_data import VernierCalliper + +class TestVernierCalliper(unittest.TestCase): + + def setUp(self): + self.calliper_a = VernierCalliper("test_calliper_a") + self.calliper_b = VernierCalliper("test_calliper_b") + + def test_init(self): + self.assertEqual(self.calliper_a.name, "test_calliper_a") + self.assertEqual(self.calliper_a.time_percent, []) + self.assertEqual(self.calliper_a.cumul_time, []) + self.assertEqual(self.calliper_a.self_time, []) + self.assertEqual(self.calliper_a.total_time, []) + self.assertEqual(self.calliper_a.n_calls, []) + + def test_reduce(self): + self.calliper_a.time_percent = [10.0, 20.0] + self.calliper_a.cumul_time = [30.0, 40.0] + self.calliper_a.self_time = [5.0, 15.0] + self.calliper_a.total_time = [25.0, 35.0] + self.calliper_a.n_calls = [2, 2] + + reduced_data = self.calliper_a.reduce() + self.assertEqual(reduced_data[0], "test_calliper_a") + self.assertEqual(reduced_data[1], 30.0) + self.assertEqual(reduced_data[2], 10.0) + self.assertEqual(reduced_data[3], 35.0) + self.assertEqual(reduced_data[4], 2) + self.assertEqual(reduced_data[5], 15.0) + self.assertEqual(reduced_data[6], 15.0) + + def test_compare(self): + self.calliper_a.time_percent = [10.0, 20.0] + self.calliper_a.cumul_time = [30.0, 40.0] + self.calliper_a.self_time = [5.0, 15.0] + self.calliper_a.total_time = [25.0, 35.0] + self.calliper_a.n_calls = [2, 2] + + self.calliper_b.time_percent = [12.0, 25.0] + self.calliper_b.cumul_time = [35.0, 46.0] + self.calliper_b.self_time = [6.0, 19.0] + self.calliper_b.total_time = [28.0, 39.0] + self.calliper_b.n_calls = [2, 2] + + self.assertTrue(self.calliper_a < self.calliper_b) + self.assertFalse(self.calliper_a > self.calliper_b) + self.assertFalse(self.calliper_a == self.calliper_b) + +if __name__ == '__main__': + unittest.main() diff --git a/post-processing/tests/test_vernier_data.py b/post-processing/tests/test_vernier_data.py index 3513b20c..d1c0dd66 100644 --- a/post-processing/tests/test_vernier_data.py +++ b/post-processing/tests/test_vernier_data.py @@ -18,124 +18,124 @@ class TestVernierData(unittest.TestCase): def setUp(self): self.test_data = VernierData() - def test_add_empty_caliper(self): - self.test_data.add_caliper("test_caliper") - self.assertIn("test_caliper", self.test_data.data) - self.assertEqual(self.test_data.data["test_caliper"].time_percent, []) - self.assertEqual(self.test_data.data["test_caliper"].cumul_time, []) - self.assertEqual(self.test_data.data["test_caliper"].self_time, []) - self.assertEqual(self.test_data.data["test_caliper"].total_time, []) - self.assertEqual(self.test_data.data["test_caliper"].n_calls, []) - - def test_filter_caliper(self): - self.test_data.add_caliper("timestep_caliper") - self.test_data.add_caliper("other_caliper") + def test_add_empty_calliper(self): + self.test_data.add_calliper("test_calliper") + self.assertIn("test_calliper", self.test_data.data) + self.assertEqual(self.test_data.data["test_calliper"].time_percent, []) + self.assertEqual(self.test_data.data["test_calliper"].cumul_time, []) + self.assertEqual(self.test_data.data["test_calliper"].self_time, []) + self.assertEqual(self.test_data.data["test_calliper"].total_time, []) + self.assertEqual(self.test_data.data["test_calliper"].n_calls, []) + + def test_filter_calliper(self): + self.test_data.add_calliper("timestep_calliper") + self.test_data.add_calliper("other_calliper") filtered = self.test_data.filter(["timestep"]) - self.assertIn("timestep_caliper", filtered.data) - self.assertNotIn("other_caliper", filtered.data) + self.assertIn("timestep_calliper", filtered.data) + self.assertNotIn("other_calliper", filtered.data) def test_filter_no_match(self): - self.test_data.add_caliper("timestep_caliper") + self.test_data.add_calliper("timestep_calliper") with self.assertRaises(ValueError): self.test_data.filter(["nonexistent"]) def test_filter_multiple_matches(self): - self.test_data.add_caliper("timestep_caliper_1") - self.test_data.add_caliper("timestep_caliper_2") + self.test_data.add_calliper("timestep_calliper_1") + self.test_data.add_calliper("timestep_calliper_2") filtered = self.test_data.filter(["timestep"]) - self.assertIn("timestep_caliper_1", filtered.data) - self.assertIn("timestep_caliper_2", filtered.data) + self.assertIn("timestep_calliper_1", filtered.data) + self.assertIn("timestep_calliper_2", filtered.data) def test_filter_empty_keys(self): - self.test_data.add_caliper("timestep_caliper") + self.test_data.add_calliper("timestep_calliper") with self.assertRaises(ValueError): self.test_data.filter([]) def test_write_txt_output_file(self): - self.test_data.add_caliper("test_caliper") - self.test_data.data["test_caliper"].time_percent = [10.0, 20.0] - self.test_data.data["test_caliper"].cumul_time = [30.0, 40.0] - self.test_data.data["test_caliper"].self_time = [5.0, 15.0] - self.test_data.data["test_caliper"].total_time = [25.0, 35.0] - self.test_data.data["test_caliper"].n_calls = [2] + self.test_data.add_calliper("test_calliper") + self.test_data.data["test_calliper"].time_percent = [10.0, 20.0] + self.test_data.data["test_calliper"].cumul_time = [30.0, 40.0] + self.test_data.data["test_calliper"].self_time = [5.0, 15.0] + self.test_data.data["test_calliper"].total_time = [25.0, 35.0] + self.test_data.data["test_calliper"].n_calls = [2] with tempfile.NamedTemporaryFile(delete=False) as tmp_file: self.test_data.write_txt_output(Path(tmp_file.name)) contents = Path(tmp_file.name).read_text().splitlines() - self.assertEqual("| Routine | Total time (s) | Self (s) | Cumul time (s) | No. calls | % time | Time per call (s) |", contents[0]) - self.assertEqual("| test_caliper | 30.0 | 10.0 | 35.0 | 2 | 15.0 | 15.0 |", contents[1]) + self.assertEqual("| Routine | Total time (s) | Self (s) | Cumul time (s) | No. calls | % time | Time per call (s) |", contents[0]) + self.assertEqual("| test_calliper | 30.0 | 10.0 | 35.0 | 2 | 15.0 | 15.0 |", contents[1]) def test_write_txt_output_terminal(self): - self.test_data.add_caliper("test_caliper") - self.test_data.data["test_caliper"].time_percent = [50.0, 40.0] - self.test_data.data["test_caliper"].cumul_time = [10.0, 12.0] - self.test_data.data["test_caliper"].self_time = [3.0, 4.0] - self.test_data.data["test_caliper"].total_time = [15.0, 55.0] - self.test_data.data["test_caliper"].n_calls = [2] + self.test_data.add_calliper("test_calliper") + self.test_data.data["test_calliper"].time_percent = [50.0, 40.0] + self.test_data.data["test_calliper"].cumul_time = [10.0, 12.0] + self.test_data.data["test_calliper"].self_time = [3.0, 4.0] + self.test_data.data["test_calliper"].total_time = [15.0, 55.0] + self.test_data.data["test_calliper"].n_calls = [2] write_output = StringIO() sys.stdout = write_output self.test_data.write_txt_output() sys.stdout = sys.__stdout__ - self.assertEqual("| Routine | Total time (s) | Self (s) | Cumul time (s) | No. calls | % time | Time per call (s) |", write_output.getvalue().splitlines()[0]) - self.assertEqual("| test_caliper | 35.0 | 3.5 | 11.0 | 2 | 45.0 | 17.5 |", write_output.getvalue().splitlines()[1]) + self.assertEqual("| Routine | Total time (s) | Self (s) | Cumul time (s) | No. calls | % time | Time per call (s) |", write_output.getvalue().splitlines()[0]) + self.assertEqual("| test_calliper | 35.0 | 3.5 | 11.0 | 2 | 45.0 | 17.5 |", write_output.getvalue().splitlines()[1]) def test_aggregate(self): data1 = VernierData() - data1.add_caliper("caliper_a") - data1.data["caliper_a"].time_percent = [10.0, 20.0] - data1.data["caliper_a"].cumul_time = [30.0, 40.0] - data1.data["caliper_a"].self_time = [5.0, 15.0] - data1.data["caliper_a"].total_time = [25.0, 35.0] - data1.data["caliper_a"].n_calls = [2, 2] + data1.add_calliper("calliper_a") + data1.data["calliper_a"].time_percent = [10.0, 20.0] + data1.data["calliper_a"].cumul_time = [30.0, 40.0] + data1.data["calliper_a"].self_time = [5.0, 15.0] + data1.data["calliper_a"].total_time = [25.0, 35.0] + data1.data["calliper_a"].n_calls = [2, 2] data2 = VernierData() - data2.add_caliper("caliper_a") - data2.data["caliper_a"].time_percent = [15.0, 25.0] - data2.data["caliper_a"].cumul_time = [35.0, 45.0] - data2.data["caliper_a"].self_time = [6.0, 16.0] - data2.data["caliper_a"].total_time = [28.0, 38.0] - data2.data["caliper_a"].n_calls = [3, 3] + data2.add_calliper("calliper_a") + data2.data["calliper_a"].time_percent = [15.0, 25.0] + data2.data["calliper_a"].cumul_time = [35.0, 45.0] + data2.data["calliper_a"].self_time = [6.0, 16.0] + data2.data["calliper_a"].total_time = [28.0, 38.0] + data2.data["calliper_a"].n_calls = [3, 3] aggregated = aggregate([data1, data2]) - self.assertIn("caliper_a", aggregated.data) - self.assertEqual(aggregated.data["caliper_a"].time_percent, [10.0, 20.0, 15.0, 25.0]) - self.assertEqual(aggregated.data["caliper_a"].cumul_time, [30.0, 40.0, 35.0, 45.0]) - self.assertEqual(aggregated.data["caliper_a"].self_time, [5.0, 15.0, 6.0, 16.0]) - self.assertEqual(aggregated.data["caliper_a"].total_time, [25.0, 35.0, 28.0, 38.0]) - self.assertEqual(aggregated.data["caliper_a"].n_calls, [2, 2, 3, 3]) + self.assertIn("calliper_a", aggregated.data) + self.assertEqual(aggregated.data["calliper_a"].time_percent, [10.0, 20.0, 15.0, 25.0]) + self.assertEqual(aggregated.data["calliper_a"].cumul_time, [30.0, 40.0, 35.0, 45.0]) + self.assertEqual(aggregated.data["calliper_a"].self_time, [5.0, 15.0, 6.0, 16.0]) + self.assertEqual(aggregated.data["calliper_a"].total_time, [25.0, 35.0, 28.0, 38.0]) + self.assertEqual(aggregated.data["calliper_a"].n_calls, [2, 2, 3, 3]) def test_aggregate_inconsistent(self): data1 = VernierData() - data1.add_caliper("caliper_a") - data1.data["caliper_a"].time_percent = [10.0, 20.0] - data1.data["caliper_a"].cumul_time = [30.0, 40.0] - data1.data["caliper_a"].self_time = [5.0, 15.0] - data1.data["caliper_a"].total_time = [25.0, 35.0] - data1.data["caliper_a"].n_calls = [2, 2] + data1.add_calliper("calliper_a") + data1.data["calliper_a"].time_percent = [10.0, 20.0] + data1.data["calliper_a"].cumul_time = [30.0, 40.0] + data1.data["calliper_a"].self_time = [5.0, 15.0] + data1.data["calliper_a"].total_time = [25.0, 35.0] + data1.data["calliper_a"].n_calls = [2, 2] data2 = VernierData() - data2.add_caliper("caliper_b") - data2.data["caliper_b"].time_percent = [15.0, 25.0] - data2.data["caliper_b"].cumul_time = [35.0, 45.0] - data2.data["caliper_b"].self_time = [6.0, 16.0] - data2.data["caliper_b"].total_time = [28.0, 38.0] - data2.data["caliper_b"].n_calls = [3, 3] + data2.add_calliper("calliper_b") + data2.data["calliper_b"].time_percent = [15.0, 25.0] + data2.data["calliper_b"].cumul_time = [35.0, 45.0] + data2.data["calliper_b"].self_time = [6.0, 16.0] + data2.data["calliper_b"].total_time = [28.0, 38.0] + data2.data["calliper_b"].n_calls = [3, 3] with self.assertRaises(ValueError): aggregate([data1, data2]) def test_aggregate_inconsistent_ok(self): data1 = VernierData() - data1.add_caliper("caliper_a") + data1.add_calliper("calliper_a") data2 = VernierData() - data2.add_caliper("caliper_b") + data2.add_calliper("calliper_b") agg_data = aggregate([data1, data2], internal_consistency=False) - self.assertIn("caliper_a", agg_data.data) - self.assertIn("caliper_b", agg_data.data) + self.assertIn("calliper_a", agg_data.data) + self.assertIn("calliper_b", agg_data.data) if __name__ == '__main__': unittest.main() diff --git a/post-processing/vernier/vernier_data.py b/post-processing/vernier/vernier_data.py index 5f774ab3..5e449c5c 100644 --- a/post-processing/vernier/vernier_data.py +++ b/post-processing/vernier/vernier_data.py @@ -10,8 +10,8 @@ from typing import Optional @dataclass(order=True) -class VernierCaliper(): - """Class to hold data for a single Vernier caliper, including arrays for each metric.""" +class VernierCalliper(): + """Class to hold data for a single Vernier calliper, including arrays for each metric.""" total_time: list[float] time_percent: list[float] @@ -32,10 +32,10 @@ def __init__(self, name: str): return def reduce(self) -> list: - """Reduces the data for this caliper to a single row of summary data.""" + """Reduces the data for this calliper to a single row of summary data.""" return [ - self.name.replace('@0', ''), # caliper name + self.name.replace('@0', ''), # calliper name round(np.mean(self.total_time), 5), # mean total time across calls round(np.mean(self.self_time), 5), # mean self time across calls round(np.mean(self.cumul_time), 5), # mean cumulative time across calls @@ -55,27 +55,27 @@ def __init__(self): return - def add_caliper(self, caliper_key: str): - """Adds a new caliper to the data structure, with empty arrays for each metric.""" + def add_calliper(self, calliper_key: str): + """Adds a new calliper to the data structure, with empty arrays for each metric.""" # Create empty data arrays - self.data[caliper_key] = VernierCaliper(caliper_key) + self.data[calliper_key] = VernierCalliper(calliper_key) - def filter(self, caliper_keys: list[str]): - """Filters the Vernier data to include only calipers matching the provided keys. + def filter(self, calliper_keys: list[str]): + """Filters the Vernier data to include only callipers matching the provided keys. The filtering is done in a glob-like fashion, so an input key of "timestep" - will match any caliper with "timestep" in its name.""" + will match any calliper with "timestep" in its name.""" filtered_data = VernierData() - # Filter data for a given caliper key + # Filter data for a given calliper key for timer in self.data.keys(): - if any(caliper_key in timer for caliper_key in caliper_keys): + if any(calliper_key in timer for calliper_key in calliper_keys): filtered_data.data[timer] = self.data[timer] if len(filtered_data.data) == 0: - raise ValueError(f"No calipers found matching the provided keys: {caliper_keys}") + raise ValueError(f"No callipers found matching the provided keys: {calliper_keys}") return filtered_data @@ -86,13 +86,13 @@ def write_txt_output(self, txt_path: Optional[Path] = None): it is printed to the terminal.""" txt_table = [] - for caliper in self.data.keys(): - txt_table.append(self.data[caliper].reduce()) + for calliper in self.data.keys(): + txt_table.append(self.data[calliper].reduce()) txt_table = sorted(txt_table, key=lambda x: x[2], reverse=True) # sort by self time, descending txt_table.insert(0, ["Routine", "Total time (s)", "Self (s)", "Cumul time (s)", "No. calls", "% time", "Time per call (s)"]) - max_caliper_len = max([len(line[0]) for line in txt_table]) + max_calliper_len = max([len(line[0]) for line in txt_table]) # Write to stdout if no path provided, otherwise write to file if txt_path is None: @@ -101,7 +101,7 @@ def write_txt_output(self, txt_path: Optional[Path] = None): out = open(txt_path, 'w') for row in txt_table: - out.write('| {:>{}} | {:>14} | {:>12} | {:>14} | {:>9} | {:>8} | {:>17} |\n'.format(row[0], max_caliper_len, *row[1:])) + out.write('| {:>{}} | {:>14} | {:>12} | {:>14} | {:>9} | {:>8} | {:>17} |\n'.format(row[0], max_calliper_len, *row[1:])) if txt_path is not None: out.close() @@ -109,27 +109,27 @@ def write_txt_output(self, txt_path: Optional[Path] = None): def aggregate(vernier_data_list: list[VernierData], internal_consistency: bool = True) -> VernierData: """ Aggregates a list of VernierData objects into a single VernierData object, - by concatenating the data for each caliper across the input objects. + by concatenating the data for each calliper across the input objects. """ aggregated = VernierData() if internal_consistency: - # Check that all input VernierData objects have the same set of calipers - caliper_sets = [set(vernier_data.data.keys()) for vernier_data in vernier_data_list] - if not all(caliper_set == caliper_sets[0] for caliper_set in caliper_sets): - raise ValueError("Input VernierData objects do not have the same set of calipers, " \ + # Check that all input VernierData objects have the same set of callipers + calliper_sets = [set(vernier_data.data.keys()) for vernier_data in vernier_data_list] + if not all(calliper_set == calliper_sets[0] for calliper_set in calliper_sets): + raise ValueError("Input VernierData objects do not have the same set of callipers, " \ "but internal_consistency is set to True.") for vernier_data in vernier_data_list: - for caliper in vernier_data.data.keys(): - if not caliper in aggregated.data: - aggregated.add_caliper(caliper) - - aggregated.data[caliper].time_percent.extend(vernier_data.data[caliper].time_percent) - aggregated.data[caliper].cumul_time.extend(vernier_data.data[caliper].cumul_time) - aggregated.data[caliper].self_time.extend(vernier_data.data[caliper].self_time) - aggregated.data[caliper].total_time.extend(vernier_data.data[caliper].total_time) - aggregated.data[caliper].n_calls.extend(vernier_data.data[caliper].n_calls) + for calliper in vernier_data.data.keys(): + if not calliper in aggregated.data: + aggregated.add_calliper(calliper) + + aggregated.data[calliper].time_percent.extend(vernier_data.data[calliper].time_percent) + aggregated.data[calliper].cumul_time.extend(vernier_data.data[calliper].cumul_time) + aggregated.data[calliper].self_time.extend(vernier_data.data[calliper].self_time) + aggregated.data[calliper].total_time.extend(vernier_data.data[calliper].total_time) + aggregated.data[calliper].n_calls.extend(vernier_data.data[calliper].n_calls) return aggregated diff --git a/post-processing/vernier/vernier_reader.py b/post-processing/vernier/vernier_reader.py index 89d20dd6..0a9355ba 100644 --- a/post-processing/vernier/vernier_reader.py +++ b/post-processing/vernier/vernier_reader.py @@ -30,20 +30,20 @@ def _load_from_file(self) -> VernierData: for line in contents: sline = line.split() if len(sline) > 0: # Line contains data - if sline[0].isdigit(): # Caliper lines start with a digit + if sline[0].isdigit(): # Calliper lines start with a digit - caliper = sline[-1] - if not caliper in loaded.data: - loaded.add_caliper(caliper) + calliper = sline[-1] + if not calliper in loaded.data: + loaded.add_calliper(calliper) - loaded.data[caliper].time_percent.append(float(sline[1])) - loaded.data[caliper].cumul_time.append(float(sline[2])) - loaded.data[caliper].self_time.append(float(sline[3])) - loaded.data[caliper].total_time.append(float(sline[4])) - loaded.data[caliper].n_calls.append(int(sline[5])) + loaded.data[calliper].time_percent.append(float(sline[1])) + loaded.data[calliper].cumul_time.append(float(sline[2])) + loaded.data[calliper].self_time.append(float(sline[3])) + loaded.data[calliper].total_time.append(float(sline[4])) + loaded.data[calliper].n_calls.append(int(sline[5])) if not loaded.data: - raise ValueError(f"No caliper data found in file '{self.path}'.") + raise ValueError(f"No calliper data found in file '{self.path}'.") return loaded