Beispiel #1
0
def main(exp, run, configFileName):

	experimentNameAndRun = "exp=%s:run=%d"%(exp, run)
	print("current working directory"+str(os.curdir))	
	os.system('mkdir config')
	print("creating libraries")
	os.system('touch config/__init__.py')

	print("initializing")
	myDataSource = psana.MPIDataSource(experimentNameAndRun)
	f = open('./config/'+configFileName,'w')
	print("writing libraries")

	f.write('##########################\n')
	f.write('#######DAQ DEVICES########\n')
	f.write('##########################\n')

	for thisDetectorName in psana.DetNames():
		#f.write('#detectorStart, ')
		f.write('#')
		for i in thisDetectorName:
			f.write(str(i)+', ')
		#f.write(' detectorFinish')
		f.write('\n')
	f.write('##########################\n')
	f.write('#######EPICS PVs##########\n')
	f.write('##########################\n')

	for thisDetectorName in psana.DetNames('epics'):
		f.write('#')
		for i in thisDetectorName:
			f.write(str(i)+', ')
		#f.write(' epicsPvFinish')
		f.write('\n')
	f.close()
Beispiel #2
0
def getDetName(exp, run):
    """ returns detector name.
    """
    detnames = psana.DetNames()
    for detname in detnames:
        if ("DscCsPad" in detname) or ("DsdCsPad" in detname) or ("DsaCsPad" in detname):
            return detname[1]
    return None
 def __init__(self, name='damage'):
     self.name = name
     self.detNames=[]
     for dn in psana.DetNames():
         if dn[1]!='':
             self.detNames.append(dn[1])
         else:
             self.detNames.append(dn[0])
     self.detAlias=[ det for det in self.detNames]
 def inRun(self):
     dNames=[]
     for dn in psana.DetNames():
         for dnn in dn:
             if dnn!='':
                 dNames.append(dnn)
     if self.detname in dNames:
         return True
     return False
Beispiel #5
0
 def getDetInfoList(self):
     myAreaDetectors = []
     self.detnames = psana.DetNames()
     for k in self.detnames:
         try:
             if Detector.PyDetector.dettype(str(k[0]), self.env) == Detector.AreaDetector.AreaDetector:
                 myAreaDetectors.append(k)
         except ValueError:
             continue
     self.detInfoList = list(set(myAreaDetectors))
def write_config_file(configFileName, config_type):

    f = open('./config/' + configFileName, 'w')
    print("writing libraries")

    f.write('##########################\n')
    f.write('#######DAQ DEVICES########\n')
    f.write('##########################\n')

    for thisDetectorName in psana.DetNames():
        is_acqiris = (True in ['Acqiris' in i for i in thisDetectorName])
        #IPython.embed()

        f.write('#')
        det_desc = []
        for i in thisDetectorName:
            f.write(str(i) + ',')
            det_desc.append(i)

            #f.write(' detectorFinish')

        if (is_acqiris):
            if ("make_acq_basis" == config_type):
                f.write(det_desc[-2] + ',None,make_acq_svd_basis,\n')

            elif ("use_acq_basis" == config_type):
                f.write(det_desc[-2] + ',use_acq_svd_basis,None,\n')
            else:
                f.write('\n')
        else:
            f.write('\n')
    f.write('##########################\n')
    f.write('#######EPICS PVs##########\n')
    f.write('##########################\n')

    for thisDetectorName in psana.DetNames('epics'):
        f.write('#')
        for i in thisDetectorName:
            f.write(str(i) + ', ')
        #f.write(' epicsPvFinish')
        f.write('\n')
    f.close()
Beispiel #7
0
 def __init__(self, codes=[[162], []]):
     evrNames = [n[0] for n in psana.DetNames() if ':Evr.' in n[0]]
     print('in lightStatus', evrNames)
     if len(evrNames) < 1:
         return
     nCodesMax = -1
     for name in evrNames:
         nCodes = psana.Detector(name)._fetch_configs()[0].neventcodes()
         if nCodes > nCodesMax:
             nCodesMax = nCodes
             evrName = name
     if nCodesMax < 0:
         return
     defaultDetector.__init__(self, evrName, 'lightStatus')
     self.xrayCodes = codes[0]
     self.laserCodes = codes[1]
Beispiel #8
0
    def __init__(self, exp, run, detector_name, codes=None):
        """
        exp: experiment string
        run: run number
        detector_name: detecrtor string
        """
        assert (has_psana)

        self.run_str = run
        self.exp = exp
        self.codes = codes
        self.ds = psana.DataSource("exp=%s:run=%d:idx" % (exp, run))

        self.run = self.ds.runs().next()
        self.times = self.run.times()
        self.N_events = self.N = len(self.times)
        self.event_info_string = "Start"

        self.detnames = [d for sl in psana.DetNames() for d in sl]
        self.env = self.ds.env()

        assert (detector_name in self.detnames)

        self.code_dets = [
            psana.Detector(d, self.env) for d in self.detnames
            if d.startswith("evr")
        ]

        self.detector_name = detector_name
        self.Detector = psana.Detector(self.detector_name, self.env)
        self.gas_reader = psana.Detector("FEEGasDetEnergy", self.env)
        self.spectrometer = psana.Detector("FeeSpec-bin", self.env)

        #       Get image shape..
        I = None
        i = 0
        while I is None:
            ev = self.run.event(self.times[i])
            if ev is None:
                i += 1
                continue
            I = self.Detector.image(ev)
            i += 1
        self.img_sh = I.shape
        self.empty_img = np.zeros(self.img_sh)
        self.gain_map = self.Detector.gain_mask(run) > 1
Beispiel #9
0
    def getDetName(self, exp, run):
        """ returns detector name.
        """
        if not ((exp in self.badList) and (run in self.badList[exp])):
            ds = Utils.safeDataSource(exp, run)
            print("@@@@@ saveDataSource: ", ds)
            if ds is not None:
                print("@@@@@ ds: ", ds)
                detnames = psana.DetNames()
                print("@@@@@ detnames: ", detnames)
                for detname in detnames:

                    if ("DscCsPad" in detname) or ("DsdCsPad"
                                                   in detname) or ("DsaCsPad"
                                                                   in detname):
                        return detname[1]
            return None
Beispiel #10
0
 def detectorValidator(self):
     """ Validates that the experiment and run number found used a CsPad detector
     returns the experiment, run number, detector.
     """
     while True:
         found, name, run = self.randExpRun()
         if found:
             if ("cxi" in name):
                 if not ((name in self.badList) and
                         (run in self.badList[name])):
                     ds = Utils.safeDataSource(name, run)
                     if ds is not None:
                         detnames = psana.DetNames()
                         for detname in detnames:
                             if ("DscCsPad" in detname) or (
                                     "DsdCsPad" in detname) or ("DsaCsPad"
                                                                in detname):
                                 return [True, name, run, detname[1]]
Beispiel #11
0
 def get_det_suggest(self):
     if not isinstance(self.expName,str):
         return []
     if not isinstance(self.runNumber,int):
         return []
     if self.ds is None:
         return []
     myAreaDetectors = []
     import Detector.PyDetector
     import Detector.AreaDetector
     ds = psana.DataSource("exp="+self.expName+":run="+str(self.runNumber)+':idx')
     for k in psana.DetNames():
         try:
             if Detector.PyDetector.dettype(str(k[0]), self.env) == Detector.AreaDetector.AreaDetector:
                 myAreaDetectors.append(k)
         except Exception as err:
             continue
     detInfoList = list(set(myAreaDetectors))
     return detInfoList
Beispiel #12
0
    w_weights = weiner_weights(w_weights);

    for i in range(len(runstrs)):
        runstr = runstrs[i];
        expstr = expstrs[i];
        atten = attens[i];
        vwin = vwins[i];
        num = vwin[1]-vwin[0];
        nmidshots = int(0);
        ngoodshots = int(0);
        printsample = printsamples[i];
        subref = subrefs[i];
        dsourcestr = 'exp=' + expstr + ':run=' + runstr + ':smd';
        print("running:\t",dsourcestr)
        ds = psana.DataSource(dsourcestr);
        print(psana.DetNames('detectors'));
        det = psana.Detector('OPAL1') # for AMO
        GDdet = psana.Detector('FEEGasDetEnergy'); #This I hope is the FEE Gas Detector readings
        EBdet = psana.Detector('EBeam'); #This I hope is the BLD data
        evr = psana.Detector('NoDetector.0:Evr.0');
        cd = psana.Detector('ControlData');

        y_init = 0;
        y_final = 0;
        R = np.zeros((0,nsamples),dtype=float);
        R_back = np.zeros((0,nsamples),dtype=float);
        F_abs = np.zeros((0,nsamples),dtype=float);
        F_arg = np.zeros((0,nsamples),dtype=float);
        eb_data_hdr = '';
        eb_data = np.zeros(19,dtype=float);
        E = np.zeros((0,eb_data.shape[0]),dtype=float);
