From a5414f1cdd1066f7290816eb7be86731c85746a1 Mon Sep 17 00:00:00 2001 From: Wenduo Zhou Date: Thu, 23 May 2019 00:26:56 -0400 Subject: [PATCH] Refs #113 and #121. Checkpointing improvement on HB2B generator (ready to test) and HB3A. --- hb2b_geometry.py | 51 +++++++-------- hb3a_geometry.py | 162 ++++++++++++++++++++++++++++++++--------------- helper.py | 36 +++++++++++ 3 files changed, 173 insertions(+), 76 deletions(-) diff --git a/hb2b_geometry.py b/hb2b_geometry.py index 39e7e34..e6bf3fe 100644 --- a/hb2b_geometry.py +++ b/hb2b_geometry.py @@ -42,27 +42,6 @@ def __init__(self, instname, comment=None, valid_from=None, valid_to=None): return - def add_rectangular_detector(self, x_start, x_step, x_pixels, - y_start, y_step, y_pixels, - pixel_size_x, pixel_size_y, pixel_size_z): - """ Add a rectangular detector - """ - # add detector panel - self.addRectangularDetector(name='shiftpanel', type='pixel', - xstart='{}'.format(x_start), xstep='{}'.format(x_step), - xpixels='{}'.format(x_pixels), - ystart='{}'.format(y_start), ystep='{}'.format(y_step), - ypixels='{}'.format(y_pixels)) - - # add pixels - self.addCuboidPixel(name='pixel', shape_id='pixel-shape', - lfb_pt=(pixel_size_x*0.5, -pixel_size_y*0.5, 0), # left-front-bottom - lft_pt=(pixel_size_x*0.5, pixel_size_y*0.5, 0), # left-front-top - lbb_pt=(pixel_size_x*0.5, -pixel_size_y*0.5, -pixel_size_z), # left-back-bottom - rfb_pt=(-pixel_size_x*0.5, -pixel_size_y*0.5, 0) # right-front-bottom - ) - - return # END-DEF-HB3A @@ -153,17 +132,36 @@ def generate_1bank_2d_idf(instrument_name, geom_setup_dict, pixel_setup, output_ return -def generate_2d_configure(instrument_name, geom_setup_dict, pixel_setup, output_pyrs_name): - """ +def generate_2d_configure(instrument_name, geom_setup_dict, pixel_setup, hydra_idf_name): + """ Generate an ASCII file for the instrument configuration + Here is the example: + ``` # ASCII instrument configuration file for 2K detector (2048 x 2048) - arm = 0.416 rows = 2048 columns = 2048 pixel_size_x = 0.0002 pixel_size_y = 0.0002 + ``` + :param instrument_name: + :param geom_setup_dict: + :param pixel_setup: + :param hydra_idf_name: + :return: """ - # TODO - TONIGHT 0 - Also output ... + pixel_row_count, pixel_column_count = geom_setup_dict['PixelNumber'][pixel_setup] + + config_str = '# Instrument configuration file for {} ({})\n'.format(instrument_name, pixel_setup) + config_str += 'arm = {}\n'.format(geom_setup_dict['arm']) + config_str += 'rows = {}\n'.format(pixel_row_count) + config_str += 'columns = {}\n'.format(pixel_column_count) + config_str += 'pixel_size_x = {}\n'.format(geom_setup_dict['PixelSize'][pixel_setup]) + config_str += 'pixel_size_y = {}\n'.format(geom_setup_dict['PixelSize'][pixel_setup]) + + # write out + idf_file = open(hydra_idf_name, 'w') + idf_file.write(config_str) + idf_file.close() return @@ -206,6 +204,9 @@ def main(argv): output_idf_name = '{}_Definition_{:04}{:02}{:02}_{:02}{:02}.xml' \ ''.format(instrument_name, now.year, now.month, now.day, now.hour, now.minute) + output_config_name = '{}_Definition_{:04}{:02}{:02}_{:02}{:02}.txt' \ + ''.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) generate_2d_configure(instrument_name, geom_setup_dict, pixel_setup, output_config_name) diff --git a/hb3a_geometry.py b/hb3a_geometry.py index 7712f23..8a0916f 100644 --- a/hb3a_geometry.py +++ b/hb3a_geometry.py @@ -5,13 +5,19 @@ # Definition of constants HB3A_L1 = 2. +# TODO - Need to separate FourCircle_256_SETUP and FourCircle_512_SETUP +# TODO - Unify the dictioanry layout! FourCircle_SETUP = {'L1': 2.0, 'L2': 0.3750, # arm length - 'PixelNumber': {256: (256, 256), 512: (512, 512)}, + 'PixelNumber': {1: (256, 256)}, 'PixelSize': {256: xx, 512: 0.0002265625}, + 'Panel Center': {1: (0, -Y), 2: (0, 0), 3: (0, Y)}, } -ZEBRA_SETUP = {} +ZEBRA_SETUP = {'L1': 2.0, + 'L2': 0.3750, # arm length + 'PixelNumber': {256: (256, 256)}, + 'PixelSize': {256: xx}} DEMAND_SETUP = {'L1': 2.0, 'L2': 0.3750, @@ -20,8 +26,7 @@ } - -class HB3AGeometry(helper.MantidGeom): +class DemandGeometry(helper.MantidGeom): """ HB3A geometry extended from MantidGeom """ @@ -33,65 +38,100 @@ def __init__(self, instname, comment=None, valid_from=None, valid_to=None): :param valid_from: beginning date :param valid_to: end date """ - super(HB3AGeometry, self).__init__(instname, comment, valid_from, valid_to) + super(DemandGeometry, self).__init__(instname, comment, valid_from, valid_to) return + def add_panel(self, bank_id, geom_setup_dict, cal_shift_x='diffx', cal_shift_y='diffy', + cal_rotx='cal::flip', cal_roty='cal::roty', + cal_rotz='cal::spin'): + # define arm - component + pixel_row_count, pixel_column_count = geom_setup_dict['PixelNumber'][linear_pixel_size] + arm_loc_dict = dict() + arm_loc_dict['r-position'] = {'value': 0.0} + arm_loc_dict['t-position'] = {'value': 0.0} + arm_loc_dict['p-position'] = {'value': 0.0} + arm_loc_dict['roty'] = {'logfile': 'value+0.0', 'id': '2theta'} # roty works as 2theta with experiment + arm_node = self.add_component(type_name='arm', idfillbyfirst='x', idstart=1, + idstepbyrow=pixel_column_count) + arm_loc_node = self.add_location(bank_id, arm_node, arm_loc_dict) + + # define type: arm + arm_type_node = self.add_component_type(type_name='arm') + + # define component panel under type arm + arm_loc_dict = {'z': {'logfile': 'value+{}'.format(geom_setup_dict['L2']), 'id': 'cal::arm'}, + 'rotx': {'logfile': 'value+0.0', 'id': cal_rotx}, + 'roty': {'logfile': 'value+0.0', 'id': cal_roty}, + 'rotz': {'logfile': 'value+0.0', 'id': cal_rotz}, + } + arm_node = self.add_component(type_name='panel', idfillbyfirst=None, idstart=None, + idstepbyrow=None, root=arm_type_node) + self.add_location(None, arm_node, arm_loc_dict) + + # add panel + center_y = geom_setup_dict['Panel Center'][] + panel_loc_dict = {'x': {'logfile': 'value', 'id': cal_shift_x}, + 'y': {'logfile': '{}+value'.format(center_y), 'id': cal_shift_y}} + panel_type_node = self.add_component_type('panel') + panel_node = self.add_component(type_name='shiftpanel', idfillbyfirst=None, idstart=None, + idstepbyrow=None, root=panel_type_node) + scx_instrument.add_location(None, panel_node, panel_loc_dict) + # END-DEF-HB3A -def generate_1_panel_idf(out_file_name): +def generate_1_panel_idf(is_zebra, idf_name, config_name, linear_pixel_size): """ Generate the 1 panel (256 X 256) IDF valid to October 2018 + :param is_zebra: + :param idf_name: + :param config_name: + :param linear_pixel_size: :return: """ - # rot-y --> 2theta - # diffx --> deltax - # diffy --> deltay + if is_zebra: + instrument_name = 'ZEBRA' + geom_setup_dict = ZEBRA_SETUP + else: + instrument_name = 'HB3A' + geom_setup_dict = FourCircle_SETUP # generate instrument geometry object - instrument_name = 'HB3A' authors = ["Wenduo Zhou"] - begin_date = '2015-01-01 00:00:01' - end_date = '2018-10-20 23:59:59' + begin_date = '2018-12-01 00:00:01' + end_date = '2100-10-20 23:59:59' # boiler plate stuff - hb3a = HB3AGeometry(instrument_name, - comment="Created by " + ", ".join(authors), - valid_from=begin_date, - valid_to=end_date) - - hb3a.addComment('DEFAULTS') - hb3a.addHfirDefaults() + scx_instrument = DemandGeometry(instrument_name, + comment="Created by " + ", ".join(authors), + valid_from=begin_date, + valid_to=end_date) # source - hb3a.addComment("SOURCE") - hb3a.addModerator(HB3A_L1) + scx_instrument.addComment("SOURCE") + scx_instrument.addModerator(geom_setup_dict['L1']) # sample - hb3a.addComment("SAMPLE") - hb3a.addSamplePosition() - # monitor - hb3a.addComment("MONITORS") - hb3a.add_monitor_type() - # self._vulcan.addMonitors(distance=[-1.5077], names=["monitor1"]) + scx_instrument.addComment("SAMPLE") + scx_instrument.addSamplePosition() - # add detectors - hb3a.addComment('Define detector banks') - hb3a.addComponent(type_name='detectors', idlist='detectors') - # define detector type - hb3a.add_banks_type(name='detectors', - components=['bank1']) + # Build 'arm'/panel/shiftpanel + scx_instrument.addComment("PANEL") - # define center bank - hb3a.addComment('Define Centre Bank') - hb3a.add_bank(name='bank1', component_name='square256detector', - x=2.0, y=0., z=0., rot=90) + scx_instrument.add_panel() - # 20 x 8 packs - hb3a.addComment('256 x 256 pack') - hb3a.angler_detector(name='square256detector', num_linear_pixel=256, tube_x=0.01) + # generate rectangular detector based on 'shiftpanel' + pixel_size_x = pixel_size_y = geom_setup_dict['PixelSize'][linear_pixel_size] + 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 + scx_instrument.add_rectangular_detector(x_start=x_start, x_step=x_step, x_pixels=pixel_column_count, + y_start=y_start, y_step=y_step, y_pixels=pixel_row_count, + pixel_size_x=pixel_size_x, pixel_size_y=pixel_size_y, + pixel_size_z=0.0001) - # write file - hb3a.writeGeom(out_file_name) + scx_instrument.write_terminal() + scx_instrument.writeGeom(idf_name) return @@ -166,25 +206,45 @@ def main(argv): :return: """ if len(argv) < 2: - print ('Generate HB3A IDF: {} [number of panel [1, 3, zebra]'.format(argv[0])) + print ('Generate HB3A IDF: {} [number of panel [1, 3, zebra] [pixel size (default)]'.format(argv[0])) sys.exit(0) + else: + is_zebra = argv[1].lower() == 'zebra' + if is_zebra: + instrument_name = 'ZEBRA' + else: + instrument_name = 'HB3A' + + # about output file + 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) + instrument_config_name = '{}_Definition_{:04}{:02}{:02}_{:02}{:02}.txt' \ + ''.format(instrument_name, now.year, now.month, now.day, now.hour, now.minute) - is_zebra = argv[1].lower() == 'zebra' if is_zebra: - generate_1_panel_idf(is_zebra) + generate_1_panel_idf(is_zebra, output_idf_name, instrument_config_name, None) else: num_panel = int(argv[1]) - now = datetime.datetime.now() - output_idf_name = 'HB3A_Definition_{:04}{:02}{:02}_{:02}{:02}.xml' \ - ''.format(now.year, now.month, now.day, - now.hour, now.minute) + if num_panel == 1: - generate_1_panel_idf(output_idf_name) + # 1 panel case: need to find out if it is 256 x 256 + if len(argv) == 3: + linear_pixel_number = int(argv[2]) + if linear_pixel_number not in [256, 512]: + print ('[ERROR] HB3A 1-panel only supports 256(x256) and 512(x512) but not {}(x{})' + ''.format(linear_pixel_number, linear_pixel_number)) + + generate_1_panel_idf(is_zebra, output_idf_name, instrument_config_name, linear_pixel_number) elif num_panel: - generate_3_panel_idf(output_idf_name) + generate_3_panel_idf(output_idf_name, instrument_config_name) else: print ('Panel configuration {} is not supported'.format(argv[1])) sys.exit(-1) + # END-IF-ELSE + + print ('[REPORT] {} and {} are generated for {}'.format(output_idf_name, instrument_config_name, instrument_name)) return diff --git a/helper.py b/helper.py index f60ed1d..7020df5 100644 --- a/helper.py +++ b/helper.py @@ -11,6 +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(object): def __init__(self, instname, comment=None, valid_from=None, valid_to=None): @@ -340,6 +341,41 @@ def add_component_type(self, type_name): return type_node + def add_rectangular_detector(self, x_start, x_step, x_pixels, + y_start, y_step, y_pixels, + pixel_size_x, pixel_size_y, pixel_size_z, + panel_name='shiftpanel'): + """ + Add an angular detector in rectangular shape + :param x_start: + :param x_step: + :param x_pixels: + :param y_start: + :param y_step: + :param y_pixels: + :param pixel_size_x: + :param pixel_size_y: + :param pixel_size_z: + :param panel_name: name in the XML for panel + :return: + """ + # add detector panel + self.addRectangularDetector(name=panel_name, type='pixel', + xstart='{}'.format(x_start), xstep='{}'.format(x_step), + xpixels='{}'.format(x_pixels), + ystart='{}'.format(y_start), ystep='{}'.format(y_step), + ypixels='{}'.format(y_pixels)) + + # add pixels + self.addCuboidPixel(name='pixel', shape_id='pixel-shape', + lfb_pt=(pixel_size_x*0.5, -pixel_size_y*0.5, 0), # left-front-bottom + lft_pt=(pixel_size_x*0.5, pixel_size_y*0.5, 0), # left-front-top + lbb_pt=(pixel_size_x*0.5, -pixel_size_y*0.5, -pixel_size_z), # left-back-bottom + rfb_pt=(-pixel_size_x*0.5, -pixel_size_y*0.5, 0) # right-front-bottom + ) + + return + def add_type(self, type_info_dict, root_node=None): if root_node is None: