Exemple #1
0
 def closeAllModbusConnections(self):
     '''Close all modbus connections listed in :attr: 'PDPList'.
     '''
     self.disconnectedManually = True
     for i in range(len(self.PDPList)):
         self.PDPList[i].modbusConnectionClose()
     self.PDPList = []
     self.ConnectionStatus.set(Timestamp(),5,False)
     try:
         print "Closed %r modbus connections at %s." %(i+1,Timestamp().to_string())
     except NameError:
         print "There was no modbus connection at %s."%Timestamp().to_string()
def check_target(OVST, target, tmstmp=None, check=True):
    '''
    :param tar:         str or object of class Target
                        if string: searches for the target in catalogue
    :param antennas:    list
                        list of antenna objects of class Antenna
    :param catalogue:   Catalogue
    :param tmstmp:      Timestamp
    :return:            list with position tuples
                        [(az1, el1), (az2, el2), ...]
    '''
    antennas = OVST.active_antennas
    catalogue = OVST.Catalogue

    azel = []
    if isinstance(target, Target):
        target = target
    elif isinstance(
            target, str
    ) and ',' in target:  # Check if target has format: e.g. 'azel, 30, 60'
        target = Target(target)
    elif isinstance(target, str):
        target = catalogue[target]
        if not target:
            raise ValueError("Target not in Catalogue")

    if isinstance(tmstmp, str):
        if tmstmp and len(tmstmp) == 5:
            tmstmp += ':00'
        if tmstmp and len(tmstmp) == 8:
            tmstmp = str(datetime.now().date()) + ' ' + tmstmp

    if isinstance(tmstmp, (int, float)):
        tmstmp = Timestamp(tmstmp)

    if not tmstmp:
        tmstmp = Timestamp()

    for antenna in antennas:
        ae = target.azel(timestamp=tmstmp, antenna=antenna)
        azel.append([rad2deg(ae[0]), rad2deg(ae[1])])

    az = [item[0] for item in azel]
    el = [item[1] for item in azel]
    if check:
        if all((OVST.az_limit[1] - 2 < i < OVST.az_limit[0] + 2
                for i in az)) or all(i < OVST.el_limit[0] for i in el):
            raise LookupError(
                'target cannot get focused at % s (target at azimuth %.2f and elevation %.2f).\n '
                'Allowed limits: az not in range of 150-173 and elevation > 25'
                % (tmstmp.local()[11:19], azel[0][0], azel[0][1]))

    return azel  # format: [(az1, el1), (az2, el2), ...]
    def writeTask(
        self,
        register,
        value,
        tmSp=None,
    ):
        '''Handles writing tasks. It is sorted intern by timestamp so that it keeps the correct order.
        
        params
        ------
        register:
            The register which will be written.

        value:
            The value which is written in the register.

        tmSp: object of :class: 'Timestamp'
            It have to be a param because otherwise all commands of a method for instance :meth: 'moveIncrementalAdapter' get the same timestamp.
            As a result it is sorted by the register in which it writes and it is not a good idea to send first a move command and then set the distance.
            In less critical commands like :meth: 'enableTelescopes' the default can be used
        '''
        if not isinstance(tmSp, Timestamp):
            tmSp = Timestamp()
        PriorityQueue.put(self, (3, tmSp, (register, value)))
        time.sleep(
            0.002)  # Makes sure that the next command get another 'Timestamp'
    def readTask(self, *args):
        '''Handles reading tasks.

        params
        ------
        args: not used
        '''
        PriorityQueue.put(self, (5, Timestamp(), args))