Beispiel #13
0
EXPSTR = 'exp=mfxx32516:run=%d:smd' % (args.run[0])
# EXPSTR = 'exp=mfxx32516:run=%d:smd:dir=/reg/d/ffb/mfx/mfxx32516/xtc:live' % (args.run[0])

# 'MfxEndstation.0:Epix10ka.0'  # spaghetti
# 'MfxEndstation.0:Epix10ka.1'  # meatballs
# 'MfxEndstation.0:Epix10ka.2'  # cheese

# filename = "".join([c for c in EXPSTR if c.isalnum()]).rstrip() + '.h5'
filename = "run_%d.h5" % (args.run[0])
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()

dsrc = pa.MPIDataSource(EXPSTR)
detNames = pa.DetNames()  # detector names
mdets = []  # list of detectors
mdets_sname = []  # list of short detector names
mdets_idx = []  # list of detector indicies

# only archive detectors of interest
for idx, detname in enumerate(detNames):
    sdet = detname[0].lower()
    if "epix10ka" in sdet or "beammon" in sdet or "acqiris" in sdet or "wave8" in sdet:
        mdets.append(detname[0])
        mdets_sname.append(detname[1])
        mdets_idx.append(idx)

# lists to keep track of detectors
mdets_d = []
mdets_s = []
Beispiel #14
0
    def setupExperiment(self):
        if self.parent.args.v >= 1: print "Doing setupExperiment"
        if self.hasExpRunInfo():
            self.getUsername()
            # Set up psocake directory in scratch
            if self.parent.args.outDir is None:
                self.parent.rootDir = '/reg/d/psdm/' + self.parent.experimentName[:
                                                                                  3] + '/' + self.parent.experimentName
                self.parent.elogDir = self.parent.rootDir + '/scratch/psocake'
                self.parent.psocakeDir = self.parent.rootDir + '/scratch/' + self.username + '/psocake'
            else:
                self.parent.rootDir = self.parent.args.outDir
                self.parent.elogDir = self.parent.rootDir + '/psocake'
                self.parent.psocakeDir = self.parent.rootDir + '/' + self.username + '/psocake'
            self.parent.psocakeRunDir = self.parent.psocakeDir + '/r' + str(
                self.parent.runNumber).zfill(4)

            if self.parent.args.v >= 1:
                print "psocakeDir: ", self.parent.psocakeDir

            # Update peak finder outdir and run number
            self.parent.pk.p3.param(
                self.parent.pk.hitParam_grp,
                self.parent.pk.hitParam_outDir_str).setValue(
                    self.parent.psocakeDir)
            self.parent.pk.p3.param(self.parent.pk.hitParam_grp,
                                    self.parent.pk.hitParam_runs_str).setValue(
                                        self.parent.runNumber)
            # Update powder outdir and run number
            self.parent.mk.p6.param(self.parent.mk.powder_grp,
                                    self.parent.mk.powder_outDir_str).setValue(
                                        self.parent.psocakeDir)
            self.parent.mk.p6.param(self.parent.mk.powder_grp,
                                    self.parent.mk.powder_runs_str).setValue(
                                        self.parent.runNumber)
            # Update hit finding outdir, run number
            self.parent.hf.p8.param(
                self.parent.hf.spiParam_grp,
                self.parent.hf.spiParam_outDir_str).setValue(
                    self.parent.psocakeDir)
            self.parent.hf.p8.param(self.parent.hf.spiParam_grp,
                                    self.parent.hf.spiParam_runs_str).setValue(
                                        self.parent.runNumber)
            # Update indexing outdir, run number
            self.parent.index.p9.param(self.parent.index.launch_grp,
                                       self.parent.index.outDir_str).setValue(
                                           self.parent.psocakeDir)
            self.parent.index.p9.param(self.parent.index.launch_grp,
                                       self.parent.index.runs_str).setValue(
                                           self.parent.runNumber)
            # Update quantifier filename
            fname = self.parent.psocakeRunDir + '/' + self.parent.experimentName + '_' + str(
                self.parent.runNumber).zfill(4) + '.cxi'
            if self.parent.args.mode == 'sfx':
                dsetname = '/entry_1/result_1/nPeaksAll'
            elif self.parent.args.mode == 'spi':
                dsetname = '/entry_1/result_1/nHitsAll'
            else:
                dsetname = '/entry_1/result_1/'
            self.parent.small.pSmall.param(
                self.parent.small.quantifier_grp,
                self.parent.small.quantifier_filename_str).setValue(fname)
            self.parent.small.pSmall.param(
                self.parent.small.quantifier_grp,
                self.parent.small.quantifier_dataset_str).setValue(dsetname)
            self.setupPsocake()

            # Update hidden CrystFEL files
            self.updateHiddenCrystfelFiles('lcls')

            if self.parent.args.localCalib:
                if self.parent.args.v >= 1: print "Using local calib directory"
                psana.setOption('psana.calib-dir', './calib')

            try:
                self.ds = psana.DataSource('exp=' +
                                           str(self.parent.experimentName) +
                                           ':run=' +
                                           str(self.parent.runNumber) + ':idx')
            except:
                print "############# No such datasource exists ###############"
            self.run = self.ds.runs().next()
            self.times = self.run.times()
            self.eventTotal = len(self.times)
            self.parent.stack.spinBox.setMaximum(self.eventTotal -
                                                 self.parent.stack.stackSize)
            self.p.param(self.exp_grp, self.exp_evt_str).setLimits(
                (0, self.eventTotal - 1))
            self.p.param(self.exp_grp, self.exp_evt_str,
                         self.exp_numEvents_str).setValue(self.eventTotal)
            self.env = self.ds.env()

            if self.parent.detInfoList is None:
                self.parent.evt = self.run.event(self.times[-1])
                myAreaDetectors = []
                self.parent.detnames = psana.DetNames()
                for k in self.parent.detnames:
                    try:
                        if Detector.PyDetector.dettype(
                                str(k[0]), self.env
                        ) == Detector.AreaDetector.AreaDetector:
                            myAreaDetectors.append(k)
                    except ValueError:
                        continue
                self.parent.detInfoList = list(set(myAreaDetectors))
                print "#######################################"
                print "# Available area detectors: "
                for k in self.parent.detInfoList:
                    print "#", k
                print "#######################################"

            # Launch e-log crawler
            if self.logger and self.crawlerRunning == False:
                if self.parent.args.v >= 1: print "Launching crawler"
                self.launchCrawler()
                self.crawlerRunning = True

        if self.hasExpRunDetInfo():
            self.parent.det = psana.Detector(str(self.parent.detInfo),
                                             self.env)
            self.parent.det.do_reshape_2d_to_3d(flag=True)
            self.parent.detAlias = self.getDetectorAlias(
                str(self.parent.detInfo))
            self.parent.epics = self.ds.env().epicsStore()
            self.setClen()

            # detector distance
            self.updateDetectorDistance('lcls')
            # pixel size
            self.updatePixelSize('lcls')
            # photon energy
            self.updatePhotonEnergy('lcls')

            # Some detectors do not read out at 120 Hz. So need to loop over events to guarantee a valid detector image.
            if self.parent.evt is None:
                self.parent.evt = self.run.event(self.times[0])
            self.detGuaranteed = self.parent.det.calib(self.parent.evt)
            if self.detGuaranteed is None:  # image isn't present for this event
                print "No image in this event. Searching for an event..."
                for i in np.arange(len(self.times)):
                    evt = self.run.event(self.times[i])
                    self.detGuaranteed = self.parent.det.calib(evt)
                    if self.detGuaranteed is not None:
                        print "Found an event with image: ", i
                        break

            # Setup pixel indices
            if self.detGuaranteed is not None:
                self.parent.pixelInd = np.reshape(
                    np.arange(self.detGuaranteed.size) + 1,
                    self.detGuaranteed.shape)
                self.parent.pixelIndAssem = self.parent.img.getAssembledImage(
                    'lcls', self.parent.pixelInd)
                self.parent.pixelIndAssem -= 1  # First pixel is 0
                # Get detector shape
                self.detGuaranteedData = self.parent.det.image(
                    self.parent.evt, self.detGuaranteed)

            # Write a temporary geom file
            self.parent.geom.deployCrystfelGeometry('lcls')
            self.parent.geom.writeCrystfelGeom('lcls')

            self.parent.img.setupRadialBackground()
            self.parent.img.updatePolarizationFactor()

        if self.parent.args.v >= 1: print "Done setupExperiment"
