Example #1
0
    def __init__(self, detsym, detectortype, controlprefix, imageprefix, comment):
        if DEBUG: print("Defining "+str(detsym)+" with PVs="+str(controlprefix)+
                        ' and '+str(imageprefix))
        if globals().get(detsym) is None:
            globals()[detsym] = self
        else:
            raise spec.specException('Variable '+str(detsym)+' is in use')

        global detectorTypeList
        if detectortype not in detectorTypeList:
            detectorTypeList.append(detectortype)
        self.detectortype = detectortype
        #else:
        #    raise spec.specException('Type '+str(detectortype)+'for detector '+str(detsym)+
        #                             ' is not defined,\n  allowed choices are: '+str(detectorTypeList))
        self.symbol = detsym
        if controlprefix[-1] == ":":
            self.controlprefix = controlprefix
        else:
            self.controlprefix = controlprefix + ':'
        if imageprefix[-1] == ":":
            self.imageprefix = imageprefix
        else:
            self.imageprefix = imageprefix + ':'
        self.comment = comment
Example #2
0
def AD_show(detsym=None,allowprint=True):
    '''Shows all the commands defined for a particular detector, or with any detector.

    :param object detsym: An area detector variable (or name as a string), as defined in
      :func:`DefineAreaDetector`. Default is to only list commands that can be used
      with all detectors.
    :param bool allowprint: If True (default) prints a list of the allowed commands
    :returns: a list of allowed commands

    '''
    if detsym is None:
        detTyp = None
        if allowprint: print("Defined AD_get() & AD_set() commands for all Area Detectors")
    else:
        detObj = globals().get(detsym)
        if detObj is None: detObj = detsym
        if not isinstance(detObj,_ADobject):
            raise spec.specException('AD_show error: detsym '+str(detsym)+' is not defined in DefineAreaDetector')
        detTyp = detObj.detectortype
        if allowprint: print('Defined AD_get() & AD_set() commands for "'+str(detTyp)+'" Area Detectors')

    cmdlist = []
    for cmd in sorted(CommandDict):
        for cmdObj in CommandDict[cmd]:
            if cmdObj.detectortype == detTyp or cmdObj.detectortype is None:
                if allowprint: print('  '+("%-14s" % cmd)+'\t'+str(cmdObj.comment))
                cmdlist.append(cmd)
                break
    return cmdlist
Example #3
0
def AD_done(detsyms,wait=True):
    """Test and optionally wait for the detector(s) have completed data collection

    :param object detsyms: An area detector variable (or name as a string), as defined in
      :func:`DefineAreaDetector`. Alternately, a list of area detectors variable or names
      (as strings) can be supplied.
    :param bool wait: If False test and return immediately; if True (default), return
      after the ``state`` command (if defined) indicates the data collection is done
      for each detector.

    :returns: True if all detector(s) are done; False is wait is False and any detectors are
      not done; or None if after 30 seconds, any detector is not complete
    """
    # is the detector specified as a string? 
    if isinstance(detsyms,str): detsyms = tuple((detsyms,))
    # is there a list of detectors?
    try:
        symList = tuple(detsyms)
    except TypeError:
        symList = tuple((detsyms,))
    alldone = True
    sleeptime = 0.0
    for sym in symList:
        detObj = globals().get(sym)
        if detObj is None: detObj = sym
        if not isinstance(detObj,_ADobject):
            raise spec.specException('AD_done error: detsyms '+str(sym)+' is not defined in DefineAreaDetector')
        # get cmdObj of correct type for the current detector ==============================
        for cmdObj in CommandDict['state']:
            if cmdObj.detectortype is None: break #  this a generic command
            if cmdObj.detectortype == detObj.detectortype: break # matches selected device
        else:
            continue
        if cmdObj.readstr == "": continue
        if cmdObj.useImagePrefix:
            PV = detObj.imageprefix + cmdObj.readstr
        else:
            PV = detObj.controlprefix + cmdObj.readstr
        if not (EPICS and spec.UseEPICS()): # in simulation
            print("Confirming detector "+detObj.symbol+" is done with collection")
            continue
        else:
            val = ep.caget(PV)
            if val == 0: continue # detector has completed
            if not wait: return False
            # detector is not done and a wait is requested
            while val != 0:
                if sleeptime > 30.0:
                    print('AD_done wait exceeded count*frames+30 seconds for'+detObj.symbol+', continuing with script')
                    return
                spec.sleep(0.1)
                sleeptime += 0.1
                val = ep.caget(PV)
    # all detector(s) have signed off as done
    return True