Exemple #5
0
    def __init__(self, target, subarray, spectral_window, timestamps):
        super(MinimalDataSet, self).__init__(name='test', ref_ant='array')
        num_dumps = len(timestamps)
        num_chans = spectral_window.num_chans
        num_corrprods = len(subarray.corr_products)
        dump_period = timestamps[1] - timestamps[0]

        def constant_sensor(value):
            return CategoricalData([value], [0, num_dumps])

        self.subarrays = [subarray]
        self.spectral_windows = [spectral_window]
        sensors = {}
        for ant in subarray.ants:
            sensors['Antennas/%s/antenna' %
                    (ant.name, )] = constant_sensor(ant)
            az, el = target.azel(timestamps, ant)
            sensors['Antennas/%s/az' % (ant.name, )] = az
            sensors['Antennas/%s/el' % (ant.name, )] = el
        # Extract array reference position as 'array_ant' from last antenna
        array_ant_fields = ['array'] + ant.description.split(',')[1:5]
        array_ant = Antenna(','.join(array_ant_fields))
        sensors['Antennas/array/antenna'] = constant_sensor(array_ant)

        sensors['Observation/target'] = constant_sensor(target)
        for name in ('spw', 'subarray', 'scan', 'compscan', 'target'):
            sensors['Observation/%s_index' % (name, )] = constant_sensor(0)
        sensors['Observation/scan_state'] = constant_sensor('track')
        sensors['Observation/label'] = constant_sensor('track')

        self._timestamps = timestamps
        self._time_keep = np.full(num_dumps, True, dtype=np.bool_)
        self._freq_keep = np.full(num_chans, True, dtype=np.bool_)
        self._corrprod_keep = np.full(num_corrprods, True, dtype=np.bool_)
        self.dump_period = dump_period
        self.start_time = Timestamp(timestamps[0] - 0.5 * dump_period)
        self.end_time = Timestamp(timestamps[-1] + 0.5 * dump_period)
        self.sensor = SensorCache(sensors,
                                  timestamps,
                                  dump_period,
                                  keep=self._time_keep,
                                  virtual=DEFAULT_VIRTUAL_SENSORS)
        self.catalogue.add(target)
        self.catalogue.antenna = array_ant
        self.select(spw=0, subarray=0)
Exemple #6
0
 def __init__(self, start_time=None, warp=False):
     self.offset = 0.0 if start_time is None else \
                   Timestamp(start_time).secs - time.time()
     self.warp = warp
     self.bed = Bed()
     self.master_lock = SingleThreadLock()
     self.slave_lock = SingleThreadLock()
     self.condition = None
     self.condition_satisfied = False
Exemple #7
0
 def disableTelescopes(self):
     '''Disables movement of the telescopes
     '''
     i=0
     while not self.CurrentSystemStatus.value() == 1 and not self.error:
         self.PCQ.writeTask(20, 2)
         i += 1
         if i % 10 == 0:  # if it does send 10 times it gives the system some time
             time.sleep(5)
         else:
             time.sleep(2)
     print "Telescopes Disabled at %s."%Timestamp().to_string()
    def _updateFunc(self, tbxobj, value, sensor):
        '''Enables writing to the textboxes, deletes the old value, writes in the new value and disables it for the user again.

        params
        ------
        tbxobj: object of :class: 'Text'
            The textbox in which is written in.

        value: string, float, int
            The value which is written.
        
        status: int 
            Status of the sensor
        '''
        tmSp = Timestamp(float(sensor.read()[0]))
        if tmSp < Timestamp()-5:# Was not updated the last five seconds
            status=6 # Time is over
            sensor.set(tmSp,5,(sensor.read()[2]))
        else:
            status = sensor.read()[1]
        tbxobj.configure(state="normal")
        tbxobj.delete("1.0",END)
        tbxobj.insert(END, value)
        if status == 0: 
            color = "white" 
        elif status == 1: 
            color = "green"
        elif status == 2: 
            color = "yellow"
        elif status == 3: 
            color = "red"
        elif status == 4: 
            color = "magenta"
        elif status == 5: 
            color = "cyan"
        elif status == 6: 
            color = "blue"
        tbxobj.configure(background=color)
        tbxobj.configure(state="disabled")
    def writeImportantTask(self, register, value):
        '''Handles writing tasks with higher priority. It is sorted intern by timestamp so that it keeps the correct order.
        It should be used for commands when exceptions occure.#

        params
        ------
        register:
            The register which will be written.

        value:
            The value which is written in the register.
        '''
        PriorityQueue.put(self, (2, Timestamp(), (register, value)))
