def detectors(self, exp_run):
     """What are the names of the detectors in the datastream?
     exp_run: contains experiment number, run number, e.g. 'exp=xppj1216:run=17'
     """
     from psana import DataSource
     ds = DataSource(exp_run)
     es = ds.env().epicsStore()
     names = []
     for evt in ds.events():
         keys = evt.keys()
         for d in keys:
             # E.g. d.src(): DetInfo(NoDetector.0:Evr.0), d.alias(): 'evr0'
             name = str(d.src()).split("(")[-1].split(")")[0]
             if name and not name in names: names += [name]
             name = d.alias()
             if name and not name in names: names += [name]
             for name in es.pvNames():
                 if not name in names: names += [name]
             for name in es.aliases():
                 if not name in names: names += [name]
     return names
Esempio n. 2
0
def test_CreateForEvtEnv(tname='0'):

    from psana import DataSource

    dsname = 'exp=cxif5315:run=129'
    source = 'CxiDs2.0:Cspad.0'

    if tname == '2':
        dsname = '/reg/g/psdm/detector/data_test/types/0019-XppGon.0-Epix100a.0.xtc'
        source = 'XppGon.0:Epix100a.0'

    ds = DataSource(dsname)
    env = ds.env()

    calibdir = env.calibDir()  # '/reg/d/psdm/CXI/cxif5315/calib'
    group = None  # will be substituted from dictionary or 'CsPad::CalibV1'
    runnum = 160
    pbits = 0

    par = runnum

    o = cps.CreateForEvtEnv(calibdir, group, source, par, env, pbits)
    o.print_attrs()
class DataStream:
    exp_run = None
    event_number = -1
    serial_number = -1
    detector_name = ""
    event = None

    def image(self, exp_run_event):
        """exp_run_event: contains experiment number, run number and event number
        'exp=xppj1216:run=17:event=0' or 'exp=xppj1216:run=17:event=rayonix,0'
        """
        return self.detector(exp_run_event, "rayonix:data16")

    def detectors(self, exp_run):
        """What are the names of the detectors in the datastream?
        exp_run: contains experiment number, run number, e.g. 'exp=xppj1216:run=17'
        """
        from psana import DataSource
        ds = DataSource(exp_run)
        es = ds.env().epicsStore()
        names = []
        for evt in ds.events():
            keys = evt.keys()
            for d in keys:
                # E.g. d.src(): DetInfo(NoDetector.0:Evr.0), d.alias(): 'evr0'
                name = str(d.src()).split("(")[-1].split(")")[0]
                if name and not name in names: names += [name]
                name = d.alias()
                if name and not name in names: names += [name]
                for name in es.pvNames():
                    if not name in names: names += [name]
                for name in es.aliases():
                    if not name in names: names += [name]
        return names

    def detector(self, exp_run_event, detector_name):
        """exp_run_event: contain experiment number, run number and event number
        'exp=xppj1216:run=17:event=0' or 'exp=xppj1216:run=17:event=rayonix,0'
        detector_name: detector name e.g. "XppEnds_Ipm0:sum" or "rayonix:data16"
        suffix "sum": get the sum of all four channels of a 4-quadrant detector
        suffix "channel": get all four channels of a 4-quadrant detector
        suffix "channel:0": the first channel of a 4-quadrant detector
        suffix "data16": get an image with 16 bit depth
        suffix "data16:0,0": get pixle (0,0) of an image
        """
        full_detector_name = detector_name
        attr = ""
        item = None
        if detector_name.count(":") == 1:
            detector_name, attr = detector_name.split(":")
        if detector_name.count(":") == 2:
            detector_name, attr, item = detector_name.split(":")
            try:
                item = eval(item)
            except:
                pass

        self.find_event(exp_run_event)
        if self.event is None: return None
        for d in self.event.keys():
            # E.g. d.src(): DetInfo(NoDetector.0:Evr.0), d.alias(): 'evr0'
            names = str(d.src()).split("(")[-1].split(")")[0], d.alias()
            if detector_name in names:
                value = self.event.get(d.type(), d.src())
                if attr == "": return value
                value = getattr(value, attr)()
                if item is not None: value = value[item]
                return value
        # Is detector name an EPICS process variable?
        value = self.es.value(full_detector_name)
        if value is not None: return value
        warn("Detector %r not recorded for event=%s,%s:serial_number=%s" %
             (detector_name, self.detector_name, self.event_number,
              self.serial_number))
        return None

    get = detector  # shortcut

    def timestamp(self, exp_run_event):
        """Seconds since 1970-01-01 00:00:00 UTC"""
        from psana import EventId
        self.find_event(exp_run_event)
        if self.event is not None:
            s, ns = self.event.get(EventId).time()
            t = s + ns * 1e-9
        else:
            t = nan
        return t

    def fiducial(self, exp_run_event):
        """360-Hz SLAC time stamp, 17-bit integer"""
        from psana import EventId
        self.find_event(exp_run_event)
        if self.event is not None:
            i = self.event.get(EventId).fiducials()
        else:
            i = nan
        return i

    def get_event_number(self, exp_run_event):
        """exp_run_event: contains experiment number, run number and event number
        'exp=xppj1216:run=17:event=0' or 'exp=xppj1216:run=17:event=rayonix,0'
        Reurn value: 0-based integer.
        """
        self.find_event(exp_run_event)
        return self.serial_number

    def find_event(self, exp_run_event):
        """exp_run_event: contain experiment number, run number and event
        number
        'exp=xppj1216:run=17:event=0' or 'exp=xppj1216:run=17:event=rayonix,0'
        """
        fields = []
        event_number = nan
        detector_name = ""
        for f in exp_run_event.split(':'):
            if f.startswith("event="):
                detector_event = f.replace("event=", "")
                if "," in detector_event:
                    detector_name = ",".join(detector_event.split(",")[0:-1])
                    event_number = int(detector_event.split(",")[-1])
                else:
                    event_number = int(detector_event)
            else:
                fields += [f]
        exp_run = ":".join(fields)
        if exp_run != self.exp_run or detector_name != self.detector_name \
            or event_number < self.event_number:
            start = time()
            try:
                from psana import DataSource
                self.ds = DataSource(exp_run)
                self.es = self.ds.env().epicsStore()
            except Exception, msg:
                error('Failed to open datasource: %s: %s' % (exp_run, msg))
                return None
            self.exp_run = exp_run
            self.event_number = -1
            self.serial_number = -1
            self.detector_name = detector_name
            debug('Opened %r in %g seconds' % (exp_run, time() - start))
        if event_number == self.event_number: return
        for event in self.ds.events():
            self.event = event
            self.serial_number += 1
            # If a detector name is specified, count only event for which
            # this detector is recorded.
            if detector_name != "":
                for d in self.event.keys():
                    names = str(
                        d.src()).split("(")[-1].split(")")[0], d.alias()
                    if detector_name in names:
                        self.event_number += 1
                        break
            else:
                self.event_number += 1
            if event_number == self.event_number:
                break
        if not (event_number == self.event_number):
            error('Event event=%s,%s not found' %
                  (detector_name, event_number))
            self.event = None
        else:
            from psana import EventId
            debug('found event=%s,%s:serial_number=%s:fiducial=%s' %
                  (self.detector_name, self.event_number, self.serial_number,
                   self.event.get(EventId).fiducials()))