public void TestToString()
        {
            DateTime    date       = DateTime.UtcNow;
            var         dateString = date.ToString("yyyyMMdd HH:00");
            NamTableRow row        = new NamTableRow(date, date, new Tuple <double, double>(1.0, 2.0));

            row.APCPStepSize      = 1;
            row.APCPSurface       = 1.0;
            row.CRAINSurface      = 1;
            row.CSNOWSurface      = 1;
            row.RH2mAboveGround   = 1.0;
            row.TMP2mAboveGround  = 1.0;
            row.TMP80mAboveGround = 1.0;
            row.TMPSurface        = 1.0;
            row.TMPTrop           = 1.0;
            row.UGRD10m           = 1.0;
            row.UGRD80m           = 1.0;
            row.UGRDTrop          = 1.0;
            row.VGRD10m           = 1.0;
            row.VGRD80m           = 1.0;
            row.VGRDTrop          = 1.0;
            var s         = row.ToString();
            var substring = s.Split(',');

            Assert.AreEqual(substring.Length, 18);
            Assert.AreEqual(substring[0], dateString, "Date string incorrect format");
        }
Example #2
0
        /// <summary>
        /// From a grib file decode it in to an object representing a row in our output file
        /// </summary>
        /// <param name="file">GribFile</param>
        /// <returns>List of rows</returns>
        public static List <NamTableRow> ParseNamGribFile(GribFile file)
        {
            var      Rows    = new List <GribRow>();
            DateTime?refTime = null;

            foreach (GribMessage msg in file)
            {
                var tmpTime = msg.Time;
                //Total precip is a time step value so make sure the time we get is at the end of the period
                //hour 0 is always 0 because of this; but some forecasts have more than one hours between steps
                //so make sure we enable this
                var stepSize = 0;
                if (msg.ParameterName == "Total precipitation")
                {
                    int endStep   = 0;
                    int startStep = 0;
                    var success   = Int32.TryParse(msg.StartStep, out startStep);
                    if (!success)
                    {
                        throw new Exception($"Unable to parse start step variable: {msg.StartStep} from grib file");
                    }

                    /*
                     * if(startStep != 0)
                     * {
                     *  //some forecasts have sub intervals, ignore these
                     *  //if we start using forecasts other than the one produced at time 00 then we might need to modify this to account for different start steps
                     *  continue;
                     * }
                     */
                    success = Int32.TryParse(msg.EndStep, out endStep);
                    if (!success)
                    {
                        throw new Exception($"Unable to parse end step variable: {msg.EndStep} from grib file");
                    }
                    stepSize = endStep - startStep;
                    tmpTime  = tmpTime.AddHours(stepSize);
                }

                foreach (var val in msg.GridCoordinateValues)
                {
                    if (val.IsMissing)
                    {
                        continue;
                    }
                    //Console.WriteLine("Lat: {0} Lon: {1} Name: {2} Time: {3} Level: {4} Val: {5}", val.Latitude, val.Longitude, msg.ParameterName, msg.Time, msg.Level, val.Value);
                    double lat = Math.Round(val.Latitude, 6, MidpointRounding.AwayFromZero);
                    double lon = Math.Round(-(360.0 - val.Longitude), 6, MidpointRounding.AwayFromZero);
                    refTime = msg.ReferenceTime;

                    Rows.Add(new GribRow
                    {
                        Lat           = lat,
                        Lon           = lon,
                        ParameterName = msg.ParameterName,
                        //ParameterShortName = msg.ParameterShortName, //accessing this is very slow; only add it if we need it
                        Time          = tmpTime,
                        ReferenceTime = msg.ReferenceTime,
                        Level         = msg.Level,
                        TypeOfLevel   = msg.TypeOfLevel,
                        StepSize      = stepSize,
                        Value         = val.Value
                    });
                }
            }
            var rowLookup = Rows.ToLookup(r => new Tuple <double, double, DateTime>(r.Lat, r.Lon, r.Time));
            var namTable  = new List <NamTableRow>();

            foreach (var key in rowLookup)
            {
                if (refTime == null)
                {
                    throw new InvalidDataException("refTime is null and should be a valid datetime");
                }
                var newRow = new NamTableRow(key.Key.Item3, refTime.Value, new Tuple <double, double>(key.Key.Item1, key.Key.Item2));

                foreach (var column in key)
                {
                    if (column.TypeOfLevel == "surface" || column.TypeOfLevel == "heightAboveGround")
                    {
                        if (column.Level == 0)
                        {
                            if (column.ParameterName == "Total precipitation")
                            {
                                newRow.APCPSurface  = column.Value;
                                newRow.APCPStepSize = column.StepSize;
                                continue;
                            }
                            else if (column.ParameterName == "195")
                            {
                                newRow.CSNOWSurface = (int)column.Value;
                                continue;
                            }
                            else if (column.ParameterName == "192")
                            {
                                newRow.CRAINSurface = (int)column.Value;
                                continue;
                            }
                            else if (column.ParameterName == "Temperature")
                            {
                                newRow.TMPSurface = column.Value;
                                continue;
                            }
                        }
                        else if (column.Level == 2)
                        {
                            if (column.ParameterName == "Temperature")
                            {
                                newRow.TMP2mAboveGround = column.Value;
                                continue;
                            }
                            if (column.ParameterName == "Relative humidity")
                            {
                                newRow.RH2mAboveGround = column.Value;
                                continue;
                            }
                        }
                        else if (column.Level == 10)
                        {
                            if (column.ParameterName == "u-component of wind")
                            {
                                newRow.UGRD10m = column.Value;
                                continue;
                            }
                            else if (column.ParameterName == "v-component of wind")
                            {
                                newRow.VGRD10m = column.Value;
                                continue;
                            }
                        }
                        else if (column.Level == 80)
                        {
                            if (column.ParameterName == "Temperature")
                            {
                                newRow.TMP80mAboveGround = column.Value;
                                continue;
                            }
                            else if (column.ParameterName == "u-component of wind")
                            {
                                newRow.UGRD80m = column.Value;
                                continue;
                            }
                            else if (column.ParameterName == "v-component of wind")
                            {
                                newRow.VGRD80m = column.Value;
                                continue;
                            }
                        }
                    }
                    else if (column.TypeOfLevel == "tropopause")
                    {
                        if (column.ParameterName == "Temperature")
                        {
                            newRow.TMPTrop = column.Value;
                            continue;
                        }
                        else if (column.ParameterName == "u-component of wind")
                        {
                            newRow.UGRDTrop = column.Value;
                            continue;
                        }
                        else if (column.ParameterName == "v-component of wind")
                        {
                            newRow.VGRDTrop = column.Value;
                            continue;
                        }
                    }
                    throw new NotSupportedException($"unknown parameter level: {column.Level} name: {column.ParameterName}");
                }
                namTable.Add(newRow);
            }

            return(namTable);
        }