Skip to content

Commit

Permalink
Merge pull request #798 from mantidproject/11859_new_cylinder_abscor_…
Browse files Browse the repository at this point in the history
…algo

Add Python version of the indirect cylinder absorption correction routine
  • Loading branch information
FedeMPouzols committed Jun 3, 2015
2 parents c395773 + 869ac36 commit 6d43ca2
Show file tree
Hide file tree
Showing 7 changed files with 885 additions and 45 deletions.
@@ -1,13 +1,16 @@
#pylint: disable=no-init
#pylint: disable=no-init,too-many-locals,too-many-instance-attributes

from mantid.simpleapi import *
from mantid.api import PythonAlgorithm, AlgorithmFactory, PropertyMode, MatrixWorkspaceProperty, \
WorkspaceGroupProperty, InstrumentValidator, WorkspaceUnitValidator
from mantid.kernel import StringListValidator, StringMandatoryValidator, \
FloatBoundedValidator, Direction, logger, CompositeValidator
from mantid.api import (PythonAlgorithm, AlgorithmFactory, PropertyMode, MatrixWorkspaceProperty,
WorkspaceGroupProperty, InstrumentValidator, WorkspaceUnitValidator)
from mantid.kernel import (StringListValidator, StringMandatoryValidator,
FloatBoundedValidator, Direction, logger, CompositeValidator)
from mantid import config
import math, numpy as np

#pylint: disable=too-many-instance-attributes
import math
import numpy as np


class CylinderPaalmanPingsCorrection(PythonAlgorithm):

_sample_ws_name = None
Expand All @@ -25,29 +28,34 @@ class CylinderPaalmanPingsCorrection(PythonAlgorithm):
_emode = None
_efixed = 0.0
_output_ws_name = None
_elastic = None
_use_can = None
_angles = None
_beam_width = None
_beam_height = None
_waves = None
_beam_width = None
_interpolate = None
_angles = None
_waves = None
_elastic = None

#------------------------------------------------------------------------------

def category(self):
return "Workflow\\MIDAS;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections"


def summary(self):
return "Calculates absorption corrections for a cylindrical or annular sample using Paalman & Pings format."

#------------------------------------------------------------------------------

def PyInit(self):
ws_validator = CompositeValidator([WorkspaceUnitValidator('Wavelength'), InstrumentValidator()])

self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input, validator=ws_validator),
self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '',
direction=Direction.Input,
validator=ws_validator),
doc='Name for the input sample workspace')

self.declareProperty(name='SampleChemicalFormula', defaultValue='',validator=StringMandatoryValidator(),
self.declareProperty(name='SampleChemicalFormula', defaultValue='',
validator=StringMandatoryValidator(),
doc='Sample chemical formula')
self.declareProperty(name='SampleNumberDensity', defaultValue=0.1,
validator=FloatBoundedValidator(0.0),
Expand All @@ -58,9 +66,9 @@ def PyInit(self):
doc='Sample outer radius')

self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '',
direction=Direction.Input,
optional=PropertyMode.Optional,
validator=ws_validator),
direction=Direction.Input,
optional=PropertyMode.Optional,
validator=ws_validator),
doc="Name for the input container workspace")

self.declareProperty(name='CanChemicalFormula', defaultValue='',
Expand All @@ -71,14 +79,13 @@ def PyInit(self):
self.declareProperty(name='CanOuterRadius', defaultValue=0.15,
doc='Can outer radius')

self.declareProperty(name='BeamHeight', defaultValue=0.1,
self.declareProperty(name='BeamHeight', defaultValue=3.0,
doc='Height of the beam at the sample.')
self.declareProperty(name='BeamWidth', defaultValue=0.1,
self.declareProperty(name='BeamWidth', defaultValue=2.0,
doc='Width of the beam at the sample.')

self.declareProperty(name='StepSize', defaultValue=0.002,
doc='Step size for calculation')

self.declareProperty(name='Interpolate', defaultValue=True,
doc='Interpolate the correction workspaces to match the sample workspace')

Expand All @@ -88,10 +95,12 @@ def PyInit(self):
self.declareProperty(name='Efixed', defaultValue=1.0,
doc='Analyser energy')

self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '',direction=Direction.Output),
self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '',
direction=Direction.Output),
doc='The output corrections workspace group')

#pylint: disable=too-many-locals
#------------------------------------------------------------------------------

def PyExec(self):

from IndirectImport import is_supported_f2py_platform, import_f2py
Expand Down Expand Up @@ -156,11 +165,11 @@ def PyExec(self):

