Skip to content

Commit f2b0f87

Browse files
Clean calculation of means and corrections
Made it easier to read and understand what the routine is doing when calculating the mean widths and intensity ratios. Put the multiple scattering and gamma corrections into its own function.
1 parent e0f79d7 commit f2b0f87

File tree

1 file changed

+78
-75
lines changed

1 file changed

+78
-75
lines changed

src/mvesuvio/oop/AnalysisRoutine.py

Lines changed: 78 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def __init__(self, workspace, ip_file, number_of_iterations, mask_spectra,
1919
gamma_correction, mode_running, transmission_guess=None, multiple_scattering_order=None,
2020
number_of_events=None, results_path=None):
2121

22-
self._name = workspace.name()
22+
self._name = workspace.name() + '_'
2323
self._ip_file = ip_file
2424
self._number_of_iterations = number_of_iterations
2525
spectrum_list = workspace.getSpectrumNumbers()
@@ -141,6 +141,11 @@ def _update_workspace_data(self):
141141
self._fit_profiles_workspaces[element] = self._create_emtpy_ncp_workspace(f'_{element}_ncp')
142142
self._fit_profiles_workspaces['total'] = self._create_emtpy_ncp_workspace(f'_total_ncp')
143143

144+
self._mean_widths = None
145+
self._std_widths = None
146+
self._mean_intensity_ratios = None
147+
self._std_intensity_ratios = None
148+
144149

145150
def _create_emtpy_ncp_workspace(self, suffix):
146151
return CreateWorkspace(
@@ -175,60 +180,46 @@ def run(self):
175180
# InputWorkspace=ic.sampleWS, OutputWorkspace=initialWs.name()
176181
# )
177182

178-
CloneWorkspace(
183+
RenameWorkspace(
179184
InputWorkspace=self._workspace_being_fit.name(),
180-
OutputWorkspace=self._workspace_being_fit.name() + "0"
185+
OutputWorkspace=self._name + '0'
181186
)
182187

183188
for iteration in range(self._number_of_iterations + 1):
184-
# Workspace from previous iteration
185-
self._workspace_being_fit = mtd[self._name + str(iteration)]
186189

190+
self._workspace_being_fit = mtd[self._name + str(iteration)]
187191
self._update_workspace_data()
188192

189193
self._fit_neutron_compton_profiles()
190194

191195
self._create_summed_workspaces()
192-
193-
mWidths, stdWidths, mIntRatios, stdIntRatios = self.extractMeans()
194-
195-
self.createMeansAndStdTableWS(
196-
mWidths, stdWidths, mIntRatios, stdIntRatios
197-
)
196+
self._set_means_and_std()
198197

199198
# When last iteration, skip MS and GC
200199
if iteration == self._number_of_iterations:
201200
break
202201

202+
# Do this because MS and Gamma corrections do not accept zero columns
203203
if iteration==0:
204204
self._replace_zero_columns_with_ncp_fit()
205205

206-
CloneWorkspace(InputWorkspace=self._name, OutputWorkspace="tmpNameWs")
207-
208-
if self._gamma_correction:
209-
wsGC = self.createWorkspacesForGammaCorrection(mWidths, mIntRatios)
210-
Minus(
211-
LHSWorkspace="tmpNameWs", RHSWorkspace=wsGC, OutputWorkspace="tmpNameWs"
212-
)
213-
214-
if self._multiple_scattering_correction:
215-
wsMS = self.createWorkspacesForMSCorrection(mWidths, mIntRatios)
216-
Minus(
217-
LHSWorkspace="tmpNameWs", RHSWorkspace=wsMS, OutputWorkspace="tmpNameWs"
218-
)
206+
CloneWorkspace(
207+
InputWorkspace=self._workspace_for_corrections.name(),
208+
OutputWorkspace="next_iteration"
209+
)
210+
self._correct_for_gamma_and_multiple_scattering("next_iteration")
211+
self._remask_columns_with_zeros("next_iteration")
219212

220-
self._remask_columns_with_zeros("tmpNameWS")
221213
RenameWorkspace(
222-
InputWorkspace="tmpNameWs", OutputWorkspace=self._name + str(iteration + 1)
214+
InputWorkspace="next_iteration",
215+
OutputWorkspace=self._name + str(iteration + 1)
223216
)
224217

225-
self._set_up_results_mehtods()
218+
self._set_results()
226219
self.save_results()
227220
return self
228221

229222

230-
231-
232223
def createTableInitialParameters(self):
233224
meansTableWS = CreateEmptyTableWorkspace(
234225
OutputWorkspace=self._name + "_Initial_Parameters"
@@ -265,9 +256,7 @@ def _fit_neutron_compton_profiles(self):
265256
self._fit_neutron_compton_profiles_to_row()
266257
self._row_being_fit += 1
267258

268-
assert ~np.all(
269-
self._fit_parameters == 0
270-
), "Fitting parameters cannot be zero for all spectra!"
259+
assert np.any(self._fit_parameters), "Fitting parameters cannot be zero for all spectra!"
271260
return
272261

273262

@@ -396,8 +385,8 @@ def _create_summed_workspaces(self):
396385
OutputWorkspace=ws.name() + "_Sum"
397386
)
398387

399-
def extractMeans(self):
400-
"""Extract widths and intensities from tableWorkspace"""
388+
def _set_means_and_std(self):
389+
"""Calculate mean widths and intensities from tableWorkspace"""
401390

402391
fitParsTable = self._table_fit_results
403392
widths = np.zeros((self._masses.size, fitParsTable.rowCount()))
@@ -413,35 +402,40 @@ def extractMeans(self):
413402
) = self.calculateMeansAndStds(widths, intensities)
414403

415404
assert (
416-
len(widths) == self._masses.size
417-
), "Widths and intensities must be in shape (noOfMasses, noOfSpec)"
418-
return meanWidths, stdWidths, meanIntensityRatios, stdIntensityRatios
405+
len(meanWidths) == len(self._profiles)
406+
), "Number of mean widths must match number of profiles!"
407+
408+
self._mean_widths = meanWidths
409+
self._std_widths = stdWidths
410+
self._mean_intensity_ratios = meanIntensityRatios
411+
self._std_intensity_ratios = stdIntensityRatios
419412

413+
self.createMeansAndStdTableWS()
414+
return
420415

421-
def createMeansAndStdTableWS(
422-
self, meanWidths, stdWidths, meanIntensityRatios, stdIntensityRatios
423-
):
416+
417+
def createMeansAndStdTableWS(self):
424418
meansTableWS = CreateEmptyTableWorkspace(
425-
OutputWorkspace=self._workspace_being_fit.name() + "_Mean_Widths_And_Intensities"
419+
OutputWorkspace=self._workspace_being_fit.name() + "_MeanWidthsAndIntensities"
426420
)
427-
meansTableWS.addColumn(type="float", name="Mass")
421+
meansTableWS.addColumn(type="str", name="Mass")
428422
meansTableWS.addColumn(type="float", name="Mean Widths")
429423
meansTableWS.addColumn(type="float", name="Std Widths")
430424
meansTableWS.addColumn(type="float", name="Mean Intensities")
431425
meansTableWS.addColumn(type="float", name="Std Intensities")
432426

433427
print("\nCreated Table with means and std:")
434428
print("\nMass Mean \u00B1 Std Widths Mean \u00B1 Std Intensities\n")
435-
for m, mw, stdw, mi, stdi in zip(
436-
self._masses.astype(float),
437-
meanWidths,
438-
stdWidths,
439-
meanIntensityRatios,
440-
stdIntensityRatios,
429+
for p, mean_width, std_width, mean_intensity, std_intensity in zip(
430+
self._profiles.values(),
431+
self._mean_widths,
432+
self._std_widths,
433+
self._mean_intensity_ratios,
434+
self._std_intensity_ratios,
441435
):
442-
meansTableWS.addRow([m, mw, stdw, mi, stdi])
443-
print(f"{m:5.2f} {mw:10.5f} \u00B1 {stdw:7.5f} {mi:10.5f} \u00B1 {stdi:7.5f}")
444-
print("\n")
436+
meansTableWS.addRow([p.label, mean_width, std_width, mean_intensity, std_intensity])
437+
print(f"{p.label:5s} {mean_width:10.5f} \u00B1 {std_width:7.5f} \
438+
{mean_intensity:10.5f} \u00B1 {std_intensity:7.5f}\n")
445439
return
446440

447441

@@ -737,15 +731,14 @@ def _replace_zero_columns_with_ncp_fit(self):
737731

738732
self._zero_columns_mask = np.all(dataY == 0, axis=0) # Masked Cols
739733

740-
ws = CloneWorkspace(
734+
self._workspace_for_corrections = CloneWorkspace(
741735
InputWorkspace=self._workspace_for_corrections.name(),
742736
OutputWorkspace=self._workspace_for_corrections.name() + "_CorrectionsInput"
743737
)
744-
for row in range(ws.getNumberHistograms()):
738+
for row in range(self._workspace_for_corrections.getNumberHistograms()):
745739
# TODO: Once the option to chage point to hist is removed, remove [:len(ncp)]
746-
ws.dataY(row)[self._zero_columns_mask] = ncp[row, self._zero_columns_mask[:len(ncp[row])]]
740+
self._workspace_for_corrections.dataY(row)[self._zero_columns_mask] = ncp[row, self._zero_columns_mask[:len(ncp[row])]]
747741

748-
self._workspace_for_corrections = ws
749742
SumSpectra(
750743
InputWorkspace=self._workspace_for_corrections.name(),
751744
OutputWorkspace=self._workspace_for_corrections.name() + "_Sum"
@@ -759,29 +752,39 @@ def _remask_columns_with_zeros(self, ws_to_remask_name):
759752
initial workspace to set these columns again to zero on the
760753
workspace resulting from the multiple scattering or gamma correction.
761754
"""
762-
ws = mtd[ws_to_remask_name]
763-
for row in range(ws.getNumberHistograms()):
764-
ws.dataY(row)[self._zero_columns_mask] = 0
765-
ws.dataE(row)[self._zero_columns_mask] = 0
766-
# dataX, dataY, dataE = extractWS(ws)
767-
# mask = np.all(dataY == 0, axis=0)
768-
#
769-
# wsM = mtd[wsToMaskName]
770-
# dataXM, dataYM, dataEM = extractWS(wsM)
771-
# dataYM[:, mask] = 0
772-
# if np.all(dataE == 0):
773-
# dataEM = np.zeros(dataEM.shape)
774-
#
775-
# passDataIntoWS(dataXM, dataYM, dataEM, wsM)
755+
ws_to_remask = mtd[ws_to_remask_name]
756+
for row in range(ws_to_remask.getNumberHistograms()):
757+
ws_to_remask.dataY(row)[self._zero_columns_mask] = 0
758+
ws_to_remask.dataE(row)[self._zero_columns_mask] = 0
759+
return
760+
761+
762+
def _correct_for_gamma_and_multiple_scattering(self, ws_name):
763+
764+
if self._gamma_correction:
765+
gamma_correction_ws = self.create_gamma_workspaces()
766+
Minus(
767+
LHSWorkspace=ws_name,
768+
RHSWorkspace=gamma_correction_ws.name(),
769+
OutputWorkspace=ws_name
770+
)
771+
772+
if self._multiple_scattering_correction:
773+
multiple_scattering_ws = self.create_multiple_scattering_workspaces()
774+
Minus(
775+
LHSWorkspace=ws_name,
776+
RHSWorkspace=multiple_scattering_ws.name(),
777+
OutputWorkspace=ws_name
778+
)
776779
return
777780

778781

779-
def createWorkspacesForMSCorrection(self, meanWidths, meanIntensityRatios):
782+
def create_multiple_scattering_workspaces(self):
780783
"""Creates _MulScattering and _TotScattering workspaces used for the MS correction"""
781784

782785
self.createSlabGeometry(self._workspace_for_corrections) # Sample properties for MS correction
783786

784-
sampleProperties = self.calcMSCorrectionSampleProperties(meanWidths, meanIntensityRatios)
787+
sampleProperties = self.calcMSCorrectionSampleProperties(self._mean_widths, self._mean_intensity_ratios)
785788
print(
786789
"\nThe sample properties for Multiple Scattering correction are:\n\n",
787790
sampleProperties,
@@ -884,12 +887,12 @@ def createMulScatWorkspaces(self, ws, sampleProperties):
884887
return mtd[ws.name() + "_MulScattering"]
885888

886889

887-
def createWorkspacesForGammaCorrection(self, meanWidths, meanIntensityRatios):
890+
def create_gamma_workspaces(self):
888891
"""Creates _gamma_background correction workspace to be subtracted from the main workspace"""
889892

890893
inputWS = self._workspace_for_corrections.name()
891894

892-
profiles = self.calcGammaCorrectionProfiles(meanWidths, meanIntensityRatios)
895+
profiles = self.calcGammaCorrectionProfiles(self._mean_widths, self._mean_intensity_ratios)
893896

894897
# Approach below not currently suitable for current versions of Mantid, but will be in the future
895898
# background, corrected = VesuvioCalculateGammaBackground(InputWorkspace=inputWS, ComptonFunction=profiles)
@@ -937,7 +940,7 @@ def calcGammaCorrectionProfiles(self, meanWidths, meanIntensityRatios):
937940
return profiles
938941

939942

940-
def _set_up_results_mehtods(self):
943+
def _set_results(self):
941944
"""Used to collect results from workspaces and store them in .npz files for testing."""
942945

943946
self.wsFinal = mtd[self._name + str(self._number_of_iterations)]
@@ -981,7 +984,7 @@ def _set_up_results_mehtods(self):
981984
allIterNcp.append(allNCP)
982985

983986
# Extract Mean and Std Widths, Intensities
984-
meansTable = mtd[wsIterName + "_Mean_Widths_And_Intensities"]
987+
meansTable = mtd[wsIterName + "_MeanWidthsAndIntensities"]
985988
allMeanWidhts.append(meansTable.column("Mean Widths"))
986989
allStdWidths.append(meansTable.column("Std Widths"))
987990
allMeanIntensities.append(meansTable.column("Mean Intensities"))

0 commit comments

Comments
 (0)