Beispiel #1
0
 def test_reused(self):
     # Observations from file1 should be reused in file1_no_obs
     inputs = [
         verif.input.Text("verif/tests/files/file1.txt"),
         verif.input.Text("verif/tests/files/file1_no_obs.txt")
     ]
     data = verif.data.Data(inputs)
     obs0 = data.get_scores(verif.field.Obs(), 0)
     obs1 = data.get_scores(verif.field.Obs(), 1)
     np.testing.assert_array_equal(obs0, obs1)
Beispiel #2
0
 def test_order(self):
    # Check that the order of leadtimes in the file does not matter
    input1 = verif.input.Text("verif/tests/files/file_order1.txt")
    input2 = verif.input.Text("verif/tests/files/file_order2.txt")
    data = verif.data.Data([input1, input2])
    np.testing.assert_array_equal(np.sort(input1.leadtimes), np.sort(input2.leadtimes))
    np.testing.assert_array_equal(np.sort(data.leadtimes), [0, 6, 12])
    s1 = data.get_scores(verif.field.Fcst(), 0)
    s2 = data.get_scores(verif.field.Fcst(), 1)
    np.testing.assert_array_equal(s1, s2)
Beispiel #3
0
 def test_different_missing(self):
     # The two files are identical, other than some obs and fcst are missing for different times
     # The obs and fcst arrays after retriving through data should be the same
     inputs = [
         verif.input.Text("verif/tests/files/file1.txt"),
         verif.input.Text("verif/tests/files/file1_different_missing.txt")
     ]
     data = verif.data.Data(inputs)
     fields = [verif.field.Obs(), verif.field.Fcst()]
     obs0, fcst0 = data.get_scores(fields, 0)
     obs1, fcst1 = data.get_scores(fields, 1)
     np.testing.assert_array_equal(obs0, obs1)
     np.testing.assert_array_equal(fcst0, fcst1)
Beispiel #4
0
    def test_simple(self):
        inputs = [
            verif.input.get_input(filename) for filename in
            ["verif/tests/files/file1.txt", "verif/tests/files/file2.txt"]
        ]
        data = verif.data.Data(inputs=inputs)
        lats = [loc.lat for loc in data.locations]
        self.assertTrue(len(lats) == 1)
        self.assertTrue(lats[0] == 42)
        lons = [loc.lon for loc in data.locations]
        self.assertTrue(len(lons) == 1)
        self.assertTrue(lons[0] == 23)

        leadtimes = data.leadtimes
        self.assertEqual(2, leadtimes.shape[0])
        self.assertEqual(0, leadtimes[0])
        self.assertEqual(12, leadtimes[1])

        times = data.times
        self.assertEqual(3, times.shape[0])
        # 20120101: Common leadtimes: 0 and 12, locations 41
        fields = [verif.field.Obs(), verif.field.Fcst()]
        axis = verif.axis.Time()

        [obs, fcst] = data.get_scores(fields, 0, axis, 0)
        self.assertEqual(5, fcst[0])  # Offset 0
        self.assertEqual(7, fcst[1])  # Offset 12
        self.assertEqual(-1, obs[0])
        self.assertEqual(2, obs[1])
        # 20120102: (missing obs at leadtime 12)
        [obs, fcst] = data.get_scores(fields, 0, axis, 1)
        self.assertEqual(1, fcst.shape[0])
        self.assertEqual(6, fcst[0])
        self.assertEqual(1, obs[0])

        # 20120101
        [obs, fcst] = data.get_scores(fields, 1, axis, 0)
        self.assertEqual(0, fcst[0])  # Offset 0
        self.assertEqual(1, fcst[1])  # Offset 12
        self.assertEqual(-1, obs[0])
        self.assertEqual(2, obs[1])
        # 20120102
        [obs, fcst] = data.get_scores(fields, 1, axis, 1)
        self.assertEqual(1, fcst.shape[0])
        self.assertEqual(5, fcst[0])
        self.assertEqual(1, obs[0])
Beispiel #5
0
    def test_repeated_times_two_files(self):
        inputs = [
            verif.input.get_input("verif/tests/files/netcdf_repeated_%s.nc" %
                                  name) for name in ["times", "leadtimes"]
        ]
        data = verif.data.Data(inputs=inputs)
        self.assertEqual(2, len(data.times))
        self.assertEqual(2, len(data.leadtimes))
        self.assertEqual(1, len(data.locations))

        fcst = data.get_scores([verif.field.Fcst()], 0, verif.axis.All())[0]
        np.testing.assert_array_equal(np.array([[11, 12], [14, 15]]),
                                      fcst[:, :, 0])

        fcst = data.get_scores([verif.field.Fcst()], 1, verif.axis.All())[0]
        np.testing.assert_array_equal(np.array([[11, 12], [14, 15]]),
                                      fcst[:, :, 0])
Beispiel #6
0
    def test_repeated_times(self):
        inputs = [
            verif.input.get_input("verif/tests/files/netcdf_repeated_times.nc")
        ]
        data = verif.data.Data(inputs=inputs)
        self.assertEqual(2, len(data.times))
        self.assertEqual(3, len(data.leadtimes))
        self.assertEqual(1, len(data.locations))

        # Check that we only have two times
        obs = data.get_scores([verif.field.Obs()], 0, verif.axis.All())[0]
        np.testing.assert_array_equal(np.array([[1, 2, 3], [4, 5, 6]]),
                                      obs[:, :, 0])

        # Check that subset of times works
        data = verif.data.Data(inputs=inputs, times=inputs[0].times[[0, 2]])
        obs = data.get_scores([verif.field.Obs()], 0, verif.axis.All(), 0)[0]
        np.testing.assert_array_equal(np.array([[1, 2, 3]]), obs[:, :, 0])
Beispiel #7
0
    def test_dayofyear(self):
        inputs = [verif.input.get_input("verif/tests/files/file1.txt")]
        data = verif.data.Data(inputs=inputs)
        axis = verif.axis.Dayofyear()
        axis_values = data.get_axis_values(axis)
        self.assertEqual(3, len(axis_values))
        self.assertEqual(1, axis_values[0])
        self.assertEqual(2, axis_values[1])
        self.assertEqual(3, axis_values[2])

        # All the values for day 1
        values = data.get_scores([verif.field.Fcst()], 0, axis, 0)[0]
        self.assertEqual(6, len(values))
        assert_set_equal(np.array([6, 7, 7, 5, 4, 7]), values)

        values = data.get_scores([verif.field.Fcst()], 0, axis, 2)[0]
        self.assertEqual(5, len(values))
        assert_set_equal(np.array([-4, 3, 9, 12, 16]), values)
Beispiel #8
0
   def test_missing_values(self):
      # Check NA, na, nan are detected
      input = verif.input.Text("verif/tests/files/file_missing_values.txt")
      data = verif.data.Data([input])
      obs = data.get_scores(verif.field.Obs(), 0)
      fcst = data.get_scores(verif.field.Fcst(), 0)
      self.assertEqual(len(data.locations), 1)

      self.assertEqual(obs[0, 0, 0], 3)
      self.assertEqual(fcst[0, 0, 0], 6)

      self.assertTrue(np.isnan(obs[0, 2, 0]))
      self.assertEqual(fcst[0, 2, 0], 7)

      self.assertEqual(obs[0, 3, 0], 3)
      self.assertTrue(np.isnan(fcst[0, 3, 0]))

      self.assertTrue(np.isnan(obs[0, 4, 0]))
      self.assertTrue(np.isnan(fcst[0, 4, 0]))
Beispiel #9
0
    def test_obsrange(self):
        inputs = [
            verif.input.Text("verif/tests/files/file1.txt"),
            verif.input.Text("verif/tests/files/file3.txt")
        ]
        data = verif.data.Data(inputs=inputs, obs_range=[0, 3.5])

        fields = [verif.field.Obs(), verif.field.Fcst()]
        axis = verif.axis.Time()

        [obs, fcst] = data.get_scores(fields, 0, axis, 0)
        self.assertEqual(6, fcst[0])  # Offset 0
        self.assertEqual(7, fcst[1])  # Offset 12
        self.assertEqual(3, obs[0])
        self.assertEqual(2, obs[1])
        # 20120102: (missing obs at leadtime 12)
        [obs, fcst] = data.get_scores(fields, 0, axis, 1)
        self.assertEqual(1, fcst.shape[0])
        self.assertEqual(6, fcst[0])
        self.assertEqual(1, obs[0])
Beispiel #10
0
    def test_repeated_leadtimes(self):
        inputs = [
            verif.input.get_input(
                "verif/tests/files/netcdf_repeated_leadtimes.nc")
        ]
        data = verif.data.Data(inputs=inputs)
        self.assertEqual(2, len(data.times))
        self.assertEqual(2, len(data.leadtimes))
        self.assertEqual(1, len(data.locations))

        obs = data.get_scores([verif.field.Obs()], 0, verif.axis.All())[0]
        np.testing.assert_array_equal(np.array([[1, 2], [4, 5]]), obs[:, :, 0])

        # Check that subset of locations works
        data = verif.data.Data(inputs=inputs,
                               leadtimes=inputs[0].leadtimes[[0, 2]])
        obs = data.get_scores([verif.field.Obs()], 0, verif.axis.All())[0]
        ar = np.zeros([2, 1])
        ar[0] = 1
        ar[1] = 4
        np.testing.assert_array_equal(ar, obs[:, :, 0])
Beispiel #11
0
    def test_repeated_locations(self):
        inputs = [
            verif.input.get_input(
                "verif/tests/files/netcdf_repeated_locations.nc")
        ]
        data = verif.data.Data(inputs=inputs)
        self.assertEqual(2, len(data.times))
        self.assertEqual(2, len(data.leadtimes))
        self.assertEqual(2, len(data.locations))

        obs = data.get_scores([verif.field.Obs()], 0, verif.axis.All())[0]
        self.assertEqual(2, obs.shape[2])
        np.testing.assert_array_equal(np.array([[1, 4], [7, 10]]), obs[:, :,
                                                                       0])
        np.testing.assert_array_equal(np.array([[2, 5], [8, 11]]), obs[:, :,
                                                                       1])

        # Check that intersections with locations work
        data = verif.data.Data(inputs=inputs, locations=[18700, 18700])
        obs = data.get_scores([verif.field.Obs()], 0, verif.axis.All())[0]
        self.assertEqual(1, obs.shape[2])
        np.testing.assert_array_equal(np.array([[1, 4], [7, 10]]), obs[:, :,
                                                                       0])
Beispiel #12
0
    def test_timeofday(self):
        inputs = [verif.input.Text("verif/tests/files/file4.txt")]
        data = verif.data.Data(inputs, tods=[6])
        self.assertEqual(2, len(data.times))
        self.assertEqual(1325397600, data.times[0])
        self.assertEqual(1325570400, data.times[1])

        # Check that data retrieved is of the correct size
        obs, fcst = data.get_scores([verif.field.Obs(), verif.field.Fcst()], 0)
        self.assertEqual(2, obs.shape[0])
        self.assertEqual(3, obs.shape[1])
        self.assertEqual(1, obs.shape[2])
        np.testing.assert_array_equal(np.array([[11, 4, 9], [3, 5, 6]]),
                                      obs[:, :, 0])
        np.testing.assert_array_equal(np.array([[6, 7, 7], [3, 1, 2]]),
                                      fcst[:, :, 0])

        data = verif.data.Data(inputs, tods=[0])
        self.assertEqual(3, len(data.times))
        self.assertEqual(1325376000, data.times[0])
        self.assertEqual(1325462400, data.times[1])
        self.assertEqual(1325548800, data.times[2])
