<commit_before># Class library for the NWN Baron format
#  OO is fun!
#  <NAME> 16 May 2003
# 18 Nov 2003    Fix a very stupid error in parseLineRT :(
#  5 Jan 2004    Forgot what a pleasure temperatures below zero are.  For 
#        whatever reason, the values from some KELO sites are reported
#        differently "0-5F".  This is not good
# 21 Oct 2004    Support wind averaging

# A 058  09:23 05/16/03 ESE 08MPH 050K 460F 057F 088% 30.02R 00.01"D 02.79"M 00.00"R
# H 025   Max  05/16/03 SE  08MPH 057K 460F 057F 100% 30.04" 00.00"D 03.55"M 00.00"R
# K 072   Min  05/16/03 NE  00MPH 000K 075F 048F 083% 30.02" 00.00"D 02.53"M 00.00"R

import datetime
import pytz
import re
import math
import pyiem.reference as reference
import traceback
import pyiem.util as util


def uv(sped, drct2):
    dirr = drct2 * math.pi / 180.00
    s = math.sin(dirr)
    c = math.cos(dirr)
    u = round(- sped * s, 2)
    v = round(- sped * c, 2)
    return u, v


def dwpf(tmpf, relh):
    """
    Compute the dewpoint in F given a temperature and relative humidity
    """
    if tmpf is None or relh is None:
        return None

    tmpk = 273.15 + ( 5.00/9.00 * ( tmpf - 32.00) )
    dwpk = tmpk / (1+ 0.000425 * tmpk * -(math.log10(relh/100.0)) )
    return int(float( ( dwpk - 273.15 ) * 9.00/5.00 + 32 ))


def mydir(u, v):
    if (v == 0):
        v = 0.000000001
    dd = math.atan(u / v)
    ddir = (dd * 180.00) / math.pi

    if (u > 0 and v > 0):
        ddir = 180 + ddir
    elif (u > 0 and v < 0):
        ddir = 360 + ddir
    elif (u < 0 and v < 0):
        ddir = ddir
    elif (u < 0 and v > 0):
        ddir = 180 + ddir

    return int(math.fabs(ddir))


def feelslike(tmpf, relh, sped):
    if (tmpf > 50):
        return heatidx(tmpf, relh)
    else:
        return wchtidx(tmpf, sped)


def heatidx(tmpf, relh):
    if tmpf < 70:
      return tmpf
    if (tmpf > 140):
      return -99
    if (relh == 0):
      return -99

    PR_HEAT =  61 + ( tmpf - 68 ) * 1.2 + relh * .094
    if (PR_HEAT < 77):
      return PR_HEAT

    t2 = tmpf * tmpf;
    t3 = tmpf * tmpf * tmpf
    r2 = relh * relh
    r3 = relh * relh * relh

    return (17.423 + 0.185212 * tmpf
            + 5.37941 * relh
            - 0.100254 * tmpf * relh
            +  0.00941695 * t2
            +  0.00728898 * r2
            +  0.000345372 * t2 * relh
            -  0.000814971 * tmpf * r2
            +  0.0000102102 * t2 * r2
            -  0.000038646 * t3
            +  0.0000291583 * r3
            +  0.00000142721 * t3 * relh
            +  0.000000197483 * tmpf * r3
            -  0.0000000218429 * t3 * r2
            +  0.000000000843296  * t2 * r3
            -  0.0000000000481975  * t3 * r3)


def wchtidx(tmpf, sped):
    if sped < 3 or tmpf > 50:
        return tmpf
    import math
    wci = math.pow(sped,0.16);

    return 35.74 + .6215 * tmpf - 35.75 * wci + .4275 * tmpf * wci


