robintw / py6s Goto Github PK
View Code? Open in Web Editor NEWA Python interface to the 6S Radiative Transfer Model
License: GNU Lesser General Public License v3.0
A Python interface to the 6S Radiative Transfer Model
License: GNU Lesser General Public License v3.0
Hello, I stumbled upon what I think is an issue with the U of Wyoming Radiosonde import helper function SixSHelpers.radiosonde.import_uow_radiosonde_data
, where, due to an issue with some of U of W's data, the absolute humidity ends up being set to zero for the first atmospheric "slice" from 0 to 1 km.
This stems from an issue in U of Wyoming's interpolation of the raw Radiosonde data that sometimes (and for periods of months at a time) generates a partially empty row at the top of their text file. See for instance:
this URL for Lincoln, IL, USA, 2019-10-31 00:00Z
Where the first few lines are:
1000.0 143
996.0 178 3.6 3.0 96 4.79 10 8 277.1 290.3 277.9
992.0 211 3.4 2.7 95 4.71 11 9 277.2 290.2 278.0`
The raw IGRA radiosonde data does have valid data starting at the very first point, so that partly empty line must be coming from U of W's interpolation? This is the header and first line of the raw radiosonde data for that day:
#USM00074560 2018 11 15 00 2302 189 ncdc-nws ncdc-nws 401517 -893383
21 0 100826B 179 -20B 750 38 54 21
Now, when import_uow_radiosonde_data
calls this on L323:
array = np.genfromtxt(s,skip_header=4, delimiter=7,usecols=(0, 1, 2, 5),filling_values=0)
...
mixing_ratio = array[:, 3]
mixing_ratio[0]
(and all other missing parameters) is set to zero.
Then when _import_from_arrays
interpolates the zero altitude point from this:
f_interp_mixrat = interp1d(altitude, mixing_ratio, bounds_error=False, fill_value=mixing_ratio[0])
We end up with zero absolute humidity at zero altitude, only picking it up again at 1 km. I haven't checked the total precipitable water integration that happens next, but I'm guessing this zero humidity point will have a fairly large effect on that?
The intent here is good, to set the zero altitude point to the lowest altitude radiosonde point (often ~100m), but that partially empty row in the U of W data ends up setting mixing_ratio[0]
to zero and thus also zeroes the humidity of the zero altitude point.
I don't know how widespread this U of W issue is, but it covers at least several months of 2019 historical data for this particular station (it appears to have gone away 15 days ago?).
I would propose a fix along the following lines, checking if the first U of W data row has an invalid number of columns and skip past it if so:
table = "\n".join(spl)
# Check for partly empty first line in U of W data which impacts interpolations:
if len(table.split('\n')[4].split()) != 11:
num_skip = 5
else:
num_skip = 4
# Import to NumPy arrays
s = io.BytesIO(table.encode())
array = np.genfromtxt(s,skip_header=num_skip, delimiter=7,usecols=(0, 1, 2, 5),filling_values=0)
A more general solution might check the first few rows, but so far I've only seen this issue in the first row.
It has been a few years since the last time I used Py6S and now that I revisited, I was trying to remember the difference between "apparent_reflectance" and "pixel_reflectance". Looking at the code to find an answer I read:
Line 168 in cf26368
Surely if it is reflectance should be adimensional? The line just before is "apparent_radiance" so I guess this is a typo.
the Rayleigh scattering look-up table can be built by using py6s?
Calling s.altitudes.set_sensor_satellite_level() should set the sensor altitude to satellite level regardless, but this doesn't work if the sensor has previously been set to a custom altitude.
Hello,
I've run into an issue with the subprocess call in sixs.py, line 291:
process = subprocess.Popen("%s < %s" % (self.sixs_path, tmp_file_name), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
The command segfaults due to the use of stdin redirection:
sixs < inputfile
whereas I've always just called sixs handing it an input filename:
sixs inputfile
This isn't really a Py6S issue since it obviously works on other machines, but I can't figure out if this is a platform issue or how Py6S is compiled on my machine? (ubuntu w bash shell).
I've also verified at the command line that it is the redirection that causes the segfault.
Hi, when following the instructions and installing Py6S with conda on a Mac:
conda create -n py6s-env -c conda-forge py6s
The test fails:
from Py6S import *
SixS.test()
6S wrapper script by Robin Wilson
Using 6S located at /Users/maxim/opt/anaconda3/envs/py6s-env/bin/sixs
Running 6S using a set of test parameters
b'Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG\n'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/maxim/opt/anaconda3/envs/py6s-env/lib/python3.6/site-packages/Py6S/sixs.py", line 354, in test
test.run()
File "/Users/maxim/opt/anaconda3/envs/py6s-env/lib/python3.6/site-packages/Py6S/sixs.py", line 315, in run
self.outputs = Outputs(outputs[0], outputs[1])
File "/Users/maxim/opt/anaconda3/envs/py6s-env/lib/python3.6/site-packages/Py6S/outputs.py", line 64, in __init__
raise OutputParsingError("6S returned an error (shown above) - check for invalid parameter inputs")
Py6S.sixs_exceptions.OutputParsingError: 6S returned an error (shown above) - check for invalid parameter inputs
I've tried with different versions of Py6S in conda-forge and different versions of Python, all yield the same error.
Pip installed Py6S and ran:
>>> from Py6S import *
>>> SixS.test()
6S wrapper script by Robin Wilson
Using 6S located at /Users/dwelch/virtualenvs/atmocorrect/bin/sixs
Running 6S using a set of test parameters
The results are:
Expected result: 619.158000
Actual result: 619.158000
#### Results agree, Py6S is working correctly
0
but this IS NOT a test suite (or even a real test, since it doesn't run anything but the default values!). I have two users with different environments/versions, etc., both with "passing" reports but vastly different results for their outputs when being used "in the wild".
One hallmark of software design is that it's better to have no tests than tests that mislead users with inadequate/invalid coverage. What happens is developers start depending on the 'bad' tests and introduce bugs that only pass the 'bad' tests.
Please add a README file to your repository.
This really helps to improve the sustainability of your software, and helps others pick up your code and get running with it easily.
(This issue was created by the Open Source Health Checker tool at www.healthchecker.io)
Hi Robin, i`m new with Py6S. I intend to use it for teaching and i have to run it in google colab. I have followed all instructions and everything seems OK, but whwn i try to run it, it crashes and sends this error message:
6S wrapper script by Robin Wilson
Using 6S located at /usr/local/bin/sixsV1.1
Running 6S using a set of test parameters
Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG
OutputParsingError Traceback (most recent call last)
in ()
----> 1 s.test()
2 frames
/usr/local/lib/python3.7/dist-packages/Py6S/outputs.py in init(self, stdout, stderr)
69 print(stderr)
70 raise OutputParsingError(
---> 71 "6S returned an error (shown above) - check for invalid parameter inputs"
72 )
73 elif (
OutputParsingError: 6S returned an error (shown above) - check for invalid parameter inputs
I am not very skilfull at programming so i cant realize what is going bad. I`ll apreciate very much if you can give a hand.
Thanks in advance!!!
Please add a README! Test from OpenSourceHealthCheck
When using s.altitudes.set_sensor_custom_altitude() you don't have to specify AOT, if you don't (ie. give -1) then it will be calculated from a standard 2km extinction profile.
hi, i'm getting familiar with this tool. I'm using it without a problem from the windows prompt or iphyton but when a try to open a jupyter notebook it keeps freezing. I can see that the implementation has some years by now, could that be the problem? I could be important to use py6s from inside them to be able to use their outputs all together on a script.
thanks.
Hello,I'm not familiar with this tool,and I have a problem to change the parament "visibility".When i change visibility to 40.0,it doesn‘work.Or it cannot be modified once i choose specific aero_profile or atmos_profile?
Hello,
We're using Py6S for some time now and everything works smoothly, thanks a lot 👍!
But today we noticed an issue when Py6S is used with numpy 1.20.0. The issue is easily reproducible thanks to the RunAllWavelengthsTests
unit test of Py6S.
Unit tests are green in a virtualenv with numpy 1.19.5:
$ virtualenv venv_numpy_1_19_5
$ source venv_numpy_1_19_5/bin/activate
(venv_numpy_1_19_5) $ pip install numpy==1.19.5 scipy matplotlib pytest
(venv_numpy_1_19_5) $ pytest test/test_run_all_wavelengths.py
========================================== test session starts ===========================================
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /tmp/Py6S
collected 2 items
test/test_run_all_wavelengths.py .. [100%]
=========================================== 2 passed in 9.29s ===========================================
But there's an exception when the last version of numpy (1.20.0) is used:
$ virtualenv venv_numpy_1_20_0
$ source venv_numpy_1_20_0/bin/activate
(venv_numpy_1_20_0) $ pip install numpy scipy matplotlib pytest
(venv_numpy_1_20_0) $ pytest test/test_run_all_wavelengths.py
========================================== test session starts ===========================================
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /tmp/Py6S
collected 2 items
E Py6S.sixs_exceptions.OutputParsingError: The specifed output variable does not exist.
...
...
pip install py6s
install pysolar-0.7
which is incompatible with python 2. In order to solve this, the pysolar
version should be specified in setup.py
. I will make a pull request shortly.
Lookup Tables (LUTs) are really useful for various applications where Py6S simulations are run many times - they can speed up things like atmospheric correction to make them actually possible!
I have preliminary versions of this running as part of my PhD, and will be hopefully releasing them as part of Py6S in the future.
Hello,
I'm trying to use the SixS.altitudes.set_target_pressure
command but it doesn't seem to have any effect on the simulation results.
For example:
# Initialise
s = SixS()
# Sensor is TOA
s.altitudes.set_sensor_satellite_level()
# Set atmospheric profile with WV and Ozone
s.atmos_profile = AtmosProfile.UserWaterAndOzone(3.6, 0.9)
# Set aerosol profile
s.aero_profile = AeroProfile.PredefinedType(AeroProfile.Maritime)
# Set wavelength range
s.wavelength = Wavelength(0.5)
for pres in np.arange(400, 1000, 50):
s.altitudes.set_target_pressure(pres)
s.run()
print(pres,
s.outputs.atmospheric_intrinsic_reflectance,
s.outputs.total_gaseous_transmittance)
Returns:
400 0.094 0.942
450 0.094 0.942
500 0.094 0.942
550 0.094 0.942
600 0.094 0.942
650 0.094 0.942
700 0.094 0.942
750 0.094 0.942
800 0.094 0.942
850 0.094 0.942
900 0.094 0.942
950 0.094 0.942
i.e: The reflectance and transmittance do not appear to change.
If I instead iterate over altitude using:
for alt in np.arange(10, 0, -1):
s.altitudes.set_target_custom_altitude(alt)
Then as expected I do get changes in the above values:
10 0.054 0.946
9 0.056 0.945
8 0.059 0.945
7 0.062 0.945
6 0.065 0.944
5 0.069 0.944
4 0.073 0.943
3 0.078 0.943
2 0.083 0.943
1 0.088 0.942
Do you have any ideas why set_target_pressure
might not be working?
Certain wavelengths such as 761 nm are returning NaN irradiance (in some cases over a 1.2 nm range corresponding to two sampling points at the 10 cm^-1 resolution?). I am putting in 30% broadband surface albedo and moderate AOT and water content, have not experimented with reducing those yet to see if this still occurs.
I found this 2014 thread here that implies this may be a 6S issue. I'm not sure if there is more up to date information or a fix for this, or if this is still a fundamental 6S issue?
https://groups.google.com/forum/m/#!topic/py6s/vUwoQ_DWBTk
Wavelengths at which I'm getting NaN irradiance (grid with 1 nm spacing):
Full debug report and output full text
Py6S Debugging Report --------------------- Run on 2020-06-12 11:04:05.180328 Platform: Windows-10-10.0.18362-SP0 Python version: 3.7.6 | packaged by conda-forge | (default, Jun 1 2020, 18:11:50) [MSC v.1916 64 bit (AMD64)] Py6S version: 1.8.0 --------------------- 6S wrapper script by Robin Wilson Using 6S located at C:\Users\Ceres\AppData\Local\conda\conda\envs\improc\Library\bin\sixs.exe Running 6S using a set of test parameters 6sV version: 1.1 The results are: Expected result: 619.158000 Actual result: 619.158000 #### Results agree, Py6S is working correctly --------------------- 0 (User defined) 21.307878 133.471212 0.000000 0.000000 6 5 8 (Water Vapour and Ozone) 2.981510 0.324494 1 0 0.093113 value 0.000000 0.000000 -1 0.500000 0 Homogeneous surface 0 No directional effects 0 0.3 -1 No atm. corrections selected
Output full text:
******************************* 6SV version 1.1 ******************************* * * * geometrical conditions identity * * ------------------------------- * * user defined conditions * * * * month: 6 day : 5 * * solar zenith angle: 21.31 deg solar azimuthal angle: 133.47 deg * * view zenith angle: 0.00 deg view azimuthal angle: 0.00 deg * * scattering angle: 158.69 deg azimuthal angle difference: 133.47 deg * * * * atmospheric model description * * ----------------------------- * * atmospheric model identity : * * user defined water content : uh2o= 2.982 g/cm2 * * user defined ozone content : uo3 = 0.324 cm-atm * * aerosols type identity : * * Continental aerosol model * * optical condition identity : * * visibility : 69.61 km opt. thick. 550 nm : 0.0931 * * * * spectral condition * * ------------------ * * monochromatic calculation at wl 0.761 micron * * * * Surface polarization parameters * * ---------------------------------- * * * * * * Surface Polarization Q,U,Rop,Chi 0.00000 0.00000 0.00000 0.00 * * * * * * target type * * ----------- * * homogeneous ground * * monochromatic reflectance 0.300 * * * * target elevation description * * ---------------------------- * * ground pressure [mb] 1013.00 * * ground altitude [km] 0.000 * * * * plane simulation description * * ---------------------------- * * plane pressure [mb] 1013.00 * * plane altitude absolute [km] 0.000 * * atmosphere under plane description: * * ozone content 0.000 * * h2o content 0.000 * * aerosol opt. thick. 550nm 0.000 * * * ******************************************************************************* ******************************************************************************* * * * integrated values of : * * -------------------- * * * * apparent reflectance NaN appar. rad.(w/m2/sr/mic) NaN * * total gaseous transmittance 0.378 * * * ******************************************************************************* * * * coupling aerosol -wv : * * -------------------- * * wv above aerosol : NaN wv mixed with aerosol : NaN * * wv under aerosol : NaN * ******************************************************************************* * * * integrated values of : * * -------------------- * * * * app. polarized refl. 0.0000 app. pol. rad. (w/m2/sr/mic) 0.000 * * direction of the plane of polarization 0.00 * * total polarization ratio NaN * * * ******************************************************************************* * * * int. normalized values of : * * --------------------------- * * % of irradiance at ground level * * % of direct irr. % of diffuse irr. % of enviro. irr * * 0.000 0.000 0.000 * * reflectance at satellite level * * atm. intrin. ref. background ref. pixel reflectance * * 0.000 NaN NaN * * * * int. absolute values of * * ----------------------- * * irr. at ground level (w/m2/mic) * * direct solar irr. atm. diffuse irr. environment irr * * NaN NaN NaN * * rad at satel. level (w/m2/sr/mic) * * atm. intrin. rad. background rad. pixel radiance * * 0.000 NaN NaN * * * * * * sol. spect (in w/m2/mic) * * 1207.242 * * * ******************************************************************************* ******************************************************************************* * * * integrated values of : * * -------------------- * * * * downward upward total * * global gas. trans. : 0.37803 1.00000 0.37803 * * water " " : 1.00000 1.00000 1.00000 * * ozone " " : 0.99748 1.00000 0.99748 * * co2 " " : 1.00000 1.00000 1.00000 * * oxyg " " : 0.37899 1.00000 0.37899 * * no2 " " : 1.00000 1.00000 1.00000 * * ch4 " " : 1.00000 1.00000 1.00000 * * co " " : 1.00000 1.00000 1.00000 * * * * * * rayl. sca. trans. : NaN NaN NaN * * aeros. sca. " : NaN NaN NaN * * total sca. " : NaN NaN NaN * * * * * * * * rayleigh aerosols total * * * * spherical albedo : NaN NaN NaN * * optical depth total: NaN 0.06524 NaN * * optical depth plane: 0.00000 0.00000 0.00000 * * reflectance I : 0.00000 0.00000 0.00000 * * reflectance Q : 0.00000 0.00000 0.00000 * * reflectance U : 0.00000 0.00000 0.00000 * * polarized reflect. : 0.00000 0.00000 0.00000 * * degree of polar. : NaN 0.00 NaN * * dir. plane polar. : -45.00 -45.00 -45.00 * * phase function I : 1.38442 0.23668 NaN * * phase function Q : -0.09495 0.04385 NaN * * phase function U : -1.33978 -0.13987 NaN * * primary deg. of pol: -0.06858 0.18526 NaN * * sing. scat. albedo : 1.00000 0.87229 NaN * * * * * *******************************************************************************
Hello,
I'm having several problems installing and running Py6S:
Traceback (most recent call last):
File "/Users/ehzjl/PycharmProjects/Py6S_test/main.py", line 2, in
from Py6S import *
ModuleNotFoundError: No module named 'Py6S'
Then, I run pip install py6s, which solved the module errore for Ipython and Jupiter, but not for PyCharm.
I then tried to continue with the Quick Start commands, but it returns this error:
Running for many wavelengths - this may take a long time
ExecutionError Traceback (most recent call last)
in
----> 1 wavelengths, results = SixSHelpers.Wavelengths.run_vnir(s, output_name="pixel_radiance")/opt/anaconda3/lib/python3.8/site-packages/Py6S/SixSHelpers/all_wavelengths.py in run_vnir(cls, s, spacing, **kwargs)
129
130 wv = np.arange(0.400, 1.400, spacing)
--> 131 return cls.run_wavelengths(s, wv, **kwargs)
132
133 @classmethod/opt/anaconda3/lib/python3.8/site-packages/Py6S/SixSHelpers/all_wavelengths.py in run_wavelengths(cls, s, wavelengths, output_name, n, verbose)
88
89 print("Running for many wavelengths - this may take a long time")
---> 90 results = pool.map(f, wavelengths)
91
92 pool.close()/opt/anaconda3/lib/python3.8/multiprocessing/pool.py in map(self, func, iterable, chunksize)
362 in a list that is returned.
363 '''
--> 364 return self._map_async(func, iterable, mapstar, chunksize).get()
365
366 def starmap(self, func, iterable, chunksize=None):/opt/anaconda3/lib/python3.8/multiprocessing/pool.py in get(self, timeout)
769 return self._value
770 else:
--> 771 raise self._value
772
773 def _set(self, i, obj):/opt/anaconda3/lib/python3.8/multiprocessing/pool.py in worker(inqueue, outqueue, initializer, initargs, maxtasks, wrap_exception)
123 job, i, func, args, kwds = task
124 try:
--> 125 result = (True, func(*args, **kwds))
126 except Exception as e:
127 if wrap_exception and func is not _helper_reraises_exception:/opt/anaconda3/lib/python3.8/multiprocessing/pool.py in mapstar(args)
46
47 def mapstar(args):
---> 48 return list(map(*args))
49
50 def starmapstar(args):/opt/anaconda3/lib/python3.8/site-packages/Py6S/SixSHelpers/all_wavelengths.py in f(wv)
68 if verbose:
69 print(wv)
---> 70 a.run()
71 if output_name is None:
72 return a.outputs/opt/anaconda3/lib/python3.8/site-packages/Py6S/sixs.py in run(self)
342
343 if self.sixs_path is None:
--> 344 raise ExecutionError("6S executable not found.")
345
346 # Create the input file as a temporary fileExecutionError: 6S executable not found.
How about making matplotlib
an optional dependency? It is only used in a single place in the main code:
Py6S/Py6S/SixSHelpers/all_wavelengths.py
Line 778 in bbfbca9
I can make a PR if you like.
I'm just getting started with Py6S version 1.7.2. When I run the following:
s = SixS()
wavelengths, results = SixSHelpers.Wavelengths.run_vnir(s, output_name="pixel_radiance")
# Plot these results, with the y axis label set to "Pixel Radiance"
SixSHelpers.Wavelengths.plot_wavelengths(wavelengths, results, "Pixel Radiance");
I get a lengthy output to stdout.
It took some digging but I found run_wavelengths has verbose=True. I wonder if this would be better with a default False or at least some documentation on how to suppress the output when running run_vnir etc.
I'm happy to attempt a modification and pull request.
I am a inexperienced 6S/Py6S user so this might not be an issue with Py6S, but rather, my misunderstanding of how 6S/Py6S works.
I would like to compute the pixel_radiance
in the principal plane when the ground is a black surface (i.e. homogeneous lambertian surface with null reflectance) and the atmosphere is free of aerosols and scatters light but does not absorb it. The sun zenith and azimuth angles are 50 and 0 degrees, respectively. The sensor altitude is satellite level (which I assume, means that the pixel radiance is measured at the top of the atmosphere) and the target altitude is sea level (which I assume, means that the sensor simply looks down at the ground).
I expect the resulting pixel radiance values to be non zero, as the atmosphere scatters some of the sun light back. However, I get zero values.
Here is the code, that I've used to obtain these results:
from Py6S import *
import numpy as np
import matplotlib.pyplot as plt
def make_scene():
# arbitrary wavelength value
s.wavelength = Wavelength(0.550)
# atmosphere does not absorb
s.atmos_profile = AtmosProfile.PredefinedType(AtmosProfile.NoGaseousAbsorption)
# ground is a homogeneous lambertian surface with a reflectance of zero (i.e. black surface)
s.ground_reflectance = GroundReflectance.HomogeneousLambertian(0.)
# no aerosols
s.aero_profile = AeroProfile.PredefinedType(AeroProfile.NoAerosols)
s.aot550 = 0.
s.visibility = None
# sun zenith is 50°
s.geometry = Geometry.User()
s.geometry.solar_z = 50.
s.geometry.solar_a = 0.
# sensor is at the top of the atmosphere and looks down at the surface
s.altitudes = Altitudes()
s.altitudes.set_target_sea_level()
s.altitudes.set_sensor_satellite_level()
# no atmospheric correction
s.atmos_corr = AtmosCorr.NoAtmosCorr()
return s
def run_principal_plane(signed_view_z):
s = make_scene()
pixel_radiances = []
s.geometry.view_a = 180.
for view_z in signed_view_z[signed_view_z<0]:
s.geometry.view_z = -view_z
s.run()
pixel_radiances.append(s.outputs.pixel_radiance)
s.geometry.view_a = 0.
for view_z in signed_view_z[signed_view_z>=0]:
s.geometry.view_z = view_z
s.run()
pixel_radiances.append(s.outputs.pixel_radiance)
return np.array(pixel_radiances)
# compute
signed_view_z = np.linspace(-89, 89, 179)
pixel_radiances = run_principal_plane(signed_view_z)
# plot
plt.figure(figsize=(10, 8))
plt.plot(signed_view_z, pixel_radiances)
plt.xlabel('Signed viewing zenith angle [deg]')
plt.ylabel('Pixel radiance [W/m^2/str/μm]')
plt.annotate(text="Sun", xy=(50, 0), xytext=(50, max(pixel_radiances)/2), arrowprops={"arrowstyle":"->"})
plt.show()
Am I wrong to expect non-zero pixel radiance values here?
I thought that the scene prepared by the above make_scene
function would be a purely molecular scattering atmosphere on top of a all-absorbing surface, that we observe from the top. Am I building the scene correctly?
Does the NoGaseousAbsorption
atmospheric profile only "disable" gaseous absorption or does it also disables scattering by the air molecules?
If I vary the surface reflectance value so that it tends toward zero (from 1e-1
to 1e-6
), the pixel radiance values also seem to tend towards zero.
If that can be useful, the corresponding 6S input file (generated by SixS.write_input_file
for one value of view_z
) is:
0 (User defined)
50.000000 0.000000 45.000000 0.000000 1 1
0
0
0
0.000000 value
0.000000
-1000.000000
-1
0.550000
0 Homogeneous surface
0 No directional effects
0
0.0
-1 No atm. corrections selected
ASTER band 8 in the PredefinedWavelengths class of wavelength.py does not seem to be correct. The Start Wavelength (2.25) is higher than the End Wavelength (2.244).
(line 732 of wavelength.py) ASTER_B8 = (-136, 2.250, 2.244)
The original 6S fortran code (attached) assigns the values of 2.21 and 2.39, respectively.
ASTER.zip
However, the 6S values are also odd. This is because the fortran array for the band 8 spectral filter function has 76 elements, yet the spectral range (2.39-2.21) divided by the spectral increment (0.0025) would require a 72 element array.
Py6s has dependency on Pysolar 0.6 which is a release 7 years ago.
Please consider switch to newer pysolar repo or remove the dependency.
Dear Robintw:
I am using the 6sv model recently, but I have encountered a little problem. I found your code, but I would like to know how to calculate the percentage density of the aerosol when customizing the aerosol model. I look forward to your reply, thank you!
The Sentinel 3 OLCI has some very narrow bands and the predefined 2.5 nm is too broad to capture the exact shape of them (showing in the figure below):
There seems to be no simple way to change the spectral resolution in 6S from 2.5nm to 1nm. Suggested method to get around with it would be to compute variables (such as reflectance) at 2.5nm, and interpolated to 1nm, then do a multiplication of bandpass for Sentinel 3 narrow bands. Or, try at least to adapt Predefined wavelengths to have the same peak as the original Sentinel 3 RSRs...
But the above suggestions are only based on intuitive understandings, and further quantitative analysis is needed....
Marc.
in
early.ground_reflectance = GroundReflectance.HeterogeneousLambertian(GroundReflectance.GreenVegetation)
TypeError: HeterogeneousLambertian() missing 2 required positional arguments: 'ro_target' and 'ro_env'
Py6S/Py6S/SixSHelpers/aeronet.py
Line 115 in 2a606a4
ix has been depreciated from pandas for a while and was dropped after pandas v1.0. Suggest to replace ix with iloc. We need search entire project to refactor ix to iloc
Python 3.7.3 (default, Mar 27 2019, 22:11:17)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.4.0 -- An enhanced Interactive Python. Type '?' for help.
PyDev console: using IPython 7.4.0
Python 3.7.3 (default, Mar 27 2019, 22:11:17)
[GCC 7.3.0] on linux
from Py6S import *
s = SixS()
s.wavelength = Wavelength(0.675)
s.aero_profile = AeroProfile.PredefinedType(AeroProfile.Maritime)
s.run()
Traceback (most recent call last):
File "/home/rohit/anaconda3/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3296, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "", line 1, in
s.run()
File "/home/rohit/Downloads/Py6S-master (1)/Py6S/sixs.py", line 322, in run
raise ExecutionError("6S executable not found.")
Py6S.sixs_exceptions.ExecutionError: 6S executable not found.
I can import all thing of Py6S by from Py6S import *
in python but when I do this through IPython its throw ImportError: No module named Py6S
. What the probably reasons ?
Add importers for spectra collected using field spectrometers to Py6S.SixSHelpers.spectra
. Specifically make importer for .sig format files, developed by @arsf for internal use, available within Py6S.
For more details on the format see FSF import guide (pdf)
(Opening issue as a reminder I had discussed with @robintw doing this. If anyone wants the reader before a pull request is submitted to Py6S let me know).
Currently, when accidentally using 6S-V2.1 instead of the legacy V1.1 version, Py6S does not give an error but gives wrong values instead.
As the output of 6S-V2.1 is very similar to the output of V1.1, Py6S apparently does not fail to parse the file. However, the newer output has 2 extra lines in the upper part of the ouput, as can be seen in this diff between an output of 6S-V2.1 and V1.1 when run on the same input file:
diff Example_Out_1.txt test.out
6c6
< ******************************* 6SV version 1.1 *******************************
---
> ******************************* 6SV version 2.1 *******************************
55,57c55
< * ground altitude [km] 0.200 *
< * gaseous content at target level: *
< * uh2o= 3.000 g/cm2 uo3= 3.500 cm-atm *
---
> * ground altitude [km]-0.200 *
82c80
< * apparent reflectance 0.0330894 appar. rad.(w/m2/sr/mic) 12.749 *
---
> * apparent reflectance 0.0330914 appar. rad.(w/m2/sr/mic) 12.750 *
97c95
< * direction of the plane of polarization-27.40 *
---
> * direction of the plane of polarization-27.41 *
115c113
< * 453.572 127.136 3.157 *
---
> * 453.574 127.136 3.157 *
184a183,184
> * coefficients xap xb xc : 2.639795 0.038705 0.068196 *
> * y=xap*(measured reflectance)-xb; acr=y/(1.+xc*y)
Note that most of the differences are irrelevant, and just due to small floating point differences. However, these 2 lines are present in the V2.1 output and are lacking in the V1.1 output, just after the 'ground altitude' line:
gaseous content at target level:
uh2o= 3.000 g/cm2 uo3= 3.500 cm-atm
I suppose Py6S does not check which version of 6S was used, and just parses certain lines from the output file. In case of V2.1, it will therefore parse the wrong values when these lines are past the 2 extra lines.
Proposed solution:
check the version of 6S in the first line of the output file. If not 1.1, give an error instead of giving wrong values.
I'll file another issue to discsuss V2.1 support, which might or might not be as simple as just skipping these extra 2 lines when parsing the output file.
Please add a README file to your repository.
This really helps to improve the sustainability of your software, and helps others pick up your code and get running with it easily.
(This issue was created by the Open Source Health Checker tool at www.healthchecker.io)
open profile: sudo vi /etc/profile
add one line at the end of the file: export PATH=$PATH:/home/'xxx'/build/6SV1.1
notice: 'xxx' is your username
we can only obtain downward and upward transmittance of Rayleigh scattering from current function
The documentation states that you can pass the path argument in the SixS.test() method. This is not possible, at least in the 1.6.1 version.
The current code:
def test(self):
"""Runs a simple test to ensure that 6S and Py6S are installed correctly."""
test = SixS()
should be changes to something like:
def test(cls, path=None):
"""Runs a simple test to ensure that 6S and Py6S are installed correctly."""
test = cls(path)
Also note, that by using the cls name you avoid hard coding the class name, and you are also compatible with PEP8 (https://www.python.org/dev/peps/pep-0008/#function-and-method-arguments).
hello, I wanted to check and see if there is any planned support for LWIR wavelengths to facilitate thermal analyses? and if not, what it may take to do so?
This may include:
If 6S is compiled (linux, debian testing, gfortran4.9) with the flags as in the Py6S documentation, sixs.test() fails because at the end of the 6S output a warning is printed: "Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG". This can be suppressed by adding "-ffpe-summary=none" to the gfortran flags in the Makefile. When compiled with this flag, sixs.test() runs fine.
-> might be a good idea to update the documentation in the linux install section.
Hi, I'd like to try and add support for Himawari-8.
I was wondering is there any intrinsic reason for the 4µm maximum wavelength?
https://github.com/robintw/Py6S/blob/master/Py6S/Params/wavelength.py#L103
Because Himawari-8 has bands with wavelengths up to 13.3µm
https://www.data.jma.go.jp/mscweb/en/himawari89/space_segment/spsg_ahi.html#band
Himawari-8 spectral responsivity function defined here: http://www.data.jma.go.jp/mscweb/en/himawari89/space_segment/srf_201309/AHI-08_SpectralResponsivity.zip
In Geometry.from_time_and_location the datetutil parser is configured with the 'dayfirst' flag which leads to ambiguity in parsing date and datetime strings.
This means that if you pass an unambiguous date string in iso format (e.g. 2020-01-31T...) it is interpreted as YYYY-MM-DD... but if you pass an ambiguous date string (e.g. 2020-02-01T...) it is interpreted as YYYY-DD-MM.
This is probably not the behaviour most people are expecting (i.e. it should always be interpreted in the same order). Might be better to replace datestring kwarg with separate components e.g. Geometry.from_time_and_location(year=2020, month=12, day=1, ...) and let the user handle their own string parsing.
I have installed Py6S in Anaconda, its wavelength.py file has only 1323 lines but the one in master is 1536 lines, can the older be replaced by the newer override directly? thank you!
Spectra can currently be imported from the ASTER and USGS spectral libraries. However, it'd be good to import from ENVI spectral libraries too.
I can't immediately find where the description of this filetype is - but will update here when I can.
The spectral filter function for Landsat ETM panchromatic band seems to be missing from the PredefinedWavelengths class.
https://github.com/robintw/Py6S/blob/master/Py6S/Params/wavelength.py
Using a .dubovik file acquired using the step-by-step method returns error.
/usr/local/lib/python3.6/dist-packages/Py6S/SixSHelpers/aeronet.py in _get_aot(cls, df)
206
207 # Remove the columns for AOT wavelengths with no data
--> 208 aot_df = df.ix[:, inds]
209 aot_df = aot_df.dropna(axis=1, how='all')
210 aot_df = aot_df.dropna(axis=0, how='any')
/usr/local/lib/python3.6/dist-packages/pandas/core/generic.py in __getattr__(self, name)
5272 if self._info_axis._can_hold_identifiers_and_holds_name(name):
5273 return self[name]
-> 5274 return object.__getattribute__(self, name)
5275
5276 def __setattr__(self, name: str, value) -> None:
AttributeError: 'DataFrame' object has no attribute 'ix'
A attribute/key check of the dataframe could be useful to spot errors early on and not raise them within the code.
Hi, the link in the documention failed, could you fix it? Thank you very much!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.