コード例 #1
0
    def test_execute_hourly_without_sun(self):
        # Prepare input files, without solar radiation
        self.timestamp = dt.datetime(2014, 10, 1, 15, 0, tzinfo=senegal_tzinfo)
        self.setup_input_file("temperature", np.array([[38.0, 28.0]]))
        self.setup_input_file("humidity", np.array([[52.0, 42.0]]))
        self.setup_input_file("wind_speed", np.array([[3.3, 2.3]]))
        self.setup_input_file("pressure", np.array([[1013.0, 1013.0]]))

        # Configuration
        with open(self.config_file, "w") as f:
            f.write(
                textwrap.dedent("""\
                base_dir = {self.tempdir}
                albedo = 0.23
                nighttime_solar_radiation_ratio = 0.8
                elevation = 8
                time_step = H
                unit_converter_pressure = x / 10.0
                unit_converter_solar_radiation = x * 3600 / 1e6
                """).format(self=self))

        # Execute and check exception
        msg = "Neither sunshine_duration nor solar_radiation are available"
        with self.assertRaisesRegex(click.ClickException, msg):
            cli.App(self.config_file).run()
コード例 #2
0
    def test_daily(self):
        self.setup_daily_input_files()
        self.setup_config_file("D")

        # Verify the output file doesn't exist yet
        result_filename = os.path.join(self.tempdir, "evaporation.hts")
        assert not os.path.exists(result_filename)

        # Execute
        cli.App(self.config_file).run()

        # Check that it has created a file and that the file is correct
        with open(result_filename) as f:
            t = HTimeseries(f)
        expected_result = pd.DataFrame(
            data={
                "value": [3.9],
                "flags": [""]
            },
            columns=["value", "flags"],
            index=[dt.datetime(2014, 7, 6)],
        )
        expected_result.index.name = "date"
        pd.testing.assert_frame_equal(t.data,
                                      expected_result,
                                      check_less_precise=1)
コード例 #3
0
 def test_missing_altitude(self):
     self.setup_hourly_input_files(missing="altitude")
     self.setup_config_file("H")
     msg = (
         "Incorrect or unspecified or inconsistent altitudes in the time series "
         "files.")
     with self.assertRaisesRegex(click.ClickException, msg):
         cli.App(self.config_file).run()
コード例 #4
0
    def test_execute_with_dem(self):
        """This is essentially the same as test_execute, but uses a GeoTIFF
        with a DEM instead of a constant elevation. The numbers are the same,
        however (all DEM gridpoints have the same value)."""

        # Prepare input files
        self.timestamp = dt.datetime(2014, 10, 1, 15, 0, tzinfo=senegal_tzinfo)
        self.setup_input_file("temperature", np.array([[38.0, 28.0]]))
        self.setup_input_file("humidity", np.array([[52.0, 42.0]]))
        self.setup_input_file("wind_speed", np.array([[3.3, 2.3]]))
        self.setup_input_file("pressure", np.array([[1013.0, 1013.0]]))
        self.setup_input_file("solar_radiation", np.array([[681.0, 403.0]]))
        self.setup_input_file("dem", np.array([[8.0, 8.0]]), with_date=False)

        with open(self.config_file, "w") as f:
            f.write(
                textwrap.dedent("""\
                base_dir = {self.tempdir}
                albedo = 0.23
                nighttime_solar_radiation_ratio = 0.8
                elevation = dem.tif
                time_step = H
                unit_converter_pressure = x / 10.0
                unit_converter_solar_radiation = x * 3600 / 1e6
                """).format(self=self))

        # Verify the output file doesn't exist yet
        result_filename = os.path.join(
            self.tempdir,
            "evaporation-{}.tif".format(
                self.timestamp.strftime("%Y-%m-%d-%H-%M%z")),
        )
        self.assertFalse(os.path.exists(result_filename))

        # Execute
        cli.App(self.config_file).run()

        # Check that it has created a file
        self.assertTrue(os.path.exists(result_filename))

        # Check that the created file is correct
        fp = gdal.Open(result_filename)
        timestamp = fp.GetMetadata()["TIMESTAMP"]
        self.assertEqual(timestamp, "2014-10-01T15:00:00-01:00")
        self.assertEqual(fp.RasterXSize, 2)
        self.assertEqual(fp.RasterYSize, 1)
        self.assertEqual(fp.GetGeoTransform(), self.geo_transform)
        # We can't just compare fp.GetProjection() to self.wgs84.ExportToWkt(),
        # because sometimes there are minor differences in the formatting or in
        # the information contained in the WKT.
        self.assertTrue(fp.GetProjection().startswith('GEOGCS["WGS 84",'))
        self.assertTrue(
            fp.GetProjection().endswith('AUTHORITY["EPSG","4326"]]'))
        np.testing.assert_almost_equal(fp.GetRasterBand(1).ReadAsArray(),
                                       np.array([[0.63, 0.36]]),
                                       decimal=2)
        fp = None