Beispiel #15
0
    default_dets.append(eorbitsDetector())
elif args.epicsAll:
    epicsPVall = ds.env().epicsStore().aliases()
elif args.full:
    epicsPVall = ds.env().epicsStore().aliases()
if len(epicsPVall) > 0:
    logger.debug('adding all epicsPVs....total of %d PVs' % (len(epicsPVall)))
    default_dets.append(epicsDetector(PVlist=epicsPVall, name='epicsAll'))
    logger.debug('default dets: ', [det.name for det in default_dets])

dets = []
if args.full:
    default_det_aliases = [det.name for det in default_dets]

    aliases = []
    for dn in psana.DetNames():
        if dn[1] != '':
            aliases.append(dn[1])
        else:
            aliases.append(dn[0])

    for alias in aliases:
        if alias in default_det_aliases: continue
        if alias == 'FEEGasDetEnergy': continue  #done by mpidatasource
        if alias == 'PhaseCavity': continue  #done by mpidatasource
        if alias.find('evr') >= 0: continue  #done by mpidatasource
        if alias == 'ControlData': continue  #done by my code
        if alias.find('BMMON') >= 0:
            default_dets.append(bmmonDetector(alias))
            continue
        elif alias.find('IPM') >= 0 or alias.find('Ipm') > 0:
Beispiel #16
0
from psmon.plots import Image as ii
from psmon.plots import XYPlot
from psmon import publish
import sys
from PIL import Image, ImageFont, ImageDraw

DETECTOR0 = 'MfxEndstation.0:Epix10ka.1'
# DETECTOR1 = 'MfxEndstation.0:Epix10ka.1'

# average over NUMEVT
NUMEVT = 120

ds = pa.DataSource('shmem=psana.0:stop=no')
# ds = pa.DataSource('exp=mfxx32516:run=253:smd')

detNames = pa.DetNames()
for detname in detNames:
    print(detname)

src = pa.Source(DETECTOR0)
det = pa.Detector(DETECTOR0)
env = ds.env()

config = env.configStore().get(pa.Epix.Config10kaV1, src)
if not config:
    print('no config')
else:
    print('epix10ka is configed')

BTEMP_color = "green"
ATEMP_color = "green"
Beispiel #17
0
                                   central=False,
                                   unbond=False,
                                   unbondnbrs=False)
        ipm = psana.Detector(ipm_name)
        if jet_cam_name is not None:
            jet_cam = psana.Detector(jet_cam_name)
        evr = psana.Detector(evr_name)
        masks = get_r_masks(det_map['shape'], cal_params['azav_bins'])
    except Exception as e:
        logger.warning('Unable to create psana detectors: {}'.format(e))
        sys.exit()

    if rank == 0:
        logger.info(f"Gathering small data for exp: {exp}, run: {run}, events:"
                    f" {cal_params['events']}")
        logger.info('Detectors Available: {}'.format(psana.DetNames()))

    # Iterate through and pull out small data
    for evt_idx, evt in enumerate(ds.events()):
        if evt_idx % 10 == 0:
            print('Event: {}'.format(evt_idx))
        try:
            print(event_code)
            print(type(event_code))
            if event_code not in evr.eventCodes(evt):
                continue
            # Get image and azav
            calib = detector.calib(evt)
            calib = calib * psana_mask
            det_image = detector.image(evt, calib)
            azav = np.array([np.mean(det_image[mask]) for mask in masks])
Beispiel #18
0
from pylab import *
import psana

dsource = psana.DataSource("exp=sxr10116:run=24")
psana.DetNames()

exitSlitOpal = psana.Detector("EXS_OPAL")
getEnergy = psana.Detector("SIOC:SYS0:ML00:AO627")

enumeratedEvents = enumerate(dsource.events())

eventNumber, myEvent = next(enumeratedEvents)

myImage = exitSlitOpal.image(myEvent)
myEnergy = getEnergy(myEvent)

monoExitSlitYagSpectrum = sum(myImage, axis=1)
myEnergyList = array([myEnergy])

