dmrl_prec_file_prec_3_sigma.py 7.21 KB
import urllib.request
import json
import os
import datetime
from imageio import imread
import cv2
import numpy as np
import loca_data
import duamel_model
import matplotlib.pyplot as plt
import sher_duam_class
import dateutil.parser
import dmrl_prec_file

class DMRLPrecFile_3SC(dmrl_prec_file.DMRLPrecFile):

    # Получить результаты расчёта
    def GetResult(self, _prec, _test_datetime=None):
        """
        _prec это JSON вида:
            {"time": "2020-03-20T10:00:00Z",
            "period": 600,
            "sum": 0.0,
            "intensity": 0.0,
            "type": 0}
        """

        result = None
        if _prec["sum"] == " ":
            _prec = None

        """
        result это JSON вида:
            {"time": "2020-03-20T10:00:00Z",    - время расчета
            "water_volume": 0.0,                - общее воличество выпавшей воды в м^3
            "prec_square": 0.0,                 - площадь выпадения осадков в м^2
            "all_square": 0.0}            - общая площадь водосбора в м^2
        """

        #self.k_point_correction = 1                                 # Коэффициент корректировки точечный (интенсивность на осадкомере к интенсивносьти по радару в точке)
        #self.k_reserv_volume_prec = 1                               # Резервный коэффициент (объем воды / текущие осадки на осадкомере)
        temp_datetime = datetime.datetime.now()
        temp_cur_min = (temp_datetime.minute // 10) * 10
        cur_datetime = datetime.datetime(temp_datetime.year, temp_datetime.month, temp_datetime.day, temp_datetime.hour, temp_cur_min, 0, 0)

        if _prec is not None:
            #cur_datetime = dateutil.parser.parse(_prec["time"], ignoretz=False).replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
            cur_datetime = dateutil.parser.parse(_prec["time"])

        if _test_datetime is not None:
            cur_datetime = _test_datetime

        matrix = self.GetMatrix(cur_datetime)

        #####################################
        # TODO Delete!!!!
        #temp_val = int(cur_datetime.timestamp())
        #temp_f_p = os.path.abspath(os.curdir) + '\\result\\{}.png'.format(int(cur_datetime.timestamp()))
        #cv2.imwrite(temp_f_p, matrix)
        #####################################

        # 1. Если ДМРЛ нет и нет осадков
        if matrix is None and _prec is None:
            result = dict(time = cur_datetime.__str__(),
                water_volume = -1.0,
                prec_square = -1.0,
                all_square = -1.0,
                dmrl_prec = -1.0)
            return json.dumps(result)


        # 2. Если ДМРЛ нет, но есть осадки
        if matrix is None and _prec is not None:
            temp_volume = self.GetReservDataByPrec(float(_prec["sum"]))

            result = dict(time = cur_datetime.__str__(),
                water_volume = temp_volume,
                prec_square = self.squere,
                all_square = -1.0)
            return json.dumps(result)

        # 3-4. Если есть ДМРЛ и есть (или нет) осадков с АГК - ОБЫЧНЫЙ АЛГОРИТМ
        # Определяем коэффициент корреляции, если оба значения есть и отличны от нуля
        cur_prec_value = 0
        if _prec is not None:
            cur_prec_value = float(_prec["sum"])

            test = matrix[0]
            test = test[0]
            test = test[0]

            value = matrix[int(self.corr_y)][int(self.corr_x)][0]
            dmrl_prec = self.GetPrecByDBZ(value)
            dmrl_prec = dmrl_prec / 6

            ####################################################################
            # Работаем с коэффициентами корректировки
            temp_k_point_correction = 1

            if dmrl_prec > 0 and cur_prec_value > 0:
                temp_k_point_correction = cur_prec_value / dmrl_prec

                if self.k_point_correction == 1 and self.k_count_point_correction == 0:
                    self.k_count_point_correction = 1
                    self.k_math_waiting = temp_k_point_correction
                    self.k_dispersion = 0
                    self.k_point_correction = temp_k_point_correction
                else:
                    new_count = self.k_count_point_correction + 1                       # Новое количество успешных попыток

                    mval1 = self.k_math_waiting * self.k_count_point_correction         # сумма всех старых значений
                    mval2 = mval1 + self.k_point_correction                             # новая сумма значеий
                    mval3 = mval2 / new_count                                           # Новое среднее (матожидание)

                    dval1 = (self.k_dispersion ** 2) * self.k_count_point_correction    # сумма всех квадратов дельт старых
                    dval2 = (mval3 - temp_k_point_correction) ** 2                      # новый квадрат дельты
                    dval4 = (dval1 + dval2) / new_count                                 # общая сумма к общему кол-ву новая
                    dval5 = dval4 ** 0.5                                                # новое среднеквадратичное отклонение (типа дисперсия)

                    cval1 = temp_k_point_correction - mval3                             # новое отклонение с учетом данной попытки

                    # Проверка на 3 сигмы
                    if abs(cval1) > abs(dval5) * 3.0:
                        temp_k_point_correction = mval3 + abs(dval5) * 3.0 * np.sign(cval1)

                self.k_point_correction = temp_k_point_correction

            ####################################################################

        sum_squere = 0.0
        vol_water = 0.0
        pixel_counter = 0.0
        for yy in matrix:
            for xx in yy:
                lm_value = xx[0]
                m_prec = self.GetPrecByDBZ(lm_value) / 6.0

                vol_local = self.pixel_size * self.pixel_size * (1.0/1000.0) * m_prec * self.k_point_correction
                vol_water = vol_water + vol_local

                if vol_local > 0.0:
                    sum_squere = sum_squere + 1.0
                    pixel_counter += 1.0

        sum_squere = sum_squere * self.pixel_size * self.pixel_size

        result = dict(time = cur_datetime.__str__(),
            water_volume = vol_water,
            prec_square = sum_squere,
            all_square = self.squere)

        self.SetNewReservKoefficient(cur_prec_value, vol_water)

        return json.dumps(result)
########################################################################