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
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Original file line number Diff line number Diff line change
Expand Up @@ -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``
Expand Down
60 changes: 0 additions & 60 deletions post-processing/tests/test_vernier_caliper.py

This file was deleted.

60 changes: 60 additions & 0 deletions post-processing/tests/test_vernier_calliper.py
Original file line number Diff line number Diff line change
@@ -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()
140 changes: 70 additions & 70 deletions post-processing/tests/test_vernier_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Loading
Loading