def main(options, args):

    import remoteObjects as ro
    logger = ro.nullLogger()

    dummyDatafileLock = None

    svConfig = StatusVarConfig(options.configfile, dummyDatafileLock, logger)
    gen2AliasDict = svConfig.getGen2AliasDict()
    print '\nconfigFromFile is ', svConfig.configFromFile
    print '\ngen2AliasDict is ', gen2AliasDict
    print '\nconfigGen2 is ', svConfig.configGen2
    print '\nconfigID is ', svConfig.configID
    def __init__(self, logger = ro.nullLogger()):
        super(PACmd, self).__init__(logger)

        self.errorThreshold = 0.1 # degree
        self.delaySecondsPerDegree = 0.6667 # seconds/degree
        self.paCmdStartTime = None
        self.paDelayIntervalMin = 6.0 # seconds
        self.paDelayInterval = None

        self.svConfig = None
        self.domeShutter = None
        self.mirrorCover = None
        self.telState = None
        self.focalStation = None
def jplObjectDBSearch(targetName=None, targetID=None, logger=ro.nullLogger()):
    """
    Search the JPL Object Database for the specified target.

    Args:
        targetName: The target name to search for in the JPL Object Database
        targetID:   The unique identifier that identifies the target (JPL SBDB identifier)

        You can supply either targetName or targetID. Both are keyword
        arguments. If you supply targetName and targetID, targetID
        will be ignored.

    Returns:
        targetID

        If targetName was supplied and it resulted in a unique match
        in the database, then targetID is returned as the unique
        identifier for the target in the JPL Horizons system. If
        targetName resulted in multiple matches in the database, then
        targetID is returned as a list of the matching objects. Eath
        item in the list is a dict with the following keys:

        ID => identifier of the object in the JPL Small Body Database Browser (SBDB)
        name => name of the object

        Note that the above ID is the identifier of the object in the
        SBDB, not in JPL Horizons. You can supply the ID value to
        jplObjectDBSearch as the targetID and the return value will be
        the identifier of the object in the JPL Horizons system.
    
    Raises:
        MissingInputError
    """

    if targetName:
        jplHorizonsMB = searchJplHorizonsMB(targetName)
        if jplHorizonsMB:
            targetID = jplHorizonsMB
        else:
            jplSmallBodyDBOutput = jplSmallBodyDBQuery(jplSmallBodyDBurl, sstr=targetName)
            targetID = parseJPLSmallBodyDBOutput(jplSmallBodyDBOutput)
    elif targetID:
        jplSmallBodyDBOutput = jplSmallBodyDBQuery(jplSmallBodyDBurl, ID=targetID)
        targetID = parseJPLSmallBodyDBOutput(jplSmallBodyDBOutput)
    else:
        raise MissingInputError('You must supply either a target name or a target ID')
    logger.info('DB search result %s' % targetID)
    return targetID
    def __init__(self, logger=ro.nullLogger()):
        self.logger = logger
        self.statusVar = {
            'EL': {
                'ID': 'Melco_00A11C0',
                'value': None
            },
            'LimitFlag': {
                'ID': 'Melco_00A13D6',
                'value': None
            },
            'TelDrive': {
                'ID': 'TelDrive',
                'value': None
            }
        }

        # This is the "inactive elevation angle threshold". If the
        # telescope elevation angle is greater than the threshold,
        # then the telescope is considered to be "stowed", i.e.,
        # inactive.
        self.inactiveElevationThreshold = 89.5

        # These are the bit-masks for looking at the TSCL.LIMIT_FLAG
        # value and determining which of the angle limit calculations
        # are valid.
        self.limitFlagElLowMask = 0x01
        self.limitFlagElHighMask = 0x02
        self.limitFlagAzMask = 0x04
        self.limitFlagRotMask = 0x08
        self.limitFlagBigRotMask = 0x10

        # These are the strings that identify the telescope drive as
        # being in slewing or pointing or guiding.
        self.slewing = 'slewing'
        self.pointing = 'pointing'
        self.guiding = 'guiding'

        # These are the different guiding and drive modes that the
        # STATL.TELDRIVE status alias can have.
        self.telDriveModes = {
            'Guiding': ('Guiding(AG1)', 'Guiding(AG2)', 'Guiding(SV1)',
                        'Guiding(SV2)', 'Guiding(AGPIR)', 'Guiding(AGFMOS)'),
            'Slewing': ('Slewing'),
            'Tracking': ('Tracking', 'Tracking(Non-Sidereal)'),
            'Pointing': ('Pointing')
        }
    def __init__(self, logger=ro.nullLogger()):
        super(Windspeed, self).__init__(logger)

        # These status variables are defined in the alarm
        # configuration file.
        self.statusVar = {
            'topRingRear': {
                'ID': 'Melco_002C174',
                'value': common.STATNONE
            },
            'topRingFront': {
                'ID': 'Melco_002C180',
                'value': common.STATNONE
            },
            'csctFrontX': {
                'ID': 'Melco_002C1A4',
                'value': common.STATNONE
            },
            'csctFrontY': {
                'ID': 'Melco_002C1B0',
                'value': common.STATNONE
            },
            'csctFrontZ': {
                'ID': 'Melco_002C1BC',
                'value': common.STATNONE
            },
            'csctRearX': {
                'ID': 'Melco_002C1C8',
                'value': common.STATNONE
            },
            'csctRearY': {
                'ID': 'Melco_002C1D4',
                'value': common.STATNONE
            },
            'csctRearZ': {
                'ID': 'Melco_002C1E0',
                'value': common.STATNONE
            },
        }

        self.compositeAlarms = ('HighWindspeedTopRing', 'HighWindspeedCSCT')

        # We will store a TelState object here. We need this because
        # TelState tells us if we are pointing or slewing.
        self.telState = None
    def __init__(self, logger = ro.nullLogger()):
        super(AngleLimitTime, self).__init__(logger)

        self.statusVar = {
            'limitTimeAz':     {'ID': 'Melco_00A13D3', 'value': None},
            'limitTimeElLow':  {'ID': 'Melco_00A13D1', 'value': None},
            'limitTimeElHigh': {'ID': 'Melco_00A13D2', 'value': None},
            'limitTimeRot':    {'ID': 'Melco_00A13D4', 'value': None}
            }
        self.compositeAlarms = ('TimeLimitAz', 'TimeLimitELLow', 'TimeLimitELUp', 'TimeLimitInRImRProbe')

        # We will store DomeShutter, MirrorCover, TelState, and
        # FocalStation objects here. We need these because we want to
        # mute the alarms when the dome is closed and telescope is
        # "inactive".
        self.domeShutter = None
        self.mirrorCover = None
        self.telState = None