class nwnformat:

    def __init__(self, do_avg_winds=True):
        self.error = 0
        self.do_avg_winds = do_avg_winds

        self.sid = None
        self.ts = None
        self.avg_sknt = None
        self.avg_drct = None
        self.drct = None
        self.drctTxt = None
        self.avg_drctTxt = None
        self.sped = None
        self.rad = 0
        self.insideTemp = 460
        self.tmpf = None
        self.humid = None
        self.pres = None
        self.presTend = None
        self.pDay = 0.00
        self.pMonth = 0.00
        self.pRate = 0.00
        self.dwpf = None
        self.feel = None

        self.nhumid = 0
        self.xhumid = 0

        self.npres = 0
        self.xpres = 0

        self.xtmpf = None
        self.ntmpf = None
        self.xsped = None
        self.xdrct = None
        self.xdrctTxt = None
        self.xsrad = None

        self.strMaxLine = None
        self.strMinLine = None

        self.aSknt = []
        self.aDrct = []

    def setTS(self, newval):
        try:
            self.ts = datetime.datetime.strptime(newval, "%m/%d/%y %H:%M:%S")
        except:
            traceback.print_exc()
            self.error = 100
            return
        now = datetime.datetime.now()
        if (now - self.ts) > 7200:
            self.error = 101

    def avgWinds(self):
        if (len(self.aSknt) == 0):
            self.sped = None
            self.drct = None
            return

        self.avg_sknt = int(float(sum(self.aSknt)) / float(len(self.aSknt)))
        utot = 0
        vtot = 0
        for i in range(len(self.aSknt)):
            u, v = uv(self.aSknt[i], self.aDrct[i])
            if (self.aSknt[i] > self.xsped):
                self.xsped = self.aSknt[i] * 1.150
                self.xdrct = self.aDrct[i]
                self.xdrctTxt = util.drct2text(self.aDrct[i])

            utot += u
            vtot += v
        uavg = utot / len(self.aSknt)
        vavg = vtot / len(self.aSknt)
        self.avg_drct = mydir(uavg, vavg)
        self.avg_drctTxt = util.drct2text(self.avg_drct)

        self.aSknt = []
        self.aDrct = []

    def parseLineRT(self, tokens):
        if self.ts is None:<commit_msg>fix nwnformat latency comparison, this is python2.7<commit_after># Class library for the NWN Baron format
#  OO is fun!
#  <NAME> 16 May 2003
# 18 Nov 2003    Fix a very stupid error in parseLineRT :(
#  5 Jan 2004    Forgot what a pleasure temperatures below zero are.  For 
#        whatever reason, the values from some KELO sites are reported
#        differently "0-5F".  This is not good
# 21 Oct 2004    Support wind averaging

# A 058  09:23 05/16/03 ESE 08MPH 050K 460F 057F 088% 30.02R 00.01"D 02.79"M 00.00"R
# H 025   Max  05/16/03 SE  08MPH 057K 460F 057F 100% 30.04" 00.00"D 03.55"M 00.00"R
# K 072   Min  05/16/03 NE  00MPH 000K 075F 048F 083% 30.02" 00.00"D 02.53"M 00.00"R

import datetime
import pytz
import re
import math
import pyiem.reference as reference
import traceback
import pyiem.util as util


def uv(sped, drct2):
    dirr = drct2 * math.pi / 180.00
    s = math.sin(dirr)
    c = math.cos(dirr)
    u = round(- sped * s, 2)
    v = round(- sped * c, 2)
    return u, v


def dwpf(tmpf, relh):
    """
    Compute the dewpoint in F given a temperature and relative humidity
    """
    if tmpf is None or relh is None:
        return None

    tmpk = 273.15 + ( 5.00/9.00 * ( tmpf - 32.00) )
    dwpk = tmpk / (1+ 0.000425 * tmpk * -(math.log10(relh/100.0)) )
    return int(float( ( dwpk - 273.15 ) * 9.00/5.00 + 32 ))


def mydir(u, v):
    if (v == 0):
        v = 0.000000001
    dd = math.atan(u / v)
    ddir = (dd * 180.00) / math.pi

    if (u > 0 and v > 0):
        ddir = 180 + ddir
    elif (u > 0 and v < 0):
        ddir = 360 + ddir
    elif (u < 0 and v < 0):
        ddir = ddir
    elif (u < 0 and v > 0):
        ddir = 180 + ddir

    return int(math.fabs(ddir))


