def test_6s_example1(self): # Implements Example_In_1.txt from the 6S distribution in Py6S # Tests against manual run of that file s = SixS() s.geometry = Geometry.User() s.geometry.solar_z = 40 s.geometry.solar_a = 100 s.geometry.view_z = 45 s.geometry.view_a = 50 s.geometry.month = 7 s.geometry.day = 23 s.atmos_profile = AtmosProfile.UserWaterAndOzone(3.0, 3.5) s.aero_profile = AeroProfile.User(dust=0.25, water=0.25, oceanic=0.25, soot=0.25) s.aot550 = 0.5 s.altitudes.set_target_custom_altitude(0.2) s.altitudes.set_sensor_custom_altitude(3.3, aot=0.25) s.wavelength = Wavelength(PredefinedWavelengths.AVHRR_NOAA9_B1) s.ground_reflectance = GroundReflectance.HeterogeneousLambertian( 0.5, GroundReflectance.ClearWater, GroundReflectance.GreenVegetation) s.atmos_corr = AtmosCorr.AtmosCorrBRDFFromReflectance(0.1) s.run() self.assertAlmostEqual(s.outputs.apparent_radiance, 12.749, delta=0.002)
def __init__(self, bandnums, wavelengths, geometry, date_time, sensor=None): """ Run SixS atmospheric model using Py6S """ start = datetime.datetime.now() VerboseOut('Running atmospheric model (6S)', 2) s = SixS() # Geometry s.geometry = Geometry.User() s.geometry.from_time_and_location(geometry['lat'], geometry['lon'], str(date_time), geometry['zenith'], geometry['azimuth']) s.altitudes = Altitudes() s.altitudes.set_target_sea_level() s.altitudes.set_sensor_satellite_level() doy = (date_time - datetime.datetime(date_time.year, 1, 1)).days + 1 # Atmospheric profile s.atmos_profile = atmospheric_model(doy, geometry['lat']) # Aerosols # TODO - dynamically adjust AeroProfile? s.aero_profile = AeroProfile.PredefinedType(AeroProfile.Continental) self.aod = aodData.get_aod(geometry['lat'], geometry['lon'], date_time.date()) s.aot550 = self.aod[1] # Other settings s.ground_reflectance = GroundReflectance.HomogeneousLambertian( GroundReflectance.GreenVegetation) s.atmos_corr = AtmosCorr.AtmosCorrLambertianFromRadiance(1.0) # Used for testing try: stdout = sys.stdout funcs = { 'LT5': SixSHelpers.Wavelengths.run_landsat_tm, 'LT7': SixSHelpers.Wavelengths.run_landsat_etm, # LC8 doesn't seem to work #'LC8': SixSHelpers.Wavelengths.run_landsat_oli } if sensor in funcs.keys(): sys.stdout = open(os.devnull, 'w') wvlens, outputs = funcs[sensor](s) sys.stdout = stdout else: # Use wavelengths outputs = [] for wv in wavelengths: s.wavelength = Wavelength(wv[0], wv[1]) s.run() outputs.append(s.outputs) except Exception, e: sys.stdout = stdout raise AtmCorrException("Error running 6S: %s" % e)
def __init__(self, bandnums, wavelengths, geometry, date_time, sensor=None): """ Run SixS atmospheric model using Py6S """ start = datetime.datetime.now() verbose_out('Running atmospheric model (6S)', 2) s = SixS() # Geometry s.geometry = Geometry.User() s.geometry.from_time_and_location(geometry['lat'], geometry['lon'], str(date_time), geometry['zenith'], geometry['azimuth']) s.altitudes = Altitudes() s.altitudes.set_target_sea_level() s.altitudes.set_sensor_satellite_level() doy = (date_time - datetime.datetime(date_time.year, 1, 1)).days + 1 # Atmospheric profile s.atmos_profile = atmospheric_model(doy, geometry['lat']) # Aerosols # TODO - dynamically adjust AeroProfile? s.aero_profile = AeroProfile.PredefinedType(AeroProfile.Continental) self.aod = aodData.get_aod( geometry['lat'], geometry['lon'], date_time.date() ) # sixs throws IEEE_UNDERFLOW_FLAG IEEE_DENORMAL for small aod. # and if using a predefined AeroProfile, visible or aot550 must be # specified. Small here was determined emprically on my laptop, and # visible = 1000 km is essentially setting the visibility to infinite. if self.aod[1] < 0.0103: s.visible = 1000 else: s.aot550 = self.aod[1] # Other settings s.ground_reflectance = GroundReflectance.HomogeneousLambertian(GroundReflectance.GreenVegetation) s.atmos_corr = AtmosCorr.AtmosCorrLambertianFromRadiance(1.0) # Used for testing funcs = { 'LT5': SixSHelpers.Wavelengths.run_landsat_tm, 'LT7': SixSHelpers.Wavelengths.run_landsat_etm, # LC8 doesn't seem to work #'LC8': SixSHelpers.Wavelengths.run_landsat_oli } if sensor in funcs.keys(): saved_stdout = sys.stdout try: sys.stdout = open(os.devnull, 'w') wvlens, outputs = funcs[sensor](s) finally: sys.stdout = saved_stdout else: # Use wavelengths outputs = [] for wv in wavelengths: s.wavelength = Wavelength(wv[0], wv[1]) s.run() outputs.append(s.outputs) self.results = {} verbose_out("{:>6} {:>8}{:>8}{:>8}".format('Band', 'T', 'Lu', 'Ld'), 4) for b, out in enumerate(outputs): t = out.trans['global_gas'].upward Lu = out.atmospheric_intrinsic_radiance Ld = (out.direct_solar_irradiance + out.diffuse_solar_irradiance + out.environmental_irradiance) / numpy.pi self.results[bandnums[b]] = [t, Lu, Ld] verbose_out("{:>6}: {:>8.3f}{:>8.2f}{:>8.2f}".format(bandnums[b], t, Lu, Ld), 4) verbose_out('Ran atmospheric model in %s' % str(datetime.datetime.now() - start), 2)
def test_multimodal_dist_errors3(self): with self.assertRaises(ParameterError): ap = AeroProfile.MultimodalLogNormalDistribution(0.001, 20) ap.add_component( 0.4, 2.03, 0.005, [ 1.508, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.495, 1.490, 1.490, 1.490, 1.486, 1.480, 1.470, 1.460, 1.456, 1.443, 1.430, 1.470, 1.999, 1.999, 0, ], [ 3.24e-07, 3.0e-08, 2.86e-08, 2.51e-08, 2.2e-08, 2.0e-08, 1.0e-08, 1.0e-08, 1.48e-08, 2.0e-08, 6.85e-08, 1.0e-07, 1.25e-06, 3.0e-06, 3.5e-04, 6.0e-04, 6.86e-04, 1.7e-03, 4.0e-03, 1.4e-03, ], )
def test_sun_photo_dist_errors2(self): with self.assertRaises(ParameterError): # Different numbers of elements for first two arguments AeroProfile.SunPhotometerDistribution( [ 0.050000001, 0.065604001, 0.086076997, 0.112939, 0.148184001, 0.194428995, 0.255104989, 0.334715992, 0.439173013, 0.576227009, 0.756052017, 0.99199599, 1.30157101, 1.707757, 2.24070191, 2.93996596, 3.85745192, 5.06126022, 6.64074516, 8.71314526, 11.4322901, 15, ], [ 0.001338098, 0.007492487, 0.026454749, 0.058904506, 0.082712278, 0.073251031, 0.040950641, 0.014576218, 0.003672085, 0.001576356, 0.002422644, 0.004472982, 0.007452302, 0.011037065, 0.014523974, 0.016981738, 0.017641816, 0.016284294, 0.01335547, 0.009732267, 0.006301342, 0.003625077, ], [1.47] * 15, [0.0093] * 20, )
def test_aero_profile(self): user_ap = AeroProfile.UserProfile(AeroProfile.Maritime) user_ap.add_layer(5, 0.34) aps = [ AeroProfile.Continental, AeroProfile.NoAerosols, AeroProfile.User(dust=0.3, oceanic=0.7), user_ap, ] results = [122.854, 140.289, 130.866, 136.649] for i in range(len(aps)): s = SixS() s.aero_profile = aps[i] s.run() self.assertAlmostEqual( s.outputs.apparent_radiance, results[i], "Error in aerosol profile with ID %s. Got %f, expected %f." % (str(aps[i]), s.outputs.apparent_radiance, results[i]), delta=0.002, )
def test_running_multiple_add_components(self): s = SixS() real_intp = [0.0] * 20 imag_intp = [0.0] * 20 # Running these lines more than twice used to give an error for i in range(4): s.aeroprofile = AeroProfile.MultimodalLogNormalDistribution( 0.085, 2.9) s.aeroprofile.add_component( rmean=2.65, sigma=0.62, percentage_density=0.093, refr_real=real_intp, refr_imag=imag_intp, )
def test_6s_example2(self): # Implements Example_In_2.txt from the 6S distribution in Py6S # Tests against manual run of that file s = SixS() s.geometry = Geometry.User() s.geometry.solar_z = 0 s.geometry.solar_a = 20 s.geometry.view_z = 30 s.geometry.view_a = 0 s.geometry.month = 8 s.geometry.day = 22 s.atmos_profile = AtmosProfile.PredefinedType( AtmosProfile.NoGaseousAbsorption) s.aero_profile = AeroProfile.SunPhotometerDistribution( [ 0.050000001, 0.065604001, 0.086076997, 0.112939, 0.148184001, 0.194428995, 0.255104989, 0.334715992, 0.439173013, 0.576227009, 0.756052017, 0.99199599, 1.30157101, 1.707757, 2.24070191, 2.93996596, 3.85745192, 5.06126022, 6.64074516, 8.71314526, 11.4322901, 15, ], [ 0.001338098, 0.007492487, 0.026454749, 0.058904506, 0.082712278, 0.073251031, 0.040950641, 0.014576218, 0.003672085, 0.001576356, 0.002422644, 0.004472982, 0.007452302, 0.011037065, 0.014523974, 0.016981738, 0.017641816, 0.016284294, 0.01335547, 0.009732267, 0.006301342, 0.003625077, ], [1.47] * 20, [0.0093] * 20, ) s.aot550 = 1.0 s.altitudes.set_target_sea_level() s.altitudes.set_sensor_satellite_level() s.wavelength = Wavelength(0.550) s.ground_reflectance = GroundReflectance.HomogeneousRoujean( 0.037, 0.0, 0.133) s.run() self.assertAlmostEqual(s.outputs.apparent_radiance, 76.999, delta=0.002) self.assertAlmostEqual(s.outputs.background_radiance, 10.017, delta=0.002)
def test_6s_example4(self): s = SixS() s.geometry = Geometry.User() s.geometry.solar_z = 61.23 s.geometry.solar_a = 18.78 s.geometry.solar_a = 0 s.geometry.view_z = 18.78 s.geometry.view_a = 159.2 s.geometry.month = 4 s.geometry.day = 30 s.atmos_profile = AtmosProfile.UserWaterAndOzone(0.29, 0.41) s.aero_profile = AeroProfile.PredefinedType(AeroProfile.Continental) s.aot550 = 0.14 s.altitudes.set_target_sea_level() s.altitudes.set_sensor_satellite_level() s.wavelength = Wavelength(PredefinedWavelengths.AVHRR_NOAA11_B1) s.ground_reflectance = GroundReflectance.HomogeneousLambertian([ 0.827, 0.828, 0.828, 0.827, 0.827, 0.827, 0.827, 0.826, 0.826, 0.826, 0.826, 0.825, 0.826, 0.826, 0.827, 0.827, 0.827, 0.827, 0.828, 0.828, 0.828, 0.829, 0.829, 0.828, 0.826, 0.826, 0.825, 0.826, 0.826, 0.826, 0.827, 0.827, 0.827, 0.826, 0.825, 0.826, 0.828, 0.829, 0.830, 0.831, 0.833, 0.834, 0.835, 0.836, 0.836, 0.837, 0.838, 0.838, 0.837, 0.836, 0.837, 0.837, 0.837, 0.840, 0.839, 0.840, 0.840, 0.841, 0.841, 0.841, 0.841, 0.842, 0.842, 0.842, 0.842, 0.843, 0.842, 0.843, 0.843, 0.843, 0.843, 0.843, 0.843, 0.841, 0.841, 0.842, 0.842, 0.842, 0.842, 0.842, 0.841, 0.840, 0.841, 0.838, 0.839, 0.837, 0.837, 0.836, 0.832, 0.832, 0.830, 0.829, 0.826, 0.826, 0.824, 0.821, 0.821, 0.818, 0.815, 0.813, 0.812, 0.811, 0.810, 0.808, 0.807, 0.807, 0.812, 0.808, 0.806, 0.807, 0.807, 0.807, 0.807, ]) s.run() self.assertAlmostEqual(s.outputs.apparent_radiance, 170.771, delta=0.002)
def test_6s_example3(self): s = SixS() s.geometry = Geometry.Landsat_TM() s.geometry.month = 5 s.geometry.day = 9 s.geometry.gmt_decimal_hour = 11.222 s.geometry.latitude = 40 s.geometry.longitude = 30 s.atmos_profile = AtmosProfile.PredefinedType( AtmosProfile.MidlatitudeSummer) s.aero_profile = AeroProfile.MultimodalLogNormalDistribution(0.001, 20) s.aero_profile.add_component( 0.05, 2.03, 0.538, [ 1.508, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.495, 1.490, 1.490, 1.490, 1.486, 1.480, 1.470, 1.460, 1.456, 1.443, 1.430, 1.470, ], [ 3.24e-07, 3.0e-08, 2.86e-08, 2.51e-08, 2.2e-08, 2.0e-08, 1.0e-08, 1.0e-08, 1.48e-08, 2.0e-08, 6.85e-08, 1.0e-07, 1.25e-06, 3.0e-06, 3.5e-04, 6.0e-04, 6.86e-04, 1.7e-03, 4.0e-03, 1.4e-03, ], ) s.aero_profile.add_component( 0.0695, 2.03, 0.457, [ 1.452, 1.440, 1.438, 1.433, 1.432, 1.431, 1.431, 1.430, 1.429, 1.429, 1.429, 1.428, 1.427, 1.425, 1.411, 1.401, 1.395, 1.385, 1.364, 1.396, ], [ 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.38e-08, 1.47e-08, 1.68e-08, 1.93e-08, 4.91e-08, 1.75e-07, 9.66e-06, 1.94e-04, 3.84e-04, 1.12e-03, 2.51e-03, 1.31e-01, ], ) s.aero_profile.add_component( 0.4, 2.03, 0.005, [ 1.508, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.495, 1.490, 1.490, 1.490, 1.486, 1.480, 1.470, 1.460, 1.456, 1.443, 1.430, 1.470, ], [ 3.24e-07, 3.0e-08, 2.86e-08, 2.51e-08, 2.2e-08, 2.0e-08, 1.0e-08, 1.0e-08, 1.48e-08, 2.0e-08, 6.85e-08, 1.0e-07, 1.25e-06, 3.0e-06, 3.5e-04, 6.0e-04, 6.86e-04, 1.7e-03, 4.0e-03, 1.4e-03, ], ) s.aot550 = 0.8 s.altitudes.set_target_custom_altitude(2) s.altitudes.set_sensor_satellite_level() s.wavelength = Wavelength(PredefinedWavelengths.MODIS_B4) s.ground_reflectance = GroundReflectance.HomogeneousOcean( 11, 30, 35, 3) s.run() self.assertAlmostEqual(s.outputs.apparent_reflectance, 0.1234623, delta=0.002)
def test_aero_profile_errors(self): with self.assertRaises(ParameterError): AeroProfile.User(dust=0.8, oceanic=0.4)
def test_multimodal_dist_errors1(self): with self.assertRaises(ParameterError): ap = AeroProfile.MultimodalLogNormalDistribution(0.001, 20) # Add > 4 components ap.add_component( 0.05, 2.03, 0.538, [ 1.508, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.495, 1.490, 1.490, 1.490, 1.486, 1.480, 1.470, 1.460, 1.456, 1.443, 1.430, 1.470, ], [ 3.24e-07, 3.0e-08, 2.86e-08, 2.51e-08, 2.2e-08, 2.0e-08, 1.0e-08, 1.0e-08, 1.48e-08, 2.0e-08, 6.85e-08, 1.0e-07, 1.25e-06, 3.0e-06, 3.5e-04, 6.0e-04, 6.86e-04, 1.7e-03, 4.0e-03, 1.4e-03, ], ) ap.add_component( 0.0695, 2.03, 0.457, [ 1.452, 1.440, 1.438, 1.433, 1.432, 1.431, 1.431, 1.430, 1.429, 1.429, 1.429, 1.428, 1.427, 1.425, 1.411, 1.401, 1.395, 1.385, 1.364, 1.396, ], [ 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.0e-08, 1.38e-08, 1.47e-08, 1.68e-08, 1.93e-08, 4.91e-08, 1.75e-07, 9.66e-06, 1.94e-04, 3.84e-04, 1.12e-03, 2.51e-03, 1.31e-01, ], ) ap.add_component( 0.4, 2.03, 0.005, [ 1.508, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.495, 1.490, 1.490, 1.490, 1.486, 1.480, 1.470, 1.460, 1.456, 1.443, 1.430, 1.470, ], [ 3.24e-07, 3.0e-08, 2.86e-08, 2.51e-08, 2.2e-08, 2.0e-08, 1.0e-08, 1.0e-08, 1.48e-08, 2.0e-08, 6.85e-08, 1.0e-07, 1.25e-06, 3.0e-06, 3.5e-04, 6.0e-04, 6.86e-04, 1.7e-03, 4.0e-03, 1.4e-03, ], ) ap.add_component( 0.4, 2.03, 0.005, [ 1.508, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.495, 1.490, 1.490, 1.490, 1.486, 1.480, 1.470, 1.460, 1.456, 1.443, 1.430, 1.470, ], [ 3.24e-07, 3.0e-08, 2.86e-08, 2.51e-08, 2.2e-08, 2.0e-08, 1.0e-08, 1.0e-08, 1.48e-08, 2.0e-08, 6.85e-08, 1.0e-07, 1.25e-06, 3.0e-06, 3.5e-04, 6.0e-04, 6.86e-04, 1.7e-03, 4.0e-03, 1.4e-03, ], ) ap.add_component( 0.4, 2.03, 0.005, [ 1.508, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.500, 1.495, 1.490, 1.490, 1.490, 1.486, 1.480, 1.470, 1.460, 1.456, 1.443, 1.430, 1.470, ], [ 3.24e-07, 3.0e-08, 2.86e-08, 2.51e-08, 2.2e-08, 2.0e-08, 1.0e-08, 1.0e-08, 1.48e-08, 2.0e-08, 6.85e-08, 1.0e-07, 1.25e-06, 3.0e-06, 3.5e-04, 6.0e-04, 6.86e-04, 1.7e-03, 4.0e-03, 1.4e-03, ], )