Exemple #10
0
    def openModbusConnections(self, amount=1):
        """The defined number of client objects can be defined, opend and append to the 'PDPList' with that method.
        This does not need to be added to the Queue because it does not write or read anything.
        Maximum length of the 'PDPList' is 10.

        params
        ------
        amount: int
            The amount of objects, which will be opened.
            The program uses always the first entry in the list. 
            The user could use a second entry           
            """
        self.disconnectedManually = False
        for i in range (amount):
            self.PDPList.insert(0,PythonDiagnosticProgramm())
            connected = self.PDPList[0].modbusConnectionOpen()
            if connected:
                self.ConnectionStatus.set(Timestamp(),1,True)
            else:
                self.ConnectionStatus.set(Timestamp(),5,False)
        if len(self.PDPList)>10:
            for i in range(len(self.PDPList)-10):
                self.PDPList.pop()
Exemple #11
0
    def haltTelescopes(self):
        """Halts the telescopes.
        """

        i = 0
        self.halt=True
        while not self.CurrentMotionCommand.value() == 0 and not self.error:
            self.PCQ.writeTask(20, 0)
            i += 1
            if i % 10 == 0:  # if it does send 10 times it gives the system some time
                time.sleep(5)
            else:
                time.sleep(2)
        print "Halt the telescopes at %s."%Timestamp().to_string()
Exemple #12
0
    def clearTelescopeFault(self, rollover=None):
        '''Clear the telescope from faults, when a fault has occured
        It also clears the software fault

        param
        -----
        enable: bool
            Enable the Telescope
        '''
        self.PCQ.writeTask(22,1)
        self.askRolloverCounter(rollover)
        self.error = False

        self.clearTelescopeHalt()
        print "Telescope Faults cleared at %s."%Timestamp().to_string()
Exemple #13
0
    def enableTelescopes(self):
        '''Enables movement of the telescopes.
        It also allows automatically reconnection.
        '''
        self.clearTelescopeHalt()
        self.disconnectedManually = False
        i =0
        while not self.CurrentSystemStatus.value() == 2 and not self.error:
            self.PCQ.writeTask(20, 1)
            i += 1
            if i%10==0:     # if it does send 10 times it gives the system some time
                time.sleep(5)
            else:
                time.sleep(2)

        print "Telescopes Enabled at %s."%Timestamp().to_string()
Exemple #14
0
    def clearTelescopeHalt(self):
        '''Clear the telescope from faults, when a fault has occured
        It also clears the software fault

        param
        -----
        enable: bool
            Enable the Telescope
        '''
        self.halt =False
        try:
            # That also enables the Catalogue Manager
            self.currentCatalogue.halt = False
        except AttributeError:
            pass #There is no Catalogue tracked
        print "Telescope Halt cleared at %s."%Timestamp().to_string()
def connectionExceptionHandling(self):
    ''' Handles the event of a 'ConnectionException' with the modbus.
            It sets the 'ConnectionStatus' on 'False' and try to reconnect.
            '''
    print "Handle connection exception at %s." % Timestamp().to_string()
    setConnectionStatus(self)
    while not self.OVST.ConnectionStatus.value(
    ) == True and not self.OVST.disconnectedManually:
        #Reconnection if not disconnected manually
        self.OVST.openModbusConnections(
        )  #sets OVST.ConnectionStatus.value()=True
        try:
            self.OVST.PDPList[0].modbusReadOut(
                1)  # With default start address ist does not work
        except AttributeError:
            setConnectionStatus(self)
        except ConnectionException:
            setConnectionStatus(self)