コード例 #5
0
 def test_albedo_configuration_as_one_number(self, m):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
             base_dir = {self.tempdir}
             time_step = H
             albedo = 0.23
             nighttime_solar_radiation_ratio = 0.8
             """).format(self=self))
     cli.App(self.configfilename).run()
     m.return_value.execute.assert_called_once_with()
コード例 #6
0
 def test_missing_albedo_raises_error(self):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
                 base_dir = {self.tempdir}
                 nighttime_solar_radiation_ratio = 0.8
                 elevation = 8
                 time_step = H
                 """).format(self=self))
     with self.assertRaisesRegex(click.ClickException, "albedo"):
         cli.App(self.configfilename).run()
コード例 #7
0
 def test_executes(self, m):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
                 base_dir = {self.tempdir}
                 albedo = 0.23
                 nighttime_solar_radiation_ratio = 0.8
                 time_step = H
                 unit_converter_pressure = x / 10.0
                 unit_converter_solar_radiation = x * 3600 /1e6
                 """).format(self=self))
     cli.App(self.configfilename).run()
     m.return_value.execute.assert_called_once_with()
コード例 #8
0
 def test_single_albedo_with_wrong_domain_float_inputs(self):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
             base_dir = {self.tempdir}
             time_step = H
             albedo = 2
             nighttime_solar_radiation_ratio = 0.8
             elevation = 8
             """).format(self=self))
     with self.assertRaisesRegex(ValueError,
                                 "Albedo must be between 0.0 and 1.0"):
         cli.App(self.configfilename).run()
コード例 #9
0
 def test_run_app_with_seasonal_albedo_with_mix_sample_inputs(self, m):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
             base_dir = {self.tempdir}
             time_step = H
             albedo = a00.tif 0.23 a00.tif a00.tif a00.tif a00.tif
                      a00.tif a00.tif 0.23 a00.tif 0.23 a00.tif
             nighttime_solar_radiation_ratio = 0.8
             elevation = 8
             """).format(self=self))
     cli.App(self.configfilename).run()
     m.return_value.execute.assert_called_once_with()
コード例 #10
0
 def test_seasonal_albedo_configuration_as_mix_numbers_and_grids(self, m):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
             base_dir = {self.tempdir}
             time_step = H
             albedo = 0.23 a02.tif a03.tif a04.tif a05.tif a06.tif
                      a07.tif a08.tif a09.tif a10.tif a11.tif a12.tif
             nighttime_solar_radiation_ratio = 0.8
             elevation = 8
             """).format(self=self))
     cli.App(self.configfilename).run()
     m.return_value.execute.assert_called_once_with()
コード例 #11
0
 def test_seasonal_albedo_configuration_with_not_enough_arguments(self):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
             base_dir = {self.tempdir}
             time_step = H
             albedo = a01.tiff a02.tiff a11.tiff a12.tiff
             nighttime_solar_radiation_ratio = 0.8
             elevation = 8
             """).format(self=self))
     msg = "Albedo must be either one item or 12 space-separated items"
     with self.assertRaisesRegex(ValueError, msg):
         cli.App(self.configfilename).run()
コード例 #12
0
 def test_seasonal_albedo_configuration_as_12_numbers(self, m):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
             base_dir = {self.tempdir}
             time_step = H
             albedo = 0.10 0.23 0.34 0.24 0.45 0.46
                      0.34 0.12 0.14 0.78 0.78 0.12
             nighttime_solar_radiation_ratio = 0.8
             elevation = 8
             """).format(self=self))
     cli.App(self.configfilename).run()
     m.return_value.execute.assert_called_once_with()