Beispiel #13
0
def run(argv):
   ############
   # Defaults #
   ############
   ifiles = list()
   ofile = None
   metric = None
   locations = None
   locations_x = None
   lat_range = None
   lon_range = None
   elev_range = None
   obs_range = None
   thresholds = None
   quantiles = None
   clim_file = None
   clim_type = "subtract"
   leg = None
   ylabel = None
   xlabel = None
   clabel = None
   title = None
   dates = None
   tods = None
   times = None
   leadtimes = None
   axis = None
   aspect = None
   figsize = None
   dpi = 100
   no_margin = False
   bin_type = None
   simple = None
   marker_size = None
   line_width = None
   line_colors = None
   line_styles = None
   tick_font_size = None
   lab_font_size = None
   leg_font_size = None
   title_font_size = None
   leg_loc = None
   plot_type = "plot"
   grid = True
   xrot = None
   yrot = None
   bottom_padding = None
   top_padding = None
   right_padding = None
   left_padding = None
   Pad = None
   show_perfect = None
   aggregator_name = None
   do_hist = False
   do_sort = False
   do_acc = False
   proj = None
   xlim = None
   ylim = None
   clim = None
   annotate = False
   xticks = None
   xticklabels = None
   yticks = None
   yticklabels = None
   version = None
   list_thresholds = False
   list_quantiles = False
   list_locations = False
   list_times = False
   list_dates = False
   map_type = None
   xlog = False
   ylog = False
   cmap = None
   obs_field = verif.field.Obs()
   fcst_field = verif.field.Fcst()

   # Parse config files
   i = 1
   extra = []
   while(i < len(argv)):
      arg = argv[i]
      if arg == "--config":
         if i == len(argv) - 1:
            verif.util.error("Missing filename after --config")
         i = i + 1
         filename = argv[i]
         try:
            fid = open(filename, 'r')
            for line in fid:
               extra += line.split()
         except:
            if not os.path.isfile(filename):
               verif.util.error("Could not read %s" % filename)
      i = i + 1

   argv = argv + extra

   # Read command line arguments
   i = 1
   while(i < len(argv)):
      arg = argv[i]
      if arg[0] == '-':
         # Process option
         if arg == "-nomargin":
            no_margin = True
         elif arg == "--version":
            version = True
         elif arg == "--list-thresholds":
            list_thresholds = True
         elif arg == "--list-quantiles":
            list_quantiles = True
         elif arg == "--list-locations":
            list_locations = True
         elif arg == "--list-times":
            list_times = True
         elif arg == "--list-dates":
            list_dates = True
         elif arg == "-sp":
            show_perfect = True
         elif arg == "-hist":
            do_hist = True
         elif arg == "-acc":
            do_acc = True
         elif arg == "-sort":
            do_sort = True
         elif arg == "-simple":
            simple = True
         elif arg == "-xlog":
            xlog = True
         elif arg == "-ylog":
            ylog = True
         elif arg == "-a":
            annotate = True
         elif arg == "-nogrid":
            grid = False
         else:
            if len(argv) <= i + 1:
               verif.util.error("Missing value after %s" % argv[i])
            arg_next = argv[i + 1]
            if arg == "-f":
               ofile = arg_next
            elif arg == "-l":
               locations = verif.util.parse_numbers(arg_next)
            elif arg == "-lx":
               locations_x = verif.util.parse_numbers(arg_next)
            elif arg == "-latrange":
               lat_range = verif.util.parse_numbers(arg_next)
            elif arg == "-lonrange":
               lon_range = verif.util.parse_numbers(arg_next)
            elif arg == "-elevrange":
               elev_range = verif.util.parse_numbers(arg_next)
            elif arg == "-obsrange":
               obs_range = verif.util.parse_numbers(arg_next)
            elif arg == "-x":
               axisname = arg_next
               axis = verif.axis.get(axisname)
            elif arg == "-o":
               leadtimes = verif.util.parse_numbers(arg_next)
            elif arg == "-leg":
               leg = str(arg_next)
            elif arg == "-ylabel":
               ylabel = str(arg_next)
            elif arg == "-xlabel":
               xlabel = str(arg_next)
            elif arg == "-clabel":
               clabel = str(arg_next)
            elif arg == "-title":
               title = str(arg_next)
            elif arg == "-b":
               bin_type = arg_next
            elif arg == "-type":
               plot_type = arg_next
            elif arg == "-fs":
               figsize = arg_next
            elif arg == "-dpi":
               dpi = int(arg_next)
            elif arg == "-d":
               dates = verif.util.parse_numbers(arg_next, True)
            elif arg == "-tod":
               tods = [int(tod) for tod in verif.util.parse_numbers(arg_next)]
            elif arg == "-t":
               times = verif.util.parse_numbers(arg_next)
            elif arg == "-c":
               clim_file = verif.input.get_input(arg_next)
               clim_type = "subtract"
            elif arg == "-C":
               clim_file = verif.input.get_input(arg_next)
               clim_type = "divide"
            elif arg == "-xlim":
               xlim = verif.util.parse_numbers(arg_next)
            elif arg == "-ylim":
               ylim = verif.util.parse_numbers(arg_next)
            elif arg == "-clim":
               clim = verif.util.parse_numbers(arg_next)
            elif arg == "-xticks":
               xticks = verif.util.parse_numbers(arg_next)
            elif arg == "-xticklabels":
               xticklabels = (arg_next).split(',')
            elif arg == "-yticks":
               yticks = verif.util.parse_numbers(arg_next)
            elif arg == "-yticklabels":
               yticklabels = (arg_next).split(',')
            elif arg == "-agg":
               aggregator_name = arg_next
            elif arg == "-aspect":
               aspect = float(arg_next)
            elif arg == "-r":
               thresholds = np.array(verif.util.parse_numbers(arg_next))
            elif arg == "-q":
               quantiles = np.array(verif.util.parse_numbers(arg_next))
               if np.min(quantiles) < 0 or np.max(quantiles) > 1:
                  verif.util.error("Quantiles must be between 0 and 1 inclusive")
            elif arg == "-ms":
               marker_size = float(arg_next)
            elif arg == "-lw":
               line_width = float(arg_next)
            elif arg == "-lc":
               line_colors = arg_next
            elif arg == "-ls":
               line_styles = arg_next
            elif arg == "-tickfs":
               tick_font_size = float(arg_next)
            elif arg == "-labfs":
               lab_font_size = float(arg_next)
            elif arg == "-legfs":
               leg_font_size = float(arg_next)
            elif arg == "-legloc":
               leg_loc = arg_next.replace('_', ' ')
            elif arg == "-xrot":
               xrot = float(arg_next)
            elif arg == "-yrot":
               yrot = float(arg_next)
            elif arg == "-bottom":
               bottom_padding = float(arg_next)
            elif arg == "-top":
               top_padding = float(arg_next)
            elif arg == "-right":
               right_padding = float(arg_next)
            elif arg == "-left":
               left_padding = float(arg_next)
            elif arg == "-pad":
               Pad = arg_next
            elif arg == "-titlefs":
               title_font_size = float(arg_next)
            elif arg == "-cmap":
               cmap = arg_next
            elif arg == "-maptype":
               map_type = arg_next
            elif arg == "-proj":
               proj = arg_next
            elif arg == "-obs":
               obs_field = verif.field.get(arg_next)
            elif arg == "-fcst":
               fcst_field = verif.field.get(arg_next)
            elif arg == "-m":
               metric = arg_next
            elif arg == "--config":
               pass
            else:
               verif.util.error("Flag '" + argv[i] + "' not recognized")
            i = i + 1
      else:
         ifiles.append(argv[i])
      i = i + 1

   if version:
      print("Version: " + verif.version.__version__)
      return

   # Deal with legend entries
   if leg is not None:
      leg = leg.split(',')
      for i in range(0, len(leg)):
         leg[i] = leg[i].replace('_', ' ')

   if lat_range is not None and len(lat_range) != 2:
      verif.util.error("-latrange <values> must have exactly 2 values")

   if lon_range is not None and len(lon_range) != 2:
      verif.util.error("-lonrange <values> must have exactly 2 values")

   if elev_range is not None and len(elev_range) != 2:
      verif.util.error("-elevrange <values> must have exactly 2 values")

   if obs_range is not None and len(obs_range) != 2:
      verif.util.error("-obsrange <values> must have exactly 2 values")

   if len(ifiles) > 0:
      inputs = [verif.input.get_input(filename) for filename in ifiles]
      data = verif.data.Data(inputs, clim=clim_file, clim_type=clim_type,
            times=times, dates=dates, tods=tods, leadtimes=leadtimes, locations=locations,
            locations_x=locations_x,
            lat_range=lat_range, lon_range=lon_range, elev_range=elev_range,
            obs_range=obs_range, legend=leg, obs_field=obs_field, fcst_field=fcst_field)
   else:
      data = None

   if list_thresholds or list_quantiles or list_locations or list_times or list_dates:
      if len(ifiles) == 0:
         verif.util.error("Files are required in order to list thresholds, quantiles, or times")
      if list_thresholds:
         print("Thresholds:", end=' ')
         for threshold in data.thresholds:
            print("%g" % threshold, end=' ')
         print("")
      if list_quantiles:
         print("Quantiles:", end=' ')
         for quantile in data.quantiles:
            print("%g" % quantile, end=' ')
         print("")
      if list_locations:
         print("    id     lat     lon    elev")
         for location in data.locations:
            print("%6d %7.2f %7.2f %7.1f" % (location.id, location.lat,
                  location.lon, location.elev))
         print("")
      if list_times:
         for time in data.times:
            print("%d" % time)
         print("")
      if list_dates:
         for time in data.times:
            date = verif.util.unixtime_to_date(time)
            diff = time % 86400
            hour = diff / 3600
            minute = (diff % 3600)/60
            second = diff % 60
            print("%d %02d:%02d:%02d" % (date, hour, minute, second))
         print("")
      return
   elif len(ifiles) == 0 and metric is not None:
      m = verif.metric.get(metric)
      if m is not None:
         print(m.help())
      else:
         m = verif.output.get(metric)
         if m is not None:
            print(m.help())
      return
   elif len(argv) == 1 or len(ifiles) == 0 or metric is None:
      print(show_description(data))
      return

   if figsize is not None:
      figsize = figsize.split(',')
      if len(figsize) != 2:
         print("-fs figsize must be in the form: width,height")
         sys.exit(1)

   m = None

   # Handle special plots
   if metric == "pithist":
      pl = verif.output.PitHist()
   elif metric == "obsfcst":
      pl = verif.output.ObsFcst()
   elif metric == "timeseries":
      pl = verif.output.TimeSeries()
   elif metric == "meteo":
      pl = verif.output.Meteo()
   elif metric == "qq":
      pl = verif.output.QQ()
   elif metric == "autocorr":
      pl = verif.output.Auto("corr")
   elif metric == "autocov":
      pl = verif.output.Auto("cov")
   elif metric == "fss":
      pl = verif.output.Fss()
   elif metric == "cond":
      pl = verif.output.Cond()
   elif metric == "against":
      pl = verif.output.Against()
   elif metric == "scatter":
      pl = verif.output.Scatter()
   elif metric == "change":
      pl = verif.output.Change()
   elif metric == "spreadskill":
      pl = verif.output.SpreadSkill()
   elif metric == "taylor":
      pl = verif.output.Taylor()
   elif metric == "error":
      pl = verif.output.Error()
   elif metric == "freq":
      pl = verif.output.Freq()
   elif metric == "roc":
      pl = verif.output.Roc()
   elif metric == "droc":
      pl = verif.output.DRoc()
   elif metric == "droc0":
      pl = verif.output.DRoc0()
   elif metric == "drocnorm":
      pl = verif.output.DRocNorm()
   elif metric == "reliability":
      pl = verif.output.Reliability()
   elif metric == "discrimination":
      pl = verif.output.Discrimination()
   elif metric == "performance":
      pl = verif.output.Performance()
   elif metric == "invreliability":
      pl = verif.output.InvReliability()
   elif metric == "igncontrib":
      pl = verif.output.IgnContrib()
   elif metric == "economicvalue":
      pl = verif.output.EconomicValue()
   elif metric == "marginal":
      pl = verif.output.Marginal()
   else:
      # Standard plots
      # Attempt at automating
      m = verif.metric.get(metric)
      if m is None:
         m = verif.metric.FromField(verif.field.Other(metric))

      if aggregator_name is not None:
         if not m.supports_aggregator:
            verif.util.warning("-m %s does not support -agg" % metric)
         m.aggregator = verif.aggregator.get(aggregator_name)

      # Output type
      if plot_type in ["plot", "text", "csv", "map", "maprank", "rank", "impact", "mapimpact"]:
         if do_sort:
            field = verif.field.get(metric)
            pl = verif.output.Sort(field)
         elif do_hist:
            field = verif.field.get(metric)
            pl = verif.output.Hist(field)
         else:
            pl = verif.output.Standard(m)
      else:
         verif.util.error("Type not understood")

   # Rest dimension of '-x' is not allowed
   if axis is not None and not pl.supports_x:
      verif.util.warning("'-m %s'" % metric + " does not support '-x'. Ignoring it.")
      axis = None

   # Reset dimension if 'threshold' is not allowed
   if axis == verif.axis.Threshold() and ((not pl.supports_threshold) or (m is not None and not m.supports_threshold)):
      verif.util.warning("'-m %s'" % metric + " does not support '-x threshold'. Ignoring it.")
      thresholds = None
      axis = None
   # Reset dimension if 'obs' or 'fcst' is not allowed
   if axis in [verif.axis.Obs(), verif.axis.Fcst()] and ((not pl.supports_field) or (m is not None and not m.supports_field)):
      verif.util.warning("'-m %s'" % metric + " does not support '-x %s'. Ignoring it." % axis.name().lower())
      thresholds = None
      axis = None

   # Create thresholds if needed
   if thresholds is None:
      type = None
      if plot_type == "impact":
         type = "deterministic"
      elif pl.require_threshold_type == "deterministic":
         type = "deterministic"
      elif pl.require_threshold_type == "threshold":
         type = "threshold"
      elif pl.require_threshold_type == "quantile":
         type = "quantile"
      elif m is not None:
         if m.require_threshold_type == "deterministic":
            type = "deterministic"
         elif m.require_threshold_type == "threshold":
            type = "threshold"
         elif m.require_threshold_type == "quantile":
            type = "quantile"
         elif m.require_threshold_type is not None:
            verif.util.error("Internal error for metric %s: Cannot understand required threshold type '%s'" % (m.name(), m.require_threshold_type))
      elif pl.require_threshold_type is not None:
         verif.util.error("Internal error for output %s: Cannot understand required threshold type '%s'" % (pl.name(), pl.require_threshold_type))

      if type is not None:
         if type == "deterministic":
            smin = np.inf
            smax = -np.inf
            if verif.field.Obs() in data.get_fields():
               obs = data.get_scores(verif.field.Obs(), 0)
               smin = min(np.nanmin(obs), smin)
               smax = max(np.nanmax(obs), smax)
            if verif.field.Fcst() in data.get_fields():
               fcst = data.get_scores(verif.field.Fcst(), 0)
               smin = min(np.nanmin(fcst), smin)
               smax = max(np.nanmax(fcst), smax)
            num_default_thresholds = 20
            thresholds = np.linspace(smin, smax, num_default_thresholds)
            verif.util.warning("Missing '-r <thresholds>'. Automatically setting thresholds.")
         elif type == "threshold":
            thresholds = data.thresholds
            verif.util.warning("Missing '-r <thresholds>'. Automatically setting thresholds.")
         elif type == "quantile":
            thresholds = data.quantiles
            verif.util.warning("Missing '-r <thresholds>'. Automatically setting thresholds.")
         if len(thresholds) == 0:
            verif.util.error("No thresholds available")

   # Set plot parameters
   if simple is not None:
      pl.simple = simple
   if marker_size is not None:
      pl.ms = marker_size
   if line_width is not None:
      pl.lw = line_width
   if line_colors is not None:
      pl.line_colors = line_colors
   if line_styles is not None:
      pl.line_styles = line_styles
   if lab_font_size is not None:
      pl.labfs = lab_font_size
   if leg_font_size is not None:
      pl.legfs = leg_font_size
   if title_font_size is not None:
      pl.title_font_size = title_font_size
   if leg_loc is not None:
      pl.leg_loc = leg_loc
   if tick_font_size is not None:
      pl.tick_font_size = tick_font_size
   if xrot is not None:
      pl.xrot = xrot
   if yrot is not None:
      pl.yrot = yrot
   if bottom_padding is not None:
      pl.bottom = bottom_padding
   if top_padding is not None:
      pl.top = top_padding
   if right_padding is not None:
      pl.right = right_padding
   if left_padding is not None:
      pl.left = left_padding
   if Pad is not None:
      pl.pad = None
   if bin_type is not None:
      pl.bin_type = bin_type
   if show_perfect is not None:
      pl.show_perfect = show_perfect
   if proj is not None:
      pl.proj = proj
   if xlim is not None:
      pl.xlim = xlim
   if ylim is not None:
      pl.ylim = ylim
   if clim is not None:
      pl.clim = clim
   if xticks is not None:
      pl.xticks = xticks
   if xticklabels is not None:
      pl.xticklabels = xticklabels
   if yticks is not None:
      pl.yticks = yticks
   if yticklabels is not None:
      pl.yticklabels = yticklabels
   if xlog is not None:
      pl.xlog = xlog
   if ylog is not None:
      pl.ylog = ylog
   if annotate is not None:
      pl.annotate = annotate
   pl.grid = grid
   if cmap is not None:
      pl.cmap = cmap
   if map_type is not None:
      pl.map_type = map_type
   pl.filename = ofile
   if thresholds is not None:
      pl.thresholds = thresholds
   if quantiles is not None:
      pl.quantiles = quantiles
   pl.figsize = figsize
   pl.dpi = dpi
   if axis is not None:
      pl.axis = axis
   if aggregator_name is not None:
      pl.aggregator = verif.aggregator.get(aggregator_name)
   if aspect is not None:
      pl.aspect = aspect
   pl.show_margin = not no_margin
   if ylabel is not None:
      pl.ylabel = ylabel
   if xlabel is not None:
      pl.xlabel = xlabel
   if clabel is not None:
      pl.clabel = clabel
   if title is not None:
      pl.title = title
   if do_acc:
      if pl.supports_acc:
         pl.show_acc = do_acc
      else:
         verif.util.warning("%s does not support -acc" % metric)

   if plot_type == "text":
      pl.text(data)
   elif plot_type == "csv":
      pl.csv(data)
   elif plot_type == "map":
      pl.map(data)
   elif plot_type == "maprank":
      pl.show_rank = True
      pl.map(data)
   elif plot_type == "rank":
      pl.show_rank = True
      pl.plot_rank(data)
   elif plot_type == "impact":
      pl.plot_impact(data)
   elif plot_type == "mapimpact":
      pl.plot_mapimpact(data)
   else:
      pl.plot(data)
