Skip to content

Commit

Permalink
Refs #113. Added support for HB2B.
Browse files Browse the repository at this point in the history
  • Loading branch information
wdzhou committed Jan 8, 2019
1 parent 1f63969 commit 681354f
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 3 deletions.
166 changes: 166 additions & 0 deletions hb2b_geometry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import sys
import datetime
import helper

# Definition of constants
HB3A_L1 = 2.


HB2B_SETUP = {'L1': 2.678898,
'L2': 0.95, # arm length
'PixelNumber': {'1K': (1024, 1024), '2K': (2048, 2048)},
'PixelSize': {'1K': 0.00029296875, '2K': 0.00029296875*0.5}
}

XRAY_SETUP = {'L1': 2.678898,
'L2': 0.416, # arm length
'PixelNumber': {'1K': (1024, 1024), '2K': (2048, 2048)},
'PixelSize': {'1K': 0.0004000, '2K': 0.0004000*0.5}
}


class HB2BGeometry(helper.MantidGeom):
"""
HB3A geometry extended from MantidGeom
"""
def __init__(self, instname, comment=None, valid_from=None, valid_to=None):
"""
initialization
:param instname: name of instrument
:param comment: comment
:param valid_from: beginning date
:param valid_to: end date
"""
super(HB2BGeometry, self).__init__(instname, comment, valid_from, valid_to)

return

# END-DEF-HB3A


def generate_1bank_2d_idf(instrument_name, geom_setup_dict, pixel_setup, output_idf_name):
""" Generate the general HB2B (or similar X-Ray) IDF file from 2018.12.01
:param instrument_name:
:param geom_setup_dict:
:param pixel_setup:
:param output_idf_name:
:return:
"""
# generate instrument geometry object
authors = ["Wenduo Zhou"]
begin_date = '2018-12-01 00:00:01'
end_date = '2100-10-20 23:59:59'

# boiler plate stuff
hb2b = HB2BGeometry(instrument_name,
comment="Created by " + ", ".join(authors),
valid_from=begin_date,
valid_to=end_date)

# TODO/FIXME - NO HFIR Default
# hb2b.addComment('DEFAULTS')
# hb2b.addHfirDefaults()

# source
hb2b.addComment("SOURCE")
hb2b.addModerator(geom_setup_dict['L1'])
# sample
hb2b.addComment("SAMPLE")
hb2b.addSamplePosition()

# TODO/FIXME - NO Default
# monitor
# hb2b.addComment("MONITORS")
# hb2b.add_monitor_type()

# arm - component
pixel_row_count, pixel_column_count = geom_setup_dict['PixelNumber'][pixel_setup]
arm_loc_dict = {'r-position': {'value': 0.0},
't-position': {'logfile': 'value+0.0', 'id': 'cal::2theta'},
'p-position': {'value': 0.0},
'roty': {'logfile': 'value+0.0', 'id': 'cal::roty'}}

arm_node = hb2b.add_component(type_name='arm', idfillbyfirst='x', idstart=1, idstepbyrow=pixel_column_count)
arm_loc_node = hb2b.add_location('bank1', arm_node, arm_loc_dict)
hb2b.add_parameter('r-position', 0.0, arm_loc_node)

# generate rectangular detector
pixel_size_x = pixel_size_y = geom_setup_dict['PixelSize'][pixel_setup]
x_start = (float(pixel_column_count)*0.5 - 0.5) * pixel_size_x
x_step = - pixel_size_x
y_start = -(float(pixel_row_count)*0.5 - 0.5) * pixel_size_y
y_step = pixel_size_y
hb2b.addRectangularDetector(name='panel', type='pixel',
xstart='{}'.format(x_start), xstep='{}'.format(x_step),
xpixels='{}'.format(pixel_column_count),
ystart='{}'.format(y_start), ystep='{}'.format(y_step),
ypixels='{}'.format(pixel_row_count))

hb2b.write_terminal()

return

# add detectors
hb2b.addComment('Define detector banks')
hb2b.addComponent(type_name='detectors', idlist='detectors')
# define detector type
hb2b.add_banks_type(name='detectors',
components=['bank1'])

# define center bank
hb2b.addComment('Define Centre Bank')
hb2b.add_bank(name='bank1', component_name='square256detector',
x=2.0, y=0., z=0., rot=90)

# 20 x 8 packs
hb2b.addComment('256 x 256 pack')
hb2b.angler_detector(name='square256detector', num_linear_pixel=256, tube_x=0.01)

# write file
hb2b.writeGeom(output_idf_name)

return


def main(argv):
""" Main
:param argv:
:return:
"""
if len(argv) < 3:
print ('Generate HB2B IDF: {} [hb2b [xray]] [1k [2k]]'.format(argv[0]))
sys.exit(0)

