def test_habitat_quality_nodata(self): """Habitat Quality: on missing base and future LULC rasters.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'workspace_dir': self.workspace_dir, } args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path']) args['lulc_cur_path'] = os.path.join(args['workspace_dir'], 'lc_samp_cur_b.tif') make_lulc_raster(args['lulc_cur_path'], 2) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder']) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) habitat_quality.execute(args) # Reasonable to just check quality out in this case assert_array_sum( os.path.join(args['workspace_dir'], 'output', 'quality_c.tif'), 5951.2827)
def test_habitat_quality_nodata_small_fut(self): """Habitat Quality: small test with future raster only.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'landuse_cur_uri': os.path.join(REGRESSION_DATA, 'small_lulc_base.tif'), 'landuse_bas_uri': os.path.join(REGRESSION_DATA, 'small_lulc_base.tif'), 'sensitivity_uri': os.path.join(REGRESSION_DATA, 'small_sensitivity_samp.csv'), 'threat_raster_folder': os.path.join(REGRESSION_DATA), 'threats_uri': os.path.join(REGRESSION_DATA, 'small_threats_samp.csv'), u'workspace_dir': self.workspace_dir, } habitat_quality.execute(args) HabitatQualityTests._test_same_files( os.path.join(REGRESSION_DATA, 'file_list_small_nodata_fut.txt'), args['workspace_dir']) # reasonable to just check quality out in this case natcap.invest.pygeoprocessing_0_3_3.testing.assert_rasters_equal( os.path.join(REGRESSION_DATA, 'small_quality_out_c.tif'), os.path.join(self.workspace_dir, 'output', 'quality_out_c.tif'), 1e-6)
def test_habitat_quality_missing_threat(self): """Habitat Quality: expected ValueError on missing threat raster.""" from natcap.invest import habitat_quality args = { 'access_uri': os.path.join(SAMPLE_DATA, 'HabitatQuality', 'access_samp.shp'), 'half_saturation_constant': '0.5', 'landuse_cur_uri': os.path.join(REGRESSION_DATA, 'small_lulc_base.tif'), 'sensitivity_uri': os.path.join(REGRESSION_DATA, 'small_sensitivity_samp_missing_threat.csv'), 'threat_raster_folder': os.path.join(REGRESSION_DATA), 'threats_uri': os.path.join(REGRESSION_DATA, 'small_threats_samp_missing_threat.csv'), u'workspace_dir': self.workspace_dir, } with self.assertRaises(ValueError): habitat_quality.execute(args)
def test_habitat_quality_nodata_fut(self): """Habitat Quality: on missing future LULC raster.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'workspace_dir': self.workspace_dir, } args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path']) scenarios = ['_bas_', '_cur_'] # Missing '_fut_' for lulc_val, scenario in enumerate(scenarios, start=1): args['lulc' + scenario + 'path'] = os.path.join( args['workspace_dir'], 'lc_samp' + scenario + 'b.tif') make_lulc_raster(args['lulc' + scenario + 'path'], lulc_val) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder']) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) habitat_quality.execute(args) # Reasonable to just check quality out in this case assert_array_sum( os.path.join(args['workspace_dir'], 'output', 'quality_c.tif'), 5951.2827)
def test_habitat_quality_invalid_decay_type(self): """Habitat Quality: expected ValueError on invalid decay type.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'workspace_dir': self.workspace_dir, } args['access_vector_path'] = os.path.join(args['workspace_dir'], 'access_samp.shp') make_access_shp(args['access_vector_path']) args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path']) args['lulc_cur_path'] = os.path.join(args['workspace_dir'], 'lc_samp_cur_b.tif') make_lulc_raster(args['lulc_cur_path'], 2) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder']) # Include an invalid decay function name to the threats csv table. args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path'], include_invalid_decay=True) with self.assertRaises(ValueError): habitat_quality.execute(args)
def test_habitat_quality_bad_rasters(self): """Habitat Quality: on threats that aren't real rasters.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'workspace_dir': self.workspace_dir, } args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path']) args['lulc_cur_path'] = os.path.join(args['workspace_dir'], 'lc_samp_cur_b.tif') make_lulc_raster(args['lulc_cur_path'], 2) # Make an empty threat raster in the workspace folder. args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder'], make_empty_raster=True) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) with self.assertRaises(ValueError): habitat_quality.execute(args)
def test_habitat_quality_missing_sensitivity_threat(self): """Habitat Quality: ValueError w/ missing threat in sensitivity.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'workspace_dir': self.workspace_dir, } args['access_vector_path'] = os.path.join(args['workspace_dir'], 'access_samp.shp') make_access_shp(args['access_vector_path']) # Include a missing threat to the sensitivity csv table args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path'], include_threat=False) args['lulc_cur_path'] = os.path.join(args['workspace_dir'], 'lc_samp_cur_b.tif') make_lulc_raster(args['lulc_cur_path'], 2) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder']) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) with self.assertRaises(ValueError): habitat_quality.execute(args)
def test_habitat_quality_numeric_threats(self): """Habitat Quality: regression test on numeric threat names.""" from natcap.invest import habitat_quality threat_array = numpy.zeros((100, 100), dtype=numpy.int8) threatnames = ['1111', '2222'] threats_folder = os.path.join(self.workspace_dir, 'threats') os.makedirs(threats_folder) for suffix in ['_c', '_f']: for i, threat in enumerate(threatnames): raster_path = os.path.join(threats_folder, threat + suffix + '.tif') threat_array[100//(i+1):, :] = 1 # making variations among threats make_raster_from_array(threat_array, raster_path) threat_csv_path = os.path.join(self.workspace_dir, 'threats.csv') with open(threat_csv_path, 'w') as open_table: open_table.write('MAX_DIST,WEIGHT,THREAT,DECAY\n') open_table.write('0.9,0.7,%s,linear\n' % threatnames[0]) open_table.write('0.5,1.0,%s,exponential\n' % threatnames[1]) args = { 'half_saturation_constant': '0.5', 'results_suffix': 'regression', 'threats_table_path': threat_csv_path, 'workspace_dir': os.path.join(self.workspace_dir, 'workspace'), 'threat_raster_folder': threats_folder, 'sensitivity_table_path': os.path.join(self.workspace_dir, 'sensitivity_samp.csv'), 'access_vector_path': os.path.join(self.workspace_dir, 'access_samp.shp') } make_access_shp(args['access_vector_path']) scenarios = ['_bas_', '_cur_', '_fut_'] for lulc_val, scenario in enumerate(scenarios, start=1): args['lulc' + scenario + 'path'] = os.path.join( self.workspace_dir, 'lc_samp' + scenario + 'b.tif') make_lulc_raster(args['lulc' + scenario + 'path'], lulc_val) with open(args['sensitivity_table_path'], 'w') as open_table: open_table.write('LULC,NAME,HABITAT,L_%s,L_%s\n' % tuple(threatnames)) open_table.write('1,"lulc 1",1,1,1\n') open_table.write('2,"lulc 2",0.5,0.5,1\n') open_table.write('3,"lulc 3",0,0.3,1\n') habitat_quality.execute(args) # Assert values were obtained by summing each output raster. for output_filename, assert_value in { 'deg_sum_c_regression.tif': 1792.8088, 'deg_sum_f_regression.tif': 2308.9636, 'quality_c_regression.tif': 6928.5293, 'quality_f_regression.tif': 4916.338, 'rarity_c_regression.tif': 2500.0000000, 'rarity_f_regression.tif': 2500.0000000 }.items(): assert_array_sum( os.path.join(args['workspace_dir'], 'output', output_filename), assert_value)
def test_habitat_quality_lulc_bbox(self): """Habitat Quality: regression test for bbox sizes.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'results_suffix': 'regression', 'workspace_dir': self.workspace_dir, } args['access_vector_path'] = os.path.join(args['workspace_dir'], 'access_samp.shp') make_access_shp(args['access_vector_path']) scenarios = ['_bas_', '_cur_', '_fut_'] for lulc_val, scenario in enumerate(scenarios, start=1): args['lulc' + scenario + 'path'] = os.path.join( args['workspace_dir'], 'lc_samp' + scenario + 'b.tif') make_lulc_raster(args['lulc' + scenario + 'path'], lulc_val) args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path']) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder'], side_length=50, threat_values=[1, 1]) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) habitat_quality.execute(args) base_lulc_bbox = pygeoprocessing.get_raster_info( args['lulc_bas_path'])['bounding_box'] # Assert values were obtained by summing each output raster. for output_filename in [ 'deg_sum_c_regression.tif', 'deg_sum_f_regression.tif', 'quality_c_regression.tif', 'quality_f_regression.tif', 'rarity_c_regression.tif', 'rarity_f_regression.tif' ]: raster_path = os.path.join(args['workspace_dir'], 'output', output_filename) # Check that the output raster has the same bounding box as the # LULC rasters. raster_info = pygeoprocessing.get_raster_info(raster_path) raster_bbox = raster_info['bounding_box'] numpy.testing.assert_allclose(raster_bbox, base_lulc_bbox, rtol=0, atol=1e-6)
def test_habitat_quality_missing_lucodes_in_table(self): """Habitat Quality: on missing lucodes in the sensitivity table.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'workspace_dir': self.workspace_dir, } args['access_vector_path'] = os.path.join(args['workspace_dir'], 'access_samp.shp') make_access_shp(args['access_vector_path']) scenarios = ['_bas_', '_cur_', '_fut_'] for lulc_val, scenario in enumerate(scenarios, start=1): path = os.path.join(args['workspace_dir'], 'lc_samp' + scenario + 'b.tif') args['lulc' + scenario + 'path'] = path make_lulc_raster(path, lulc_val) # Add a nodata value to this raster to make sure we don't include # the nodata value in the error message. raster = gdal.OpenEx(path, gdal.OF_RASTER | gdal.GA_Update) band = raster.GetRasterBand(1) band_nodata = 255 band.SetNoDataValue(band_nodata) # band nodata before this is -1 current_array = band.ReadAsArray() current_array[49][49] = band_nodata band.WriteArray(current_array) band = None raster = None args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path'], missing_lines=True) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder']) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) with self.assertRaises(ValueError) as cm: habitat_quality.execute(args) actual_message = str(cm.exception) self.assertTrue( 'The following land cover codes were found in ' in actual_message, actual_message) # 2, 3 are the missing landcover codes. # Raster nodata is 255 and should NOT appear in this list. self.assertTrue(': 2, 3.' in actual_message, actual_message)
def test_habitat_quality_regression(self): """Habitat Quality: base regression test with simplified data.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'results_suffix': 'regression', 'workspace_dir': self.workspace_dir, } args['access_vector_path'] = os.path.join(args['workspace_dir'], 'access_samp.shp') make_access_shp(args['access_vector_path']) scenarios = ['_bas_', '_cur_', '_fut_'] for lulc_val, scenario in enumerate(scenarios, start=1): args['lulc' + scenario + 'path'] = os.path.join( args['workspace_dir'], 'lc_samp' + scenario + 'b.tif') make_lulc_raster(args['lulc' + scenario + 'path'], lulc_val) args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path']) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder'], threat_values=[0.5, 6.6]) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) habitat_quality.execute(args) # Assert values were obtained by summing each output raster. for output_filename, assert_value in { 'deg_sum_c_regression.tif': 1792.8088, 'deg_sum_f_regression.tif': 2308.9636, 'quality_c_regression.tif': 6928.5293, 'quality_f_regression.tif': 4916.338, 'rarity_c_regression.tif': 2500.0000000, 'rarity_f_regression.tif': 2500.0000000 }.items(): raster_path = os.path.join(args['workspace_dir'], 'output', output_filename) # Check that the raster's computed values are what we expect. # In this case, the LULC and threat rasters should have been # expanded to be beyond the bounds of the original threat values, # so we should exclude those new nodata pixel values. assert_array_sum(raster_path, assert_value, include_nodata=False)
def test_habitat_quality_regression(self): """Habitat Quality: base regression test with simplified data.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'suffix': 'regression', u'workspace_dir': self.workspace_dir, } args['access_vector_path'] = os.path.join(args['workspace_dir'], 'access_samp.shp') make_access_shp(args['access_vector_path']) scenarios = ['_bas_', '_cur_', '_fut_'] for lulc_val, scenario in enumerate(scenarios): args['lulc' + scenario + 'path'] = os.path.join( args['workspace_dir'], 'lc_samp' + scenario + 'b.tif') make_lulc_raster(args['lulc' + scenario + 'path'], lulc_val) args['sensitivity_table_path'] = os.path.join(args['workspace_dir'], 'sensitivity_samp.csv') make_sensitivity_samp_csv(args['sensitivity_table_path']) args['threat_raster_folder'] = args['workspace_dir'] make_threats_raster(args['threat_raster_folder']) args['threats_table_path'] = os.path.join(args['workspace_dir'], 'threats_samp.csv') make_threats_csv(args['threats_table_path']) habitat_quality.execute(args) # Assert values were obtained by summing each output raster. for output_filename, assert_value in { 'deg_sum_c_regression.tif': 10.728817, 'deg_sum_f_regression.tif': 16.461340, 'quality_c_regression.tif': 7499.9975586, 'quality_f_regression.tif': 4999.9995117, 'rarity_c_regression.tif': 2500.0000000, 'rarity_f_regression.tif': 2500.0000000 }.iteritems(): assert_array_sum( os.path.join(args['workspace_dir'], 'output', output_filename), assert_value)
def test_habitat_quality_regression(self): """Habitat Quality: base regression test.""" from natcap.invest import habitat_quality args = { 'access_uri': os.path.join(SAMPLE_DATA, 'HabitatQuality', 'access_samp.shp'), 'half_saturation_constant': '0.5', 'landuse_bas_uri': os.path.join(SAMPLE_DATA, 'HabitatQuality', 'lc_samp_bse_b.tif'), 'landuse_cur_uri': os.path.join(SAMPLE_DATA, 'HabitatQuality', 'lc_samp_cur_b.tif'), 'landuse_fut_uri': os.path.join(SAMPLE_DATA, 'HabitatQuality', 'lc_samp_fut_b.tif'), 'sensitivity_uri': os.path.join(SAMPLE_DATA, 'HabitatQuality', 'sensitivity_samp.csv'), 'suffix': 'regression', 'threat_raster_folder': os.path.join(SAMPLE_DATA, 'HabitatQuality'), 'threats_uri': os.path.join(SAMPLE_DATA, 'HabitatQuality', 'threats_samp.csv'), u'workspace_dir': self.workspace_dir, } habitat_quality.execute(args) HabitatQualityTests._test_same_files( os.path.join(REGRESSION_DATA, 'file_list_regression.txt'), args['workspace_dir']) for output_filename in [ 'rarity_f_regression.tif', 'deg_sum_out_c_regression.tif', 'deg_sum_out_f_regression.tif', 'quality_out_c_regression.tif', 'quality_out_f_regression.tif', 'rarity_c_regression.tif' ]: natcap.invest.pygeoprocessing_0_3_3.testing.assert_rasters_equal( os.path.join(REGRESSION_DATA, output_filename), os.path.join(self.workspace_dir, 'output', output_filename), 1e-6)
def test_habitat_quality_bad_rasters(self): """Habitat Quality: on threats that aren't real rasters.""" from natcap.invest import habitat_quality args = { 'half_saturation_constant': '0.5', 'landuse_cur_uri': os.path.join(REGRESSION_DATA, 'small_lulc_base.tif'), 'sensitivity_uri': os.path.join(REGRESSION_DATA, 'small_sensitivity_samp.csv'), 'threat_raster_folder': os.path.join(REGRESSION_DATA, 'bad_rasters'), 'threats_uri': os.path.join(REGRESSION_DATA, 'small_threats_samp.csv'), u'workspace_dir': self.workspace_dir, } with self.assertRaises(ValueError): habitat_quality.execute(args)