Exemple #16
0
def moveContinuousAdapter(OVST,
                          targetname,
                          tmSp=None,
                          deltaTmSp=None,
                          inTrack=False,
                          mode=ObservationMode(),
                          disableMaxSpeedWarning=False):
    '''This function allows moving to an continuous position by writing into the PLC.
    A modbus connection has to be defined in the :object: 'OVST' :attr: 'PDPList' to use the default of modbus.

    !!Attention!!
    -------------
    :func:  'moveContinuousAdapter' does not check if limit switch will be hit! 
            It belongs to the responsibility of the user.

    Params
    ------
    OVST:
    
    targetname:     string,   object of :class: 'Target'
                    Name of the target on which will be pointed.
                    If it is a object of :class: 'Target', catalogue value will be skipped.
                    Used in :func: 'check_target'

    tmSp:           object of :class: 'Timestamp'
                    The Timestamp at which the azimuth and elevation cooordinate calculated.

    deltaTmSp:      float
                    The time between the next Timestamp and the current Timestamp.
                    It is used to calculate the speed between two points.
                    Too big values are handled in this class.
                    Too small and also too big values are handled in the PLC to protect it from damage.

    inTrack:        bool
                    If it is true the antennas are not updated during the observation.
                    The value is already writtin in the incremental movement to the start position.
            
    mode:           object of :class: 'GoOffPointing'.
                    The GoOffPointing Class of the target. It returns the 'currentOff'.

    disableMaxSpeedWarning

    '''

    # if antenna is not defined, use the first one which is stored in OVST.antennaList
    antennas = (OVST.active_antennas)

    # Creates a list of a single antenna
    if not isinstance(antennas, list):
        antennas = [antennas]
    # Initialise
    axisToMove = 0
    current_azEl = check_target(OVST, targetname, tmSp, False)
    nextAzEl = check_target(OVST, targetname, tmSp + deltaTmSp, False)
    azElOff = mode.currentOff
    mode.timeStampToCheck = Timestamp() + deltaTmSp
    nextAzElOff = mode.currentOff
    mode.timeStampToCheck = None  # It is very important to clear the timestamp for the next check
    for i in range(len(antennas)):
        # Calculation of Speed
        azSpeed = abs(
            (nextAzEl[i][0] + nextAzElOff[0] - current_azEl[i][0] - azElOff[0])
            / deltaTmSp)
        elSpeed = abs(
            (elevationDegreeToLength(nextAzEl[i][1] + nextAzElOff[1],
                                     antennas[i].azElPos[1].offset) -
             elevationDegreeToLength(current_azEl[i][1] + azElOff[1],
                                     antennas[i].azElPos[1].offset)) /
            deltaTmSp)

        if disableMaxSpeedWarning:
            # Only for RasterDiscrete
            azSpeed = 5.0
            elSpeed = 5.0

        # Catches too big speed values
        if azSpeed > 5:
            azSpeed = 5.0
            if not disableMaxSpeedWarning:
                print "Azimuth Speed is higher than 5 at %s" % Timestamp(
                ).to_string()
        OVST.PCQ.writeTask(antennas[i].azimuthMoveAbsoluteSpeedRegister,
                           float(azSpeed), Timestamp())

        if elSpeed > 5:
            elSpeed = 5.0
            if not disableMaxSpeedWarning:
                print "Elevation Speed is higher than 5 at %s" % Timestamp(
                ).to_string()
        OVST.PCQ.writeTask(antennas[i].elevationMoveAbsoluteSpeedRegister,
                           float(elSpeed), Timestamp())

        # Positions after speed. Otherwise it uses the old speed from the last writing period.
        # Write the values in the registers
        OVST.PCQ.writeTask(
            antennas[i].azimuthMoveAbsolutePositionRegister,
            float(
                azimuthOffset(nextAzEl[i][0] + nextAzElOff[0],
                              antennas[i].azElPos[0].offset)), Timestamp())
        print antennas[i].name, float(
            azimuthOffset(nextAzEl[i][0] + nextAzElOff[0],
                          antennas[i].azElPos[0].offset))
        OVST.PCQ.writeTask(
            antennas[i].elevationMoveAbsolutePositionRegister,
            float(
                elevationDegreeToLength(nextAzEl[i][1] + nextAzElOff[1],
                                        antennas[i].azElPos[1].offset)),
            Timestamp())

        if not inTrack:
            # Only called when Track gets started
            axisToMove += antennas[i].selectValue
            # Write which axis should move
            OVST.PCQ.writeTask(OVST.axisToMoveRegister, axisToMove,
                               Timestamp())
            # Start move continuous status
            OVST.PCQ.writeTask(OVST.motionCommandRegister,
                               OVST.moveContinuousValue, Timestamp())
    OVST.inSavetyPosition = False
    OVST.inHomePosition = False
