Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
mantid
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Model registry
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Code review analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mantidproject
mantid
Commits
f4a2d703
Commit
f4a2d703
authored
14 years ago
by
Doucet, Mathieu
Browse files
Options
Downloads
Patches
Plain Diff
Updated HFIR/SANS reduction script. Re #1334
parent
9eb54bab
Loading
Loading
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Code/Mantid/PythonAPI/scripts/SANS/HFIRSANSReduction.py
+135
-7
135 additions, 7 deletions
Code/Mantid/PythonAPI/scripts/SANS/HFIRSANSReduction.py
with
135 additions
and
7 deletions
Code/Mantid/PythonAPI/scripts/SANS/HFIRSANSReduction.py
+
135
−
7
View file @
f4a2d703
...
@@ -95,6 +95,25 @@ class InstrumentConfiguration:
...
@@ -95,6 +95,25 @@ class InstrumentConfiguration:
TODO: think about a way to clean this up
TODO: think about a way to clean this up
"""
"""
return
[
1000000
+
p
[
0
]
*
1000
+
p
[
1
]
for
p
in
masked_pixels
]
return
[
1000000
+
p
[
0
]
*
1000
+
p
[
1
]
for
p
in
masked_pixels
]
def
get_spectra_from_ID
(
self
,
ids
):
"""
Returns a list of spectra from a list of detector IDs
TODO: think about a way to clean this up
"""
def
_get_spec
(
id
):
iy
=
(
id
-
1000000
)
%
1000
ix
=
int
(
math
.
floor
(((
id
-
1000000
)
-
iy
)
/
1000
))
return
ix
+
iy
*
self
.
ny_pixels
return
map
(
_get_spec
,
ids
)
def
get_monitor_UDET
(
self
,
spectraID
):
"""
Returns the detector ID of a monitor spectra
TODO: Fix this
"""
return
spectraID
+
1
class
SANSReductionMethod
:
class
SANSReductionMethod
:
"""
"""
...
@@ -106,6 +125,12 @@ class SANSReductionMethod:
...
@@ -106,6 +125,12 @@ class SANSReductionMethod:
NORMALIZATION_NONE
=
None
NORMALIZATION_NONE
=
None
NORMALIZATION_TIME
=
1
NORMALIZATION_TIME
=
1
NORMALIZATION_MONITOR
=
0
NORMALIZATION_MONITOR
=
0
## Transmission options
TRANSMISSION_NONE
=
None
TRANSMISSION_BY_HAND
=
1
TRANSMISSION_DIRECT_BEAM
=
2
TRANSMISSION_BEAM_SPREADER
=
3
def
__init__
(
self
):
def
__init__
(
self
):
"""
"""
...
@@ -147,6 +172,11 @@ class SANSReductionMethod:
...
@@ -147,6 +172,11 @@ class SANSReductionMethod:
# Transmission parameters #############################################
# Transmission parameters #############################################
## Number of pixels around the center that define the transmission monitor
self
.
transmission_method
=
SANSReductionMethod
.
TRANSMISSION_NONE
self
.
transmission_radius
=
3.0
self
.
transmission_sample_filepath
=
None
self
.
transmission_empty_filepath
=
None
class
SANSReduction
:
class
SANSReduction
:
...
@@ -360,6 +390,11 @@ class SANSReduction:
...
@@ -360,6 +390,11 @@ class SANSReduction:
# Apply transmission correction #######################################
# Apply transmission correction #######################################
# 1- Compute zero-angle transmission correction (Note: CalcTransCoef)
# 1- Compute zero-angle transmission correction (Note: CalcTransCoef)
if
self
.
method
.
transmission_method
==
SANSReductionMethod
.
TRANSMISSION_DIRECT_BEAM
:
self
.
_transmission_correction
()
# If a dark current workspace was given, correct the result for the dark current
# 2- Apply correction (Note: Apply2DTransCorr)
# 2- Apply correction (Note: Apply2DTransCorr)
# TODO: Need an Algo that will produce a workspace with the following spectra values
# TODO: Need an Algo that will produce a workspace with the following spectra values
...
@@ -372,6 +407,57 @@ class SANSReduction:
...
@@ -372,6 +407,57 @@ class SANSReduction:
# TODO: set the X bins as wavelength with the correct value
# TODO: set the X bins as wavelength with the correct value
def
_transmission_correction
(
self
):
"""
Compute the transmission using the attenuated direct beam method.
Pixels around the beam center will be summed to create a transmission
"
monitor
"
.
Depending on the reduction method settings, the time or monitor channel
will be used for normalization.
@param sample_ws: workspace containing data with direct beam on sample
@param empty_ws: workspace containing data with direct beam w/o sample
"""
sample_ws
=
_extract_workspace_name
(
self
.
method
.
transmission_sample_filepath
)
LoadSpice2D
(
self
.
method
.
transmission_sample_filepath
,
sample_ws
)
empty_ws
=
_extract_workspace_name
(
self
.
method
.
transmission_empty_filepath
)
LoadSpice2D
(
self
.
method
.
transmission_empty_filepath
,
empty_ws
)
# Find which pixels to sum up as our "monitor". At this point we have moved the detector
# so that the beam is at (0,0), so all we need is to sum the area around that point.
#TODO: in IGOR, the error-weighted average is computed instead of simply summing up the pixels
cylXML
=
'
<infinite-cylinder id=
"
transmission_monitor
"
>
'
+
\
'
<centre x=
"
0.0
"
y=
"
0.0
"
z=
"
0.0
"
/>
'
+
\
'
<axis x=
"
0.0
"
y=
"
0.0
"
z=
"
1.0
"
/>
'
+
\
'
<radius val=
"
%12.10f
"
/>
'
%
(
self
.
method
.
transmission_radius
*
self
.
configuration
.
pixel_size_x
/
1000.0
)
+
\
'
</infinite-cylinder>
\n
'
det_finder
=
FindDetectorsInShape
(
Workspace
=
self
.
reduced_ws
,
ShapeXML
=
cylXML
)
det_list
=
det_finder
.
getPropertyValue
(
"
DetectorList
"
)
first_det
=
int
(
det_list
.
split
(
'
,
'
)[
0
])
print
"
DETLIST
"
,
len
(
det_list
.
split
(
'
,
'
)),
det_list
GroupDetectors
(
InputWorkspace
=
empty_ws
,
OutputWorkspace
=
"
empty_mon
"
,
DetectorList
=
det_list
,
KeepUngroupedSpectra
=
"
1
"
)
GroupDetectors
(
InputWorkspace
=
sample_ws
,
OutputWorkspace
=
"
sample_mon
"
,
DetectorList
=
det_list
,
KeepUngroupedSpectra
=
"
1
"
)
#TODO: check that both workspaces have the same masked spectra
# Calculate transmission. Use the reduction method's normalization channel (time or beam monitor)
# as the monitor channel.
CalculateTransmission
(
DirectRunWorkspace
=
"
empty_mon
"
,
SampleRunWorkspace
=
"
sample_mon
"
,
OutputWorkspace
=
"
transmission_fit
"
,
IncidentBeamMonitor
=
str
(
self
.
method
.
normalization
),
TransmissionMonitor
=
str
(
first_det
))
#TODO: If dark current is specified, subtract it
#Apply angle-dependent transmission correction using the zero-angle transmission
ApplyTransmissionCorrection
(
InputWorkspace
=
self
.
reduced_ws
,
TransmissionWorkspace
=
"
transmission_fit
"
,
OutputWorkspace
=
self
.
reduced_ws
)
def
_extract_workspace_name
(
self
,
suffix
=
''
):
def
_extract_workspace_name
(
self
,
suffix
=
''
):
"""
"""
...
@@ -441,7 +527,7 @@ def _read_Mantid(filepath):
...
@@ -441,7 +527,7 @@ def _read_Mantid(filepath):
print
"
_read_Mantid:
"
,
i
,
sys
.
exc_value
print
"
_read_Mantid:
"
,
i
,
sys
.
exc_value
return
data
return
data
def
_verify_result
(
reduced_file
,
test_file
):
def
_verify_result
(
reduced_file
,
test_file
,
tolerance
=
1e-6
):
"""
"""
Compare the data in two reduced data files.
Compare the data in two reduced data files.
@param reduced_file: path of the Mantid-reduced file
@param reduced_file: path of the Mantid-reduced file
...
@@ -465,17 +551,20 @@ def _verify_result(reduced_file, test_file):
...
@@ -465,17 +551,20 @@ def _verify_result(reduced_file, test_file):
# Check that I(q) is the same for both data sets
# Check that I(q) is the same for both data sets
deltas
=
map
(
_diff_iq
,
data_mantid
,
data_igor
)
deltas
=
map
(
_diff_iq
,
data_mantid
,
data_igor
)
delta
=
reduce
(
_add
,
deltas
)
/
len
(
deltas
)
delta
=
reduce
(
_add
,
deltas
)
/
len
(
deltas
)
assert
(
math
.
fabs
(
delta
)
<
1e-6
)
if
math
.
fabs
(
delta
)
>
tolerance
:
print
"
Sum of I(q) deltas is outside tolerance: %g > %g
"
%
(
math
.
fabs
(
delta
),
tolerance
)
# Then compare the errors
# Then compare the errors
deltas
=
map
(
_diff_err
,
data_mantid
,
data_igor
)
deltas
=
map
(
_diff_err
,
data_mantid
,
data_igor
)
delta_err
=
reduce
(
_add
,
deltas
)
/
len
(
deltas
)
delta_err
=
reduce
(
_add
,
deltas
)
/
len
(
deltas
)
assert
(
math
.
fabs
(
delta_err
)
<
1e-6
)
if
math
.
fabs
(
delta_err
)
>
tolerance
:
print
"
Sum of dI(q) deltas is outside tolerance: %g > %g
"
%
(
math
.
fabs
(
delta_err
),
tolerance
)
# Compute chi2 of our result relative to IGOR
# Compute chi2 of our result relative to IGOR
deltas
=
map
(
_diff_chi2
,
data_mantid
,
data_igor
)
deltas
=
map
(
_diff_chi2
,
data_mantid
,
data_igor
)
chi2
=
reduce
(
_add
,
deltas
)
chi2
=
reduce
(
_add
,
deltas
)
/
len
(
data_igor
)
assert
(
chi2
<
1e-5
)
if
chi2
>
10.0
*
tolerance
:
print
"
Chi2 is outside tolerance: %g > %g
"
%
(
chi2
,
10.0
*
tolerance
)
print
"
Completed tests: delta = %g / %g chi2 = %g
"
%
(
delta
,
delta_err
,
chi2
)
print
"
Completed tests: delta = %g / %g chi2 = %g
"
%
(
delta
,
delta_err
,
chi2
)
...
@@ -525,7 +614,7 @@ def test_center_by_hand():
...
@@ -525,7 +614,7 @@ def test_center_by_hand():
def
test_center_calculated
():
def
test_center_calculated
():
"""
"""
Beam center
entered by han
d
Beam center
calculate
d
Subtract dark current
Subtract dark current
Correct for solid angle
Correct for solid angle
Correct for detector efficiency, excluding high/low pixels
Correct for detector efficiency, excluding high/low pixels
...
@@ -555,7 +644,46 @@ def test_center_calculated():
...
@@ -555,7 +644,46 @@ def test_center_calculated():
_verify_result
(
reduced_file
=
"
mantid_center_calculated.txt
"
,
test_file
=
TEST_DIR
+
"
reduced_center_calculated.txt
"
)
_verify_result
(
reduced_file
=
"
mantid_center_calculated.txt
"
,
test_file
=
TEST_DIR
+
"
reduced_center_calculated.txt
"
)
def
test_transmission
():
"""
Beam center calculated
No dark current subtraction
Correct for solid angle
No detector efficiency correction
No background
Transmission calculation uses sum of counts around the beam instead
of using an error-weighted average.
"""
# Data file to reduce
datafile
=
TEST_DIR
+
"
BioSANS_test_data.xml
"
# Reduction parameters
method
=
SANSReductionMethod
()
method
.
transmission_method
=
SANSReductionMethod
.
TRANSMISSION_DIRECT_BEAM
method
.
transmission_sample_filepath
=
TEST_DIR
+
"
BioSANS_sample_trans.xml
"
method
.
transmission_empty_filepath
=
TEST_DIR
+
"
BioSANS_empty_trans.xml
"
#method.transmission_radius=10
# Instrument parameters
conf
=
InstrumentConfiguration
()
conf
.
beam_center_method
=
InstrumentConfiguration
.
BEAM_CENTER_DIRECT_BEAM
conf
.
beam_center_filepath
=
TEST_DIR
+
"
BioSANS_empty_cell.xml
"
reduction
=
SANSReduction
(
datafile
,
method
,
conf
)
reduction
.
reduce
()
SaveCSV
(
Filename
=
"
mantid_transmission.txt
"
,
InputWorkspace
=
"
Iq
"
,
Separator
=
"
\t
"
,
LineSeparator
=
"
\n
"
)
_verify_result
(
reduced_file
=
"
mantid_transmission.txt
"
,
test_file
=
TEST_DIR
+
"
reduced_transmission.txt
"
,
tolerance
=
0.1
)
if
__name__
==
"
__main__
"
:
if
__name__
==
"
__main__
"
:
test_center_calculated
()
# EXECUTE THIS FROM Mantid/release
#test_center_calculated()
#test_center_by_hand()
#test_center_by_hand()
test_transmission
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment