Workspace operations and transformations form the heart of Open GENIE. They permit analysis which takes into the account the underlying model of the data from neutron scattering experiments. For example, the Units() command can be used to convert the units of a Time-of-Flight (TOF) spectrum.
This level of knowledge about the data being operated on is only possible if some assumptions are made about the fields which will be present in any workspace containing experimental data. This in turn requires agreement about the contents and names of fields for each kind of data.
By default, Open GENIE workspaces are treated as an enhanced version of the original GENIE-V2 workspace which was based on a one dimensional Time-of-Flight spectrum. In Open GENIE two dimensional workspaces are also supported (i.e. workspaces with a two-dimensional Y-array).
The arithmetic functions (as defined in the Template Routines section) require arrays of X, Y, and error values to be present (a basic histogram). For the Units() command to work, a workspace also requires fields giving parameters such as the primary flight path and incident angle (a TOF spectrum).
In the next sections three topics are discussed before giving a complete listing of the modifiable template routines.
Classification of the basic data models used in the analysis of neutron scattering data is still at a very early stage. Open GENIE is being designed to cope with several detailed classifications when they are developed. So far it only recognises one class of neutron scattering data - the GENIE-V2 style TOF spectrum - but extended to cope with 2-D data. This consists of n-histograms of data and may also contain general annotation information suitable for a plotting and units conversion. In experimental terms a workspace can correspond to a single detector scan (in TOF) or multiple scans as would be collected from a single timed run on a position sensitive detector array (the contents of an ISIS raw data file). Open GENIE is also intended for workspaces with different types of data (eg triple axis Qx, Qy, Qz arrays) and it is only necessary to redefine the template routines to make sense of operations such as w1 + w2 appropriately.
The next section briefly describes how to go about adding a new workspace type. Before doing this, some experience of wrinting Open GENIE procedures in GCL should be gained..
When defining a different class of data there is a special syntax for defining a new type of data workspace with default fields. Lets say for example, that we wish to create a workspace for triple axis data where we can directly plot/compare this data with ISIS TOF data. The steps in this process are given below.
# Defines a new workspace type called Tripleaxis [ Workspace.(subclass="Tripleaxis", fields="QX QY QZ", comment="Triple axis workspace") ]
The string after "subclass" gives the new workspace type name and the fields are specified in a list after "fields" and separated by a single space. This syntax is case sensitive so be sure to use a capital letters where they are used below and nowhere else (anything is OK in the comment string of course).
# Now define any PROCEDURES which operate on these workspaces, for example, # to fill with data, display, convert etc. PROCEDURE example_print PARAMETERS scan=Tripleaxis # we can now type check for only triple axis data printn "Qx = " scan.qx "Qy = " scan.qy "Qx = " scan.qz ENDPROCEDURE
>> my_work = Tripleaxis.new() # note capital T, rest lowercase. >> printn my_work # print out workspace Tripleaxis [Triple axis workspace] ( qx = _ # elements undefined and needing values qz = _ # eg my_work.qx = ... qy = _ )
PROCEDURE Workspace_add; PARAMETERS w1=Workspace w2=Workspace; RESULT=wres IF is_a(w1, "Tripleaxis") wres = my_TA_func(w1, w2) ELSE ... what was here before ENDIF ENDPROCEDURE
If you intend to embark on a project of this sort it is probably worth mailing genie@isise.rl.ac.uk to check that this work has not already been done for your type of data.
This section lists the required fields and types needed in a workspace to "Qualify" as a Histogram, TOFSpectrum or AnnotatedSpectrum.
The field names and requirements are listed here but the distinctions are not made rigidly with separate workspace types at the moment. For example if you try to add two workspaces without Y arrays you will certainly get an error.
Workspace Field | Description | Variable type |
X(1-D) | array of X values | RealArray |
Y(1-D) | array of Y values | RealArray |
E(1-D) | array of errors for Y field | RealArray |
Workspace Field | Description | Variable type |
X(1-D) | array of X values | RealArray |
Y(2-D) | 2-D array of Y values | RealArray |
E(2-D) | 2-D array of errors for Y field | RealArray |
Workspace Field | Description | Variable type |
Histogram + | (all fields in Histogram) | |
L1 | primary flight path (m) | Real |
L2 | secondary flight path (m) | Real |
Twotheta | scattering angle | Real |
Delta | hold off in microseconds | Real |
Emode | energy mode | Real |
Efixed | fixed energy (if applicable) | Real |
Xlabel | Units for X values | String |
Ylabel | Units for Y values | String |
Ut(1-D) | User parameters (this array may be of any length and caters for information not already named in a field | RealArray |
Workspace Field | Description | Variable type |
2DHistogram + | (all fields in 2DHistogram) | |
L1 | primary flight path (m) | Real |
L2(1-D) | secondary flight path (m) | Real |
Twotheta(1-D) | scattering angle | Real |
Delta | hold off in microseconds | Real |
Emode | energy mode | Integer 0=inelastic, 1=incident, 2=transmitted |
Efixed | fixed energy (if applicable) | Real |
Xlabel | Units for X values | String |
Ylabel | Units for Y values | String |
Ut(1-D) | User parameters (this array may be of any length and caters for information not already named in a field) | RealArray |
Workspace Field | Description | Variable type |
TOFSpectrum + | (all fields in TOFspectrum) | |
File | File from which data came | String |
Title | run title | String |
User_name | User name | String |
Time | run start date and time | String |
Run_duration | run duration in seconds | Real |
Spec_no | spectrum number | Integer |
Run_no | run number | String |
Inst_name | instrument name | String |
History | workspace history | String |
Workspace Field | Description | Variable type |
2DTOFSpectrum + | (all fields in TOFspectrum) | |
AnnotatedSpectrum + | (all fields in AnnotatedSpectrum but...) | |
Spec_no(1-D) | spectrum number (this is now an array) | Integer |
The following functions are called whenever an intrinsic operation involving workspaces is specified (for example w1 + w2 will invoke the template routine Workspace_add () with the workspaces as parameters). The purpose of this is to allow customisation of the routines. These functions can be redefined by a (careful) user to take account of any experiment specific data which may be passed in the workspace.
The example with each function description gives the template procedure currently installed in Open GENIE, the aim of these is to broadly approximate the operations implicit in GENIE-V2 and to give an example of how to write the routine and handle the errors as Open GENIE does.
All the template routines are kept together in one file "workspace_user.gcl." By modifying all the template routines in the file, the behaviour of the Open GENIE workspace operations may be completely modified. It is important to maintain the default functionality for each procedure, or at least to be aware of routines which may fail to operate when it is changed!
To activate the changes, the modified copy of "workspace_user.gcl" can be loaded into Open GENIE using the Load command. e.g.
>> Load "SRC/workspace_user.gcl" Loading file SRC/workspace_user.gcl 275 lines scanned/compiled buffer space remaining = 10958
This table lists all the Workspace operations which can be modified.
Unary operations | Description |
Workspace_abs | |w| |
Workspace_arccos | acos(w) |
Workspace_arcsin | asin(w) |
Workspace_arctan | atan(w) |
Workspace_coerce | Defines how workspaces combine with other types, e.g. w1 * 4.0 |
Workspace_cos | cos(w) |
Workspace_exp | exp(w) |
Workspace_ln | ln(w) |
Workspace_log | log(w) |
Workspace_negated | -w |
Workspace_not | NOT w |
Workspace_sin | sin(w) |
Workspace_sqrt | sqrt(w) |
Workspace_tan | tan(w) |
Binary Operations | |
Workspace_add | w1 + w2 |
Workspace_append | End on join of one histogram to another (w1 & w2) |
Workspace_divide | w1 / w2 |
Workspace_raised_to | w1 ^ w2 |
Workspace_subtract | w1 - w2 |
Workspace_modulo | w1 | w2 |
Workspace_multiply | w1 * w2 |
Comparison Operations | |
Workspace_and | w1 AND w2 |
Workspace_equal | w1 = w2 |
Workspace_greater_than | w1 > w2 |
Workspace_greater_than_or_equal | w1 >= w2 |
Workspace_less_than | w1 < w2 |
Workspace_less_than_or_equal | w1 <= w2 |
Workspace_not_equal | w1 != w2 |
Workspace_or | w1 OR w2 |
Called by the generic function Acos(x) when x is of type Workspace.
WORKSPACE_ARCCOS() | w1=Workspace | acos(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_arccos; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = arccos(w1.y) wres.e = w1.e / sqrt( 1 - w1.y^2 ) ENDPROCEDURE
Called by the generic function Asin(x) when x is of type Workspace.
WORKSPACE_ARCSIN() | w1=Workspace | asin(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_arcsin; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = arcsin(w1.y) wres.e = w1.e / sqrt( 1 - w1.y^2 ) ENDPROCEDURE
Called by the generic function Atan(x) when x is of type Workspace.
WORKSPACE_ARCTAN() | w1=Workspace | atan(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_arctan; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = arctan(w1.y) wres.e = w1.e / sqrt( 1 - w1.y^2 ) ENDPROCEDURE
Called to convert numbers and arrays automatically in to workspaces.
WORKSPACE_COERCE() | something=Any | convert "something" into a workspace (if possible) |
The default procedure definition and the calculation of errors for this procedure is shown below. This routine is called whenever a mixed type expression involving workspaces requires to convert the NON workspace parameter into a workspace. The result will always be a workspace
This is procedure is best not changed without a good understanding of how it works. It is not likely to be necessary to alter this when defining a new type of workspace.
PROCEDURE workspace_coerce; PARAMETERS something; RESULT wres LOCAL self # assign self to be the current workspace object to allow sizing & copying to the new one %( gXself _ line at: 1 )% wres=fields() # new a workspace # these cases shouldn't be able to happen IF is_a(something, "workspace") OR is_a(something, "workspacearray") printen "Coercion failure - workspace(array) -> workspace" ELSE wres = self # copy all workspace fields wres.ylabel = "(dimensionless)" fill wres.e 0.0 wres.y = fill(wres.y, 0.0) + something # use array coercion to fill the workspace ENDIF ENDPROCEDURE
Called by the generic function Cos(x) when x is of type Workspace.
WORKSPACE_COS() | w1=Workspace | cos(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_cos; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = cos(w1.y) wres.e = abs( sin(w1.y) * w1.e ) ENDPROCEDURE
Called by the generic function Exp(x) when x is of type Workspace.
WORKSPACE_EXP() | w1=Workspace | exp(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_exp; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = exp(w1.y) wres.e = w1.e * wres.y ENDPROCEDURE
Called by the generic function ln(x) when x is of type Workspace.
WORKSPACE_LN() | w1=Workspace | ln(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_ln; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = ln(w1.y) wres.e = w1.e/w1.y ENDPROCEDURE
Called by the generic function log(x) when x is of type Workspace.
WORKSPACE_LOG() | w1=Workspace | log(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_log; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = log(w1.y) wres.e = w1.e/(w1.y * ln(10.0)) ENDPROCEDURE
Called by the generic function -x when x is of type Workspace.
WORKSPACE_NEGATED() | w1=Workspace | -w |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_negated; PARAMETERS w1=workspace; RESULT wres wres=w1 wres.y = -w1.y ENDPROCEDURE
Called by the generic function NOT x when x is of type Workspace.
WORKSPACE_NOT() | w1=Workspace | NOT w |
The default procedure definition and the calculation of errors for this procedure is shown below. This function does not have a useful implementation currently. This is really only included for the sake of completeness as the syntax does allow it to be called.
PROCEDURE workspace_not; PARAMETERS w1=workspace; RESULT wres printen "Operation NOT is not defined for workspaces" ENDPROCEDURE
Called by the generic function Sin(x) when x is of type Workspace.
WORKSPACE_SIN() | w1=Workspace | sin(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_sin; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = sin(w1.y) wres.e = abs( cos(w1.y) * w1.e ) ENDPROCEDURE
Called by the generic function Sqrt(x) when x is of type Workspace.
WORKSPACE_SQRT() | w1=Workspace | sqrt(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_sqrt; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = sqrt(w1.y) wres.e = w1.e / (2.0 * wres.y) ENDPROCEDURE
Called by the generic function Tan(x) when x is of type Workspace.
WORKSPACE_TAN() | w1=Workspace | tan(w) |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_tan; PARAMETERS w1=workspace; RESULT wres wres = w1 wres.y = tan(w1.y) wres.e = w1.e/(cos(w1.y)^2) ENDPROCEDURE
Called by the generic function x + y when x and y are of type Workspace.
WORKSPACE_ADD() | w1=Workspace w2=Workspace | w1 + w2 |
The default procedure definition and the calculation of errors for this procedure is shown below. Note that the characteristics of the Left hand workspace are those that define the resultant workspace (ie final length, dimensionality of arrays).
PROCEDURE workspace_add; PARAMETERS w1=workspace w2=workspace; RESULT wres IF (w1.x = w2.x) AND (w1.xlabel = w2.xlabel) wres = w1 wres.y = w1.y + w2.y wres.e = sqrt( w1.e*w1.e + w2.e*w2.e ) ELSE printen "Workspaces are not compatible - please re-bin" ENDIF ENDPROCEDURE
Called by the generic function x & y (append) when x and y are of type Workspace.
WORKSPACE_APPEND() | w1=Workspace w2=Workspace | w1 & w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_append; PARAMETERS w1=workspace w2=workspace; RESULT wres LOCAL lenx1 lenx2 leny1 leny2 lenx1 = length(w1.x) lenx2 = length(w2.x) leny1 = length(w1.y) leny2 = length(w2.y) IF (Max(w1.x) = Min(w2.x)) wres = w1 wres.x = w1.x & w2.x[2:lenx2] wres.y = w1.y & w2.y wres.e = w1.e & w2.e ELSEIF (leny1 = lenx1) OR (leny2 = lenx2) printen "Error - both workspaces must be histograms" ELSE printen "Error - Start and end X values must match" ENDIF ENDPROCEDURE
Called by the generic function x / y when x and y are of type Workspace.
WORKSPACE_DIVIDE() | w1=Workspace w2=Workspace | w1 / w2 |
The default procedure definition and the calculation of errors for this procedure is shown below. Note that the characteristics of the Left hand workspace are those that define the resultant workspace (ie final length, dimensionality of arrays).
PROCEDURE workspace_divide; PARAMETERS w1=workspace w2=workspace; RESULT wres IF (w1.x = w2.x) AND (w1.xlabel = w2.xlabel) wres = w1 wres.y = w1.y / w2.y wres.e = sqrt( wres.y * ((w1.e/w1.y)^2 + (w2.e/w2.y)^2) ) IF w2.ylabel != "(dimensionless)" wres.ylabel = "(dimensionless)" ENDIF ELSE printin "Workspaces are not compatible - please re-bin" ENDIF ENDPROCEDURE
Called by the generic function x ^ y when x and y are of type Workspace.
WORKSPACE_RAISED_TO() | w1=Workspace w2=Workspace | w1 ^ w2 |
The default procedure definition and the calculation of errors for this procedure is shown below. Note that the characteristics of the Left hand workspace are those that define the resultant workspace (ie final length, dimensionality of arrays).
PROCEDURE workspace_raised_to; PARAMETERS w1=workspace w2=workspace; RESULT wres IF (w1.x = w2.x) AND (w1.xlabel = w2.xlabel) wres = w1 wres.y = w1.y ^ w2.y wres.e = sqrt( (ln(w1.y) * (w2.e))^2 + ((w2.y/w1.y) * w1.e)^2 ) ELSE printin "Workspaces are not compatible - please re-bin" ENDIF ENDPROCEDURE
Called by the generic function x - y when x and y are of type Workspace.
WORKSPACE_SUBTRACT() | w1=Workspace w2=Workspace | w1 - w2 |
The default procedure definition and the calculation of errors for this procedure is shown below. Note that the characteristics of the Left hand workspace are those that define the resultant workspace (ie final length, dimensionality of arrays).
PROCEDURE workspace_subtract; PARAMETERS w1=workspace w2=workspace; RESULT wres IF (w1.x = w2.x) AND (w1.xlabel = w2.xlabel) wres = w1 wres.y = w1.y - w2.y wres.e = sqrt( w1.e*w1.e + w2.e*w2.e ) ELSE printin "Workspaces are not compatible - please re-bin" ENDIF ENDPROCEDURE
Called by the generic function x | y when x and y are of type Workspace.
WORKSPACE_MODULO() | w1=Workspace w2=Workspace | w1 | w2 |
The default procedure definition and the calculation of errors for this procedure is shown below. Note that the characteristics of the Left hand workspace are those that define the resultant workspace (ie final length, dimensionality of arrays).
PROCEDURE workspace_modulo; PARAMETERS w1=workspace w2=workspace; RESULT wres IF (w1.x = w2.x) AND (w1.xlabel = w2.xlabel) wres = w1 wres.y = w1.y | w2.y wres.e = sqrt( wres.y * ((w1.e/w1.y)^2 + (w2.e/w2.y)^2) ) # errors as for divide or wres.ylabel = "(dimensionless)" ELSE printin "Workspaces are not compatible - please re-bin" ENDIF ENDPROCEDURE
Called by the generic function x * y when x and y are of type Workspace.
WORKSPACE_MULTIPLY() | w1=Workspace w2=Workspace | w1 * w2 |
The default procedure definition and the calculation of errors for this procedure is shown below. Note that the characteristics of the Left hand workspace are those that define the resultant workspace (ie final length, dimensionality of arrays).
PROCEDURE workspace_multiply; PARAMETERS w1=workspace w2=workspace; RESULT wres IF (w1.x = w2.x) AND (w1.xlabel = w2.xlabel) wres = w1 wres.y = w1.y * w2.y wres.e = sqrt((w1.y*w2.e)^2 + (w2.y*w1.e)^2) ELSE printin "Workspaces are not compatible - please re-bin" ENDIF ENDPROCEDURE
Called by the generic function x AND y when x and y are of type Workspace.
WORKSPACE_AND() | w1=Workspace w2=Workspace | w1 AND w2 |
The default procedure definition and the calculation of errors for this procedure is shown below. This function does not have a useful implementation currently. This is really only included for the sake of completeness as the syntax does allow it to be called.
PROCEDURE workspace_and; PARAMETERS w1=workspace w2=workspace; RESULT wres printin "Operation AND is not defined for workspaces" ENDPROCEDURE
Called by the generic function x = y when x and y are of type Workspace.
WORKSPACE_EQUAL() | w1=Workspace w2=Workspace | w1 = w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_equal; PARAMETERS w1=workspace w2=workspace; RESULT wres wres = (w1.x = w2.x) AND (w1.xlabel = w2.xlabel) AND ( w1.y = w2.y ) ENDPROCEDURE
Called by the generic function x > y when x and y are of type Workspace.
WORKSPACE_GREATER_THAN() | w1=Workspace w2=Workspace | w1 > w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_greater_than; PARAMETERS w1=workspace w2=workspace; RESULT wres printin "w1 > w2 is not currently defined for workspaces" ENDPROCEDURE
Called by the generic function x >= y when x and y are of type Workspace.
WORKSPACE_GREATER_THAN_OR_EQUAL() | w1=Workspace w2=Workspace | w1 >= w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_greater_than_or_equal; PARAMETERS w1=workspace w2=workspace; RESULT wres printin "w1 >= w2 is not currently defined for workspaces" ENDPROCEDURE
Called by the generic function x < y when x and y are of type Workspace.
WORKSPACE_LESS_THAN() | w1=Workspace w2=Workspace | w1 < w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_less_than_or_equal; PARAMETERS w1=workspace w2=workspace; RESULT wres printin "w1 <= w2 is not currently defined for workspaces" ENDPROCEDURE
Called by the generic function x <= y when x and y are of type Workspace.
WORKSPACE_LESS_THAN_OR_EQUAL() | w1=Workspace w2=Workspace | w1 <= w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_less_than_or_equal; PARAMETERS w1=workspace w2=workspace; RESULT wres printin "w1 <= w2 is not currently defined for workspaces" ENDPROCEDURE
Called by the generic function x != y when x and y are of type Workspace.
WORKSPACE_NOT_EQUAL() | w1=Workspace w2=Workspace | w1 != w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_not_equal; PARAMETERS w1=workspace w2=workspace; RESULT wres wres = ( w1.x != w2.x ) OR ( w1.y != w2.y ) ENDPROCEDURE
Called by the generic function x OR y when x and y are of type Workspace.
WORKSPACE_OR() | w1=Workspace w2=Workspace | w1 OR w2 |
The default procedure definition and the calculation of errors for this procedure is shown below.
PROCEDURE workspace_or; PARAMETERS w1=workspace w2=workspace; RESULT wres printin "Operation OR is not defined for workspaces" ENDPROCEDURE