Exemple #17
0
def moveAbsoluteAdapter(OVST,
                        targetname,
                        catalogue=None,
                        antennas=None,
                        modbus=None,
                        tmSp=None,
                        inTrack=False,
                        azElGoOff=[0, 0]):
    '''This function allows moving to an absolute position by writing into the PLC.
    A modbus connection has to be defined in the :object: 'OVST' :attr: 'PDPList' to use the default of modbus.

    Attention
    ---------
    :func: 'moveAbsoluteAdapter' does not check if limit switch will be hit! It belongs to the responsibility of the user.

    Params
    ------
    targetname: string,   object of :class: 'Target'
        Name of the target on which will be pointed.
        If it is a object of :class: 'Target', catalogue value will be skipped.
        Used in :func: 'check_target'

    catalogue: object of :class: 'Catalogue'
        It should containing an element called 'targetname'
        Used in :func: 'check_target'

    antennas: list of object or object of :class: 'Antenna'
        If there is no antenna specified the antenna(s)
        defined in 'catalogue' or the antennas defined in
        the object of :class: 'Target' are used.

    modbus: object of :class: 'ModbusClient'
        Necessary for Modbus communication
        If there is no object defined, the first object of the 'PDPList' in overall
        settings object 'OVST' is used

    tmSp: object of :class: 'Timestamp'
        The Timestamp at which the azimuth and elevation cooordinate calculated.

    inTrack: bool
        If it is true the antennas are not updated during the observation.
        The value is already writtin in the incremental movement to the start position.

    azElGoOff: list of 2 floats
            index 0 is the azimuth Off
            index 1 is the elevation Off
            it is used to go off the target
    '''

    # if modbus is not defined, use the first one which is stored in OVST.PDPList
    if (modbus == None):
        modbus = (OVST.PDPList[0])
    # if catalogue is not defined, use the first one which is stored in OVST.Catalogue
    if (catalogue == None):
        catalogue = (OVST.Catalogue)
    # if antenna is not defined, use the first one which is stored in OVST.antennaList
    if (antennas == None):
        antennas = (OVST.antennaList)

    # Creates a list of a single antenna
    if not isinstance(antennas, list):
        antennas = [antennas]
    # Initialise
    axisToMove = 0
    azEl = check_target(OVST, targetname, tmSp)
    for i in range(len(antennas)):
        # Write the values in the registers
        OVST.PCQ.writeTask(
            antennas[i].azimuthMoveAbsolutePositionRegister,
            float(
                azimuthOffset(azEl[i][0] + azElGoOff[0],
                              antennas[i].azElPos[0].offset)), Timestamp())
        OVST.PCQ.writeTask(
            antennas[i].elevationMoveAbsolutePositionRegister,
            float(
                elevationDegreeToLength(azEl[i][1] + azElGoOff[1],
                                        antennas[i].azElPos[1].offset)),
            Timestamp())
        # Add the axis to the list of axis which move when move command occures
        axisToMove += antennas[i].selectValue
    if not inTrack:
        # Write which axis should move
        OVST.PCQ.writeTask(OVST.axisToMoveRegister, axisToMove, Timestamp())
    # Move to the absolute position
    OVST.PCQ.writeTask(OVST.motionCommandRegister, OVST.moveAbsoluteValue,
                       Timestamp())
    OVST.inSavetyPosition = False
    OVST.inHomePosition = False
