Skip to content
Snippets Groups Projects
ConvertToMD-v1.rst 12.1 KiB
Newer Older
.. relatedalgorithms::
The algorithm is used transform existing :ref:`Event <EventWorkspace>` 
or :ref:`Matrix <MatrixWorkspace>` workspace into 
`Multidimensional workspace <http://www.mantidproject.org/MDEventWorkspace>`__ using
`MD Transformations Factory <http://www.mantidproject.org/MD_Transformation_factory>`_. 

If  the target workspace does not exist, the algorithm creates `MDEventWorkspace <http://www.mantidproject.org/MDEventWorkspace>`__
with selected dimensions, e.g. the reciprocal space of momentums **(Qx, Qy, Qz)** or momentums modules **\|Q|**, energy transfer **dE** if available 
and any other user specified log values which can be treated as dimensions. If the target workspace do exist, 
the **MD Events** are added to this workspace.

Using the FileBackEnd and Filename properties the algorithm can produce a file-backed workspace.
Note that this will significantly increase the execution time of the algorithm.

The algorithm uses :ref:`Unit Factory <Unit Factory>` and existing unit
conversion procedures from the input Workspace :ref:`units <Unit Factory>` 
to the :ref:`units <Unit Factory>` , necessary
for transformation into correspondent **MD Event workspace**. It also uses
:ref:`algm-PreprocessDetectorsToMD` algorithm to help
with transformation to reciprocal space.

If min, max or both lists of values (properties 12 and 13) for the
algorithm are not specified,
:ref:`algm-ConvertToMDMinMaxLocal` is used to estimate
missing min-max values. This algorithm is also used to calculate min-max
values if specified min-max values are deemed incorrect (e.g. less
values then dimensions or some min values are bigger then max values)

:math:`l = (extents) / (SplitInto^{MaxRecursionDepth}).`

Notes
-----

#. For elastic analysis (:math:`dEAnalysisMode=Elastic`) the target
   :ref:`unit <Unit Factory>` is momentum :math:`k`.
#. For no analysis (CopyToMD) mode, the units remain the one, previously
   defined along the workspace's axes.
#. When units of input Matrix 2D workspace (Histogram workspace) are not
   Momentums for Elastic or EnergyTransfer for inelastic mode, the
   algorithm uses internal unit conversion of input X-values based on
   central average of a bin ranges. Namely, value
   :math:`X_c = 0.5*(X_i+X_{i+1})` is calculated and converted to
   Momentum or EnergyTransfer correspondingly. This can give slightly
   different result from the case, when input workspace has been
   converted into correspondent units before converting to MDEvents.
#. Confusing message "Error in execution of algorithm ConvertToMD: emode
   must be equal to 1 or 2 for energy transfer calculation" is generated
   when one tries to process the results of inelastic scattering
   experiment in elastic mode. This message is generated by units
   conversion routine, which finds out that one of the workspace axis is
   in :ref:`unit <Unit Factory>` of DeltaE. These units can not be directly
   converted into momentum or energy, necessary for elastic mode. Select
   Direct or Indirect mode and integrate over whole energy transfer
   range to obtain MD workspace, which would correspond to an Elastic
   mode.
#. A good guess on the limits can be obtained from the
   :ref:`algm-ConvertToMDMinMaxLocal` algorithm.

How to write custom ConvertToMD plugin
--------------------------------------

This information intended for developers who have at least basic
knowledge of C++ and needs to write its own
plugin using `custom ConvertTo MD transformation <http://www.mantidproject.org/Writing_custom_ConvertTo_MD_transformation>`__.

Usage examples
--------------

The examples below demonstrate the usages of the algorithm in most
common situations. They work with the data files which already used by
Mantid for different testing tasks.


**Example - Convert re-binned MARI 2D workspace to 3D MD workspace for further analysis/merging with data at different temperatures :**