Example #7
0
    def __init__(self,
                 name,
                 start_cmd,
                 stop_cmd=None,
                 logger=None,
                 stdout=None,
                 stderr=None,
                 autorestart=False,
                 restart_threshold=10,
                 restart_interval=1.0):
        self.name = name
        self.start_cmd = start_cmd
        self.stop_cmd = stop_cmd
        self.proc = None
        self.timestart = time.time()
        self.timecheck = self.timestart
        self.startcount = 0
        self.stopcount = 0
        self.autorestart = autorestart
        self.restart_threshold = restart_threshold
        self.restart_interval_init = restart_interval
        self.restart_interval = restart_interval
        self.lock = threading.RLock()
        # Seconds to wait after sending SIGTERM before trying SIGKILL
        self.killwait = 2.0

        # If no logger is passed in, create a simple one to stderr
        if not logger:
            self.logger = ro.nullLogger()
        else:
            self.logger = logger

        # Stdout/stderr messages
        if stdout:
            self.stdout = stdout
        else:
            #self.stdout = open("/dev/null", "w")
            self.stdout = sys.stdout
        if stderr:
            self.stderr = stderr
        else:
            #self.stderr = open("/dev/null", "w")
            self.stderr = sys.stderr
def writeTSCTrackFile(filename, trackInfo, logger=None):
    """
    Write time-history suitable for Subaru TSC.

    Args:
        filename:  output filename
        trackInfo: tracking coordinate info (as a python dict)
                   containing the following information:
                   - target description (in the 'description' key)
                   - RA proper motion (arcsec/yr) (in the 'pm_ra' key)
                   - Dec proper motion (arcsec/yr) (in the 'pm_dec' key)
                   - annual parallax (arcsec) (in the 'parallax' key)
                   - time scale (UTC or TDT) (in the 'timescale' key)
                   - coordinate description (in the 'coord_descr' key)
                   - equinox (in the 'equinox' key)
                   - time history of tracking coordinates and
                     target distance (in the 'timeHistory' key)
        logger:     An ssdlog object

        The time history is an array of tuples with each tuple containing:
          - UTC date/time (python datetime object)
          - RA (degrees)
          - Dec (degrees)
          - target distance (AU)

    Returns:
        Nothing

    Raises:
        Nothing
    """
    if logger == None:
        logger = ro.nullLogger()
    # Write header and time-history suitable for Subaru TSC to
    # specified file
    with open(filename, 'w') as outfile:
        writeTSCTrackOutput(outfile, trackInfo, logger)
    logger.info('Output written to %s' % filename)
    def __init__(self, logger=ro.nullLogger()):
        super(AG_PosnError, self).__init__(logger)

        # These status variables are defined in the alarm
        # configuration file. Each one of these status variables is
        # related to a single Gen2 status alias derived from data
        # supplied to Gen2 via the TSC status packets.
        self.statusVar = {
            'AG_Error': {
                'ID': 'AG_PosnError',
                'value': None
            },
            'SV_Error': {
                'ID': 'SV_PosnError',
                'value': None
            }
        }

        # We will store a TelState object here. We need a TelState
        # object because it tells us if the telescope is guiding and,
        # if so, whether it is guiding via the regular autoguider or
        # via the slit-viewer.
        self.telState = None
