BCDA-APS / mdaviz

Data visualization for mda
https://bcda-aps.github.io/mdaviz/
Other
3 stars 0 forks source link

mdaLib classes #104

Open rodolakis opened 7 months ago

rodolakis commented 7 months ago
################################################################################
# classes
# scanDim holds all of the data associated with a single execution of a single sscan record.
class scanDim:
    def __init__(self):
        self.rank = 0           # [1..n]  1 means this is the "innermost" or only scan dimension
        self.dim = 0            # dimensionality of data (numerically same as rank)
        self.npts = 0           # number of data points planned
        self.curr_pt = 0        # number of data points actually acquired
        self.plower_scans = 0   # file offsets of next lower rank scans
        self.name = ""          # name of sscan record that acquired the data
        self.time = ""          # time at which scan (dimension) started
        self.np = 0             # number of positioners
        self.p = []             # list of scanPositioner instances
        self.nd = 0             # number of detectors
        self.d = []             # list of scanDetector instances
        self.nt = 0             # number of detector triggers
        self.t = []             # list of scanTrigger instances

    def __str__(self):
        if self.name != '':
            s = "%dD data from \"%s\" acquired on %s:\n%d/%d pts; %d positioners, %d detectors" % (
                self.dim, self.name, self.time, self.curr_pt, self.npts, self.np, self.nd)
        else:
            s = "%dD data (not read in)" % (self.dim)

        return s

# scanPositioner holds all the information associated with a single positioner, and
# all the data written and acquired by that positioner during an entire (possibly
# multidimensional) scan.
class scanPositioner:
    def __init__(self):
        self.number = 0             # positioner number in sscan record
        self.fieldName = ""         # name of sscanRecord PV
        self.name = ""              # name of EPICS PV this positioner wrote to
        self.desc = ""              # description of 'name' PV
        self.step_mode = ""         # 'LINEAR', 'TABLE', or 'FLY'
        self.unit = ""              # units of 'name' PV
        self.readback_name = ""     # name of EPICS PV this positioner read from, if any
        self.readback_desc = ""     # description of 'readback_name' PV
        self.readback_unit = ""     # units of 'readback_name' PV
        self.data = []              # list of values written to 'name' PV.  If rank==2, lists of lists, etc.

    def __str__(self):
        global use_numpy
        data = self.data
        if use_numpy:
            n = data.ndim
            if n==1:
                dimString = '(' + str(data.shape[0]) + ')'
            else:
                dimString = str(data.shape)
        else:
            n = 1
            dimString = str(len(data))
            while (len(data)>0) and ((type(data[0]) == type([])) or (type(data[0]) == type(()))):
                data = data[0]
                n = n+1
                dimString = dimString+"x"+str(len(data))
            dimString = '('+dimString+')'
        s = "positioner <scanRecord>.%s\nPV name  '%s'\nPV desc. '%s'\nPV units    '%s'\nstep mode: %s\nRB name  '%s'\nRB desc. '%s'\nRB units    '%s'\ndata: %dD array %s\n" % (self.fieldName,
        self.name, self.desc, self.unit, self.step_mode, self.name, self.desc, self.unit, n, dimString)
        return s

# scanDetector holds all the information associated with a single detector, and
# all the data acquired by that detector during an entire (possibly multidimensional) scan.
class scanDetector:
    def __init__(self):
        self.number = 0         # detector number in sscan record
        self.fieldName = ""     # name of sscanRecord PV
        self.name = ""          # name of EPICS PV this detector read from
        self.desc = ""          # description of 'name' PV
        self.unit = ""          # units of 'name' PV
        self.data = []          # list of values read from 'name' PV.  If rank==2, lists of lists, etc.

    def __str__(self):
        global use_numpy
        data = self.data
        if use_numpy:
            n = data.ndim
            if n==1:
                dimString = '(' + str(data.shape[0]) + ')'
            else:
                dimString = str(data.shape)
        else:
            n = 1
            dimString = str(len(data))
            while (len(data)>0) and ((type(data[0]) == type([])) or (type(data[0]) == type(()))):
                data = data[0]
                n = n+1
                dimString = dimString+"x"+str(len(data))
            dimString = '('+dimString+')'
        s = "detector <scanRecord>.%s\nPV name  '%s'\nPV desc. '%s'\nPV units    '%s'\ndata: %dD array %s\n" % (self.fieldName,
        self.name, self.desc, self.unit, n, dimString)
        return s

# scanTrigger holds all the information associated with a single detector trigger.
class scanTrigger:
    def __init__(self):
        self.number = 0         # detector-trigger number in sscan record
        self.name = ""          # name of sscanRecord PV
        self.command = 0.0      # value written to 'name' PV

    def __str__(self):
        s = "trigger %d (%s), command=%f\n" % (self.number,
            self.name, self.command)
        return s