def update(self): global countdn # check for config save if countdn > 0: countdn -= 1 if countdn == 0 and self._db: # save config db_url, db_name, db_instrument, db_alias = self._db.split( ',', 4) mycdb = cdb.configdb(db_url, db_instrument, True, db_name) mycdb.add_device_config('xpm') top = cdict() top.setInfo('xpm', self._name, None, 'serial1234', 'No comment') top.setAlg('config', [0, 0, 0]) lock.acquire() top.set('XTPG.CuDelay', self._xpm.CuGenerator.cuDelay.get(), 'UINT32') top.set('XTPG.CuBeamCode', self._xpm.CuGenerator.cuBeamCode.get(), 'UINT8') top.set('XTPG.CuInput', self._xpm.AxiSy56040.OutputConfig[0].get(), 'UINT8') v = [] for i in range(8): self._xpm.XpmApp.partition.set(i) v.append(self._xpm.XpmApp.l0Delay.get()) top.set('PART.L0Delay', v, 'UINT32') lock.release() if not db_alias in mycdb.get_aliases(): mycdb.add_alias(db_alias) mycdb.modify_device(db_alias, top)
def set_calib(db_url, instrument, seg, alias, calib): dict = json.loads(calib) create = True dbname = 'configDB' mycdb = cdb.configdb(db_url, instrument, create, root='configDB', user=instrument + 'opr', password='******') mycdb.add_device_config('hsdcal') top = cdict() top.setAlg('calib', [0, 0, 0]) help_str = "No help at this time" top.set("help:RO", help_str, 'CHARSTR') for k, v in dict['expert'].items(): top.set("expert." + k, v, 'UINT16') mycdb.add_alias(alias) name = seg.split('_')[0] segn = int(seg.split('_')[1]) top.setInfo('hsd', name, segn, 'serial1234', 'No comment') mycdb.modify_device(alias, top)
def update(self, cycle): # The following section will throw an exception if the CuInput PV is not set properly if cycle < 10: print('pvseq in %d' % (10 - cycle)) elif cycle == 10: self._seq = PVSeq(provider, self._name + ':SEQENG:0', self._ip, Engine(0, self._xpm.SeqEng_0)) self._pv_dumpSeq = SharedPV(initial=NTScalar('I').wrap(0), handler=CmdH(self._seq._eng.dump)) provider.add(self._name + ':DumpSeq', self._pv_dumpSeq) global countdn # check for config save if countdn > 0: countdn -= 1 if countdn == 0 and self._db: # save config print('Updating {}'.format(self._db)) db_url, db_name, db_instrument, db_alias = self._db.split( ',', 4) mycdb = cdb.configdb(db_url, db_instrument, True, db_name, user=db_instrument + 'opr', password='******') mycdb.add_device_config('xpm') top = cdict() top.setInfo('xpm', self._name, None, 'serial1234', 'No comment') top.setAlg('config', [0, 0, 0]) lock.acquire() top.set('XTPG.CuDelay', self._xpm.CuGenerator.cuDelay.get(), 'UINT32') top.set('XTPG.CuBeamCode', self._xpm.CuGenerator.cuBeamCode.get(), 'UINT8') top.set('XTPG.CuInput', self._xpm.AxiSy56040.OutputConfig[0].get(), 'UINT8') v = [] for i in range(8): self._xpm.XpmApp.partition.set(i) v.append(self._xpm.XpmApp.l0Delay.get()) top.set('PART.L0Delay', v, 'UINT32') lock.release() if not db_alias in mycdb.get_aliases(): mycdb.add_alias(db_alias) try: mycdb.modify_device(db_alias, top) except: pass
def get_config_with_params(db_url, instrument, db_name, cfgtype, detname): create = False mycdb = cdb.configdb(db_url, instrument, create, db_name) cfg = mycdb.get_configuration(cfgtype, detname) if cfg is None: raise ValueError('Config for instrument/detname %s/%s not found. dbase url: %s, db_name: %s, config_style: %s'%(instrument,detname,db_url,db_name,cfgtype)) cfg_no_RO_names = remove_read_only(cfg) return cfg_no_RO_names
def get_configdb(uri=URI_CONFIGDB, hutch='tmo', create=False, root=ROOT_CONFIGDB, user='******', password='******'): return configdb(uri, hutch, create=create, root=root, user=user, password=password)
def write_to_daq_config_db(args): #database contains collections which are sets of documents (aka json objects). #each type of device has a collection. The elements of that collection are configurations of that type of device. #e.g. there will be OPAL, EVR, and YUNGFRAU will be collections. How they are configured will be a document contained within that collection #Each hutch is also a collection. Documents contained within these collection have an index, alias, and list of devices with configuration IDs #How is the configuration of a state is described by the hutch and the alias found. E.g. TMO and BEAM. TMO is a collection. #BEAM is an alias of some of the documents in that collection. The document with the matching alias and largest index is the current #configuration for that hutch and alias. #When a device is configured, the device has a unique name OPAL7. Need to search through document for one that has an NAME called OPAL7. This will have #have two fields "collection" and ID field (note how collection here is a field. ID points to a unique document). This collection field and #ID point to the actuall Mongo DB collection and document create = True dbname = 'configDB' #this is the name of the database running on the server. Only client care about this name. db = 'configdb' if args.prod else 'devconfigdb' url = f'https://pswww.slac.stanford.edu/ws-auth/{db}/ws/' mycdb = cdb.configdb(url, args.inst, create, root=dbname, user=args.user, password=args.password) mycdb.add_alias(args.alias) mycdb.add_device_config('wave8') top = mcdict(args.yaml) top.setInfo('wave8', args.name, args.segm, args.id, 'No comment') top.setAlg('config', [0, 1, 0]) help_str = "-- user. --" help_str += "\ndelta_ns : nanoseconds difference from LCLS-1 timing" top.set("help:RO", help_str, 'CHARSTR') # Split configuration into two sections { User and Expert } # Expert configuration is the basis, and User configuration overrides # Expert variables map directly to Rogue variables top.set("user.delta_ns", -807692, 'INT32') # [ns from LCLS1 timing] top.set("expert.TriggerEventManager.TriggerEventBuffer.TriggerDelay", 0, 'UINT32') # user config mycdb.add_alias(args.alias) mycdb.modify_device(args.alias, top)
def main(): parser = argparse.ArgumentParser(description='Update gain map') parser.add_argument('--file' , help='input pixel mask', type=str, required=True) parser.add_argument('--gain', help='gain for pixels [0 1]', default=['M','L'], nargs=2, choices=gain_dict.keys(), required=True) parser.add_argument('--dev', help='use development db', action='store_true') parser.add_argument('--inst', help='instrument', type=str, default='ued') parser.add_argument('--alias', help='alias name', type=str, default='BEAM') parser.add_argument('--name', help='detector name', type=str, default='epixquad') parser.add_argument('--segm', help='detector segment', type=int, default=0) parser.add_argument('--id', help='device id/serial num', type=str, default='serial1234') parser.add_argument('--user', help='user for HTTP authentication', type=str, default='uedopr') parser.add_argument('--password', help='password for HTTP authentication', type=str, default='pcds') parser.add_argument('--test', help='test transformation', action='store_true') args = parser.parse_args() create = False dbname = 'configDB' detname = f'{args.name}_{args.segm}' db = 'devconfigdb' if args.dev else 'configdb' url = f'https://pswww.slac.stanford.edu/ws-auth/{db}/ws/' create = False mycdb = cdb.configdb(url, args.inst, create, root=dbname, user=args.user, password=args.password) cfg = mycdb.get_configuration(args.alias,detname) if cfg is None: raise ValueError('Config for instrument/detname %s/%s not found. dbase url: %s, db_name: %s, config_style: %s'%(args.inst,detname,url,dbname,args.alias)) top = epixquad_cdict() # We need the full cdict in order to store copyValues(cfg,top) # Now copy old values into the cdict # Write gainmap d = epixquad_readmap(args.file,args.gain) copyValues(d,top) print('Setting user.pixel_map') top.set('user.pixel_map', d['user.pixel_map']) # Store top.setInfo('epix10kaquad', args.name, args.segm, args.id, 'No comment') if not args.test: mycdb.modify_device(args.alias, top)
def write_to_daq_config_db(args): #database contains collections which are sets of documents (aka json objects). #each type of device has a collection. The elements of that collection are configurations of that type of device. #e.g. there will be OPAL, EVR, and YUNGFRAU will be collections. How they are configured will be a document contained within that collection #Each hutch is also a collection. Documents contained within these collection have an index, alias, and list of devices with configuration IDs #How is the configuration of a state is described by the hutch and the alias found. E.g. TMO and BEAM. TMO is a collection. #BEAM is an alias of some of the documents in that collection. The document with the matching alias and largest index is the current #configuration for that hutch and alias. #When a device is configured, the device has a unique name OPAL7. Need to search through document for one that has an NAME called OPAL7. This will have #have two fields "collection" and ID field (note how collection here is a field. ID points to a unique document). This collection field and #ID point to the actuall Mongo DB collection and document create = True dbname = 'configDB' #this is the name of the database running on the server. Only client care about this name. mycdb = cdb.configdb( 'https://pswww.slac.stanford.edu/ws-auth/devconfigdb/ws/', args.inst, create, root=dbname, user=args.user, password=args.password) mycdb.add_alias(args.alias) mycdb.add_device_config('timetool') top = cdict() top.setInfo('timetool', args.name, args.segm, args.id, 'No comment') top.setAlg('config', [2, 0, 0]) top.set("firmwareBuild:RO", "-", 'CHARSTR') top.set("firmwareVersion:RO", 0, 'UINT32') help_str = "-- user interface --" help_str += "\nstart_ns : nanoseconds from fiducial to exposure start" help_str += "\ngate_ns : nanoseconds from exposure start to stop" top.set("help:RO", help_str, 'CHARSTR') #Create a user interface that is an abstraction of the common inputs top.set("user.start_ns", 107649, 'UINT32') top.set("user.gate_ns", 1000, 'UINT32') #top.set("user.raw.prescale" , 2, 'UINT32') #top.set("user.fex.prescale_bkg", 3, 'UINT32') #top.set("user.fex.prescale_bkg", 3, 'UINT32') #top.set("user.fex.fir_coeff0"", 1., 'DOUBLE') #There are many rogue fields, but only a handful need to be configured. what are they? #1) the FIR coefficients. after accounting for parabolic fitting detection #2) start and stop? #3) main by pass. (still isn't working with FEX in hardware, but does in simulation.) #4) all prescalers. This has potential to crash linux kernel during hi rate and low prescaling. How to add protection? Slow ramp? #5) low pass on background #6) op code (now called readout group). there's no rogue counter part of this yet. #7) the load coefficients bit needs to set to one for the FIR coefficients to be written. #8) camera rate and soft or hard trigger. The soft trigger is for offline testing. For users or just for me? #9) the batcher bypass so soft trigger doesn't halt. # timing system top.set( 'expert.TimeToolKcu1500.Kcu1500Hsio.TimingRx.TriggerEventManager.TriggerEventBuffer[0].PauseThreshold', 16, 'UINT32') top.set( 'expert.TimeToolKcu1500.Kcu1500Hsio.TimingRx.TriggerEventManager.TriggerEventBuffer[0].TriggerDelay', 42, 'UINT32') top.set( 'expert.TimeToolKcu1500.Kcu1500Hsio.TimingRx.TriggerEventManager.TriggerEventBuffer[0].Partition', 0, 'UINT32') # prescaling top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Prescale.DialInPreScaling", 2, 'UINT32') # prescaled raw data top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.background_prescaler.DialInPreScaling", 3, 'UINT32' ) # prescaled raw backgrounds (may consider accumulated backgrounds instead) # initial fir filter top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet0", "7f7f7f7f", 'CHARSTR') #high part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet1", "7f7f7f7f", 'CHARSTR') #high part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet2", "7f7f7f7f", 'CHARSTR') #high part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet3", "7f7f7f7f", 'CHARSTR') #high part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet4", "81818181", 'CHARSTR') #low part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet5", "81818181", 'CHARSTR') #low part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet6", "81818181", 'CHARSTR') #low part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.CoefficientSet7", "81818181", 'CHARSTR') #low part of step top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FIR.LoadCoefficients", "1", 'CHARSTR' ) #low part of step. Having a value of 1 causes a segfault in pgpread_timetool.cc. But not in tt_config.py. # time constants top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FrameIIR.TimeConstant", 8, 'UINT32') # subtraction enabled top.set( "expert.TimeToolKcu1500.Application.AppLane[0].Fex.FrameSubtractor.SubtractionActive", 0, 'UINT32') #turn background subtract on # Feb[0] refers to pgp lane, Ch[0][,1] refers to camera link channel from Feb (these should be abstracted) # UartOpal1000 is camType; sets serial registers # ClinkTop.LinkMode is Base,Medium,Full,Deca # ClinkTop.DataMode is 8b,10b,12b,14b,16b,24b,30b,36b # ClinkTop.FrameMode is None,Line,Frame # ClinkTop.TapCount # All serial commands are enumerated as registers top.set('expert.ClinkFeb[0].TrigCtrl[0].EnableTrig', 1, 'UINT8') # rogue wants 'bool' top.set('expert.ClinkFeb[0].TrigCtrl[0].InvCC', 0, 'UINT8') # rogue wants 'bool' top.set('expert.ClinkFeb[0].TrigCtrl[0].TrigMap', 0, 'UINT32') # ChanA/ChanB top.set('expert.ClinkFeb[0].TrigCtrl[0].TrigMask', 1, 'UINT32') # CC1 top.set('expert.ClinkFeb[0].TrigCtrl[0].TrigPulseWidth', 32.768, 'FLOAT') top.set("expert.ClinkFeb[0].ClinkTop.PllConfig[0]", '80MHz', 'CHARSTR') top.set("expert.ClinkFeb[0].ClinkTop.PllConfig[1]", '80MHz', 'CHARSTR') top.set("expert.ClinkFeb[0].ClinkTop.PllConfig[2]", '80MHz', 'CHARSTR') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].LinkMode", 3, 'UINT32') # Full mode top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].DataMode", 1, 'UINT32') # 8-bit top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].FrameMode", 1, 'UINT32') # Line top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].TapCount", 8, 'UINT32') # top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].DataEn", 1, 'UINT8') # rogue wants 'bool' top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].Blowoff", 0, 'UINT8') # rogue wants 'bool' top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].BaudRate", 9600, 'UINT32') # bps top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].SerThrottle", 30000, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].SwControlValue", 0, 'UINT32') # Frame top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].SwControlEn", 0, 'UINT32') # Frame # Piranha Settings #commands can be sent manually using cl.ClinkFeb0.ClinkTop.Ch0.UartPiranha4._tx.sendString('GCP') #to manually query a camera hardware setting cl.ClinkFeb0.ClinkTop.Ch0.UartPiranha4._tx.sendString('get stm') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.CLS", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.CLM", 2, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.DST", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.FFM", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.FRS", 2, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.LPC", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.ROI[0]", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.ROI[1]", 2048, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SAC", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SAD[0]", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SAD[1]", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SAD[2]", 2048, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SAM", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SBH", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SBR", 9600, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SBV", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SCD", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SEM", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SET", 5000, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SMM", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SPF", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SSB", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SSF", 2, 'UINT32') #top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SSG",1,'UINT32') # requires two arguments (selector,gain) top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.STG", 2, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.STM", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.SVM", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.USD", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.USL", 1, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartPiranha4.USS", 1, 'UINT32') #the object hierarchy paths (e.g. cl.TimeToolKcu1500.Application.AppLane[0]... yadayadayada) for a device can be found by implementing #pr.generateAddressMap where pr comes from "import rogue as pr". For this to work, one has to be logged onto the machine hosting the firmware #that interacts with rogue. This particular register map can be found in the lcls2-pcie-apps directory cloned from https://github.com/slaclab/lcls2-pcie-apps. mycdb.modify_device(args.alias, top)
create = True dbname = 'configDB' #this is the name of the database running on the server. Only client care about this name. args = cdb.createArgs().args args.name = 'tmoopal2' args.segm = 0 args.id = 'opal_serial1235' args.alias = 'BEAM' args.prod = True args.inst = 'tmo' args.user = '******' args.password = '******' db = 'configdb' if args.prod else 'devconfigdb' url = f'https://pswww.slac.stanford.edu/ws-auth/{db}/ws/' mycdb = cdb.configdb(url, args.inst, create, root=dbname, user=args.user, password=args.password) mycdb.add_alias(args.alias) mycdb.add_device_config('opal') top = opal_cdict() top.setInfo('opal', args.name, args.segm, args.id, 'No comment') mycdb.modify_device(args.alias, top)
description='Write a new teb configuration into the database') parser.add_argument('--inst', help='instrument', type=str, default='tst') parser.add_argument('--alias', help='alias name', type=str, default='BEAM') parser.add_argument('--name', help='detector name', type=str, default='tmoTeb') parser.add_argument('--segm', help='detector segment', type=int, default=0) parser.add_argument('--id', help='device id/serial num', type=str, default='No serial number') args = parser.parse_args() # these are the current default values, but put them here to be explicit create = False dbname = 'configDB' mycdb = cdb.configdb('https://pswww.slac.stanford.edu/ws-auth/devconfigdb/ws/', args.inst, create, dbname) # this needs to be called once per detType at the # "beginning of time" to create the collection name (same as detType # in top.setInfo). It doesn't hurt to call it again if the collection # already exists, however. mycdb.add_device_config('teb') top = cdict() top.setInfo('teb', args.name, args.segm, args.id, 'No comment') top.setAlg('tebConfig', [0, 0, 1]) top.set('soname', 'libtmoTeb.so', 'CHARSTR') # This is a required entry:
help='user for HTTP authentication', type=str, default='xppopr') parser.add_argument('--password', help='password for HTTP authentication', type=str, default='pcds') args = parser.parse_args() # these are the current default values, but I put them here to be explicit create = True dbname = 'configDB' mycdb = cdb.configdb('https://pswww.slac.stanford.edu/ws-auth/devconfigdb/ws/', args.inst, create, root=dbname, user=args.user, password=args.password) mycdb.add_alias(args.alias) # this needs to be called once per detType at the # "beginning of time" to create the collection name (same as detType # in top.setInfo). It doesn't hurt to call it again if the collection # already exists, however. mycdb.add_device_config('ts') top = cdict() top.setInfo('ts', args.name, args.segm, args.id, 'No comment') top.setAlg('config', [2, 0, 0])
default='https://pswww.slac.stanford.edu/ws-auth/devconfigdb/ws/', help='DB URL') parser.add_argument('--inst', type=str, default='tst', help='instrument') parser.add_argument('--alias', type=str, default='PROD', help='alias') parser.add_argument('--db', type=str, default='configDB', help='database') parser.add_argument('--load', action='store_true', help='load from db') parser.add_argument('--store', action='store_true', help='store to db') parser.add_argument('--name', type=str, default='DAQ:LAB2:XPM:0', help='device name') args = parser.parse_args() if args.store: mycdb = cdb.configdb(args.url, args.inst, create, args.db) mycdb.add_device_config('xpm') top = cdict() top.setInfo('xpm', args.name, None, 'serial1234', 'No comment') top.setAlg('config', [0, 0, 0]) top.set('XTPG.CuDelay', 160000, 'UINT32') top.set('XTPG.CuBeamCode', 40, 'UINT8') top.set('XTPG.CuInput', 2, 'UINT8') v = [90] * 8 top.set('PART.L0Delay', v, 'UINT32') if not args.alias in mycdb.get_aliases(): mycdb.add_alias(args.alias)
def write_to_daq_config_db(args): #database contains collections which are sets of documents (aka json objects). #each type of device has a collection. The elements of that collection are configurations of that type of device. #e.g. there will be OPAL, EVR, and YUNGFRAU will be collections. How they are configured will be a document contained within that collection #Each hutch is also a collection. Documents contained within these collection have an index, alias, and list of devices with configuration IDs #How is the configuration of a state is described by the hutch and the alias found. E.g. TMO and BEAM. TMO is a collection. #BEAM is an alias of some of the documents in that collection. The document with the matching alias and largest index is the current #configuration for that hutch and alias. #When a device is configured, the device has a unique name OPAL7. Need to search through document for one that has an NAME called OPAL7. This will have #have two fields "collection" and ID field (note how collection here is a field. ID points to a unique document). This collection field and #ID point to the actuall Mongo DB collection and document create = True dbname = 'configDB' #this is the name of the database running on the server. Only client care about this name. db = 'configdb' if args.prod else 'devconfigdb' url = f'https://pswww.slac.stanford.edu/ws-auth/{db}/ws/' mycdb = cdb.configdb(url, args.inst, create, root=dbname, user=args.user, password=args.password) mycdb.add_alias(args.alias) mycdb.add_device_config('wave8') top = mcdict(args.yaml) top.setInfo('wave8', args.name, args.segm, args.id, 'No comment') top.setAlg('config', [0, 0, 1]) top.set("firmwareBuild:RO", "-", 'CHARSTR') top.set("firmwareVersion:RO", 0, 'UINT32') help_str = "-- user.raw --" help_str += "\nstart_ns : nanoseconds from timing fiducial to sampling start" help_str += "\ngate_ns : nanoseconds from sampling start to finish" help_str += "\nenable[8] : include channel in readout [0/1]" help_str += "\nprescale : record 1-out-of-N events" help_str += "\n-- user.fex --" help_str += "\nbaseline : samples prior to start to average for integral subtraction" help_str += "\nstart_ns : nanoseconds from timing fiducial to integral start" help_str += "\ngate_ns : nanoseconds from integral start to finish" help_str += "\nquadsel : select [even/odd] channels for X,Y,I calculation" help_str += "\ncoeff[4] : coefficients for X,Y,I calculation" help_str += "\n (A,B,C,D) = (0,2,4,6) if quadsel=even else (1,3,5,7)" help_str += "\n I = (coeff[0]*integ[A] + coeff[1]*integ[B] + coeff[2]*integ[C] + coeff[3]*integ[D])" help_str += "\n X = (coeff[0]*integ[A] + coeff[1]*integ[B] - coeff[2]*integ[C] + coeff[3]*integ[D]) / I" help_str += "\n Y = (coeff[0]*integ[A] - coeff[1]*integ[B] + coeff[2]*integ[C] - coeff[3]*integ[D]) / I" top.set("help:RO", help_str, 'CHARSTR') top.define_enum('baselineEnum', {'%d samples' % (2**key): key for key in range(1, 8)}) top.define_enum('quadrantEnum', {'Even': 0, 'Odd': 1}) # Split configuration into two sections { User and Expert } # Expert configuration is the basis, and User configuration overrides # Expert variables map directly to Rogue variables top.set("user.raw.start_ns", 107692, 'UINT32') # [ns from timing fiducial] top.set("user.raw.gate_ns", 400, 'UINT32') # [ns] top.set("user.raw.nsamples:RO", 100, 'UINT32') # [ns] top.set("user.raw.enable", [1] * 8, 'UINT8') # record channel top.set("user.raw.prescale", 1, 'UINT32') # record 1 out of N events top.set("user.fex.baseline", 1, 'baselineEnum') # [log2 of 250 MHz ADC samples] top.set("user.fex.start_ns", 107892, 'UINT32') # [ns from timing fiducial] top.set("user.fex.gate_ns", 200, 'UINT32') # [ns] top.set("user.fex.nsamples:RO", 50, 'UINT32') # [ns] top.set("user.fex.quadsel", 0, 'quadrantEnum') # channels for X,Y,I calculation top.set("user.fex.coeff", [1.] * 4, 'DOUBLE') # coefficient in X,Y,I calculation top.init("expert", "Top.SystemRegs.AvccEn0", 1, 'UINT8') top.init("expert", "Top.SystemRegs.AvccEn1", 1, 'UINT8') top.init("expert", "Top.SystemRegs.Ap5V5En", 1, 'UINT8') top.init("expert", "Top.SystemRegs.Ap5V0En", 1, 'UINT8') top.init("expert", "Top.SystemRegs.A0p3V3En", 1, 'UINT8') top.init("expert", "Top.SystemRegs.A1p3V3En", 1, 'UINT8') top.init("expert", "Top.SystemRegs.Ap1V8En", 1, 'UINT8') top.init("expert", "Top.SystemRegs.FpgaTmpCritLatch", 0, 'UINT8') top.init("expert", "Top.SystemRegs.AdcReset", 0, 'UINT8') top.init("expert", "Top.SystemRegs.AdcCtrl1", 0, 'UINT8') top.init("expert", "Top.SystemRegs.AdcCtrl2", 0, 'UINT8') top.init("expert", "Top.SystemRegs.TrigEn", 0, 'UINT8') top.init("expert", "Top.SystemRegs.timingRxUserRst", 0, 'UINT8') top.init("expert", "Top.SystemRegs.timingTxUserRst", 0, 'UINT8') top.init("expert", "Top.SystemRegs.timingUseMiniTpg", 0, 'UINT8') top.init("expert", "Top.SystemRegs.TrigSrcSel", 1, 'UINT8') top.init("expert", "Top.Integrators.TrigDelay", 0, 'UINT32') # user config top.init("expert", "Top.Integrators.IntegralSize", 0, 'UINT32') # user config top.init("expert", "Top.Integrators.BaselineSize", 0, 'UINT8') # user config top.init("expert", "Top.Integrators.QuadrantSel", 0, 'quadrantEnum') # user config top.init("expert", "Top.Integrators.CorrCoefficientFloat64", [1.0] * 4, 'DOUBLE') # user config top.init("expert", "Top.Integrators.CntRst", 0, 'UINT8') top.init("expert", "Top.Integrators.ProcFifoPauseThreshold", 255, 'UINT32') top.init("expert", "Top.Integrators.IntFifoPauseThreshold", 255, 'UINT32') top.init("expert", "Top.RawBuffers.BuffEn", [0] * 8, 'UINT32') # user config top.init("expert", "Top.RawBuffers.BuffLen", 100, 'UINT32') # user config top.init("expert", "Top.RawBuffers.CntRst", 0, 'UINT8') top.init("expert", "Top.RawBuffers.FifoPauseThreshold", 100, 'UINT32') top.init("expert", "Top.RawBuffers.TrigPrescale", 0, 'UINT32') # user config top.init("expert", "Top.BatcherEventBuilder.Bypass", 0, 'UINT8') top.init("expert", "Top.BatcherEventBuilder.Timeout", 0, 'UINT32') top.init("expert", "Top.BatcherEventBuilder.Blowoff", 0, 'UINT8') top.init("expert", "Top.TriggerEventManager.TriggerEventBuffer.Partition", 0, 'UINT8') top.init("expert", "Top.TriggerEventManager.TriggerEventBuffer.PauseThreshold", 16, 'UINT8') top.init("expert", "Top.TriggerEventManager.TriggerEventBuffer.TriggerDelay", 0, 'UINT32') # user config top.init("expert", "Top.TriggerEventManager.TriggerEventBuffer.MasterEnable", 0, 'UINT8') dlyAlane = [[0x0c, 0x0b, 0x0e, 0x0e, 0x10, 0x10, 0x12, 0x0b], [0x0a, 0x08, 0x0c, 0x0b, 0x0d, 0x0c, 0x0b, 0x0c], [0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13], [0x0d, 0x0c, 0x0d, 0x0b, 0x0a, 0x12, 0x12, 0x13]] dlyBlane = [[0x11, 0x11, 0x12, 0x12, 0x10, 0x11, 0x0b, 0x0b], [0x0a, 0x0a, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0a], [0x14, 0x14, 0x14, 0x14, 0x14, 0x12, 0x10, 0x11], [0x13, 0x12, 0x13, 0x12, 0x12, 0x11, 0x12, 0x11]] for iadc in range(4): base = 'Top.AdcReadout%d' % iadc top.init('expert', base + '.DelayAdcALane', dlyAlane[iadc], 'UINT8') top.init('expert', base + '.DelayAdcBLane', dlyBlane[iadc], 'UINT8') top.init('expert', base + '.DMode', 3, 'UINT8') top.init('expert', base + '.Invert', 0, 'UINT8') top.init('expert', base + '.Convert', 3, 'UINT8') for iadc in range(4): base = 'Top.AdcConfig%d' % iadc zeroregs = [ 7, 8, 0xb, 0xc, 0xf, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x20 ] for r in zeroregs: top.init('expert', base + '.AdcReg_0x%04X' % r, 0, 'UINT8') top.init('expert', base + '.AdcReg_0x0006', 0x80, 'UINT8') top.init('expert', base + '.AdcReg_0x000D', 0x6c, 'UINT8') top.init('expert', base + '.AdcReg_0x0015', 1, 'UINT8') top.init('expert', base + '.AdcReg_0x001F', 0xff, 'UINT8') top.init('expert', 'Top.AdcPatternTester.Channel', 0, 'UINT8') top.init('expert', 'Top.AdcPatternTester.Mask', 0, 'UINT8') top.init('expert', 'Top.AdcPatternTester.Pattern', 0, 'UINT8') top.init('expert', 'Top.AdcPatternTester.Samples', 0, 'UINT32') top.init('expert', 'Top.AdcPatternTester.Request', 0, 'UINT8') mycdb.add_alias(args.alias) mycdb.modify_device(args.alias, top)
def write_to_daq_config_db(args): #database contains collections which are sets of documents (aka json objects). #each type of device has a collection. The elements of that collection are configurations of that type of device. #e.g. there will be OPAL, EVR, and YUNGFRAU will be collections. How they are configured will be a document contained within that collection #Each hutch is also a collection. Documents contained within these collection have an index, alias, and list of devices with configuration IDs #How is the configuration of a state is described by the hutch and the alias found. E.g. TMO and BEAM. TMO is a collection. #BEAM is an alias of some of the documents in that collection. The document with the matching alias and largest index is the current #configuration for that hutch and alias. #When a device is configured, the device has a unique name OPAL7. Need to search through document for one that has an NAME called OPAL7. This will have #have two fields "collection" and ID field (note how collection here is a field. ID points to a unique document). This collection field and #ID point to the actuall Mongo DB collection and document create = True dbname = 'configDB' #this is the name of the database running on the server. Only client care about this name. mycdb = cdb.configdb( 'https://pswww.slac.stanford.edu/ws-auth/devconfigdb/ws/', args.inst, create, root=dbname, user=args.user, password=args.password) mycdb.add_alias(args.alias) mycdb.add_device_config('opal') top = cdict() top.setInfo('opal', args.name, args.segm, args.id, 'No comment') top.setAlg('config', [2, 0, 0]) top.set("firmwareBuild:RO", "-", 'CHARSTR') top.set("firmwareVersion:RO", 0, 'UINT32') help_str = "-- user interface --" help_str += "\nstart_ns : nanoseconds from fiducial to exposure start" help_str += "\ngate_ns : nanoseconds of exposure; rounded up to 10 microseconds" top.set("help:RO", help_str, 'CHARSTR') top.define_enum('binEnum', {'x%d' % (2**key): key for key in range(4)}) #Create a user interface that is an abstraction of the common inputs top.set("user.start_ns", 107749, 'UINT32') top.set("user.gate_ns", 100, 'UINT32') top.set("user.black_level", 32, 'UINT32') top.set("user.vertical_bin", 0, 'binEnum') # timing system top.set( 'expert.ClinkPcie.Hsio.TimingRx.TriggerEventManager.TriggerEventBuffer[0].PauseThreshold', 16, 'UINT32') top.set( 'expert.ClinkPcie.Hsio.TimingRx.TriggerEventManager.TriggerEventBuffer[0].TriggerDelay', 42, 'UINT32') top.set( 'expert.ClinkPcie.Hsio.TimingRx.TriggerEventManager.TriggerEventBuffer[0].Partition', 0, 'UINT32') top.define_enum( 'rateEnum', { '929kHz': 0, '71kHz': 1, '10kHz': 2, '1kHz': 3, '100Hz': 4, '10Hz': 5, '1Hz': 6 }) top.set( 'expert.ClinkPcie.Hsio.TimingRx.XpmMiniWrapper.XpmMini.Config_L0Select_RateSel', 6, 'rateEnum') # Feb[0] refers to pgp lane, Ch[0][,1] refers to camera link channel from Feb (these should be abstracted) # UartOpal1000 is camType; sets serial registers # ClinkTop.LinkMode is Base,Medium,Full,Deca # ClinkTop.DataMode is 8b,10b,12b,14b,16b,24b,30b,36b # ClinkTop.FrameMode is None,Line,Frame # ClinkTop.TapCount # All serial commands are enumerated as registers top.set('expert.ClinkFeb[0].TrigCtrl[0].EnableTrig', 1, 'UINT8') # rogue wants 'bool' top.set('expert.ClinkFeb[0].TrigCtrl[0].InvCC', 0, 'UINT8') # rogue wants 'bool' top.set('expert.ClinkFeb[0].TrigCtrl[0].TrigMap', 0, 'UINT32') # ChanA/ChanB top.set('expert.ClinkFeb[0].TrigCtrl[0].TrigMask', 1, 'UINT32') # CC1 top.set('expert.ClinkFeb[0].TrigCtrl[0].TrigPulseWidth', 32.768, 'FLOAT') top.set("expert.ClinkFeb[0].ClinkTop.PllConfig[0]", '80MHz', 'CHARSTR') top.set("expert.ClinkFeb[0].ClinkTop.PllConfig[1]", '80MHz', 'CHARSTR') top.set("expert.ClinkFeb[0].ClinkTop.PllConfig[2]", '80MHz', 'CHARSTR') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].LinkMode", 1, 'UINT32') # Base mode top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].DataMode", 3, 'UINT32') # 12-bit top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].FrameMode", 2, 'UINT32') # Frame top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].TapCount", 2, 'UINT32') # top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].DataEn", 1, 'UINT8') # rogue wants 'bool' top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].Blowoff", 0, 'UINT8') # rogue wants 'bool' top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].BaudRate", 57600, 'UINT32') # bps top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].SerThrottle", 10000, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].SwControlValue", 0, 'UINT32') # Frame top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].SwControlEn", 0, 'UINT32') # Frame top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.BL", 32, 'UINT32') # black level top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.GA", 100, 'UINT32') # digital gain, percent top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.VBIN", 0, 'UINT32') # vertical binning (powers-of-two)[0..3] top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.VR", 1, 'UINT32') # vertical remapping (top-to-bottom, left-to-right) top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.MI", 0, 'UINT32') # output mirroring (hor=b0, ver=b1) top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.OR", 12, 'UINT32') # output resolution, bits top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.TP", 0, 'UINT32') # test pattern on/off # top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.OLUTE", 0,'UINT32') # output lookup table enable on/off (not implemented) top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.DPE", 0, 'UINT32') # defect pixel correction on/off top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.OVL", 1, 'UINT32') # overlay frame counter and integration time top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.MO", 1, 'UINT32') # operating mode continuous, triggered top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.CCE[0]", 0, 'UINT32') # trigger on CC1 top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.CCE[1]", 0, 'UINT32') # polarity 0=rise-to-fall 1=fall-to-rise top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.FP", 0, 'UINT32') # frame period, continuous mode, 10 us units top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.IT", 1, 'UINT32') # integration time, 10 us units (< FP-10 and 32000) top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.CCFS[0]", 0, 'UINT32') # only relevant for modes 2,3 top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.CCFS[1]", 0, 'UINT32') # only relevant for modes 2,3 top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.OFS", 1, 'UINT32') # color cameras only top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.WB[0]", 100, 'UINT32') # red gain top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.WB[1]", 100, 'UINT32') # green gain top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.WB[2]", 100, 'UINT32') # blue gain # top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.FSE",0,'UINT32') # flash strobe enable (not implemented) top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.FSM", 0, 'UINT32') # flash strobe mode top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.FST[0]", 0, 'UINT32') # flash stroble timing top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.FST[1]", 0, 'UINT32') top.set("expert.ClinkFeb[0].ClinkTop.Ch[0].UartOpal1000.FSP", 1, 'UINT32') # flash strobe polarity #the object hierarchy paths (e.g. cl.TimeToolKcu1500.Application.AppLane0... yadayadayada) for a device can be found by implementing #pr.generateAddressMap where pr comes from "import rogue as pr". For this to work, one has to be logged onto the machine hosting the firmware #that interacts with rogue. This particular register map can be found in the lcls2-pcie-apps directory cloned from https://github.com/slaclab/lcls2-pcie-apps. mycdb.modify_device(args.alias, top)
def get_configdb(uri_suffix=URI_CONFIGDB, inst=None, root=ROOT_CONFIGDB): #print('XXX get_configdb', uri_suffix, inst, root) return configdb(uri_suffix, inst, root=root)