Giter VIP home page Giter VIP logo

py6s's Introduction

image

image

Introduction

Py6S is a Python interface to the 6S Radiative Transfer Model. It allows you to run many 6S simulations using a simple Python syntax, rather than dealing with the rather cryptic 6S input and output files. As well as generally making it easier to use 6S, Py6S adds some new features:

  • The ability to run many simulations easily and quickly, with no manual editing of input files
  • The ability to run for many wavelengths and/or angles and easily plot the results
  • The ability to import real-world data to parameterise 6S, from radiosonde measurements and AERONET sun photometer measurements

Py6S has been designed to be easy to use, and to work on the 'principle of least surprise'. Far more details are available in the rest of this documentation, but a quick code example should give you an idea of what Py6S can do:

# Import the Py6S module
from Py6S import *
# Create a SixS object
s = SixS()
# Set the wavelength to 0.675um
s.wavelength = Wavelength(0.675)
# Set the aerosol profile to Maritime
s.aero_profile = AeroProfile.PredefinedType(AeroProfile.Maritime)
# Run the model
s.run()
# Print some outputs
print(s.outputs.pixel_reflectance, s.outputs.pixel_radiance, s.outputs.direct_solar_irradiance)
# Run the model across the VNIR wavelengths, and plot the result
wavelengths, results = SixSHelpers.Wavelengths.run_vnir(s, output_name='pixel_radiance')
SixSHelpers.Wavelengths.plot_wavelengths(wavelengths, results, "Pixel radiance ($W/m^2$)")

This will produce the results shown below:

0.283 112.095 667.589

Followed by an image containing a graph showing the result for each wavelength.

To use Py6S you will also need to compile and install the 6S executable. Please follow the installation instructions in the documentation to find out how to do this on Windows, OS X or Linux.

Py6S was described in a journal article which should be referenced if Py6S is used for producing outputs for a scientific report/publication.

This project was written as part of my PhD at the University of Southampton. The code is open-source, released under the LGPL license, and is available at Github.

I'm very interested in receiving feedback, bug reports and feature suggestions, so please email me at [email protected].

py6s's People

Contributors

danclewley avatar dmwelch avatar fnemina avatar lopezvoliver avatar marcyin avatar pblottiere avatar petebunting avatar pmav99 avatar robintw avatar simonrp84 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

py6s's Issues

Make SixS.test() compatible with the documentation

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).

About SixS Parameter "visibility"

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?

Add importer for spectra from NERC FSF instruments

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).

need to add -ffpe-summary=none to gfortran flags to prevent warning in 6S output

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.

How to calculate the percentage density of the aerosol?

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!

Latest version of Py6S throws error

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.

Py6S should raise an exception when used with the wrong version of 6S

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.

Aeronet's import_aeronet_data returning indexing error

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.

Testing with SixS.test() doesn't run full test suite

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.

S3A OLCI narrow bands relative spectral response functions

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):

image

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.

the environment variable needs to be set on linux system

After Compiling the 6S source code, 'sixsV1.1' needs to be add in linux environment variable.

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

why Py6S cannot use in IPython?

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 ?

Py6s pysolar dependency is too old

Py6s has dependency on Pysolar 0.6 which is a release 7 years ago.

  1. Current Pysolar active one is 0.9 and API are completely different.
  2. it was a broken package (from pypi or conda channel, I also checked the source code archive and it supportted my assumption)
    In my case, I was using pysolar and py6s at the same time and I cannot use pysolar 0.6
    If I wanna continue using both together I have to make a patch the source code dynamically, that looks weird.
  3. Also, some bugs are reported as below.
    pingswept/pysolar#99

Please consider switch to newer pysolar repo or remove the dependency.

Build in support for easily creating LUTs

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.

Bad Wavelengths Return NaN Irradiance, e.g. 761 nm

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):
image

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         *
*                                                                             *
*                                                                             *
*******************************************************************************

Add import from ENVI spectral library files

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.

support for LWIR thermal applications

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?

error IEEE_INVALID_FLAG

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!!!

image

Test Issue

Please add a README! Test from OpenSourceHealthCheck

AHI (Himawari-8) sensor support

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

Geometry.from_time_and_location ambiguity

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.

model error

in
early.ground_reflectance = GroundReflectance.HeterogeneousLambertian(GroundReflectance.GreenVegetation)
TypeError: HeterogeneousLambertian() missing 2 required positional arguments: 'ro_target' and 'ro_env'

Typo in description of apparent reflectance (?)

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:

"appar. rad.(w/m2/sr/mic)": (CURRENT, 2, "apparent_reflectance", float),

Surely if it is reflectance should be adimensional? The line just before is "apparent_radiance" so I guess this is a typo.

ASTER band 8 - PredefinedWavelengths

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.

set_target_pressure has no effect

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?

troubles regarding the use of jupyter notebooks

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.

Hardcode pysolar version in setup.py

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.

Add a README

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)

Py6S.sixs_exceptions.ExecutionError: 6S executable not found

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.

stdin

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.

import_uow_radiosonde_data error - zero humidity 0-1 km

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:

`-----------------------------------------------------------------------------
PRES HGHT TEMP DWPT RELH MIXR DRCT SKNT THTA THTE THTV
hPa m C C % g/kg deg knot K K K

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.

Add easy ways to export Py6S parameterisation

This may include:

  • Ways of saving the whole SixS object so that it can be loaded again (not just the 6S input file, but the object so that the wavelength can be changed and can pick up the right ground reflectance info)
  • Ways of exporting parameterisations easily into a table (eg. LaTeX) to display in a paper
  • Other cool things...

several problem with installation and run of Py6S

Hello,
I'm having several problems installing and running Py6S:

  • First, I installed it with the command conda create -n py6s-env -c conda-forge py6s, and activated it. I run the test, and everything was fine. Then, I tried the quickstart command with IPYthon, Jupiter and PiCharm, but I got the error message:

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 file

ExecutionError: 6S executable not found.

Exception with numpy 1.20.0

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.
...
...

Pixel radiance above black surface and non-absorbing aerosol-free atmosphere is zero

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

Change run_wavelengths verbose default to False

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.

6S-V2.1 support

What would be involved to add support for 6S-V2.1?

This is related to #31

Is it as simple as, depending on the version of 6S (available in the first line of the output of 6S), just skipping the extra 2 lines (see example in #31)?

Add a README

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.