Example #4
0
def DefineAreaDetector(detsym, detectortype, controlprefix, imageprefix=None, comment=''):
    """Define an area detector for use in this module
    
    :param str detsym: a symbolic name for the detector. A global variable is
      defined in this module's name space with this name, This must be unique;
      exception specException is raised if a name is reused.
    :param str detectortype: the type of the detector. This must match one of the entries in
      global variable detectorTypeList (case sensitive). 
    :param str controlprefix: the prefix for the detector PV (dev:camN).
      Omit the detector record field names (.NumImages, etc.).
      Inclusion of a final colon (':') is optional.
    :param str imageprefix: the prefix for the detector PV (dev:fmt).
      Omit the detector record field names (.FileNumber, etc.).
      Inclusion of a final colon (':') is optional.
      If not specified, defaults to the value for controlprefix
    :param string comment: a optional human-readable text field that describes the detector.

    :returns: detector object created for the detector

    Example: 

    >>> DefineAreaDetector('GE1', 'GE', 'GE1:cam1', comment='bottom')
    >>> DefineAreaDetector('GE2', 'GE', 'GE2:cam1', comment='left')
    >>> DefineAreaDetector('GE3', 'GE', 'GE3:cam1', comment='top')
    >>> DefineAreaDetector('GE4', 'GE', 'GE4:cam1', comment='right')
    >>> DefineAreaDetector('ScintX', 'ScintX', 'ScintX:cam1', 'ScintX:TIFF1:')
    >>> DefineAreaDetector('Retiga1', 'Retiga', 'QIMAGE1:cam1:', 'QIMAGE1:TIFF1:')
    >>> DefineAreaDetector('Retiga2', 'Retiga', 'QIMAGE2:cam1:', 'QIMAGE2:TIFF1:')

    """
    
    if imageprefix==None:
        imageprefix = controlprefix
        
    try: 
        obj = _ADobject(detsym, detectortype, controlprefix, imageprefix, comment)
    except spec.specException,err:
        print('Error in creating detector '+str(detsym)+'\n  '+str(err))
        raise spec.specException('Error defining Area Detector '+str(detsym))
Example #5
0
def AD_set(detsyms,cmd,value,ignoreOK=False):
    '''Set a parameter for an area detector. *This routine has been patched to add a \0 to
    strings, to fix a problem in EPICS.*

    :param object detsyms: An area detector variable (or name as a string), as defined in
      :func:`DefineAreaDetector`. Alternately, a list of area detectors variable or names
      (as strings) can be supplied.
      The command (``cmd``) must be defined for all supplied detectors, or an exception occurs. 
    :param str cmd: a command that has been defined using :func:`defADcmd`
    :param str value: The value to set the parameter. This value will be set to the type defined for the
      command from :func:`defADcmd` if possible and will be checked against the enumeration range,
      if one is supplied. If the type conversion fails or the check fails, an exception is raised.

    :param bool ignoreOK: if ignoreOK is False (default) an exception will be raised if command
      cmd is not defined for a detector. If True, the command will be ignored
    :returns: the as-read parameter. The type will be determined by the PV associated with the command.
    
    Examples:

    >>> AD.DefineAreaDetector('GE1', 'GE', 'GE1:cam1')
    >>> val = AD.AD_set(AD.GE1,'acquire_time',3)

    or 
    
    >>> val = AD.AD_set('GE1','acquire_time',3)

    also

    >>> hydra = (AD.GE1,AD.GE2,AD.GE3,AD.GE4)
    >>> val =  AD.AD_set(hydra,'trigger_mode',0)

    '''

    if cmd not in CommandDict:
        raise spec.specException('AD_set error: command '+str(cmd)+' is not defined')
    # is the detector specified as a string? 
    if isinstance(detsyms,str): detsyms = tuple((detsyms,))
    # is there a list of detectors?
    try:
        symList = tuple(detsyms)
    except TypeError:
        symList = tuple((detsyms,))
    for sym in symList:
        detObj = globals().get(sym)
        if detObj is None: detObj = sym
        if not isinstance(detObj,_ADobject):
            raise spec.specException('AD_set error: detsyms '+str(sym)+' is not defined in DefineAreaDetector')
        # get cmdObj of correct type for the current detector ==============================
        for cmdObj in CommandDict[cmd]:
            if cmdObj.detectortype is None: break #  this a generic command
            if cmdObj.detectortype == detObj.detectortype: break # matches selected device
        else:
            if ignoreOK: continue
            raise spec.specException('AD_set error: no match for command '+str(cmd)+
                                     ' and detector type '+detObj.detectortype)
        if cmdObj.setstr == "": 
            raise spec.specException('No AD_set "'+str(cmd)+'" set command')
        # validate the supplied value =========================================================
        if cmdObj.enum is not None and not isinstance(cmdObj.enum,str):
            if value in cmdObj.enum:
                val = value
            else:
                raise spec.specException('AD_set error: value '+str(value)+
                                         ' is not in allowed list: '+str(cmdObj.enum))
        else:
            try:
                val = cmdObj.valtyp(value)
            except Exception, err:
                raise spec.specException('AD_set error: value '+str(value)+' is not of correct type')
        if isinstance(cmdObj.enum,str):
            try:
                tst = eval(cmdObj.enum)
            except Exception, err:
                tst = True
                print("AD_set: Error evaluating expression "+cmdObj.enum)
                print err
            if not tst:
                raise spec.specException('AD_set error: value '+str(value)+' is outside allowed range: '+cmdObj.enum)