Example #10
0
def jplHorizonsGetEphem(start,
                        end,
                        incr,
                        targetName=None,
                        targetID=None,
                        logger=ro.nullLogger()):
    """
    Get ephemeris data from JPL Horizons

    Args:
        start: start time of ephemeris data
        end:        end time of ephemeris data
        incr:       time increment for ephemeris (minutes)
        targetName: The target name to search for in the JPL Object Database
        targetID:   The unique identifier that identifies the target
                    (this can be obtained from jplObjectDBSearch)
        logger:     An ssdlog object

        You can supply either targetName or targetID. Both are keyword
        arguments. If you supply targetName and there are multiple
        targets with that name in the JPL Object Database, you will
        get a MultipleTargetMatchError. targetID is ignored if you
        supply targetName.

        Note that the start and end times can be supplied in many
        different ways:
           - Python datetime object
           - Julian Date
           - Modified Julian date
           - YYYYMMDD.DDDD
           - YYYYMMDD HH:MM:SS (You can leave off the HH:MM:SS or some subset of that)
           - YYYY-MM-DD HH:MM:SS (You can leave off the HH:MM:SS or some subset of that)
           - YYYY/MM/DD HH:MM:SS (You can leave off the HH:MM:SS or some subset of that)
           - YYYY-MMM-DD HH:MM
    
    Returns:
        A string containing the output from JPL Horizons

    Raises:
        MultipleTargetMatchError
    """
    if targetName:
        logger.info('targetName is %s' % targetName)
        # Search for the target name in the JPL Object Database
        targetID = jplObjectDBSearch.jplObjectDBSearch(targetName,
                                                       logger=logger)
    logger.info('targetID is %s' % targetID)
    # If a unique match was found for the targetName or the targetID
    # was supplied as a string, then query JPL Horizons to get the
    # ephemeris data. Otherwise, raise an exception.
    if type(targetID) is str:
        jplHorizonsSettings = setJPLHorizonsParms(targetID, start, end, incr,
                                                  jplHorizonsDefaultSettings)
        jplHorizonsOutput = jplHorizonsQuery(jplHorizonsURL,
                                             jplHorizonsSettings)

        return jplHorizonsOutput
    elif type(targetID) is list:
        raise MultipleTargetMatchError(
            'Multiple objects match supplied target %s: %s' %
            (targetName, targetID))
    else:
        raise Exception('Unexpected error occurred. Check input parameters')
