From ad49d367d7712a421d050ebb03842dee949f7413 Mon Sep 17 00:00:00 2001 From: Mattia Mancini <mancini@astron.nl> Date: Mon, 10 Dec 2018 12:17:57 +0000 Subject: [PATCH] OSB-36: Wrong specification of the LBL antenna number --- .../monitoringdb/views/controllers.py | 273 ++++++++++-------- 1 file changed, 159 insertions(+), 114 deletions(-) diff --git a/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py b/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py index ce5a8713348..239e049db52 100644 --- a/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py +++ b/LCU/Maintenance/DBInterface/monitoringdb/views/controllers.py @@ -2,25 +2,26 @@ import datetime import logging from collections import OrderedDict from math import ceil -from django.conf import settings + import coreapi import coreschema +import pytz from django.db.models import Count from lofar.maintenance.monitoringdb.models.component_error import ComponentError -from lofar.maintenance.monitoringdb.models.rtsm import RTSMErrorSummary, MODE_TO_COMPONENT, COMPONENT_TO_MODE +from lofar.maintenance.monitoringdb.models.rtsm import RTSMErrorSummary, MODE_TO_COMPONENT, \ + COMPONENT_TO_MODE from lofar.maintenance.monitoringdb.models.rtsm import RTSMObservation from lofar.maintenance.monitoringdb.models.station import Station from lofar.maintenance.monitoringdb.models.station_test import StationTest from rest_framework import status -from rest_framework.reverse import reverse from rest_framework.response import Response +from rest_framework.reverse import reverse from rest_framework.schemas import ManualSchema from rest_framework.views import APIView -import pytz - logger = logging.getLogger(__name__) + def parse_date(date): expected_format = '%Y-%m-%d' try: @@ -57,6 +58,65 @@ def _get_unique_error_types(): return [item['type'] for item in ComponentError.objects.values('type').distinct()] +def rcu_from_antenna_type_polarization(antenna_id, type, polarization): + """ + Compute the rcu number for a given antenna number, type and polarization + :param antenna_id: id of the antenna + :param type: type of the antenna + :param polarization: polarization either [X, Y] + :return: the rcu id + :rtype: int + """ + if polarization not in ['X', 'Y']: + raise ValueError('Polarization has to be either X or Y: %s not recognized' % polarization) + + if type == 'LBH': + rcu_id = antenna_id * 2 + rcu_id += 0 if polarization == 'X' else 1 + elif type == 'LBL': + rcu_id = (antenna_id - 48) * 2 + rcu_id += 1 if polarization == 'X' else 0 + elif type == 'HBA': + rcu_id = antenna_id * 2 + rcu_id += 0 if polarization == 'X' else 1 + else: + rcu_id = -1 + return rcu_id + + +def antenna_id_polarization_from_rcu_type_polarization(rcu, type): + """ + Compute the antenna id for a given rcu, type and polarization + :param rcu: id of the rcu + :param type: type of the antenna + :return: the antenna id and polarization + :rtype: (int, str) + :rtype: int + """ + polarization_index = rcu % 2 + + + if type in ['LBH', 'HBA']: + antenna_id = rcu - polarization_index + antenna_id /= 2. + polarization = 'Y' if polarization_index > 0 else 'X' + elif type == 'LBL': + antenna_id = (rcu - polarization_index)/2. + 48 + polarization = 'X' if polarization_index > 0 else 'Y' + else: + antenna_id = -1 + polarization = '' + + return int(antenna_id), polarization + +def rcus_from_antenna_and_type(antenna_id, type): + rcu_x = rcu_from_antenna_type_polarization(antenna_id, type, 'X') + rcu_y = rcu_from_antenna_type_polarization(antenna_id, type, 'Y') + + rcus = {rcu_x: 'X', rcu_y: 'Y'} + return rcus + + class ValidableReadOnlyView(APIView): """ Convenience APIView class to have the validation of the query parameters on a get http request @@ -65,6 +125,7 @@ class ValidableReadOnlyView(APIView): # Override this to make the schema validation work fields = [] description = '' + def compute_response(self): raise NotImplementedError() @@ -197,7 +258,7 @@ class ControllerStationOverview(ValidableReadOnlyView): station_test_payload = OrderedDict() component_errors = station_test.component_errors selected_component_errors = component_errors - if(self.error_types): + if (self.error_types): selected_component_errors = component_errors.filter(type__in=self.error_types) station_test_payload[ 'total_component_errors'] = selected_component_errors.count() @@ -235,8 +296,9 @@ class ControllerStationOverview(ValidableReadOnlyView): rtsm_payload['mode'] = unique_modes selected_rtsm_errors = rtsm.errors_summary - if(self.error_types): - selected_rtsm_errors = rtsm.errors_summary.filter(error_type__in=self.error_types) + if (self.error_types): + selected_rtsm_errors = rtsm.errors_summary.filter( + error_type__in=self.error_types) rtsm_payload['total_component_errors'] = selected_rtsm_errors.count() @@ -322,9 +384,9 @@ class ControllerStationTestsSummary(ValidableReadOnlyView): station_test_payload = OrderedDict() station_test_payload['station_name'] = station_test.station.name selected_component_errors = station_test.component_errors - if(self.error_types): - selected_component_errors = selected_component_errors.filter(type__in=self.error_types) - + if (self.error_types): + selected_component_errors = selected_component_errors.filter( + type__in=self.error_types) station_test_payload[ 'total_component_errors'] = selected_component_errors.count() @@ -735,8 +797,8 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): .filter(start_datetime__gte=self.from_date, end_datetime__lte=self.to_date) - failing_component_types = station_tests.distinct('component_errors__component__type').\ - exclude(component_errors__component__type__isnull=True).\ + failing_component_types = station_tests.distinct('component_errors__component__type'). \ + exclude(component_errors__component__type__isnull=True). \ values_list('component_errors__component__type') for failing_component_type in failing_component_types: @@ -752,7 +814,7 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): test_summary['end_date'] = station_test.end_datetime component_errors_dict = OrderedDict() test_summary['component_errors'] = component_errors_dict - component_errors = station_test.component_errors\ + component_errors = station_test.component_errors \ .filter(component__type=failing_component_type) if self.error_types: component_errors = component_errors.filter(type__in=self.error_types) @@ -764,7 +826,7 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): if component_id not in component_errors: component_errors_dict[str(component_id)] = list() component_errors_dict[str(component_id)] += [dict(error_type=error_type, - details=details)] + details=details)] component_type_errors_list.append(test_summary) @@ -782,6 +844,7 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): for observing_mode in failing_component_modes: observing_mode = observing_mode[0] + component_name = MODE_TO_COMPONENT[observing_mode] rtsm_errors_per_component_type = list() @@ -795,12 +858,12 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): component_errors_dict = OrderedDict() rtsm_summary['component_errors'] = component_errors_dict - component_errors = rtsm_observation.errors_summary\ - .filter(mode=observing_mode)\ + component_errors = rtsm_observation.errors_summary \ + .filter(mode=observing_mode) \ .values('error_type', 'start_frequency', 'stop_frequency', 'percentage', 'error_type', 'count', 'rcu', 'pk') - if component_errors.count() == 0 and rtsm_observation.errors_summary.count() !=0: + if component_errors.count() == 0 and rtsm_observation.errors_summary.count() != 0: continue else: rtsm_errors_per_component_type.append(rtsm_summary) @@ -810,20 +873,30 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): for component_error in component_errors: - component_id = component_error['rcu'] - details = dict(percentage = component_error['percentage'], - start_frequency = component_error['start_frequency'], - stop_frequency = component_error['stop_frequency'], - count = component_error['count']) + rcu_id = component_error['rcu'] + component_id, polarization = antenna_id_polarization_from_rcu_type_polarization(rcu_id, component_name) + details = dict(percentage=component_error['percentage'], + start_frequency=component_error['start_frequency'], + stop_frequency=component_error['stop_frequency'], + count=component_error['count'], + component_id=component_id) error_type = component_error['error_type'] # CHECKS IF THE ERROR IS PRESENT IN BOTH RCUS (hence, both polarizations of the antenna) - url_to_plot = reverse('rtsm-summary-plot-detail', (component_error['pk'],), request=self.request) + url_to_plot = reverse('rtsm-summary-plot-detail', (component_error['pk'],), + request=self.request) details['url'] = url_to_plot - if component_id not in component_errors: - component_errors_dict[str(component_id)] = list() - component_errors_dict[str(component_id)] += [dict(error_type=error_type, details=details)] - component_name = MODE_TO_COMPONENT[observing_mode] + if not str(component_id) in component_errors_dict: + component_errors_dict[str(component_id)] = OrderedDict() + + if error_type not in component_errors_dict[str(component_id)]: + rtsm_error_summary = dict(error_type=error_type) + component_errors_dict[str(component_id)][error_type] = rtsm_error_summary + else: + rtsm_error_summary = component_errors_dict[str(component_id)][error_type] + + rtsm_error_summary[polarization] = dict(details=details, error_type=error_type, rcu_id=rcu_id, polarization=polarization,) + if component_name not in response_payload: response_payload[component_name] = rtsm_errors_per_component_type else: @@ -850,18 +923,19 @@ class ControllerStationComponentErrors(ValidableReadOnlyView): station_test_errors_per_type = station_test_errors.get(component_type, []) rtsm_errors_per_type = rtsm_errors.get(component_type, []) - payload[component_type] = sorted(station_test_errors_per_type + rtsm_errors_per_type, key=lambda item: item['start_date'], reverse=True) + payload[component_type] = sorted(station_test_errors_per_type + rtsm_errors_per_type, + key=lambda item: item['start_date'], reverse=True) return Response(status=status.HTTP_200_OK, data=payload) class ControllerStationComponentElementErrors(ValidableReadOnlyView): - station_name= None # required - from_date= None # required - to_date= None # required - component_type= None # required - antenna_id= None # required - test_type= "A" + station_name = None # required + from_date = None # required + to_date = None # required + component_type = None # required + antenna_id = None # required + test_type = "A" fields = [ coreapi.Field( @@ -910,69 +984,37 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): ) ] - def rcu_from_antenna_type_polarization(self, antenna_id, type, polarization): - """ - Compute the rcu number for a given antenna number, type and polarization - :param antenna_id: id of the antenna - :param type: type of the antenna - :param polarization: polarization either [X, Y] - :return: the rcu id - :rtype: int - """ - if polarization not in ['X', 'Y']: - raise ValueError('Polarization has to be either X or Y: %s not recognized' % polarization) - - if type == 'LBH': - rcu_id = antenna_id * 2 - rcu_id += 0 if polarization == 'X' else 1 - elif type == 'LBL': - rcu_id = (antenna_id - 48) * 2 - rcu_id += 1 if polarization == 'X' else 0 - elif type == 'HBA': - rcu_id = antenna_id * 2 - rcu_id += 0 if polarization == 'X' else 1 - else: - rcu_id = -1 - return rcu_id - - def rcus_from_antenna_and_type(self, antenna_id, type): - rcu_x = self.rcu_from_antenna_type_polarization(antenna_id, type, 'X') - rcu_y = self.rcu_from_antenna_type_polarization(antenna_id, type, 'Y') - - rcus={rcu_x:'X', rcu_y:'Y'} - return rcus - def compute_ok_rtsm_list(self): - mode=COMPONENT_TO_MODE[self.component_type] + mode = COMPONENT_TO_MODE[self.component_type] + + rcus_per_polarization = rcus_from_antenna_and_type(self.antenna_id, + self.component_type) - rcus_per_polarization = self.rcus_from_antenna_and_type(self.antenna_id, - self.component_type) - good_observation_list = RTSMObservation.objects.filter(errors_summary__mode__in=mode, - start_datetime__gt=self.from_date, - end_datetime__lt=self.to_date, - station__name=self.station_name).\ - exclude(errors_summary__rcu__in=list(rcus_per_polarization.keys())).\ + start_datetime__gt=self.from_date, + end_datetime__lt=self.to_date, + station__name=self.station_name). \ + exclude(errors_summary__rcu__in=list(rcus_per_polarization.keys())). \ values('pk', - 'observation_id', - 'start_datetime', - 'end_datetime').distinct('pk') + 'observation_id', + 'start_datetime', + 'end_datetime').distinct('pk') result = [] for observation in good_observation_list: entry = dict(test_id=observation['observation_id'], - db_id=observation['pk'], - start_date=observation['start_datetime'], - end_date=observation['end_datetime'], - test_type='R', - component_errors=dict()) + db_id=observation['pk'], + start_date=observation['start_datetime'], + end_date=observation['end_datetime'], + test_type='R', + component_errors=dict()) result.append(entry) return result def compute_ok_station_test(self): good_station_test = StationTest.objects.filter(start_datetime__gt=self.from_date, - end_datetime__lt=self.to_date, - station__name=self.station_name).\ - exclude(component_errors__component__component_id=self.antenna_id).\ + end_datetime__lt=self.to_date, + station__name=self.station_name). \ + exclude(component_errors__component__component_id=self.antenna_id). \ values('pk', 'start_datetime', 'end_datetime').order_by('-start_datetime') result = [] for station_test in good_station_test: @@ -987,21 +1029,21 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): def compute_rtsm_errors_list(self): errors = dict() - rcus_per_polarization = self.rcus_from_antenna_and_type(self.antenna_id, - self.component_type) + rcus_per_polarization = rcus_from_antenna_and_type(self.antenna_id, + self.component_type) rtsm_errors = RTSMErrorSummary.objects.values('observation__pk', - 'observation__start_datetime', - 'observation__end_datetime', - 'observation__observation_id', - 'observation__station__name', - 'pk', - 'rcu', - 'mode', - 'error_type', - 'percentage', - 'count', - 'observation__samples').filter( + 'observation__start_datetime', + 'observation__end_datetime', + 'observation__observation_id', + 'observation__station__name', + 'pk', + 'rcu', + 'mode', + 'error_type', + 'percentage', + 'count', + 'observation__samples').filter( observation__start_datetime__gt=self.from_date, observation__end_datetime__lt=self.to_date, observation__station__name=self.station_name, @@ -1011,13 +1053,13 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): observation_pk = item['observation__pk'] if observation_pk not in errors.keys(): errors[observation_pk] = dict(test_id=item['observation__observation_id'], - db_id=item['observation__pk'], - start_date=item[ - 'observation__start_datetime'], - end_date=item[ - 'observation__end_datetime'], - test_type='R', - component_errors=dict()) + db_id=item['observation__pk'], + start_date=item[ + 'observation__start_datetime'], + end_date=item[ + 'observation__end_datetime'], + test_type='R', + component_errors=dict()) rcu = item['rcu'] polarization = rcus_per_polarization[rcu] @@ -1031,12 +1073,13 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): errors[observation_pk]['component_errors'][error_type] = dict() url_to_plot = reverse('rtsm-summary-plot-detail', (item['pk'],), request=self.request) - errors[observation_pk]['component_errors'][error_type][polarization] = dict(samples=samples, - percentage=percentage, - count=count, - mode=mode, - rcu=rcu, - url=url_to_plot) + errors[observation_pk]['component_errors'][error_type][polarization] = dict( + samples=samples, + percentage=percentage, + count=count, + mode=mode, + rcu=rcu, + url=url_to_plot) return list(errors.values()) def compute_station_tests_error_list(self): @@ -1058,11 +1101,13 @@ class ControllerStationComponentElementErrors(ValidableReadOnlyView): component_errors=dict()) error_type = component_error.type details = component_error.details - errors[station_test_pk]['component_errors'][error_type] = dict(details=details, element_errors = dict()) + errors[station_test_pk]['component_errors'][error_type] = dict(details=details, + element_errors=dict()) error_per_error_type = errors[station_test_pk]['component_errors'][error_type] - for element in component_error.failing_elements.values('element__element_id', 'details'): + for element in component_error.failing_elements.values('element__element_id', + 'details'): element_id = element['element__element_id'] error_per_error_type["element_errors"][element_id] = element['details'] -- GitLab