Beispiel #14
0
 def test(self):
     data = verif.data.Data(
         [verif.input.Text("verif/tests/files/file_nan_time.txt")])
     np.testing.assert_array_equal(
         np.array([1325376000, 1325462400, 1325548800]), data.times)
     obs = data.get_scores(verif.field.Obs(), 0)
Beispiel #15
0
def run(argv):
   ############
   # Defaults #
   ############
   ifiles = list()
   ofile = None
   metric = None
   locations = None
   locations_x = None
   lat_range = None
   lon_range = None
   elev_range = None
   thresholds = None
   quantiles = None
   clim_file = None
   clim_type = "subtract"
   leg = None
   ylabel = None
   xlabel = None
   title = None
   times = None
   leadtimes = None
   axis = None
   aspect = None
   figsize = None
   dpi = 100
   no_margin = False
   bin_type = None
   simple = None
   marker_size = None
   line_width = None
   line_colors = None
   line_styles = None
   tick_font_size = None
   lab_font_size = None
   leg_font_size = None
   title_font_size = None
   leg_loc = None
   plot_type = "plot"
   grid = True
   xrot = None
   yrot = None
   bottom_padding = None
   top_padding = None
   right_padding = None
   left_padding = None
   Pad = None
   show_perfect = None
   aggregator_name = None
   do_hist = False
   do_sort = False
   do_acc = False
   xlim = None
   ylim = None
   clim = None
   xticks = None
   xticklabels = None
   yticks = None
   yticklabels = None
   version = None
   list_thresholds = False
   list_quantiles = False
   list_locations = False
   list_times = False
   map_type = None
   xlog = False
   ylog = False
   cmap = None
   obs_field = verif.field.Obs()
   fcst_field = verif.field.Fcst()

   # Read command line arguments
   i = 1
   while(i < len(argv)):
      arg = argv[i]
      if(arg[0] == '-'):
         # Process option
         if(arg == "-nomargin"):
            no_margin = True
         elif(arg == "--version"):
            version = True
         elif(arg == "--list-thresholds"):
            list_thresholds = True
         elif(arg == "--list-quantiles"):
            list_quantiles = True
         elif(arg == "--list-locations"):
            list_locations = True
         elif(arg == "--list-times"):
            list_times = True
         elif(arg == "-sp"):
            show_perfect = True
         elif(arg == "-hist"):
            do_hist = True
         elif(arg == "-acc"):
            do_acc = True
         elif(arg == "-sort"):
            do_sort = True
         elif(arg == "-simple"):
            simple = True
         elif(arg == "-xlog"):
            xlog = True
         elif(arg == "-ylog"):
            ylog = True
         elif(arg == "-nogrid"):
            grid = False
         else:
            if len(argv) <= i + 1:
               verif.util.error("Missing value after %s" % argv[i])
            arg_next = argv[i + 1]
            if(arg == "-f"):
               ofile = arg_next
            elif(arg == "-l"):
               locations = verif.util.parse_numbers(arg_next)
            elif(arg == "-lx"):
               locations_x = verif.util.parse_numbers(arg_next)
            elif(arg == "-latrange"):
               lat_range = verif.util.parse_numbers(arg_next)
            elif(arg == "-lonrange"):
               lon_range = verif.util.parse_numbers(arg_next)
            elif(arg == "-elevrange"):
               elev_range = verif.util.parse_numbers(arg_next)
            elif(arg == "-x"):
               axisname = arg_next
               axis = verif.axis.get(axisname)
            elif(arg == "-o"):
               leadtimes = verif.util.parse_numbers(arg_next)
            elif(arg == "-leg"):
               leg = unicode(arg_next, 'utf8')
            elif(arg == "-ylabel"):
               ylabel = unicode(arg_next, 'utf8')
            elif(arg == "-xlabel"):
               xlabel = unicode(arg_next, 'utf8')
            elif(arg == "-title"):
               title = unicode(arg_next, 'utf8')
            elif(arg == "-b"):
               bin_type = arg_next
            elif(arg == "-type"):
               plot_type = arg_next
            elif(arg == "-fs"):
               figsize = arg_next
            elif(arg == "-dpi"):
               dpi = int(arg_next)
            elif(arg == "-d"):
               dates = verif.util.parse_numbers(arg_next, True)
               times = [verif.util.date_to_unixtime(date) for date in dates]
            elif(arg == "-t"):
               times = verif.util.parse_numbers(arg_next, True)
            elif(arg == "-c"):
               clim_file = verif.input.get_input(arg_next)
               clim_type = "subtract"
            elif(arg == "-C"):
               clim_file = verif.input.get_input(arg_next)
               clim_type = "divide"
            elif(arg == "-xlim"):
               xlim = verif.util.parse_numbers(arg_next)
            elif(arg == "-ylim"):
               ylim = verif.util.parse_numbers(arg_next)
            elif(arg == "-clim"):
               clim = verif.util.parse_numbers(arg_next)
            elif(arg == "-xticks"):
               xticks = verif.util.parse_numbers(arg_next)
            elif(arg == "-xticklabels"):
               xticklabels = (arg_next).split(',')
            elif(arg == "-yticks"):
               yticks = verif.util.parse_numbers(arg_next)
            elif(arg == "-yticklabels"):
               yticklabels = (arg_next).split(',')
            elif(arg == "-agg"):
               aggregator_name = arg_next
            elif(arg == "-aspect"):
               aspect = float(arg_next)
            elif(arg == "-r"):
               thresholds = np.array(verif.util.parse_numbers(arg_next))
            elif(arg == "-q"):
               quantiles = np.array(verif.util.parse_numbers(arg_next))
               if np.min(quantiles) < 0 or np.max(quantiles) > 1:
                  verif.util.error("Quantiles must be between 0 and 1 inclusive")
            elif(arg == "-ms"):
               marker_size = float(arg_next)
            elif(arg == "-lw"):
               line_width = float(arg_next)
            elif(arg == "-lc"):
               line_colors = arg_next
            elif(arg == "-ls"):
               line_styles = arg_next
            elif(arg == "-tickfs"):
               tick_font_size = float(arg_next)
            elif(arg == "-labfs"):
               lab_font_size = float(arg_next)
            elif(arg == "-legfs"):
               leg_font_size = float(arg_next)
            elif(arg == "-legloc"):
               leg_loc = arg_next.replace('_', ' ')
            elif(arg == "-xrot"):
               xrot = float(arg_next)
            elif(arg == "-yrot"):
               yrot = float(arg_next)
            elif(arg == "-bottom"):
               bottom_padding = float(arg_next)
            elif(arg == "-top"):
               top_padding = float(arg_next)
            elif(arg == "-right"):
               right_padding = float(arg_next)
            elif(arg == "-left"):
               left_padding = float(arg_next)
            elif(arg == "-pad"):
               Pad = arg_next
            elif(arg == "-titlefs"):
               title_font_size = float(arg_next)
            elif(arg == "-cmap"):
               cmap = arg_next
            elif(arg == "-maptype"):
               map_type = arg_next
            elif(arg == "-obs"):
               obs_field = verif.field.get(arg_next)
            elif(arg == "-fcst"):
               fcst_field = verif.field.get(arg_next)
            elif(arg == "-m"):
               metric = arg_next
            else:
               verif.util.error("Flag '" + argv[i] + "' not recognized")
            i = i + 1
      else:
         ifiles.append(argv[i])
      i = i + 1

   if(version):
      print "Version: " + verif.version.__version__
      return

   # Deal with legend entries
   if(leg is not None):
      leg = leg.split(',')
      for i in range(0, len(leg)):
         leg[i] = leg[i].replace('_', ' ')

   if(lat_range is not None and len(lat_range) != 2):
      verif.util.error("-lat_range <values> must have exactly 2 values")

   if(lon_range is not None and len(lon_range) != 2):
      verif.util.error("-lon_range <values> must have exactly 2 values")

   if(elev_range is not None and len(elev_range) != 2):
      verif.util.error("-elev_range <values> must have exactly 2 values")

   if(len(ifiles) > 0):
      inputs = [verif.input.get_input(filename) for filename in ifiles]
      data = verif.data.Data(inputs, clim=clim_file, clim_type=clim_type,
            times=times, leadtimes=leadtimes, locations=locations,
            locations_x=locations_x,
            lat_range=lat_range, lon_range=lon_range, elev_range=elev_range,
            legend=leg, obs_field=obs_field, fcst_field=fcst_field)
   else:
      data = None

   if(list_thresholds or list_quantiles or list_locations or list_times):
      if(len(ifiles) == 0):
         verif.util.error("Files are required in order to list thresholds, quantiles, or times")
      if(list_thresholds):
         print "Thresholds:",
         for threshold in data.thresholds:
            print "%g" % threshold,
         print ""
      if(list_quantiles):
         print "Quantiles:",
         for quantile in data.quantiles:
            print "%g" % quantile,
         print ""
      if(list_locations):
         print "    id     lat     lon    elev"
         for location in data.locations:
            print "%6d %7.2f %7.2f %7.1f" % (location.id, location.lat,
                  location.lon, location.elev)
         print ""
      if(list_times):
         for time in data.times:
            print "%d" % time
         print ""
      return
   elif(len(ifiles) == 0 and metric is not None):
      m = verif.metric.get(metric)
      if(m is not None):
         print m.help()
      else:
         m = verif.output.get(metric)
         if(m is not None):
            print m.help()
      return
   elif(len(argv) == 1 or len(ifiles) == 0 or metric is None):
      print show_description(data)
      return

   if(figsize is not None):
      figsize = figsize.split(',')
      if(len(figsize) != 2):
         print "-fs figsize must be in the form: width,height"
         sys.exit(1)

   m = None

   # Handle special plots
   if(metric == "pithist"):
      pl = verif.output.PitHist()
   elif(metric == "obsfcst"):
      pl = verif.output.ObsFcst()
   elif(metric == "timeseries"):
      pl = verif.output.TimeSeries()
   elif(metric == "meteo"):
      pl = verif.output.Meteo()
   elif(metric == "qq"):
      pl = verif.output.QQ()
   elif(metric == "cond"):
      pl = verif.output.Cond()
   elif(metric == "against"):
      pl = verif.output.Against()
   elif(metric == "impact"):
      pl = verif.output.Impact()
   elif(metric == "scatter"):
      pl = verif.output.Scatter()
   elif(metric == "change"):
      pl = verif.output.Change()
   elif(metric == "spreadskill"):
      pl = verif.output.SpreadSkill()
   elif(metric == "taylor"):
      pl = verif.output.Taylor()
   elif(metric == "error"):
      pl = verif.output.Error()
   elif(metric == "freq"):
      pl = verif.output.Freq()
   elif(metric == "roc"):
      pl = verif.output.Roc()
   elif(metric == "droc"):
      pl = verif.output.DRoc()
   elif(metric == "droc0"):
      pl = verif.output.DRoc0()
   elif(metric == "drocnorm"):
      pl = verif.output.DRocNorm()
   elif(metric == "reliability"):
      pl = verif.output.Reliability()
   elif(metric == "discrimination"):
      pl = verif.output.Discrimination()
   elif(metric == "performance"):
      pl = verif.output.Performance()
   elif(metric == "invreliability"):
      pl = verif.output.InvReliability()
   elif(metric == "igncontrib"):
      pl = verif.output.IgnContrib()
   elif(metric == "economicvalue"):
      pl = verif.output.EconomicValue()
   elif(metric == "marginal"):
      pl = verif.output.Marginal()
   else:
      # Standard plots
      # Attempt at automating
      m = verif.metric.get(metric)
      if(m is None):
         verif.util.error("Unknown plot: %s" % metric)

      if aggregator_name is not None:
         if not m.supports_aggregator:
            verif.util.warning("-m %s does not support -agg" % metric)
         m.aggregator = verif.aggregator.get(aggregator_name)

      # Output type
      if(plot_type in ["plot", "text", "csv", "map", "maprank"]):
         if do_sort:
            field = verif.field.get(metric)
            pl = verif.output.Sort(field)
         elif do_hist:
            field = verif.field.get(metric)
            pl = verif.output.Hist(field)
         else:
            pl = verif.output.Standard(m)
      else:
         verif.util.error("Type not understood")

   # Rest dimension of '-x' is not allowed
   if(axis is not None and not pl.supports_x):
      verif.util.warning(metric + " does not support -x. Ignoring it.")
      axis = None

   # Reset dimension if 'threshold' is not allowed
   if(axis == verif.axis.Threshold() and
         ((not pl.supports_threshold) or (m is not None and not m.supports_threshold))):
      verif.util.warning(metric + " does not support '-x threshold'. Ignoring it.")
      thresholds = None
      axis = None

   # Create thresholds if needed
   if thresholds is None:
      type = None
      if pl.require_threshold_type == "deterministic":
         type = "deterministic"
      elif pl.require_threshold_type == "threshold":
         type = "threshold"
      elif pl.require_threshold_type == "quantile":
         type = "quantile"
      elif m is not None:
         if m.require_threshold_type == "deterministic":
            type = "deterministic"
         elif m.require_threshold_type == "threshold":
            type = "threshold"
         elif m.require_threshold_type == "quantile":
            type = "quantile"
         elif m.require_threshold_type is not None:
            verif.util.error("Internal error for metric %s: Cannot understand required threshold type '%s'" % (m.name(), m.require_threshold_type))
      elif pl.require_threshold_type is not None:
         verif.util.error("Internal error for output %s: Cannot understand required threshold type '%s'" % (pl.name(), pl.require_threshold_type))

      if type is not None:
         if type == "deterministic":
            smin = np.inf
            smax = -np.inf
            if verif.field.Obs() in data.get_fields():
               obs = data.get_scores(verif.field.Obs(), 0)
               smin = min(np.nanmin(obs), smin)
               smax = max(np.nanmax(obs), smax)
            if verif.field.Fcst() in data.get_fields():
               fcst = data.get_scores(verif.field.Fcst(), 0)
               smin = min(np.nanmin(fcst), smin)
               smax = max(np.nanmax(fcst), smax)
            thresholds = np.linspace(smin, smax, 10)
            verif.util.warning("Missing '-r <thresholds>'. Automatically setting thresholds.")
         elif type == "threshold":
            thresholds = data.thresholds
            verif.util.warning("Missing '-r <thresholds>'. Automatically setting thresholds.")
         elif type == "quantile":
            thresholds = data.quantiles
            verif.util.warning("Missing '-r <thresholds>'. Automatically setting thresholds.")
         if len(thresholds) == 0:
            verif.util.error("No thresholds available")

   # Set plot parameters
   if(simple is not None):
      pl.simple = simple
   if(marker_size is not None):
      pl.ms = marker_size
   if(line_width is not None):
      pl.lw = line_width
   if(line_colors is not None):
      pl.line_colors = line_colors
   if(line_styles is not None):
      pl.line_styles = line_styles
   if(lab_font_size is not None):
      pl.labfs = lab_font_size
   if(leg_font_size is not None):
      pl.legfs = leg_font_size
   if(title_font_size is not None):
      pl.title_font_size = title_font_size
   if(leg_loc is not None):
      pl.leg_loc = leg_loc
   if(tick_font_size is not None):
      pl.tick_font_size = tick_font_size
   if(xrot is not None):
      pl.xrot = xrot
   if(yrot is not None):
      pl.yrot = yrot
   if(bottom_padding is not None):
      pl.bottom = bottom_padding
   if(top_padding is not None):
      pl.top = top_padding
   if(right_padding is not None):
      pl.right = right_padding
   if(left_padding is not None):
      pl.left = left_padding
   if(Pad is not None):
      pl.pad = None
   if(bin_type is not None):
      pl.bin_type = bin_type
   if(show_perfect is not None):
      pl.show_perfect = show_perfect
   if(xlim is not None):
      pl.xlim = xlim
   if(ylim is not None):
      pl.ylim = ylim
   if(clim is not None):
      pl.clim = clim
   if(xticks is not None):
      pl.xticks = xticks
   if(xticklabels is not None):
      pl.xticklabels = xticklabels
   if(yticks is not None):
      pl.yticks = yticks
   if(yticklabels is not None):
      pl.yticklabels = yticklabels
   if(xlog is not None):
      pl.xlog = xlog
   if(ylog is not None):
      pl.ylog = ylog
   pl.grid = grid
   if(cmap is not None):
      pl.cmap = cmap
   if(map_type is not None):
      pl.map_type = map_type
   pl.filename = ofile
   if thresholds is not None:
      pl.thresholds = thresholds
   if quantiles is not None:
      pl.quantiles = quantiles
   pl.figsize = figsize
   pl.dpi = dpi
   if axis is not None:
      pl.axis = axis
   if aggregator_name is not None:
      pl.aggregator = verif.aggregator.get(aggregator_name)
   if aspect is not None:
      pl.aspect = aspect
   pl.show_margin = not no_margin
   if ylabel is not None:
      pl.ylabel = ylabel
   if xlabel is not None:
      pl.xlabel = xlabel
   if title is not None:
      pl.title = title
   if do_acc:
      if pl.supports_acc:
         pl.show_acc = do_acc
      else:
         verif.util.warning("%s does not support -acc" % metric)

   if(plot_type == "text"):
      pl.text(data)
   elif(plot_type == "csv"):
      pl.csv(data)
   elif(plot_type == "map"):
      pl.map(data)
   elif(plot_type == "maprank"):
      pl.show_rank = True
      pl.map(data)
   else:
      pl.plot(data)