コード例 #13
0
 def test_nonexistent_log_level_raises_error(self):
     with open(self.configfilename, "w") as f:
         f.write(
             textwrap.dedent("""\
                 base_dir = {self.tempdir}
                 albedo = 0.23
                 nighttime_solar_radiation_ratio = 0.8
                 elevation = 8
                 time_step = H
                 unit_converter_pressure = x / 10.0
                 unit_converter_solar_radiation = x * 3600 /1e6
                 loglevel = NONEXISTENT_LOG_LEVEL
                 """.format(self=self)))
     msg = "loglevel must be one of ERROR, WARNING, INFO, DEBUG"
     with self.assertRaisesRegex(click.ClickException, msg):
         cli.App(self.configfilename).run()
コード例 #14
0
 def test_creates_log_file(self, *args):
     with tempfile.TemporaryDirectory() as dirname:
         configfilename = os.path.join(dirname, "evaporation.conf")
         logfilename = os.path.join(dirname, "vaporize.log")
         with open(configfilename, "w") as f:
             f.write(
                 textwrap.dedent("""\
                     base_dir = {}
                     albedo = 0.23
                     nighttime_solar_radiation_ratio = 0.8
                     time_step = H
                     unit_converter_pressure = x / 10.0
                     unit_converter_solar_radiation = x * 3600 /1e6
                     logfile = {}
                     """).format(dirname, logfilename))
         htsfilename = os.path.join(dirname, "somefile.hts")
         Path(htsfilename).touch()
         cli.App(configfilename).run()
         self.assertTrue(os.path.exists(logfilename))
コード例 #15
0
    def test_execute_notz(self):
        # Prepare input files without time zone
        self.timestamp = dt.datetime(2014, 10, 1, 15, 0)
        self.setup_input_file("temperature-notz", np.array([[38.0, 28.0]]))
        self.setup_input_file("humidity-notz", np.array([[52.0, 42.0]]))
        self.setup_input_file("wind_speed-notz", np.array([[3.3, 2.3]]))
        self.setup_input_file("pressure-notz", np.array([[1013.0, 1013.0]]))
        self.setup_input_file("solar_radiation-notz", np.array([[681.0,
                                                                 403.0]]))

        with open(self.config_file, "w") as f:
            f.write(
                textwrap.dedent("""\
                base_dir = {self.tempdir}
                albedo = 0.23
                nighttime_solar_radiation_ratio = 0.8
                elevation = 8
                time_step = H
                unit_converter_pressure = x / 10.0
                unit_converter_solar_radiation = x * 3600 / 1e6
                temperature_prefix = temperature-notz
                humidity_prefix = humidity-notz
                wind_speed_prefix = wind_speed-notz
                solar_radiation_prefix = solar_radiation-notz
                pressure_prefix = pressure-notz
                """).format(self=self))

        # Verify the output file doesn't exist yet
        result_filename = os.path.join(
            self.tempdir,
            "evaporation-{}.tif".format(
                self.timestamp.strftime("%Y-%m-%d-%H-%M%z")),
        )
        self.assertFalse(os.path.exists(result_filename))

        # Execute
        with self.assertRaisesRegex(Exception, "time zone"):
            cli.App(self.config_file).run()

        # Verify the output file still doesn't exist
        self.assertFalse(os.path.exists(result_filename))
