Python Forum

Full Version: Parsing Date/Time from Metar Reports with 6 hourly weather information
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am trying to create a parsing function that will generate the Date and Time of METAR reports which contain 6 hourly weather information. Based on the research I have done, I have found a parsing function that will do what I am trying to accomplish:
import pandas as pd
import numpy as np
import seaborn as sns
import DateTime

Training_METAR = pd.read_csv("KBOS Boston Training Metar Data.csv")
Test_METAR = pd.read_csv("KBOS Test METAR Data.csv")

np.random.seed(0)

# print(Training_METAR['valid'].head())

Training_METAR["Dates_Needed"] = pd.to_datetime(Training_METAR["valid"], format="%m/%d/%Y %H:%M")

print(Training_METAR["Dates_Needed"].head())
While I am sure that this is the parsing function that I need, I am somewhat unsure where I can implement this function into my METAR parsing code. I have tried this function in multiple sections of the METAR parsing code (separate copies to ensure the original stays intact), but I am unsure where I can place it within the code that would allow for the proper parsing of the Dates and times for the reports I need.

For clarity, the METAR parsing code is the following:
import os
import pathlib  # get your own relative path
import pandas as pd
from lazyme.string import color_print
import csv  # included in python 3.8.2 install
import numpy as np
import tkinter as tk
from tkinter import filedialog
import seaborn as sns
import datetime
count = 1


# this is an example string from the decoder doc with added fields
# exampleData = "METAR KABC 121755Z AUTO 21016G24KT 180V240 1SM R11/P6000FT -RA " \
#                  "BR BKN015 OVC025 06/04 A2990 RMK AO2 PK WND 20032/25 WSHFT 1715 " \
#                  "VIS 3/4V1 1/2 VIS 3/4 RWY11 RAB07 CIG 013V017 CIG 017 RWY11 " \
#                  "PRESFR SLP125 P0003 60009 70015 T00640036 10066 21012 400461006 " \
#                  "58033 TSNO $"

class MetarDataObj(object):
    """ A Metar Object contains only the data that is decoded from a single
        metar string.
    """
    """ The contents of the example data and their field labels
     METAR               - TYPE OF REPORT
     KABC                - STATION IDENTIFIER
     121755Z             - DATE/TIME
     AUTO                - REPORT MODIFIER
     21016G24KT 180V240  - WIND DIRECTION AND SPEED
     1SM                 - VISIBILITY
     R11/P6000FT         - RUNWAY VISUAL RANGE
     -RA BR              - WEATHER PHENOMENA
     BKN015 OVC025       - SKY CONDITION
     06/04               - TEMPERATURE/DEW POINT
     A2990               - ALTIMETER
     RMK                 - REMARK
                         - TORNADIC ACTIVITY
     AO2                 - TYPE OF AUTOMATED STATION
     PK WND 20032/25     - PEAK WIND
     WSHFT 1715          - WIND SHIFT
                         - TOWER OR SURFACE VISIBILITY
     VIS 3/4V1 1/2       - VARIABLE PREVAILING VISIBILITY
     VIS 3/4 RWY11       - VISIBILITY AT SECOND LOCATION
                         - LIGHTNING
     RAB07               - BEGINNING AND ENDING OF PRECIPITATION AND THUNDERSTORM
     CIG 013V017         - VIRGA
     CIG 017 RWY11       - VARIABLE CEILING HEIGHT
     PRESFR              - PRESSURE RISING OR FALLING RAPIDLY
     SLP125              - SEA-LEVEL PRESSURE
     P0003               - HOURLY PRECIPITATION AMOUNT
     60009               - 3- AND 6-HOUR PRECIPITATION AMOUNT    ** want this
                         - 24-HOUR PRECIPITATION AMOUNT  ** want this
     T00640036           - HOURLY TEMPERATURE AND DEW POINT
     10066               - 6-HOUR MAXIMUM TEMPERATURE    ** want this
     21012               - 6-HOUR MINIMUM TEMPERATURE    ** want this
                         - 24-HOUR MAXIMUM AND MINIMUM TEMPERATURE   ** want this
     58033               - PRESSURE TENDENCY
     TSNO                - SENSOR STATUS INDICATORS
     $                   - MAINTENANCE CHECK INDICATOR
     """

    # class constructor
    def __init__(self, metarString):
        # class local variables, initialized to nothing
        self.precip6 = None
        self.temp6max = None
        self.temp6min = None
        self.time = None
        # call function to parse data, pass string from constructor
        # handle empty construction
        if metarString != None:
            self.parseCSVdata(metarString)


    # process metar data
    def parseCSVdata(self, aString):
        """ Here we will parse the metar string passed into the default
            constructor.
        """

        # the field named 'SEA-LEVEL PRESSURE' is the stake in the ground.
        # stripping off everything before this field, packing into a list
        tinyMetar = aString[aString.find("SLP"): -1].split()
        # remove the stake

        # color_print('\tSpreadsheet row' + str(count) + '\n', color="red")
        # an empty list looks like []
        # handling the case where a row does not have a stake in the ground
        if len(tinyMetar) != 0:
            # Loop over contents looking for data, skipping over the stake
            for metarField in tinyMetar:
                # look for 6 hour precip
                if metarField[0] == "6" and len(metarField) == 5:
                    # get the 6 hour
                    if metarField[1:] == "////":
                        self.precip6 = None
                    else:
                        self.precip6 = float(metarField[3:]) * .01

                elif metarField[0] == "T" and len(metarField) == 9:
                    continue

                # look for 6 hour max
                elif metarField[0] == "1" and len(metarField) == 5:
                    # custom exception handling
                    # try to catch improper field
                    if metarField[1:] == "////":
                        self.temp6max = None
                    else:
                        try:
                            float(metarField)  # try to do this but don't die if
                            # fails
                            t6minSign = None
                            # get the sign of max
                            if metarField[1] == "0":
                                # positive temp
                                t6minSign = ""
                            else:
                                # negative temp
                                t6minSign = "-"
                            # get 6 hr max
                            self.temp6max = float(
                                t6minSign + metarField[2] + "." + metarField[3:])

                        except ValueError:  # if it fails come down here and do this
                            continue
                    # look for 6 hour min
                elif metarField[0] == "2" and len(metarField) == 5:

                    t6minSign = None
                    # get the sign of min
                    if metarField[1:] == "////":
                        self.temp6min = None
                    else:
                        if metarField[1] == "0":
                            # positive temp
                            t6minSign = ""
                        else:
                            # negative temp
                            t6minSign = "-"
                        # get 6 hr min
                        self.temp6min = float(t6minSign + metarField[2] + "." + metarField[3:])


        # color_print("\trow skipped", color="yellow")