ISISComputingGroup / IBEX

Top level repository for IBEX stories
5 stars 2 forks source link

Reflectometry: Setup and support acceptance test on SURF #4327

Closed John-Holt-Tessella closed 5 years ago

John-Holt-Tessella commented 5 years ago

As a SURF instrument scientist, I need the acceptance test setup on my machine and potentially help running these tests.

Acceptance Criteria

  1. IBEX installed
  2. Motor parameters transferred
  3. Motors checked
  4. Motor scans are done over the following to check they agree with variation in SECI (3x in IBEX and 3x in SECI):
    • sample phi, psi and height
    • All different types of jaw
    • theta
    • any unusual motor
  5. Experiments are performed to show tracking works.

Notes

Plan for surf:

  1. Record motor positions in SECI
  2. Stop SECI and start IBEX
  3. Final setup of IBEX on SURF
  4. Visual check motor directions are as Reflectometry IOC expects (up is positive, +ve angle is clockwise)
  5. Check alignment is still correct
  6. Align sample block.
  7. Perform repeatability movements in IBEX:
    1. Add ranges to script
    2. Run Script
  8. Perform repeatability measurements in SECI if needed; they won’t be needed if IBEX motors curves are the same
  9. Align samples for blind test.
  10. Run test in NR for Si
  11. Run test in NR for gold
  12. Runs test with super mirror for Si and Gold
  13. Run contrast change tests
  14. Analysis results
  15. Celebrate
ThomasLohnert commented 5 years ago

Tasks in preparation:

kjwoodsISIS commented 5 years ago

@ThomasLohnert - SURF should already have a private network (I asked Anthony to do this some time ago - see Footprints ticket: FIT-4040). Ports 19 to 22 are on the private network (but may be worth double-checking with Anthony)

John-Holt-Tessella commented 5 years ago

Talked through this config with SURF instrument scientist:

# CRISP

from ReflectometryServer import *

# components in the beamline
components = []
# parameters for the beamline
parameters = []
# drivers for the beamline
drivers = []
# all modes of the system
modes = []
# parameters in nr mode
nr_mode_params = []
# parameters in polaraised mode
polerised_mode_params = []
# parameters in disabled mode
disabled_mode_params = []
# parameters in laser mode
laser_mode_params = []

def add_mode(mode_name, parameters, inits, is_disabled=False):
    """
    Add a mode
    Args:
        mode_name: name of the mode
        parameters: parameter in mode
        inits: intial parameter values
        is_disabled: is a disabled mode

    Returns: mode

    """
    inits_for_beamline = {}
    for param, value in inits.items():
        inits_for_beamline[param.name] = value
    comps_for_beamline = [param.name for param in parameters]
    mode = BeamlineMode(mode_name, comps_for_beamline, inits_for_beamline, is_disabled)
    modes.append(mode)
    return mode

def add_component(component, marker=None):
    """
    Add a component
    Args:
        component: component
        marker:

    Returns:

    """
    _add_at_marker_or_end(component, marker, components)
    return component

def _add_at_marker_or_end(item_to_add, marker, list_to_add_to):
    if marker is None:
        list_to_add_to.append(item_to_add)
    else:
        marker_pos = list_to_add_to.index(marker)
        list_to_add_to[marker_pos] = item_to_add

def add_driver(driver):
    drivers.append(driver)
    return driver

def add_parameter(parameter, nr=False, polarised=False, disabled=False, laser=False, marker=None):
    _add_at_marker_or_end(parameter, marker, parameters)
    if nr:
        nr_mode_params.append(parameter)
    if polarised:
        polerised_mode_params.append(parameter)
    if disabled:
        disabled_mode_params.append(parameter)
    if laser:
        laser_mode_params.append(parameter)
    return parameter