for angle_idx in range(number_angles):
kill, ass, assc, acsc, acc = cylabs.cylabs(self._step_size, beam, ncan, radii,
density, sigs, siga, self._angles[angle_idx],
self._elastic, self._waves, angle_idx, wrk, 0)
density, sigs, siga, self._angles[angle_idx], self._elastic, self._waves, angle_idx, wrk, 0)

if kill == 0:
logger.information('Angle %d: %f successful' % (angle_idx+1, self._angles[angle_idx]))

data_ass = np.append(data_ass, ass)
data_assc = np.append(data_assc, assc)
data_acsc = np.append(data_acsc, acsc)
Expand All @@ -170,7 +179,7 @@ def PyExec(self):
raise ValueError('Angle ' + str(angle_idx) + ' : ' + str(self._angles[angle_idx]) + ' *** failed : Error code ' + str(kill))

sample_logs = {'sample_shape': 'cylinder', 'sample_filename': self._sample_ws_name,
'sample_inner_radius': self._sample_inner_radius, 'sample_outer_radius': self._sample_outer_radius}
'sample_inner_radius': self._sample_inner_radius, 'sample_outer_radius': self._sample_outer_radius}
dataX = self._waves * number_angles

# Create the output workspaces
Expand Down Expand Up @@ -214,6 +223,7 @@ def PyExec(self):
GroupWorkspaces(InputWorkspaces=','.join(workspaces), OutputWorkspace=self._output_ws_name)
self.setPropertyValue('OutputWorkspace', self._output_ws_name)

#------------------------------------------------------------------------------

def validateInputs(self):
self._setup()
Expand All @@ -232,6 +242,7 @@ def validateInputs(self):

return issues

#------------------------------------------------------------------------------

def _setup(self):
"""
Expand Down Expand Up @@ -267,6 +278,7 @@ def _setup(self):

self._output_ws_name = self.getPropertyValue('OutputWorkspace')

#------------------------------------------------------------------------------

def _get_angles(self):
"""
Expand All @@ -283,6 +295,7 @@ def _get_angles(self):
two_theta = detector.getTwoTheta(sample_pos, beam_pos) * 180.0 / math.pi # calc angle
self._angles.append(two_theta)

#------------------------------------------------------------------------------

def _wave_range(self):
wave_range = '__WaveRange'
Expand All @@ -305,6 +318,7 @@ def _wave_range(self):
logger.information('Elastic lambda %f' % self._elastic)
DeleteWorkspace(wave_range)

#------------------------------------------------------------------------------

def _interpolate_corrections(self, workspaces):
"""
Expand All @@ -314,12 +328,13 @@ def _interpolate_corrections(self, workspaces):
@param workspaces List of correction workspaces to interpolate
"""

for wks in workspaces:
for wrksp in workspaces:
SplineInterpolation(WorkspaceToMatch=self._sample_ws_name,
WorkspaceToInterpolate=wks,
OutputWorkspace=wks,
WorkspaceToInterpolate=wrksp,
OutputWorkspace=wrksp,
OutputWorkspaceDeriv='')

#------------------------------------------------------------------------------

def _copy_detector_table(self, workspaces):
"""
Expand All @@ -330,22 +345,23 @@ def _copy_detector_table(self, workspaces):

instrument = mtd[self._sample_ws_name].getInstrument().getName()

for wks in workspaces:
LoadInstrument(Workspace=wks,
for wrksp in workspaces:
LoadInstrument(Workspace=wrksp,
InstrumentName=instrument)

CopyDetectorMapping(WorkspaceToMatch=self._sample_ws_name,
WorkspaceToRemap=wks,
WorkspaceToRemap=wrksp,
IndexBySpectrumNumber=True)

#------------------------------------------------------------------------------

def _add_sample_logs(self, wks, sample_logs):
def _add_sample_logs(self, wrksp, sample_logs):
"""
Add a dictionary of logs to a workspace.
The type of the log is inferred by the type of the value passed to the log.
@param wks - workspace to add logs too.
@param wrksp - workspace to add logs too.
@param sample_logs - dictionary of logs to append to the workspace.
"""

Expand All @@ -357,8 +373,9 @@ def _add_sample_logs(self, wks, sample_logs):
else:
log_type = 'String'

AddSampleLog(Workspace=wks, LogName=key, LogType=log_type, LogText=str(value))
AddSampleLog(Workspace=wrksp, LogName=key, LogType=log_type, LogText=str(value))

#------------------------------------------------------------------------------

# Register algorithm with Mantid
AlgorithmFactory.subscribe(CylinderPaalmanPingsCorrection)

0 comments on commit 6d43ca2

Please sign in to comment.