def test_extract_snapshots(self): """CBC: Extract snapshots from a snapshot CSV.""" csv_path = os.path.join(self.workspace_dir, 'snapshots.csv') transition_years = (2000, 2010, 2020) transition_rasters = [] with open(csv_path, 'w') as transitions_csv: # Check that we can interpret varying case. transitions_csv.write('snapshot_YEAR,raster_PATH\n') for transition_year in transition_years: # Write absolute paths. transition_file_path = os.path.join(self.workspace_dir, f'{transition_year}.tif)') transition_rasters.append(transition_file_path) transitions_csv.write( f'{transition_year},{transition_file_path}\n') # Make one path relative to the workspace, where the transitions # CSV also lives. # The expected raster path is absolute. transitions_csv.write('2030,some_path.tif\n') transition_years += (2030, ) transition_rasters.append( os.path.join(self.workspace_dir, 'some_path.tif')) extracted_transitions = ( coastal_blue_carbon._extract_snapshots_from_table(csv_path)) self.assertEqual(extracted_transitions, dict(zip(transition_years, transition_rasters)))
def test_model_one_transition_no_analysis_year(self): """CBC: Test the model on one transition with no analysis year. This test came up while looking into an issue reported on the forums: https://community.naturalcapitalproject.org/t/coastal-blue-carbon-negative-carbon-stocks/780/12 """ args = TestCBC2._create_model_args(self.workspace_dir) args['workspace_dir'] = os.path.join(self.workspace_dir, 'workspace') prior_snapshots = coastal_blue_carbon._extract_snapshots_from_table( args['landcover_snapshot_csv']) baseline_year = min(prior_snapshots.keys()) baseline_raster = prior_snapshots[baseline_year] with open(args['landcover_snapshot_csv'], 'w') as snapshot_csv: snapshot_csv.write('snapshot_year,raster_path\n') snapshot_csv.write(f'{baseline_year},{baseline_raster}\n') snapshot_csv.write(f'2010,{prior_snapshots[2010]}\n') del args['analysis_year'] # Use valuation parameters rather than price table. args['use_price_table'] = False args['inflation_rate'] = 4 args['price'] = 1.0 coastal_blue_carbon.execute(args) # Check sequestration raster expected_sequestration_2000_to_2010 = numpy.array([[83.5, 0.]], dtype=numpy.float32) raster_path = os.path.join(args['workspace_dir'], 'output', ('total-net-carbon-sequestration-between-' '2000-and-2010.tif')) try: raster = gdal.OpenEx(raster_path) numpy.testing.assert_allclose(raster.ReadAsArray(), expected_sequestration_2000_to_2010) finally: raster = None # Check valuation raster # Discount rate here matches the inflation rate, so the value of the 10 # years' accumulation is just 1*(10 years of accumulation). expected_net_present_value_at_2010 = numpy.array([[835.0, 0.]], dtype=numpy.float32) raster_path = os.path.join(args['workspace_dir'], 'output', 'net-present-value-at-2010.tif') try: raster = gdal.OpenEx(raster_path) numpy.testing.assert_allclose(raster.ReadAsArray(), expected_net_present_value_at_2010, rtol=1e-6) finally: raster = None
def test_model_no_transitions(self): """CBC: Test model without transitions. When the model executes without transitions, we still evaluate carbon sequestration (accumulation only) for the whole baseline period. """ args = TestCBC2._create_model_args(self.workspace_dir) args['workspace_dir'] = os.path.join(self.workspace_dir, 'workspace') prior_snapshots = coastal_blue_carbon._extract_snapshots_from_table( args['landcover_snapshot_csv']) baseline_year = min(prior_snapshots.keys()) baseline_raster = prior_snapshots[baseline_year] with open(args['landcover_snapshot_csv'], 'w') as snapshot_csv: snapshot_csv.write('snapshot_year,raster_path\n') snapshot_csv.write(f'{baseline_year},{baseline_raster}\n') args['analysis_year'] = baseline_year + 10 # Use valuation parameters rather than price table. args['use_price_table'] = False args['inflation_rate'] = 4 args['price'] = 1.0 coastal_blue_carbon.execute(args) # Check sequestration raster expected_sequestration_2000_to_2010 = numpy.array([[83.5, 0.]], dtype=numpy.float32) raster_path = os.path.join(args['workspace_dir'], 'output', ('total-net-carbon-sequestration-between-' '2000-and-2010.tif')) try: raster = gdal.OpenEx(raster_path) numpy.testing.assert_allclose(raster.ReadAsArray(), expected_sequestration_2000_to_2010) finally: raster = None # Check valuation raster # Discount rate here matches the inflation rate, so the value of the 10 # years' accumulation is just 1*(10 years of accumulation). expected_net_present_value_at_2010 = numpy.array([[835.0, 0.]], dtype=numpy.float32) raster_path = os.path.join(args['workspace_dir'], 'output', 'net-present-value-at-2010.tif') try: raster = gdal.OpenEx(raster_path) numpy.testing.assert_allclose(raster.ReadAsArray(), expected_net_present_value_at_2010, rtol=1e-6) finally: raster = None
def test_validation(self): """CBC: Test custom validation.""" args = TestCBC2._create_model_args(self.workspace_dir) args['workspace_dir'] = self.workspace_dir # verify validation passes on basic set of arguments. validation_warnings = coastal_blue_carbon.validate(args) self.assertEqual([], validation_warnings) # Now work through the extra validation warnings. # Create an invalid transitions table. invalid_raster_path = os.path.join(self.workspace_dir, 'invalid_raster.tif') with open(invalid_raster_path, 'w') as raster: raster.write('not a raster') # Write over the landcover snapshot CSV prior_snapshots = coastal_blue_carbon._extract_snapshots_from_table( args['landcover_snapshot_csv']) baseline_year = min(prior_snapshots) with open(args['landcover_snapshot_csv'], 'w') as snapshot_table: snapshot_table.write('snapshot_year,raster_path\n') snapshot_table.write( f'{baseline_year},{prior_snapshots[baseline_year]}\n') snapshot_table.write(f"{baseline_year + 10},{invalid_raster_path}") # analysis year must be >= the last transition year. args['analysis_year'] = baseline_year validation_warnings = coastal_blue_carbon.validate(args) self.assertEqual(len(validation_warnings), 2) self.assertIn( coastal_blue_carbon.INVALID_SNAPSHOT_RASTER_MSG.format( snapshot_year=baseline_year + 10), validation_warnings[0][1]) self.assertIn( coastal_blue_carbon.INVALID_ANALYSIS_YEAR_MSG.format( analysis_year=2000, latest_year=2010), validation_warnings[1][1])