instrument = argv[1]
if instrument == 'hb2b':
geom_setup_dict = HB2B_SETUP
instrument_name = 'HB2B'
elif instrument == 'xray':
geom_setup_dict = XRAY_SETUP
instrument_name = 'XRAY'
else:
print ('[ERROR] Instrument {} is not supported.'.format(instrument))
sys.exit(-1)

# about the number of pixels setup
pixel_setup = argv[2]
if pixel_setup == '1k':
pixel_setup = '1K'
elif pixel_setup == '2k':
pixel_setup = '2K'
else:
print ('[ERROR] Pixel setup {} is not supported.'.format(pixel_setup))

# create instrument
now = datetime.datetime.now()

output_idf_name = '{}_Definition_{:04}{:02}{:02}_{:02}{:02}.xml' \
''.format(instrument_name, now.year, now.month, now.day,
now.hour, now.minute)
generate_1bank_2d_idf(instrument_name, geom_setup_dict, pixel_setup, output_idf_name)

return


if __name__ == '__main__':
main(sys.argv)
95 changes: 92 additions & 3 deletions helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
XSI = "http://www.w3.org/2001/XMLSchema-instance"
SCHEMA_LOC = "http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"

class MantidGeom:
class MantidGeom(object):

def __init__(self, instname, comment=None, valid_from=None, valid_to=None):
from datetime import datetime
Expand All @@ -36,6 +36,15 @@ def __init__(self, instname, comment=None, valid_from=None, valid_to=None):
else:
self.__root.append(le.Comment(comment))

def write_terminal(self):
"""
write the current content to terminal
:return:
"""
print (le.tostring(self.__root, pretty_print=True, xml_declaration=True))

return

def writeGeom(self, filename):
"""
Write the XML geometry to the given filename
Expand Down Expand Up @@ -246,15 +255,95 @@ def addComponent(self, type_name, idlist=None, root=None, blank_location=True):
root = self.__root

if idlist is not None:
comp = le.SubElement(root, "component", type=type_name,
idlist=idlist)
comp = le.SubElement(root, "component", type=type_name, idlist=idlist)
else:
comp = le.SubElement(root, "component", type=type_name)

l=comp
if blank_location:
l = le.SubElement(comp, "location")
return l

def add_component(self, type_name, idfillbyfirst, idstart, idstepbyrow, root=None):
""" add an component
:param type_name:
:param idfillbyfirst:
:param idstart:
:param idstepbyrow:
:param root:
:return:
"""
if root is None:
root = self.__root

comp = le.SubElement(root, 'component', type=type_name,
idfillbyfirst='{}'.format(idfillbyfirst),
idstart='{}'.format(idstart),
idstepbyrow='{}'.format(idstepbyrow))

return comp

def add_location(self, location_name, node, location_param_dict):
""" add an location
:param location_name:
:param node
:return:
"""
location_node = le.SubElement(node, 'location', name=location_name)

for param_name in location_param_dict:
if 'value' in location_param_dict[param_name]:
# write parameter value
param_value = location_param_dict[param_name]['value']
self.add_parameter(param_name, param_value, location_node)
elif 'logfile' in location_param_dict[param_name]:
# write logfile
log_equation = location_param_dict[param_name]['logfile']
log_name = location_param_dict[param_name]['id']
self.add_log_file(param_name, log_equation, log_name, location_node)
else:
raise RuntimeError('Either value or logfile must be in location parameter dict')
# END-IF-ELSE
# END-FOR

return location_node

def add_parameter(self, par_name, par_value, node):

param_node = le.SubElement(node, 'parameter', name=par_name)
le.SubElement(param_node, 'value', val='{}'.format(par_value))

return param_node

def add_log_file(self, par_name, log_equation, log_id, root_node):

log_file_node = le.SubElement(root_node, 'parameter', name=par_name)
le.SubElement(log_file_node, 'logfile', eq=log_equation, id=log_id)

return log_file_node

"""
<component idfillbyfirst="x" idstart="1" idstepbyrow="1024" type="arm">
<location name="bank1">
<parameter name="r-position">
<value val='0.0'/>
<!--logfile eq="1.0*value+0.950" id="cal::arm"/-->
</parameter>
<parameter name="t-position">
<logfile eq="value+0.0" id="cal::2theta"/>
</parameter>
<parameter name="p-position">
<value val="0.0"/>
</parameter>
<parameter name="roty">
<logfile eq="value+0.0" id="cal::roty"/>
</parameter>
</location>
</component>
"""

def addComponentILL(self, type_name, x, y, z, isType=None, root=None):
"""
Add a component with location to the XML definition.
Expand Down

0 comments on commit 681354f

Please sign in to comment.