16.4. Use cases: adding items to the NeXus file¶
16.4.1. How to add an NXmonochromator entry¶
The motivation here is to add information on the beamline monochromator to the
NeXus file. The monochromator itself is not scanned and so is not a scannable
object. It is however described in many cases by a series of positions and
values for other scannables such as the ring energy, slit position, size,
rotation etc. Each beamline may have a different monochromator depending on
different scannables. To create an NXmonochromator entry in the NeXus file,
it is necessary to pull together all the scannables that contain the
information needed to describe the monochromator.
There are currently a few ways of doing this in both new and old scanning. The use cases below are based on the way that beamlines currently configure the items that get written to the NeXus files during scanning.
This method is applicable for both old and new scanning.
Set up the relevant scannables
The example below assumes that the monochromator depends on a scannable representing the energy, and a scannable representing the slit position. As such the following ‘dummy’ items are defined in an xml file and referenced by the
server.xml.
<bean id="energy" class="gda.device.scannable.ScannableMotor"> <property name="motor" ref="dummy_energy" /> </bean> <bean id="slitpos" class="gda.device.scannable.ScannableMotor"> <property name="motor" ref="dummy_slit" /> </bean> <bean id="dummy_energy" class="gda.device.motor.DummyMotor"/> <bean id="dummy_slit" class="gda.device.motor.DummyMotor"/>
Note that in live mode there may actually be an
EnergyScannableobject to represent the energy:
<bean id="energy" class="uk.ac.gda.server.ncd.scannable.EnergyScannable"> <property name="bragg" ref="dmm_energy" /> </bean>
Next use the location map to specify where these scannables should be located when added to the NeXus file. The location map is a legacy implementation and could potentially be removed when the Nexus templating has been finalised and fully integrated. However, it should be noted that the location map is heavily used across beamlines to specify NeXus objects location. Below is an example defining the location of where the
energyandslitposscannables should write their information to.
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="gda.data.scan.datawriter.NexusDataWriter.setLocationmap" /> <property name="arguments"> <map> <entry key="energy"> <bean class="gda.data.scan.datawriter.scannablewriter.SingleScannableWriter"> <property name="paths" value="instrument:NXinstrument/TestMonochromator:NXmonochromator/energy"/> <property name="units" value="keV"/> </bean> </entry> <entry key="slitpos"> <bean class="gda.data.scan.datawriter.scannablewriter.SingleScannableWriter"> <property name="paths" value="instrument:NXinstrument/TestMonochromator:NXmonochromator/slit_position"/ <property name="units" value="mm"/> </bean> </entry> </map> </property> </bean>
Now register the scannables with the
NexusDataWriteras scannables that should record their metadata for any detector used in the scan (see theNexusDataWriter’s purpose here). This is necessary as if a scannable is not scanned (or involved directly in the scan) then its metadata will not be added. Instead, we want to say that it must always be added to the file which is achieved by adding the Spring code below.
<!-- Metas to be recorded for any detector --> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="gda.data.scan.datawriter.NexusDataWriter.setMetadatascannables" /> <property name="arguments"> <set> <value>energy</value> <value>slitpos</value> </set> </property> </bean>
This argument is inherently based on old scanning however new scanning still supports this method. The above scannables are GDA8 scannables and indeed it is true that most beamlines still use GDA8 scannables. As described this section, when these are used in new scanning, they are wrapped using the
ScannableNexusWrapperto look like GDA9 scannables that can add NeXus entries. TheScannableDeviceConnectorServicecreates a newScannableNexusWrapperwhich adapts a GDA8 scannables to theIScannableAPI. During the server startup process, theNexusScanFileManageradds the ‘legacy’ monitors to the scan by calling on theScannableDeviceConnectorServicewhich sets theMetadataScannables set in theNexusDataWriter. It is worth noting that all of this is deemed as a legacy implementation that should be removed, yet this seems to be the way most beamlines do it and there are very few alternatives currently.
Aside for NEW scanning: For new scanning, it is actually possible to use the Jython console in the client to directly run a new style scan (i.e.
mscan) instead of using the Mapping UI. This allows beamlines to be more precise on what they configure. Instead of adding the above scannables to theNexusDataWriter(considered deprecated) we can simply add theenergyandslitposscannables as ‘monitors per scan’, e.g.monitorsPerScan=['beam','energy','slitpos']. Below is an examplemscancommand using the malcolm detector, and the above monitors per scan.
mscan(path=[grid(axes=('stagex', 'stagey'), start=(0, 0), stop=(1, 1), count=(5, 5), snake=True, continuous=True, roi=[rect(origin=(0, 0), size=(1, 1))])], monitorsPerScan=['beam','energy','slitpos'], det=[detector('malcolm', 0.1, dummyDetectorModels=[DummyMalcolmControlledDetectorModel [name=detector, datasets=[DummyMalcolmDatasetModel [name=detector, dtype=class java.lang.Double, rank=2, shape=null]]]], positionerNames=[stagex, stagey], monitorNames=[])])
In addition, this gives us the option to add these as monitors per point where the metadata will then be included in the detector group and added to each scan point. E.g.
monitorsPerPoint=['slitpos']
Below is the layout of a NeXus file produced by this implementation. The
NXmonochromator information is stored under ‘instruments’ as defined by our
location map.
NEW scanning:
A group for ‘scannables’ is also added which contains the scannables which are
defined as NXpositioners by default by the ScannableNexusWrapper. The
purpose of this group is just to keep the default NeXus objects separate from
anything created according to the location map.
And for OLD scanning:
2. Use GDA9 scannables
As most beamlines still use GDA8 scannables, the ‘location map method’ is a
popular way of including the information. Alternatively you could create a GDA9
scannable class directly in Java. There are multiple ways of adding the
scannable to the scan, such as adding it using the
NexusDataWriter.setMetadatascananbles method (this is a legacy mechanism
related to the location map), adding it to the DefaultScanConfiguration
specified in Spring, or selecting it in the ‘Monitors’ view in the Mapping
perspective.
An example of a GDA9 scannable is the BeamScannable which extends
AbstractScannable and implements INexusDevice. This is configured to write
the ‘beam extent’ information under the Sample category. This is a special
case which the Mapping UI will add to the scan on submission. It is defined in
Spring like so:
<!-- A scannable holding the beam size so that it can be written to Nexus. -->
<bean id="beam" class="uk.ac.diamond.daq.scanning.BeamScannable"
init-method="register">
<property name="name" value="beam" />
<property name="beamSize" value="0.1"/>
</bean>
Aside
scanMetadataAttributes: In NEW scanning we are also able to add static information to a scannable simply by including thescanMetadataAttributesproperty in the scannable definition in Spring. This method is implementation byScannableBaseso is applicable for any scannable or device implementing this class. ThescanMetadataAttributescan be used to set multiple additional metadata fields of the NeXus object for the scannable. There are two reserved names that are used for other purposes,NXclasswhich will change the type of NeXus object created, andnexusCategory, which will change the group of the NeXus tree that the object is added to.
In New Scanning, the group that the NeXus object is added to is dependent on the type of the NeXus object and in most cases it will be added to
NXinstrument. This is the case forNXdetectorandNXpositionerfor example, where theNXpositioneris the default NeXus class produced by theScannableNexusWrapper. Using thescanMetadataAttributeswe can change the group that the object is added to by altering thenexusCategorylike so:
<bean id="energy" class="gda.device.scannable.ScannableMotor">
<property name="motor" ref="dummy_energy" />
<property name="scanMetadataAttributes">
<map>
<entry key="nexusCategory" value="NXentry" />
<entry key="Extra static info" value="this is a test piece on info" />
</map>
</property>
</bean>
Remember that the
nexusCategorymust one of the default categories because at the time these get added the default groups are the only ones present.
3. Jython scripts - the ‘i15-1’ implementation
The following is a method used by i15-1 to get the vast amount of metadata that
they require into their NeXus files while running a NEW scan. It is implemented
in Jython but if deemed as the best way forward it should be formalised so that
other beamlines can easily implement the same set-up. Indeed, what these scripts
are essentially doing is setting up scannables that implement the
INexusDevice, configuring the object returned by the NeXus provider and
adding these devices to the ScanRequest. All of this does not necessarily
have to be performed in Jython.
More information can be found here
i15-1 create their own monochromator class (XpdfMonochromator) which has a
getNexus() method that handles the creation of a NeXus node to fully describe
the monochromator. Their monochromator depends on other objects/scannables such
as the crystal position, and the xtalBragg motor (to name only 2). The NeXus
file creation method can include all of these as a collection within the
NXmonochromator category and so all information can be added to the NeXus
file. E.g.
def getNexus(self):
nxMonochromator = NexusNodeFactory.createNXmonochromator()
description = NexusNodeFactory.createDataNode()
description.setDataset(dnp.array(['Bent-Laue monochromator, FMB-Oxford'])._jdataset())
nxMonochromator.addDataNode('description',description)
crystalPosition = self.getPosition()
nxMonochromator.setEnergyScalar(crystalPosition.crystal.energy)
nxMonochromator.setAttribute(nxMonochromator.NX_ENERGY, 'units', 'keV')
xtalBraggMotor = getNxMotor('xtalBragg','BL15J-OP-LAUE-01:PITCH','Crystal cage coarse pitch (Bragg) rotation stage')
xtalRollMotor = getNxMotor('xtalRoll','BL15J-OP-LAUE-01:ROLL','Crystal cage roll arc segment')
xtalYawMotor = getNxMotor('xtalYaw','BL15J-OP-LAUE-01:YAW','Crystal cage yaw arc segment')
xtalBendMotor = getNxMotor('xtalBend','BL15J-OP-LAUE-01:BENDER','Crystal cage bender motor')
nxCollection.addGroupNode('xtalY',xtalYMotor)
nxCollection.addGroupNode('xtalBragg',xtalBraggMotor)
The XpdfMonochromator object is created and loaded in the localStation.py
script which gets run on GDA startup. Following this, the mscan.py script
(which runs a GDA9 scan), is used to create an NxObjectScannable and register
it with the ScannableDeviceService to include its NeXus information in the
scan.
4. NeXus templating
This is applicable to both new and old scanning and can be used to add static data into a created entry. It is under development now and still subject to some change, but the current status is described below. The NeXus templating scheme would replace the location map (which is already deemed as outdated) and provides a more powerful and robust method of defining NeXus file content.
For this example we will assume that the energy and slitpos are the
scannables that have been added as monitors to the scan (i.e. the information
already exists in the NeXus file but perhaps not in the right place), we can
create the NXmonochromator entry under the ‘instrument’ group by applying a
simple template (written in YAML) to the NeXus file. A standalone application
currently exists and can be run using the commands given in the
templating section.
An example YAML template for creating the NXmonochromator is outlines below:
entry/:
NX_class@: NXentry # the '@' has to come at the end as
instrument/:
NX_class@: NXinstrument
TestMonochromator/:
NX_class@: NXmonochromator
energy: /entry/energy
slit_position: /entry/slitpos
This would transform the current NeXus file:
… into:
This method yields the same results as those produced using the deprecated location map.
16.4.2. How to add an NXcite entry¶
NXcite represents a literature reference that could include references for
detectors, manuals, instruments etc. This could be included in the relevant
NeXus object (e.g. NXdetector for detectors or NXinstrument for
instruments).
1. Use the location map
This has not been implemented by any beamline yet but it is possible to add an
NXcite entry using a similar method to that above for the
NXmonochromator. However, the main difference here is that it contains only
static information so instead create a pseudo scannable using the
SimpleScannable class which poses no limitations on the position type.
Create
SimpleScannablein Spring and label it as anNXciteNXclass. ThecurrentPositionwhich will be added as metadata to the NeXus file can be defined as aStringin this case, and a constant with value ‘www.somewebsite.com’.
<bean id="citation" class="gda.device.scannable.SimpleScannable"> <property name="name" value="citation"/> <property name="currentPosition"> <bean class="java.lang.String"> <constructor-arg value="www.somewebsite.com" /> </bean> </property> </bean>
Add the pseudo scannable to the location map so that the entry gets mapped to the correct place:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="gda.data.scan.datawriter.NexusDataWriter.setLocationmap" /> <property name="arguments"> <map> <entry key="citation"> <bean class="gda.data.scan.datawriter.scannablewriter.SingleScannableWriter"> <property name="paths" value="instrument:NXinstrument/TestCite:NXcite/citation"/> </bean> </entry> </map> </property> </bean>
Register it with the
NexusDataWriter:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="gda.data.scan.datawriter.NexusDataWriter.setMetadatascannables" /> <property name="arguments"> <set> <value>citation</value> </set> </property> </bean>
Again for NEW scanning it can be set as a
monitorPerScanin themscancommand from the Jython console (as detailed above).
The resulting entry in the NeXus file will look as such:
2. Use GDA9 scannables
Again it would be possible to create a GDA9 scannable (or in-fact even a GDA8
scannable) and use the scanMetadataAttributes (from
above), then use
NexusDataWriter.setMetadatascananbles, DefaultScanConfiguration or the
‘Monitors view’ in the Mapping UI to add the scannable to the scan.
E.g.
<bean id="citation" class="gda.device.scannable.SimpleScannable">
<property name="name" value="citation"/>
<property name="currentPosition">
<bean class="java.lang.String">
<constructor-arg value="www.somewebsite.com" />
</bean>
</property>
<property name="scanMetadataAttributes">
<map>
<entry key="nexusCategory" value="NXentry" />
<entry key="NXclass" value="NXcite" />
</map>
</property>
</bean>
3. Jython scripts - the ‘i15-1’ implementation
Using the Jython scripting and getNexus() methods it would be trivial for
i15-1 to add an NXcite entry into their NeXus files. For more details on
their implementation see the confluence pages
https://confluence.diamond.ac.uk/display/SSCC/I15-1+NeXus+implementation
and
https://confluence.diamond.ac.uk/display/I151/Metadata+scannable.
4. NeXus templating
In a similar fashion to that described for the NXmonochromator, one could
apply a template that adds an NXcite entry to the NeXus file once it has been
created or during the scan.
A template YAML files similar to that below would carry this out:
entry/:
NX_class@: NXentry # the '@' has to come at the end as
detector/:
NX_class@: NXdata
TestCite/:
NX_class@: NXcite
url: "www.somewebsite.com"
Producing:

