├── .gitignore ├── AUTHORS ├── CHANGES ├── COPYING ├── INSTALL ├── MANIFEST ├── MANIFEST.in ├── README.rst ├── create_version.sh ├── debian ├── changelog ├── compat ├── control ├── copyright ├── format ├── pycompat └── rules ├── docker ├── python2 │ └── Dockerfile └── python3 │ └── Dockerfile ├── docs ├── Makefile ├── make.bat └── source │ ├── _static │ ├── favicon.ico │ ├── gui │ │ ├── modis_convert.png │ │ ├── modis_download.png │ │ ├── modis_download_from_list.png │ │ ├── modis_mosaic.png │ │ ├── modis_multiparse.png │ │ ├── modis_parse.png │ │ └── modis_quality.png │ ├── ipython_dash.png │ ├── ipython_example.png │ ├── pyModis.png │ ├── pymodis.css │ └── urs_earthdata_nasa_gov.png │ ├── _templates │ ├── layout.html │ ├── oholosidebar.html │ └── pdfsidebar.html │ ├── conf.py │ ├── examples │ ├── examples.rst │ ├── full_example_gdal.rst │ ├── full_example_mrt.rst │ ├── pyModis.ipynb │ └── topng.py │ ├── index.rst │ ├── info.rst │ ├── pymodis │ ├── convertmodis.rst │ ├── convertmodis_gdal.rst │ ├── downmodis.rst │ ├── modules.rst │ ├── optparse.rst │ ├── parsemodis.rst │ └── qualitymodis.rst │ └── scripts │ ├── modis_convert.rst │ ├── modis_download.rst │ ├── modis_download_from_list.rst │ ├── modis_mosaic.rst │ ├── modis_multiparse.rst │ ├── modis_parse.rst │ ├── modis_quality.rst │ └── software.rst ├── pyModis.ico ├── pyModis.png ├── pymodis ├── __init__.py ├── convertmodis.py ├── convertmodis_gdal.py ├── downmodis.py ├── optparse_gui.py ├── optparse_required.py ├── parsemodis.py ├── productmodis.py └── qualitymodis.py ├── pyproject.toml ├── rpm ├── python-pymodis.changes └── python-pymodis.spec ├── scripts ├── modis_check.py ├── modis_convert.py ├── modis_download.py ├── modis_download_from_list.py ├── modis_mosaic.py ├── modis_multiparse.py ├── modis_parse.py └── modis_quality.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # backup files 2 | *~ 3 | *.bak 4 | 5 | # Python's precompiled files 6 | *.pyc 7 | *.pyo 8 | 9 | # Setuptools/Distribute's files 10 | *.egg-info 11 | /dist 12 | /build 13 | 14 | # Sphinx's builds 15 | /docs/build 16 | 17 | # Visual Studio Code 18 | .vscode/ -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | pyModis List of Authors 2 | =========================== 3 | 4 | - Luca Delucchi Main Developer 5 | - Ingmar Nitze 6 | - Xavier Corredor Llano 7 | - Martin Landa 8 | - Anton Petrov 9 | 10 | Thanks to 11 | Anne Ghisla for help in code writing 12 | Markus Neteler and Markus Metz for testing 13 | Stefano Cavallari for bug fix 14 | Logan Byers for commenting 15 | Anton Petrov for token support 16 | 17 | Full list of contributors at https://github.com/lucadelu/pyModis/graphs/contributors 18 | 19 | Contact: 20 | 21 | pyModis Development Team 22 | c/o Luca Delucchi 23 | Fondazione Edmund Mach (FEM) 24 | IASMA Research and Innovation Centre 25 | 38010 S. Michele all'Adige (Trento), Italy 26 | luca.delucchi AT fmach.it 27 | 28 | Internet: http://pymodis.org 29 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | - version 0.6.3, 2013-04-30 -- first release installable using pip 2 | * fix parseModisMulti class to work with different range of times 3 | * update setup.py to be compliant with Pipy 4 | * update README 5 | - version 0.6.4, 2013-05-06 -- update scripts 6 | * move option required for optparse from script to optparse_required library 7 | * update INSTALL 8 | - version 0.7.0 2013-07-05 -- update repository 9 | * add support for http NASA repository 10 | * fix bug with modis_download.py and no tiles 11 | * update documentation 12 | - version 0.7.1 2013-07-30 -- fix problems 13 | * fix modis_download.py script 14 | * add documentation how to install on Windows 15 | - version 0.7.2 2013-08-01 -- fix convertmodis.py for windows 16 | * fix path to executable in convertmodis.py 17 | - version 0.7.3 18 | * fix functions to download data 19 | * add timeout to http urlopen 20 | * add GDAL to check integrity of downloaded files 21 | - version 0.7.4 22 | * add support to requests library to download files 23 | * fix english typo 24 | - version 1.0.0 25 | * add support to use GDAL to convert MODIS hdf files 26 | * add graphical interfaces to scripts 27 | * add quality check: library and script 28 | * improved documentation and examples (add iPython notebook tutorial) 29 | - version 1.0.1 30 | * GDAL support in downmodis is not mandatory 31 | * fixed some small bugs 32 | * improved documentation 33 | - version 1.0.2 34 | * fixed GDAL support in downmodis is not mandatory 35 | * fixed raise exception 36 | - version 1.0.3 37 | * new website address 38 | - version 2.0.1 39 | * pyModis now support Python 3 40 | * fixed and improved documentation 41 | * added support for new authentication system 42 | * added capabilities to set user and password through standard input 43 | - version 2.0.2 44 | * fixed bug in parsemodis library 45 | * improved documentation 46 | - version 2.0.3 47 | * improved OSX support 48 | * added capabilities to return the layers name 49 | * added support for HTTPS server 50 | * fixed several small errors 51 | - version 2.0.4 52 | * fixed problem with different projection system 53 | * fixed documentation for user and password in download library and scripts 54 | * improved documentation 55 | - version 2.0.5 56 | * added capability to use netrc 57 | * fixed bug for windows where mrtmosaic/resample tools are without ending .exe 58 | * removed warnings from HTTPS website 59 | - version 2.0.6 60 | * improved doc 61 | * fixed small bugs 62 | * added quiet option to the convert functions 63 | * warnings redirect to logging 64 | - version 2.0.7 65 | * fixed authentication for https://n5eil01u.ecs.nsidc.org/ 66 | * improved doc for previous url 67 | * fix small bug https://github.com/lucadelu/pyModis/issues/90 68 | - version 2.0.8 69 | * fixed problem with import #95 70 | - version 2.0.9 71 | * fixed typos 72 | * improved warning 73 | * fixed bug calculating extracting dates 74 | - version 2.1.0 75 | * bug fixes 76 | * add pygdal support 77 | - version 2.2.0 78 | * replaced print with warnings in import warning 79 | * add support for newer wxPython version 80 | * add support for multiband product like MCD19A2 81 | - version 2.3.0 82 | * changed getiterator with items 83 | * slugify layer name 84 | * removeEmptyFiles improvement 85 | - version 2.4.0 86 | * added support for token authorization to library 87 | - version 2.4.1 88 | * added support for token authorization to the script 89 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright and License Statement 2 | 3 | The pyMobis is Copyright by members of the 4 | pyMobis Development Team. 5 | 6 | This program is free software; you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by the 8 | Free Software Foundation; either version 2 of the License, or (at your 9 | option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License (GPL) for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the 18 | Free Software Foundation, Inc., 19 | 59 Temple Place - Suite 330, 20 | Boston, MA 02111-1307, USA. 21 | 22 | Questions regarding pyMobis should be directed to the 23 | pyModis Development Team at the following address: 24 | 25 | pyModis Development Team 26 | c/o Luca Delucchi 27 | Fondazione Edmund Mach (FEM) 28 | IASMA Research and Innovation Centre 29 | 38010 S. Michele all'Adige (Trento), Italy 30 | luca.delucchi AT fmach DOT it 31 | 32 | Internet: http://www.pymodis.org/ 33 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | PREREQUISITIES 2 | ============== 3 | 4 | pyModis requires Python, which comes preinstalled on most Unix machines. 5 | 6 | You can check to see if you have it installed on a Unix machine by typing Python at a command prompt. 7 | A result like this and you have Python istalled 8 | 9 | Python 2.6.6 (r266:84292, Oct 9 2010, 11:40:09) 10 | [GCC 4.4.5] on linux2 11 | Type "help", "copyright", "credits" or "license" for more information. 12 | >>> 13 | 14 | The next error however means that there is a problem: 15 | 16 | bash: python: command not found 17 | 18 | You can download Python from http://www.python.org/download/releases/ 19 | 20 | It also requires the Python package of GDAL library (commonly named "python-gdal") 21 | 22 | INSTALL 23 | ======== 24 | 25 | Using pip 26 | ^^^^^^^^^^ 27 | 28 | You can use pip to install pyModis 29 | 30 | pip install pyModis 31 | 32 | To upgrade version 33 | 34 | pip install --upgrade pyModis 35 | 36 | To uninstall 37 | 38 | pip uninstall pyModis 39 | 40 | From source 41 | ^^^^^^^^^^^^ 42 | 43 | Download the last stable version from Github 44 | 45 | 46 | Now decompress the archivie 47 | 48 | tar -xzf pyModis.tar.gz 49 | 50 | 51 | Enter inside the new directory 52 | 53 | cd pyModis 54 | 55 | 56 | Install the library with root permission 57 | 58 | su 59 | python setup.py install 60 | 61 | 62 | on Ubuntu 63 | 64 | sudo python setup.py install 65 | 66 | 67 | Now we can try to load the library so 68 | 69 | python 70 | 71 | Python 2.6.6 (r266:84292, Oct 9 2010, 11:40:09) 72 | [GCC 4.4.5] on linux2 73 | Type "help", "copyright", "credits" or "license" for more information. 74 | >>> import pymodis 75 | 76 | with this response it is all ok 77 | 78 | >>> 79 | 80 | instead with this one, you must check the installation 81 | 82 | Traceback (most recent call last): 83 | File "", line 1, in 84 | ImportError: No module named pymodis 85 | 86 | Windows 87 | ^^^^^^^^^ 88 | 89 | The most simple way to install pyModis on Windows is to install latest Python 2.7 from http://python.org/download/ 90 | 91 | Now you have to modify the "Path" environment variable using Powershell running 92 | 93 | [Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Python27\;C:\Python27\Scripts\", "User") 94 | 95 | Download and install the last version of Distribute for Windows from http://python-distribute.org/distribute_setup.py 96 | 97 | At this point you can install pip using easy_install 98 | 99 | easy_install pip 100 | 101 | Now install `numpy `_ library using *easy_install* because installation from pip is broken (this is required only for version >= 0.7.1) 102 | 103 | easy_install numpy 104 | 105 | Finally install pyModis using pip 106 | 107 | pip install pyModis 108 | 109 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | pymodis/convertmodis.py 2 | pymodis/downmodis.py 3 | pymodis/__init__.py 4 | pymodis/parsemodis.py 5 | pymodis/optparse_gui.py 6 | pymodis/optparse_required.py 7 | pymodis/convertmodis_gdal.py 8 | pymodis/qualitymodis.py 9 | scripts/modis_download.py 10 | scripts/modis_parse.py 11 | scripts/modis_quality.py 12 | scripts/modis_multiparse.py 13 | scripts/modis_mosaic.py 14 | scripts/modis_convert.py 15 | AUTHORS 16 | COPYING 17 | INSTALL 18 | README 19 | pyModis.png 20 | setup.py 21 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include pyModis.png * 2 | recursive-include docs * -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Welcome in pyModis library 3 | ========================== 4 | 5 | *Thank you for downloading pyModis* 6 | 7 | **pyModis is a Python library to download and process MODIS data from NASA server** 8 | 9 | Copyright Luca Delucchi - 2010-2020 10 | 11 | License 12 | ------- 13 | 14 | pyModis is licensed under the terms of **GNU GPL 2**. Read COPYING for more info 15 | 16 | Install 17 | ------- 18 | 19 | For how to compile or install pyModis see INSTALL file. 20 | 21 | Executables 22 | ----------- 23 | 24 | Some executables are distributed with the library: 25 | 26 | * **modis_download** downloads MODIS data 27 | * **modis_download_from_list** downloads MODIS data from NASA servers, the names of files to download have to be contained into a text file. 28 | * **modis_parse** parses the XML file of MODIS data and return some variables 29 | * **modis_multiparse** parses the XML file of multiple MODIS data and returns the bounding box or writes the XML file with the information of all 30 | selected tiles 31 | * **modis_mosaic** creates the mosaic of multiple MODIS tiles 32 | * **modis_convert** converts MODIS data from HDF format and Sinusoidal projection to other formats and projections 33 | * **modis_quality** checks the quality of MODIS data using the QA layer 34 | 35 | 36 | Other info 37 | ---------- 38 | 39 | The logo of pyModis is pyModis.png; it is released under CC-BY-SA and it's distributed with the pyModis library 40 | 41 | More info about pyModis at http://www.pymodis.org/ 42 | -------------------------------------------------------------------------------- /create_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | t=`which twine` 4 | 5 | if [ $? -ne 0 ]; then 6 | echo "twine is required, please install it" 7 | exit 1 8 | fi 9 | 10 | echo "STEP to be done before: 11 | * update CHANGES and pymodis/__init__.py files 12 | * add new tag 13 | * run this script 14 | "; 15 | echo "Could it \"procede\" (answer yes or no)?" 16 | read procede 17 | 18 | if [ $procede = "yes" ]; then 19 | 20 | pymodis_version=`python setup.py -V` 21 | curdir=`pwd` 22 | 23 | rm -rf build/* 24 | rm -rf dist/* 25 | 26 | python3 -m build 27 | 28 | cd docs/ 29 | 30 | make latexpdf 31 | make html 32 | 33 | cd build/html/ 34 | 35 | find . -type f -name "*~" -exec rm -f {} \; 36 | 37 | cp ../latex/pyModis.pdf . 38 | 39 | zip -r -9 $curdir/pymodis_${pymodis_version}_html.zip * 40 | 41 | cd $curdir 42 | 43 | rm -rf docs/build/ 44 | 45 | find . -type f -name "*~" -exec rm -f {} \; 46 | 47 | twine check dist/* 48 | 49 | echo "Is twine \"check\" ok? (answer yes or no)" 50 | read check 51 | 52 | if [ $check = "yes" ]; then 53 | twine upload dist/* 54 | fi 55 | 56 | echo "Do you want create \"Debian\" packages (answer yes or no)?" 57 | read Debian 58 | 59 | if [ $Debian = "yes" ]; then 60 | su -c "dpkg-buildpackage -us -uc -d" 61 | fi 62 | 63 | fi 64 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | pymodis (0.7.4-0) precise; urgency=low 2 | 3 | * Initial build. 4 | 5 | -- Angelos Tzotsos Thu, 27 Mar 2014 12:20:00 +0100 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: pymodis 2 | Section: python 3 | Priority: optional 4 | Maintainer: Angelos Tzotsos 5 | Build-Depends: debhelper (>= 7.0.50), python-setuptools (>= 0.6), python-support (>=0.6), python-all-dev (>= 2.3.5-11), python (>= 2.6.6-3) 6 | Standards-Version: 3.9.3 7 | X-Python-Version: >= 2.5 8 | Homepage: http://www.pymodis.org/ 9 | 10 | Package: python-pymodis 11 | Architecture: all 12 | Depends: ${misc:Depends}, debconf, python (>=2.5), python-numpy, python-gdal 13 | Description: Python library for MODIS data 14 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This package was created by Angelos Tzotsos on 2 | Thu, 27 Mar 2014 12:20:00 +0100 3 | 4 | Copyright: 5 | The pyMobis is Copyright by members of the 6 | pyMobis Development Team. 7 | 8 | License: 9 | 10 | This program is free software; you can redistribute it and/or modify it 11 | under the terms of the GNU General Public License as published by the 12 | Free Software Foundation; either version 2 of the License, or (at your 13 | option) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License (GPL) for more details. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with this program; if not, write to the 22 | Free Software Foundation, Inc., 23 | 59 Temple Place - Suite 330, 24 | Boston, MA 02111-1307, USA. 25 | 26 | Questions regarding pyMobis should be directed to the 27 | pyModis Development Team at the following address: 28 | 29 | pyModis Development Team 30 | c/o Luca Delucchi 31 | Fondazione Edmund Mach (FEM) 32 | IASMA Research and Innovation Centre 33 | 38010 S. Michele all'Adige (Trento), Italy 34 | luca.delucchi AT fmach DOT it 35 | 36 | Internet: http://www.pymodis.org/ 37 | -------------------------------------------------------------------------------- /debian/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/pycompat: -------------------------------------------------------------------------------- 1 | 2 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | %: 5 | dh $@ --with python2 6 | 7 | 8 | -------------------------------------------------------------------------------- /docker/python2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | # http://www.pymodis.org/ docker image 4 | 5 | MAINTAINER Luca Delucchi 6 | 7 | # system environment 8 | ENV DEBIAN_FRONTEND noninteractive 9 | #### ENV CPLUS_INCLUDE_PATH=/usr/include/gdal \ 10 | #### C_INCLUDE_PATH=/usr/include/gdal 11 | 12 | # ?? && apt-get install -y --install-recommends \ 13 | 14 | # fetch dependencies 15 | RUN apt-get update \ 16 | && apt-get install -y \ 17 | gdal-bin \ 18 | python-numpy \ 19 | python \ 20 | python-gdal \ 21 | ipython \ 22 | python-pip \ 23 | python-future \ 24 | python-requests 25 | 26 | # && apt-get autoremove \ 27 | # && apt-get clean 28 | 29 | # Install pyModis 30 | #####? RUN pip install GDAL==$(gdal-config --version | awk -F'[.]' '{print $1"."$2}') 31 | RUN pip install pyModis 32 | -------------------------------------------------------------------------------- /docker/python3/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | # http://www.pymodis.org/ docker image 4 | 5 | MAINTAINER Luca Delucchi 6 | 7 | # system environment 8 | ENV DEBIAN_FRONTEND noninteractive 9 | #### ENV CPLUS_INCLUDE_PATH=/usr/include/gdal \ 10 | #### C_INCLUDE_PATH=/usr/include/gdal 11 | 12 | # ?? && apt-get install -y --install-recommends \ 13 | 14 | # fetch dependencies 15 | RUN apt-get update \ 16 | && apt-get install -y \ 17 | gdal-bin \ 18 | python3-numpy \ 19 | python3 \ 20 | python3-gdal \ 21 | ipython3 \ 22 | python3-pip \ 23 | python3-future \ 24 | python3-requests 25 | 26 | # && apt-get autoremove \ 27 | # && apt-get clean 28 | 29 | # Install pyModis 30 | #####? RUN pip install GDAL==$(gdal-config --version | awk -F'[.]' '{print $1"."$2}') 31 | RUN pip3 install pyModis 32 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 14 | # the i18n builder cannot share the environment and doctrees with the others 15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 16 | 17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 18 | 19 | help: 20 | @echo "Please use \`make ' where is one of" 21 | @echo " html to make standalone HTML files" 22 | @echo " dirhtml to make HTML files named index.html in directories" 23 | @echo " singlehtml to make a single large HTML file" 24 | @echo " pickle to make pickle files" 25 | @echo " json to make JSON files" 26 | @echo " htmlhelp to make HTML files and a HTML help project" 27 | @echo " qthelp to make HTML files and a qthelp project" 28 | @echo " devhelp to make HTML files and a Devhelp project" 29 | @echo " epub to make an epub" 30 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 31 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 32 | @echo " text to make text files" 33 | @echo " man to make manual pages" 34 | @echo " texinfo to make Texinfo files" 35 | @echo " info to make Texinfo files and run them through makeinfo" 36 | @echo " gettext to make PO message catalogs" 37 | @echo " changes to make an overview of all changed/added/deprecated items" 38 | @echo " linkcheck to check all external links for integrity" 39 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 40 | 41 | clean: 42 | -rm -rf $(BUILDDIR)/* 43 | 44 | html: 45 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 46 | if test -e $(BUILDDIR)/latex/pyModis.pdf; then cp $(BUILDDIR)/latex/pyModis.pdf $(BUILDDIR)/html/_static; fi; 47 | @echo 48 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 49 | 50 | dirhtml: 51 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 52 | if test -e $(BUILDDIR)/latex/pyModis.pdf; then cp $(BUILDDIR)/latex/pyModis.pdf $(BUILDDIR)/dirhtml/_static; fi; 53 | @echo 54 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 55 | 56 | singlehtml: 57 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 58 | if test -e $(BUILDDIR)/latex/pyModis.pdf; then cp $(BUILDDIR)/latex/pyModis.pdf $(BUILDDIR)/singlehtml/_static; fi; 59 | @echo 60 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 61 | 62 | pickle: 63 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 64 | @echo 65 | @echo "Build finished; now you can process the pickle files." 66 | 67 | json: 68 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 69 | @echo 70 | @echo "Build finished; now you can process the JSON files." 71 | 72 | htmlhelp: 73 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 74 | @echo 75 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 76 | ".hhp project file in $(BUILDDIR)/htmlhelp." 77 | 78 | qthelp: 79 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 80 | @echo 81 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 82 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 83 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pyModis.qhcp" 84 | @echo "To view the help file:" 85 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pyModis.qhc" 86 | 87 | devhelp: 88 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 89 | @echo 90 | @echo "Build finished." 91 | @echo "To view the help file:" 92 | @echo "# mkdir -p $$HOME/.local/share/devhelp/pyModis" 93 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pyModis" 94 | @echo "# devhelp" 95 | 96 | epub: 97 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 98 | @echo 99 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 100 | 101 | latex: 102 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 103 | @echo 104 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 105 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 106 | "(use \`make latexpdf' here to do that automatically)." 107 | 108 | latexpdf: 109 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 110 | @echo "Running LaTeX files through pdflatex..." 111 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 112 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 113 | 114 | text: 115 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 116 | @echo 117 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 118 | 119 | man: 120 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 121 | @echo 122 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 123 | 124 | texinfo: 125 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 126 | @echo 127 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 128 | @echo "Run \`make' in that directory to run these through makeinfo" \ 129 | "(use \`make info' here to do that automatically)." 130 | 131 | info: 132 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 133 | @echo "Running Texinfo files through makeinfo..." 134 | make -C $(BUILDDIR)/texinfo info 135 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 136 | 137 | gettext: 138 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 139 | @echo 140 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 141 | 142 | changes: 143 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 144 | @echo 145 | @echo "The overview file is in $(BUILDDIR)/changes." 146 | 147 | linkcheck: 148 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 149 | @echo 150 | @echo "Link check complete; look for any errors in the above output " \ 151 | "or in $(BUILDDIR)/linkcheck/output.txt." 152 | 153 | doctest: 154 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 155 | @echo "Testing of doctests in the sources finished, look at the " \ 156 | "results in $(BUILDDIR)/doctest/output.txt." 157 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. linkcheck to check all external links for integrity 37 | echo. doctest to run all doctests embedded in the documentation if enabled 38 | goto end 39 | ) 40 | 41 | if "%1" == "clean" ( 42 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 43 | del /q /s %BUILDDIR%\* 44 | goto end 45 | ) 46 | 47 | if "%1" == "html" ( 48 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 49 | if errorlevel 1 exit /b 1 50 | echo. 51 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 52 | goto end 53 | ) 54 | 55 | if "%1" == "dirhtml" ( 56 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 57 | if errorlevel 1 exit /b 1 58 | echo. 59 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 60 | goto end 61 | ) 62 | 63 | if "%1" == "singlehtml" ( 64 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 65 | if errorlevel 1 exit /b 1 66 | echo. 67 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 68 | goto end 69 | ) 70 | 71 | if "%1" == "pickle" ( 72 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 73 | if errorlevel 1 exit /b 1 74 | echo. 75 | echo.Build finished; now you can process the pickle files. 76 | goto end 77 | ) 78 | 79 | if "%1" == "json" ( 80 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 81 | if errorlevel 1 exit /b 1 82 | echo. 83 | echo.Build finished; now you can process the JSON files. 84 | goto end 85 | ) 86 | 87 | if "%1" == "htmlhelp" ( 88 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 89 | if errorlevel 1 exit /b 1 90 | echo. 91 | echo.Build finished; now you can run HTML Help Workshop with the ^ 92 | .hhp project file in %BUILDDIR%/htmlhelp. 93 | goto end 94 | ) 95 | 96 | if "%1" == "qthelp" ( 97 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 98 | if errorlevel 1 exit /b 1 99 | echo. 100 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 101 | .qhcp project file in %BUILDDIR%/qthelp, like this: 102 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pyModis.qhcp 103 | echo.To view the help file: 104 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pyModis.ghc 105 | goto end 106 | ) 107 | 108 | if "%1" == "devhelp" ( 109 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 110 | if errorlevel 1 exit /b 1 111 | echo. 112 | echo.Build finished. 113 | goto end 114 | ) 115 | 116 | if "%1" == "epub" ( 117 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 118 | if errorlevel 1 exit /b 1 119 | echo. 120 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 121 | goto end 122 | ) 123 | 124 | if "%1" == "latex" ( 125 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 129 | goto end 130 | ) 131 | 132 | if "%1" == "text" ( 133 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 134 | if errorlevel 1 exit /b 1 135 | echo. 136 | echo.Build finished. The text files are in %BUILDDIR%/text. 137 | goto end 138 | ) 139 | 140 | if "%1" == "man" ( 141 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 142 | if errorlevel 1 exit /b 1 143 | echo. 144 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 145 | goto end 146 | ) 147 | 148 | if "%1" == "texinfo" ( 149 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 150 | if errorlevel 1 exit /b 1 151 | echo. 152 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 153 | goto end 154 | ) 155 | 156 | if "%1" == "gettext" ( 157 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 158 | if errorlevel 1 exit /b 1 159 | echo. 160 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 161 | goto end 162 | ) 163 | 164 | if "%1" == "changes" ( 165 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 166 | if errorlevel 1 exit /b 1 167 | echo. 168 | echo.The overview file is in %BUILDDIR%/changes. 169 | goto end 170 | ) 171 | 172 | if "%1" == "linkcheck" ( 173 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 174 | if errorlevel 1 exit /b 1 175 | echo. 176 | echo.Link check complete; look for any errors in the above output ^ 177 | or in %BUILDDIR%/linkcheck/output.txt. 178 | goto end 179 | ) 180 | 181 | if "%1" == "doctest" ( 182 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 183 | if errorlevel 1 exit /b 1 184 | echo. 185 | echo.Testing of doctests in the sources finished, look at the ^ 186 | results in %BUILDDIR%/doctest/output.txt. 187 | goto end 188 | ) 189 | 190 | :end 191 | -------------------------------------------------------------------------------- /docs/source/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/favicon.ico -------------------------------------------------------------------------------- /docs/source/_static/gui/modis_convert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/gui/modis_convert.png -------------------------------------------------------------------------------- /docs/source/_static/gui/modis_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/gui/modis_download.png -------------------------------------------------------------------------------- /docs/source/_static/gui/modis_download_from_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/gui/modis_download_from_list.png -------------------------------------------------------------------------------- /docs/source/_static/gui/modis_mosaic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/gui/modis_mosaic.png -------------------------------------------------------------------------------- /docs/source/_static/gui/modis_multiparse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/gui/modis_multiparse.png -------------------------------------------------------------------------------- /docs/source/_static/gui/modis_parse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/gui/modis_parse.png -------------------------------------------------------------------------------- /docs/source/_static/gui/modis_quality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/gui/modis_quality.png -------------------------------------------------------------------------------- /docs/source/_static/ipython_dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/ipython_dash.png -------------------------------------------------------------------------------- /docs/source/_static/ipython_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/ipython_example.png -------------------------------------------------------------------------------- /docs/source/_static/pyModis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/pyModis.png -------------------------------------------------------------------------------- /docs/source/_static/pymodis.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #FFFFFF; 3 | text-align: justify; 4 | } 5 | 6 | div.section { 7 | text-align: justify; 8 | } 9 | 10 | h1.bigger { 11 | font-size: 4em; 12 | vertical-align: middle; 13 | } 14 | 15 | div.footer { 16 | background-color: #FFFFFF; 17 | } 18 | 19 | h1 { 20 | font-size: 2.5em; 21 | vertical-align: middle; 22 | } 23 | 24 | h3 { 25 | font-size: 1.1em; 26 | } 27 | 28 | a { 29 | color: #00ab08; 30 | } 31 | 32 | div.related ul li a { 33 | color: #00ab08; 34 | } 35 | 36 | .pre { 37 | color: #00ab08; 38 | } 39 | 40 | p.admonition-title { 41 | background-color: rgba(207, 66, 0, 0.85) 42 | } 43 | 44 | div.highlight { 45 | background: #FFFFFF; 46 | } 47 | 48 | img.gui { 49 | padding-top: 10px; 50 | padding-right: 10px; 51 | } 52 | 53 | div.sphinxsidebar { 54 | padding-right: 25px!important; 55 | } -------------------------------------------------------------------------------- /docs/source/_static/urs_earthdata_nasa_gov.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/docs/source/_static/urs_earthdata_nasa_gov.png -------------------------------------------------------------------------------- /docs/source/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | {% block extrahead %} 3 | 4 | {% endblock %} 5 | 6 | {% block header %} 7 |