Exemple #18
0
def moveIncrementalAdapter(OVST,
                           targetname,
                           catalogue=None,
                           antennas=None,
                           modbus=None,
                           azTargetRolloverCounter=None,
                           azElOff=[0, 0]):
    '''This function allows moving for a incremental distance
    If 'azTargetRolloverCounter' is not None it will use that azimuth values.
    A modbus connection has to be defined in the :object: 'OVST' :attr: 'PDPList' to use the default of modbus.

    Params
    ------
    targetname: string,   object of :class: 'Target'
        Name of the target on which will be pointed.
        If it is a object of :class: 'Target', catalogue value will be skipped.
        Used in :func: 'check_target'.

    catalogue: object of :class: 'Catalogue'
        It should containing an element called 'targetname'.
        Used in :func: 'check_target'.

    antennas: list objects of :class: 'Antenna'
        If there is no antenna specified the antenna(s) defined in 'catalogue' or
        the antennas defined in the object of :class: 'Target' are used.

    modbus: object of :class: 'ModbusClient'
        Necessary for Modbus Communication.

    azTargetRolloverCounter: array of floats
        a array of possible azimuth start values for each axis in an absolute coordinate without rollovers
        It already mention the goOff in azimuth

    azElOff: list of two floats
        The first entry is the off in azimuth and the second is the off in elevation.
        It is necessary for moving to the correct start position,
        if the goOffPointing does not start at the target itself.
        Azimuth Off is already mentioned in 'azTargetRolloverCounter
    '''
    # if modbus is not defined, use the first one which is stored in OVST.PDPList
    if (modbus == None):
        modbus = (OVST.PDPList[0])
    # if catalogue is not defined, use the first one which is stored in OVST.Catalogue
    if (catalogue == None):
        catalogue = (OVST.Catalogue)
    # if antenna is not defined, use the first one which is stored in OVST.antennaList
    if (antennas == None):
        antennas = (OVST.antennaList)
    # Creates a list of a single antenna
    if not isinstance(antennas, list):
        antennas = [antennas]
    # Initialise that only the selected axis move
    axisToMove = 0
    # azEl has to be defined for elevation
    azEl = check_target(OVST, targetname)

    if not azTargetRolloverCounter == None:
        # make sure that it is a list
        if not isinstance(azTargetRolloverCounter, list):
            azTargetRolloverCounter = [azTargetRolloverCounter]
    for i in range(len(antennas)):
        if (azTargetRolloverCounter == None):
            # Gives the shortest move distance
            azMoveDistance = getMoveDistance(azEl[i][0] + azElOff[0],
                                             antennas[i].azElPos[0])
        else:
            # Make the add for each axis seperate because the lenght of the sublist must not be of the same length
            distLst = []
            absLst = []
            # Get the closest azimuth that is closest to the current possition
            for azi in range(len(azTargetRolloverCounter[i])):
                distLst.append(azTargetRolloverCounter[i][azi] -
                               antennas[i].azElPos[0].positionWithoutRollover)
                absLst.append(abs(distLst[azi]))
            # take the shortest azimuth distance
            # a.index(min(a)) index of minimal value
            azMoveDistance = (distLst[absLst.index(min(absLst))])
        # Write the values in the registers
        OVST.PCQ.writeTask(antennas[i].azimuthMoveIncrementalDistanceRegister,
                           (azMoveDistance), Timestamp())
        OVST.PCQ.writeTask(
            antennas[i].elevationMoveIncrementalDistanceRegister,
            (getMoveDistance(azEl[i][1] + azElOff[1], antennas[i].azElPos[1])),
            Timestamp())
        # Add the axis to the list of axis which move when move command occures
        axisToMove += antennas[i].selectValue
    # Write which axis should move
    OVST.PCQ.writeTask(OVST.axisToMoveRegister, axisToMove, Timestamp())
    # Move to the absolute position
    OVST.PCQ.writeTask(OVST.motionCommandRegister, OVST.moveIncrementalValue,
                       Timestamp())
    OVST.inSavetyPosition = False
    OVST.inHomePosition = False
Exemple #19
0
    def move_to_pos(self, az, el=None, for_track=False, azel_off=[0,0]):
        '''
        moves the telescopes to a specific azel or radec or to a target position
        :param az:  float/int, string
                    if float/int: az    if string: ra when in format ('HH:MM:SS') otherwise search for target
        :param el:  float/int, string
                    if float/int: el, if string: declination in degree
        '''
        if self.error:
            print "Error has occured. Can not move at %s."%Timestamp().to_string()
        elif self.halt:
            print "Halt has occured. Can not move at %s."%Timestamp().to_string()
        # Important if you choose another telescope while another is moving
        antennas = self.active_antennas
        # Checks whether azel, radec or a target is given
        if isinstance(az, (int, float)) and isinstance(el, (int, float)):
            az = az % 360
            target = construct_azel_target(deg2rad(az), deg2rad(el))
            target.name = 'Moving to az: %d, el: % d at %s' % (az, el, Timestamp().to_string())
        elif isinstance(az, str) and isinstance(el, str):
            target = construct_radec_target(az, el)
            target.name = 'Moving to ra: %s, dec: %s at %s' % (az, el, Timestamp().to_string())
        elif isinstance(az, str) and not el:
            if ',' in az:
                target = Target(az)
            else:
                target = self.Catalogue[az]
        elif isinstance(az, Target):
            target = az
        else:
            raise AttributeError('Wrong format')


        try:
            azel = check_target(self, target)
        except LookupError:
            return 'Target with position az: %s, el: %s is out of telescope range' % (az, el)
        self.enableTelescopes()
        self.inSafetyPosition = False
        moveIncrementalAdapter(self, target, antennas=antennas, azElOff=azel_off)
        #inRange = [[False]*2]*len(antennas)
        inRange = []
        for i in antennas:
            # list of Booleans which show if the antennas are at the right position
            inRange.append([False, False])
        all_inRange = False
        azel = np.add(azel,azel_off)
        while ((self.CurrentSystemStatus.value() == 5 or (not all_inRange)) and not
                self.error and not self.halt):
            for n, ant in enumerate(antennas):
                for i, az_el in enumerate(azel[n]):
                    # check if antenna is range
                    if az_el-0.5 <= ant.azElPos[i].value() <= az_el+0.5:
                        inRange[n][i] = True
            all_inRange = all(i == [True]*2 for i in inRange)

            time.sleep(1)
            if (not all_inRange and not self.CurrentMotionCommand.value() == self.moveIncrementalValue and
                    not self.error and not self.halt):
                moveIncrementalAdapter(self, target, antennas=antennas, azElOff=azel_off)

        # Get position of all Telescopes
        pos = self.get_pos()
        if not for_track:
            if inRange:
                print 'Telescopes are in position at %s:'% Timestamp().to_string()
                for i, azel in enumerate(pos):
                    print '%s     \t Azimuth: %s \t Elevation: %s' % (self.antennaList[i].name, azel[1], azel[2])
                self.disableTelescopes()
    def run(self):
        """Infinite loop which updates a object of :class: 'Sensor' or sends commands to the PLC.
        It is called with 'BackgroundUpdaterObject.start()' in the command line.
        """

        while True:
            # Add a readout command to the Queue if the Queue is not too long. Important for the first loop
            if self.OVST.PCQ.qsize() < 5:
                self.OVST.PCQ.readTask()
            # get the command
            priority, tmSp, args = self.OVST.PCQ.get()
            # if it is a reading task, the priority is 5
            if priority == 2:
                successful = False
                while not successful:
                    try:
                        self.OVST.PDPList[0].modbusWrite(args[0], args[1])
                        successful = True
                        #print "Send the priority 2 command '%r' to address '%r' at %s" %(args[1],args[0],Timestamp().to_string())
                    except OverflowError:
                        print "OverflowError 'Writing Priority' at %r " % Timestamp(
                        )
                    except ConnectionException:
                        connectionExceptionHandling(self)
                    except AttributeError:
                        connectionExceptionHandling(self)
                    except IndexError:
                        # it is disconnected manually
                        setConnectionStatus(self)
            elif priority == 5:
                try:
                    # Process the command
                    returnValue = self.OVST.PDPList[0].modbusReadOutAll()
                    self.OVST.ConnectionStatus.set(Timestamp(), 1, True)
                except OverflowError:
                    print "OverflowError Reading at %r " % Timestamp()
                except ConnectionException:
                    connectionExceptionHandling(self)
                except AttributeError:
                    connectionExceptionHandling(self)
                except IndexError:
                    # it is disconnected manually
                    setConnectionStatus(self)
                try:
                    #Check if the SUT is finished with working
                    if not self.OVST.SUT.is_alive():
                        self.OVST.SUT = SensorUpdateThread(
                            returnValue, self.OVST)
                except AttributeError:  # If the name is None
                    try:
                        self.OVST.SUT = SensorUpdateThread(
                            returnValue, self.OVST)
                    except UnboundLocalError:
                        pass  #Just do not update: it happens when updating is not possible because of a lost modbus connection
            if (priority == 3) & (not self.OVST.error):  # it is a writing task
                # The asking for a error makest that it doesnot Move furhter.
                # It is necessary because even if the telescope will be telescope disabled, the next 'moveAbsoluteCommand' cause it to move.
                try:
                    self.OVST.PDPList[0].modbusWrite(args[0], args[1])
                except OverflowError:
                    print "OverflowError Writing at %r " % Timestamp()
                    print "lenght of PCQ (not reliable)", (
                        self.OVST.PCQ.qsize())
                except ConnectionException:
                    connectionExceptionHandling(self)
                except AttributeError:
                    connectionExceptionHandling(self)
                except IndexError:
                    # it is disconnected manually
                    setConnectionStatus(self)
                if args[0] == self.OVST.antennaList[
                        0].azimuthMoveIncrementalDistanceRegister:
                    self.OVST.pointingLog[0].append(args[1])
                if args[0] == self.OVST.antennaList[
                        0].elevationMoveIncrementalDistanceRegister:
                    self.OVST.pointingLog[1].append(args[1])

            # Indicates the Queue that the task is done.
            self.OVST.PCQ.task_done()
