Esempio n. 1
0
def runclient(args):
    if args.exprun.find('shmem') < 0:
        #get last run from experiment to extract calib info in DetObject
        dsname = args.exprun + ':smd'
        run = int(args.exprun.split('run=')[-1])
        hutch = args.exprun.split(':')[0].replace('exp=', '')[0:3]
    else:  #shared memory.
        hutches = ['amo', 'sxr', 'xpp', 'xcs', 'mfx', 'cxi', 'mec']
        import socket
        hostname = socket.gethostname()
        for ihutch in hutches:
            if hostname.find(ihutch) >= 0:
                hutch = ihutch
                break
        expname = RegDB.experiment_info.active_experiment(hutch.upper())[1]
        run = int(
            RegDB.experiment_info.experiment_runs(hutch.upper(),
                                                  exper=expname)[-1]['num'])
        calibdir = '/reg/d/psdm/%s/%s/calib' % (hutch, expname)
        psana.setOption('psana.calib-dir', calibdir)

        if args.exprun == 'shmem':
            dsname = 'shmem=psana.0:stop=no'  #was for ls6116
        else:
            dsname = args.dsname

    ds = psana.DataSource(dsname)
    defaultDets = defaultDetectors(hutch)
    defaultDets.append(ebeamDetector('EBeam', 'ebeam'))
    dets = []  #this list is for user data and ill initially not be used.

    import time
    time0 = time.time()
    timeLastEvt = time0
    #slow down code when playing xtc files to look like real data
    timePerEvent = (1. / 120.) * (
        size - 1)  #time one event should take so that code is running 120 Hz

    sendFrequency = 20  #send whenever rank has seen x events
    #vars_to_send=['event_time','ipm2__sum','ebeam__L3Energy']
    #vars_to_send.append(['tt__FLTPOSPS','tt__AMPL'])
    vars_to_send = []

    masterDict = {}
    for nevent, evt in enumerate(ds.events()):
        if nevent == args.noe: break
        if args.exprun.find('shmem') < 0:
            if nevent % (size - 1) != rank - 1:
                continue  # different ranks look at different events
        #print 'pass here: ',nevent, rank, nevent%(size-1)
        defData = detData(defaultDets, evt)

        ###
        #event selection.
        ###
        #check that all required detectors are ok - this should ensure that we don't need to do any fancy event matching/filling at the cost of losing events.
        if 'ipm2' in defData.keys() and defData['damage']['ipm2'] < 1:
            continue
        if 'ipm5' in defData.keys() and defData['damage']['ipm5'] < 1:
            continue
        if defData['damage']['evr0'] < 1:
            continue

        try:
            if defData['damage']['tt'] < 1:
                continue
        except:
            pass

        try:
            if defData['damage']['enc'] < 1:
                continue
        except:
            pass

        #only now bother to deal with detector data to save time.
        #for now, this will be empty and we will only look at defalt data
        userDict = {}
        for det in dets:
            try:
                #this should be a plain dict. Really.
                det.evt = dropObject()
                det.getData(evt)
                det.processDetector()
                userDict[det._name] = getUserData(det)
                try:
                    envData = getUserEnvData(det)
                    if len(envData.keys()) > 0:
                        userDict[det._name + '_env'] = envData
                except:
                    pass
            except:
                pass

        #here we should append the current dict to a dict that will hold a subset of events.
        for key in defData:
            if isinstance(defData[key], dict):
                for skey in defData[key].keys():
                    if isinstance(defData[key][skey], dict):
                        print 'why do I have this level of dict?', key, skey, defData[
                            key][skey].keys()
                        continue
                    varname_in_masterDict = '%s__%s' % (key, skey)
                    if len(vars_to_send
                           ) > 0 and varname_in_masterDict not in vars_to_send:
                        continue
                    if varname_in_masterDict not in masterDict.keys():
                        masterDict[varname_in_masterDict] = [
                            defData[key][skey]
                        ]
                    else:
                        masterDict[varname_in_masterDict].append(
                            defData[key][skey])
            else:
                if len(vars_to_send) > 0 and key not in vars_to_send:
                    continue
                if key not in masterDict.keys():
                    masterDict[key] = [defData[key]]
                else:
                    masterDict[key].append(defData[key])
        if 'event_time' not in masterDict.keys():
            masterDict['event_time'] = [evt.get(psana.EventId).time()]
        else:
            masterDict['event_time'].append(evt.get(psana.EventId).time())

        #make this run at 120 Hz - slow down if necessary
        # send mpi data object to master when desired
        #not sure how this is supposed to work...
        if len(masterDict['event_time']) % sendFrequency == 0:
            timeNow = time.time()
            if (timeNow - timeLastEvt) < timePerEvent * sendFrequency:
                time.sleep(timePerEvent * sendFrequency -
                           (timeNow - timeLastEvt))
                timeLastEvt = time.time()
            #print 'send data, looked at %d events, total ~ %d, run time %g, in rank %d '%(nevent, nevent*(size-1), (time.time()-time0),rank)
            if rank == 1 and nevent > 0:
                if args.exprun.find('shmem') < 0:
                    print 'send data, looked at %d events/rank, total ~ %d, run time %g, approximate rate %g from rank %d' % (
                        nevent, nevent * (size - 1),
                        (time.time() - time0), nevent * (size - 1) /
                        (time.time() - time0), rank)
                else:
                    print 'send data, looked at %d events/rank, total ~ %d, run time %g, approximate rate %g from rank %d' % (
                        nevent, nevent * (size - 1),
                        (time.time() - time0), nevent /
                        (time.time() - time0), rank)
            md = mpidata()
            #I think add a list of keys of the data dictionary to the client.
            md.addarray('nEvts', np.array([nevent]))
            md.addarray('send_timeStamp',
                        np.array(evt.get(psana.EventId).time()))
            for key in masterDict.keys():
                md.addarray(key, np.array(masterDict[key]))
            md.send()

            #now reset the local dictionay/lists.
            masterDict = {}

    #should be different for shared memory. R
    try:
        md.endrun()
        print 'call md.endrun from rank ', rank
    except:
        print 'failed to call md.endrun from rank ', rank
        pass