.. testcode:: ExConvertToMDNoQ
    
   # Load Operation (disabled in test code)
   # Load(Filename='MAR11001.nxspe',OutputWorkspace='MAR11001')
   # Simulates Load of the workspace above #################
   redWS = CreateSimulationWorkspace(Instrument='MAR',BinParams=[-10,1,10],UnitX='DeltaE',OutputWorkspace='MAR11001')
   AddSampleLog(redWS,LogName='Ei',LogText='12.',LogType='Number');
   # Do fine rebinning, which accounts for poligon intersections
   SofQW3(InputWorkspace='MAR11001',OutputWorkspace='MAR11001Qe2',QAxisBinning='0,0.1,7',EMode='Direct')
   AddSampleLog(Workspace='MAR11001Qe2',LogName='T',LogText='100.0',LogType='Number Series')
   # copy to new MD workspace
   ws=ConvertToMD(InputWorkspace='MAR11001Qe2',OutputWorkspace='MD3',QDimensions='CopyToMD',OtherDimensions='T',\
   MinValues='-10,0,0',MaxValues='10,6,500',SplitInto='50,50,5')

   
   #Output **MD3** workspace can be viewed in slice-viewer as 3D workspace with T-axis having single value.   
   #Visualize 3D data using slice viewer:
   #plotSlice(ws)
   
   # Look at sample results:   
   # A way to look at these results as a text:
   print("Resulting MD workspace has {0} events and {1} dimensions".format(ws.getNEvents(),ws.getNumDims()))
   print("--------------------------------------------")

    
.. testcleanup:: ExConvertToMDNoQ

   DeleteWorkspace('MAR11001')
   DeleteWorkspace('MAR11001Qe2')   
   DeleteWorkspace('MD3')      
   DeleteWorkspace('PreprocessedDetectorsWS')   

**Output:**

.. testoutput:: ExConvertToMDNoQ

   Resulting MD workspace has 805 events and 3 dimensions
   --------------------------------------------
**Example - Convert Set of Event Workspaces (Horace scan) to 4D MD workspace, direct mode:**
Meaningfull results can be obtained on the basis of CNCS\_7860\_event.nxs file, available in Mantid
test folder. The script below simulates workspace loading but would produce meaningfill result if real experimental data
obtained in an experiment and stored in nxspe files are provided to it.
.. testcode:: ExConvertToMDQ3D
   import os
   # set up target ws name and remove target workspace with the same name which can occasionally exist.
   # list of MD files (workspaces) to combine into target MD workspace
   MD_FilesList='';
   
   # define convetr to MD parameters
   pars = dict();
   pars['InputWorkspace']=''
   pars['QDimensions']='Q3D'
   pars['dEAnalysisMode']='Direct'
   pars['Q3DFrames']='HKL'
   pars['QConversionScales']='HKL'
   pars['PreprocDetectorsWS']='preprDetMantid'
   pars['MinValues']='-3,-3,-3.,-50.0'
   pars['MaxValues']='3.,3.,3.,50.0'
   pars['SplitInto']=50
   pars['MaxRecursionDepth']=1
   pars['MinRecursionDepth']=1
   pars['OverwriteExisting']=1  # Change this to false, if the files should/can be added in memory
   # test script combines all contributed files in memory
   pars['OverwriteExisting']=0  # Change this to false, if the files should/can be added in memory
   #
   #---> Start loop over contributing files 
        source_file = 'MER19566_22.0meV_one2one125.nxspe'; # redefine source files list as function of loop number
        target  = 'MDMAP_T1'+str(n)+'.nxs';
        # check if the file already been converted to MD and is there
        if not(os.path.exists(target )): 
            print('Converting  {}'.format(source_file))
            #current_ws=LoadNXSPE(Filename=source)
            #### For the sample script, simulate load operation above 
            current_ws = CreateSimulationWorkspace(Instrument='MAR',BinParams=[-3,1,3],UnitX='DeltaE',OutputWorkspace=source_file)
            AddSampleLog(Workspace=current_ws,LogName='Ei',LogText='3.0',LogType='Number')

            #### Add iformation which is not stored in the nxspe file
            # Add UB matrix (lattice and the beam direction)
            SetUB(Workspace=current_ws,a='1.4165',b='1.4165',c='1.4165',u='1,0,0',v='0,1,0')
            # Add crystal rotation (assume rotation abgle Psi=5*n where n is file number. Define list of angles if this is not correct
            AddSampleLog(Workspace=current_ws,LogName='Psi',LogText=str(5*n)+'.',LogType='Number')  # --correct Psi value may be already in nxspe file. This operation is then unnecessary
            # set crystal rotation 
            SetGoniometer(Workspace=current_ws,Axis0='Psi,0,1,0,1')

            # Convert to MD
            pars['InputWorkspace']=current_ws;
            md_ws=ConvertToMD(**pars)

            # save MD for further usage -- disabled in test script
            #SaveMD(md_ws,Filename=target);
            #DeleteWorkspace(md_ws);  # delete intermediate workspace to save memory
            DeleteWorkspace(current_ws);

        # add the file name of the file to combine
        if (len(MD_FilesList) == 0):
            MD_FilesList = target;
        else:
            MD_FilesList=MD_FilesList+','+target;
   #---> End loop

   # merge md files into file-based MD workspace
   #md_ws = MergeMDFiles(MD_FilesList,OutputFilename='TestSQW_1.nxs',Parallel='0');
   # plot results using sliceviewer
   #plotSlice(md_ws)
   # produce some test output
   print("Resulting MD workspace contains {0} events and {1} dimensions".format(md_ws.getNEvents(),md_ws.getNumDims()))
   print("--------------------------------------------")
    