コード例 #16
0
    def test_execute_hourly_no_pressure(self):
        """Same as test_execute_hourly, but does not have pressure an input;
           therefore, it will calculate pressure itself."""
        # Prepare input files
        self.timestamp = dt.datetime(2014, 10, 1, 15, 0, tzinfo=senegal_tzinfo)
        self.setup_input_file("temperature", np.array([[38.0, 28.0]]))
        self.setup_input_file("humidity", np.array([[52.0, 42.0]]))
        self.setup_input_file("wind_speed", np.array([[3.3, 2.3]]))
        self.setup_input_file("solar_radiation", np.array([[681.0, 403.0]]))

        # Also setup an output file that has no corresponding input files
        rogue_output_file = os.path.join(
            self.tempdir, "evaporation-2013-01-01-15-00-0100.tif")
        with open(rogue_output_file, "w") as f:
            f.write("irrelevant contents")

        with open(self.config_file, "w") as f:
            f.write(
                textwrap.dedent("""\
                base_dir = {self.tempdir}
                albedo = 0.23
                nighttime_solar_radiation_ratio = 0.8
                elevation = 8
                time_step = H
                unit_converter_solar_radiation = x * 3600 / 1e6
                """).format(self=self))

        # Verify the output file doesn't exist yet
        result_filename = os.path.join(
            self.tempdir,
            "evaporation-{}.tif".format(
                self.timestamp.strftime("%Y-%m-%d-%H-%M%z")),
        )
        self.assertFalse(os.path.exists(result_filename))

        # Verify the rogue output file is still here
        self.assertTrue(os.path.exists(rogue_output_file))

        # Execute
        cli.App(self.config_file).run()

        # Check that it has created a file
        self.assertTrue(os.path.exists(result_filename))

        # Check that the rogue output file is gone
        self.assertFalse(os.path.exists(rogue_output_file))

        # Check that the created file is correct
        fp = gdal.Open(result_filename)
        timestamp = fp.GetMetadata()["TIMESTAMP"]
        self.assertEqual(timestamp, "2014-10-01T15:00:00-01:00")
        self.assertEqual(fp.RasterXSize, 2)
        self.assertEqual(fp.RasterYSize, 1)
        self.assertEqual(fp.GetGeoTransform(), self.geo_transform)
        # We can't just compare fp.GetProjection() to self.wgs84.ExportToWkt(),
        # because sometimes there are minor differences in the formatting or in
        # the information contained in the WKT.
        self.assertTrue(fp.GetProjection().startswith('GEOGCS["WGS 84",'))
        self.assertTrue(
            fp.GetProjection().endswith('AUTHORITY["EPSG","4326"]]'))
        np.testing.assert_almost_equal(fp.GetRasterBand(1).ReadAsArray(),
                                       np.array([[0.63, 0.36]]),
                                       decimal=2)
        fp = None
コード例 #17
0
    def test_execute_daily_with_radiation(self):
        """Same as test_execute_daily, except that we use solar radiation
           instead of sunshine duration."""
        # Prepare input files
        self.timestamp = dt.date(2014, 7, 6)
        self.setup_input_file("temperature_max", np.array([[21.5, 28]]))
        self.setup_input_file("temperature_min", np.array([[12.3, 15]]))
        self.setup_input_file("humidity_max", np.array([[84.0, 70.0]]))
        self.setup_input_file("humidity_min", np.array([[63.0, 60.0]]))
        self.setup_input_file("wind_speed", np.array([[2.078, 2.244]]))
        self.setup_input_file("solar_radiation", np.array([[22.07, 21.62]]))

        # Also setup an output file that has no corresponding input files
        rogue_output_file = os.path.join(self.tempdir,
                                         "evaporation-2013-01-01.tif")
        with open(rogue_output_file, "w") as f:
            f.write("irrelevant contents")

        with open(self.config_file, "w") as f:
            f.write(
                textwrap.dedent("""\
                base_dir = {self.tempdir}
                albedo = 0.23
                elevation = 100
                time_step = D
                """).format(self=self))

        # Verify the output file doesn't exist yet
        result_filename = os.path.join(
            self.tempdir,
            "evaporation-{}.tif".format(self.timestamp.strftime("%Y-%m-%d")),
        )
        self.assertFalse(os.path.exists(result_filename))

        # Verify the rogue output file is still here
        self.assertTrue(os.path.exists(rogue_output_file))

        # Execute
        cli.App(self.config_file).run()

        # Check that it has created a file
        self.assertTrue(os.path.exists(result_filename))

        # Check that the rogue output file is gone
        self.assertFalse(os.path.exists(rogue_output_file))

        # Check that the created file is correct
        fp = gdal.Open(result_filename)
        timestamp = fp.GetMetadata()["TIMESTAMP"]
        self.assertEqual(timestamp, "2014-07-06")
        self.assertEqual(fp.RasterXSize, 2)
        self.assertEqual(fp.RasterYSize, 1)
        self.assertEqual(fp.GetGeoTransform(), self.geo_transform)
        # We can't just compare fp.GetProjection() to self.wgs84.ExportToWkt(),
        # because sometimes there are minor differences in the formatting or in
        # the information contained in the WKT.
        self.assertTrue(fp.GetProjection().startswith('GEOGCS["WGS 84",'))
        self.assertTrue(
            fp.GetProjection().endswith('AUTHORITY["EPSG","4326"]]'))
        np.testing.assert_almost_equal(fp.GetRasterBand(1).ReadAsArray(),
                                       np.array([[3.9, 4.8]]),
                                       decimal=1)
        fp = None