Skip to content
Snippets Groups Projects
Commit 90bdb4f9 authored by Marina Ganeva's avatar Marina Ganeva
Browse files

Draft of the DNS legacy format loader.

parent f26b6098
No related branches found
No related tags found
No related merge requests found
from mantid.kernel import *
from mantid.api import *
import mantid.simpleapi as api
import numpy as np
from dnsdata import DNSdata
class LoadDNSLegacy(PythonAlgorithm):
"""
Load the DNS Legacy data file to the mantid workspace
"""
def category(self):
"""
"""
return 'DataHandling'
def name(self):
"""
"""
return "LoadDNSLegacy"
def summary(self):
return "Load the DNS Legacy data file to the mantid workspace."
def PyInit(self):
self.declareProperty(FileProperty("Filename", "", FileAction.Load, ['.d_dat']),
"Name of DNS experimental data file.")
self.declareProperty(WorkspaceProperty("OutputWorkspace","",direction=Direction.Output),
doc="Name of the workspace to store the loaded experimental data.")
return
def PyExec(self):
# Input
filename = self.getPropertyValue("Filename")
outws = self.getPropertyValue("OutputWorkspace")
# load data array from the given file
data_array = np.loadtxt(filename)
ndet = 24
#nbins = 1
dataX = np.zeros(ndet)
dataY = data_array[0:ndet,1:]
dataE = np.sqrt(dataY)
# create workspace
__temporary_workspace__ = api.CreateWorkspace(DataX=dataX, DataY=dataY, DataE=dataE, NSpec=ndet,UnitX="Wavelength")
api.LoadInstrument(__temporary_workspace__, InstrumentName='DNS')
# load run information
metadata = DNSdata()
metadata.read_legacy(filename)
run = __temporary_workspace__.mutableRun()
run.setStartAndEndTime(DateAndTime(metadata.start_time), DateAndTime(metadata.end_time))
self.setProperty("OutputWorkspace", __temporary_workspace__)
self.log().debug('LoadDNSLegacy: OK')
api.DeleteWorkspace(__temporary_workspace__)
return
def getEnergy(wavelength):
"""
Calculates neutron energy in eV from the given wavelength in Angstrom
"""
return (1e-3*81.73 / wavelength**2)
# Register algorithm with Mantid
AlgorithmFactory.subscribe(LoadDNSLegacy)
import os, sys
import numpy as np
import datetime
sys.path.append('/Users/ganeva/build/parse/parse-1.6.6')
from parse import *
class DNSdata:
"""
class which describes the DNS data structure
will be used for data read-in and write-out routines
"""
def __init__(self):
self.title = ""
self.experiment_number = ""
self.run_number = ""
self.start_time = ""
self.end_time = ""
self.duration = None
self.deterota = 0
self.wavelength = None # Angstrom
self.ndet = 24
self.sample_name = ""
self.userid = ""
self.user_name = ""
self.sample_description = ""
self.coil_status = ""
self.befilter_status = ""
self.notes = ""
self.monochromator_angle = None # degree
self.monochromator_position = None
self.huber = None
self.cradle_lower = None
self.cradle_upper = None
self.slit_i_upper_blade_position = None
self.slit_i_lower_blade_position = None
self.slit_i_left_blade_position = None
self.slit_i_right_blade_position = None
self.slit_f_upper_blade_position = None
self.slit_f_lower_blade_position = None
self.detector_position_vertical = None
self.polarizer_translation = None
self.polarizer_rotation = None
self.flipper_precession_current = None
self.flipper_z_compensation_current = None
self.a_coil_current = None
self.b_coil_current = None
self.c_coil_current = None
self.z_coil_current = None
self.t1 = None # T1
self.t2 = None # T2
self.tsp = None # T_setpoint
self.tof_channel_number = None
self.tof_channel_width = None
self.tof_delay_time = None
self.tof_elastic_channel = None
self.chopper_rotation_speed = None
self.chopper_slits = None
self.monitor_counts = None
def read_legacy(self, filename):
"""
reads the DNS legacy ascii file into the DNS data object
"""
with open(filename, 'r') as fhandler:
# read file content and split it into blocks
splitsymbol = '#--------------------------------------------------------------------------'
unparsed = fhandler.read()
blocks = unparsed.split(splitsymbol)
# parse each block
# parse block 0 (header)
# [TODO:] rewrite to get rid of dependence on parse
res = parse("# DNS Data userid={userid},exp={exp_id},file={run_number},sample={sample_name}", blocks[0])
# [TODO:] raise exception on the wrong file format
#if not res:
# print "Wrong file format."
# sys.exit()
self.run_number = res['run_number']
self.experiment_number = res['exp_id']
self.sample_name = res['sample_name']
self.userid = res['userid']
# parse block 1 (general information)
b1splitted = map(str.strip, blocks[1].split('#'))
b1rest = [el for el in b1splitted] # otherwise unexpected behaviour due to the removed lines
for line in b1splitted:
res = parse('User: {user_name}', line)
if res:
self.user_name = res['user_name']
b1rest.remove(line)
res = parse('Sample: {sample_descr}', line)
if res:
self.sample_description = res['sample_descr']
b1rest.remove(line)
res = parse('{coil_status} xyz-coil,', line)
if res:
self.coil_status = res['coil_status']
b1rest.remove(line)
res = parse('{filter_status} Be-filter', line)
if res:
self.befilter_status = res['filter_status']
b1rest.remove(line)
# the rest unparsed lines go to notes for the moment
# [TODO]: parse more information about the sample, e.g. space group etc.
self.notes = ' '.join(b1rest)
# parse block 2 (wavelength and mochromator angle)
# for the moment, only theta and lambda are needed
b2splitted = map(str.strip, blocks[2].split('#'))
# assume that theta and lambda are always on the fixed positions
# assume theta is give in degree, lambda in nm
line = b2splitted[2].split()
self.monochromator_angle = float(line[2])
self.wavelength = float(line[3])*10.0
# parse block 3 (motors position)
b3splitted = map(str.strip, blocks[3].split('#'))
self.monochromator_position = float(b3splitted[2].split()[1])
# DeteRota, angle of rotation of detector bank
self.deterota = float(b3splitted[3].split()[1])
# Huber default units degree
self.huber = float(b3splitted[5].split()[1])
self.cradle_lower = float(b3splitted[6].split()[1])
self.cradle_upper = float(b3splitted[7].split()[1])
# Slit_i, convert mm to meter
self.slit_i_upper_blade_position = 0.001*float(b3splitted[9].split()[2])
self.slit_i_lower_blade_position = 0.001*float(b3splitted[10].split()[1])
self.slit_i_left_blade_position = 0.001*float(b3splitted[11].split()[2])
self.slit_i_right_blade_position = 0.001*float(b3splitted[12].split()[1])
# Slit_f
self.slit_f_upper_blade_position = 0.001*float(b3splitted[14].split()[1])
self.slit_f_lower_blade_position = 0.001*float(b3splitted[15].split()[1])
# Detector_position vertical
self.detector_position_vertical = 0.001*float(b3splitted[16].split()[1])
# Polarizer
self.polarizer_translation = 0.001*float(b3splitted[19].split()[1])
self.polarizer_rotation = float(b3splitted[20].split()[1])
# parse block 4 (B-fields), only currents in A are taken
b4splitted = map(str.strip, blocks[4].split('#'))
self.flipper_precession_current = float(b4splitted[2].split()[1])
self.flipper_z_compensation_current = float(b4splitted[3].split()[1])
self.a_coil_current = float(b4splitted[4].split()[1])
self.b_coil_current = float(b4splitted[5].split()[1])
self.c_coil_current = float(b4splitted[6].split()[1])
self.z_coil_current = float(b4splitted[7].split()[1])
# parse block 5 (Temperatures)
# assume: T1=cold_head_temperature, T2=sample_temperature
b5splitted = map(str.strip, blocks[5].split('#'))
self.t1 = float(b5splitted[2].split()[1])
self.t2 = float(b5splitted[3].split()[1])
self.tsp = float(b5splitted[4].split()[1])
# parse block 6 (TOF parameters)
b6splitted = map(str.strip, blocks[6].split('#'))
self.tof_channel_number = int(b6splitted[2].split()[2])
self.tof_channel_width = float(b6splitted[3].split()[3])
self.tof_delay_time = float(b6splitted[4].split()[2])
self.tof_elastic_channel = int(b6splitted[6].split()[3])
# chopper rotation speed
self.chopper_rotation_speed = float(b6splitted[7].split()[2])
# chopper number of slits
self.chopper_slits = int(b6splitted[5].split()[2])
# parse block 7 (Time and monitor)
# assume everything to be at the fixed positions
b7splitted = map(str.strip, blocks[7].split('#'))
# duration
line = b7splitted[2].split()
self.duration = float(line[1]) # assume seconds [TODO]: check
# monitor data
line = b7splitted[3].split()
self.monitor_counts = int(line[1])
# start_time and end_time
outfmt = "%Y-%m-%dT%H:%M:%S"
sinfmt = "start at %a %b %d %H:%M:%S %Y"
einfmt = "stopped at %a %b %d %H:%M:%S %Y"
self.start_time = datetime.datetime.strptime(b7splitted[5], sinfmt).strftime(outfmt)
self.end_time = datetime.datetime.strptime(b7splitted[6], einfmt).strftime(outfmt)
if __name__== '__main__':
fname = sys.argv[1]
d = DNSdata()
d.read_legacy(fname)
print d.__dict__
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment