Пример #1
0
    def __init__(self):
        with safe_load('SmarAct'):
            self.las1 = SmarActTipTilt(prefix='XCS:MCS2:01', tip_pv=':m1', tilt_pv=':m2', name='las1')
            self.las2 = SmarActTipTilt(prefix='XCS:MCS2:01', tip_pv=':m4', tilt_pv=':m5', name= 'las2')
            self.las3 = SmarActTipTilt(prefix='XCS:MCS2:01', tip_pv=':m7', tilt_pv=':m8', name = 'las3')
        with safe_load('elog'):
            kwargs = dict()
            self.elog = HutchELog.from_conf('XCS', **kwargs)

        with safe_load('cameras'):
            self. = ImagerHdf5(camviewer.xcs_gige_lj1)
Пример #2
0
    def __init__(self):
        with safe_load('SmarAct'):
            self.las1 = SmarActTipTilt(prefix='XCS:MCS2:01', tip_pv=':m1', tilt_pv=':m2', name='las1')
            self.las2 = SmarActTipTilt(prefix='XCS:MCS2:01', tip_pv=':m4', tilt_pv=':m5', name= 'las2')
            self.las3 = SmarActTipTilt(prefix='XCS:MCS2:01', tip_pv=':m7', tilt_pv=':m8', name = 'las3')

        with safe_load('lw9319_piezos'):
            self.gon_top_x = MMC_Axis('XCS:USR:MMC:01', name='gon_top_x')
            self.gon_top_y = MMC_Axis('XCS:USR:MMC:02', name='gon_top_y')

        with safe_load('elog'):
            kwargs = dict()
            self.elog = HutchELog.from_conf('XCS', **kwargs)

        with safe_load('cameras'):
            self.near_fieldh5 = ImagerHdf5(camviewer.xcs_gige_20)
            self.intermediate_fieldh5 = ImagerHdf5(getattr(camviewer,'cam-crix-gige-03'))
Пример #3
0
def load_conf(conf, hutch_dir=None):
    """
    Step through the object loading procedure, given a configuration.

    The procedure is:

    - Check the configuration for errors
    - Display the banner by calling `hutch_banner`
    - Use ``hutch`` key to create ``hutch.db`` importable namespace to
      stash the objects. This will be literally ``hutch.db`` if hutch is
      not provided, or the hutch name e.g. ``mfx.db``.
    - Create a ``RunEngine``, ``RE``
    - Import ``plan_defaults`` and include as ``p``, ``plans``
    - Create a ``daq`` object with ``RE`` registered, using ``daq_platform``
      to define the ``platform`` argument if provided. The default value if
      ``daq_platform`` was not defined is 0.
    - Use ``db`` key to load devices from the ``happi`` beamline database
      and create a ``hutch_beampath`` object from ``lightpath``
    - Use ``load`` key to bring up the user's ``beamline`` modules
    - Use ``experiment`` key to select the current experiment

        - If ``experiment`` was missing, autoselect experiment using
          ``hutch`` key

    - Use current experiment to load experiment objects from questionnaire
    - Use current experiment to load experiment file

    If a conf key is missing, we'll note it in a ``logger.info`` message.
    If an extra conf entry is found, we'll note it in a ``logger.warning``
    message.
    If an automatically selected file is missing, we'll note it in a
    ``logger.info`` message.
    All other errors will be noted in a logger.error message.

    Parameters
    ----------
    conf: ``dict``
        ``dict`` interpretation of the original yaml file

    hutch_dir: ``Path`` or ``str``, optional
        ``Path`` object that points to the hutch's launch directory. This is
        the directory that includes the ``experiments`` directory and a
        hutchname directory e.g. ``mfx``
        If this is missing, we'll be unable to write the ``db.txt`` file,
        do relative filepath database selection for ``happi``,
        or establish a preset positions directory.

    Returns
    ------
    objs: ``dict{str: object}``
        See the return value of `load`
    """
    # Warn user about excess config entries
    for key in conf:
        if key not in VALID_KEYS:
            txt = ('Found %s in configuration, but this is not a valid key. '
                   'The valid keys are %s')
            logger.warning(txt, key, VALID_KEYS)

    # Grab configurations from dict, set defaults, show missing
    try:
        hutch = conf['hutch']
        if isinstance(hutch, str):
            hutch = hutch.lower()
        else:
            logger.error('Invalid hutch conf %s, must be string.', hutch)
            hutch = None
    except KeyError:
        hutch = None
        logger.info('Missing hutch from conf. Will skip DAQ.')

    # Display the banner
    if hutch is None:
        hutch_banner()
    else:
        hutch_banner(hutch)

    try:
        db = conf['db']
        if isinstance(db, str):
            if db[0] == '/':
                db = Path(db)
            else:
                db = Path(hutch_dir) / db
        else:
            logger.error('Invalid db conf %s, must be string.', db)
            db = None
    except KeyError:
        db = None
        logger.info(('Missing db from conf. Will skip loading from shared '
                     'database.'))
    try:
        load = conf['load']
        if not isinstance(load, (str, list)):
            logger.error('Invalid load conf %s, must be string or list', load)
            load = None
    except KeyError:
        load = None
        logger.info('Missing load from conf. Will skip loading hutch files.')

    try:
        experiment = conf['experiment']
        if (not isinstance(experiment, dict)
                or 'proposal' not in experiment
                or 'run' not in experiment):
            logger.error(('Invalid experiment selection %s, must be a dict '
                          'with keys "proposal" and "run"'), experiment)
            experiment = None
    except KeyError:
        experiment = None
        if hutch is None:
            logger.info(('Missing hutch and experiment from conf. Will not '
                         'load objects from questionnaire or experiment '
                         'file.'))

    try:
        # This is an internal variable here for note-keeping. The ELog uses
        # this to determine if we are in the secondary or primary DAQ mode
        default_platform = True
        platform_info = conf['daq_platform']
        hostname = gethostname()
        try:
            daq_platform = platform_info[hostname]
            logger.info('Selected %s daq platform: %s',
                        hostname, daq_platform)
            default_platform = False
        except KeyError:
            daq_platform = platform_info['default']
            logger.info('Selected default %s daq platform: %s',
                        hutch, daq_platform)
    except KeyError:
        daq_platform = 0
        logger.info('Selected default hutch-python daq platform: 0')

    # Make cache namespace
    cache = LoadCache((hutch or 'hutch') + '.db', hutch_dir=hutch_dir)

    # Make RunEngine
    RE = RunEngine({})
    bec = BestEffortCallback()
    RE.subscribe(bec)
    cache(RE=RE)
    try:
        install_kicker()
    except RuntimeError:
        # Probably don't have a display if this failed, so nothing to kick
        pass

    # Collect Plans
    cache(plans=plan_defaults)
    cache(p=plan_defaults)

    # Daq
    with safe_load('daq'):
        daq_objs = get_daq_objs(daq_platform, RE)
        cache(**daq_objs)

    # Happi db and Lightpath
    if db is not None:
        with safe_load('database'):
            happi_objs = get_happi_objs(db, hutch)
            cache(**happi_objs)
            bp = get_lightpath(db, hutch)
            cache(**{"{}_beampath".format(hutch.lower()): bp})

    # Elog
    with safe_load('elog'):
        # Use the fact if we we used the default_platform or not to decide
        # whether we are in a specialty station or not
        if default_platform:
            logger.debug("Using primary experiment ELog")
            kwargs = dict()
        else:
            logger.info("Configuring ELog to post to secondary experiment")
            kwargs = {'station': '1'}
        cache(elog=HutchELog.from_conf(hutch.upper(), **kwargs))

    # Load user files
    if load is not None:
        load_objs = get_user_objs(load)
        cache(**load_objs)

    # Auto select experiment if we need to
    proposal = None
    if experiment is None:
        if hutch is not None:
            try:
                # xpplp1216
                expname = get_current_experiment(hutch)
                logger.info('Selected active experiment %s', expname)
                # lp12
                proposal = expname[3:-2]
                # 16
                run = expname[-2:]
            except Exception:
                err = 'Failed to select experiment automatically'
                logger.error(err)
                logger.debug(err, exc_info=True)

    # Experiment objects
    if experiment is not None:
        proposal = experiment['proposal']
        run = experiment['run']

    if proposal is not None:
        qs_objs = get_qs_objs(proposal, run)
        cache(**qs_objs)
        user = get_exp_objs(proposal, run)
        for name, obj in qs_objs.items():
            setattr(user, name, obj)
        cache(x=user, user=user)

    # Default namespaces
    with safe_load('default groups'):
        default_class_namespace('EpicsMotor', 'motors', cache)
        default_class_namespace('Slits', 'slits', cache)
        if hutch is not None:
            tree = tree_namespace(scope='hutch_python.db')
            # Prune meta, remove branches with only one object
            for name, space in tree.__dict__.items():
                if count_ns_leaves(space) > 1:
                    cache(**{name: space})

        all_objs = copy(cache.objs)
        cache(a=all_objs, all_objects=all_objs)

    # Install Presets
    if hutch_dir is not None:
        with safe_load('position presets'):
            presets_dir = Path(hutch_dir) / 'presets'
            beamline_presets = presets_dir / 'beamline'
            preset_paths = [presets_dir, beamline_presets]
            if proposal is not None:
                experiment_presets = presets_dir / (proposal + str(run))
                preset_paths.append(experiment_presets)
            for path in preset_paths:
                if not path.exists():
                    path.mkdir()
                    path.chmod(0o777)
            if proposal is None:
                setup_preset_paths(hutch=beamline_presets)
            else:
                setup_preset_paths(hutch=beamline_presets,
                                   exp=experiment_presets)

    # Write db.txt info file to the user's module
    try:
        cache.write_file()
    except OSError:
        logger.warning('No permissions to write db.txt file')

    return cache.objs.__dict__
Пример #4
0
def load_conf(conf, hutch_dir=None):
    """
    Step through the object loading procedure, given a configuration.

    The procedure is:

    - Check the configuration for errors
    - Display the banner by calling `hutch_banner`
    - Use ``hutch`` key to create ``hutch.db`` importable namespace to
      stash the objects. This will be literally ``hutch.db`` if hutch is
      not provided, or the hutch name e.g. ``mfx.db``.
    - Create a ``RunEngine``, ``RE``
    - Import ``plan_defaults`` and include as ``p``, ``plans``
    - Create a ``daq`` object with ``RE`` registered.
    - Create a ``scan_pvs`` object, and leave it ``disabled``.
    - Use ``hutch`` and ``daq_platform`` keys to create the ``elog`` object
      and configure it to match the correct experiment.
    - Use ``db`` key to load devices from the ``happi`` beamline database
      and create a ``hutch_beampath`` object from ``lightpath``
    - Use ``hutch`` key to load detector objects from the ``camviewer``
      configuration file.
    - Use ``experiment`` key to select the current experiment

        - If ``experiment`` was missing, autoselect experiment using
          ``hutch`` key

    - Use current experiment to load experiment objects from questionnaire
    - Use ``load`` key to bring up the user's ``beamline`` modules
    - Use current experiment to load experiment file

    If a conf key is missing, we'll note it in a ``logger.info`` message.
    If an extra conf entry is found, we'll note it in a ``logger.warning``
    message.
    If an automatically selected file is missing, we'll note it in a
    ``logger.info`` message.
    All other errors will be noted in a logger.error message.

    Parameters
    ----------
    conf: ``dict``
        ``dict`` interpretation of the original yaml file

    hutch_dir: ``Path`` or ``str``, optional
        ``Path`` object that points to the hutch's launch directory. This is
        the directory that includes the ``experiments`` directory and a
        hutchname directory e.g. ``mfx``
        If this is missing, we'll be unable to write the ``db.txt`` file,
        do relative filepath database selection for ``happi``,
        or establish a preset positions directory.

    Returns
    ------
    objs: ``dict{str: object}``
        See the return value of `load`
    """
    # Warn user about excess config entries
    for key in conf:
        if key not in VALID_KEYS:
            txt = ('Found %s in configuration, but this is not a valid key. '
                   'The valid keys are %s')
            logger.warning(txt, key, VALID_KEYS)

    # Grab configurations from dict, set defaults, show missing
    try:
        hutch = conf['hutch']
        if isinstance(hutch, str):
            hutch = hutch.lower()
        else:
            logger.error('Invalid hutch conf %s, must be string.', hutch)
            hutch = None
    except KeyError:
        hutch = None
        logger.info(('Missing hutch from conf. Will skip elog '
                     'and cameras.'))

    # Display the banner
    if hutch is None:
        hutch_banner()
    else:
        hutch_banner(hutch)

    try:
        db = conf['db']
        if isinstance(db, str):
            if db[0] == '/':
                db = Path(db)
            else:
                db = Path(hutch_dir) / db
        else:
            logger.error('Invalid db conf %s, must be string.', db)
            db = None
    except KeyError:
        db = None
        logger.info(('Missing db from conf. Will skip loading from shared '
                     'database.'))
    try:
        load = conf['load']
        if not isinstance(load, (str, list)):
            logger.error('Invalid load conf %s, must be string or list', load)
            load = None
    except KeyError:
        load = None
        logger.info('Missing load from conf. Will skip loading hutch files.')

    try:
        experiment = conf['experiment']
        if not isinstance(experiment, str):
            logger.error(
                'Invalid experiment selection %s, must be a string '
                'matching the elog experiment name.', experiment)
            experiment = None
    except KeyError:
        experiment = None
        if hutch is None:
            logger.info(('Missing hutch and experiment from conf. Will not '
                         'load objects from questionnaire or experiment '
                         'file.'))

    try:
        # This is an internal variable here for note-keeping. The ELog uses
        # this to determine if we are in the secondary or primary DAQ mode
        default_platform = True
        platform_info = conf['daq_platform']
        hostname = gethostname()
        try:
            daq_platform = platform_info[hostname]
            logger.info('Selected %s daq platform: %s', hostname, daq_platform)
            default_platform = False
        except KeyError:
            daq_platform = platform_info['default']
            logger.info('Selected default %s daq platform: %s', hutch,
                        daq_platform)
    except KeyError:
        daq_platform = 0
        logger.info('Selected default hutch-python daq platform: 0')

    # Make cache namespace
    cache = LoadCache((hutch or 'hutch') + '.db', hutch_dir=hutch_dir)

    # Make RunEngine
    RE = RunEngine({})
    initialize_qt_teleporter()
    bec = BestEffortCallback()
    RE.subscribe(bec)
    cache(RE=RE)

    # Collect Plans
    cache(bp=plan_defaults.plans)
    cache(bps=plan_defaults.plan_stubs)
    cache(bpp=plan_defaults.preprocessors)

    # Daq
    with safe_load('daq'):
        cache(daq=Daq(RE=RE, hutch_name=hutch))

    # Scan PVs
    if hutch is not None:
        with safe_load('scan_pvs'):
            scan_pvs = ScanVars('{}:SCAN'.format(hutch.upper()),
                                name='scan_pvs',
                                RE=RE)
            scan_pvs.enable()
            cache(scan_pvs=scan_pvs)

    # Elog
    if hutch is not None:
        with safe_load('elog'):
            # Use the fact if we we used the default_platform or not to decide
            # whether we are in a specialty station or not
            if default_platform:
                logger.debug("Using primary experiment ELog")
                kwargs = dict()
            else:
                logger.info("Configuring ELog to post to secondary experiment")
                kwargs = {'station': '1'}
            cache(elog=HutchELog.from_conf(hutch.upper(), **kwargs))

    # Shared global devices for LCLS
    with safe_load('lcls PVs'):
        cache(**global_devices())

    # Happi db and Lightpath
    if db is not None:
        with safe_load('database'):
            happi_objs = get_happi_objs(db, hutch)
            cache(**happi_objs)
            bp = get_lightpath(db, hutch)
            if bp.devices:
                cache(**{"{}_beampath".format(hutch.lower()): bp})

    # ArchApp
    with safe_load('archapp'):
        cache(archive=EpicsArchive())

    # Camviewer
    if hutch is not None:
        with safe_load('camviewer config'):
            objs = read_camviewer_cfg(CAMVIEWER_CFG.format(hutch))
            cache(camviewer=SimpleNamespace(**objs))

    # Simulated hardware
    with safe_load('simulated hardware'):
        cache(sim=sim.get_hw())

    # Auto select experiment if we need to
    if experiment is None:
        if hutch is not None:
            try:
                # xpplp1216
                experiment = get_current_experiment(hutch)
                logger.info('Selected active experiment %s', experiment)
            except Exception:
                err = 'Failed to select experiment automatically'
                logger.error(err)
                logger.debug(err, exc_info=True)

    # Process experiment name a bit
    if experiment is not None:
        if hutch in experiment:
            full_expname = experiment
            raw_expname = experiment.replace(hutch, '', 1)
        else:
            full_expname = hutch + experiment
            raw_expname = experiment

    # Load questionnaire
    if experiment is not None:
        qs_objs = get_qs_objs(full_expname)
        cache(**qs_objs)

    # Load user/beamline files
    if load is not None:
        load_objs = get_user_objs(load)
        cache(**load_objs)

    # Load experiment file
    if experiment is not None:
        user = get_exp_objs(raw_expname)
        for name, obj in qs_objs.items():
            setattr(user, name, obj)
        cache(x=user, user=user)

    # Default namespaces
    with safe_load('default groups'):
        default_class_namespace('ophyd.PositionerBase', 'motors', cache)
        default_class_namespace('Slits', 'slits', cache)
        default_class_namespace('pcdsdaq.ami.AmiDet', 'detectors', cache)

        # Hotfix/disabled until we fix issues here
        # Tree namespace can cause havoc and break top-level devices
        #
        # if hutch is not None:
        #     tree = tree_namespace(scope='hutch_python.db')
        #     # Prune meta, remove branches with only one object
        #     for name, space in tree.__dict__.items():
        #         if count_ns_leaves(space) > 1:
        #             cache(**{name: space})

        all_objs = copy(cache.objs)
        cache(a=all_objs, all_objects=all_objs)

    # Install Presets
    if hutch_dir is not None:
        with safe_load('position presets'):
            presets_dir = Path(hutch_dir) / 'presets'
            beamline_presets = presets_dir / 'beamline'
            preset_paths = [presets_dir, beamline_presets]
            if experiment is not None:
                experiment_presets = presets_dir / raw_expname
                preset_paths.append(experiment_presets)
            for path in preset_paths:
                if not path.exists():
                    path.mkdir()
                    path.chmod(0o777)
            if experiment is None:
                setup_preset_paths(hutch=beamline_presets)
            else:
                setup_preset_paths(hutch=beamline_presets,
                                   exp=experiment_presets)

    # Write db.txt info file to the user's module
    try:
        cache.write_file()
    except OSError:
        logger.warning('No permissions to write db.txt file')

    return cache.objs.__dict__