def feelslike(tmpf, relh, sped):
    if (tmpf > 50):
        return heatidx(tmpf, relh)
    else:
        return wchtidx(tmpf, sped)


def heatidx(tmpf, relh):
    if tmpf < 70:
      return tmpf
    if (tmpf > 140):
      return -99
    if (relh == 0):
      return -99

    PR_HEAT =  61 + ( tmpf - 68 ) * 1.2 + relh * .094
    if (PR_HEAT < 77):
      return PR_HEAT

    t2 = tmpf * tmpf;
    t3 = tmpf * tmpf * tmpf
    r2 = relh * relh
    r3 = relh * relh * relh

    return (17.423 + 0.185212 * tmpf
            + 5.37941 * relh
            - 0.100254 * tmpf * relh
            +  0.00941695 * t2
            +  0.00728898 * r2
            +  0.000345372 * t2 * relh
            -  0.000814971 * tmpf * r2
            +  0.0000102102 * t2 * r2
            -  0.000038646 * t3
            +  0.0000291583 * r3
            +  0.00000142721 * t3 * relh
            +  0.000000197483 * tmpf * r3
            -  0.0000000218429 * t3 * r2
            +  0.000000000843296  * t2 * r3
            -  0.0000000000481975  * t3 * r3)


def wchtidx(tmpf, sped):
    if sped < 3 or tmpf > 50:
        return tmpf
    import math
    wci = math.pow(sped,0.16);

    return 35.74 + .6215 * tmpf - 35.75 * wci + .4275 * tmpf * wci


class nwnformat:

    def __init__(self, do_avg_winds=True):
        self.error = 0
        self.do_avg_winds = do_avg_winds

        self.sid = None
        self.ts = None
        self.avg_sknt = None
        self.avg_drct = None
        self.drct = None
        self.drctTxt = None
        self.avg_drctTxt = None
        self.sped = None
        self.rad = 0
        self.insideTemp = 460
        self.tmpf = None
        self.humid = None
        self.pres = None
        self.presTend = None
        self.pDay = 0.00
        self.pMonth = 0.00
        self.pRate = 0.00
        self.dwpf = None
        self.feel = None

        self.nhumid = 0
        self.xhumid = 0

        self.npres = 0
        self.xpres = 0

        self.xtmpf = None
        self.ntmpf = None
        self.xsped = None
        self.xdrct = None
        self.xdrctTxt = None
        self.xsrad = None

        self.strMaxLine = None
        self.strMinLine = None

        self.aSknt = []
        self.aDrct = []

    def setTS(self, newval):
        try:
            self.ts = datetime.datetime.strptime(newval, "%m/%d/%y %H:%M:%S")
        except:
            traceback.print_exc()
            self.error = 100
            return
        now = datetime.datetime.now()
        if (now - self.ts).total_seconds() > 7200:
            self.error = 101

    def avgWinds(self):
        if (len(self.aSknt) == 0):
            self.sped = None
            self.drct = None
            return

        self.avg_sknt = int(float(sum(self.aSknt)) / float(len(self.aSknt)))
        utot = 0
        vtot = 0
        for i in range(len(self.aSknt)):
            u, v = uv(self.aSknt[i], self.aDrct[i])
            if (self.aSknt[i] > self.xsped):
                self.xsped = self.aSknt[i] * 1.150
                self.xdrct = self.aDrct[i]
                self.xdrctTxt = util.drct2text(self.aDrct[i])

            utot += u
            vtot += v
        uavg = utot / len(self.aSknt)
        vavg = vtot / len(self.aSknt)
        self.avg_drct = mydir(uavg, vavg)
        self.avg_drctTxt = util.drct2text(self.avg_drct)

        self.aSknt = []
        self.aDrct = []

    def parseLineRT(self, tokens):
        if self.ts is None:
{'fraction_non_alphanumeric': 0.11383623216728551, 'fraction_numerical': 0.09771350400625367, 'mean_word_length': 1.5555555555555556, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3579749', 'n_tokens_mistral': 4620, 'n_tokens_neox': 3866, 'n_words': 1029}