Once again, see the templating section for details of how such a template could be applied to a NeXus file using the standalone templating application.
16.4.3. Entry/subentry conforming to an Application Definition¶
THe NeXus framework in GDA9 does not currently validate the NeXus file created
against any application definition. It also does not have the ability to
specify which application definition an NXentry should be validated against
or to build an NXsubentry for a particular application definition.
There are 36 application definitions in total, but only 9 are currently in use
and at Diamond, only 2 or so are used commonly, namely NXarpes, NXtomo and
maybe NXmx.
Currently, GDA9 does auto-generate Java validators for each application
definition, for example NXarpesValidator extends AbstractNexusValidator implements NexusApplicationValidator contained in the
org.eclipse.dawnsci.nexus.validation package. The general form is to take an
NXentry and check that it has the correctly named fields and correct types
etc. E.g.
...
// validate field 'title' of type NX_CHAR.
final IDataset title = group.getTitle();
validateFieldNotNull("title", title);
validateFieldType("title", title, NX_CHAR);
...
However, while these validators exist, they are not yet implemented anywhere within GDA9. There are plans to do so.
Templating solution
The new NeXus templating application (under development) could potentially allow the user to easily apply an application definition template and then use these validators (perhaps in a standalone manner) to validate their NeXus files against the definitions. See the templating section for more information and details on how to use the standalone application.
This could be done by creating a template in YAML which defines an entry which follows a particular Application Definition and maps each of the correctly named variables (according to the definition) to an item that is already defined in the NeXus file.
For example, take the NXarpes application definition for angular resolved
photo electron spectroscopy. An extract from the definition is given below
(full definition can be found
here).
<group type="NXmonochromator" name="monochromator">
<field name="energy" type="NX_NUMBER" units="NX_ENERGY"/>
</group>
<group type="NXdetector" name="analyser">
<field name="data" type="NX_NUMBER" />
...
</group>
This definition requires a group name of ‘monochromator’ as type
‘NXmonochromator’ and under this it must contain the field ‘energy’. In the
YAML template you could meet this requirement by creating this group and adding
a link for the ‘energy’ field value to the location of the equivalent variable
in the current NeXus file (which may have a different name). Equally, the above
definition says that the detector should be named ‘analyser’ whereas commonly
in the NeXus file produced at Diamond it will be the detector name (e.g.
mandelbrot).
An example of a YAML template that would create an entry from an existing NeXus file that would conform to this application definition is given below:
scan/:
NX_class@: NXentry # the '@' has to come at the end as
title: /entry/experiment_identifier
start_time: /entry/start_time
definition: NXscan
instrument/:
NX_class@: NXinstrument
source/:
NX_class@: NXsource
type: "ray"
name: "testname"
probe: "x-ray"
monochromator/:
NX_class@: NXmonochromator
energy: /entry/instrument/ring_energy/value
analyser/:
NX_class@: NXdetector
data: /entry/mandelbrot/data
lens_mode: "none"
acqusition_mode: "fixed"
Here is the NeXus file before applying the template:
And after:
Here you can see that the monochromator entry has been created and links to the
‘ring_energy’ value which is saved under the field ‘energy’ as required.
Similarly, we now have the NXdetector named as ‘analyser’ with the ‘data’
field linked to the data field of the ‘entry/mandelbrot’.
The template can be applied to an existing NeXus file and can also be applied during new scanning after the NeXus tree is created and before it is written to disk.
16.4.4. Including diffraction calibration data¶
Currently, the only case of this is on the i15-1 beamline where calibration data is added into the NeXus file using Jython scripts.
When calibrations are carried out the results are saved to a NeXus file (via a Dawn utility). Users are then told the location of the calibration file which they can use to calibrate their data. The new idea is to have this calibration data contained in the scan NeXus file to provide a complete set of information from the experiment.
i15-1 have achieved this by reading the calibration file, extracting the NeXus
tree, saving it to memory and then writing it into the experiment data NeXus
file. This is done by exploiting the ‘getNexusProvider()’ method which all
GDA9 scannables have. GDA8 scannables can also be wrapped in new scanning by
the NexusScannableWrapper which also gives them access to this method. i15-1
write their own getNexusProvider() method in Jython which is implemented via
a ‘delegated’ mechanism that allows Jython methods to be called from Java.
Doing so allows them to specify what information is used to populate the NeXus
nodes for a given scannable. By using this method for a detector, they can
populate the NXdetector node with information about the detector and its
calibration information.
For example, they have a detector class named ‘peAd.py’ that takes a proxy as
an argument and returns an AbstractAreaDetectorRunnableDeviceDelegate. This
peAd class defines the getNexusProvider() method which defines what to add
to the NeXus file.
It creates a NeXus detector entry:
nxDetector = NexusNodeFactory.createNXdetector()Sets the required attributes (e.g. gain, frame time):
nxDetector.setGain_setting(...)Calls the method ‘
addCalibrationToNxDetector()’ which extracts the NeXus tree from the calibration file and adds it under theNXdetectornode.
The localStation.py script (which is loaded near the end of the server start
up) configures the ‘delegate’ and registers it as an object on the server. This
allows the creation of runnable devices defined by Jython classes which don’t
exist at Spring configuration time, e.g.
testRunnableDeviceProxyFinder = Finder.find("testRunnableDeviceProxyFinder")
testRunnableDeviceProxy = testRunnableDeviceProxyFinder.getRunnableDevice()
testJythonRunnableDeviceDelegate = PeAd(testRunnableDeviceProxy, ....)
testRunnableDeviceProxy.setDelegate(testJythonRunnableDeviceDelegate)
testRunnableDeviceProxy.register()
test = testJythonRunnableDeviceDelegate
More information can be found on the 15-1 confluence page.
While this is the only beamline to have implemented it so far, it is believed that it is a generic enough case that other beamlines (e.g. i122, i14, i12, i15 etc… essentially any beamline doing diffraction) might also require it and so should be formalised by creating Java code to do this.
Most of the calibration information comes from the detector and detectors are
responsible for adding their own NeXus information to the file when asked for
it in a scan and so this is potentially where the calibration data could be
added. I.e. the detectors could be configured to add the calibration data as
well as its own (to the NXdata category). A caveat to this is that some
calibration information may come from the ‘Sample’ (for example the incident
wavelength which never reaches the detector) and so another way would be needed
to add this information as well. There may also be different beamline
requirements, so the systems should remain flexible and users should be able to
override different options. For example some beamlines may run calibrations to
get the wavelength of the beam whereas others will simply read it from the
monochromator, which can add its own metadata in the scan.
16.4.5. Adding metadata¶
1. In the ScanRequest in New Scanning
In new scanning, scan metadata can be added to ScanRequest with an entry such
as:
"scanMetadata":[{"@type":"ScanMetadata","type":"SAMPLE","fields":{"name":"Unnamed Sample","description":"No description provided."}}]
The above is an example for what the Mapping UI adds to the ScanRequest on
submission from the GUI using the inputs provided by the user in the ‘Sample
name’ and ‘Description’ fields. The scan metadata is added to the NeXus tree
just after the default groups have been added and before the providers add
their metadata therefore it must be categorised under one of the default
groups.
However, there is currently no user interface in the Mapping UI to configure
what scan metadata items are added to the NeXus file. The only way to do this
is for a beamline to manually created their own ScanRequest object, insert
the scan metadata they want under the above ‘scanMetadata’ attribute and
submit this through the Jython console.
For example, to run an mscan from the Jython console:
Make sure to have imported the modules by defining them in localStation.py:
from mapping_scan_commands import ( mscan, detector, scan_request, submit, step, grid, circ, poly, rect, sample)
Run an
mscanwith the metadata variable set.mscan(step(stage_x, 0, 10, 1), det=detector('mandelbrot', 0.1), metadata=sample(meta_key="Some information") )
This will produce the entry
Note that these ScanMetadata objects are only necessary for adding metadata
fields to the three default groups (NXentry, NXinstrument and NXsample)
that do not come from NeXus devices. If the metadata is required anywhere else
in NeXus tree, then this can be achieved by configuring the device (creating
one if necessary) that creates the NeXus group containing the metadata. Also
note that if a NeXus device (scannable) is included in the scan that produces
an NXsample object, this will overwrite the existing empty NXsample created
at the start of the scan.
2. Jython scripts - i15-1 implementation in New Scanning
i15-1 have a vast amount of metadata to add to the NeXus file so have a system
of doing this that relies on Jython scripting. They have their own mscan.py
script which runs a new style scan from Jython console. For metadata that does
not fall into a scannable (e.g. sample info) a light-weight scannable is
created where the NeXus node location is specified. NXObjectScannables are
created and added to the GDA9 scan request. An NXObjectScannable implements
the NexusObjectProvider so will be able to contribute NeXus information. On
construction it also creates an NXObjectProvider. The
ScannableDeviceConnectorService (which implements IScannableDeviceService)
is used to register it as a scannable. This can also work for objects that are
not GDA scannables (such as nxSource and nxInsertionDevice).
However, note that the following example will only work for the case of adding
metadata to the Nxsample group. A similar approach to the creation of the
NXmonochromator and NXcite entry needs to be taken to
add metadata to the NXentry or NXinstrument groups.
Firstly the getNexus() method is created for the ‘sample’ object. This
creates an NXsample group and adds the nodes and information to it, e.g.
def getNexus(self):
#print "In XpdfSample.getNexus"
nxSample = NexusNodeFactory.createNXsample()
nxSample.setChemical_formula(dnp.array([self.composition])._jdataset())
node = NexusNodeFactory.createDataNode()
node.setDataset(dnp.array([self.rmm])._jdataset())
nxSample.addDataNode('chemical_formula_weight',node)
nxSample.setDensityScalar(self.density)
Then in the mscan.py script they create an NXObjectScannable for the
nxsample using this NXObject created in the above getNexus(). This is
then registered to the ScannableDeviceService and added as the
monitorPerScan field in the mscan call.
testNxSample = NXObjectScannable("testNxSample","sample",sample.getNexus())
getScannableDeviceService().register(testNxSample)
self.monitorsPerScan = self.monitorsPerScan + [testNxSample.getName()]
More information can be found on the i15-1 confluence page.
3. Command line tools in Old Scanning
Static metadata can be added to the NeXus file on the fly before running an experiment using Jython command line tools. To configure the Jython command line tools:
Create a ‘
metashop’ object in Spring configuration as a container to all metadata (this may already exist in the file:GDAMetadata.xmlat root of/config/servers/main/_common/).<bean id="metashop" class="gda.data.metadata.NXMetaDataProvider" > <property name="name" value="metashop"/> </bean>
Add or create a
metashop.pywith the following content:''' This requires GDA 'metashop' object to be defined in Spring configuration on the server as: <bean id="metashop" class="gda.data.metadata.NXMetaDataProvider" /> Created on 20 Mar 2014 @author: fy65 ''' from gda.jython.commands.GeneralCommands import alias from gdascripts.metadata.metadata_commands import meta_add, meta_ll, meta_ls, meta_rm # @UnusedImport from gda.configuration.properties import LocalProperties alias("meta_add") alias("meta_ll") alias("meta_ls") alias("meta_rm") from gda.data.scan.datawriter import NexusDataWriter LocalProperties.set(NexusDataWriter.GDA_NEXUS_METADATAPROVIDER_NAME,"metashop")
Ensure the dependency
gdascripts.metadata.metadata_commandsis available in the workspaceAdd the following lines to your localStation.py
print "-----------------------------------------------------------------------------------------------------------------" print "setup meta-data provider commands:meta_add, meta_ll, meta_ls, meta_rm " from metashop import * # @UnusedWildImport import metashop
This will give you access to the following commands:
add:
meta_add- Command to add a scannable to the items to be put into the scan metadataremove:
meta_rm- Command to remove items to be put into the scan metadatalist with value:
meta_ll- Command to list the items to be put into the scan metadata.list:
meta_ls- Command to list the items to be put into the scan metadata.
Now before running a scan from the Jython console use:
> meta_add("Notes", "Here's some static info")
> scan stage_x 0 10 2
This is added to the group ‘before_scan’ as shown below:
4. NeXus Templating
Adding any metadata to an exiting or in-memory NeXus tree is trivial using the new templating application. By simply constructing a YAML template file like the one below, the information can be added, e.g.
entry/:
NX_class@: NXentry # the '@' has to come at the end as
notes/:
NX_class@: NXnote
Info: "This experiment ran well"
Producing the entry:
Once again, see the templating section for details of how such a template could be applied to a NeXus file using the standalone templating application.









