Skip to content

Commit

Permalink
Merge 1c42a4e into 4d2ef3e
Browse files Browse the repository at this point in the history
  • Loading branch information
JackEAllen committed Jun 5, 2024
2 parents 4d2ef3e + 1c42a4e commit bbac521
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#2216: Add Wavelength, ToF and Energy unit conversions to Spectrum Viewer CSV Output
6 changes: 5 additions & 1 deletion mantidimaging/core/io/csv_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class CSVOutput:
def __init__(self) -> None:
self.columns: dict[str, np.ndarray] = {}
self.num_rows: int | None = None
self.units: dict[str, str] = {}

def add_column(self, name: str, values: np.ndarray) -> None:
as_column = values.reshape((-1, 1))
Expand All @@ -24,5 +25,8 @@ def add_column(self, name: str, values: np.ndarray) -> None:

def write(self, outstream: IO[str]) -> None:
header = ",".join(self.columns.keys())
if self.units:
units = ",".join(self.units.values()) + ",Counts" * (len(self.columns) - len(self.units))
outstream.write("# " + header + "\n" + units + "\n" if self.units else "# " + header + "\n")
data = np.hstack(list(self.columns.values()))
np.savetxt(outstream, data, header=header, fmt="%s", delimiter=",")
np.savetxt(outstream, data, fmt="%s", delimiter=",")
16 changes: 14 additions & 2 deletions mantidimaging/gui/windows/spectrum_viewer/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,18 @@ def save_csv(self, path: Path, normalized: bool) -> None:

csv_output = CSVOutput()
csv_output.add_column("tof_index", np.arange(self._stack.data.shape[0]))
self.tof_data = self.get_stack_time_of_flight()
if self.tof_data is not None:
self.units.set_data_to_convert(self.tof_data)
csv_output.units = {
"ToF_index": "#",
"Wavelength": "Angstrom",
"ToF": "Microseconds",
"Energy": "MeV",
}
csv_output.add_column("Wavelength", self.units.tof_seconds_to_wavelength_in_angstroms())
csv_output.add_column("ToF", self.units.tof_seconds_to_us())
csv_output.add_column("Energy", self.units.tof_seconds_to_energy())

for roi_name in self.get_list_of_roi_names():
csv_output.add_column(roi_name, self.get_spectrum(roi_name, SpecType.SAMPLE))
Expand Down Expand Up @@ -506,9 +518,9 @@ def set_tof_unit_mode_for_stack(self) -> None:
self.tof_mode = ToFUnitMode.IMAGE_NUMBER
self.presenter.change_selected_menu_option("Image Index")
elif self.tof_mode == ToFUnitMode.ENERGY:
self.presenter.change_selected_menu_option("Energy")
self.presenter.change_selected_menu_option("Energy MEV")
elif self.tof_mode == ToFUnitMode.TOF_US:
self.presenter.change_selected_menu_option("Time of Flight (\u03BCs)")
self.presenter.change_selected_menu_option("Time of Flight")
else:
self.tof_mode = ToFUnitMode.WAVELENGTH
self.presenter.change_selected_menu_option("Wavelength")
29 changes: 25 additions & 4 deletions mantidimaging/gui/windows/spectrum_viewer/test/model_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ def setUp(self) -> None:
def _set_sample_stack(self, with_tof=False):
spectrum = np.arange(0, 10)
stack = ImageStack(np.ones([10, 11, 12]) * spectrum.reshape((10, 1, 1)))
self.model.set_stack(stack)
self.model.set_new_roi("roi")
if with_tof:
mock_inst_log = mock.create_autospec(InstrumentLog, source_file="")
mock_inst_log.get_column.return_value = np.arange(0, 10) * 0.1
stack.log_file = mock_inst_log
self.model.set_stack(stack)
self.model.set_new_roi("roi")
stack.tof = np.arange(0, 10) * 0.1
return stack, spectrum

def _make_mock_path_stream(self):
Expand Down Expand Up @@ -182,7 +183,7 @@ def test_save_csv(self):
self.model.save_csv(mock_path, False)

mock_path.open.assert_called_once_with("w")
self.assertIn("# tof_index,all,roi", mock_stream.captured[0])
self.assertIn("tof_index,all,roi", mock_stream.captured[0])
self.assertIn("0.0,0.0,0.0", mock_stream.captured[1])
self.assertIn("1.0,2.0,2.0", mock_stream.captured[2])
self.assertTrue(mock_stream.is_closed)
Expand Down Expand Up @@ -319,11 +320,31 @@ def test_save_csv_norm(self):
self.model.save_csv(mock_path, True)

mock_path.open.assert_called_once_with("w")
self.assertIn("# tof_index,all,all_open,all_norm,roi,roi_open,roi_norm", mock_stream.captured[0])
self.assertIn("tof_index,all,all_open,all_norm,roi,roi_open,roi_norm", mock_stream.captured[0])
self.assertIn("0.0,0.0,2.0,0.0,0.0,2.0,0.0", mock_stream.captured[1])
self.assertIn("1.0,1.0,2.0,0.5,1.0,2.0,0.5", mock_stream.captured[2])
self.assertTrue(mock_stream.is_closed)

def test_save_csv_norm_with_tof_loaded(self):
stack, _ = self._set_sample_stack(with_tof=True)
norm = ImageStack(np.full([10, 11, 12], 2))
stack.data[:, :, :5] *= 2
self.model.set_normalise_stack(norm)

mock_stream, mock_path = self._make_mock_path_stream()
with mock.patch.object(self.model, "save_roi_coords"):
self.model.save_csv(mock_path, True)

mock_path.open.assert_called_once_with("w")
self.assertIn("tof_index,Wavelength,ToF,Energy,all,all_open,all_norm,roi,roi_open,roi_norm",
mock_stream.captured[0])
self.assertIn("#,Angstrom,Microseconds,MeV,Counts,Counts,Counts", mock_stream.captured[1])
self.assertIn("0.0,0.0,0.0,inf,0.0,2.0,0.0,0.0,2.0,0.0", mock_stream.captured[2])
self.assertIn(
"1.0,7.064346392065392,100000.0,2.9271405738026552,1.4166666666666667,2.0,0.7083333333333334,1.4166666666666667,2.0,0.7083333333333334",
mock_stream.captured[3])
self.assertTrue(mock_stream.is_closed)

def test_WHEN_roi_name_generator_called_THEN_correct_names_returned_visible_to_model(self):
self.assertEqual(self.model.roi_name_generator(), "roi")
self.assertEqual(self.model.roi_name_generator(), "roi_1")
Expand Down

0 comments on commit bbac521

Please sign in to comment.