pyModis

8 | {% endblock %} 9 | 10 | {% block footer %} 11 | 12 | 13 | 14 | 15 | 16 | 17 |
{{ super() }}
18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /docs/source/_templates/oholosidebar.html: -------------------------------------------------------------------------------- 1 |

2 |

3 | 4 |

5 | -------------------------------------------------------------------------------- /docs/source/_templates/pdfsidebar.html: -------------------------------------------------------------------------------- 1 |

PDF documentation

2 |

3 | Download the documentation in pdf format 4 |

5 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # pyModis documentation build configuration file, created by 4 | # sphinx-quickstart on Thu Jun 28 10:50:11 2012. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys 15 | import os 16 | import shutil 17 | 18 | thispath = os.path.split(os.path.abspath('.'))[0] 19 | 20 | sys.path.insert(0, os.path.split(thispath)[0]) 21 | 22 | import pymodis 23 | modisversion = pymodis.__version__ 24 | 25 | # If extensions (or modules to document with autodoc) are in another directory, 26 | # add these directories to sys.path here. If the directory is relative to the 27 | # documentation root, use os.path.abspath to make it absolute, like shown here. 28 | #sys.path.insert(0, os.path.abspath('.')) 29 | 30 | # -- General configuration ----------------------------------------------------- 31 | 32 | # If your documentation needs a minimal Sphinx version, state it here. 33 | #needs_sphinx = '1.0' 34 | 35 | # Add any Sphinx extension module names here, as strings. They can be extensions 36 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 37 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.imgmath', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] 38 | 39 | # Add any paths that contain templates here, relative to this directory. 40 | templates_path = ['_templates'] 41 | 42 | # The suffix of source filenames. 43 | source_suffix = '.rst' 44 | 45 | # The encoding of source files. 46 | source_encoding = 'utf-8' 47 | 48 | # The master toctree document. 49 | master_doc = 'index' 50 | 51 | # General information about the project. 52 | project = 'pyModis' 53 | copyright = '2012-2013, Luca Delucchi' 54 | 55 | # The version info for the project you're documenting, acts as replacement for 56 | # |version| and |release|, also used in various other places throughout the 57 | # built documents. 58 | # 59 | # The short X.Y version. 60 | version = modisversion.rsplit('.',1)[0] 61 | # The full version, including alpha/beta/rc tags. 62 | release = modisversion 63 | 64 | # The language for content autogenerated by Sphinx. Refer to documentation 65 | # for a list of supported languages. 66 | #language = None 67 | 68 | # There are two options for replacing |today|: either, you set today to some 69 | # non-false value, then it is used: 70 | #today = '' 71 | # Else, today_fmt is used as the format for a strftime call. 72 | #today_fmt = '%B %d, %Y' 73 | 74 | # List of patterns, relative to source directory, that match files and 75 | # directories to ignore when looking for source files. 76 | exclude_patterns = ['_build'] 77 | 78 | # The reST default role (used for this markup: `text`) to use for all documents. 79 | #default_role = None 80 | 81 | # If true, '()' will be appended to :func: etc. cross-reference text. 82 | #add_function_parentheses = True 83 | 84 | # If true, the current module name will be prepended to all description 85 | # unit titles (such as .. function::). 86 | #add_module_names = True 87 | 88 | # If true, sectionauthor and moduleauthor directives will be shown in the 89 | # output. They are ignored by default. 90 | show_authors = True 91 | 92 | # The name of the Pygments (syntax highlighting) style to use. 93 | pygments_style = 'sphinx' 94 | 95 | # A list of ignored prefixes for module index sorting. 96 | #modindex_common_prefix = [] 97 | 98 | 99 | # -- Options for HTML output --------------------------------------------------- 100 | 101 | # The theme to use for HTML and HTML Help pages. See the documentation for 102 | # a list of builtin themes. 103 | html_theme = 'sphinxdoc' 104 | 105 | # Theme options are theme-specific and customize the look and feel of a theme 106 | # further. For a list of options available for each theme, see the 107 | # documentation. 108 | #html_theme_options = {} 109 | 110 | # Add any paths that contain custom themes here, relative to this directory. 111 | #html_theme_path = [] 112 | 113 | # The name for this set of Sphinx documents. If None, it defaults to 114 | # " v documentation". 115 | #html_title = None 116 | 117 | # A shorter title for the navigation bar. Default is the same as html_title. 118 | #html_short_title = None 119 | 120 | # The name of an image file (relative to this directory) to place at the top 121 | # of the sidebar. 122 | #html_logo = '_static/pyModis.png' 123 | 124 | # The name of an image file (within the static path) to use as favicon of the 125 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 126 | # pixels large. 127 | html_favicon = '_static/favicon.ico' 128 | 129 | # Add any paths that contain custom static files (such as style sheets) here, 130 | # relative to this directory. They are copied after the builtin static files, 131 | # so a file named "default.css" will overwrite the builtin "default.css". 132 | html_static_path = ['_static'] 133 | 134 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 135 | # using the given strftime format. 136 | html_last_updated_fmt = '%b %d, %Y' 137 | 138 | # If true, SmartyPants will be used to convert quotes and dashes to 139 | # typographically correct entities. 140 | #html_use_smartypants = True 141 | 142 | # Custom sidebar templates, maps document names to template names. 143 | html_sidebars = {"**":["localtoc.html",'relations.html','searchbox.html','oholosidebar.html']} 144 | 145 | pdfpath = os.path.join(thispath,'build','latex','pyModis.pdf') 146 | if os.path.exists(pdfpath) and os.path.exists(os.path.join(thispath,'build','html')): 147 | html_sidebars['**'].insert(3,'pdfsidebar.html') 148 | 149 | # Additional templates that should be rendered to pages, maps page names to 150 | # template names. 151 | #html_additional_pages = {} 152 | 153 | # If false, no module index is generated. 154 | #html_domain_indices = True 155 | 156 | # If false, no index is generated. 157 | #html_use_index = True 158 | 159 | # If true, the index is split into individual pages for each letter. 160 | #html_split_index = False 161 | 162 | # If true, links to the reST sources are added to the pages. 163 | html_show_sourcelink = False 164 | 165 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 166 | html_show_sphinx = False 167 | 168 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 169 | html_show_copyright = False 170 | 171 | # If true, an OpenSearch description file will be output, and all pages will 172 | # contain a tag referring to it. The value of this option must be the 173 | # base URL from which the finished HTML is served. 174 | #html_use_opensearch = '' 175 | 176 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 177 | #html_file_suffix = None 178 | 179 | # Output file base name for HTML help builder. 180 | htmlhelp_basename = 'pyModisdoc' 181 | 182 | 183 | # -- Options for LaTeX output -------------------------------------------------- 184 | 185 | latex_elements = { 186 | # The paper size ('letterpaper' or 'a4paper'). 187 | 'papersize': 'a4paper', 188 | 189 | # The font size ('10pt', '11pt' or '12pt'). 190 | 'pointsize': '11pt', 191 | 192 | # remove blank pages 193 | 'classoptions': ',oneside', 194 | 'babel': '\\usepackage[english]{babel}' 195 | 196 | # Additional stuff for the LaTeX preamble. 197 | #'preamble': 'This library was developed to replace old bash scripts of Markus Neteler. It is very useful for GIS and Remote Sensing Platform of Fondazione Edmund Mach. Thanks to the Fondazione to leave us to develop and contribute to free and open source software' 198 | } 199 | 200 | # Grouping the document tree into LaTeX files. List of tuples 201 | # (source start file, target name, title, author, documentclass [howto/manual]). 202 | latex_documents = [ 203 | ('index', 'pyModis.tex', 'pyModis Documentation', 204 | 'Luca Delucchi', 'manual'), 205 | ] 206 | 207 | # The name of an image file (relative to this directory) to place at the top of 208 | # the title page. 209 | latex_logo = '_static/pyModis.png' 210 | 211 | # For "manual" documents, if this is true, then toplevel headings are parts, 212 | # not chapters. 213 | #latex_use_parts = False 214 | 215 | # If true, show page references after internal links. 216 | #latex_show_pagerefs = False 217 | 218 | # If true, show URL addresses after external links. 219 | #latex_show_urls = False 220 | 221 | # Documents to append as an appendix to all manuals. 222 | #latex_appendices = [] 223 | 224 | # If false, no module index is generated. 225 | #latex_domain_indices = True 226 | 227 | 228 | # -- Options for manual page output -------------------------------------------- 229 | 230 | # One entry per manual page. List of tuples 231 | # (source start file, name, description, authors, manual section). 232 | man_pages = [ 233 | ('index', 'pymodis', 'pyModis Documentation', 234 | ['Luca Delucchi'], 1) 235 | ] 236 | 237 | # If true, show URL addresses after external links. 238 | #man_show_urls = False 239 | 240 | 241 | # -- Options for Texinfo output ------------------------------------------------ 242 | 243 | # Grouping the document tree into Texinfo files. List of tuples 244 | # (source start file, target name, title, author, 245 | # dir menu entry, description, category) 246 | texinfo_documents = [ 247 | ('index', 'pyModis', 'pyModis Documentation', 248 | 'Luca Delucchi', 'pyModis', 'One line description of project.', 249 | 'Miscellaneous'), 250 | ] 251 | 252 | # Documents to append as an appendix to all manuals. 253 | #texinfo_appendices = [] 254 | 255 | # If false, no module index is generated. 256 | #texinfo_domain_indices = True 257 | 258 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 259 | #texinfo_show_urls = 'footnote' 260 | 261 | 262 | # -- Options for Epub output --------------------------------------------------- 263 | 264 | # Bibliographic Dublin Core info. 265 | epub_title = 'pyModis' 266 | epub_author = 'Luca Delucchi' 267 | epub_publisher = 'Luca Delucchi' 268 | epub_copyright = '2012-2013, Luca Delucchi' 269 | 270 | # The language of the text. It defaults to the language option 271 | # or en if the language is not set. 272 | #epub_language = '' 273 | 274 | # The scheme of the identifier. Typical schemes are ISBN or URL. 275 | #epub_scheme = '' 276 | 277 | # The unique identifier of the text. This can be a ISBN number 278 | # or the project homepage. 279 | #epub_identifier = '' 280 | 281 | # A unique identification for the text. 282 | #epub_uid = '' 283 | 284 | # A tuple containing the cover image and cover page html template filenames. 285 | #epub_cover = () 286 | 287 | # HTML files that should be inserted before the pages created by sphinx. 288 | # The format is a list of tuples containing the path and title. 289 | #epub_pre_files = [] 290 | 291 | # HTML files shat should be inserted after the pages created by sphinx. 292 | # The format is a list of tuples containing the path and title. 293 | #epub_post_files = [] 294 | 295 | # A list of files that should not be packed into the epub file. 296 | #epub_exclude_files = [] 297 | 298 | # The depth of the table of contents in toc.ncx. 299 | #epub_tocdepth = 3 300 | 301 | # Allow duplicate toc entries. 302 | #epub_tocdup = True 303 | 304 | 305 | # Example configuration for intersphinx: refer to the Python standard library. 306 | intersphinx_mapping = {'http://docs.python.org/': None} 307 | -------------------------------------------------------------------------------- /docs/source/examples/examples.rst: -------------------------------------------------------------------------------- 1 | Examples 2 | ======== 3 | 4 | Some example about ``pyModis`` library and script 5 | 6 | Scripts 7 | ^^^^^^^ 8 | 9 | .. only:: latex 10 | 11 | * :doc:`full_example_gdal` 12 | * :doc:`full_example_mrt` 13 | 14 | .. raw:: latex 15 | 16 | \newpage % hard pagebreak at exactly this position 17 | 18 | .. toctree:: 19 | :maxdepth: 4 20 | 21 | full_example_gdal 22 | full_example_mrt 23 | 24 | Library 25 | ^^^^^^^ 26 | 27 | To test ``pyModis`` library you can find an `Ipython notebook`_ example 28 | in the documentation source code. 29 | If you already downloaded ``pyModis`` source code you have just to 30 | move inside the directory ``pyModis/docs/source/examples`` otherwise 31 | you can download the needed file from 32 | `source code `_ 33 | and move to the directory where you downloaded the file. 34 | 35 | At this point you can start `Ipython notebook`_ running a notebook server 36 | from the command line using the following command 37 | 38 | :: 39 | 40 | ipython notebook 41 | 42 | This will print some information about the notebook server in your console, 43 | and open a web browser to the URL of the web application. 44 | 45 | The landing page of the IPython notebook web application, the dashboard, 46 | shows the notebooks currently available in the notebook directory 47 | (in our case only **pyModis.ipynb**). 48 | 49 | .. image:: ../_static/ipython_dash.png 50 | :scale: 80% 51 | :alt: Ipython notebook dashboard 52 | :align: center 53 | 54 | Clicking on **pyModis.ipynb** link you will start the notebook 55 | 56 | .. image:: ../_static/ipython_example.png 57 | :scale: 40% 58 | :alt: Ipython notebook pyModis example 59 | :align: center 60 | 61 | .. warning:: 62 | 63 | You have to install ``pyModis`` before run the `Ipython notebook`_ example. 64 | 65 | 66 | .. _Ipython notebook: http://ipython.org/notebook.html -------------------------------------------------------------------------------- /docs/source/examples/full_example_gdal.rst: -------------------------------------------------------------------------------- 1 | Example of a full process with GDAL library 2 | =========================================== 3 | 4 | In this short example you will learn how to run a series of 5 | scripts to obtain a GeoTIFF file for each band of the 6 | chosen product using as backend GDAL library. 7 | 8 | .. warning:: 9 | 10 | This example is based on a Linux based system. If you use 11 | another operating system you need to change the paths where data will be saved 12 | 13 | .. _download-data: 14 | 15 | Downloading data 16 | ---------------- 17 | 18 | For first you need to obtain data, so you need to use :doc:`../scripts/modis_download` 19 | 20 | .. warning:: 21 | 22 | Remember to register in the NASA portal following the instructions at :ref:`userpw-label` session 23 | 24 | :: 25 | 26 | mkdir $HOME/tmp 27 | modis_download.py -I -f 2012-12-05 -O -t h28v05,h29v05,h28v04 $HOME/tmp 28 | 29 | .. warning:: 30 | 31 | In this example we are working on the spatial extent of Italy: 32 | for your area of interest, change the tile name(s) according to your region. 33 | 34 | User and password are passed through standard input. 35 | 36 | We are going to download data for only one day (2012-12-05) using the option "-O". 37 | 38 | Inside the ``$HOME/tmp/`` directory you will find a file called *listfileMOD11A1.005.txt* 39 | containing the names of downloaded files. The name of file is related to 40 | the product that you want to download. 41 | 42 | .. warning:: 43 | 44 | Every time that you download new files of the same product they will be overwritten, 45 | so if you need them, you must rename the file before. 46 | 47 | Mosaic data 48 | ----------- 49 | 50 | At this point you need to create the mosaic of the tiles downloaded. 51 | :doc:`../scripts/modis_mosaic` is the script to use. We create a *VRT* 52 | file (``flag -v``) to improve the speed of analysis, without losing any data 53 | only for the first layer :: 54 | 55 | modis_mosaic.py -s "1" -o $HOME/tmp/mosaic -v $HOME/tmp/listfileMOD11A1.005.txt 56 | 57 | The command will create a file called ``mosaic_LST_Day_1km.vrt`` in $HOME/tmp/ 58 | directory 59 | 60 | Convert data 61 | ------------ 62 | 63 | The last part of the procedure is to convert the mosaic using 64 | :doc:`../scripts/modis_convert`. Using *VRT* format it create dataset 65 | of only one later, so you are forced to use ``-s "( 1 )"``. The 66 | following command create a GeoTIFF file called 67 | final_mosaic_LST_Day_1km.vrt.tif :: 68 | 69 | modis_convert.py -v -s "( 1 )" -o $HOME/tmp/final -e 4326 $HOME/tmp/mosaic_LST_Day_1km.vrt 70 | -------------------------------------------------------------------------------- /docs/source/examples/full_example_mrt.rst: -------------------------------------------------------------------------------- 1 | Example reproject data with MRT 2 | =============================== 3 | 4 | In this short example you can understand how to concatenate 5 | the scripts to obtain a GeoTIFF file for each band of the 6 | chosen product using as backend MODIS Reprojection Tools (MRT). 7 | 8 | .. warning:: 9 | 10 | This example is based on a Linux based system. Please if 11 | you use other OS change the paths where data will be saved 12 | 13 | Downloading data 14 | ---------------- 15 | 16 | For first you need to obtain data, so you need to use :doc:`../scripts/modis_download` 17 | 18 | .. warning:: 19 | 20 | Remember to register in the NASA portal following the instructions at :ref:`userpw-label` session 21 | 22 | :: 23 | 24 | modis_download.py -I -f 2012-12-05 -O -t h28v05,h29v05,h28v04 /tmp 25 | 26 | .. warning:: 27 | 28 | In this example we are working on Japan extension, so please 29 | change the name of tiles according with your region. 30 | 31 | User and password are passed through standard input. 32 | 33 | In this example we download data for only one day (2012-12-05) 34 | using the option "-O". 35 | 36 | Inside ``/tmp/`` directory you will find a file called *listfileMOD11A1.005.txt* 37 | containing the names of files downloaded. The name of file it is related to 38 | the product that you download. 39 | 40 | .. warning:: 41 | 42 | Every time that you download new files of same product it will be overwrite, 43 | so if you need it, you should rename the file 44 | 45 | 46 | Mosaic data 47 | ----------- 48 | 49 | :doc:`../scripts/modis_mosaic` is the script to use. 50 | 51 | :: 52 | 53 | modis_mosaic.py -m /path/to/mrt/ -o /tmp/outputfile /tmp/listfileMOD11A1.005.txt 54 | 55 | .. warning:: 56 | 57 | ``/path/to/mrt/`` is the directory where Modis Reprojection Tools is stored 58 | 59 | The output of this command are *outputfile.hdf* and *outputfile.hdf.xml* inside the 60 | directory ``/tmp``. It's reading the input files contained in *listfileMOD11A1.005.txt* 61 | 62 | Convert data 63 | ------------ 64 | 65 | The last part of the procedure is to convert the mosaic, from HDF format and sinusoidal 66 | projection, to GeoTIFF with several projection. You have to use :doc:`../scripts/modis_convert` 67 | 68 | .. only:: html 69 | 70 | :: 71 | 72 | modis_convert.py -s '( 1 1 1 1 1 1 1 1 1 1 1 1 )' -m /path/to/mrt/ -o /tmp/finalfile.tif -g 250 /tmp/outputfile.hdf 73 | 74 | .. only:: latex 75 | 76 | :: 77 | 78 | modis_convert.py -s '( 1 1 1 1 1 1 1 1 1 1 1 1 )' -m /path/to/mrt/ 79 | -o /tmp/finalfile.tif -g 250 /tmp/outputfile.hdf 80 | 81 | Extract quality information 82 | --------------------------- 83 | 84 | If necessary, you can extract specific quality type from the chosen quality layer. 85 | In this particular case, we extract the Mandatory QA flag of the daytime temperature. 86 | You have to use :doc:`../scripts/modis_quality` 87 | 88 | .. only:: html 89 | 90 | :: 91 | 92 | modis_quality.py -p MOD11A1 -l 1 -t 1 /tmp/outputfile.hdf /tmp/mod11a1_daytime_qaflag.tif 93 | 94 | .. only:: latex 95 | 96 | :: 97 | 98 | modis_quality.py -p MOD11A1 -l 1 -t 1 /tmp/outputfile.hdf 99 | /tmp/mod11a1_daytime_qaflag.tif 100 | -------------------------------------------------------------------------------- /docs/source/examples/pyModis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:3f28a84fd60926eecfe4af2e2afed0c1d0b7203c32431e0b6e90253ea046975f" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "heading", 13 | "level": 1, 14 | "metadata": {}, 15 | "source": [ 16 | "pyModis notebook" 17 | ] 18 | }, 19 | { 20 | "cell_type": "heading", 21 | "level": 2, 22 | "metadata": {}, 23 | "source": [ 24 | "Download data" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "First we have to import pymodis library and set all the needed variables" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "collapsed": false, 37 | "input": [ 38 | "import os\n", 39 | "import glob\n", 40 | "from IPython.core.display import Image\n", 41 | "from pymodis import downmodis" 42 | ], 43 | "language": "python", 44 | "metadata": {}, 45 | "outputs": [] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "collapsed": false, 50 | "input": [ 51 | "# destination foldert\n", 52 | "dest = \"/tmp\"\n", 53 | "# tiles to download\n", 54 | "tiles = \"h18v04,h19v04\"\n", 55 | "# starting day\n", 56 | "day = \"2014-08-14\"\n", 57 | "# number of day to download\n", 58 | "delta = 1" 59 | ], 60 | "language": "python", 61 | "metadata": {}, 62 | "outputs": [] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "At this point we can initialize the downmodis object. We are going to download MODIS LST product, in the \"/tmp\" directory" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "collapsed": false, 74 | "input": [ 75 | "modisDown = downmodis.downModis(destinationFolder=dest, tiles=tiles, today=day, delta=delta)" 76 | ], 77 | "language": "python", 78 | "metadata": {}, 79 | "outputs": [] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "collapsed": false, 84 | "input": [ 85 | "modisDown.connect()" 86 | ], 87 | "language": "python", 88 | "metadata": {}, 89 | "outputs": [] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "At this point we start the download of files." 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "
Warning
\n", 103 | "The next operation could take some minutes depending on your internet speed
" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "collapsed": false, 109 | "input": [ 110 | "modisDown.downloadsAllDay()" 111 | ], 112 | "language": "python", 113 | "metadata": {}, 114 | "outputs": [] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "collapsed": false, 119 | "input": [ 120 | "# create the list of files to use\n", 121 | "files = glob.glob(os.path.join(dest, 'MOD11A1.A2014*.hdf'))\n", 122 | "print files" 123 | ], 124 | "language": "python", 125 | "metadata": {}, 126 | "outputs": [] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "collapsed": false, 131 | "input": [ 132 | "from topng import hdf2png\n", 133 | "pngfile = hdf2png(files[0])\n", 134 | "Image(filename=pngfile)" 135 | ], 136 | "language": "python", 137 | "metadata": {}, 138 | "outputs": [] 139 | }, 140 | { 141 | "cell_type": "heading", 142 | "level": 2, 143 | "metadata": {}, 144 | "source": [ 145 | "Parse the data" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "We import the needed modules and after we obtain a list with the full path to the downloaded MODIS files" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "collapsed": false, 158 | "input": [ 159 | "from pymodis import parsemodis" 160 | ], 161 | "language": "python", 162 | "metadata": {}, 163 | "outputs": [] 164 | }, 165 | { 166 | "cell_type": "heading", 167 | "level": 4, 168 | "metadata": {}, 169 | "source": [ 170 | "Parse single data" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "At this point we can parse one file (in this case the first one), creating a parseModis object" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "collapsed": false, 183 | "input": [ 184 | "modisParse = parsemodis.parseModis(files[0])" 185 | ], 186 | "language": "python", 187 | "metadata": {}, 188 | "outputs": [] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "Now you can obtain several parameters from the MODIS metadata, we query only some values to show you:" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "collapsed": false, 200 | "input": [ 201 | "# bounding box of the tiles\n", 202 | "modisParse.retBoundary()" 203 | ], 204 | "language": "python", 205 | "metadata": {}, 206 | "outputs": [] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "collapsed": false, 211 | "input": [ 212 | "# quality statistics\n", 213 | "modisParse.retMeasure()" 214 | ], 215 | "language": "python", 216 | "metadata": {}, 217 | "outputs": [] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "collapsed": false, 222 | "input": [ 223 | "modisParse.retRangeTime()" 224 | ], 225 | "language": "python", 226 | "metadata": {}, 227 | "outputs": [] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": {}, 232 | "source": [ 233 | "Check parseModis class documentation for more info" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "collapsed": false, 239 | "input": [ 240 | "parsemodis.parseModis?" 241 | ], 242 | "language": "python", 243 | "metadata": {}, 244 | "outputs": [] 245 | }, 246 | { 247 | "cell_type": "heading", 248 | "level": 4, 249 | "metadata": {}, 250 | "source": [ 251 | "Parse multiple data" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "metadata": {}, 257 | "source": [ 258 | "After the test with only a MODIS file, we are going to test the parsing for multiple files" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "collapsed": false, 264 | "input": [ 265 | "modisMultiParse = parsemodis.parseModisMulti(files)" 266 | ], 267 | "language": "python", 268 | "metadata": {}, 269 | "outputs": [] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "Now you can obtain the value of boundary" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "collapsed": false, 281 | "input": [ 282 | "modisMultiParse.valBound()\n", 283 | "modisMultiParse.boundary" 284 | ], 285 | "language": "python", 286 | "metadata": {}, 287 | "outputs": [] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": {}, 292 | "source": [ 293 | "or write a xml for a MODIS mosaic file" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "collapsed": false, 299 | "input": [ 300 | "modisMultiParse.writexml(os.path.join(dest, 'modismultiparse.xml'))" 301 | ], 302 | "language": "python", 303 | "metadata": {}, 304 | "outputs": [] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "at the end you can read the created file and print the lines" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "collapsed": false, 316 | "input": [ 317 | "f = open(os.path.join(dest, 'modismultiparse.xml'))\n", 318 | "lines = f.readlines()\n", 319 | "p = [l.strip() for l in lines]\n", 320 | "f.close()\n", 321 | "print \"\\n\".join(p)" 322 | ], 323 | "language": "python", 324 | "metadata": {}, 325 | "outputs": [] 326 | }, 327 | { 328 | "cell_type": "heading", 329 | "level": 2, 330 | "metadata": {}, 331 | "source": [ 332 | "Create a mosaic file" 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": {}, 338 | "source": [ 339 | "We are going to use the GDAL library to create the mosaic. As subset we are going to use daily and nightly temperature and it's quality layer" 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "collapsed": false, 345 | "input": [ 346 | "from pymodis.convertmodis_gdal import createMosaicGDAL\n", 347 | "# [daily temp, quality for daily, not used, not used, nightly temp, quality for nightly]\n", 348 | "subset = [1,1,0,0,1,1]\n", 349 | "output_pref = os.path.join(dest, 'MOD11A1.A2014226.mosaic')\n", 350 | "output_tif = os.path.join(dest, 'MOD11A1.A2014226.mosaic.tif')" 351 | ], 352 | "language": "python", 353 | "metadata": {}, 354 | "outputs": [] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": {}, 359 | "source": [ 360 | "First we'll initialize the mosaic object" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "collapsed": false, 366 | "input": [ 367 | "# the first parameter is a list with the original tiles,\n", 368 | "# the second one is a list with the the subset to process,\n", 369 | "# the last is the output format, in this case GeoTiff\n", 370 | "mosaic = createMosaicGDAL(files, subset, 'GTiff')" 371 | ], 372 | "language": "python", 373 | "metadata": {}, 374 | "outputs": [] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": {}, 379 | "source": [ 380 | "At this point we create the xml file with the information of input data, and a multilayr GeoTiff file containing the mosaic of the choosen band" 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "collapsed": false, 386 | "input": [ 387 | "mosaic.run(output_tif)" 388 | ], 389 | "language": "python", 390 | "metadata": {}, 391 | "outputs": [] 392 | }, 393 | { 394 | "cell_type": "markdown", 395 | "metadata": {}, 396 | "source": [ 397 | "Finally we can also create a GDAL VRT file, a XML file containing the information about input data. This is really powerfull if you want convert it in different format or projection system" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "collapsed": false, 403 | "input": [ 404 | "mosaic.write_vrt(output_pref)" 405 | ], 406 | "language": "python", 407 | "metadata": {}, 408 | "outputs": [] 409 | }, 410 | { 411 | "cell_type": "heading", 412 | "level": 2, 413 | "metadata": {}, 414 | "source": [ 415 | "Convert data" 416 | ] 417 | }, 418 | { 419 | "cell_type": "heading", 420 | "level": 4, 421 | "metadata": {}, 422 | "source": [ 423 | "Single HDF file" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": {}, 429 | "source": [ 430 | "In this first example we are going to convert an original MODIS HDF file using GDAL library" 431 | ] 432 | }, 433 | { 434 | "cell_type": "code", 435 | "collapsed": false, 436 | "input": [ 437 | "from pymodis.convertmodis_gdal import convertModisGDAL\n", 438 | "output_pref = os.path.join(dest, 'MOD11A1.A2014226.h18v04')" 439 | ], 440 | "language": "python", 441 | "metadata": {}, 442 | "outputs": [] 443 | }, 444 | { 445 | "cell_type": "markdown", 446 | "metadata": {}, 447 | "source": [ 448 | "We are going to convert a single tile, with the 'subset' already used for mosaicking, the output resolution will be 1000 meters and the projection system will be EU-LAEA" 449 | ] 450 | }, 451 | { 452 | "cell_type": "code", 453 | "collapsed": false, 454 | "input": [ 455 | "convertsingle = convertModisGDAL(hdfname=files[0], prefix=output_pref, subset=subset, res=1000, epsg=3035)\n", 456 | "convertsingle.run()" 457 | ], 458 | "language": "python", 459 | "metadata": {}, 460 | "outputs": [] 461 | }, 462 | { 463 | "cell_type": "heading", 464 | "level": 4, 465 | "metadata": {}, 466 | "source": [ 467 | "VRT mosaic file" 468 | ] 469 | }, 470 | { 471 | "cell_type": "markdown", 472 | "metadata": {}, 473 | "source": [ 474 | "We created separated VRT file, one for each choosen subset. So first we collect the name of VRT files" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "collapsed": false, 480 | "input": [ 481 | "vrtfiles = glob.glob(os.path.join(dest, 'MOD11A1.A2014*.vrt'))\n", 482 | "print vrtfiles" 483 | ], 484 | "language": "python", 485 | "metadata": {}, 486 | "outputs": [] 487 | }, 488 | { 489 | "cell_type": "markdown", 490 | "metadata": {}, 491 | "source": [ 492 | "Now we can convert all the VRT files in a *``for``* loop " 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "collapsed": false, 498 | "input": [ 499 | "for f in vrtfiles:\n", 500 | " base = os.path.basename(f).replace('.vrt', '_vrt')\n", 501 | " output = os.path.join(dest, base)\n", 502 | " convertsingle = convertModisGDAL(hdfname=f, prefix=output, subset= [1,1,1,1], res=1000, epsg=3035, vrt=True)\n", 503 | " convertsingle.run_vrt_separated()" 504 | ], 505 | "language": "python", 506 | "metadata": {}, 507 | "outputs": [] 508 | }, 509 | { 510 | "cell_type": "markdown", 511 | "metadata": {}, 512 | "source": [ 513 | "It will create 4 GeoTIFF files ready to be processed." 514 | ] 515 | }, 516 | { 517 | "cell_type": "code", 518 | "collapsed": false, 519 | "input": [ 520 | "vrttiffiles = glob.glob(os.path.join(dest, 'MOD11A1.A2014*_vrt.tif'))\n", 521 | "print vrttiffiles" 522 | ], 523 | "language": "python", 524 | "metadata": {}, 525 | "outputs": [] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "collapsed": false, 530 | "input": [ 531 | "from topng import tif2png\n", 532 | "pngfile = tif2png(vrttiffiles[1])\n", 533 | "Image(filename=pngfile)" 534 | ], 535 | "language": "python", 536 | "metadata": {}, 537 | "outputs": [] 538 | }, 539 | { 540 | "cell_type": "heading", 541 | "level": 3, 542 | "metadata": {}, 543 | "source": [ 544 | "The tutorial is finished, you can find more info at pyModis website" 545 | ] 546 | } 547 | ], 548 | "metadata": {} 549 | } 550 | ] 551 | } 552 | -------------------------------------------------------------------------------- /docs/source/examples/topng.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Sep 9 22:51:41 2014 4 | 5 | @author: lucadelu 6 | """ 7 | 8 | import os 9 | import subprocess 10 | try: 11 | import osgeo.gdal as gdal 12 | except ImportError: 13 | try: 14 | import gdal 15 | except ImportError: 16 | raise Exception('Python GDAL library not found, please install python-gdal') 17 | 18 | lstcolortable = "\ 19 | 0 255 255 255\n\ 20 | 9657.5 0 0 40\n\ 21 | 11657.5 91 10 168\n\ 22 | 12407.5 91 50 128\n\ 23 | 12657.5 50 0 150\n\ 24 | 12907.5 4 25 130\n\ 25 | 13157.5 8 54 106\n\ 26 | 13257.5 4 20 150\n\ 27 | 13407.5 0 50 255\n\ 28 | 13557.5 8 10 118\n\ 29 | 13654.42755 8 113 155\n\ 30 | 13658.19275 8 118 157\n\ 31 | 13662.029699999999 8 123 158\n\ 32 | 13665.93835 8 128 159\n\ 33 | 13669.918750000001 8 133 159\n\ 34 | 13673.97085 8 136 160\n\ 35 | 13678.094649999999 8 140 162\n\ 36 | 13682.290199999999 8 145 163\n\ 37 | 13686.55745 8 150 165\n\ 38 | 13690.8964 8 156 166\n\ 39 | 13695.3071 8 161 167\n\ 40 | 13699.789500000001 8 166 169\n\ 41 | 13704.343650000001 8 172 172\n\ 42 | 13708.969450000001 8 177 177\n\ 43 | 13713.66705 8 182 182\n\ 44 | 13718.436299999999 8 187 187\n\ 45 | 13723.2773 8 192 192\n\ 46 | 13728.190049999999 8 197 197\n\ 47 | 13733.17445 8 200 200\n\ 48 | 13738.230600000001 8 204 204\n\ 49 | 13743.3585 8 209 209\n\ 50 | 13748.5581 8 213 213\n\ 51 | 13753.829400000001 8 216 216\n\ 52 | 13759.172399999999 8 219 219\n\ 53 | 13764.587149999999 8 222 222\n\ 54 | 13770.07365 8 225 225\n\ 55 | 13775.631799999999 8 227 227\n\ 56 | 13781.261699999999 8 230 230\n\ 57 | 13786.96335 8 233 233\n\ 58 | 13792.736699999999 8 235 235\n\ 59 | 13798.581749999999 8 237 236\n\ 60 | 13804.4985 8 238 234\n\ 61 | 13810.486999999999 8 238 229\n\ 62 | 13816.547200000001 8 238 223\n\ 63 | 13822.67915 8 237 216\n\ 64 | 13828.882799999999 8 235 209\n\ 65 | 13835.158149999999 8 234 202\n\ 66 | 13841.50525 8 232 192\n\ 67 | 13847.92405 8 231 178\n\ 68 | 13854.4146 8 230 162\n\ 69 | 13860.976849999999 8 229 147\n\ 70 | 13867.6108 8 227 133\n\ 71 | 13874.31645 8 226 123\n\ 72 | 13881.093849999999 8 224 116\n\ 73 | 13887.942999999999 8 221 114\n\ 74 | 13894.863799999999 8 219 114\n\ 75 | 13901.856400000001 8 216 115\n\ 76 | 13908.92065 8 213 117\n\ 77 | 13916.05665 8 209 118\n\ 78 | 13923.264349999999 8 204 118\n\ 79 | 13930.543799999999 8 199 117\n\ 80 | 13937.894899999999 8 193 115\n\ 81 | 13945.317800000001 8 188 112\n\ 82 | 13952.81235 8 184 107\n\ 83 | 13960.378650000001 8 181 99\n\ 84 | 13968.0167 8 178 91\n\ 85 | 13975.72645 8 175 84\n\ 86 | 13983.507900000001 8 172 81\n\ 87 | 13991.36105 8 169 80\n\ 88 | 13999.28595 8 164 80\n\ 89 | 14007.28255 8 159 80\n\ 90 | 14015.350899999999 8 153 80\n\ 91 | 14023.490949999999 8 148 79\n\ 92 | 14031.7027 8 143 79\n\ 93 | 14039.986199999999 8 138 79\n\ 94 | 14048.341399999999 8 134 78\n\ 95 | 14056.76835 8 132 75\n\ 96 | 14065.267 8 134 70\n\ 97 | 14073.83735 8 137 63\n\ 98 | 14082.4794 8 140 56\n\ 99 | 14091.1932 8 140 48\n\ 100 | 14099.97875 8 139 37\n\ 101 | 14108.835950000001 9 138 24\n\ 102 | 14117.7649 14 139 14\n\ 103 | 14126.765600000001 24 141 9\n\ 104 | 14135.838 37 146 8\n\ 105 | 14144.982099999999 47 151 8\n\ 106 | 14154.197899999999 52 156 8\n\ 107 | 14163.48545 55 161 8\n\ 108 | 14172.84475 57 166 8\n\ 109 | 14182.2757 60 172 8\n\ 110 | 14191.778399999999 65 177 8\n\ 111 | 14201.352849999999 70 182 8\n\ 112 | 14210.998949999999 75 187 8\n\ 113 | 14220.716850000001 80 192 8\n\ 114 | 14230.5064 85 196 8\n\ 115 | 14240.367700000001 89 199 8\n\ 116 | 14250.3007 95 201 8\n\ 117 | 14260.30545 103 204 8\n\ 118 | 14270.3819 110 206 8\n\ 119 | 14280.530049999999 118 209 8\n\ 120 | 14290.749949999999 126 211 8\n\ 121 | 14301.04155 134 214 8\n\ 122 | 14311.404850000001 142 217 8\n\ 123 | 14321.839900000001 151 219 8\n\ 124 | 14332.346649999999 160 222 8\n\ 125 | 14342.925149999999 169 225 8\n\ 126 | 14353.575349999999 179 227 8\n\ 127 | 14364.29725 187 229 8\n\ 128 | 14375.090899999999 195 230 8\n\ 129 | 14385.956249999999 205 230 8\n\ 130 | 14396.8933 215 230 8\n\ 131 | 14407.902099999999 223 229 8\n\ 132 | 14418.982599999999 226 227 8\n\ 133 | 14430.13485 225 224 8\n\ 134 | 14441.3588 224 221 8\n\ 135 | 14452.65445 224 217 8\n\ 136 | 14464.021849999999 224 211 8\n\ 137 | 14475.460950000001 224 205 8\n\ 138 | 14486.971750000001 224 198 8\n\ 139 | 14498.5543 224 191 8\n\ 140 | 14510.208549999999 224 185 8\n\ 141 | 14521.93455 224 180 8\n\ 142 | 14533.7322 224 174 8\n\ 143 | 14545.601650000001 224 166 8\n\ 144 | 14557.542750000001 224 159 8\n\ 145 | 14569.5556 224 151 8\n\ 146 | 14581.6402 224 143 8\n\ 147 | 14593.79645 224 135 8\n\ 148 | 14606.024450000001 224 127 8\n\ 149 | 14618.324199999999 224 119 8\n\ 150 | 14630.69565 224 111 8\n\ 151 | 14643.138800000001 224 103 8\n\ 152 | 14655.65365 224 95 8\n\ 153 | 14668.240250000001 224 89 8\n\ 154 | 14680.8986 224 84 8\n\ 155 | 14693.6286 224 78 8\n\ 156 | 14706.430350000001 223 70 8\n\ 157 | 14719.30385 223 63 8\n\ 158 | 14732.24905 223 55 8\n\ 159 | 14745.265950000001 222 46 8\n\ 160 | 14758.35455 221 37 8\n\ 161 | 14771.5149 219 28 8\n\ 162 | 14784.746950000001 216 19 8\n\ 163 | 14798.05075 213 12 8\n\ 164 | 14811.42625 209 9 8\n\ 165 | 14824.873449999999 204 8 8\n\ 166 | 14838.392400000001 200 8 8\n\ 167 | 14851.983050000001 196 8 8\n\ 168 | 14865.64545 190 8 8\n\ 169 | 14879.37955 182 8 8\n\ 170 | 14893.18535 175 8 8\n\ 171 | 14907.06285 167 8 8\n\ 172 | 14921.0121 159 8 8\n\ 173 | 14935.033100000001 151 8 8\n\ 174 | 14949.125749999999 143 8 8\n\ 175 | 14963.290199999999 135 8 8\n\ 176 | 14977.5263 127 8 8\n\ 177 | 14991.834150000001 120 8 8\n\ 178 | 15006.2137 115 8 8\n\ 179 | 15020.665000000001 110 8 8\n\ 180 | 15035.18795 104 8 8\n\ 181 | 15049.7827 108 13 13\n\ 182 | 15064.4491 112 19 19\n\ 183 | 15079.187250000001 114 22 22\n\ 184 | 15093.997149999999 115 26 26\n\ 185 | 15108.87875 118 30 30\n\ 186 | 15123.832050000001 119 34 33\n\ 187 | 15138.857050000001 121 38 38\n\ 188 | 15153.953799999999 123 41 41\n\ 189 | 15169.12225 125 45 45\n\ 190 | 15184.362450000001 127 49 49\n\ 191 | 15199.674349999999 128 52 53\n\ 192 | 15215.05795 130 56 56\n\ 193 | 15230.513300000001 132 60 60\n\ 194 | 15246.040349999999 134 64 63\n\ 195 | 15261.639150000001 136 67 67\n\ 196 | 15277.309649999999 138 71 70\n\ 197 | 15293.05185 140 75 74\n\ 198 | 15308.865750000001 142 79 78\n\ 199 | 15324.751399999999 143 82 82\n\ 200 | 15340.7088 145 85 85\n\ 201 | 15356.73785 147 89 90\n\ 202 | 15372.83865 149 93 93\n\ 203 | 15389.011200000001 150 97 97\n\ 204 | 15405.255450000001 152 100 100\n\ 205 | 15421.571400000001 154 104 104\n\ 206 | 15437.959049999999 156 107 108\n\ 207 | 15454.418449999999 158 112 111\n\ 208 | 15470.9496 160 115 115\n\ 209 | 15487.5524 162 119 119\n\ 210 | 15504.22695 164 123 123\n\ 211 | 15520.973249999999 165 126 126\n\ 212 | 15537.7912 168 130 130\n\ 213 | 15554.68095 169 134 134\n\ 214 | 15571.64235 170 138 137\n\ 215 | 15588.675499999999 173 141 141\n\ 216 | 15605.780350000001 175 145 145\n\ 217 | 15622.95695 176 149 149\n\ 218 | 15640.205250000001 178 153 153\n\ 219 | 15657.525250000001 181 156 156\n\ 220 | 15674.916999999999 182 159 159\n\ 221 | 15692.380450000001 183 163 163\n\ 222 | 15709.9156 185 167 167\n\ 223 | 15727.522499999999 188 170 171\n\ 224 | 15745.2011 190 174 174\n\ 225 | 15762.95145 191 178 178\n\ 226 | 15780.773499999999 193 182 182\n\ 227 | 15798.66725 195 185 185\n\ 228 | 15816.632750000001 197 189 189\n\ 229 | 15834.66995 199 192 193\n\ 230 | 15852.778850000001 200 197 197\n\ 231 | 15870.959500000001 202 200 201\n\ 232 | " 233 | # 234 | #lstcolortable = "\ 235 | #0 255 255 255\n\ 236 | #9657 0 0 40\n\ 237 | #15870 202 200 201\n\ 238 | #" 239 | 240 | 241 | def hdf2png(hdffile, layer=1): 242 | src_ds = gdal.Open(hdffile) 243 | layers = src_ds.GetSubDatasets() 244 | output = hdffile.split('.')[:-1] 245 | output.append('png') 246 | outname = '.'.join(output) 247 | pid = os.getpid() 248 | colortable = open('colortable_{p}'.format(p=pid), 'w') 249 | colortable.write(lstcolortable) 250 | colortable.close() 251 | subprocess.call(['gdaldem', 'color-relief', '-of', 'PNG', layers[layer][0], 252 | colortable.name, outname]) 253 | #os.remove(colortable.name) 254 | return outname 255 | 256 | 257 | def tif2png(tiffile): 258 | output = tiffile.split('.')[:-1] 259 | output.append('png') 260 | pid = os.getpid() 261 | colortable = open('colortable_{p}'.format(p=pid), 'w') 262 | colortable.write(lstcolortable) 263 | colortable.close() 264 | subprocess.call(['gdaldem', 'color-relief', '-of', 'PNG', tiffile, 265 | colortable.name, '.'.join(output)]) 266 | os.remove(colortable.name) 267 | return '.'.join(output) 268 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. pyModis documentation master file, created by 2 | sphinx-quickstart on Thu Jun 28 10:50:11 2012. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to pyModis 7 | ================== 8 | 9 | ``pyModis`` is a Free and Open Source Python based library to work with MODIS data. 10 | It offers bulk-download for user selected time ranges, mosaicking of MODIS tiles, 11 | and the reprojection from Sinusoidal to other projections, convert HDF format to 12 | other formats and the extraction of data quality information. 13 | 14 | ``pyModis`` library was developed to replace old bash scripts developed by Markus 15 | Neteler to download MODIS data from NASA FTP server. It is very useful for 16 | `GIS and Remote Sensing Platform`_ of `Fondazione Edmund Mach`_ to update 17 | its large collection of MODIS data. 18 | 19 | It has several features: 20 | 21 | * for downloading large numbers of MODIS HDF/XML files and for using 22 | it in a cron job for continuous automated updating; it 23 | supports both FTP and HTTP NASA repositories 24 | 25 | * parses the XML file to obtain information about the HDF files 26 | 27 | * converts a HDF MODIS file to GEOTIFF format by either using `MODIS Reprojection Tool`_ 28 | or `GDAL`_ (pyModis >= 1.0) 29 | 30 | * creates a mosaic of several tiles by either using `MODIS Reprojection Tool`_ or 31 | `GDAL`_ (pyModis >= 1.0) 32 | 33 | * creates the XML metadata file with the information of all tiles used for the mosaic 34 | 35 | * extracts specific information from bit-encoded MODIS quality assessment layers 36 | of different product types 37 | 38 | * Graphical User Interface for each script written in `wxPython`_ (pyModis >= 1.0) 39 | 40 | * it support Python 2 and Python 3 (pyModis >= 2.0) 41 | 42 | .. only:: latex 43 | 44 | We acknowledge the `Fondazione Edmund Mach`_ for promoting the development of 45 | free and open source software. 46 | 47 | .. only:: html 48 | 49 | Contents: 50 | 51 | .. toctree:: 52 | :maxdepth: 2 53 | 54 | info 55 | scripts/software 56 | examples/examples 57 | pymodis/modules 58 | 59 | .. only:: html 60 | 61 | We acknowledge the `Fondazione Edmund Mach`_ for promoting the development of 62 | free and open source software. 63 | 64 | .. Indices and tables 65 | ================== 66 | 67 | * :ref:`genindex` 68 | * :ref:`modindex` 69 | * :ref:`search` 70 | 71 | .. _GIS and Remote Sensing Platform: http://gis.cri.fmach.it 72 | .. _Fondazione Edmund Mach: http://www.fmach.it 73 | .. _MODIS Reprojection Tool: https://lpdaac.usgs.gov/lpdaac/tools/modis_reprojection_tool 74 | .. _GDAL: http://www.gdal.org 75 | .. _wxPython: http://www.wxpython.org/ 76 | -------------------------------------------------------------------------------- /docs/source/info.rst: -------------------------------------------------------------------------------- 1 | About pyModis 2 | ============= 3 | 4 | Requirements 5 | ------------ 6 | 7 | ``pyModis`` requires **Python GDAL**, **Numpy**, **requests** and **future** packages. 8 | 9 | If you want to use the Graphical User Interface you have to 10 | install also **wxPython** library. 11 | 12 | You can use also software is `MODIS Reprojection Tool `_ 13 | to convert or mosaic MODIS HDF files. 14 | 15 | .. _userpw-label: 16 | 17 | User and password 18 | ^^^^^^^^^^^^^^^^^ 19 | To be able to download data you need user and password provided by NASA. 20 | Please **register at https://urs.earthdata.nasa.gov/users/new**; now login 21 | and move to your profile page. Go to "My application" tab and approve the 22 | following applications "LP DAAC Data Pool", "Earthdata Search" (for Snow products you 23 | have to enable also "NSIDC_DATAPOOL_OPS"). 24 | 25 | .. image:: _static/urs_earthdata_nasa_gov.png 26 | :scale: 60% 27 | :alt: GUI for modis_download.py 28 | :align: center 29 | :class: gui 30 | 31 | If you are an already registered user, login and enable the applications 32 | at https://urs.earthdata.nasa.gov/home 33 | 34 | 35 | How to install pyModis 36 | ---------------------- 37 | 38 | Using pip 39 | ^^^^^^^^^ 40 | 41 | From version 0.6.3 it is possible to install ``pyModis`` using 42 | `pip `_. You have to run the following 43 | command as administrator 44 | 45 | .. code-block:: none 46 | 47 | pip install pyModis 48 | 49 | If you need to update your ``pyModis`` version you have to run 50 | 51 | .. code-block:: none 52 | 53 | pip install --upgrade pyModis 54 | 55 | With ``pip`` it is also really simple to remove the library 56 | 57 | .. code-block:: none 58 | 59 | pip uninstall pyModis 60 | 61 | Compile from source 62 | ^^^^^^^^^^^^^^^^^^^ 63 | 64 | Compile ``pyModis`` is very simple. First you need to download ``pyModis`` 65 | source code from `github repository `_. 66 | 67 | You can use `git `_ to download the latest code 68 | (with the whole history and so it contain all the different stable versions, 69 | from the last to the first) 70 | 71 | .. code-block:: none 72 | 73 | git clone https://github.com/lucadelu/pyModis.git 74 | 75 | or `download the latest stable version `_ 76 | from the repository and decompress it. 77 | 78 | Now enter the ``pyModis`` folder and launch as administrator of 79 | your computer 80 | 81 | .. code-block:: none 82 | 83 | python setup.py install 84 | 85 | If the installation doesn't return any errors you should be able to use 86 | ``pyModis`` library from a Python console. Then, launch a your favorite 87 | Python console (I really suggest ``ipython``) and digit :: 88 | 89 | import pymodis 90 | 91 | If the console doesn't return any error like this :: 92 | 93 | ImportError: No module named pymodis 94 | 95 | the ``pyModis`` library has been installed properly and you can use it 96 | or one of the tools distributed with ``pyModis``. 97 | 98 | If you want to install into /usr/local/, run 99 | 100 | .. code-block:: none 101 | 102 | python setup.py install --prefix=/usr/local 103 | 104 | In this case, if you get the following error 105 | 106 | .. code-block:: none 107 | 108 | TEST FAILED: /usr/local/lib/python2.7/site-packages/ does NOT support .pth files 109 | 110 | then you need to define the PYTHONPATH environmental variable :: 111 | 112 | export PYTHONPATH=/usr/local/lib/python2.7/site-packages 113 | python setup.py install --prefix=/usr/local 114 | 115 | and now re-run the installation command. 116 | 117 | Install on Windows with osgeo4w 118 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 119 | 120 | .. warning:: 121 | 122 | Using this way to install pyModis it will be possible to use pyModis 123 | only from OSGeo4W environment. 124 | 125 | It will not possible to use other versions of Python except the OSGeo4W one. 126 | 127 | The simple way to install ``pyModis`` on Windows is to use 128 | `OSGeo4W `_. 129 | 130 | .. note:: 131 | 132 | To execute OSGeo4W may be required to run it as Administrator. 133 | 134 | 135 | Choose *Advanced Install* in the first step of installation and set the 136 | corrected value until the packages selection. 137 | 138 | At this point select the following packages: 139 | 140 | * *gdal-python* 141 | * *python-numpy* 142 | * *python-requests* 143 | * *python-future* 144 | * *wxpython* 145 | 146 | OSGeo4W will install all the required dependencies. 147 | 148 | At this point, using the OSGeo4W shell, you can follow `Compile from source`_ 149 | section to install pyModis. 150 | 151 | Install on Windows without osgeo4w (old and not updated) 152 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 153 | 154 | Another way to install ``pyModis`` on Windows is to install latest Python 2.7 155 | from http://python.org/download/ 156 | 157 | Now you have to modify the "Path" environment variable using *powershell* running 158 | 159 | .. only:: html 160 | 161 | .. code-block:: none 162 | 163 | [Environment]::SetEnvironmentVariable("Path", "$env:Path;C:\Python27\;C:\Python27\Scripts\", "User") 164 | 165 | .. only:: latex 166 | 167 | .. code-block:: none 168 | 169 | [Environment]::SetEnvironmentVariable("Path", 170 | "$env:Path;C:\Python27\;C:\Python27\Scripts\", "User") 171 | 172 | Download and install the last version of Distribute for Windows from 173 | http://python-distribute.org/distribute_setup.py 174 | 175 | At this point you have to move to standard command line (*cmd*) and install *pip* 176 | using *easy_install* 177 | 178 | .. code-block:: none 179 | 180 | easy_install pip 181 | 182 | Now install `numpy `_ library using *easy_install* because 183 | installation from pip is broken (this is required only for version >= 0.7.1) 184 | 185 | .. code-block:: none 186 | 187 | easy_install numpy GDAL 188 | 189 | If you want the Graphical User Interface you have to install also **wxPython** 190 | 191 | .. code-block:: none 192 | 193 | easy_install WxPython WxPython-Common 194 | 195 | Finally install ``pyModis`` using *pip* 196 | 197 | .. code-block:: none 198 | 199 | pip install pyModis 200 | 201 | If you want use the GUI you have to `download and install wxPython `_ 202 | 203 | Troubleshooting 204 | --------------- 205 | 206 | Problem installing dependencies with pip 207 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 208 | 209 | .. warning:: 210 | 211 | Sometimes *pip* return error when it try to install Python GDAL, Numpy or wxPython. 212 | You can solve this problem installing Python GDAL or Numpy using the 213 | version of your operating system. 214 | 215 | 216 | How to report a bug 217 | ------------------- 218 | 219 | If you find any problems in ``pyModis`` library you can report it using 220 | the `issues tracker of github `_. 221 | 222 | How to compile documentation 223 | ---------------------------- 224 | 225 | This documentation has been made with `Sphinx `_, so you 226 | need to install it to compile the original files to obtain different 227 | output formats. 228 | 229 | Please enter the ``docs`` folder of ``pyModis`` source and run :: 230 | 231 | make 232 | 233 | with one of the following target to obtain the desired output: 234 | 235 | - **html**: to make standalone HTML files 236 | - **dirhtml**: to make HTML files named index.html in directories 237 | - **singlehtml**: to make a single large HTML file 238 | - **pickle**: to make pickle files 239 | - **json**: to make JSON files 240 | - **htmlhelp**: to make HTML files and a HTML help project 241 | - **qthelp**: to make HTML files and a qthelp project 242 | - **devhelp**: to make HTML files and a Devhelp project 243 | - **epub**: to make an epub 244 | - **latex**: to make LaTeX files, you can set PAPER=a4 or PAPER=letter 245 | - **latexpdf**: to make LaTeX files and run them through pdflatex 246 | - **text**: to make text files 247 | - **man**: to make manual pages 248 | - **texinfo**: to make Texinfo files 249 | - **info**: to make Texinfo files and run them through makeinfo 250 | - **gettext**: to make PO message catalogs 251 | - **changes**: to make an overview of all changed/added/deprecated items 252 | - **linkcheck**: to check all external links for integrity 253 | - **doctest**: to run all doctests embedded in the documentation (if enabled) 254 | 255 | PDF link in HTML 256 | ^^^^^^^^^^^^^^^^ 257 | To insert a link to PDF file of pyModis documentation into HTML documentation 258 | (the link will be added on the sidebar) you have to compile first the PDF and 259 | after the HTML, so you need to launch:: 260 | 261 | make latexpdf 262 | make html 263 | 264 | If PDF file is missing no link will be added 265 | 266 | Ohloh statistics 267 | ---------------- 268 | 269 | .. only:: html 270 | 271 | .. raw:: html 272 | 273 | 274 | 275 | 278 | 281 | 282 | 283 | 286 | 289 | 290 |
276 | 277 | 279 | 280 |
284 | 285 | 287 | 288 |
291 | 292 | .. only:: latex 293 | 294 | For more information about ``pyModis`` please visit the 295 | `pyModis Ohloh page `_ 296 | -------------------------------------------------------------------------------- /docs/source/pymodis/convertmodis.rst: -------------------------------------------------------------------------------- 1 | :mod:`convertmodis` module 2 | ------------------------------------------------------------------------------------------------------------------------------------------ 3 | 4 | .. automodule:: pymodis.convertmodis 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | .. only:: latex 10 | 11 | .. raw:: latex 12 | 13 | \newpage % hard pagebreak at exactly this position 14 | -------------------------------------------------------------------------------- /docs/source/pymodis/convertmodis_gdal.rst: -------------------------------------------------------------------------------- 1 | :mod:`convertmodis_gdal` module 2 | ------------------------------------------------------------------------ 3 | 4 | .. automodule:: pymodis.convertmodis_gdal 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | .. only:: latex 10 | 11 | .. raw:: latex 12 | 13 | \newpage % hard pagebreak at exactly this position 14 | -------------------------------------------------------------------------------- /docs/source/pymodis/downmodis.rst: -------------------------------------------------------------------------------- 1 | :mod:`downmodis` module 2 | ------------------------------------------------------------------------------------ 3 | 4 | .. automodule:: pymodis.downmodis 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | .. only:: latex 10 | 11 | .. raw:: latex 12 | 13 | \newpage % hard pagebreak at exactly this position 14 | -------------------------------------------------------------------------------- /docs/source/pymodis/modules.rst: -------------------------------------------------------------------------------- 1 | pyModis Library 2 | =============== 3 | 4 | ``pyModis`` library it is a Python library to work with MODIS data. 5 | 6 | It can easily used in your application to download, analyze, 7 | convert and check the quality of MODIS data. 8 | 9 | ``pyModis`` can be used in other free and open source software, 10 | it is already present in GRASS GIS used by r.in.modis addon. 11 | 12 | It is compose by this modules: 13 | 14 | .. only:: latex 15 | 16 | * :doc:`downmodis` 17 | * :doc:`parsemodis` 18 | * :doc:`convertmodis` 19 | * :doc:`convertmodis_gdal` 20 | * :doc:`qualitymodis` 21 | * :doc:`optparse` 22 | 23 | .. raw:: latex 24 | 25 | \newpage % hard pagebreak at exactly this position 26 | 27 | .. toctree:: 28 | :maxdepth: 4 29 | 30 | downmodis 31 | parsemodis 32 | convertmodis 33 | convertmodis_gdal 34 | qualitymodis 35 | optparse 36 | -------------------------------------------------------------------------------- /docs/source/pymodis/optparse.rst: -------------------------------------------------------------------------------- 1 | :mod:`optparse_required` module 2 | ---------------------------------------- 3 | 4 | .. automodule:: pymodis.optparse_required 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | .. only:: latex 10 | 11 | .. raw:: latex 12 | 13 | \newpage % hard pagebreak at exactly this position 14 | 15 | :mod:`optparse_gui` module 16 | ---------------------------------------------- 17 | 18 | .. automodule:: pymodis.optparse_gui 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | .. only:: latex 24 | 25 | .. raw:: latex 26 | 27 | \newpage % hard pagebreak at exactly this position 28 | -------------------------------------------------------------------------------- /docs/source/pymodis/parsemodis.rst: -------------------------------------------------------------------------------- 1 | :mod:`parsemodis` module 2 | -------------------------------------------------------------------------------------------------------------------------------------------- 3 | 4 | .. automodule:: pymodis.parsemodis 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | .. only:: latex 10 | 11 | .. raw:: latex 12 | 13 | \newpage % hard pagebreak at exactly this position 14 | -------------------------------------------------------------------------------- /docs/source/pymodis/qualitymodis.rst: -------------------------------------------------------------------------------- 1 | :mod:`qualitymodis` module 2 | -------------------------------------------------------------- 3 | 4 | .. automodule:: pymodis.qualitymodis 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | .. only:: latex 10 | 11 | .. raw:: latex 12 | 13 | \newpage % hard pagebreak at exactly this position 14 | -------------------------------------------------------------------------------- /docs/source/scripts/modis_convert.rst: -------------------------------------------------------------------------------- 1 | modis_convert.py 2 | ---------------- 3 | 4 | **modis_convert.py** converts MODIS data to TIF formats and different 5 | projection reference system. It is an interface to MRT mrtmosaic 6 | software or GDAL library. 7 | 8 | Usage 9 | ^^^^^ 10 | .. code-block:: none 11 | 12 | modis_convert.py [options] hdf_file 13 | 14 | Options 15 | ^^^^^^^ 16 | 17 | .. image:: ../_static/gui/modis_convert.png 18 | :scale: 70% 19 | :alt: GUI for modis_convert.py 20 | :align: left 21 | :class: gui 22 | 23 | .. code-block:: none 24 | 25 | -h, --help show this help message and exit 26 | 27 | Required options: 28 | -s SUBSET, --subset=SUBSET 29 | (Required) a subset of product's layers. The string 30 | should be similar to: ( 1 0 ) 31 | -o OUTPUT_FILE, --output=OUTPUT_FILE 32 | (Required) the prefix of output file 33 | -g RESOLUTION, --grain=RESOLUTION 34 | the spatial resolution of output file 35 | -r RESAMPLING_TYPE, --resampl=RESAMPLING_TYPE 36 | the method of resampling. -- mrt methods: 37 | 'NEAREST_NEIGHBOR', 'BICUBIC', 'CUBIC_CONVOLUTION', 38 | 'NONE' -- gdal methods: 'AVERAGE', 'BILINEAR', 39 | 'CUBIC', 'CUBIC_SPLINE', 'LANCZOS', 'MODE', 40 | 'NEAREST_NEIGHBOR' [default=NEAREST_NEIGHBOR] 41 | 42 | Options for GDAL: 43 | -f OUTPUT_FORMAT, --output-format=OUTPUT_FORMAT 44 | output format supported by GDAL [default=GTiff] 45 | -e EPSG, --epsg=EPSG 46 | EPSG code for the output 47 | -w WKT, --wkt_file=WKT 48 | file or string containing projection definition in WKT 49 | format 50 | -v, --vrt Read from a GDAL VRT file. 51 | --formats print supported GDAL formats 52 | 53 | Options for MRT: 54 | -m MRT_PATH, --mrt=MRT_PATH 55 | the path to MRT software 56 | -d DATUM, --datum=DATUM 57 | the code of datum. Available: 'NODATUM', 'NAD27', 58 | 'NAD83', 'WGS66', 'WGS72', 'WGS84' [default=WGS84] 59 | -t PROJECTION_SYSTEM, --proj_type=PROJECTION_SYSTEM 60 | the output projection system. Available: 'AEA', 'GEO', 61 | 'HAM', 'IGH', 'ISIN', 'LA', 'LCC', 'MOL', 'PS', 'SIN', 62 | 'TM', 'UTM', 'MERCAT' [default=GEO] 63 | -p PROJECTION_PARAMETERS, --proj_parameters=PROJECTION_PARAMETERS 64 | a list of projection parameters, for more info check 65 | the 'Appendix C' of MODIS reprojection tool user's 66 | manual https://lpdaac.usgs.gov/content/download/4831/2 67 | 2895/file/mrt41_usermanual_032811.pdf [default=( 0.0 68 | 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 69 | 0.0 )] 70 | -u UTM_ZONE, --utm=UTM_ZONE 71 | the UTM zone if projection system is UTM 72 | the UTM zone if projection system is UTM 73 | 74 | Examples 75 | ^^^^^^^^ 76 | 77 | .. warning:: 78 | The resolution value in ``modis_convert.py`` has to be set with the 79 | right value depending on the projection used. 1 kilometer in metrical 80 | projection has to be set as 1000 meter, instead in latitude and longitude 81 | something like 0.01* depending on the placement in the Earth. 82 | 83 | MODIS Reprojection Tools 84 | """""""""""""""""""""""" 85 | 86 | .. warning:: 87 | 88 | You can find the supported projections in the 'Appendix C' of 89 | `MODIS reprojection tool user's manual`_ and the datums at section 90 | ``Datum Conversion`` of the same manual 91 | 92 | Convert layers from MODIS data with the original resolution in 93 | latitude and longitude reference system 94 | 95 | .. code-block:: none 96 | 97 | modis_convert.py -s "( 1 0 1 0 )" -o OUTPUT_FILE -m "/usr/local/bin/" FILE 98 | 99 | Convert layers from MODIS data with output resolution in 500 meters with 100 | UTM projection in the 32 zone 101 | 102 | .. code-block:: none 103 | 104 | modis_convert.py -s "( 1 0 1 0 )" -o OUTPUT_FILE -m "/usr/local/bin/" -g 500 -p UTM -u 32 FILE 105 | 106 | GDAL 107 | """" 108 | 109 | Convert the first layer in latitude and longitude with the original resolution 110 | 111 | .. code-block:: none 112 | 113 | modis_convert.py -s "( 1 )" -o OUTPUT_FILE -e 4326 FILE 114 | 115 | Convert the first three layers from MODIS data with output resolution in 500 116 | meters with UTM projection in the 32 zone 117 | 118 | .. code-block:: none 119 | 120 | modis_convert.py -s "( 1 1 1 )" -o OUTPUT_FILE -g 500 -e 32632 FILE 121 | 122 | 123 | .. _`MODIS reprojection tool user's manual`: https://lpdaac.usgs.gov/sites/default/files/public/mrt41_usermanual_032811.pdf 124 | 125 | .. only:: latex 126 | 127 | .. raw:: latex 128 | 129 | \newpage % hard pagebreak at exactly this position 130 | -------------------------------------------------------------------------------- /docs/source/scripts/modis_download.rst: -------------------------------------------------------------------------------- 1 | modis_download.py 2 | ----------------- 3 | **modis_download.py** downloads MODIS data from NASA FTP servers. 4 | It can download large amounts of data and it can be profitably 5 | used with cron jobs to receive data with a fixed delay of time. 6 | 7 | .. warning:: 8 | 9 | Remember to register yourself at https://urs.earthdata.nasa.gov/users/new, 10 | read more at :ref:`userpw-label` session. 11 | 12 | .. note:: 13 | 14 | The script is able also to read the 15 | `.netrc file `_. 16 | You have to add something similar to this :: 17 | 18 | machine urs.earthdata.nasa.gov 19 | login YOURUSER 20 | password YOURPASSWD 21 | 22 | Usage 23 | ^^^^^ 24 | 25 | :: 26 | 27 | modis_download.py [options] destination_folder 28 | 29 | Options 30 | ^^^^^^^ 31 | 32 | .. image:: ../_static/gui/modis_download.png 33 | :scale: 60% 34 | :alt: GUI for modis_download.py 35 | :align: left 36 | :class: gui 37 | 38 | .. code-block:: none 39 | 40 | -h --help shows the help message and exit 41 | -u --url http/ftp server url [default=https://e4ftl01.cr.usgs.gov] 42 | -I --input insert user and password from standard input 43 | -P --password password to connect 44 | -U --username username to connect 45 | -t --tiles string of tiles separated by comma 46 | [default=none] for all tiles 47 | -s --source directory on the http/ftp server 48 | [default=MOLT] 49 | -p --product product name as on the http/ftp server 50 | [default=MOD11A1.005] 51 | -D --delta delta of day starting from first day [default=10] 52 | -f --firstday the day to start download, if you want change 53 | data you have to use this format YYYY-MM-DD 54 | ([default=none] is for today) 55 | -e --endday the day to finish download, if you want change 56 | data you have to use this format YYYY-MM-DD 57 | ([default=none] use delta option) 58 | -x useful for debugging the download 59 | [default=False] 60 | -j download also the jpeg files [default=False] 61 | -O download only one day, it sets delta=1 [default=False] 62 | -A download all days, useful for initial download of a 63 | product. It overwrites the 'firstday' and 'endday' 64 | options [default=False] 65 | -r remove files with size same to zero from 66 | 'destination_folder' [default=False] 67 | 68 | 69 | 70 | 71 | 72 | Examples 73 | ^^^^^^^^ 74 | 75 | Download Terra LST data for a month for two tiles from HTTP server 76 | 77 | .. code-block:: none 78 | 79 | modis_download.py -I -r -t h18v03,h18v04 -f 2008-01-01 -e 2008-01-31 lst_terra/ 80 | 81 | Download the last 15 days of Aqua LST data 82 | 83 | .. code-block:: none 84 | 85 | modis_download.py -I -r -s MOLA -p MYD11A1.005 -t h18v03,h18v04 -D 15 lst_aqua/ 86 | 87 | Download all tiles of NDVI for one day (you have pick the right day otherwise it does not download anything) 88 | 89 | .. code-block:: none 90 | 91 | modis_download.py -U user -P passwd -r -p MOD13Q1.005 -f 2010-12-31 -O 92 | 93 | Download Snow product from FTP server 94 | 95 | .. only:: html 96 | 97 | .. code-block:: none 98 | 99 | modis_download.py -I -u ftp://n4ftl01u.ecs.nasa.gov -p mail@pymodis.com -s SAN/MOST -p MOD10A1.005 100 | 101 | .. only:: latex 102 | 103 | .. code-block:: none 104 | 105 | modis_download.py -I -u ftp://n4ftl01u.ecs.nasa.gov -p mail@pymodis.com 106 | -s SAN/MOST -p MOD10A1.005 107 | 108 | .. raw:: latex 109 | 110 | \newpage % hard pagebreak at exactly this position 111 | -------------------------------------------------------------------------------- /docs/source/scripts/modis_download_from_list.rst: -------------------------------------------------------------------------------- 1 | modis_download_from_list.py 2 | --------------------------- 3 | 4 | **modis_download_from_list.py** downloads MODIS data from NASA servers, 5 | the names of files to download have to be contained into a text file. 6 | 7 | .. warning:: 8 | 9 | Remember to register yourself at https://urs.earthdata.nasa.gov/users/new, 10 | read more at :ref:`userpw-label` session. 11 | 12 | .. note:: 13 | 14 | The script is able also to read the 15 | `.netrc file `_. 16 | You have to add something similar to this :: 17 | 18 | machine urs.earthdata.nasa.gov 19 | login YOURUSER 20 | password YOURPASSWD 21 | 22 | Usage 23 | ^^^^^ 24 | 25 | .. code-block:: none 26 | 27 | modis_download_from_list.py [options] destination_folder 28 | 29 | Options 30 | ^^^^^^^ 31 | 32 | .. image:: ../_static/gui/modis_download_from_list.png 33 | :scale: 50% 34 | :alt: GUI for modis_download_from_list.py 35 | :align: left 36 | :class: gui 37 | 38 | .. code-block:: none 39 | 40 | -h --help show the help message and exit 41 | -f --file Input file containing data to donwload 42 | -u --url http/ftp server url [default=https://e4ftl01.cr.usgs.gov] 43 | -I --input insert user and password from standard input 44 | -P --password password to connect 45 | -U --username username to connect 46 | -s --source directory on the http/ftp 47 | [default=MOLT] 48 | -p --product product name as on the http/ftp server 49 | [default=MOD11A1.006] 50 | -o --outputs the output where write the missing files in the server 51 | [default=none]. Use 'stdout' to write to STDOUT 52 | -n use netrc file to read user and password 53 | -x this is useful for debugging the download 54 | [default=False] 55 | -j download also the jpeg files [default=False] 56 | 57 | 58 | Examples 59 | ^^^^^^^^ 60 | 61 | The following text should be in your *MODTiles.txt* file 62 | 63 | .. code-block:: none 64 | 65 | MOD11A1.A2012278.h19v11.005.*.hdf* 66 | MOD11A1.A2012278.h19v12.005.*.hdf* 67 | MOD11A1.A2012278.h20v11.005.*.hdf* 68 | MOD11A1.A2012278.h20v12.005.*.hdf* 69 | MOD11A1.A2012278.h21v11.005.*.hdf* 70 | 71 | 72 | Download Terra LST data from the above text file 73 | 74 | .. code-block:: none 75 | 76 | modis_download_from_list.py -U user -P passwd -f /tmp/MODTiles.txt /tmp 77 | 78 | The following text should be in your *MYDTiles.txt* file 79 | 80 | .. code-block:: none 81 | 82 | MYD11A1.A2012278.h19v11.005.*.hdf* 83 | MYD11A1.A2012278.h19v12.005.*.hdf* 84 | MYD11A1.A2012278.h20v11.005.*.hdf* 85 | MYD11A1.A2012278.h20v12.005.*.hdf* 86 | MYD11A1.A2012278.h21v11.005.*.hdf* 87 | 88 | Download Aqua LST data from the above text file 89 | 90 | .. code-block:: none 91 | 92 | modis_download_from_list.py -I -s MOLA -p MYD11A1.005 -f /tmp/MYDTiles.txt /tmp 93 | 94 | .. only:: latex 95 | 96 | .. raw:: latex 97 | 98 | \newpage % hard pagebreak at exactly this position 99 | -------------------------------------------------------------------------------- /docs/source/scripts/modis_mosaic.rst: -------------------------------------------------------------------------------- 1 | modis_mosaic.py 2 | --------------- 3 | 4 | **modis_mosaic.py** creates a mosaic of several MODIS tiles in 5 | HDF format, using MRT mrtmosaic software or GDAL library. 6 | 7 | Usage 8 | ^^^^^ 9 | .. code-block:: none 10 | 11 | modis_mosaic.py [options] hdflist_file 12 | 13 | Options 14 | ^^^^^^^ 15 | .. image:: ../_static/gui/modis_mosaic.png 16 | :scale: 65% 17 | :alt: GUI for modis_mosaic.py 18 | :align: left 19 | :class: gui 20 | 21 | .. code-block:: none 22 | 23 | General options: 24 | -o OUTPUT_FILE, --output=OUTPUT_FILE 25 | (Required) the name or prefix (for VRT) of output 26 | mosaic 27 | -s SUBSET, --subset=SUBSET 28 | a subset of product layers. The string should be 29 | similar to: 1 0 [default: all layers] 30 | 31 | Options for GDAL: 32 | -f OUTPUT_FORMAT, --output-format=OUTPUT_FORMAT 33 | output format supported: GTiff, HDF4Image 34 | [default=GTiff] 35 | -v, --vrt Create a GDAL VRT file. No other GDAL options have to 36 | been set 37 | 38 | Options for MRT: 39 | -m MRT_PATH, --mrt=MRT_PATH 40 | (Required) the path to MRT software 41 | 42 | Examples 43 | ^^^^^^^^ 44 | 45 | Using the MODIS Reprojection Tool 46 | """"""""""""""""""""""""""""""""" 47 | 48 | Convert all the layers of several tiles 49 | 50 | .. code-block:: none 51 | 52 | modis_mosaic.py -m "/usr/local/bin/" -o FILE_mosaic MOSAIC_FILES_LIST 53 | 54 | Convert LAYERS of several LST MODIS tiles 55 | 56 | .. code-block:: none 57 | 58 | modis_mosaic.py -s "1 0 1 0" -m "/usr/local/bin/" -o FILE_mosaic MOSAIC_FILES_LIST 59 | 60 | Using GDAL 61 | """""""""" 62 | 63 | Convert the first LAYERS of several tiles with resolution 1km in GeoTIFF format 64 | 65 | .. code-block:: none 66 | 67 | modis_mosaic.py -o FILE_mosaic.tif -s "1" MOSAIC_FILES_LIST 68 | 69 | Create a mosaic with all the layers of several tiles in HDF4Image format 70 | 71 | .. code-block:: none 72 | 73 | modis_mosaic.py -o FILE_mosaic.hdf -f HDF4Image MOSAIC_FILES_LIS 74 | 75 | Create VRT file for all subset. It creates a VRT file for each subset with the 76 | chosen prefix (``-o`` flag) and the name of layer as suffix 77 | 78 | .. code-block:: none 79 | 80 | modis_mosaic.py -o mosaic_vrt -v MOSAIC_FILES_LIS 81 | 82 | .. only:: latex 83 | 84 | .. raw:: latex 85 | 86 | \newpage % hard pagebreak at exactly this position 87 | -------------------------------------------------------------------------------- /docs/source/scripts/modis_multiparse.rst: -------------------------------------------------------------------------------- 1 | modis_multiparse.py 2 | ------------------- 3 | 4 | **modis_multiparse.py** parses several XML metadata files 5 | for MODIS tiles. It is very useful to create XML metadata file for a 6 | mosaic. 7 | 8 | Usage 9 | ^^^^^ 10 | .. code-block:: none 11 | 12 | modis_multiparse.py [options] hdf_files_list 13 | 14 | Options 15 | ^^^^^^^ 16 | 17 | .. image:: ../_static/gui/modis_multiparse.png 18 | :scale: 40% 19 | :alt: GUI for modis_multiparse.py 20 | :align: left 21 | :class: gui 22 | 23 | .. code-block:: none 24 | 25 | -h --help show the help 26 | -b print the values related to the spatial max extent 27 | -w --write write the MODIS XML metadata file for MODIS mosaic 28 | 29 | Examples 30 | ^^^^^^^^ 31 | 32 | Print values of spatial bounding box 33 | 34 | .. code-block:: none 35 | 36 | modis_multiparse.py -b hdf_file1 hdf_file2 ... 37 | 38 | Write xml file to use with hdf file created by :doc:`modis_convert` 39 | 40 | .. code-block:: none 41 | 42 | modis_multiparse.py -w FILE_mosaic.xml hdf_file1 hdf_file2 ... 43 | 44 | .. only:: latex 45 | 46 | .. raw:: latex 47 | 48 | \newpage % hard pagebreak at exactly this position 49 | -------------------------------------------------------------------------------- /docs/source/scripts/modis_parse.rst: -------------------------------------------------------------------------------- 1 | modis_parse.py 2 | -------------- 3 | 4 | **modis_parse.pys** parses the XML metadata file for a MODIS 5 | tile and return the requested value. It can also write the metadata information 6 | into a text file. 7 | 8 | Usage 9 | ^^^^^ 10 | .. code-block:: none 11 | 12 | modis_parse.py [options] hdf_file 13 | 14 | Options 15 | ^^^^^^^ 16 | 17 | .. image:: ../_static/gui/modis_parse.png 18 | :scale: 35% 19 | :alt: GUI for modis_parse.py 20 | :align: left 21 | :class: gui 22 | 23 | .. code-block:: none 24 | 25 | -h --help show the help 26 | -w --write write the chosen information into a file 27 | -a print all possible values of metadata 28 | -b print the values related to the spatial max extent 29 | -d print the values related to the date files 30 | -e print the values related to the ECSDataGranule 31 | -i print the input layers 32 | -o print the other values 33 | -p print the values related to platform 34 | -q print the values related to quality 35 | -s print the values related to psas 36 | -t print the values related to times 37 | -l print the names of layer in HDF file 38 | 39 | Examples 40 | ^^^^^^^^ 41 | 42 | Return all values of metadata 43 | 44 | .. code-block:: none 45 | 46 | modis_parse.py -a hdf_file 47 | 48 | Write all values to a file 49 | 50 | .. code-block:: none 51 | 52 | modis_parse.py -a -w metadata_FILE.txt hdf_file 53 | 54 | Print spatial extent and quality 55 | 56 | .. code-block:: none 57 | 58 | modis_parse.py -b -q hdf_file 59 | 60 | .. only:: latex 61 | 62 | .. raw:: latex 63 | 64 | \newpage % hard pagebreak at exactly this position 65 | -------------------------------------------------------------------------------- /docs/source/scripts/modis_quality.rst: -------------------------------------------------------------------------------- 1 | modis_quality.py 2 | ---------------- 3 | 4 | **modis_quality.py** checks the quality of MODIS data using the QA layer 5 | 6 | Usage 7 | ^^^^^ 8 | .. code-block:: none 9 | 10 | modis_quality.py [options] input_file destination_file 11 | 12 | Options 13 | ^^^^^^^ 14 | 15 | .. image:: ../_static/gui/modis_quality.png 16 | :scale: 60% 17 | :alt: GUI for modis_quality.py 18 | :align: left 19 | :class: gui 20 | 21 | .. code-block:: none 22 | 23 | -h, --help show this help message and exit 24 | -o OUTPUT_FILE, --output=OUTPUT_FILE 25 | (Required) the prefix of output file 26 | -t TYPE, --type=TYPE quality type either as number or name (e.g. 1 or 27 | VIQuality for MOD13 products) [default=1] 28 | -l LAYER, --qualitylayer=LAYER 29 | quality layer of the dataset, dependent on the used 30 | MODIS product. (e.g. 1 or QC_Day for the Daytime QC 31 | Layer of MOD11) [default=1] 32 | -p PRODUCT, --producttype=PRODUCT 33 | quality layer of the dataset, dependent on the used 34 | MODIS product. (e.g. 1 or QC_Day for the Daytime QC 35 | Layer of MOD11) [default=MOD13Q1] 36 | 37 | Examples 38 | ^^^^^^^^ 39 | 40 | Extract VI Usefulness value from MOD13 product 41 | 42 | .. code-block:: none 43 | 44 | modis_quality.py -t 2 infile.hdf -o outfile.tif 45 | 46 | Extract shadow mask from MOD13 product 47 | 48 | .. code-block:: none 49 | 50 | modis_quality.py -t 9 input_file.hdf -o destination_file.tif 51 | 52 | Extract Emissitivity error flag of Nighttime LSTE quality control from MOD11C1 product 53 | 54 | .. code-block:: none 55 | 56 | modis_quality.py -t 4 -l 2 infile.hdf -o outfile.tif 57 | 58 | Extract MODLAND QA value from MOD13Q1 mosaic 59 | 60 | .. code-block:: none 61 | 62 | modis_quality.py -t 1 -p MOD13Q1 input_file.hdf -o destination_file.tif 63 | 64 | .. only:: latex 65 | 66 | .. raw:: latex 67 | 68 | \newpage % hard pagebreak at exactly this position 69 | -------------------------------------------------------------------------------- /docs/source/scripts/software.rst: -------------------------------------------------------------------------------- 1 | pyModis Scripts 2 | =============== 3 | 4 | The ``pyModis`` **scripts** provide you with a complete toolkit 5 | to work with MODIS data, you can download, analyze and convert 6 | the data. They are developed to work from command line and inside 7 | scripts to automatically update your MODIS files dataset. 8 | From version 1.0 the scripts have also Graphical User Interface. 9 | 10 | Currently the tools are: 11 | 12 | .. only:: latex 13 | 14 | * :doc:`modis_download` 15 | * :doc:`modis_download_from_list` 16 | * :doc:`modis_parse` 17 | * :doc:`modis_multiparse` 18 | * :doc:`modis_mosaic` 19 | * :doc:`modis_convert` 20 | * :doc:`modis_quality` 21 | 22 | .. raw:: latex 23 | 24 | \newpage % hard pagebreak at exactly this position 25 | 26 | .. toctree:: 27 | :maxdepth: 1 28 | 29 | modis_download 30 | modis_download_from_list 31 | modis_parse 32 | modis_multiparse 33 | modis_mosaic 34 | modis_convert 35 | modis_quality 36 | -------------------------------------------------------------------------------- /pyModis.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/pyModis.ico -------------------------------------------------------------------------------- /pyModis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucadelu/pyModis/9a88a645751b5c558b635b091f65393a9af35789/pyModis.png -------------------------------------------------------------------------------- /pymodis/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import warnings 3 | 4 | from . import downmodis 5 | from . import parsemodis 6 | from . import convertmodis 7 | from . import optparse_required 8 | try: 9 | from . import qualitymodis 10 | from . import convertmodis_gdal 11 | except ImportError: 12 | warnings.warn("qualitymodis and convertmodis_gdal modules not enabled, " 13 | "maybe Python GDAL is missing", ImportWarning) 14 | pass 15 | from . import productmodis 16 | try: 17 | from . import optparse_gui 18 | except: 19 | warnings.warn("WxPython missing, no GUI enabled", ImportWarning) 20 | __version__ = '2.4.1' 21 | -------------------------------------------------------------------------------- /pymodis/convertmodis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # class to convert/process modis data 3 | # 4 | # (c) Copyright Luca Delucchi 2010 5 | # Authors: Luca Delucchi 6 | # Email: luca dot delucchi at iasma dot it 7 | # 8 | ################################################################## 9 | # 10 | # This MODIS Python class is licensed under the terms of GNU GPL 2. 11 | # This program is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU General Public License as 13 | # published by the Free Software Foundation; either version 2 of 14 | # the License, or (at your option) any later version. 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | ################################################################## 21 | """Convert MODIS HDF file to GeoTiff file or create a HDF mosaic file for 22 | several tiles using Modis Reprojection Tools. 23 | 24 | Classes: 25 | 26 | * :class:`convertModis` 27 | * :class:`createMosaic` 28 | * :class:`processModis` 29 | 30 | Functions: 31 | 32 | * :func:`checkMRTpath` 33 | 34 | """ 35 | # python 2 and 3 compatibility 36 | from __future__ import print_function 37 | 38 | import os 39 | import sys 40 | 41 | 42 | def checkMRTpath(mrtpath): 43 | """Function to check if MRT path it correct 44 | 45 | :param str mrtpath: the path to MRT directory 46 | :return: The path to 'bin' and 'data' directory inside MRT path 47 | """ 48 | if os.path.exists(mrtpath): 49 | if os.path.exists(os.path.join(mrtpath, 'bin')): 50 | if os.environ['PATH'].find(os.path.join(mrtpath, 'data')) == -1: 51 | os.environ['PATH'] = "{path}:{data}".format(path=os.environ['PATH'], 52 | data=os.path.join(mrtpath, 'data')) 53 | mrtpathbin = os.path.join(mrtpath, 'bin') 54 | else: 55 | raise Exception('The path {path} does not exist'.format(path=os.path.join(mrtpath, 'bin'))) 56 | if os.path.exists(os.path.join(mrtpath, 'data')): 57 | mrtpathdata = os.path.join(mrtpath, 'data') 58 | os.environ['MRTDATADIR'] = os.path.join(mrtpath, 'data') 59 | else: 60 | raise Exception('The path {path} does not exist'.format(path=os.path.join(mrtpath, 'data'))) 61 | else: 62 | raise Exception('The path {name} does not exist'.format(name=mrtpath)) 63 | return mrtpathbin, mrtpathdata 64 | 65 | 66 | class convertModis: 67 | """A class to convert modis data from hdf to tif using resample 68 | (from MRT tools) 69 | 70 | :param str hdfname: the full path to the hdf file 71 | :param str confile: the full path to the paramater file 72 | :param str mrtpath: the full path to mrt directory which contains 73 | the bin and data directories 74 | """ 75 | def __init__(self, hdfname, confile, mrtpath): 76 | """Initialization function""" 77 | # check if the hdf file exists 78 | if os.path.exists(hdfname): 79 | self.name = hdfname 80 | else: 81 | raise Exception('{name} does not exist'.format(name=hdfname)) 82 | # check if confile exists 83 | if os.path.exists(confile): 84 | self.conf = confile 85 | else: 86 | raise Exception('{name} does not exist'.format(name=confile)) 87 | # check if mrtpath and subdirectories exists and set environment 88 | # variables 89 | self.mrtpathbin, self.mrtpathdata = checkMRTpath(mrtpath) 90 | 91 | def executable(self): 92 | """Return the executable of resample MRT software""" 93 | if sys.platform.count('linux') or sys.platform.count('darwin'): 94 | if os.path.exists(os.path.join(self.mrtpathbin, 'resample')): 95 | return os.path.join(self.mrtpathbin, 'resample') 96 | elif sys.platform.count('win32'): 97 | if os.path.exists(os.path.join(self.mrtpathbin, 'resample.exe')): 98 | return os.path.join(self.mrtpathbin, 'resample.exe') 99 | elif os.path.exists(os.path.join(self.mrtpathbin, 'resample')): 100 | return os.path.join(self.mrtpathbin, 'resample') 101 | raise Exception("No possible to find MRT resample executable") 102 | 103 | def run(self, quiet=False): 104 | """Exec the convertion process""" 105 | import subprocess 106 | execut = self.executable() 107 | if not os.path.exists(execut): 108 | raise Exception('The path {name} does not exist: it could be an ' 109 | 'erroneus path or software'.format(name=execut)) 110 | else: 111 | subprocess.call([execut, '-p', self.conf]) 112 | if not quiet: 113 | print("The hdf file {name} was converted " 114 | "successfully".format(name=self.name)) 115 | return True 116 | 117 | 118 | class createMosaic: 119 | """A class to convert several MODIS tiles into a mosaic 120 | 121 | :param str listfile: the path to file with the list of HDF MODIS 122 | file 123 | :param str outprefix: the prefix for output files 124 | :param str mrtpath: the full path to mrt directory which contains 125 | the bin and data directories 126 | :param str subset: a string composed by 1 and 0 according with the 127 | layer to mosaic. The string should something like 128 | '1 0 1 0 0 0 0' 129 | """ 130 | def __init__(self, listfile, outprefix, mrtpath, subset=False): 131 | """Function to initialize the object""" 132 | import tempfile 133 | # check if the hdf file exists 134 | if os.path.exists(listfile): 135 | self.basepath = os.path.split(listfile)[0] 136 | self.fullpath = os.path.realpath(self.basepath) 137 | self.listfiles = listfile 138 | self.tmplistfiles = open(os.path.join(tempfile.gettempdir(), 139 | '{name}.prm'.format(name=str(os.getpid()))), 'w') 140 | self.HDFfiles = open(listfile).readlines() 141 | else: 142 | raise Exception('{name} not exists'.format(name=listfile)) 143 | # check if mrtpath and subdirectories exists and set environment 144 | # variables 145 | self.mrtpathbin, self.mrtpathdata = checkMRTpath(mrtpath) 146 | self.out = os.path.join(self.basepath, outprefix + '.hdf') 147 | self.outxml = self.out + '.xml' 148 | self.subset = subset 149 | 150 | def write_mosaic_xml(self): 151 | """Write the XML metadata file for MODIS mosaic""" 152 | from .parsemodis import parseModisMulti 153 | listHDF = [] 154 | for i in self.HDFfiles: 155 | if i.find(self.basepath) == -1 and i.find('.hdf.xml') == -1: 156 | print("Attention: maybe you do not have the full path in the" 157 | " HDF file list") 158 | listHDF.append(os.path.join(self.basepath, i.strip())) 159 | self.tmplistfiles.write("{name}\n".format(name=os.path.join(self.basepath, i.strip()))) 160 | elif i.find('.hdf.xml') == -1: 161 | listHDF.append(i.strip()) 162 | self.tmplistfiles.write("{name}\n".format(name=os.path.join(self.fullpath, i.strip()))) 163 | pmm = parseModisMulti(listHDF) 164 | pmm.writexml(self.outxml) 165 | self.tmplistfiles.close() 166 | 167 | def executable(self): 168 | """Return the executable of mrtmosaic MRT software""" 169 | if sys.platform.count('linux') or sys.platform.count('darwin'): 170 | if os.path.exists(os.path.join(self.mrtpathbin, 'mrtmosaic')): 171 | return os.path.join(self.mrtpathbin, 'mrtmosaic') 172 | elif sys.platform.count('win32'): 173 | if os.path.exists(os.path.join(self.mrtpathbin, 'mrtmosaic.exe')): 174 | return os.path.join(self.mrtpathbin, 'mrtmosaic.exe') 175 | elif os.path.exists(os.path.join(self.mrtpathbin, 'mrtmosaic')): 176 | return os.path.join(self.mrtpathbin, 'mrtmosaic') 177 | raise Exception("No possible to find MRT mrtmosaic executable") 178 | 179 | def run(self, quiet=False): 180 | """Exect the mosaic process""" 181 | import subprocess 182 | execut = self.executable() 183 | if not os.path.exists(execut): 184 | raise Exception('The path {name} does not exist, it could be an ' 185 | 'erroneus path or software'.format(name=execut)) 186 | else: 187 | self.write_mosaic_xml() 188 | if self.subset: 189 | subprocess.call([execut, '-i', self.tmplistfiles.name, '-o', 190 | self.out, '-s', self.subset], 191 | stderr=subprocess.STDOUT) 192 | else: 193 | subprocess.call([execut, '-i', self.tmplistfiles.name, '-o', 194 | self.out], stderr=subprocess.STDOUT) 195 | if not quiet: 196 | print("The mosaic file {name} has been " 197 | "created".format(name=self.out)) 198 | return True 199 | 200 | 201 | class processModis: 202 | """A class to process raw modis data from hdf to tif using swath2grid 203 | (from MRT Swath tools) 204 | 205 | :param str hdfname: the full path to the hdf file 206 | :param str confile: the full path to the paramater file 207 | :param str mrtpath: the full path to mrt directory which contains 208 | the bin and data directories 209 | """ 210 | def __init__(self, hdfname, confile, mrtpath): 211 | """Function to initialize the object""" 212 | # check if the hdf file exists 213 | if os.path.exists(hdfname): 214 | self.name = hdfname 215 | else: 216 | raise Exception('%s does not exist' % hdfname) 217 | # check if confile exists 218 | if os.path.exists(confile): 219 | self.conf = confile 220 | else: 221 | raise Exception('%s does not exist' % confile) 222 | # check if mrtpath and subdirectories exists and set environment 223 | # variables 224 | self.mrtpathbin, self.mrtpathdata = checkMRTpath(mrtpath) 225 | 226 | def executable(self): 227 | """Return the executable of resample MRT software""" 228 | if sys.platform.count('linux') != -1 or sys.platform.count('darwin') != -1: 229 | if os.path.exists(os.path.join(self.mrtpathbin, 'swath2grid')): 230 | return os.path.join(self.mrtpathbin, 'swath2grid') 231 | elif sys.platform.count('win32') != -1: 232 | if os.path.exists(os.path.join(self.mrtpathbin, 'swath2grid.exe')): 233 | return os.path.join(self.mrtpathbin, 'swath2grid.exe') 234 | 235 | def run(self, quiet=False): 236 | """Exec the convertion process""" 237 | import subprocess 238 | execut = self.executable() 239 | if not os.path.exists(execut): 240 | raise Exception('The path {name} does not exist, it could be an ' 241 | 'erroneus path or software'.format(name=execut)) 242 | else: 243 | subprocess.call([execut, '-pf={name}'.format(name=self.conf)]) 244 | if not quiet: 245 | print("The hdf file {name} has been " 246 | "converted".format(name=self.name)) 247 | return True 248 | -------------------------------------------------------------------------------- /pymodis/optparse_required.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # class to parse modis data 3 | # 4 | # (c) Copyright Luca Delucchi 2013 5 | # Authors: Luca Delucchi 6 | # Email: luca dot delucchi at iasma dot it 7 | # 8 | ################################################################## 9 | # 10 | # This MODIS Python class is licensed under the terms of GNU GPL 2. 11 | # This program is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU General Public License as 13 | # published by the Free Software Foundation; either version 2 of 14 | # the License, or (at your option) any later version. 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | ################################################################## 21 | """Module to extend optparse, it add required options and new types to use 22 | into gui module. 23 | 24 | Classes: 25 | 26 | * :class:`OptionWithDefault` 27 | * :class:`OptionParser` 28 | 29 | """ 30 | 31 | import optparse 32 | 33 | # classes for required options 34 | STREQUIRED = 'required' 35 | 36 | 37 | class OptionWithDefault(optparse.Option): 38 | """Extend optparse.Option add required to the attributes and some new 39 | types for the GUI 40 | """ 41 | ATTRS = optparse.Option.ATTRS + [STREQUIRED] 42 | TYPES = optparse.Option.TYPES + ('file', 'output', 'directory') 43 | 44 | def __init__(self, *opts, **attrs): 45 | """Function to initialize the object""" 46 | if attrs.get(STREQUIRED, False): 47 | attrs['help'] = '(Required) ' + attrs.get('help', "") 48 | optparse.Option.__init__(self, *opts, **attrs) 49 | 50 | 51 | class OptionParser(optparse.OptionParser): 52 | """Extend optparse.OptionParser""" 53 | def __init__(self, **kwargs): 54 | """Function to initialize the object""" 55 | kwargs['option_class'] = OptionWithDefault 56 | optparse.OptionParser.__init__(self, **kwargs) 57 | 58 | def check_values(self, values, args): 59 | """Check if value is required for an option""" 60 | for option in self.option_list: 61 | if hasattr(option, STREQUIRED) and option.required: 62 | if not getattr(values, option.dest): 63 | self.error("option {opt} is required".format(opt=str(option))) 64 | return optparse.OptionParser.check_values(self, values, args) 65 | -------------------------------------------------------------------------------- /pymodis/productmodis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # class to download modis data 4 | # 5 | # (c) Copyright Luca Delucchi 2010-2016 6 | # Authors: Luca Delucchi 7 | # Email: luca dot delucchi at fmach dot it 8 | # 9 | ################################################################## 10 | # 11 | # The Modis class is licensed under the terms of GNU GPL 2 12 | # This program is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU General Public License as 14 | # published by the Free Software Foundation; either version 2 of 15 | # the License, or (at your option) any later version. 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | # See the GNU General Public License for more details. 20 | # 21 | ################################################################## 22 | 23 | class product: 24 | """Definition of MODIS product with url and path in the ftp server 25 | """ 26 | 27 | def __init__(self, value=None): 28 | # url to download products 29 | urlbase = 'http://e4ftl01.cr.usgs.gov' 30 | usrsnow = 'ftp://n5eil01u.ecs.nsidc.org' 31 | # values of lst product: 32 | lst_spec = '( 1 0 0 0 1 0 0 0 0 0 0 0 )' 33 | lst_specqa = '( 1 1 0 0 1 1 0 0 0 0 0 0 )' 34 | # suffix for the lst product (key is the lst map, value the QA) 35 | lst1km_suff = {'.LST_Day_1km': '.QC_Day', 36 | '.LST_Night_1km': '.QC_Night'} 37 | lst6km_suff = {'.LST_Day_6km': '.QC_Day', 38 | '.LST_Night_6km': '.QC_Night'} 39 | # color for lst product 40 | lst_color = ['celsius'] 41 | # values of vi product: 42 | vi_spec = '( 1 1 0 0 0 0 0 0 0 0 0 0 )' 43 | vi_specqa = '( 1 1 1 0 0 0 0 0 0 0 0 1 )' 44 | vi_color = ['ndvi', 'evi'] 45 | vi250m_suff = {'.250m_16_days_NDVI': '.250m_16_days_VI_Quality', 46 | '.250m_16_days_EVI': '.250m_16_days_VI_Quality'} 47 | vi500m_suff = {'.500m_16_days_NDVI': '.500m_16_days_VI_Quality', 48 | '.500m_16_days_EVI': '.500m_16_days_VI_Quality'} 49 | vi1km_suff = {'.1_km_16_days_NDVI': '.1_km_16_days_VI_Quality', 50 | '.1_km_16_days_EVI': '.1_km_16_days_VI_Quality'} 51 | # values of snow product: 52 | snow1_spec = ('( 1 )') 53 | snow1_specqa = ('( 1 1 )') 54 | snow1_suff = {'.Snow_Cover_Daily_Tile': '.Snow_Spatial_QA'} 55 | snow8_spec = ('( 1 1 )') 56 | snow_color = ['gyr'] # TODO CREATE THE COLOR TABLE FOR MODIS_SNOW 57 | snow8_suff = {'.Maximum_Snow_Extent': None, 58 | '.Eight_Day_Snow_Cover': None} 59 | lstL2_spec = 'LST; QC; Error_LST; Emis_31; Emis_32; View_angle; View_time' 60 | # values of surface reflectance product: 61 | surf_spec = '( 1 1 1 1 1 1 1 0 0 0 0 0 0 )' 62 | surf_specqa = '( 1 1 1 1 1 1 1 1 0 0 0 0 0 )' 63 | surf_suff = {'.sur_refl_b01': '.sur_refl_qc_500m', '.sur_refl_b02': 64 | '.sur_refl_qc_500m', '.sur_refl_b03': '.sur_refl_qc_500m', 65 | '.sur_refl_b04': '.sur_refl_qc_500m', '.sur_refl_b05': 66 | '.sur_refl_qc_500m', '.sur_refl_b06': '.sur_refl_qc_500m', 67 | '.sur_refl_b07': '.sur_refl_qc_500m'} 68 | # value for water product 69 | water_spec = ('( 1 )') 70 | water_specqa = ('( 1 1 )') 71 | water_suff = {'.water_mask': '.water_mask_QA'} 72 | 73 | # granularity 74 | daily = 1 75 | eight = 8 76 | sixteen = 16 77 | self.prod = value 78 | lst = {'lst_aqua_daily_1000': {'url': urlbase, 'folder': 'MOLA/', 79 | 'prod': 'MYD11A1.005', 'days': daily, 80 | 'spec': lst_spec, 'spec_qa': lst_specqa, 81 | 'suff': lst1km_suff, 'res': 1000, 82 | 'color': lst_color}, 83 | 'lst_terra_daily_1000': {'url': urlbase, 'folder': 'MOLT/', 84 | 'prod': 'MOD11A1.005', 'days': daily, 85 | 'spec': lst_spec, 'spec_qa': lst_specqa, 86 | 'suff': lst1km_suff, 'res': 1000, 87 | 'color': lst_color}, 88 | 'lst_terra_eight_1000': {'url': urlbase, 'folder': 'MOLT/', 89 | 'prod': 'MOD11A2.005', 'days': eight, 90 | 'spec': lst_spec, 'spec_qa': lst_specqa, 91 | 'suff': lst1km_suff, 'res': 1000, 92 | 'color': lst_color}, 93 | 'lst_aqua_eight_1000': {'url': urlbase, 'folder': 'MOLA/', 94 | 'prod': 'MYD11A2.005', 'days': eight, 95 | 'spec': lst_spec, 'spec_qa': lst_specqa, 96 | 'suff': lst1km_suff, 'res': 1000, 97 | 'color': lst_color}, 98 | 'lst_terra_daily_6000': {'url': urlbase, 'folder': 'MOLT/', 99 | 'prod': 'MOD11B1.005', 'days': daily, 100 | 'spec': lst_spec, 'spec_qa': lst_specqa, 101 | 'suff': lst6km_suff, 'res': 6000, 102 | 'color': lst_color}, 103 | 'lst_aqua_daily_6000': {'url': urlbase, 'folder': 'MOLA/', 104 | 'prod': 'MYD11B1.005', 'days': daily, 105 | 'spec': lst_spec, 'spec_qa': lst_specqa, 106 | 'suff': lst6km_suff, 'res': 6000, 107 | 'color': lst_color} 108 | } 109 | vi = {'ndvi_terra_sixteen_250': {'url': urlbase, 'folder': 'MOLT/', 110 | 'prod': 'MOD13Q1.005', 111 | 'spec': vi_spec, 'spec_qa': vi_specqa, 112 | 'suff': vi250m_suff, 'res': 250, 113 | 'color': vi_color, 'days': sixteen}, 114 | 'ndvi_aqua_sixteen_250': {'url': urlbase, 'folder': 'MOLA/', 115 | 'prod': 'MYD13Q1.005', 116 | 'spec': vi_spec, 'spec_qa': vi_specqa, 117 | 'suff': vi250m_suff, 'res': 250, 118 | 'color': vi_color, 'days': sixteen}, 119 | 'ndvi_terra_sixteen_500': {'url': urlbase, 'folder': 'MOLT/', 120 | 'prod': 'MOD13A1.005', 121 | 'spec': vi_spec, 'spec_qa': vi_specqa, 122 | 'suff': vi1km_suff, 'res': 500, 123 | 'color': vi_color, 'days': sixteen}, 124 | 'ndvi_aqua_sixteen_500': {'url': urlbase, 'folder': 'MOLA/', 125 | 'prod': 'MYD13A1.005', 126 | 'spec': vi_spec, 'spec_qa': vi_specqa, 127 | 'suff': vi500m_suff, 'res': 500, 128 | 'color': vi_color, 'days': sixteen}, 129 | 'ndvi_terra_sixteen_1000': {'url': urlbase, 'folder': 'MOLT/', 130 | 'prod': 'MOD13A2.005', 131 | 'spec': vi_spec, 'spec_qa': vi_specqa, 132 | 'suff': vi500m_suff, 'res': 1000, 133 | 'color': vi_color, 'days': sixteen}, 134 | 'ndvi_aqua_sixteen_1000': {'url': urlbase, 'folder': 'MOLA/', 135 | 'prod': 'MYD13A2.005', 136 | 'spec': vi_spec, 'spec_qa': vi_specqa, 137 | 'suff': vi1km_suff, 'res': 1000, 138 | 'color': vi_color, 'days': sixteen} 139 | } 140 | surf_refl = {'surfreflec_terra_eight_500': {'url': urlbase, 141 | 'folder': 'MOLT/', 142 | 'prod': 'MOD09A1.005', 143 | 'spec': surf_spec, 144 | 'spec_qa': surf_specqa, 145 | 'res': 500, 'days': eight, 146 | 'color': snow_color, 147 | 'suff': surf_suff}, 148 | 'surfreflec_aqua_eight_500': {'url': urlbase, 149 | 'folder': 'MOLA/', 150 | 'prod': 'MYD09A1.005', 151 | 'spec': surf_spec, 152 | 'spec_qa': surf_specqa, 153 | 'res': 500, 'days': eight, 154 | 'color': snow_color, 155 | 'suff': surf_suff} 156 | } 157 | snow = {'snow_terra_daily_500': {'url': usrsnow, 'folder': 'SAN/MOST/', 158 | 'prod': 'MOD10A1.005', 159 | 'spec': snow1_spec, 'days': daily, 160 | 'spec_qa': snow1_specqa, 161 | 'color': snow_color, 162 | 'suff': snow1_suff, 'res': 500}, 163 | 'snow_aqua_daily_500': {'url': usrsnow, 164 | 'folder': 'SAN/MOSA/', 165 | 'prod': 'MYD10A1.005', 166 | 'spec': snow1_spec, 'days': daily, 167 | 'spec_qa': snow1_specqa, 168 | 'color': snow_color, 169 | 'suff': snow1_suff, 'res': 500}, 170 | 'snow_terra_eight_500': {'url': usrsnow, 171 | 'folder': 'SAN/MOST/', 172 | 'prod': 'MOD10A2.005', 173 | 'spec': snow8_spec, 174 | 'spec_qa': None, 'days': eight, 175 | 'color': snow_color, 176 | 'suff': snow8_suff, 'res': 500}, 177 | 'snow_aqua_eight_500': {'url': usrsnow, 178 | 'folder': 'SAN/MOSA/', 179 | 'prod': 'MYD10A2.005', 180 | 'spec': snow8_spec, 181 | 'spec_qa': None, 'days': eight, 182 | 'color': snow_color, 183 | 'suff': snow8_suff, 'res': 500} 184 | } 185 | water = {'water_terra_250': {'url': urlbase, 'folder': 'MOLT/', 186 | 'prod': 'MOD44W.005', 'spec': water_spec, 187 | 'spec_qa': water_specqa, 'res': 250, 188 | 'suff': water_suff, 'days': daily, 189 | 'color': snow_color} 190 | } 191 | self.products = {} 192 | self.products.update(lst) 193 | self.products.update(vi) 194 | self.products.update(snow) 195 | self.products.update(surf_refl) 196 | self.products.update(water) 197 | self.products_swath = {'lst_terra_daily': {'url': urlbase, 198 | 'folder': 'MOLT/', 199 | 'prod': 'MOD11_L2.005', 200 | 'spec': lstL2_spec}, 201 | 'lst_aqua_daily': {'url': urlbase, 202 | 'folder': 'MOLA/', 203 | 'prod': 'MYD11_L2.005', 204 | 'spec': lstL2_spec} 205 | } 206 | 207 | def returned(self): 208 | if self.products.keys().count(self.prod) == 1: 209 | return self.products[self.prod] 210 | elif self.products_swath.keys().count(self.prod) == 1: 211 | return self.products_swath[self.prod] 212 | else: 213 | raise Exception ("The code insert is not supported yet. Consider " 214 | "to ask on the grass-dev mailing list for future " 215 | "support") 216 | 217 | def fromcode(self, code): 218 | import string 219 | for k, v in self.products.iteritems(): 220 | if string.find(v['prod'], code) != -1: 221 | return self.products[k] 222 | for k, v in self.products_swath.iteritems(): 223 | if string.find(v['prod'], code) != -1: 224 | return self.products_swath[k] 225 | raise Exception("The code insert is not supported yet. Consider to " 226 | "open a ticket in https://github.com/lucadelu/pyModis/issues") 227 | 228 | def color(self, code=None): 229 | if code: 230 | return self.fromcode(code)['color'] 231 | else: 232 | return self.returned()['color'] 233 | 234 | def suffix(self, code=None): 235 | if code: 236 | return self.fromcode(code)['suff'] 237 | else: 238 | return self.returned()['suff'] 239 | 240 | def __str__(self): 241 | prod = self.returned() 242 | string = "url: " + prod['url'] + ", folder: " + prod['folder'] 243 | if prod.keys().count('spec') == 1: 244 | string += ", spectral subset: " + prod['spec'] 245 | if prod.keys().count('spec_qa') == 1: 246 | string += ", spectral subset qa:" + prod['spec_qa'] 247 | return string 248 | -------------------------------------------------------------------------------- /pymodis/qualitymodis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # class to convert/process modis data 3 | # 4 | # (c) Copyright Ingmar Nitze 2013 5 | # Authors: Ingmar Nitze, Luca Delucchi 6 | # Email: initze at ucc dot ie 7 | # Email: luca dot delucchi at iasma dot it 8 | # 9 | ################################################################## 10 | # 11 | # This MODIS Python class is licensed under the terms of GNU GPL 2. 12 | # This program is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU General Public License as 14 | # published by the Free Software Foundation; either version 2 of 15 | # the License, or (at your option) any later version. 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | # See the GNU General Public License for more details. 20 | # 21 | ################################################################## 22 | """A class for the extraction and transformation of MODIS quality layers to 23 | specific information 24 | 25 | Classes: 26 | 27 | * :class:`QualityModis` 28 | 29 | """ 30 | 31 | # python 2 and 3 compatibility 32 | from __future__ import print_function 33 | from builtins import dict 34 | 35 | import os 36 | try: 37 | import numpy as np 38 | except ImportError: 39 | raise ImportError('Numpy library not found, please install it') 40 | 41 | try: 42 | import osgeo.gdal as gdal 43 | import osgeo.gdal_array as gdal_array 44 | except ImportError: 45 | try: 46 | import gdal 47 | import gdal_array 48 | except ImportError: 49 | raise ImportError('Python GDAL library not found, please install ' 50 | 'python-gdal') 51 | 52 | 53 | VALIDTYPES = dict({'13': list(map(str, list(range(1, 10)))), '11': list(map(str, list(range(1, 6))))}) 54 | 55 | PRODUCTPROPS = dict({ 56 | 'MOD13Q1': ([2], ['QAGrp1']), 57 | 'MYD13Q1': ([2], ['QAGrp1']), 58 | 'MOD13A1': ([2], ['QAGrp1']), 59 | 'MYD13A1': ([2], ['QAGrp1']), 60 | 'MOD13A2': ([2], ['QAGrp1']), 61 | 'MYD13A2': ([2], ['QAGrp1']), 62 | 'MOD13A3': ([2], ['QAGrp1']), 63 | 'MYD13A3': ([2], ['QAGrp1']), 64 | 'MOD13C1': ([2], ['QAGrp1']), 65 | 'MYD13C1': ([2], ['QAGrp1']), 66 | 'MOD13C2': ([2], ['QAGrp1']), 67 | 'MYD13C2': ([2], ['QAGrp1']), 68 | 'MOD11A1': ([1, 5], ['QAGrp2', 'QAGrp2']), 69 | 'MYD11A1': ([1, 5], ['QAGrp2', 'QAGrp2']), 70 | 'MOD11A2': ([1, 5], ['QAGrp4', 'QAGrp4']), 71 | 'MYD11A2': ([1, 5], ['QAGrp4', 'QAGrp4']), 72 | 'MOD11B1': ([1, 5, -2], ['QAGrp2', 'QAGrp2', 'QAGrp3']), 73 | 'MYD11B1': ([1, 5, -2], ['QAGrp2', 'QAGrp2', 'QAGrp3']), 74 | 'MOD11C1': ([1, 5, -2], ['QAGrp2', 'QAGrp2', 'QAGrp3']), 75 | 'MYD11C1': ([1, 5, -2], ['QAGrp2', 'QAGrp2', 'QAGrp3']), 76 | 'MOD11C2': ([1, 6], ['QAGrp2', 'QAGrp2']), 77 | 'MYD11C2': ([1, 6], ['QAGrp2', 'QAGrp2']), 78 | 'MOD11C3': ([1, 6], ['QAGrp2', 'QAGrp2']), 79 | 'MYD11C3': ([1, 6], ['QAGrp2', 'QAGrp2']) 80 | }) 81 | 82 | 83 | QAindices = dict({ 84 | 'QAGrp1': (16, [[-2, None], [-6, -2], [-8, -6], [-9, -8], 85 | [-10, -9], [-11, -10], [-14, -11], [-15, -14], 86 | [-16, -15]]), 87 | 'QAGrp2': (7, [[-2, None], [-3, -2], [-4, -3], [-6, -4], 88 | [-8, -6]]), 89 | 'QAGrp3': (7, [[-3, None], [-6, -3], [-7, -6]]), 90 | 'QAGrp4': (8, [[-2, None], [-4, -2], [-6, -4], [-8, -6]]) 91 | }) 92 | 93 | 94 | class QualityModis(): 95 | """A Class for the extraction and transformation of MODIS 96 | quality layers to specific information 97 | 98 | :param str infile: the full path to the hdf file 99 | :param str outfile: the full path to the parameter file 100 | """ 101 | 102 | def __init__(self, infile, outfile, qType=None, qLayer=None, pType=None): 103 | """Function to initialize the object""" 104 | self.infile = infile 105 | self.outfile = outfile 106 | self.qType = qType 107 | self.qLayer = qLayer 108 | self.qaGroup = None 109 | self.pType = pType 110 | 111 | def loadData(self): 112 | """loads the input file to the object""" 113 | os.path.isfile(self.infile) 114 | self.ds = gdal.Open(self.infile) 115 | 116 | def setProductType(self): 117 | """read productType from Metadata of hdf file""" 118 | if self.pType == None: 119 | self.productType = self.ds.GetMetadata()['SHORTNAME'] 120 | else: 121 | self.productType = self.pType 122 | 123 | def setProductGroup(self): 124 | """read productGroup from Metadata of hdf file""" 125 | self.productGroup = self.productType[3:5] 126 | 127 | def setQAGroup(self): 128 | """set QA dataset group type""" 129 | if self.productType in list(PRODUCTPROPS.keys()): 130 | self.qaGroup = PRODUCTPROPS[self.productType][1][int(self.qLayer)-1] 131 | else: 132 | print("Product version is currently not supported!") 133 | 134 | def setQALayer(self): 135 | """function sets the input path of the designated QA layer""" 136 | self.qaLayer = self.ds.GetSubDatasets()[PRODUCTPROPS[self.productType][0][int(self.qLayer)-1]][0] 137 | 138 | def loadQAArray(self): 139 | """loads the QA layer to the object""" 140 | self.qaArray = gdal_array.LoadFile(self.qaLayer) 141 | 142 | def qualityConvert(self, modisQaValue): 143 | """converts encoded Bit-Field values to designated QA information""" 144 | startindex = QAindices[self.qaGroup][1][int(self.qType)-1][0] 145 | endindex = QAindices[self.qaGroup][1][int(self.qType)-1][1] 146 | return int(np.binary_repr(modisQaValue, QAindices[self.qaGroup][0])[startindex: endindex], 2) 147 | 148 | def exportData(self): 149 | """writes calculated QA values to physical .tif file""" 150 | qaDS = gdal.Open(self.qaLayer) 151 | dr = gdal.GetDriverByName('GTiff') 152 | outds = dr.Create(self.outfile, self.ncols, self.nrows, 1, gdal.GDT_Byte) 153 | outds.SetProjection(qaDS.GetProjection()) 154 | outds.SetGeoTransform(qaDS.GetGeoTransform()) 155 | outds.GetRasterBand(1).WriteArray(self.qaOut) 156 | outds = None 157 | qaDS = None 158 | 159 | def run(self): 160 | """Function defines the entire process""" 161 | self.loadData() 162 | self.setProductType() 163 | self.setProductGroup() 164 | #self.setDSversion() 165 | self.setQAGroup() 166 | self.setQALayer() 167 | self.loadQAArray() 168 | self.nrows, self.ncols = self.qaArray.shape 169 | print("Conversion started !") 170 | self.qaOut = np.zeros_like(self.qaArray, dtype=np.int8) 171 | if self.productGroup in ['11', '13'] and self.qType in VALIDTYPES[self.productGroup] and self.qaGroup != None: 172 | for val in np.unique(self.qaArray): 173 | ind = np.where(self.qaArray == val) 174 | self.qaOut[ind] = self.qualityConvert(self.qaArray[ind][0]) 175 | self.exportData() 176 | print("Export finished!") 177 | else: 178 | print("This MODIS type is currently not supported.") 179 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=61.0"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project.scripts] 6 | modis_check = "scripts.modis_check:main" 7 | modis_convert = "scripts.modis_convert" 8 | modis_download_from_list = "scripts.modis_download_from_list:main" 9 | modis_download = "scripts.modis_download:main" 10 | modis_mosaic = "scripts.modis_mosaic:main" 11 | modis_multiparse = "scripts.modis_multiparse:main" 12 | modis_parse = "scripts.modis_parse:main" 13 | modis_quality = "scripts.modis_quality:main" 14 | 15 | [project] 16 | name = "pyModis" 17 | license = { text = "GNU General Public License v2 or later" } 18 | version = "2.4.1" 19 | authors = [ 20 | { name="Luca Delucchi", email="luca.delucchi@fmach.it" }, 21 | { name="Ingmar Nitze" }, 22 | { name="Xavier Corredor Llano" }, 23 | { name="Martin Landa" }, 24 | { name="Anton Petrov" }, 25 | ] 26 | maintainers = [ 27 | { name="Luca Delucchi", email="luca.delucchi@fmach.it" } 28 | ] 29 | description = "Python library for MODIS data" 30 | readme = "README.rst" 31 | classifiers = [ 32 | "Development Status :: 5 - Production/Stable", 33 | "Environment :: Console", 34 | "Topic :: Scientific/Engineering :: GIS", 35 | "Intended Audience :: End Users/Desktop", 36 | "Intended Audience :: Developers", 37 | "Operating System :: MacOS :: MacOS X", 38 | "Operating System :: Microsoft :: Windows", 39 | "Operating System :: POSIX", 40 | "Programming Language :: Python :: 2.7", 41 | "Programming Language :: Python :: 3", 42 | "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", 43 | ] 44 | dependencies = [ 45 | "numpy", 46 | "future", 47 | "requests", 48 | "GDAL", 49 | ] 50 | 51 | [project.optional-dependencies] 52 | gui = [ 53 | "wxPython", 54 | "wxPython-common" 55 | ] 56 | 57 | [project.urls] 58 | "Homepage" = "http://www.pymodis.org" 59 | "Issues" = "https://github.com/lucadelu/pyModis/issues" 60 | "Source" = "https://github.com/lucadelu/pyModis/" -------------------------------------------------------------------------------- /rpm/python-pymodis.changes: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------- 2 | Thu Mar 27 10:27:37 UTC 2014 - Angelos Tzotsos 3 | 4 | - initial release 0.7.4 5 | 6 | -------------------------------------------------------------------------------- /rpm/python-pymodis.spec: -------------------------------------------------------------------------------- 1 | # 2 | # spec file for package pyModis (0.7.4) 3 | # 4 | # Copyright (c) 2014 Angelos Tzotsos 5 | # 6 | # All modifications and additions to the file contributed by third parties 7 | # remain the property of their copyright owners, unless otherwise agreed 8 | # upon. The license for this file, and modifications and additions to the 9 | # file, is the same license as for the pyModis package itself (unless the 10 | # license for the pyModis package is not an Open Source License, in which 11 | # case the license is the MIT License). An "Open Source License" is a 12 | # license that conforms to the Open Source Definition (Version 1.9) 13 | # published by the Open Source Initiative. 14 | 15 | # Please submit bugfixes or comments via http://bugs.opensuse.org/ 16 | # 17 | 18 | %{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} 19 | %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} 20 | 21 | %define pyname pymodis 22 | %define pyname_cap pyModis 23 | 24 | Name: python-%{pyname} 25 | Version: 0.7.4 26 | Release: 0 27 | Summary: PyModis is a FOSS Python library to work with MODIS data 28 | License: GPLv2+ 29 | Url: http://www.pymodis.org/ 30 | Group: Productivity/Scientific/Other 31 | Source0: %{pyname_cap}-%{version}.tar.gz 32 | BuildRoot: %{_tmppath}/%{name}-%{version}-build 33 | BuildArch: noarch 34 | BuildRequires: python-devel 35 | BuildRequires: python-setuptools 36 | BuildRequires: python-numpy 37 | BuildRequires: fdupes 38 | Requires: python 39 | Requires: python-numpy 40 | Requires: python-gdal 41 | 42 | %description 43 | PyModis is a Free and Open Source Python based library to work with MODIS data. It offers bulk-download for user selected time ranges, mosaicking of MODIS tiles, and the reprojection from Sinusoidal to other projections, convert HDF format to other formats 44 | 45 | %prep 46 | %setup -q -n %{pyname_cap}-%{version} 47 | 48 | %build 49 | %{__python} setup.py build 50 | 51 | %install 52 | rm -rf %{buildroot} 53 | 54 | python setup.py install --prefix=%{_prefix} --root=%{buildroot} \ 55 | --record-rpm=INSTALLED_FILES 56 | 57 | %fdupes -s %{buildroot} 58 | 59 | %clean 60 | rm -rf %{buildroot} 61 | 62 | %files -f INSTALLED_FILES 63 | %defattr(-,root,root,-) 64 | 65 | %changelog 66 | -------------------------------------------------------------------------------- /scripts/modis_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # script to check which tiles are missing 3 | # 4 | # (c) Copyright Luca Delucchi 2018 5 | # Authors: Luca Delucchi 6 | # Email: luca dot delucchi at fmach dot it 7 | # 8 | ################################################################## 9 | # 10 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 11 | # This program is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU General Public License as 13 | # published by the Free Software Foundation; either version 2 of 14 | # the License, or (at your option) any later version. 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | ################################################################## 21 | """script to check which tiles are missing""" 22 | 23 | import glob 24 | import os 25 | import sys 26 | import calendar 27 | import copy 28 | from datetime import datetime 29 | 30 | from collections import OrderedDict 31 | 32 | try: 33 | from pymodis import optparse_gui 34 | WXPYTHON = True 35 | except: 36 | WXPYTHON = False 37 | from pymodis import optparse_required 38 | 39 | def main(): 40 | """Main function""" 41 | # usage 42 | usage = "usage: %prog [options] destination_folder" 43 | if 1 == len(sys.argv) and WXPYTHON: 44 | option_parser_class = optparse_gui.OptionParser 45 | else: 46 | option_parser_class = optparse_required.OptionParser 47 | parser = option_parser_class(usage=usage, description='modis_check') 48 | # output 49 | parser.add_option("-o", "--outputs", dest="outs", default="stdout", 50 | help="the output where write " 51 | "[default=%default]") 52 | # tiles 53 | parser.add_option("-t", "--tiles", dest="tiles", default=None, 54 | help="string of tiles separated with comma " 55 | "[default=%default for all tiles]") 56 | # the product 57 | parser.add_option("-p", "--product", dest="prod", default="MOD11A1", 58 | help="product name as on the http/ftp server " 59 | "[default=%default]") 60 | # the MODIS version 61 | parser.add_option("-m", "--modis_version", dest="mver", default="006", 62 | help="the version of MODIS product " 63 | "[default=%default]") 64 | 65 | # first day 66 | parser.add_option("-f", "--firstday", dest="today", default=None, 67 | help="the day to start download [default=%default is for" 68 | " today]; if you want change data you must use " 69 | "this format YYYY-MM-DD", metavar="FIRST_DAY") 70 | # last day 71 | parser.add_option("-e", "--endday", dest="enday", default=None, 72 | metavar="LAST_DAY", help="the day to stop download " 73 | "[default=%default]; if you want change" 74 | " data you must use this format YYYY-MM-DD") 75 | 76 | # number of days 77 | parser.add_option("-d", "--days", dest="days", default=1, metavar="DAYS", 78 | help="The temporal resolution of the dataset, " 79 | "[default=%default]") 80 | 81 | # return options and argument 82 | (options, args) = parser.parse_args() 83 | # test if args[0] it is set 84 | if len(args) == 0 and not WXPYTHON: 85 | parser.print_help() 86 | sys.exit(1) 87 | if len(args) == 0: 88 | parser.error("You have to define the destination folder for HDF file") 89 | if not os.path.isdir(args[0]): 90 | parser.error("The destination folder is not a dir or not exists") 91 | 92 | sday = 1 93 | if options.today: 94 | sday = int(datetime.strptime(options.today, "%Y-%m-%d").strftime("%j")) 95 | eday = 366 96 | if options.enday: 97 | eday = int(datetime.strptime(options.enday, "%Y-%m-%d").strftime("%j")) 98 | tres = int(options.days) 99 | 100 | if options.outs == "stdout": 101 | write = sys.stdout 102 | else: 103 | write = open(options.outs, 'w') 104 | 105 | files = glob.glob(os.path.join(args[0], '*.hdf')) 106 | tiles = options.tiles.split(',') 107 | output = OrderedDict() 108 | missing_dates = {} 109 | for fi in files: 110 | if fi.startswith('./'): 111 | fi = fi.lstrip('./') 112 | if fi.count('.') != 5: 113 | print("Error with file {fi}, to many dots, skipping it. Please " \ 114 | "to be sure run it for the same folder containing the HDF" \ 115 | " file".format(fi=fi)) 116 | continue 117 | fisplit = fi.split('.') 118 | dat = fisplit[1] 119 | year = int(dat[1:5]) 120 | if year not in missing_dates.keys(): 121 | if eday == 366 and calendar.isleap(year): 122 | eday = 367 123 | missing_dates[year] = list(range(sday, eday, tres)) 124 | doy = int(dat[5:8]) 125 | try: 126 | missing_dates[year].remove(doy) 127 | except ValueError: 128 | pass 129 | if dat not in output.keys(): 130 | output[dat] = copy.deepcopy(tiles) 131 | try: 132 | output[dat].remove(fisplit[2]) 133 | except ValueError: 134 | continue 135 | for k, v in missing_dates.items(): 136 | for dat in v: 137 | for ti in tiles: 138 | yd = "A{ye}{do}".format(ye=k, do=str(dat).zfill(3)) 139 | write.write("{co}\n".format(co=".".join((options.prod, yd, ti, 140 | options.mver, '*', 141 | 'hdf*')))) 142 | for k, v in output.items(): 143 | if len(v) != 0: 144 | for ti in v: 145 | write.write("{co}\n".format(co=".".join((options.prod, k, 146 | ti, options.mver, 147 | '*', 'hdf*')))) 148 | if options.outs != "stdout": 149 | write.close() 150 | 151 | if __name__ == "__main__": 152 | main() 153 | -------------------------------------------------------------------------------- /scripts/modis_convert.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # script to convert hdf file in sinusoidal projection to another format and 3 | # projection 4 | # 5 | # (c) Copyright Luca Delucchi 2012 6 | # Authors: Luca Delucchi 7 | # Email: luca dot delucchi at iasma dot it 8 | # 9 | ################################################################## 10 | # 11 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 12 | # This program is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU General Public License as 14 | # published by the Free Software Foundation; either version 2 of 15 | # the License, or (at your option) any later version. 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | # See the GNU General Public License for more details. 20 | # 21 | ################################################################## 22 | """Script to convert the input file HDF or VRT in different projection and 23 | format. It is able to use MRT or GDAL as backend 24 | """ 25 | 26 | import os 27 | import sys 28 | try: 29 | from pymodis import optparse_gui 30 | WXPYTHON = True 31 | except: 32 | WXPYTHON = False 33 | from pymodis import optparse_required 34 | from pymodis import parsemodis 35 | from pymodis import convertmodis_gdal 36 | from optparse import OptionGroup 37 | 38 | try: 39 | import osgeo.gdal as gdal 40 | except ImportError: 41 | try: 42 | import gdal 43 | except ImportError: 44 | raise Exception('Python GDAL library not found, please install python-gdal') 45 | 46 | 47 | def removeBracs(stri): 48 | """Remove brackets from string""" 49 | return stri.replace(']', '').replace('[', '') 50 | 51 | 52 | def main(): 53 | """Main function""" 54 | # usage 55 | usage = "usage: %prog [options] hdf_file" 56 | if 1 == len(sys.argv) and WXPYTHON: 57 | option_parser_class = optparse_gui.OptionParser 58 | else: 59 | option_parser_class = optparse_required.OptionParser 60 | parser = option_parser_class(usage=usage, description='modis_convert') 61 | groupR = OptionGroup(parser, 'General options') 62 | groupG = OptionGroup(parser, 'Options for GDAL') 63 | groupM = OptionGroup(parser, 'Options for MRT') 64 | # options used by both methos 65 | groupR.add_option("-s", "--subset", dest="subset", required=True, 66 | help="a subset of product's layers. The string should " 67 | "be similar to: ( 1 0 )") 68 | groupR.add_option("-o", "--output", dest="output", required=True, 69 | help="the prefix of output file", metavar="OUTPUT_FILE") 70 | groupR.add_option("-g", "--grain", dest="resolution", type="float", 71 | help="the spatial resolution of output file") 72 | help_resampl = "the method of resampling." 73 | help_resampl += " -- mrt methods: {res}".format(res=parsemodis.RESAM_LIST) 74 | help_resampl += " -- gdal methods: {res}".format(res=convertmodis_gdal.RESAM_GDAL) 75 | help_resampl = removeBracs(help_resampl) 76 | res_choice = parsemodis.RESAM_LIST + convertmodis_gdal.RESAM_GDAL 77 | groupR.add_option("-r", "--resampl", dest="resampling", 78 | help=help_resampl + " [default=%default]", 79 | metavar="RESAMPLING_TYPE", default='NEAREST_NEIGHBOR', 80 | type='choice', choices=res_choice) 81 | # options only for GDAL 82 | groupG.add_option("-f", "--output-format", dest="output_format", 83 | metavar="OUTPUT_FORMAT", default="GTiff", 84 | help="output format supported by GDAL [default=%default]") 85 | groupG.add_option("-e", "--epsg", dest="epsg", metavar="EPSG", 86 | help="EPSG code for the output") 87 | groupG.add_option("-w", "--wkt_file", dest="wkt", metavar="WKT", 88 | help="file or string containing projection definition" 89 | " in WKT format") 90 | groupG.add_option("-v", "--vrt", dest="vrt", action="store_true", 91 | default=False, help="Read from a GDAL VRT file.") 92 | groupG.add_option("--formats", dest="formats", action="store_true", 93 | help="print supported GDAL formats") 94 | # options only for MRT 95 | groupM.add_option("-m", "--mrt", dest="mrt_path", type='directory', 96 | help="the path to MRT software", metavar="MRT_PATH") 97 | help_datum = "the code of datum. Available: {dat}".format(dat=parsemodis.DATUM_LIST) 98 | help_datum = removeBracs(help_datum) 99 | groupM.add_option("-d", "--datum", dest="datum", default="WGS84", 100 | type='choice', choices=parsemodis.DATUM_LIST, 101 | help=help_datum + " [default=%default]") 102 | help_pt = "the output projection system. Available: {proj}".format(proj=parsemodis.PROJ_LIST) 103 | help_pt = removeBracs(help_pt) 104 | groupM.add_option("-t", "--proj_type", dest="projection_type", 105 | type='choice', metavar="PROJECTION_SYSTEM", 106 | choices=parsemodis.PROJ_LIST, action='store', 107 | help=help_pt + " [default=%default]", default='GEO') 108 | groupM.add_option("-p", "--proj_parameters", dest="projection_parameter", 109 | metavar="PROJECTION_PARAMETERS", 110 | default='( 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0' 111 | ' 0.0 0.0 0.0 0.0 )', 112 | help="a list of projection parameters, for more info " 113 | "check the 'Appendix C' of MODIS reprojection tool user" 114 | "'s manual https://lpdaac.usgs.gov/content/download" 115 | "/4831/22895/file/mrt41_usermanual_032811.pdf " 116 | "[default=%default]") 117 | groupM.add_option("-u", "--utm", dest="utm_zone", metavar="UTM_ZONE", 118 | help="the UTM zone if projection system is UTM") 119 | parser.add_option_group(groupR) 120 | parser.add_option_group(groupG) 121 | parser.add_option_group(groupM) 122 | # return options and argument 123 | (options, args) = parser.parse_args() 124 | # check the argument 125 | if len(args) == 0 and not WXPYTHON: 126 | parser.print_help() 127 | sys.exit(1) 128 | if len(args) > 1: 129 | parser.error("You have to define the name of HDF file.") 130 | if not os.path.isfile(args[0]): 131 | parser.error("You have to define the name of HDF file.") 132 | if not (options.subset.strip().startswith('(') and options.subset.strip().endswith(')')): 133 | parser.error('ERROR: The spectral string should be similar to: "( 1 0 )"') 134 | 135 | if options.mrt_path: 136 | if not options.output.endswith('.tif') and \ 137 | not options.output.endswith('.hdf') and \ 138 | not options.output.endswith('.hdr'): 139 | parser.error("Valid extensions for output are .hdf, .hdr, or .tif") 140 | from pymodis import convertmodis 141 | modisParse = parsemodis.parseModis(args[0]) 142 | confname = modisParse.confResample(options.subset, options.resolution, 143 | options.output, options.datum, 144 | options.resampling, 145 | options.projection_type, 146 | options.utm_zone, 147 | options.projection_parameter) 148 | modisConver = convertmodis.convertModis(args[0], confname, 149 | options.mrt_path) 150 | else: 151 | modisConver = convertmodis_gdal.convertModisGDAL(args[0], 152 | options.output, 153 | options.subset, 154 | options.resolution, 155 | options.output_format, 156 | options.epsg, 157 | options.wkt, 158 | options.resampling, 159 | options.vrt) 160 | modisConver.run() 161 | 162 | if __name__ == "__main__": 163 | gdal.AllRegister() 164 | argv = gdal.GeneralCmdLineProcessor(sys.argv) 165 | if argv is not None: 166 | main() 167 | -------------------------------------------------------------------------------- /scripts/modis_download.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # script to download massive MODIS data from ftp 3 | # 4 | # (c) Copyright Luca Delucchi 2010 5 | # Authors: Luca Delucchi 6 | # Email: luca dot delucchi at iasma dot it 7 | # 8 | ################################################################## 9 | # 10 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 11 | # This program is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU General Public License as 13 | # published by the Free Software Foundation; either version 2 of 14 | # the License, or (at your option) any later version. 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | ################################################################## 21 | """Script to download massive MODIS data""" 22 | import sys 23 | import os 24 | import getpass 25 | try: 26 | from pymodis import optparse_gui 27 | WXPYTHON = True 28 | except: 29 | WXPYTHON = False 30 | from pymodis import optparse_required 31 | from pymodis import downmodis 32 | 33 | 34 | def main(): 35 | """Main function""" 36 | # usage 37 | usage = "usage: %prog [options] destination_folder" 38 | if 1 == len(sys.argv) and WXPYTHON: 39 | option_parser_class = optparse_gui.OptionParser 40 | else: 41 | option_parser_class = optparse_required.OptionParser 42 | parser = option_parser_class(usage=usage, description='modis_download') 43 | # url 44 | parser.add_option("-u", "--url", default="https://e4ftl01.cr.usgs.gov", 45 | help="http/ftp server url [default=%default]", 46 | dest="url") 47 | # username and password from stdin 48 | parser.add_option("-I", "--input", dest="input", action="store_true", 49 | help="insert user and password from standard input") 50 | # password 51 | parser.add_option("-P", "--password", dest="password", default=None, 52 | help="password to connect to the server") 53 | # username 54 | parser.add_option("-U", "--username", dest="user", default=None, 55 | help="username to connect to the server") 56 | 57 | # token 58 | parser.add_option("-T", "--token", dest="token", default=None, 59 | help="user token to connect to the server") 60 | # tiles 61 | parser.add_option("-t", "--tiles", dest="tiles", default=None, 62 | help="string of tiles separated with comma " 63 | "[default=%default for all tiles]") 64 | # path to add the path in the server 65 | parser.add_option("-s", "--source", dest="path", default="MOLT", 66 | help="directory on the http/ftp server " 67 | "[default=%default]") 68 | # path to add the url 69 | parser.add_option("-p", "--product", dest="prod", default="MOD11A1.005", 70 | help="product name as on the http/ftp server " 71 | "[default=%default]") 72 | # delta 73 | parser.add_option("-D", "--delta", dest="delta", default=10, 74 | help="delta of day from the first day " 75 | "[default=%default]") 76 | # first day 77 | parser.add_option("-f", "--firstday", dest="today", default=None, 78 | help="the day to start download [default=%default is for" 79 | " today]; if you want change data you must use " 80 | "this format YYYY-MM-DD", metavar="FIRST_DAY") 81 | # last day 82 | parser.add_option("-e", "--endday", dest="enday", default=None, 83 | metavar="LAST_DAY", help="the day to stop download " 84 | "[default=%default]; if you want change" 85 | " data you must use this format YYYY-MM-DD") 86 | # debug 87 | parser.add_option("-x", action="store_true", dest="debug", default=False, 88 | help="this is useful for debugging the " 89 | "download [default=%default]") 90 | # jpg 91 | parser.add_option("-j", action="store_true", dest="jpg", default=False, 92 | help="download also the jpeg files [default=%default]") 93 | # only one day 94 | parser.add_option("-O", dest="oneday", action="store_true", default=False, 95 | help="download only one day, it set " 96 | "delta=1 [default=%default]") 97 | # all days 98 | parser.add_option("-A", dest="alldays", action="store_true", default=False, 99 | help="download all days, it useful for initial download" 100 | " of a product. It overwrite the 'firstday' and " 101 | "'endday' options [default=%default]") 102 | # remove file with size = 0 103 | parser.add_option("-r", dest="empty", action="store_true", default=False, 104 | help="remove empty files (size equal to zero) from " 105 | "'destination_folder' [default=%default]") 106 | #parser.add_option("-A", dest="alldays", action="store_true", default=True, 107 | #help="download all days from the first") 108 | 109 | # set false several options 110 | parser.set_defaults(oneday=False) 111 | parser.set_defaults(debug=False) 112 | parser.set_defaults(jpg=False) 113 | 114 | user = None 115 | password = None 116 | token = None 117 | 118 | # return options and argument 119 | (options, args) = parser.parse_args() 120 | # test if args[0] it is set 121 | if len(args) == 0 and not WXPYTHON: 122 | parser.print_help() 123 | sys.exit(1) 124 | if len(args) == 0: 125 | parser.error("You have to define the destination folder for HDF file") 126 | if not os.path.isdir(args[0]): 127 | parser.error("The destination folder is not a dir or not exists") 128 | 129 | # check if oneday option it is set 130 | if options.oneday: 131 | options.delta = 1 132 | if options.input: 133 | if sys.version_info.major == 3: 134 | user = input("Username [type 'token' if you need to use token instead of user/login]: ") 135 | else: 136 | user = raw_input("Username: ") 137 | if user == "token": 138 | token = getpass.getpass("Token: ") 139 | else: 140 | password = getpass.getpass("Password: ") 141 | else: 142 | user = options.user 143 | password = options.password 144 | token = options.token 145 | 146 | # set modis object 147 | modisOgg = downmodis.downModis(url=options.url, 148 | user=user, 149 | password=password, 150 | token=token, 151 | destinationFolder=args[0], 152 | tiles=options.tiles, path=options.path, 153 | product=options.prod, today=options.today, 154 | enddate=options.enday, jpg=options.jpg, 155 | delta=int(options.delta), 156 | debug=options.debug) 157 | # connect to ftp 158 | modisOgg.connect() 159 | if modisOgg.nconnection <= 20: 160 | # download data 161 | modisOgg.downloadsAllDay(clean=options.empty, allDays=options.alldays) 162 | else: 163 | parser.error("A problem with the connection occured") 164 | 165 | #add options 166 | if __name__ == "__main__": 167 | main() 168 | -------------------------------------------------------------------------------- /scripts/modis_download_from_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Script to download massive MODIS data from a text file containing a list of 3 | # MODIS file name 4 | # 5 | # (c) Copyright Luca Delucchi 2013 6 | # Authors: Luca Delucchi 7 | # Email: luca dot delucchi at fmach dot it 8 | # 9 | ################################################################## 10 | # 11 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 12 | # This program is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU General Public License as 14 | # published by the Free Software Foundation; either version 2 of 15 | # the License, or (at your option) any later version. 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | # See the GNU General Public License for more details. 20 | # 21 | ################################################################## 22 | """Script to download massive MODIS data from a text file containing a list of 23 | MODIS file name""" 24 | from datetime import date 25 | try: 26 | from pymodis import optparse_gui 27 | WXPYTHON = True 28 | except: 29 | WXPYTHON = False 30 | from pymodis import downmodis 31 | from pymodis import optparse_required 32 | import sys 33 | import os 34 | import getpass 35 | 36 | 37 | def write_out(out, ts, options, day): 38 | """Write the missing files""" 39 | opts = options.prod.split('.') 40 | for ti in ts: 41 | out.write("{co}\n".format(co=".".join((opts[0], "A{da}".format(da=day), 42 | ti, opts[1], '*', 'hdf*')))) 43 | 44 | 45 | def main(): 46 | """Main function""" 47 | # usage 48 | usage = "usage: %prog [options] destination_folder" 49 | if 1 == len(sys.argv) and WXPYTHON: 50 | option_parser_class = optparse_gui.OptionParser 51 | else: 52 | option_parser_class = optparse_required.OptionParser 53 | parser = option_parser_class(usage=usage, 54 | description='modis_download_from_list') 55 | # file 56 | parser.add_option("-f", "--file", dest="file", type='file', 57 | help="Input file containing data to download") 58 | # url 59 | parser.add_option("-u", "--url", default="https://e4ftl01.cr.usgs.gov", 60 | help="http/ftp server url [default=%default]", 61 | dest="url") 62 | # username and password from stdin 63 | parser.add_option("-I", "--input", dest="input", action="store_true", 64 | help="insert user and password from standard input") 65 | # password 66 | parser.add_option("-P", "--password", dest="password", 67 | help="password to connect to the server") 68 | # username 69 | parser.add_option("-U", "--username", dest="user", 70 | help="username to connect to the server ") 71 | # path to add the path in the server 72 | parser.add_option("-s", "--source", dest="path", default="MOLT", 73 | help="directory on the http/ftp server " 74 | "[default=%default]") 75 | # path to add the url 76 | parser.add_option("-p", "--product", dest="prod", default="MOD11A1.006", 77 | help="product name as on the http/ftp server " 78 | "[default=%default]") 79 | # path to file with server missing tiles 80 | parser.add_option("-o", "--outputs", dest="outs", default=None, 81 | help="the output where write the missing files in the" 82 | " server [default=%default]. Use 'stdout' to write to " 83 | " STDOUT") 84 | # use netrc file 85 | parser.add_option("-n", action="store_true", dest="netrc", default=False, 86 | help="use netrc file to read user and password") 87 | # debug 88 | parser.add_option("-x", action="store_true", dest="debug", default=False, 89 | help="this is useful for debugging the " 90 | "download [default=%default]") 91 | # jpg 92 | parser.add_option("-j", action="store_true", dest="jpg", default=False, 93 | help="download also the jpeg overview files " 94 | "[default=%default]") 95 | # return options and argument 96 | (options, args) = parser.parse_args() 97 | if len(args) == 0 and not WXPYTHON: 98 | parser.print_help() 99 | sys.exit(1) 100 | if len(args) > 1: 101 | parser.error("You have to define the destination folder for HDF file") 102 | if not os.path.isdir(args[0]): 103 | parser.error("The destination folder is not a dir or not exists") 104 | 105 | if options.netrc: 106 | user = None 107 | password = None 108 | elif options.input: 109 | if sys.version_info.major == 3: 110 | user = input("Username: ") 111 | else: 112 | user = raw_input("Username: ") 113 | password = getpass.getpass() 114 | else: 115 | user = options.user 116 | password = options.password 117 | 118 | f = open(options.file) 119 | 120 | lines = [elem for elem in f.readlines()] 121 | 122 | vals = {} 123 | for elem in lines: 124 | if elem != '\n': 125 | dat = elem.split('.')[1].replace('A', '') 126 | fisplit = elem.strip().split('.') 127 | if dat not in vals.keys(): 128 | vals[dat] = [fisplit[2]] 129 | else: 130 | vals[dat].append(fisplit[2]) 131 | 132 | if not options.outs: 133 | write = None 134 | elif options.outs == "stdout": 135 | write = sys.stdout 136 | else: 137 | write = open(options.outs, 'w') 138 | 139 | for d, tiles in sorted(vals.items(), reverse=True): 140 | year = int(d[0:4]) 141 | doy = int(d[4:7]) 142 | fdate = date.fromordinal(date(year, 1, 1).toordinal() + doy - 1).isoformat() 143 | modisOgg = downmodis.downModis(url=options.url, user=user, 144 | password=password, 145 | destinationFolder=args[0], 146 | tiles=','.join(sorted(set(tiles))), 147 | path=options.path, product=options.prod, 148 | delta=1, today=fdate, 149 | debug=options.debug, jpg=options.jpg) 150 | 151 | modisOgg.connect() 152 | day = modisOgg.getListDays()[0] 153 | if modisOgg.urltype == 'http': 154 | listAllFiles = modisOgg.getFilesList(day) 155 | else: 156 | listAllFiles = modisOgg.getFilesList() 157 | if not listAllFiles: 158 | if write: 159 | write_out(write, tiles, options, d) 160 | continue 161 | listFilesDown = modisOgg.checkDataExist(listAllFiles) 162 | 163 | if listFilesDown: 164 | if options.debug: 165 | print(listFilesDown) 166 | modisOgg.dayDownload(day, listFilesDown) 167 | for fi in listFilesDown: 168 | if 'xml' not in fi: 169 | try: 170 | tiles.remove(fi.split('.')[2]) 171 | except ValueError: 172 | pass 173 | if write: 174 | write_out(write, tiles, options, d) 175 | if modisOgg.urltype == 'http': 176 | modisOgg.closeFilelist() 177 | else: 178 | modisOgg.closeFTP() 179 | 180 | if __name__ == "__main__": 181 | main() 182 | -------------------------------------------------------------------------------- /scripts/modis_mosaic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # script to create mosaic from several tiles of MODIS 3 | # 4 | # (c) Copyright Luca Delucchi 2012 5 | # Authors: Luca Delucchi 6 | # Email: luca dot delucchi at iasma dot it 7 | # 8 | ################################################################## 9 | # 10 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 11 | # This program is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU General Public License as 13 | # published by the Free Software Foundation; either version 2 of 14 | # the License, or (at your option) any later version. 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | ################################################################## 21 | """Script to mosaic the input tiles. It is able to use MRT or GDAL as backend 22 | """ 23 | 24 | import os 25 | import sys 26 | try: 27 | from pymodis import optparse_gui 28 | WXPYTHON = True 29 | except: 30 | WXPYTHON = False 31 | from pymodis import convertmodis 32 | from pymodis import convertmodis_gdal 33 | from pymodis import optparse_required 34 | from optparse import OptionGroup 35 | try: 36 | import osgeo.gdal as gdal 37 | except ImportError: 38 | try: 39 | import gdal 40 | except ImportError: 41 | raise Exception('Python GDAL library not found, please install python-gdal') 42 | 43 | ERROR = "You have to define the name of a text file containing HDF files" \ 44 | " (One HDF file for line)." 45 | 46 | 47 | def main(): 48 | """Main function""" 49 | # usage 50 | usage = "usage: %prog [options] hdflist_file" 51 | if 1 == len(sys.argv) and WXPYTHON: 52 | option_parser_class = optparse_gui.OptionParser 53 | else: 54 | option_parser_class = optparse_required.OptionParser 55 | parser = option_parser_class(usage=usage, description='modis_mosaic') 56 | groupR = OptionGroup(parser, 'General options') 57 | groupG = OptionGroup(parser, 'Options for GDAL') 58 | groupM = OptionGroup(parser, 'Options for MRT') 59 | # output 60 | groupR.add_option("-o", "--output", dest="output", required=True, 61 | help="the name or prefix (for VRT) of output mosaic", 62 | metavar="OUTPUT_FILE") 63 | # subset 64 | groupR.add_option("-s", "--subset", dest="subset", 65 | help="a subset of product layers. The string should" 66 | " be similar to: 1 0 [default: all layers]") 67 | # options only for GDAL 68 | groupG.add_option("-f", "--output-format", dest="output_format", 69 | metavar="OUTPUT_FORMAT", default="GTiff", 70 | help="output format supported: GTiff, HDF4Image" 71 | " [default=%default]") 72 | # groupG.add_option("-g", "--grain", dest="grain", 73 | # type="int", help="force the spatial resolution of output" 74 | # " file") 75 | # options for set VRT 76 | groupG.add_option("-v", "--vrt", dest="vrt", action="store_true", 77 | default=False, help="Create a GDAL VRT file. No other " 78 | "GDAL options have to been set") 79 | # mrt path 80 | groupM.add_option("-m", "--mrt", dest="mrt_path", type='directory', 81 | help="the path to MRT software", metavar="MRT_PATH") 82 | parser.add_option_group(groupR) 83 | parser.add_option_group(groupG) 84 | parser.add_option_group(groupM) 85 | (options, args) = parser.parse_args() 86 | # check the number of tiles 87 | if len(args) == 0 and not WXPYTHON: 88 | parser.print_help() 89 | sys.exit(1) 90 | if not args: 91 | parser.error(ERROR) 92 | else: 93 | if not isinstance(args, list): 94 | parser.error(ERROR) 95 | elif len(args) > 1: 96 | parser.error(ERROR) 97 | if not os.path.isfile(args[0]): 98 | parser.error(ERROR + '. ' + args[0] + ' does not exists') 99 | 100 | if not os.path.isfile(args[0]): 101 | parser.error("You have to define the name of a text file containing " 102 | "HDF files. (One HDF file for line)") 103 | 104 | # check is a subset it is set 105 | if not options.subset: 106 | options.subset = False 107 | else: 108 | if (options.subset.strip().startswith('(') or options.subset.strip().endswith(')')): 109 | parser.error('ERROR: The spectral string should be similar to: ' 110 | '"1 0" without "(" and ")"') 111 | # if not options.grain and options.vrt: 112 | # options.grain = False 113 | # elif not options.grain and options.vrt: 114 | # parser.error("You have to define the resolution of output file. Please" 115 | # " set -g/--grain option") 116 | if options.mrt_path: 117 | modisOgg = convertmodis.createMosaic(args[0], options.output, 118 | options.mrt_path, options.subset) 119 | modisOgg.run() 120 | else: 121 | tiles = dict() 122 | dire = os.path.dirname(args[0]) 123 | with open(args[0]) as f: 124 | for l in f: 125 | name = os.path.splitext(l.strip())[0] 126 | day = name.split('.')[1] 127 | if day not in tiles.keys(): 128 | tiles[day] = list() 129 | if '.hdf' not in name: 130 | if dire not in l: 131 | fname = os.path.join(dire, l.strip()) 132 | else: 133 | fname = l.strip() 134 | tiles[day].append(fname) 135 | 136 | for day in tiles.keys(): 137 | modisOgg = convertmodis_gdal.createMosaicGDAL(tiles[day], 138 | options.subset, 139 | options.output_format) 140 | output = "{da}_{fi}".format(da=day, fi=options.output) 141 | if options.vrt: 142 | modisOgg.write_vrt(output) 143 | else: 144 | modisOgg.run(output) 145 | 146 | if __name__ == "__main__": 147 | gdal.AllRegister() 148 | argv = gdal.GeneralCmdLineProcessor(sys.argv) 149 | if argv is not None: 150 | main() 151 | -------------------------------------------------------------------------------- /scripts/modis_multiparse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # script to obtain the bounding box of several tiles and write xml file of the mosaic 3 | # 4 | # (c) Copyright Luca Delucchi 2012 5 | # Authors: Luca Delucchi 6 | # Email: luca dot delucchi at iasma dot it 7 | # 8 | ################################################################## 9 | # 10 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 11 | # This program is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU General Public License as 13 | # published by the Free Software Foundation; either version 2 of 14 | # the License, or (at your option) any later version. 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | ################################################################## 21 | 22 | # python 2 and 3 compatibility 23 | from __future__ import print_function 24 | 25 | #import system library 26 | import sys 27 | import os 28 | #import modis library 29 | try: 30 | from pymodis import optparse_gui 31 | wxpython = True 32 | except: 33 | wxpython = False 34 | from pymodis import parsemodis 35 | from pymodis import optparse_required 36 | 37 | 38 | def readDict(dic): 39 | """Function to decode dictionary""" 40 | out = "" 41 | for k, v in dic.items(): 42 | out += "%s = %s\n" % (k, v) 43 | return out 44 | 45 | 46 | def main(): 47 | """Main function""" 48 | #usage 49 | usage = "usage: %prog [options] hdf_files_list" 50 | if 1 == len(sys.argv) and wxpython: 51 | option_parser_class = optparse_gui.OptionParser 52 | else: 53 | option_parser_class = optparse_required.OptionParser 54 | parser = option_parser_class(usage=usage, description='modis_multiparse') 55 | #spatial extent 56 | parser.add_option("-b", action="store_true", dest="bound", default=False, 57 | help="print the values related to the spatial max extent") 58 | #write into file 59 | parser.add_option("-w", "--write", dest="output", metavar="OUTPUT_FILE", 60 | help="write the MODIS XML metadata file for MODIS mosaic") 61 | 62 | (options, args) = parser.parse_args() 63 | #create modis object 64 | if len(args) == 0 and not wxpython: 65 | parser.print_help() 66 | sys.exit(1) 67 | if len(args) < 2: 68 | parser.error("You have to define the name of multiple HDF files") 69 | for arg in args: 70 | if not os.path.isfile(arg): 71 | parser.error(arg + " does not exist or is not a file") 72 | modisOgg = parsemodis.parseModisMulti(args) 73 | 74 | if options.bound: 75 | modisOgg.valBound() 76 | print(readDict(modisOgg.boundary)) 77 | elif options.output: 78 | modisOgg.writexml(options.output) 79 | print("%s write correctly" % options.output) 80 | else: 81 | parser.error("You have to choose at least one option") 82 | 83 | #add options 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /scripts/modis_parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # script to parse variable from xml file 3 | # 4 | # (c) Copyright Luca Delucchi 2012 5 | # Authors: Luca Delucchi 6 | # Email: luca dot delucchi at iasma dot it 7 | # 8 | ################################################################## 9 | # 10 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 11 | # This program is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU General Public License as 13 | # published by the Free Software Foundation; either version 2 of 14 | # the License, or (at your option) any later version. 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # See the GNU General Public License for more details. 19 | # 20 | ################################################################## 21 | """Script to read metadata from a MODIS HDF file""" 22 | 23 | # python 2 and 3 compatibility 24 | from __future__ import print_function 25 | 26 | # import system library 27 | import sys 28 | import os 29 | # import modis library 30 | try: 31 | from pymodis import optparse_gui 32 | WXPYTHON = True 33 | except: 34 | WXPYTHON = False 35 | from pymodis import parsemodis 36 | from pymodis import optparse_required 37 | 38 | ERROR = "You have to define the name of HDF file" 39 | 40 | 41 | def readDict(dic): 42 | """Function to decode dictionary""" 43 | out = "" 44 | for k, v in dic.items(): 45 | out += "%s = %s\n" % (k, v) 46 | return out 47 | 48 | 49 | def main(): 50 | """Main function""" 51 | # usage 52 | usage = "usage: %prog [options] hdf_file" 53 | if 1 == len(sys.argv) and WXPYTHON: 54 | option_parser_class = optparse_gui.OptionParser 55 | else: 56 | option_parser_class = optparse_required.OptionParser 57 | parser = option_parser_class(usage=usage, description='modis_parse') 58 | # write into file 59 | parser.add_option("-w", "--write", dest="output", metavar="OUTPUT_FILE", 60 | help="write the chosen information into a file", 61 | type='output') 62 | # all data 63 | parser.add_option("-a", action="store_true", dest="all", default=False, 64 | help="print all possible values of metadata") 65 | # spatial extent 66 | parser.add_option("-b", action="store_true", dest="boundary", 67 | default=False, help="print the values related to the " 68 | "spatial max extent") 69 | # data files 70 | parser.add_option("-d", action="store_true", dest="data", default=False, 71 | help="print the values related to the date files") 72 | # data granule 73 | parser.add_option("-e", action="store_true", dest="data_ecs", 74 | default=False, help="print the values related to the " 75 | "ECSDataGranule") 76 | # input files 77 | parser.add_option("-i", action="store_true", dest="input", default=False, 78 | help="print the input layers") 79 | # other values 80 | parser.add_option("-o", action="store_true", dest="other", default=False, 81 | help="print the other values") 82 | # platform information 83 | parser.add_option("-p", action="store_true", dest="platform", default=False, 84 | help="print the values related to platform") 85 | # data quality 86 | parser.add_option("-q", action="store_true", dest="qa", default=False, 87 | help="print the values related to quality") 88 | # psas 89 | parser.add_option("-s", action="store_true", dest="psas", default=False, 90 | help="print the values related to psas") 91 | # time 92 | parser.add_option("-t", action="store_true", dest="time", default=False, 93 | help="print the values related to times") 94 | # layers 95 | parser.add_option("-l", action="store_true", dest="layers", default=False, 96 | help="print the names of layer in HDF file") 97 | 98 | # return options and argument 99 | (options, args) = parser.parse_args() 100 | if len(args) == 0 and not WXPYTHON: 101 | parser.print_help() 102 | sys.exit(1) 103 | if not args: 104 | parser.error(ERROR) 105 | else: 106 | if not isinstance(args, list): 107 | parser.error(ERROR) 108 | if not os.path.isfile(args[0]): 109 | parser.error(ERROR + '. ' + args[0] + ' does not exists') 110 | # create modis object 111 | modisOgg = parsemodis.parseModis(args[0]) 112 | # the output string 113 | outString = "" 114 | 115 | if options.all or options.boundary: 116 | outString += readDict(modisOgg.retBoundary()) 117 | if options.all or options.time: 118 | outString += "InsertTime = %s\n" % modisOgg.retInsertTime() 119 | outString += "LastUpdate = %s\n" % modisOgg.retLastUpdate() 120 | outString += readDict(modisOgg.retRangeTime()) 121 | if options.all or options.data_ecs: 122 | outString += readDict(modisOgg.retDataGranule()) 123 | if options.all or options.data: 124 | outString += readDict(modisOgg.retDataFiles()) 125 | if options.all or options.input: 126 | outString += 'InputFiles = ' 127 | outString += ', '.join(modisOgg.retInputGranule()) 128 | outString += '\n' 129 | if options.all or options.platform: 130 | outString += readDict(modisOgg.retPlatform()) 131 | if options.all or options.psas: 132 | outString += readDict(modisOgg.retPSA()) 133 | if options.all or options.qa: 134 | out = modisOgg.retMeasure() 135 | for mes in out.values(): 136 | outString += mes['ParameterName'] + '\n' 137 | outString += readDict(mes['QAStats']) 138 | outString += readDict(mes['QAFlags']) 139 | if options.all or options.other: 140 | outString += readDict(modisOgg.retCollectionMetaData()) 141 | outString += "PGEVersion = %s\n" % modisOgg.retPGEVersion() 142 | outString += "BrowseProduct = %s\n" % modisOgg.retBrowseProduct() 143 | if options.all or options.layers: 144 | outString += modisOgg.getLayersName() 145 | if not outString: 146 | print("Please select at least one flag") 147 | # write option it is set write the string into file 148 | elif options.output: 149 | outFile = open(options.output, 'w') 150 | outFile.write(outString) 151 | outFile.close() 152 | print("{name} write correctly".format(name=outFile.name)) 153 | # else print the string 154 | else: 155 | print(outString) 156 | 157 | if __name__ == "__main__": 158 | main() 159 | -------------------------------------------------------------------------------- /scripts/modis_quality.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # script to extract specific information from MODIS Quality Masks 3 | # 4 | # (c) Copyright Ingmar Nitze 2013 5 | # Authors: Ingmar Nitze, Luca Delucchi 6 | # Email: initze at ucc dot ie 7 | # Email: luca dot delucchi at iasma dot it 8 | # 9 | ################################################################## 10 | # 11 | # This MODIS Python script is licensed under the terms of GNU GPL 2. 12 | # This program is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU General Public License as 14 | # published by the Free Software Foundation; either version 2 of 15 | # the License, or (at your option) any later version. 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | # See the GNU General Public License for more details. 20 | # 21 | ################################################################## 22 | 23 | import sys 24 | import os 25 | try: 26 | from pymodis import optparse_gui 27 | WXPYTHON = True 28 | except: 29 | WXPYTHON = False 30 | from pymodis import optparse_required 31 | from pymodis import qualitymodis 32 | 33 | 34 | def main(): 35 | """Main function""" 36 | # usage 37 | usage = "usage: %prog [options] input_file" 38 | if 1 == len(sys.argv) and WXPYTHON: 39 | option_parser_class = optparse_gui.OptionParser 40 | else: 41 | option_parser_class = optparse_required.OptionParser 42 | 43 | parser = option_parser_class(usage=usage, description='modis_quality') 44 | 45 | parser.add_option("-o", "--output", dest="output", required=True, 46 | help="the prefix of output file", metavar="OUTPUT_FILE") 47 | # type 48 | parser.add_option("-t", "--type", dest="type", default="1", 49 | help="quality type either as number or name (e.g. 1 or " 50 | "VIQuality for MOD13 products) [default=%default]") 51 | # quality layer 52 | parser.add_option("-l", "--qualitylayer", dest="layer", default="1", 53 | help="quality layer of the dataset, dependent on the " 54 | "used MODIS product. (e.g. 1 or QC_Day for the " 55 | "Daytime QC Layer of MOD11) [default=%default]") 56 | 57 | # quality layer 58 | parser.add_option("-p", "--producttype", dest="product", default="MOD13Q1", 59 | help="quality layer of the dataset, dependent on the " 60 | "used MODIS product. (e.g. 1 or QC_Day for the " 61 | "Daytime QC Layer of MOD11) [default=%default]") 62 | # return options and argument 63 | (options, args) = parser.parse_args() 64 | if len(args) == 0 and not WXPYTHON: 65 | parser.print_help() 66 | sys.exit(1) 67 | if len(args) > 1: 68 | parser.error("You have to define the name of HDF file.") 69 | if not os.path.isfile(args[0]): 70 | parser.error("You have to define the name of HDF file.") 71 | # set modis object 72 | modisQuality = qualitymodis.QualityModis(args[0], options.output, 73 | qType=options.type, 74 | qLayer=options.layer, 75 | pType=options.product) 76 | # run 77 | modisQuality.run() 78 | 79 | if __name__ == "__main__": 80 | main() 81 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # class to download modis data 4 | # 5 | # (c) Copyright Luca Delucchi 2010-2016 6 | # Authors: Luca Delucchi 7 | # Email: luca dot delucchi at fmach dot it 8 | # 9 | ################################################################## 10 | # 11 | # The Modis class is licensed under the terms of GNU GPL 2 12 | # This program is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU General Public License as 14 | # published by the Free Software Foundation; either version 2 of 15 | # the License, or (at your option) any later version. 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | # See the GNU General Public License for more details. 20 | # 21 | ################################################################## 22 | 23 | import os 24 | import re 25 | try: 26 | from setuptools import setup 27 | except: 28 | from distutils.core import setup 29 | import sys 30 | 31 | HERE = os.path.abspath(os.path.dirname(__file__)) 32 | if sys.version_info.major == 3: 33 | with open(os.path.join(HERE, 'README.rst'), encoding='utf-8') as f: 34 | README = f.read() 35 | with open(os.path.join(HERE, 'pymodis', '__init__.py'), encoding='utf-8') as fp: 36 | VERSION = re.search("__version__ = '([^']+)'", fp.read()).group(1) 37 | else: 38 | with open(os.path.join(HERE, 'README.rst')) as f: 39 | README = f.read() 40 | with open(os.path.join(HERE, 'pymodis', '__init__.py')) as fp: 41 | VERSION = re.search("__version__ = '([^']+)'", fp.read()).group(1) 42 | 43 | install_requires = ['numpy', 'future', 'requests'] 44 | try: 45 | # Support GDAL alternatives (eg. pygdal) 46 | from osgeo import gdal 47 | except ImportError: 48 | install_requires += ['GDAL'] 49 | 50 | setup( 51 | name='pyModis', 52 | version=VERSION, 53 | py_modules=['pymodis.downmodis', 'pymodis.convertmodis', 54 | 'pymodis.parsemodis', 'pymodis.optparse_required', 55 | 'pymodis.optparse_gui', 'pymodis.qualitymodis', 56 | 'pymodis.convertmodis_gdal', 'pymodis.productmodis'], 57 | #packages = ['pymodis'], 58 | scripts=['scripts/modis_download.py', 'scripts/modis_multiparse.py', 59 | 'scripts/modis_parse.py', 'scripts/modis_mosaic.py', 60 | 'scripts/modis_convert.py', 'scripts/modis_quality.py', 61 | 'scripts/modis_download_from_list.py', 'scripts/modis_check.py'], 62 | author='Luca Delucchi', 63 | author_email='luca.delucchi@fmach.it', 64 | url='http://www.pymodis.org', 65 | project_urls={'Source': 'https://github.com/lucadelu/pyModis/', 66 | 'Tracker': 'https://github.com/lucadelu/pyModis/issues'}, 67 | description='Python library for MODIS data', 68 | long_description=README, 69 | install_requires=install_requires, 70 | extras_require={'GUI': ["wxPython", "wxPython-common"]}, 71 | license='GNU GPL 2 or later', 72 | platforms=['Any'], 73 | classifiers=[ 74 | "Development Status :: 5 - Production/Stable", 75 | "Environment :: Console", 76 | "Topic :: Scientific/Engineering :: GIS", 77 | "Intended Audience :: End Users/Desktop", 78 | "Intended Audience :: Developers", 79 | "Operating System :: MacOS :: MacOS X", 80 | "Operating System :: Microsoft :: Windows", 81 | "Operating System :: POSIX", 82 | "Programming Language :: Python :: 2.7", 83 | "Programming Language :: Python :: 3", 84 | "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", 85 | ], 86 | ) 87 | --------------------------------------------------------------------------------