Exemple #21
0
    def daq_pos(self, name=None, daq_attrs=None):
        '''
        Creates a hdf5 file for every day and stores the position of the current session in the group 'name'
        :param name:    string
                        name of the datagroup in the hdf file. If None it will use the format 
                        "positions_'start Timestamp of record'" 
        '''
        # One hdf file for one day: 'positions_YYYY_MM_DD.h5'
        data_dict = {}
        for i, ant in enumerate(self.antennaList):
            data_dict[ant] = []
        self.daq = True
        self.data_saved = False
        # Start data acquisition
        while self.daq:
            pos = self.get_pos()
            for i, ant in enumerate(self.antennaList):
                target = construct_azel_target(deg2rad(pos[i][1]), deg2rad(pos[i][2]))
                radec = target.astrometric_radec(timestamp=pos[i][0], antenna=ant)
                data_dict[ant].append((pos[i][0], pos[i][1], pos[i][2],
                                       radec[0], radec[1]))
            time.sleep(1)

        # If task is done, safe the data in an hdf5 file
        if not name:
            new_name = '%s_positions' % Timestamp().local()[11:19] # positions_HH:MM:SS
        else:
            new_name = name
        used = True
        date = datetime.today().date().strftime('%Y_%m_%d')
        i = 1
        # Define column names and data types
        dtype = np.dtype([
            ('Timestamp', np.float),
            ('Azimuth', np.float),
            ('Elevation', np.float),
            ('RA (J2000)', h5py.special_dtype(vlen=str)),
            ('DEC (J2000)', h5py.special_dtype(vlen=str))
        ])

        with h5py.File(self.daq_dirpath + '/positions_%s.h5' % date, 'a') as hdf:
            while used:
                try:
                    G = hdf.create_group(new_name)
                    used = False
                except ValueError:
                    new_name = name + '_' + str(i)
                    i += 1
            for i, ant in enumerate(self.antennaList):
                data_array = np.array(data_dict[ant], dtype=dtype)
                dset = G.create_dataset('%s' % ant.name, data=data_array)
                dset.attrs.update({
                    'Antenna name':         ant.name,
                    'Antenna latitude':     ant.observer.lat,
                    'Antenna longitude':    ant.observer.long,
                    'Antenna altitude':     ant.observer.elevation
                })

                if isinstance(daq_attrs, dict):
                    for key, val in daq_attrs.iteritems():
                        dset.attrs[key] = val
            print 'Data saved!'
            self.data_saved = True
Exemple #22
0
 def test_timestamps(self):
     mjd = Timestamp(self.timestamps[0]).to_mjd()
     assert_equal(self.dataset.mjd[0], mjd)
     lst = self.array_ant.local_sidereal_time(self.timestamps)
     # Convert LST from radians (katpoint) to hours (katdal)
     assert_array_equal(self.dataset.lst, lst * (12 / np.pi))
def setConnectionStatus(self):
    self.OVST.ConnectionStatus.set(Timestamp(), 5, False)