#add config data here
userDataCfg={}
for det in dets:
    userDataCfg[det._name]=getCfgOutput(det)
Config={'UserDataCfg':userDataCfg}
smldata.save(Config)

for eventNr,evt in enumerate(ds.events()):
    printMsg(eventNr, evt.run(), ds.rank)

    if eventNr >= maxNevt/ds.size:
        break

    #add default data
    defData = detData(defaultDets, evt)
    #for key in defData.keys():
    #    print eventNr, key, defData[key]
    smldata.event(defData)

    #detector data using DetObject 
    userDict = {}
    for det in dets:
        try:
            #this should be a plain dict. Really.
            det.evt = dropObject()
            det.getData(evt)
            det.processDetector()
            userDict[det._name]=getUserData(det)
            try:
                userDict[det._name+'_env']=getUserEnvData(det)
Esempio n. 3
0
def runclient(args):
    if args.exprun.find('shmem')<0:
        #get last run from experiment to extract calib info in DetObject
        dsname = args.exprun+':smd'
        run=int(args.exprun.split('run=')[-1])
        hutch=args.exprun.split(':')[0].replace('exp=','')[0:3]
    else: #shared memory.
        hutches=['amo','sxr','xpp','xcs','mfx','cxi','mec']
        import socket
        hostname=socket.gethostname()
        for ihutch in hutches:
            if hostname.find(ihutch)>=0:
                hutch=ihutch
                break
        expname=RegDB.experiment_info.active_experiment(hutch.upper())[1]
        run=int(RegDB.experiment_info.experiment_runs(hutch.upper(),exper=expname)[-1]['num'])
        calibdir = '/reg/d/psdm/%s/%s/calib'%(hutch,expname)
        psana.setOption('psana.calib-dir',calibdir)

        if args.exprun=='shmem':
            #dsname='shmem=XPP.0:stop=no' #this seems to be the case for x288
            dsname='shmem=psana.0:stop=no' #was for ls6116
            #dsname='shmem=monreqsrvpsana0.0:stop=no'
        else:
            dsname=args.dsname


    ds = psana.DataSource(dsname)
    ADU_per_photon=args.ADU_per_photon
    thresADU=args.thresADU
    epixname=args.areaDetName
    
    defaultDets = defaultDetectors(hutch)

    dets=[]
    #epix = DetObject(epixname ,ds.env(), run, common_mode=46)
    epix = DetObject(epixname ,ds.env(), run, common_mode=4)
    #epix = DetObject(epixname ,ds.env(), run, common_mode=0)
    epix.addPhotons(ADU_per_photon=ADU_per_photon, thresADU=thresADU, retImg=2, nphotMax=200)
    dets.append(epix)

    eventFilterNames=[]
    eventFilterNames.append('off')
    eventFilterNames.append('early')
    eventFilterNames.append('late')
    nImage=[]
    i0Sum=[]
    image=[]
    for filter in eventFilterNames:
        i0Sum.append(0.)
        nImage.append(0)
        image.append(np.zeros([99,99]))

    import time
    time0=time.time()
    for nevent,evt in enumerate(ds.events()):
        if nevent == args.noe : break
        if args.exprun.find('shmem')<0:
            if nevent%(size-1)!=rank-1: continue # different ranks look at different events
        #print 'pass here: ',nevent, rank, nevent%(size-1)
        defData = detData(defaultDets, evt)

        #event selection.
        
        #check that all required detectors are ok.
        if defData['damage']['ipm2'] < 1:
            continue
        if defData['damage']['evr0'] < 1:
            continue
        if defData['damage'][epixname] < 1:
            continue

        try:
            if defData['damage']['tt'] < 1:
                continue
        except:
            pass

        try:
            if defData['damage']['enc'] < 1:
                continue
        except:
            pass

        #now select good quality events.
        xray = defData['lightStatus']['xray']
        laser = defData['lightStatus']['laser']
        ipm2Sum = defData['ipm2']['sum']
        #
        try:
            lasDelay = defData['enc']['lasDelay']
        except:
            lasDelay = (np.random.rand(1)*-0.1)*10.
        try:
            ttCorr = defData['tt']['ttCorr']
            ttAmpl = defData['tt']['AMPL']
        except:
            ttAmpl=99.
            ttCorr=0.

        delay = ttCorr+lasDelay
        if xray < 1:
            continue

        if ipm2Sum < float(args.ipm2_min):
            continue
        if ttAmpl < float(args.ttampl_min):
            continue

        #pick event for certain categories.
        eventFilter=[]        
        eventFilter.append(laser == 0)
        eventFilter.append( (delay < args.tt_early_max) and (laser > 0) )
        try:
            eventFilter.append(( (delay > args.tt_late_min ) and (delay < args.tt_late_max ) and (laser > 0) )[0])
        except:
            try:
                eventFilter.append(( (delay > args.tt_late_min ) and (delay < args.tt_late_max ) and (laser > 0) ))
            except:
                print 'late selection broken'
                eventFilter.append(False)

        #skip events that do not pass any filter
        if np.array(eventFilter).sum()==0:
            continue
        
        #only now bother to deal with detector data to save time. 
        userDict = {}
        for det in dets:
            try:
                #this should be a plain dict. Really.
                det.evt = dropObject()
                det.getData(evt)
                det.processDetector()
                userDict[det._name]=getUserData(det)
                try:
                    envData=getUserEnvData(det)
                    if len(envData.keys())>0:
                        userDict[det._name+'_env']=envData
                except:
                    pass
                #print 'DEBUG: ',userDict[det._name].keys()
            except:
                pass
        
        #now sum the data for the defined classes of events.
        img = userDict[epixname]['photon_img']
        for iFilter,passFilter in enumerate(eventFilter):
            if passFilter:
                i0Sum[iFilter]+= ipm2Sum
                nImage[iFilter]+= 1
                if image[iFilter].shape != img.shape:
                    image[iFilter] = img
                else:
                    image[iFilter] += img

        # send mpi data object to master when desired
        if ((nevent)%20 == 0): #not sure how this is supposed to work...
            #print 'send data, looked at %d events, total ~ %d, run time %g, in rank %d '%(nevent, nevent*(size-1), (time.time()-time0),rank)
            if rank==1 and nevent>0:
                print 'send data, looked at %d events/rank, total ~ %d, run time %g, approximate rate %g'%(nevent, nevent*(size-1), (time.time()-time0), nevent*(size-1)/(time.time()-time0))
            evt_ts = evt.get(psana.EventId).time()
            md=mpidata()
            for name,i0,fimg,nImg in zip(eventFilterNames, i0Sum, image, nImage):
                md.addarray('img_%s'%name,fimg)
                md.addarray('i0_%s'%name,np.array(i0))
                md.addarray('n_%s'%name,np.array(nImg))
            md.addarray('nEvts',np.array([nevent]))
            md.addarray('evt_ts',np.array(evt_ts))
            md.send()
            #now reset.
            nImage=[]
            i0Sum=[]
            image=[]
            for i in range(len(eventFilter)):
                nImage.append(0)
                i0Sum.append(0.)
                image.append(np.zeros([99,99]))                

    #should be different for shared memory. Reset image&i0 I assume as default behavior. Copies for continued sums?
    md.endrun()