Example #11
0
 def __init__(self, logger=ro.nullLogger()):
     self.logger = logger
     self.statusVar = {}
     self.compositeAlarms = {}
     self.svConfig = None
    def __init__(self, logger=ro.nullLogger()):
        super(TipTilt, self).__init__(logger)

        # These status variables are defined in the alarm
        # configuration file. Each one of these status variables is
        # related to a single MELCO value supplied to Gen2 via the TSC
        # status packets.
        self.statusVar = {
            'tipTiltChopping': {
                'ID': 'Melco_002800B',
                'value': None
            },
            'tipTiltTipTilt': {
                'ID': 'Melco_002800C',
                'value': None
            },
            'tipTiltPosition': {
                'ID': 'Melco_0028029',
                'value': None
            },
            'tipTiltMaint': {
                'ID': 'Melco_002800D',
                'value': None
            },
            'tipTiltDriveOn': {
                'ID': 'Melco_0028007',
                'value': None
            },
            'tipTiltDriveOff': {
                'ID': 'Melco_0028008',
                'value': None
            },
            'tipTiltDriveOnRdy': {
                'ID': 'Melco_002802A',
                'value': None
            },
            'choppingStart': {
                'ID': 'Melco_0028066',
                'value': None
            },
            'choppingStop': {
                'ID': 'Melco_0028067',
                'value': None
            },
            'tipTiltChoppingStartRdy': {
                'ID': 'Melco_0028026',
                'value': None
            },
            'tipTiltDataAvailable': {
                'ID': 'Melco_0028045',
                'value': None
            }
        }

        # We need these attributes to determine if the tip-tilt state
        # has changed from the previous time.
        self.previousTipTiltAndDriveState = None
        self.currentTipTiltAndDriveState = None
        self.savedAlarmState = None

        # We will store a FocalStation object here. We need this
        # because the alarm depends on knowing if the M2 value is
        # "IR".
        self.focalStation = None
 def __init__(self, logger=ro.nullLogger()):
     self.logger = logger
     self.statusVar = {
         'PM/M3 Cover Open OPN': {
             'ID': 'Melco_0024005',
             'value': None
         },
         'PM/M3 Cover Close OPN': {
             'ID': 'Melco_0024006',
             'value': None
         },
         'PM/M3 Cover Stop': {
             'ID': 'Melco_0024057',
             'value': None
         },
         'PM Cover Upper U-1A Open': {
             'ID': 'Melco_0024007',
             'value': None
         },
         'PM Cover Upper U-1A Close': {
             'ID': 'Melco_0024009',
             'value': None
         },
         'PM Cover Upper U-1B Open': {
             'ID': 'Melco_002400B',
             'value': None
         },
         'PM Cover Upper U-1B Close': {
             'ID': 'Melco_002400D',
             'value': None
         },
         'PM Cover Upper U-2A Open': {
             'ID': 'Melco_002400F',
             'value': None
         },
         'PM Cover Upper U-2A Close': {
             'ID': 'Melco_0024011',
             'value': None
         },
         'PM Cover Upper U-2B Open': {
             'ID': 'Melco_0024013',
             'value': None
         },
         'PM Cover Upper U-2B Close': {
             'ID': 'Melco_0024015',
             'value': None
         },
         'PM Cover Upper U-3A Open': {
             'ID': 'Melco_0024017',
             'value': None
         },
         'PM Cover Upper U-3A Close': {
             'ID': 'Melco_0024019',
             'value': None
         },
         'PM Cover Upper U-3B Open': {
             'ID': 'Melco_002401B',
             'value': None
         },
         'PM Cover Upper U-3B Close': {
             'ID': 'Melco_002401D',
             'value': None
         },
         'PM Cover Upper U-3C Open': {
             'ID': 'Melco_002401F',
             'value': None
         },
         'PM Cover Upper U-3C Close': {
             'ID': 'Melco_0024021',
             'value': None
         },
         'PM Cover Upper U-3D Open': {
             'ID': 'Melco_0024023',
             'value': None
         },
         'PM Cover Upper U-3D Close': {
             'ID': 'Melco_0024025',
             'value': None
         },
         'PM Cover Lower L-A Open': {
             'ID': 'Melco_0024027',
             'value': None
         },
         'PM Cover Lower L-A Close': {
             'ID': 'Melco_0024029',
             'value': None
         },
         'PM Cover Lower L-B Open': {
             'ID': 'Melco_002402B',
             'value': None
         },
         'PM Cover Lower L-B Close': {
             'ID': 'Melco_002402D',
             'value': None
         },
         'PM Cover Lower L-C Open': {
             'ID': 'Melco_002402F',
             'value': None
         },
         'PM Cover Lower L-C Close': {
             'ID': 'Melco_0024031',
             'value': None
         },
         'PM Cover Lower L-D Open': {
             'ID': 'Melco_0024033',
             'value': None
         },
         'PM Cover Lower L-D Close': {
             'ID': 'Melco_0024035',
             'value': None
         },
         'PM Cover Door U-1A-I Open': {
             'ID': 'Melco_0024037',
             'value': None
         },
         'PM Cover Door U-1A-I Close': {
             'ID': 'Melco_0024039',
             'value': None
         },
         'PM Cover Door U-1B-I Open': {
             'ID': 'Melco_002403B',
             'value': None
         },
         'PM Cover Door U-1B-I Close': {
             'ID': 'Melco_002403D',
             'value': None
         },
         'PM Cover Door U-2A-I-A Open': {
             'ID': 'Melco_002403F',
             'value': None
         },
         'PM Cover Door U-2A-I-A Close': {
             'ID': 'Melco_0024041',
             'value': None
         },
         'PM Cover Door U-2A-I-B Open': {
             'ID': 'Melco_0024043',
             'value': None
         },
         'PM Cover Door U-2A-I-B Close': {
             'ID': 'Melco_0024045',
             'value': None
         },
         'PM Cover Door U-2B-I-A Open': {
             'ID': 'Melco_0024047',
             'value': None
         },
         'PM Cover Door U-2B-I-A Close': {
             'ID': 'Melco_0024049',
             'value': None
         },
         'PM Cover Door U-2B-I-B Open': {
             'ID': 'Melco_002404B',
             'value': None
         },
         'PM Cover Door U-2B-I-B Close': {
             'ID': 'Melco_002404D',
             'value': None
         },
         'PM Cover Door U-3A-I Open': {
             'ID': 'Melco_002404F',
             'value': None
         },
         'PM Cover Door U-3A-I Close': {
             'ID': 'Melco_0024051',
             'value': None
         },
         'PM Cover Door U-3B-I Open': {
             'ID': 'Melco_0024053',
             'value': None
         },
         'PM Cover Door U-3B-I Close': {
             'ID': 'Melco_0024055',
             'value': None
         },
         'PM Cover Door U-3C-I Open': {
             'ID': 'Melco_00240EB',
             'value': None
         },
         'PM Cover Door U-3C-I Close': {
             'ID': 'Melco_00240ED',
             'value': None
         },
         'PM Cover Door U-3D-I Open': {
             'ID': 'Melco_00240EF',
             'value': None
         },
         'PM Cover Door U-3D-I Close': {
             'ID': 'Melco_00240F1',
             'value': None
         },
     }
