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
0dc8455b
Commit
0dc8455b
authored
14 years ago
by
Campbell, Stuart
Browse files
Options
Downloads
Patches
Plain Diff
Actually writes some data now. refs #1420.
parent
7a6d2cd9
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Code/Mantid/Nexus/src/SaveNXSPE.cpp
+244
-102
244 additions, 102 deletions
Code/Mantid/Nexus/src/SaveNXSPE.cpp
with
244 additions
and
102 deletions
Code/Mantid/Nexus/src/SaveNXSPE.cpp
+
244
−
102
View file @
0dc8455b
#include
"MantidNexus/SaveNXSPE.h"
#include
"MantidNexus/SaveNXSPE.h"
#include
"MantidAPI/FileProperty.h"
#include
"MantidAPI/FileProperty.h"
#include
"MantidKernel/ConfigService.h"
#include
"MantidKernel/ConfigService.h"
#include
"MantidAPI/WorkspaceValidators.h"
#include
"MantidAPI/WorkspaceValidators.h"
#include
"MantidGeometry/Instrument/Detector.h"
#include
"MantidGeometry/Instrument/ObjComponent.h"
#include
"Poco/File.h"
#include
"Poco/File.h"
#include
"Poco/Path.h"
#include
"Poco/Path.h"
namespace
Mantid
{
namespace
Mantid
namespace
NeXus
{
{
namespace
NeXus
// Register the algorithm into the algorithm factory
{
DECLARE_ALGORITHM
(
SaveNXSPE
)
// Register the algorithm into the algorithm factory
using
namespace
Kernel
;
DECLARE_ALGORITHM
(
SaveNXSPE
)
using
namespace
API
;
using
namespace
Kernel
;
SaveNXSPE
::
SaveNXSPE
()
:
using
namespace
API
;
API
::
Algorithm
()
{
}
const
double
SaveNXSPE
::
MASK_FLAG
=
-
1e30
;
const
double
SaveNXSPE
::
MASK_ERROR
=
0.0
;
/**
* Initialise the algorithm
SaveNXSPE
::
SaveNXSPE
()
:
*/
API
::
Algorithm
()
void
SaveNXSPE
::
init
()
{
{
}
std
::
vector
<
std
::
string
>
exts
;
exts
.
push_back
(
".nxspe"
);
/**
* Initialise the algorithm
declareProperty
(
new
API
::
FileProperty
(
"Filename"
,
""
,
FileProperty
::
Save
,
exts
),
*/
"The name of the NXSPE file to write, as a full or relative path"
);
void
SaveNXSPE
::
init
()
CompositeValidator
<>
*
wsValidator
=
new
CompositeValidator
<>
;
{
wsValidator
->
add
(
new
API
::
WorkspaceUnitValidator
<>
(
"DeltaE"
));
wsValidator
->
add
(
new
API
::
CommonBinsValidator
<>
);
std
::
vector
<
std
::
string
>
exts
;
wsValidator
->
add
(
new
API
::
HistogramValidator
<>
);
exts
.
push_back
(
".nxspe"
);
declareProperty
(
new
WorkspaceProperty
<
MatrixWorkspace
>
(
"InputWorkspace"
,
declareProperty
(
new
API
::
FileProperty
(
"Filename"
,
""
,
FileProperty
::
Save
,
""
,
Direction
::
Input
,
wsValidator
),
exts
),
"Name of the workspace to be saved."
);
"The name of the NXSPE file to write, as a full or relative path"
);
}
CompositeValidator
<>
*
wsValidator
=
new
CompositeValidator
<>
;
/**
wsValidator
->
add
(
new
API
::
WorkspaceUnitValidator
<>
(
"DeltaE"
));
* Execute the algorithm
wsValidator
->
add
(
new
API
::
CommonBinsValidator
<>
);
*/
wsValidator
->
add
(
new
API
::
HistogramValidator
<>
);
void
SaveNXSPE
::
exec
()
{
using
namespace
Mantid
::
API
;
declareProperty
(
new
WorkspaceProperty
<
MatrixWorkspace
>
(
"InputWorkspace"
,
// Retrieve the input workspace
""
,
Direction
::
Input
,
wsValidator
),
const
MatrixWorkspace_const_sptr
inputWS
=
getProperty
(
"InputWorkspace"
);
"Name of the workspace to be saved."
);
}
// Do the full check for common binning
if
(
!
WorkspaceHelpers
::
commonBoundaries
(
inputWS
))
{
/**
g_log
.
error
(
"The input workspace must have common bins"
);
* Execute the algorithm
throw
std
::
invalid_argument
(
"The input workspace must have common bins"
);
*/
}
void
SaveNXSPE
::
exec
()
const
int
nHist
=
inputWS
->
getNumberHistograms
();
{
this
->
nBins
=
inputWS
->
blocksize
();
using
namespace
Mantid
::
API
;
// Retrieve the filename from the properties
// Constant for converting Radians to Degrees
this
->
filename
=
getPropertyValue
(
"Filename"
);
const
double
rad2deg
=
180.0
/
M_PI
;
// Create the file.
// Retrieve the input workspace
::
NeXus
::
File
nxFile
(
this
->
filename
,
NXACC_CREATE5
);
const
MatrixWorkspace_const_sptr
inputWS
=
getProperty
(
"InputWorkspace"
);
// Make the top level entry (and open it)
// Do the full check for common binning
nxFile
.
makeGroup
(
inputWS
->
getName
(),
"NXentry"
,
true
);
if
(
!
WorkspaceHelpers
::
commonBoundaries
(
inputWS
))
{
// Create NXSPE_info
g_log
.
error
(
"The input workspace must have common bins"
);
nxFile
.
makeGroup
(
"NXSPE_info"
,
"NXcollection"
,
true
);
throw
std
::
invalid_argument
(
"The input workspace must have common bins"
);
//TODO: Get and write Ei as "fixed_energy"
}
//TODO: Get and write psi as "psi"
//TODO: Get and write ki/kf as "ki_over_kf_scaling" = 1/0
// Number of spectra
const
int
nHist
=
inputWS
->
getNumberHistograms
();
nxFile
.
closeGroup
();
// NXSPE_info
// Number of energy bins
this
->
nBins
=
inputWS
->
blocksize
();
// NXinstrument
nxFile
.
makeGroup
(
"instrument"
,
"NXinstrument"
,
true
);
// Get a pointer to the sample
Geometry
::
IObjComponent_const_sptr
sample
=
inputWS
->
getInstrument
()
->
getSample
();
// NXfermi_chopper
nxFile
.
makeGroup
(
"fermi"
,
"NXfermi_chopper"
,
true
);
// Retrieve the filename from the properties
//TODO: Get and write Ei as "fixed_energy"
this
->
filename
=
getPropertyValue
(
"Filename"
);
nxFile
.
closeGroup
();
// NXfermi_chopper
// Create the file.
nxFile
.
closeGroup
();
// NXinstrument
::
NeXus
::
File
nxFile
(
this
->
filename
,
NXACC_CREATE5
);
// NXsample
// Make the top level entry (and open it)
nxFile
.
makeGroup
(
"sample"
,
"NXsample"
,
true
);
nxFile
.
makeGroup
(
inputWS
->
getName
(),
"NXentry"
,
true
);
// TODO: Write sample info
nxFile
.
closeGroup
();
// NXsample
// Definition name and version
nxFile
.
writeData
(
"definition"
,
"NXSPE"
);
// Energy bins
nxFile
.
openData
(
"definition"
);
// Get the Energy Axis (X) of the first spectra (they are all the same - checked above)
// Make Version 1.0 as we don't have all the metadata yet!
const
MantidVec
&
X
=
inputWS
->
readX
(
0
);
nxFile
.
putAttr
(
"version"
,
"1.0"
);
nxFile
.
writeData
(
"energy"
,
X
);
nxFile
.
closeData
();
// TODO: Data Array
// Program name and version
// TODO: Error Array
nxFile
.
writeData
(
"program_name"
,
"mantid"
);
// Polar Angles
nxFile
.
openData
(
"program_name"
);
// Polar Angle Width
// TODO: Get the correct version number
// Azimuthal Angle
nxFile
.
putAttr
(
"version"
,
"1.1"
);
// Azimuthal Angle Width
nxFile
.
closeData
();
nxFile
.
closeGroup
();
// Top level NXentry
// Create NXSPE_info
}
nxFile
.
makeGroup
(
"NXSPE_info"
,
"NXcollection"
,
true
);
}
// namespace NeXus
//TODO: Get and write Ei as "fixed_energy"
//TODO: Get and write psi as "psi"
//TODO: Get and write ki/kf as "ki_over_kf_scaling" = 1/0
nxFile
.
closeGroup
();
// NXSPE_info
// NXinstrument
nxFile
.
makeGroup
(
"instrument"
,
"NXinstrument"
,
true
);
// Write the instrument name
nxFile
.
writeData
(
"name"
,
inputWS
->
getInstrument
()
->
getName
());
// and the short name
nxFile
.
openData
(
"name"
);
// TODO: Get the instrument short name
nxFile
.
putAttr
(
"short_name"
,
inputWS
->
getInstrument
()
->
getName
());
nxFile
.
closeData
();
// NXfermi_chopper
nxFile
.
makeGroup
(
"fermi"
,
"NXfermi_chopper"
,
true
);
//TODO: Get and write Ei as "fixed_energy"
nxFile
.
closeGroup
();
// NXfermi_chopper
nxFile
.
closeGroup
();
// NXinstrument
// NXsample
nxFile
.
makeGroup
(
"sample"
,
"NXsample"
,
true
);
// TODO: Write sample info
nxFile
.
closeGroup
();
// NXsample
// Make the NXdata group
nxFile
.
makeGroup
(
"data"
,
"NXdata"
,
true
);
// Energy bins
// Get the Energy Axis (X) of the first spectra (they are all the same - checked above)
const
MantidVec
&
X
=
inputWS
->
readX
(
0
);
nxFile
.
writeData
(
"energy"
,
X
);
nxFile
.
openData
(
"energy"
);
nxFile
.
putAttr
(
"units"
,
"meV"
);
nxFile
.
closeData
();
// let's create some blank arrays in the nexus file
std
::
vector
<
double
>
azimuthal
;
std
::
vector
<
double
>
polar
;
std
::
vector
<
double
>
azimuthal_width
;
std
::
vector
<
double
>
polar_width
;
double
delta_polar
=
0.0
;
double
delta_azimuthal
=
0.0
;
double
distance
=
0.0
;
std
::
vector
<
int
>
array_dims
;
array_dims
.
push_back
(
nHist
);
array_dims
.
push_back
(
nBins
);
nxFile
.
makeData
(
"data"
,
::
NeXus
::
FLOAT64
,
array_dims
,
false
);
nxFile
.
makeData
(
"error"
,
::
NeXus
::
FLOAT64
,
array_dims
,
false
);
std
::
vector
<
int
>
slab_start
;
std
::
vector
<
int
>
slab_size
;
// What size slabs are we going to write...
slab_size
.
push_back
(
1
);
slab_size
.
push_back
(
nBins
);
// And let's start at the beginning
slab_start
.
push_back
(
0
);
slab_start
.
push_back
(
0
);
// Loop over spectra
for
(
size_t
i
=
0
;
i
<
static_cast
<
size_t
>
(
nHist
);
i
++
)
{
// Check that we aren't writing a monitor...
if
(
!
inputWS
->
getDetector
(
i
)
->
isMonitor
())
{
Geometry
::
IDetector_sptr
det
=
inputWS
->
getDetector
(
i
);
polar
.
push_back
(
inputWS
->
detectorTwoTheta
(
det
)
*
rad2deg
);
azimuthal
.
push_back
(
inputWS
->
getDetector
(
i
)
->
getPhi
()
*
rad2deg
);
// Get Sample->Detector distance
distance
=
det
->
getDistance
(
*
sample
);
// Now let's work out the detector widths
// TODO: This is the historically wrong method...update it!
// Initialise to large values
double
xmin
=
-
1000.0
;
double
xmax
=
1000.0
;
double
ymin
=
-
1000.0
;
double
ymax
=
1000.0
;
double
zmin
=
-
1000.0
;
double
zmax
=
1000.0
;
// Get the bounding box
det
->
getBoundingBox
(
xmax
,
ymax
,
zmax
,
xmin
,
ymin
,
zmin
);
double
xsize
=
xmax
-
xmin
;
double
ysize
=
ymax
-
ymin
;
delta_polar
=
atan2
((
ysize
/
2.0
),
distance
)
*
rad2deg
;
delta_azimuthal
=
atan2
((
xsize
/
2.0
),
distance
)
*
rad2deg
;
// Now write the widths...
polar_width
.
push_back
(
delta_polar
);
azimuthal_width
.
push_back
(
delta_azimuthal
);
if
(
!
inputWS
->
getDetector
(
i
)
->
isMasked
())
{
// no masking...
// Open the data
nxFile
.
openData
(
"data"
);
slab_start
[
0
]
=
i
;
nxFile
.
putSlab
(
const_cast
<
MantidVec
&>
(
inputWS
->
readY
(
i
)),
slab_start
,
slab_size
);
// Close the data
nxFile
.
closeData
();
// Open the error
nxFile
.
openData
(
"error"
);
nxFile
.
putSlab
(
const_cast
<
MantidVec
&>
(
inputWS
->
readE
(
i
)),
slab_start
,
slab_size
);
// Close the error
nxFile
.
closeData
();
}
else
{
// Write a masked value...
}
}
}
// Write the Polar (2Theta) angles
nxFile
.
writeData
(
"polar"
,
polar
);
// Write the Azimuthal (phi) angles
nxFile
.
writeData
(
"azimuthal"
,
azimuthal
);
// Now the widths...
nxFile
.
writeData
(
"polar_width"
,
polar_width
);
nxFile
.
writeData
(
"azimuthal_width"
,
azimuthal_width
);
nxFile
.
closeGroup
();
// NXdata
nxFile
.
closeGroup
();
// Top level NXentry
}
}
// namespace NeXus
}
// namespace Mantid
}
// namespace Mantid
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