def station_configuration(equipment, project, dss, year, doy, time, band, collector=None, roach_loglevel=None): """ describe a standard DSN Complex with WVSR recorders @param equipment : empty dict initialized by main 'station_configuration' @type equipment : dict @param project : """ if collector: pass else: collector = WVSRmetadataCollector(project, dss, year, doy, time) if equipment: pass else: equipment = standard_equipment(dss, band) for wvsr in collector.wvsr_cfg.keys(): BE_inputs = {} output_names = [] for IF in collector.wvsr_cfg[wvsr]['channels']: band = collector.wvsr_cfg[wvsr][IF]['IF_source'].split('_')[1] rx_name = band + str(dss) rx = equipment['Receiver'][rx_name] # the following depends on a naming convention which uses names like # 'wvsr.IF1' and 'X14.chan_id 1.I' using '.' as separatots BE_inputs[wvsr+".IF"+str(IF)] = rx.outputs[rx_name + \ collector.wvsr_cfg[wvsr][IF]['pol'][0] + 'U'] for subch in collector.wvsr_cfg[wvsr][1]['subchannels']: for Stokes in ['I', 'Q', 'U', 'V']: # use '_' to separate the name parts output_names.append(rx_name + "." + subch + "." + Stokes) logger.debug("station_configuration: BE inputs: %s", BE_inputs) logger.debug("station_configuration: BE outputs: %s", output_names) BE = ClassInstance(Backend, WVSRbackend, wvsr, collector, inputs=BE_inputs, output_names=output_names) equipment['Backend'] = BE return equipment
def station_configuration(equipment, roach_loglevel=logging.WARNING): """ Configuration for the DSN X-band system on DSS-43 using SAO backend Feed 1 (F1) is at 024-0.016, F2 at 024+0.016. The polarizations are linear, E and H. There are so many receiver outputs that it is simpler to let the software generate them. """ observatory = Observatory("Canberra") equipment['Telescope'] = Telescope(observatory, dss=43) telescope = equipment['Telescope'] equipment['FrontEnd'] = ClassInstance( FrontEnd, DSN_fe, "X43", inputs={'X43': telescope.outputs[telescope.name]}, output_names=['XR', 'XL']) front_end = equipment['FrontEnd'] equipment['Receiver'] = ClassInstance(Receiver, DSN_rx, "X", inputs={ 'XR': front_end.outputs["XR"], 'XL': front_end.outputs["XL"] }) equipment['Backend'] = ClassInstance( Backend, SAOspec, "SAO spectrometer", hardware=False, inputs={ 'SAO1': equipment['Receiver'].outputs['XRU'], 'SAO2': None, 'SAO3': equipment['Receiver'].outputs['XLU'], 'SAO4': None }) equipment['sampling_clock'] = None return observatory, equipment
def __repr__(self): return self.__unicode__() def __str__(self): return self.__unicode__() def __unicode__(self): """ Return identifier """ return "Valon5007 synth 2" ############################## tests ################################ if __name__ == "__main__": a = ClassInstance(Synthesizer, Valon1) print "Synthesizer", a.__unicode__() print a.get_p("label"), "frequency is", a.get_p("frequency"), "MHz" print a.update_synth_status() b = ClassInstance(Synthesizer, Valon2) print "Synthesizer", b.__unicode__() print b.get_p("label"), "frequency is", b.get_p("frequency"), "MHz" print b.update_synth_status() # This will raise an error try: d = ClassInstance(Synthesizer, Agilent) except NameError, details: print "Synthesizer NameError:", details
def station_configuration(equipment, roach_loglevel=logging.WARNING, hardware=None): """ Describe a DSN Complex Implicit here is the naming convention explained above for DSN front ends and receivers. The telescope output name is expected to be the same as the telescope name. The front end names are constructed from the dict `cfg'. The initialization of 'DSN_fe' depends on this to know the band name. @param equipment : equipment in addition to what is defined here @type equipment : dict of Device subclass objects @param roach_loglevel : log level for the ROACH loggers @type roach_loglevel : str @param hardware : hardware which is available or to be tested @type hardware : dict of boolean """ if hardware is None: hardware = { "Antenna": False, "FrontEnd": True, # currently we have no control over the front ends "Receiver": True, # currently we have no control over the receivers "IF_switch": {"DTO": True}, # allow multiple switches "Synthesizer": True, "Backend": True } if equipment is None: equipment = {} # Define the site obs = Observatory("GDSCC") tel = {} fe = {} rx = {} # For each station at the site, get a Telescope object, FrontEnd objects, # Receiver objects, Switch objects for dss in cfg.keys(): # 14,...,26 module_logger.debug("station_configuration: processing DSS-%d", dss) # define the telescope tel[dss] = Telescope(obs, dss=dss, hardware=hardware["Antenna"]) # for each band available on the telescope for band in cfg[dss].keys(): # S, X, Ka module_logger.debug("station_configuration: processing band %s", dss) fename = band+str(dss) outnames = [] # for each polarization processed by the receiver for pol in cfg[dss][band].keys(): # L, R module_logger.debug("station_configuration: processing pol %s", pol) outnames.append(fename+pol) # cfg[dss][band][pol]) module_logger.debug("station_configuration: FE output names: %s", outnames) fe[fename] = ClassInstance(FrontEnd, DSN_fe, fename, hardware=hardware["FrontEnd"], inputs = {fename: tel[dss].outputs[tel[dss].name]}, output_names = outnames) rx_inputs = {} rx_outnames = [] for outname in outnames: rx_inputs[outname] = fe[fename].outputs[outname] rx_outnames.append(outname+'U') # all DSN IFs are USB rx[fename] = ClassInstance(Receiver, DSN_rx, fename, hardware=hardware["Receiver"], inputs = rx_inputs, output_names = rx_outnames) equipment['Telescope'] = tel equipment['FrontEnd'] = fe equipment['Receiver'] = rx #This part has to be done by hand to show the physical cabling try: IFswitch = ClassInstance(Device, MS287client, "Matrix Switch", inputs={'In01': rx['S24'].outputs['S24RU'], 'In02': rx['S26'].outputs['S26RU'], 'In03': rx['X15'].outputs['X15RU'], 'In04': rx['X25'].outputs['X25RU'], 'In05': rx['Ka25'].outputs['Ka25RU'], 'In06': rx['S15'].outputs['S15RU'], 'In07': rx['X26'].outputs['X26RU'], 'In08': rx['Ka26'].outputs['Ka26RU'], 'In09': rx['S14'].outputs['S14RU'], 'In10': rx['X14'].outputs['X14RU'], 'In11': None, 'In12': None, 'In13': None, 'In14': None, 'In15': None, 'In16': None, 'In17': None, 'In18': None, 'In19': None, 'In20': None, 'In21': None, 'In22': None, 'In23': None, 'In24': None}, output_names=['IF1', 'IF2', 'IF3', 'IF4']) except Pyro.errors.NamingError: module_logger.error("Is the MS287 IF switch server running?") equipment['IF_switch'] = {"DTO": IFswitch} sample_clk = {} sample_clk[0] = ClassInstance(Synthesizer,Valon1,timeout=10) sample_clk[1] = ClassInstance(Synthesizer,Valon2,timeout=10) module_logger.debug(" roach1 sample clock is %f", sample_clk[0].get_p("frequency")) module_logger.debug(" roach2 sample clock is %f", sample_clk[1].get_p("frequency")) equipment['Synthesizer'] BE = ClassInstance(Backend, SAObackend, "32K Spectrometer", inputs = {"Ro1In1": IFswitch.outputs['IF1'], "Ro2In1": IFswitch.outputs['IF3']}, output_names = [["IF1pwr"], ["IF2pwr"]]) equipment['Backend'] = BE return obs, equipment
def station_configuration(roach_loglevel=logging.WARNING): """ This is the test setup in the lab with simulated 'front ends' and 'downconverters':: FE FE_chl DC +---+ ROACH noise +RFI noise+RFI --1 | | +---+ none --2 | | 1--ADC0 input 0 --| | none --3 | s | | 1 | none --4 | w | 2--ADC0 input 1 --| | noise pure pure-noise --5 | i | +---+ none --6 | t | +---+ none --7 | c | 3--ADC0 input 0 --| | none --8 | h | | 2 | tone pure tone --9 | | 4--ADC0 input 1 --| | ... +---+ none -24 | | +---+ The superclasses, which are defined in module Observatory, are:: - Observatory - site for the control room and signal processing equipment - Telescope - which captures the radiation - FrontEnd - which receives the radiation and splits it into its various channels for further processing - FE_channel - which processes on signal stream from the front end - Receiver - which does the down-conversion for one channel - Backend - which processes the down-converted signal from a channel - Switch - which can change the routing of a signal When required, to specify monitor and control code, a superclass is subclassed with a device class. Examples shown below are class KurtosisSpectrometer() for the BackEnd() superclass and JFW50MS287() for the Switch() superclass. @return: class instances for hardware """ # specify the observing context lab = Observatory("PSDGlab") telescope = Telescope(lab, dss=21) # specify the front ends; no actual M&C of hardware since DTO doesn't have # that option so no implementation class needed FE = {} FE["noise"] = FrontEnd(telescope, "noise source") FE["antenna"] = FrontEnd(telescope, "amplified paperclip") FE["tone"] = FrontEnd(telescope, "synthesizer") # define the front end channels; again, no actual M&C hardware FE_chl = {} FE_chl['noise'] = FE_channel(FE["noise"], "pure noise") FE_chl['RFI'] = FE_channel(FE["antenna"], "noise with RFI") FE_chl['tone'] = FE_channel(FE["tone"], "pure tone") # specify the down-converters and their signal sources; also not under our # control so no implementation classes DC = {} DC['noise'] = Receiver(FE_chl['noise'], "pure noise") DC['RFI'] = Receiver(FE_chl['RFI'], "noise +RFI") DC['tone'] = Receiver(FE_chl['tone'], "tone") # specify where the DC inputs come from. There's no way to automate this. # These are single item lists because they are one-to-one connections #FE_chl['noise'].destinations = [DC['noise']] #FE_chl['RFI'].destinations = [DC['RFI']] #FE_chl['tone'].destinations = [DC['tone']] #DC['noise'].sources = [FE_chl['noise']] #DC['RFI'].sources = [FE_chl['RFI']] #DC['tone'].sources = [FE_chl['tone']] # The spectrometers require sample clock generators. sample_clk = {} sample_clk[0] = ClassInstance(Synthesizer, Valon1, timeout=10) sample_clk[1] = ClassInstance(Synthesizer, Valon2, timeout=10) module_logger.debug(" roach1 sample clock is %f", sample_clk[0].get_p("frequency")) module_logger.debug(" roach2 sample clock is %f", sample_clk[1].get_p("frequency")) # describe the backend input selector switches; real hardware this time IFsw = {} for index in range(4): IFsw[index] = ClassInstance(Switch, JFW50MS287, lab, index, inputs=[ DC['RFI'], None, None, None, DC['noise'], None, None, None, DC['tone'], None, None, None, None, None, None, None, None, None, None, None, None, None, None, None ]) state = IFsw[index].get_state() signal_source = IFsw[index].sources[0] module_logger.debug(" IFsw[%d] state is %d", index, state) module_logger.debug(" IFsw[%d] signal source is %s", index, str(signal_source)) signal_source.destinations.append((IFsw[index], state)) # Specify the backends; we need these before we can specify the switch # The back-end IDs are keyed to the switch outputs, that is, the first # switch output feeds spectrometer[0], the last spectrometer[3]. roach = {} roaches = ['roach1', 'roach2'] # firmware.keys() roaches.sort() spec = {} data_channel = {} for name in roaches: module_logger.debug(' Instantiating %s', name) roach_index = int(name[-1]) - 1 roach[roach_index] = ClassInstance(Backend, Spec, lab, key=None, roach=name, LO=sample_clk[roach_index], loglevel=roach_loglevel) spec[roach_index] = find_BE_channels(roach[roach_index]) data_channel[roach_index] = { 0: DataChl(roach[roach_index], 'gbe0', 'gpu1', 10000) } # This so far assumes that there is only one ADC in ZDOC 0. if spec.has_key(roach_num): if spec[roach_num].has_key(0): if spec[roach_num][0].has_key(RFnum): spec[roach_num][0][RFnum].sources = [IFsw[index]] IFsw[index].destinations = [spec[roach_num][0][RFnum]] # This set of loops only serves a diagnostic purposee. for roach_index in spec.keys(): for ADC_index in spec[roach_index].keys(): for RF in spec[roach_index][0].keys(): module_logger.debug(" spec[%d][0][%d] signal source is %s", roach_index, RF, str(spec[roach_index][0][RF].sources)) return lab, telescope, FE, FE_chl, DC, IFsw, roach, spec, sample_clk
from MonitorControl import Observatory, Telescope, ClassInstance from MonitorControl.FrontEnds import FrontEnd from MonitorControl.FrontEnds.K_band import K_4ch from MonitorControl.Receivers import Receiver from MonitorControl.Receivers.WBDC import WBDC1 from MonitorControl.BackEnds import Backend from MonitorControl.BackEnds.ROACH1.SAOspec import SAOspec module_logger = logging.getLogger() logging.basicConfig(level=logging.DEBUG) observatory = Observatory("Canberra") telescope = Telescope(observatory, dss=43) front_end = ClassInstance(FrontEnd, K_4ch, "K", inputs = {'B1': telescope.outputs[telescope.name], 'B2': telescope.outputs[telescope.name]}, output_names = [['B1P1','B1P2'], ['B2P1','B2P2']]) receiver = ClassInstance(Receiver, WBDC1, "WBDC-1", inputs = {'B1P1': front_end.outputs["B1P1"], 'B1P2': front_end.outputs["B1P2"], 'B2P1': front_end.outputs["B2P1"], 'B2P2': front_end.outputs["B2P2"]}, output_names = [['D1PAI1', 'D1PAI2'], ['D1PBI1', 'D1PBI2'], ['D2PAI1', 'D2PAI2'], ['D2PBI1', 'D2PBI2']]) back_end = ClassInstance(Backend, SAOspec, "SAO 32K", inputs = {'SAO1': receiver.outputs['D1PAI1'], 'SAO2': receiver.outputs['D1PBI1'], 'SAO3': receiver.outputs['D2PAI1'],
def station_configuration(equipment, roach_loglevel=logging.WARNING, hardware={ "sampling_clock": False, "IF_switch": False, "Backend": False }): """ Describe a DSN Complex Implicit here is the naming convention explained above for DSN front ends and receivers. The telescope output name is expected to be the same as the telescope name. The front end names are constructed from the dict `cfg'. The initialization of 'DSN_fe' depends on this to know the band name. """ print("DTO:", hardware) # Define the site obs = Observatory("GDSCC") tel = {} fe = {} rx = {} # For each station at the site for dss in list(cfg.keys()): # define the telescope tel[dss] = Telescope(obs, dss=dss) # for each band available on the telescope for band in list(cfg[dss].keys()): # S, X, Ka logger.debug("station_configuration: processing band %s", dss) fename = band + str(dss) outnames = [] # for each polarization processed by the receiver for polindex in range(len(list(cfg[dss][band].keys()))): outnames.append(fename + list(cfg[dss][band].keys())[polindex]) fe[fename] = ClassInstance( FrontEnd, DSN_fe, fename, inputs={fename: tel[dss].outputs[tel[dss].name]}, output_names=outnames) rx_inputs = {} rx_outnames = [] for outname in outnames: rx_inputs[outname] = fe[fename].outputs[outname] rx_outnames.append(outname + 'U') rx[fename] = ClassInstance(Receiver, DSN_rx, fename, inputs=rx_inputs, output_names=rx_outnames) equipment['Telescope'] = tel equipment['FrontEnd'] = fe equipment['Receiver'] = rx #This part has to be done by hand to show the physical cabling if hardware['IF_switch']: from Electronics.Instruments.JFW50MS import MS287client IFswitch = ClassInstance(Device, MS287client, "Matrix Switch", inputs=make_switch_inputs(rx), output_names=['IF1', 'IF2', 'IF3', 'IF4']) equipment['IF_switch'] = {"DTO": IFswitch} else: IFswitch = Device("JWF MS 287", inputs=make_switch_inputs(rx), output_names=['IF1', 'IF2', 'IF3', 'IF4']) equipment['IF_switch'] = IFswitch if hardware['sampling_clock']: from Electronics.Instruments import Synthesizer from Electronics.Instruments.Valon import Valon1, Valon2 sample_clk = {} sample_clk[0] = ClassInstance(Synthesizer, Valon1, timeout=10) sample_clk[1] = ClassInstance(Synthesizer, Valon2, timeout=10) logger.debug(" roach1 sample clock is %f", sample_clk[0].get_p("frequency")) logger.debug(" roach2 sample clock is %f", sample_clk[1].get_p("frequency")) equipment['sampling_clock'] = sample_clk else: equipment['sampling_clock'] = None if hardware["Backend"]: from MonitorControl.BackEnds import Backend from MonitorControl.BackEnds.ROACH1 import KurtSpec_client BE = ClassInstance(Backend, KurtSpec_client, "Kurtosis Spectrometer", inputs={ "Ro1In1": IFswitch.outputs['IF1'], "Ro1In2": IFswitch.outputs['IF2'], "Ro2In1": IFswitch.outputs['IF3'], "Ro2In2": IFswitch.outputs['IF4'] }, output_names=[["IF1kurt", "IF1pwr"], ["IF2kurt", "IF2pwr"], ["IF3kurt", "IF3pwr"], ["IF4kurt", "IF4pwr"]]) equipment['Backend'] = BE else: # if there is no backend, make up a dummy equipment['Backend'] = Device("Kurtosis Spectrometer", inputs={ "Ro1In1": IFswitch.outputs['IF1'], "Ro1In2": IFswitch.outputs['IF2'], "Ro2In1": IFswitch.outputs['IF3'], "Ro2In2": IFswitch.outputs['IF4'] }, output_names=[["IF1kurt", "IF1pwr"], ["IF2kurt", "IF2pwr"], ["IF3kurt", "IF3pwr"], ["IF4kurt", "IF4pwr"]]) return obs, equipment
def station_configuration(equipment, roach_loglevel=logging.WARNING, hardware=None): """ Describe a DSN Complex Implicit here is the naming convention explained above for DSN front ends and receivers. The telescope output name is expected to be the same as the telescope name. The front end names are constructed from the dict `cfg'. The initialization of 'DSN_fe' depends on this to know the band name. @param equipment : equipment in addition to what is defined here @type equipment : dict of Device subclass objects @param roachlist : ROACHs to be used with this configuration; default: all @type roachlist : list of str @param roach_loglevel : log level for the ROACH loggers @type roach_loglevel : str @param hardware : hardware which is available or to be tested @type hardware : dict of boolean """ if hardware is None: hardware = { "Antenna": False, "FrontEnd": True, # currently we have no control over the front ends "Receiver": True, # currently we have no control over the receivers "IF_switch": { "DTO": True }, # allow multiple switches "Synthesizer": False, "Backend": False } if equipment is None: equipment = {} # Define the site obs = Observatory("GDSCC") tel = {} fe = {} rx = {} # For each station at the site, get a Telescope object, FrontEnd objects, # Receiver objects, Switch objects for dss in cfg.keys(): # 14,...,26 logger.debug("station_configuration: processing DSS-%d", dss) # define the telescope tel[dss] = Telescope(obs, dss=dss, active=hardware["Antenna"]) # for each band available on the telescope for band in cfg[dss].keys(): # S, X, Ka logger.debug("station_configuration: processing band %s", dss) fename = band + str(dss) outnames = [] # for each polarization processed by the receiver for pol in cfg[dss][band].keys(): # L, R logger.debug("station_configuration: processing pol %s", pol) outnames.append(fename + pol) # cfg[dss][band][pol]) logger.debug("station_configuration: FE output names: %s", outnames) fe[fename] = ClassInstance( FrontEnd, DSN_fe, fename, inputs={fename: tel[dss].outputs[tel[dss].name]}, output_names=outnames) rx_inputs = {} rx_outnames = [] for outname in outnames: rx_inputs[outname] = fe[fename].outputs[outname] rx_outnames.append(outname + 'U') # all DSN IFs are USB rx[fename] = ClassInstance(Receiver, DSN_rx, fename, inputs=rx_inputs, output_names=rx_outnames) equipment['Telescope'] = tel equipment['FrontEnd'] = fe equipment['Receiver'] = rx #This part has to be done by hand to show the physical cabling #print make_switch_inputs(rx) try: IFswitch = ClassInstance(Device, MS287client, "Matrix Switch", inputs=make_switch_inputs(rx), output_names=['IF1', 'IF2', 'IF3', 'IF4']) equipment['IF_switch'] = {"DTO": IFswitch} except Pyro.errors.NamingError, details: logger.error("Is the MS287 IF switch server running?") raise Pyro.errors.NamingError("Is the MS287 IF switch server running?")
equipment['FrontEnd'] = fe equipment['Receiver'] = rx #This part has to be done by hand to show the physical cabling #print make_switch_inputs(rx) try: IFswitch = ClassInstance(Device, MS287client, "Matrix Switch", inputs=make_switch_inputs(rx), output_names=['IF1', 'IF2', 'IF3', 'IF4']) equipment['IF_switch'] = {"DTO": IFswitch} except Pyro.errors.NamingError, details: logger.error("Is the MS287 IF switch server running?") raise Pyro.errors.NamingError("Is the MS287 IF switch server running?") sample_clk = {} sample_clk[0] = ClassInstance(Synthesizer, Valon1, timeout=10) sample_clk[1] = ClassInstance(Synthesizer, Valon2, timeout=10) logger.debug(" roach1 sample clock is %f", sample_clk[0].get_p("frequency")) logger.debug(" roach2 sample clock is %f", sample_clk[1].get_p("frequency")) equipment['Synthesizer'] = sample_clk BE = ClassInstance(Backend, SAOspec, "32K Spectrometer", inputs={ "Ro1In1": IFswitch.outputs['IF1'], "Ro2In1": IFswitch.outputs['IF3'] }, output_names=[["IF1pwr"], ["IF2pwr"]]) equipment['Backend'] = BE
def station_configuration(equipment, roach_loglevel=logging.WARNING): """ DSS-13 configuration This requires classes Ellipsoid, DSNfe, DSNrx, DSNrxXKa, IFmatrixSwitch, WVSR DSS-13 is awkward because there are really two IF switches, one in the pedestal which selects 4 from many and another one in the control room which select many from four. """ site = Observatory("Venus") tel = Telescope(site, dss=13) equipment['Telescope'] = tel equipment['FE_selector'] = ClassInstance( Switch, Ellipsoid, "ellipsoid", inputs={'antenna': tel.outputs[tel.name]}, output_names=['pos1', 'pos2', 'pos3', 'pos4', 'pos5', 'pos6']) # The following information comes from document 1 (see Documentation). # Generally, the implicit band and polarization specification (i.e. in the # name) since most receivers are named conveniently. FEs = { 'X-X/Ka': ClassInstance(FrontEnd, DSNfe, 'X-X/Ka', inputs={'X': equipment['FE_selector'].outputs['pos1']}, output_names=['XR', 'XL']), 'Ka-X/Ka': ClassInstance(FrontEnd, DSNfe, 'Ka-X/Ka', inputs={'Ka': equipment['FE_selector'].outputs['pos1']}, output_names=['KaR', 'KaL']), 'S-S/X': ClassInstance(FrontEnd, DSNfe, 'S-S/X', inputs={'S': equipment['FE_selector'].outputs['pos2']}, output_names=['SR']), 'X-S/X': ClassInstance(FrontEnd, DSNfe, 'X-S/X', inputs={'X': equipment['FE_selector'].outputs['pos2']}, output_names=['XR']), 'XXKa': ClassInstance(FrontEnd, XXKa_fe, 'XXKa', inputs={ 'X': equipment['FE_selector'].outputs['pos3'], 'Ka': equipment['FE_selector'].outputs['pos3'] }, output_names=['XR', 'XL', 'KaR', 'KaL']), 'Xwide': ClassInstance(FrontEnd, DSNfe, 'Xwide', inputs={'X': equipment['FE_selector'].outputs['pos4']}, output_names=['XR', 'XL']), 'K': ClassInstance(FrontEnd, DSN_K, 'K', inputs={'K': equipment['FE_selector'].outputs['pos5']}, output_names=['out']) } equipment['FrontEnd'] = FEs # No RF switch(es) receivers = { 'S-S/X': ClassInstance(Receiver, DSNrx, 'S-S/X', inputs={'SR': FEs['S-S/X'].outputs['SR']}, output_names=['SRU']), 'X-S/X': ClassInstance(Receiver, DSNrx, 'X-S/X', inputs={'XR': FEs['X-S/X'].outputs['XR']}, output_names=['XRU']), 'X-X/Ka': ClassInstance(Receiver, DSNrx, 'X-X/Ka', inputs={ 'XR': FEs['X-X/Ka'].outputs['XR'], 'XL': FEs['X-X/Ka'].outputs['XL'] }, output_names=['XLU', 'XRU']), 'Ka-X/Ka': ClassInstance(Receiver, DSNrx, 'Ka-X/Ka', inputs={ 'KaL': FEs['Ka-X/Ka'].outputs['KaL'], 'KaR': FEs['Ka-X/Ka'].outputs['KaR'] }, output_names=['KaLU', 'KaRU']), 'XXKa': ClassInstance(Receiver, DSNrx, 'XXKa', inputs={ 'XR': FEs['XXKa'].outputs['XR'], 'XL': FEs['XXKa'].outputs['XL'], 'KaR': FEs['XXKa'].outputs['KaR'], 'KaL': FEs['XXKa'].outputs['KaL'] }, output_names=['XRU', 'XLU', 'KaRU', 'KaLU']), 'GSSR': ClassInstance(Receiver, GSSRdc, 'GSSR', inputs={ 'XL': FEs['Xwide'].outputs['XL'], 'XR': FEs['Xwide'].outputs['XR'] }, output_names=['XLU', 'XRU']), 'K': ClassInstance(Receiver, Kdc, 'K', inputs={'in': FEs['K'].outputs['out']}, output_names=['U']), 'MMS-1': ClassInstance(Receiver, MMS, 'MMS-1', inputs=None, output_names=['U']) } equipment['Receiver'] = receivers IFsw1 = ClassInstance(Device, HP_IFSwitch, 'Pedestal IF Switch', inputs={ 100: None, 101: receivers['XXKa'].outputs['XRU'], 102: receivers['X-X/Ka'].outputs['XLU'], 103: receivers['GSSR'].outputs['XRU'], 104: receivers['X-X/Ka'].outputs['XRU'], 105: receivers['X-S/X'].outputs['XRU'], 106: None, 107: receivers['GSSR'].outputs['XLU'], 108: receivers['Ka-X/Ka'].outputs['KaLU'], 109: receivers['XXKa'].outputs['XLU'], 110: None, 111: receivers['MMS-1'].outputs['U'], 112: receivers['Ka-X/Ka'].outputs['KaRU'], 113: receivers['S-S/X'].outputs['SRU'], 114: receivers['K'].outputs['U'], 115: None }, output_names=['IF0', 'IF1', 'IF2', 'IF3']) IFsw2 = ClassInstance(Device, IFMatrixSwitch, 'Station IF Switch', inputs={ 'IF0': IFsw1.outputs['IF0'], 'IF1': IFsw1.outputs['IF1'], 'IF2': IFsw1.outputs['IF2'], 'IF3': IFsw1.outputs['IF3'] }, output_names=make_IFMS_outputs()) equipment['IF_switch'] = {'pedestal': IFsw1, 'control room': IFsw2} backends = { 'WVSR': ClassInstance(Backend, WVSR, 'VenusWVSR', inputs={'WVSR1': IFsw2.outputs['out16']}) } equipment['Backend'] = backends # No sampling clock (for now) return site, equipment
def station_configuration(equipment=None, roach_loglevel=logging.WARNING, hardware=None): """ Configuration for the K-band system on DSS-43 using WBDC2 Feed 1 (F1) is at 024-0.016, F2 at 024+0.016. The polarizations are linear, E and H. There are so many receiver outputs that it is simpler to let the software generate them. """ if hardware is None: hardware = { "Antenna": False, "FrontEnd": False, "Receiver": False, "Backend": False } logger.debug("WBDC2_K2 station_configuration: hardware is %s", hardware) if equipment is None: equipment = {} logger.debug("WBDC2_K2 station_configuration: equipment is %s", equipment) observatory = Observatory("Canberra") # equipment['Telescope'] = Telescope(observatory, dss=43) # antenna = equipment['Telescope'] # equipment['Antenna'] = DSN_Antenna(observatory, dss=43, # hardware=hardware["Antenna"]) # Alternatively, I think we could do the following: equipment['Antenna'] = ClassInstance(Telescope, DSN_Antenna, observatory, dss=43, hardware=hardware["Antenna"]) antenna = equipment['Antenna'] equipment['FrontEnd'] = ClassInstance(FrontEnd, K_4ch, "K", hardware=hardware["FrontEnd"], inputs={ 'F1': antenna.outputs[antenna.name], 'F2': antenna.outputs[antenna.name] }, output_names=[['F1E', 'F1H'], ['F2E', 'F2H']]) front_end = equipment['FrontEnd'] equipment['Receiver'] = ClassInstance(Receiver, WBDC2, "WBDC-2", hardware=hardware["Receiver"], inputs={ 'F1P1': front_end.outputs["F1E"], 'F1P2': front_end.outputs["F1H"], 'F2P1': front_end.outputs["F2E"], 'F2P2': front_end.outputs["F2H"] }) equipment['IF_switch'] = IFswitch("Patch Panel", equipment) patch_panel = equipment['IF_switch'] equipment['Backend'] = ClassInstance(Backend, SAOclient, "SAO spectrometer", hardware=hardware["Backend"], inputs={ 'SAO1': patch_panel.outputs['SAO1'], 'SAO2': patch_panel.outputs['SAO2'], 'SAO3': patch_panel.outputs['SAO3'], 'SAO4': patch_panel.outputs['SAO4'] }) equipment['sampling_clock'] = None return observatory, equipment
def standard_equipment(dss, band, equipment={}): """ Describe a DSN Complex up to the IF switch Implicit here is the naming convention explained above for DSN front ends and receivers. The telescope output name is expected to be the same as the telescope name. The front end names are constructed from the dict `cfg'. The initialization of 'DSN_fe' depends on this to know the band name. An example of the convention:: inputs Device outputs X14 FrontEnd X14R, X14L X14R, X14L Receiver X14RU, X14LU """ complex_name = DSN_complex_of(dss) if complex_name == "Canberra": from MonitorControl.Configurations.CDSCC import cfg elif complex_name == "Goldstone": from MonitorControl.Configurations.GDSCC import cfg elif complex_name == "Madrid": from MonitorControl.Configurations.MDSCC import cfg else: raise RuntimeError("invalid Complex name: " + complex_name) logger.debug("standard_equipment: DSS-%2d is at %s", dss, complex_name) logger.debug("standard_equipment: cfg = %s", cfg) # Define the site obs = Observatory(complex_name) tel = {} fe = {} rx = {} # define the telescope #tel[dss] = Telescope(obs, dss=dss) tel = Telescope(obs, dss=dss) # for each band available on the telescope fename = band + str(dss) logger.debug("standard_equipment: getting %s details", fename) outnames = [] # for each polarization processed by the receiver for polindex in range(len(cfg[dss][band])): # for each band outnames.append(fename + list(cfg[dss][band].keys())[polindex]) #fe[fename] = ClassInstance(FrontEnd, fe = ClassInstance( FrontEnd, DSN_fe, fename, inputs={ fename: #tel[dss].outputs[tel[dss].name]}, tel.outputs[tel.name] }, output_names=outnames) rx_inputs = {} rx_outnames = [] # this connects the receiver to the front end for outname in outnames: #rx_inputs[outname] = fe[fename].outputs[outname] rx_inputs[outname] = fe.outputs[outname] rx_outnames.append(outname + 'U') #rx[fename] = ClassInstance(Receiver, rx = ClassInstance(Receiver, DSN_rx, fename, inputs=rx_inputs, output_names=rx_outnames) equipment['Telescope'] = tel equipment['FrontEnd'] = fe equipment['Receiver'] = rx return equipment