def add_slits(slit_number, jaws=None, nr=False, polarised=False, disabled=False, laser=False):
    if jaws is None:
        jaws = "JAWS{}".format(slit_number)
    vg_param_name = "s{}vg".format(slit_number)
    hg_param_name = "s{}hg".format(slit_number)
    vgap_param = SlitGapParameter(vg_param_name, AxisPVWrapper("MOT:{}:VGAP".format(jaws)), is_vertical=True)
    hgap_param = SlitGapParameter(hg_param_name, AxisPVWrapper("MOT:{}:HGAP".format(jaws)), is_vertical=False)

    add_parameter(vgap_param, nr=nr, polarised=polarised, disabled=disabled, laser=laser)
    add_parameter(hgap_param, nr=nr, polarised=polarised, disabled=disabled, laser=laser)
    return vgap_param

def get_beamline():

    # FIXED BEAMLINE VALUES
    lambda_min = 1.4
    lambda_max = 6.5

    z_s1 = 7302.5
    z_sm = 7930.5
    z_s2 = 9898.5
    z_sample = 10241.5
    z_s3 = 10656.5
    z_s4 = 12987.2  # no distances for S4 in SECI setup so best guess for now (z_point_detector - 150 mm)
    z_point_detector = 12102.2
    z_multi_detector = 12381.5

    ALL_MODES = {"nr": True, "polarised": True, "laser": True, "disabled": True}
    ALL_MODES_BUT_DISABLED = {"nr": True, "polarised": True, "laser": True, "disabled": False}
    POLARAISED_MODE_ONLY = {"nr": False, "polarised": True, "laser": False, "disabled": False}

    # Slit 1
    #  - tracking has height stage
    s1_comp = add_component(Component("s1", PositionAndAngle(0.0, z_s1, 90)))
    add_parameter(TrackingPosition("S1Offset", s1_comp), **ALL_MODES_BUT_DISABLED)
    add_driver(DisplacementDriver(s1_comp, MotorPVWrapper("MOT:MTR0301")))

    # - gaps
    s1_vgap_param = add_slits(1, **ALL_MODES_BUT_DISABLED)  # North 0101, South 0102, East 0201 West 0202

    # Super Mirror
    sm_comp = add_component(ReflectingComponent("sm", PositionAndAngle(0.0, z_sm, 90)))

    sm_param_in_beam = add_parameter(InBeamParameter("SMInBeam", sm_comp, False), **ALL_MODES_BUT_DISABLED)
    add_parameter(TrackingPosition("SMOffset", sm_comp), **POLARAISED_MODE_ONLY)
    add_parameter(AngleParameter("SMAngle", sm_comp), **POLARAISED_MODE_ONLY)

    add_driver(DisplacementDriver(sm_comp, MotorPVWrapper("MOT:MTR0406"), out_of_beam_position=-47.0))
    add_driver(AngleDriver(sm_comp, MotorPVWrapper("MOT:MTR0407")))

    # S2
    s2_comp = add_component(Component("s2", PositionAndAngle(0.0, z_s2, 90)))
    add_parameter(TrackingPosition("S2Offset", s2_comp), **ALL_MODES_BUT_DISABLED)
    add_driver(DisplacementDriver(s2_comp, MotorPVWrapper("MOT:MTR0302")))

    # S2 gaps
    s2_vgap_param = add_slits(2, **ALL_MODES_BUT_DISABLED) # North 0203, South 0204, East 0103 West 0104

    # Monitor in here TODO!
    # is in and out MOT0408

    # Sample  # x tranlsation 0305, y height 0306 (only one height like crisp), phi 0307, psi 0308
    sample_comp = add_component(Component("sample", PositionAndAngle(0.0, z_sample, 90)))
    add_parameter(TrackingPosition("SampOffset", sample_comp))
    add_parameter(InBeamParameter("SampInBeam", sample_comp))

    add_driver(DisplacementDriver(sample_comp, MotorPVWrapper("MOT:MTR0303"), out_of_beam_position=-10))

    # Theta
    marker = "THETA"
    components.append(marker)
    parameters.append(marker)

    # S3
    s3_comp = add_component(Component("s3", PositionAndAngle(0.0, z_s3, 90)))
    add_parameter(TrackingPosition("S3Offset", s3_comp), **ALL_MODES_BUT_DISABLED)
    add_driver(DisplacementDriver(s3_comp, MotorPVWrapper("MOT:MTR0303")))

    # S3 gaps
    s3_vgap_param = add_slits(3, **ALL_MODES_BUT_DISABLED)  # north 0105, sourth 0106 east 0205, west 0206

    # back of vacum tube
    vacback_comp = add_component(Component("vac_back", PositionAndAngle(0.0, z_s3, 90)))
    add_parameter(TrackingPosition("VBOffset", s3_comp), **ALL_MODES_BUT_DISABLED)
    add_driver(DisplacementDriver(vacback_comp, MotorPVWrapper("MOT:MTR00304")))

    # S4 gaps
    s4_vgap_param = add_slits(4, **ALL_MODES_BUT_DISABLED) # north 0107, wouth 0108, east 0207, west 0208

    # point detector
    point_detector_comp = add_component(TiltingComponent("point_detector", PositionAndAngle(0.0, z_point_detector, 90)))
    point_detector_param_track = add_parameter(TrackingPosition("PDOffset", point_detector_comp, autosave=True), **ALL_MODES)
    add_parameter(AngleParameter("PDAngle", point_detector_comp), **ALL_MODES)
    add_parameter(InBeamParameter("PDInBeam", sample_comp, False))
    add_driver(DisplacementDriver(point_detector_comp, MotorPVWrapper("MOT:MTR0401"), out_of_beam_position=?))  #  Point park high -450
    add_driver(AngleDriver(point_detector_comp, MotorPVWrapper("MOT:MTR0402")))

    # multi detector
    multi_detector_comp = add_component(Component("md", PositionAndAngle(0.0, z_multi_detector, 90)))
    multi_detector_param_track = add_parameter(TrackingPosition("MDOffset", multi_detector_comp, autosave=True), **ALL_MODES)
    multi_detector_param_angle = add_parameter(AngleParameter("MDAngle", multi_detector_comp, autosave=True), **ALL_MODES)
    add_driver(DisplacementDriver(multi_detector_comp, MotorPVWrapper("MOT:MTR0403")))
    add_driver(AngleDriver(multi_detector_comp, MotorPVWrapper("MOT:MTR0404")))

    # Create Theta at marker positions
    theta_comp = add_component(ThetaComponent("ThetaComp", PositionAndAngle(0.0, z_sample, 90), [point_detector_comp, multi_detector_comp]), marker=marker)
    theta_param_angle = add_parameter(AngleParameter("THETA", theta_comp), marker=marker, **ALL_MODES)

    # Modes
    add_mode("NR", nr_mode_params, {sm_param_in_beam: False, point_detector_param_track: 0, multi_detector_param_track: 0}) # no super mirror
#    add_mode("Polarised NR", polerised_mode_params, {sm_param_in_beam: True, point_detector_param_track: 0, multi_detector_param_track: 0})
    add_mode("Liquid", nr_mode_params, {sm_param_in_beam: False, point_detector_param_track: 0, multi_detector_param_track: 0})  # Set theta and sm angle independently

#    add_mode("Laser", laser_mode_params,
#             {point_detector_param_track: 150, multi_detector_param_track: 0, theta_param_angle: 0})
    add_mode("DISABLED", disabled_mode_params, {}, is_disabled=True)

    # Footprint calculator setup
    footprint_setup = FootprintSetup(z_s1, z_s2, z_s3, z_s4, z_sample,
                                     s1_vgap_param, s2_vgap_param, s3_vgap_param, s4_vgap_param,
                                     theta_param_angle,
                                     lambda_min, lambda_max)

    beam_start = PositionAndAngle(0.0, 0.0, 0.0)
    bl = Beamline(components, parameters, drivers, modes, beam_start, footprint_setup=footprint_setup)

    return bl

NB Not quite right see on in git in NDXSURF branch

John-Holt-Tessella commented 5 years ago

Ibex installed on SURF. Items not done because I did not want to disrupt the instrument:

  1. Installation of ISIS ICP
  2. Nagios checks
  3. Installation of wiring tables

All will be done on test commence except for nagios checks which have been added to migration ticket.

ThomasLohnert commented 5 years ago

Produced and tested the motor setting migration script on my dev machine. The VI which produces the script currently ignores some settings, so for the purpose of getting things ready for testing on Monday, I have manually edited the output file to include instructions for setting the following properties:

I have put the edited script in a folder in the private shared experiment controls area. You can test it by running it on a dev machine with Galils 01-04 running, and comparing the motor settings to the ones in the Setup Dialog in /LabVIEW Modules/Drivers/Galil DMC2280/Galil - System Functions.llb on SURF

ThomasLohnert commented 5 years ago

Requires https://github.com/ISISComputingGroup/IBEX/issues/4310, https://github.com/ISISComputingGroup/IBEX/issues/4533

ThomasLohnert commented 5 years ago

Installed the following files on SURF

John-Holt-Tessella commented 5 years ago

Progress reported:

MC says that the data for the sample doesn’t look rubbish but he needs to do some analysis to say it looks correct (I hope that is ok to say on your behalf MC).

So I think we have collected in IBEX:

  1. Dance for (dance was 10 sets of 3 movements) a. Theta (no sample) b. Phi shadow c. Sample Height d. Phi rocking e. Slit scans (from yesterday)
  2. D2O Si and Si-gold
  3. H2O Si and Si-gold
  4. Transmissions (small and large slits) x2
  5. Contrast matched Si with short count at 1.5 angle

We are now running in SECI and hope to collect the dance as above. We will plot the dance data today.

For the other 3 days we have:

  1. Setup the motors in IBEX. Issues arising were:
    1. When setting motor defaults (inc. motor resolution) positions were reset and we lost the motor positions (we could recover easily but this should be avoided in the future)
    2. The s3 height axis does not seem to remain energised correctly (we need to look at this)
    3. Because we did some of the conversion manually we made a mistake and did not keep the sample height axis energised. This was found during dance scans. This axis does now remain energised correctly
  2. Aligned the sample in IBEX
  3. We edited the JASCO IOC to put some pauses in (a less sophisticated version of Aaron’s fix) and the JASCO pump gave us no troubles, to be confirmed by Mario and the data below.
  4. Ran a dance script in SECI but this script had some CRISP items in it which means there are no results from it
  5. We ran dance script in IBEX and found:
    1. Slits looked consistent but sample height was not
    2. Also the reflectometry IOC seems to crash
  6. General comments (some we have already seen). Mario let me know if anything else occurs to you.
    1. Scan command argument should be: block (case insensitive), min, max, points, frames [fit should default to Gaussian)
    2. [Desired] Want on OPI enter to keep value and remain in field, tab to move to next value
    3. Want plots to indicate that all points have been plotted. On seci the points change from open to coloured and you get the fit added; but we like the fit being continuous so maybe change the fit colour at the end.
    4. The graph dose not refresh, Tom says we need to produce a small test case I will try to do that.
    5. [Desired] Like to be able to do a fit on restricted data range, e.g. fit a straight line to some of the data from a slit scan but not all of it
    6. Have a single screen with OPI and scripting
John-Holt-Tessella commented 5 years ago

So over the weekend of extra beam I think we have managed to get multiple runs and data for:

  1. Theta
  2. Phi rocking
  3. Phi shadow
  4. Height
  5. S1, s2, s3,s4

I also pumped new D2O into the cells and ran set of run angles for Si and Gold (along with a transmission).

We, and by that I mean Thomas (thankyou), can plot the movement runs from SECI with the IBEX ones. MC could you do the analysis for the sample runs? There is no rush ...

John-Holt-Tessella commented 5 years ago

Impeded waiting for scientific input