Example #6
0
def AD_get(detsyms,cmd,ignoreOK=False):
    '''Read a parameter from an area detector

    :param object detsyms: An area detector variable (or name as a string), as defined in
      :func:`DefineAreaDetector` or a list of area detector variables or strings.
      If a list (or tuple) of detectors is used, the function may
      return a list of values (but only if they differ.)
    :param str cmd: a command string that has been defined using :func:`defADcmd`
    :param bool ignoreOK: if ignoreOK is False (default) an exception will be raised if command
      cmd is not defined for a detector. If True, the command will be ignored

    :returns: the as-read parameter. The type will be determined by the PV associated with the command. If
      detsyms is a list and the read values differ, then a list of values is returned. Otherwise, only
      the (common) value is return.
    
    Examples:

    >>> AD.DefineAreaDetector('GE1', 'GE', 'GE1:cam1')
    >>> val = AD.AD_get(AD.GE1,'acquire_time')

    or 
    
    >>> val = AD.AD_get('GE1','acquire_time')

    also

    >>> hydra = (AD.GE1,AD.GE2,AD.GE3,AD.GE4)
    >>> val =  AD.AD_get(hydra,'trigger_mode')
    >>> try:
    >>>     if len(val) == 4 and not isinstance(val,str):
    >>>         print 'values disagree'
    >>> except TypeError:
    >>>     pass
    
    '''
    valList = []
    if cmd not in CommandDict:
        raise spec.specException('AD_get error: command '+str(cmd)+' is not defined')
    # is the detector specified as a string? 
    if isinstance(detsyms,str): detsyms = tuple((detsyms,))
    # is there a list of detectors?
    try:
        symList = tuple(detsyms)
    except TypeError:
        symList = tuple((detsyms,))
    for sym in symList:
        detObj = globals().get(sym)
        if detObj is None: detObj = sym
        if not isinstance(detObj,_ADobject):
            raise spec.specException('AD_get error: detsyms '+str(sym)+' is not defined in DefineAreaDetector')
        # get cmdObj of correct type for the current detector ==============================
        for cmdObj in CommandDict[cmd]:
            if cmdObj.detectortype is None: break #  this a generic command
            if cmdObj.detectortype == detObj.detectortype: break # matches selected device
        else:
            if ignoreOK: continue
            raise spec.specException('AD_get error: no match for command '+str(cmd)+
                                     ' and detector type '+detObj.detectortype)
        if cmdObj.readstr == "": 
            raise spec.specException('No AD_get "'+str(cmd)+'" read command')
        if cmdObj.useImagePrefix:
            PV = detObj.imageprefix + cmdObj.readstr
        else:
            PV = detObj.controlprefix + cmdObj.readstr
        if not (EPICS and spec.UseEPICS()): # in simulation
            val = pvSim.get(PV)
            if cmd == 'state': val = 0
            print("For "+detObj.symbol+" reading PV="+str(PV)+' value= '+str(val))
            valList.append(val)
            continue
        valList.append( ep.caget(PV,as_string=(cmdObj.valtyp==str)) )
    if len(valList) == 0:
        raise spec.specException('AD_get error: no detectors specified in '+str(detsyms))
    # return a single value or a list if they don't agree
    val = valList[0]
    for v in valList:
        if v != val:
            return valList
    return valList