Example #14
0
 def __init__(self, logger=ro.nullLogger()):
     self.logger = logger
     self.statusVar1 = {
         'FocalStation': {
             'ID': 'FocStation',
             'value': None
         },
         'FocusInfo': {
             'ID': 'FocusInfo',
             'value': None
         }
     }
     self.statusVar2 = {
         'POpt Selected': {
             'ID': 'Melco_00A13E4',
             'value': None,
             'M2': 'PF_OPT',
             'Rotator': 'INSR',
             'ADC': 'IN'
         },
         'PIR Selected': {
             'ID': 'Melco_00A13E5',
             'value': None,
             'M2': 'PF_IR',
             'Rotator': 'INSR',
             'ADC': 'OUT'
         },
         'Cs(CsOpt) Selected': {
             'ID': 'Melco_00A13E6',
             'value': None,
             'M2': 'CS_OPT',
             'Rotator': 'INSR',
             'ADC': 'OUT'
         },
         'Cs(CsOpt)+ADC Selected': {
             'ID': 'Melco_00A13E7',
             'value': None,
             'M2': 'CS_OPT',
             'Rotator': 'INSR',
             'ADC': 'IN'
         },
         'NsOpt(CsOPt) Selected': {
             'ID': 'Melco_00A13E8',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsOpt(CsOpt)+ADC Selected': {
             'ID': 'Melco_00A13E9',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'OUT',
             'ADC': 'IN'
         },
         'NsOpt(CsOpt)+ImR(B) Selected': {
             'ID': 'Melco_00A13EA',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'IMRB',
             'ADC': 'OUT'
         },
         'NsOpt(CsOpt)+ImR(B)+ADC Selected': {
             'ID': 'Melco_00A13EB',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'IMRB',
             'ADC': 'IN'
         },
         'NsOpt(CsOpt)+ImR(R) Selected': {
             'ID': 'Melco_00A13EC',
             'value': None,
             'M2': 'CS_OPT',
             'Rotator': 'IMRR',
             'ADC': 'OUT'
         },
         'NsOpt(CsOpt)+ImR(R)+ADC Selected': {
             'ID': 'Melco_00A13ED',
             'value': None,
             'M2': 'CS_OPT',
             'Rotator': 'IMRR',
             'ADC': 'IN'
         },
         'NsIR(CsOpt) Selected': {
             'ID': 'Melco_00A13EE',
             'value': None,
             'M2': 'CS_OPT',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsIR(CsOpt)+ImR Selected': {
             'ID': 'Melco_00A13EF',
             'value': None,
             'M2': 'CS_OPT',
             'Rotator': 'IMR',
             'ADC': 'OUT'
         },
         'NsOpt(NsOpt) Selected': {
             'ID': 'Melco_00A13F0',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsOpt(NsOpt)+ADC Selected': {
             'ID': 'Melco_00A13F1',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'OUT',
             'ADC': 'IN'
         },
         'NsOpt(NsOpt)+ImR(B) Selected': {
             'ID': 'Melco_00A13F2',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'IMRB',
             'ADC': 'OUT'
         },
         'NsOpt(NsOpt)+ImR(B)+ADC Selected': {
             'ID': 'Melco_00A13F3',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'IMRB',
             'ADC': 'IN'
         },
         'NsOpt(NsOpt)+ImR(R) Selected': {
             'ID': 'Melco_00A13F4',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'IMRR',
             'ADC': 'OUT'
         },
         'NsOpt(NsOpt)+ImR(R)+ADC Selected': {
             'ID': 'Melco_00A13F5',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'IMRR',
             'ADC': 'IN'
         },
         'NsIR(NsOpt) Selected': {
             'ID': 'Melco_00A13F6',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsIR(NsOpt)+ImR Selected': {
             'ID': 'Melco_00A13F7',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'IMR',
             'ADC': 'OUT'
         },
         'Cs(IR) Selected': {
             'ID': 'Melco_00A13F8',
             'value': None,
             'M2': 'IR',
             'Rotator': 'INSR',
             'ADC': 'OUT'
         },
         'NsOpt(IR) Selected': {
             'ID': 'Melco_00A13F9',
             'value': None,
             'M2': 'IR',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsOpt(IR)+ADC Selected': {
             'ID': 'Melco_00A13FA',
             'value': None,
             'M2': 'IR',
             'Rotator': 'OUT',
             'ADC': 'IN'
         },
         'NsOpt(IR)+ImR(B) Selected': {
             'ID': 'Melco_00A13FB',
             'value': None,
             'M2': 'IR',
             'Rotator': 'IMRB',
             'ADC': 'OUT'
         },
         'NsOpt(IR)+ImR(B)+ADC Selected': {
             'ID': 'Melco_00A13FC',
             'value': None,
             'M2': 'IR',
             'Rotator': 'IMRB',
             'ADC': 'IN'
         },
         'NsOpt(IR)+ImR(R) Selected': {
             'ID': 'Melco_00A13FD',
             'value': None,
             'M2': 'IR',
             'Rotator': 'IMRR',
             'ADC': 'OUT'
         },
         'NsOpt(IR)+ImR(R)+ADC Selected': {
             'ID': 'Melco_00A13FE',
             'value': None,
             'M2': 'IR',
             'Rotator': 'IMRR',
             'ADC': 'IN'
         },
         'NsIR(IR) Selected': {
             'ID': 'Melco_00A13FF',
             'value': None,
             'M2': 'IR',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsIR(IR)+ImR Selected': {
             'ID': 'Melco_00A1400',
             'value': None,
             'M2': 'IR',
             'Rotator': 'IMR',
             'ADC': 'OUT'
         },
         'NsIR(IR)+AO Selected': {
             'ID': 'Melco_00A1407',
             'value': None,
             'M2': 'IR',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsIR(CsOpt)+AO Selected': {
             'ID': 'Melco_00A1408',
             'value': None,
             'M2': 'CS_OPT',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'NsIR(NsOpt)+AO Selected': {
             'ID': 'Melco_00A1409',
             'value': None,
             'M2': 'NS_OPT',
             'Rotator': 'OUT',
             'ADC': 'OUT'
         },
         'HSC Selected': {
             'ID': 'Melco_00A140F',
             'value': None,
             'M2': 'PF_OPT2',
             'Rotator': 'INSR',
             'ADC': 'IN'
         }
     }