.. testcleanup:: ExConvertToMDQ3D
   DeleteWorkspace('md_ws')   
   DeleteWorkspace('preprDetMantid')   
**Output:**

.. testoutput:: ExConvertToMDQ3D
   Converting  MER19566_22.0meV_one2one125.nxspe
   Converting  MER19566_22.0meV_one2one125.nxspe
   Converting  MER19566_22.0meV_one2one125.nxspe
   Converting  MER19566_22.0meV_one2one125.nxspe
   Converting  MER19566_22.0meV_one2one125.nxspe
   Resulting MD workspace contains 27540 events and 4 dimensions
   --------------------------------------------


**Example - Convert set of inelastic results obtained in Powder mode (direct) as function of temperature to a 3D workspace:**

This example produces 3-dimensional dataset, with a temperature axis. 

.. testcode:: ExConvertToMD|Q|T

   # set up target ws name and remove target workspace with the same name which can occasionally exist.
   RezWS = 'WS_3D'
   try:
        DeleteWorkspace(RezWS)
   except ValueError:
        print("Target ws  {}  not found in analysis data service\n".format(RezWS))
   
   # define convert to MD parameters
   pars = dict();
   pars['InputWorkspace']=''
   pars['QDimensions']='|Q|'
   pars['dEAnalysisMode']='Direct'
   pars['OtherDimensions']='T'  # make temperature log to be a dimension
   pars['PreprocDetectorsWS']='preprDetMantid'
   pars['MinValues']='0,-10,0'
   pars['MaxValues']='12,10,10'
   pars['SplitInto']='100,100,12'
   pars['OverwriteExisting']=0  # contributed MD worskpaces are added in memory
   
   # let's assume this is the temperature range obtained in experiments and 
   # each data file is obtained for particular temperature. 
   T = [1.0,2.0,3.0,3.5,4.0,5.0,6.0,7.0,8.0,9.0,9.5,10.0]   
   for i in range(0,len(T),1):
        # source = sorurce_file_name[i];
        #current_ws=LoadNXSPE(Filename=source)   
        # EMULATE LOAD OF DIFFERENT results obtained for different temperatures. ------>      
        current_ws = CreateSimulationWorkspace(Instrument='MAR',BinParams=[-3,0.1,3],UnitX='DeltaE')
        AddSampleLog(Workspace=current_ws,LogName='Ei',LogText='3.0',LogType='Number')
        # if the file does not have temperature log, add it here.
        AddSampleLog(Workspace=current_ws,LogName='T',LogText=str(T[i]),LogType='Number Series')        
        # simulate changes in scattering with temperature
        current_ws = current_ws*T[i];
        # END EMULATION ---------------------------------------------------------------------
   
        pars['InputWorkspace']=current_ws;
        md_ws=ConvertToMD(**pars)
        # delete source workspace from memory;
        DeleteWorkspace(current_ws)
    # end loop
   
   # produce some test output
   print("Resulting MD workspace contains {0} events and {1} dimensions".format(md_ws.getNEvents(),md_ws.getNumDims()))
    
.. testcleanup:: ExConvertToMD|Q|T

   DeleteWorkspace(md_ws)   
   DeleteWorkspace('preprDetMantid')   

**Output:**

.. testoutput:: ExConvertToMD|Q|T

   Target ws  WS_3D  not found in analysis data service

   Resulting MD workspace contains 605880 events and 3 dimensions