for eventNumber, myEvent in enumeratedEvents:

    #myImage = exitSlitOpal.image(myEvent)
    myEnergy = getEnergy(myEvent)

    #monoExitSlitYagSpectrum = vstack([monoExitSlitYagSpectrum,sum(myImage,axis=1)])
    myEnergyList = append(myEnergyList, myEnergy)

    #print eventNumber
Beispiel #19
0
    def __init__(self, state):
        self.timestamps = None
        self.library = 'psana'
        config_file = None
        if ('LCLS/PsanaConf' in state):
            config_file = os.path.abspath(state['LCLS/PsanaConf'])
        elif ('LCLS' in state and 'PsanaConf' in state['LCLS']):
            config_file = os.path.abspath(state['LCLS']['PsanaConf'])
        if (config_file is not None):
            if (not os.path.isfile(config_file)):
                raise RuntimeError("Could not find [LCLS][PsanaConf]: %s" %
                                   (config_file))
            logging.info("Info: Found configuration file %s.", config_file)
            psana.setConfigFile(config_file)

        if 'LCLS/CalibDir' in state:
            calibdir = state['LCLS/CalibDir']
            logging.info("Setting calib-dir to %s" % calibdir)
            psana.setOption('psana.calib-dir', calibdir)
        elif ('LCLS' in state and 'CalibDir' in state['LCLS']):
            calibdir = state['LCLS']['CalibDir']
            logging.info("Setting calib-dir to %s" % calibdir)
            psana.setOption('psana.calib-dir', calibdir)

        if ('LCLS/DataSource' in state):
            dsrc = state['LCLS/DataSource']
        elif ('LCLS' in state and 'DataSource' in state['LCLS']):
            dsrc = state['LCLS']['DataSource']
        else:
            raise ValueError("You need to set the '[LCLS][DataSource]'"
                             " in the configuration")

        cmdline_args = _argparser.parse_args()
        self.N = cmdline_args.lcls_number_of_frames
        if cmdline_args.lcls_run_number is not None:
            dsrc += ":run=%i" % cmdline_args.lcls_run_number

        # Cache times of events that shall be extracted from XTC (does not work for stream)
        self.event_slice = slice(0, None, 1)
        if 'times' in state or 'fiducials' in state:
            if not ('times' in state and 'fiducials' in state):
                raise ValueError(
                    "Times or fiducials missing in state."
                    " Extraction of selected events expects both event identifiers"
                )
            if dsrc[:len('exp=')] != 'exp=':
                raise ValueError(
                    "Extraction of events with given times and fiducials"
                    " only works when reading from XTC with index files")
            if dsrc[-len(':idx'):] != ':idx':
                dsrc += ':idx'
            self.times = state['times']
            self.fiducials = state['fiducials']
            self.i = 0
            self.data_source = psana.DataSource(dsrc)
            self.run = self.data_source.runs().next()
        elif 'indexing' in state:
            if dsrc[-len(':idx'):] != ':idx':
                dsrc += ':idx'
            if 'index_offset' in state:
                self.i = state['index_offset'] / ipc.mpi.nr_event_readers()
            else:
                self.i = 0
            self.data_source = psana.DataSource(dsrc)
            self.run = self.data_source.runs().next()
            self.timestamps = self.run.times()
            if self.N is not None:
                self.timestamps = self.timestamps[:self.N]
            self.timestamps = self.timestamps[ipc.mpi.event_reader_rank()::ipc.
                                              mpi.nr_event_readers()]
        else:
            self.times = None
            self.fiducials = None
            self.i = 0
            if not dsrc.startswith('shmem='):
                self.event_slice = slice(ipc.mpi.event_reader_rank(), None,
                                         ipc.mpi.nr_event_readers())
            self.data_source = psana.DataSource(dsrc)
            self.run = None

        # Define how to translate between LCLS types and Hummingbird ones
        self._n2c = {}
        self._n2c[psana.Bld.BldDataFEEGasDetEnergy] = 'pulseEnergies'
        self._n2c[psana.Bld.BldDataFEEGasDetEnergyV1] = 'pulseEnergies'
        self._n2c[psana.Lusi.IpmFexV1] = 'pulseEnergies'
        self._n2c[psana.Camera.FrameV1] = 'camera'
        # Guard against old(er) psana versions
        try:
            self._n2c[psana.Bld.BldDataEBeamV1] = 'photonEnergies'
            self._n2c[psana.Bld.BldDataEBeamV2] = 'photonEnergies'
            self._n2c[psana.Bld.BldDataEBeamV3] = 'photonEnergies'
            self._n2c[psana.Bld.BldDataEBeamV4] = 'photonEnergies'
            self._n2c[psana.Bld.BldDataEBeamV5] = 'photonEnergies'
            self._n2c[psana.Bld.BldDataEBeamV6] = 'photonEnergies'
            self._n2c[psana.Bld.BldDataEBeamV7] = 'photonEnergies'
        except AttributeError:
            pass
        # CXI (CsPad)
        self._n2c[psana.CsPad.DataV2] = 'photonPixelDetectors'
        self._n2c[psana.CsPad2x2.ElementV1] = 'photonPixelDetectors'
        # CXI (OffAxis Cam)
        #self._n2c[psana.Camera.FrameV1] = 'photonPixelDetectors'
        # AMO (pnCCD)
        self._n2c[psana.PNCCD.FullFrameV1] = 'photonPixelDetectors'
        self._n2c[psana.PNCCD.FramesV1] = 'photonPixelDetectors'
        # --
        self._n2c[psana.Acqiris.DataDescV1] = 'ionTOFs'
        self._n2c[psana.EventId] = 'eventID'
        # Guard against old(er) psana versions
        try:
            self._n2c[psana.EvrData.DataV3] = 'eventCodes'
            self._n2c[psana.EvrData.DataV4] = 'eventCodes'
        except AttributeError:
            pass

        # Calculate the inverse mapping
        self._c2n = {}
        for k, v in self._n2c.iteritems():
            self._c2n[v] = self._c2n.get(v, [])
            self._c2n[v].append(k)

        # Define how to translate between LCLS sources and Hummingbird ones
        self._s2c = {}
        # CXI (OnAxis Cam)
        self._s2c['DetInfo(CxiEndstation.0:Opal4000.1)'] = 'Sc2Questar'
        # CXI (OffAxis Cam)
        self._s2c['DetInfo(CxiEndstation.0.Opal11000.0)'] = 'Sc2Offaxis'
        # CXI (CsPad)
        self._s2c['DetInfo(CxiDs1.0:Cspad.0)'] = 'CsPad Ds1'
        self._s2c['DetInfo(CxiDsd.0:Cspad.0)'] = 'CsPad Dsd'
        self._s2c['DetInfo(CxiDs2.0:Cspad.0)'] = 'CsPad Ds2'
        self._s2c['DetInfo(CxiDg3.0:Cspad2x2.0)'] = 'CsPad Dg3'
        self._s2c['DetInfo(CxiDg2.0:Cspad2x2.0)'] = 'CsPad Dg2'
        # AMO (pnCCD)
        self._s2c['DetInfo(Camp.0:pnCCD.1)'] = 'pnccdBack'
        self._s2c['DetInfo(Camp.0:pnCCD.0)'] = 'pnccdFront'
        # ToF detector
        self._s2c['DetInfo(AmoEndstation.0:Acqiris.0)'] = 'Acqiris 0'
        self._s2c['DetInfo(AmoEndstation.0:Acqiris.1)'] = 'Acqiris 1'
        self._s2c['DetInfo(AmoEndstation.0:Acqiris.2)'] = 'Acqiris 2'
        # AMO (Acqiris)
        self._s2c['DetInfo(AmoETOF.0:Acqiris.0)'] = 'Acqiris 0'
        self._s2c['DetInfo(AmoETOF.0:Acqiris.1)'] = 'Acqiris 1'
        self._s2c['DetInfo(AmoITOF.0:Acqiris.0)'] = 'Acqiris 2'
        self._s2c['DetInfo(AmoITOF.0:Acqiris.1)'] = 'Acqiris 3'

        # MCP Camera
        self._s2c['DetInfo(AmoEndstation.0:Opal1000.1)'] = 'OPAL1'
        # CXI (Acqiris)
        self._s2c['DetInfo(CxiEndstation.0:Acqiris.0)'] = 'Acqiris 0'
        self._s2c['DetInfo(CxiEndstation.0:Acqiris.1)'] = 'Acqiris 1'

        self.init_detectors(state)

        print "Detectors:", psana.DetNames()