{"id":18410277,"url":"https://github.com/earthobservations/phenodata","last_synced_at":"2026-02-07T14:05:01.924Z","repository":{"id":43288675,"uuid":"124856422","full_name":"earthobservations/phenodata","owner":"earthobservations","description":"An acquisition and processing toolkit for open access phenology data.","archived":false,"fork":false,"pushed_at":"2025-08-01T03:29:35.000Z","size":267,"stargazers_count":24,"open_issues_count":17,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-18T07:00:05.753Z","etag":null,"topics":["biology","cdc","data","dwd","dwd-ftp","earth-observation","earth-observations","earthobservation","open-data","opendata","phenological-metrics","phenology","phenology-data","phenology-modelling","phenology-models","phenometrics","plant","research","research-data","research-tool"],"latest_commit_sha":null,"homepage":"https://phenodata.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/earthobservations.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-03-12T08:22:37.000Z","updated_at":"2025-08-27T12:16:02.000Z","dependencies_parsed_at":"2025-04-12T09:26:52.445Z","dependency_job_id":null,"html_url":"https://github.com/earthobservations/phenodata","commit_stats":{"total_commits":192,"total_committers":4,"mean_commits":48.0,"dds":"0.25520833333333337","last_synced_commit":"cbddfd6972b3a1dc50a68c2e8b5ed00a1f8749aa"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/earthobservations/phenodata","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthobservations%2Fphenodata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthobservations%2Fphenodata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthobservations%2Fphenodata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthobservations%2Fphenodata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/earthobservations","download_url":"https://codeload.github.com/earthobservations/phenodata/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthobservations%2Fphenodata/sbom","scorecard":{"id":363880,"data":{"date":"2025-08-11","repo":{"name":"github.com/earthobservations/phenodata","commit":"cbddfd6972b3a1dc50a68c2e8b5ed00a1f8749aa"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/8 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/earthobservations/phenodata/tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/earthobservations/phenodata/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/earthobservations/phenodata/tests.yml/main?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU Affero General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2019-182 / GHSA-8867-vpm3-g98g","Warn: Project is vulnerable to: PYSEC-2012-8 / GHSA-p3h7-3c45-qj4v","Warn: Project is vulnerable to: PYSEC-2019-181 / GHSA-p86x-652p-6385"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T11:25:53.087Z","repository_id":43288675,"created_at":"2025-08-18T11:25:53.087Z","updated_at":"2025-08-18T11:25:53.087Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278457274,"owners_count":25989952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["biology","cdc","data","dwd","dwd-ftp","earth-observation","earth-observations","earthobservation","open-data","opendata","phenological-metrics","phenology","phenology-data","phenology-modelling","phenology-models","phenometrics","plant","research","research-data","research-tool"],"created_at":"2024-11-06T03:30:26.467Z","updated_at":"2026-02-07T14:05:01.907Z","avatar_url":"https://github.com/earthobservations.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"#########\nphenodata\n#########\n\n*Phenology data acquisition for humans.*\n\n`Documentation \u003chttps://phenodata.readthedocs.io\u003e`_\n| `Issues \u003chttps://github.com/earthobservations/phenodata/issues\u003e`_\n| `Changelog \u003chttps://github.com/earthobservations/phenodata/blob/main/CHANGES.rst\u003e`_\n| `PyPI \u003chttps://pypi.org/project/phenodata/\u003e`_\n| `Source code \u003chttps://github.com/earthobservations/phenodata\u003e`_\n\n.. image:: https://github.com/earthobservations/phenodata/actions/workflows/tests.yml/badge.svg\n    :target: https://github.com/earthobservations/phenodata/actions?workflow=Tests\n\n.. image:: https://readthedocs.org/projects/phenodata/badge/\n    :target: https://phenodata.readthedocs.io/\n\n.. image:: https://codecov.io/gh/earthobservations/phenodata/branch/main/graph/badge.svg\n    :target: https://codecov.io/gh/earthobservations/phenodata\n\n.. image:: https://static.pepy.tech/badge/phenodata/month\n    :target: https://pepy.tech/project/phenodata\n\n.. image:: https://img.shields.io/pypi/pyversions/phenodata.svg\n    :target: https://pypi.org/project/phenodata/\n\n.. image:: https://img.shields.io/pypi/v/phenodata.svg\n    :target: https://pypi.org/project/phenodata/\n\n.. image:: https://img.shields.io/pypi/l/phenodata.svg\n    :target: https://pypi.org/project/phenodata/\n\n\n*****\nAbout\n*****\n\nPhenodata is an acquisition and processing toolkit for open access phenology\ndata. It is based on `pandas`_, and can be used both as a standalone program,\nand as a library.\n\nCurrently, it implements data wrappers for acquiring phenology observation\ndata published on the DWD Climate Data Center (CDC) FTP server operated by\n»Deutscher Wetterdienst« (DWD). Adding adapters for other phenology databases\nand APIs is possible and welcome.\n\nAcknowledgements\n================\n\nThanks to the many observers of »Deutscher Wetterdienst« (DWD), the »Global\nPhenological Monitoring programme« (GPM), and all people working behind the\nscenes for their commitment on recording observations and making the excellent\ndatasets available to the community. You know who you are.\n\nNotes\n=====\n\nPlease note that phenodata is beta-quality software, and a work in progress.\nContributions of all kinds are welcome, in order to make it more solid.\n\nBreaking changes should be expected until a 1.0 release, so version pinning\nis recommended, especially when you use phenodata as a library.\n\n\n\n********\nSynopsis\n********\n\nThe easiest way to explore both phenodata and the dataset interactively, is to\nuse the command-line interface.\n\nThose two examples will acquire observation data from DWD's network, only focus\non the \"beginning of flowering\" phase event, and present the results in tabular\nformat using values suitable for human consumption.\n\nAcquire data from DWD's \"immediate\" dataset (Sofortmelder).\n\n.. code-block:: bash\n\n    phenodata observations \\\n        --source=dwd --dataset=immediate --partition=recent \\\n        --year=2023 --station=brandenburg \\\n        --species-preset=mellifera-de-primary \\\n        --phase=\"beginning of flowering\" \\\n        --humanize --sort=Datum --format=rst\n\nAcquire data from DWD's \"annual\" dataset (Jahresmelder).\n\n.. code-block:: bash\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --year=\"2022,2023\" --station=berlin \\\n        --species-preset=mellifera-de-primary \\\n        --phase=\"beginning of flowering\" \\\n        --humanize --sort=Datum --format=rst\n\n.. tip::\n\n    The authors recommend to copy one of those snippets into a file and invoke it\n    as a script program, in order to make subsequent invocations easier while\n    editing and exploring different option values. If you discover a bug, or want\n    to make your program available to others because you think it is useful, feel\n    free to `share it back with us`_.\n\nOutput example\n==============\n\nPhenodata can produce output in different formats. This is a table in\n`reStructuredText`_ format.\n\n==========  ======================  ======================  =====================\nDatum       Spezies                 Phase                   Station\n==========  ======================  ======================  =====================\n2018-02-17  common snowdrop         beginning of flowering  Berlin-Dahlem, Berlin\n2018-02-19  common hazel            beginning of flowering  Berlin-Dahlem, Berlin\n2018-03-30  goat willow             beginning of flowering  Berlin-Dahlem, Berlin\n2018-04-07  dandelion               beginning of flowering  Berlin-Dahlem, Berlin\n2018-04-15  cherry (late ripeness)  beginning of flowering  Berlin-Dahlem, Berlin\n2018-04-21  winter oilseed rape     beginning of flowering  Berlin-Dahlem, Berlin\n2018-04-23  apple (early ripeness)  beginning of flowering  Berlin-Dahlem, Berlin\n2018-05-03  apple (late ripeness)   beginning of flowering  Berlin-Dahlem, Berlin\n2018-05-24  black locust            beginning of flowering  Berlin-Dahlem, Berlin\n2018-08-20  common heather          beginning of flowering  Berlin-Dahlem, Berlin\n==========  ======================  ======================  =====================\n\n.. note::\n\n    Using the example snippet provided above, the program rendered a table in\n    `reStructuredText`_ format using ``--format=rst``. In order to render\n    tables in `Markdown`_ format, use ``--format=md``. For more tabular output\n    formats, use ``--format=tabular:foo``, and consult the documentation of the\n    `tabulate`_ package for choices of ``foo``.\n\n\n*****\nUsage\n*****\n\nIntroduction\n============\n\nFor most acquisition tasks, you will have to select one of two different\ndatasets of DWD, `annual-reporters`_ or `immediate-reporters`_. Further, the\ndata partition has to be selected, it is either ``recent``, or ``historical``.\n\nCurrently, as of 2023, the ``historical`` datasets extend from the past until\n2021. All subsequent observations are stored within the ``recent`` dataset\npartition.\n\nThe DWD publishes data in files separated by species, this means each plant's\ndata will be in a different file. By default, phenodata will acquire data for\nall species (plants), in order to be able to respond to all kinds of queries\nacross the whole dataset.\n\nIf you are only interested in a limited set of species (plants), you can\nimprove data acquisition performance by using the ``filename`` option to only\nselect specific files for retrieval.\n\nFor example, when using ``--filename=Hasel,Schneegloeckchen``, only file names\ncontaining ``Hasel`` or ``Schneegloeckchen`` will be retrieved, thus minimizing\nthe effort needed to acquire *all* files.\n\nInstall\n=======\n\nTo install the software from PyPI, invoke::\n\n    pip install 'phenodata[sql]' --upgrade\n\n.. note::\n\n    Please refer to the `virtualenv`_ page about best-practice recommendations to\n    install the software separate from your system environment.\n\nLibrary use\n===========\n\nThis snippet demonstrates how to use phenodata as a library within individual\nprograms. For ready-to-run code examples, please have a look into the `examples\ndirectory`_.\n\n.. hidden\n\n    .. code-block:: python\n\n        \u003e\u003e\u003e import os\n        \u003e\u003e\u003e import pytest\n        \u003e\u003e\u003e if \"GITHUB_ACTION\" in os.environ:\n        ...     pytest.skip(\"pytest-doctest-ellipsis-markers does not work on CI/GHA. Works on macOS though.\", allow_module_level=True)\n\n.. code-block:: python\n\n    \u003e\u003e\u003e import pandas as pd\n    \u003e\u003e\u003e from phenodata.ftp import FTPSession\n    \u003e\u003e\u003e from phenodata.dwd.cdc import DwdCdcClient\n    \u003e\u003e\u003e from phenodata.dwd.pheno import DwdPhenoDataClient\n\n    \u003e\u003e\u003e cdc_client = DwdCdcClient(ftp=FTPSession())\n    \u003e\u003e\u003e client = DwdPhenoDataClient(cdc=cdc_client, dataset=\"immediate\")\n    \u003e\u003e\u003e options = {\n    ...     # Select data partition.\n    ...     \"partition\": \"recent\",\n    ...\n    ...     # Filter by file names and years.\n    ...     \"filename\": [\"Hasel\", \"Raps\", \"Mais\"],\n    ...     \"year\": [2018, 2019, 2020],\n    ...\n    ...     # Filter by station identifier.\n    ...     \"station-id\": [13346]\n    ... }\n\n    \u003e\u003e\u003e observations: pd.DataFrame = client.get_observations(options)\n    \u003e\u003e\u003e observations.info()\n    [...]\n    \u003e\u003e\u003e observations\n    [...]\n\n\nCommand-line use\n================\n\nThis section gives you an idea about how to use the ``phenodata`` program on\nthe command-line.\n\n::\n\n    $ phenodata --help\n\n    Usage:\n      phenodata info\n      phenodata list-species --source=dwd [--format=csv]\n      phenodata list-phases --source=dwd [--format=csv]\n      phenodata list-stations --source=dwd --dataset=immediate [--all] [--filter=berlin] [--sort=Stationsname] [--format=csv]\n      phenodata nearest-station --source=dwd --dataset=immediate --latitude=52.520007 --longitude=13.404954 [--format=csv]\n      phenodata nearest-stations --source=dwd --dataset=immediate --latitude=52.520007 --longitude=13.404954 [--all] [--limit=10] [--format=csv]\n      phenodata list-quality-levels --source=dwd [--format=csv]\n      phenodata list-quality-bytes --source=dwd [--format=csv]\n      phenodata list-filenames --source=dwd --dataset=immediate --partition=recent [--filename=Hasel,Schneegloeckchen] [--year=2017]\n      phenodata list-urls --source=dwd --dataset=immediate --partition=recent [--filename=Hasel,Schneegloeckchen] [--year=2017]\n      phenodata (observations|forecast) --source=dwd --dataset=immediate --partition=recent [--filename=Hasel,Schneegloeckchen] [--station-id=164,717] [--species-id=113,127] [--phase-id=5] [--quality-level=10] [--quality-byte=1,2,3] [--station=berlin,brandenburg] [--species=hazel,snowdrop] [--species-preset=mellifera-de-primary] [--phase=flowering] [--quality=ROUTKLI] [--year=2017] [--forecast-year=2021] [--humanize] [--show-ids] [--language=german] [--long-station] [--sort=Datum] [--sql=sql] [--format=csv] [--verbose]\n      phenodata drop-cache --source=dwd\n      phenodata --version\n      phenodata (-h | --help)\n\n    Data acquisition options:\n      --source=\u003csource\u003e         Data source. Currently, only \"dwd\" is a valid identifier.\n      --dataset=\u003cdataset\u003e       Data set. Use \"immediate\" or \"annual\" for \"--source=dwd\".\n      --partition=\u003cdataset\u003e     Partition. Use \"recent\" or \"historical\" for \"--source=dwd\".\n      --filename=\u003cfile\u003e         Filter by file names (comma-separated list)\n\n    Direct filtering options:\n      --year=\u003cyear\u003e             Filter by year (comma-separated list)\n      --station-id=\u003cstation-id\u003e Filter by station identifiers (comma-separated list)\n      --species-id=\u003cspecies-id\u003e Filter by species identifiers (comma-separated list)\n      --phase-id=\u003cphase-id\u003e     Filter by phase identifiers (comma-separated list)\n\n    Humanized filtering options:\n      --station=\u003cstation\u003e       Filter by strings from \"stations\" data (comma-separated list)\n      --species=\u003cspecies\u003e       Filter by strings from \"species\" data (comma-separated list)\n      --phase=\u003cphase\u003e           Filter by strings from \"phases\" data (comma-separated list)\n      --species-preset=\u003cpreset\u003e Filter by strings from \"species\" data (comma-separated list)\n                                The preset will get loaded from the \"presets.json\" file.\n\n    Forecasting options:\n      --forecast-year=\u003cyear\u003e    Use as designated forecast year.\n\n    Postprocess filtering options:\n      --sql=\u003csql\u003e               Apply given SQL query before output.\n\n    Data output options:\n      --format=\u003cformat\u003e         Output data in designated format. Choose one of \"tabular\", \"json\",\n                                \"csv\", or \"string\". Use \"md\" for Markdown output, or \"rst\" for\n                                reStructuredText. With \"tabular:foo\", it is also possible to specify\n                                other tabular output formats.  [default: tabular:psql]\n      --sort=\u003csort\u003e             Sort by given field names. (comma-separated list)\n      --humanize                Resolve identifier-based fields to human-readable labels.\n      --show-ids                Show identifiers alongside resolved labels, when using \"--humanize\".\n      --language=\u003clanguage\u003e     Use labels in designated language, when using \"--humanize\"\n                                [default: english].\n      --long-station            Use long station name including \"Naturraumgruppe\" and \"Naturraum\".\n      --limit=\u003climit\u003e           Limit output of \"nearest-stations\" to designated number of entries.\n                                [default: 10]\n      --verbose                 Turn on verbose output.\n\n\n********\nExamples\n********\n\nThe best way to explore phenodata is by running a few example invocations.\n\n- The \"Metadata\" section will walk you through different commands which can be\n  used to inquire information about monitoring stations/sites, and to list\n  the actual files which will be acquired, in order to learn about data lineage.\n\n- The \"Observations\" section will demonstrate command examples to acquire,\n  process, and format actual observation data.\n\n\nMetadata\n========\n\nDisplay list of species, with their German, English, and Latin names::\n\n    phenodata list-species --source=dwd\n\nDisplay list of phases, with their German and English names::\n\n    phenodata list-phases --source=dwd\n\nList of all reporting/monitoring stations::\n\n    phenodata list-stations --source=dwd --dataset=immediate\n\nList of stations, with filtering::\n\n    phenodata list-stations --source=dwd --dataset=annual --filter=\"Fränkische Alb\"\n\nDisplay nearest station for given position::\n\n    phenodata nearest-station --source=dwd --dataset=immediate \\\n        --latitude=52.520007 --longitude=13.404954\n\nDisplay 20 nearest stations for given position::\n\n    phenodata nearest-stations \\\n        --source=dwd --dataset=immediate \\\n        --latitude=52.520007 --longitude=13.404954 --limit=20\n\nList of file names of recent observations by the annual reporters::\n\n    phenodata list-filenames \\\n        --source=dwd --dataset=annual --partition=recent\n\nSame as above, but with filtering by file name::\n\n    phenodata list-filenames \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --filename=Hasel,Kornelkirsche,Loewenzahn,Schneegloeckchen\n\nList full URLs instead of only file names::\n\n    phenodata list-urls \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --filename=Hasel,Kornelkirsche,Loewenzahn,Schneegloeckchen\n\n\nObservations\n============\n\nBasic\n-----\n\nObservations of hazel and snowdrop, using filename-based filtering at data acquisition time::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --filename=Hasel,Schneegloeckchen\n\nObservations of hazel and snowdrop (dito), but for specific station identifiers::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --filename=Hasel,Schneegloeckchen --station-id=7521,7532\n\nAll observations for specific station identifiers and specific years::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --station-id=7521,7532 --year=2020,2021\n\nAll observations for specific station and species identifiers::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --station-id=7521,7532 --species-id=113,127\n\nAll observations marked as invalid::\n\n    phenodata list-quality-bytes --source=dwd\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --quality-byte=5,6,7,8\n\n\nHumanized output\n----------------\n\nThe option ``--humanize`` will improve textual output by resolving identifier\nfields to appropriate human-readable text labels.\n\nObservations for species \"hazel\", \"snowdrop\", \"apple\" and \"pear\" at station\n\"Berlin-Dahlem\", output texts in the German language, if possible::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --filename=Hasel,Schneegloeckchen,Apfel,Birne \\\n        --station-id=12132 \\\n        --humanize \\\n        --language=german\n\n\nHumanized search\n----------------\n\nWhen using the ``--humanize`` option, you can use the non-identifier-based\nfiltering options ``--station``, ``--species``, and ``--phase``, to use\nhuman-readable text labels for filtering instead of numeric identifiers.\n\nQuery observations by using real-world location names::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --filename=Hasel,Schneegloeckchen \\\n        --station=berlin,brandenburg \\\n        --humanize --sort=Datum\n\nQuery observations near Munich with species names \"hazel\" and \"snowdrop\" in specific year::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --station=münchen \\\n        --species=hazel,snowdrop \\\n        --year=2022 \\\n        --humanize --sort=Datum\n\nNow, let's query for any \"flowering\" observations. There will be ``beginning\nof flowering``, ``general flowering``, and ``end of flowering``::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --station=münchen \\\n        --phase=flowering \\\n        --year=2022 \\\n        --humanize --sort=Datum\n\nSame observations as before but with ``ROUTKLI`` quality marker::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --station=münchen \\\n        --phase=flowering \\\n        --quality=\"nicht beanstandet\" \\\n        --year=2022 \\\n        --humanize --sort=Datum\n\nNow, let's inquire those field values which have seen corrections instead\n(``Feldwert korrigiert``)::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --station=münchen \\\n        --phase=flowering \\\n        --quality=korrigiert \\\n        --humanize --sort=Datum\n\n\nFiltering with presets\n----------------------\n\nWhen using the ``--humanize`` option, you can also use pre-defined shortcuts\nfor lists of species by name. For example, the ``mellifera-de-primary`` preset\nis defined within the `presets.json`_ file like::\n\n    Hasel, Schneeglöckchen, Sal-Weide, Löwenzahn, Süßkirsche, Apfel, Winterraps, Robinie, Winter-Linde, Heidekraut\n\nThen, you can use the option ``--species-preset=mellifera-de-primary`` instead\nof the ``--species`` option for filtering only those specified species.\n\nThis example lists all \"beginning of flowering\" observations for the specified\nyears in Köln, only for the named list of species ``mellifera-de-primary``.\nThe result will be sorted by species and date, and human-readable labels will\nbe displayed in German, when possible::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --phase=\"beginning of flowering\" \\\n        --year=2021,2022,2023 \\\n        --station=köln \\\n        --species-preset=mellifera-de-primary \\\n        --humanize --language=german --sort=Spezies,Datum\n\n.. note::\n\n    Contributions are welcome to introduce other groups of species which fit\n    into different phenology domains or use-case categories.\n\n\nFiltering with SQL\n------------------\n\nPhenodata uses the `DuckDB Python API`_ to let you directly query the `pandas`_\nDataFrame produced by the data acquisition subsystem. This example uses an SQL\nstatement to filter the results by station name, and sort them by date::\n\n    phenodata observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --year=2019,2020,2021,2022,2023 \\\n        --species-preset=mellifera-de-primary --phase=\"beginning of flowering\" \\\n        --humanize --language=german \\\n        --sql=\"SELECT * FROM data WHERE Station LIKE '%Berlin%' ORDER BY Datum\" \\\n        --format=md\n\nData export\n===========\n\nYou can use the ``phenodata export-observation`` subcommand to export observations\nincluding metadata into an `SQLite`_ database.\n\n.. code-block:: bash\n\n    phenodata export-observations \\\n        --source=dwd --dataset=annual --partition=recent \\\n        --station=münchen \\\n        --year=2021,2022,2023 \\\n        --filename=Hasel \\\n        --target=sqlite:///phenodata-dwd-sample.sqlite\n\nTo get an idea about the data, run your first query.\n\n.. code-block:: bash\n\n    sqlite3 -csv -header phenodata-dwd-sample.sqlite 'SELECT * FROM dwd_phenology ORDER BY date;'\n\nPlease refer to the `SQLite database export`_ documentation about more details how\nto use that feature, and about what you can do with it.\n\n\n*******************\nProject information\n*******************\n\nResources\n=========\n- `Source code \u003chttps://github.com/earthobservations/phenodata\u003e`_\n- `Documentation \u003chttps://phenodata.readthedocs.io/\u003e`_\n- `Python Package Index (PyPI) \u003chttps://pypi.org/project/phenodata/\u003e`_\n\nContributions\n=============\nIf you would like to contribute, you are most welcome. Spend some time taking a\nlook around, locate a bug, design issue or spelling mistake and then send us a\npull request or create an issue. Thank you in advance for your efforts, the\nauthors really appreciate any kind of help and feedback.\n\nDiscussions\n===========\nDiscussions around the development of phenodata and its applications are\ntaking place at the Hiveeyes forum. Enjoy reading them, and don't hesitate to\nwrite in, if you think you may be able to contribute a thing or another, or\nto share what you have been doing with the program in form of a \"show and tell\"\npost.\n\n- https://community.hiveeyes.org/t/phanologischer-kalender-fur-trachtpflanzen/664\n- https://community.hiveeyes.org/t/phenodata-ein-toolkit-zur-beschaffung-und-verarbeitung-von-open-access-phanologiedaten/2892\n- https://community.hiveeyes.org/t/phanologischer-kalender-2020/2893\n- https://community.hiveeyes.org/t/klimadatenkalender-zur-anzeige-der-phanologischen-daten-des-deutschen-wetterdienstes/948\n- https://community.hiveeyes.org/t/phanologie-und-imkerliche-eingriffe-bei-den-bienen/705\n- https://community.hiveeyes.org/t/phenological-calendar-for-france/800\n\nDevelopment\n===========\nIn order to setup a development environment on your workstation, please head\nover to the `development sandbox`_ documentation. When you see the software\ntests succeed, you should be ready to start hacking.\n\nCode license\n============\nThe project is licensed under the terms of the GNU AGPL license, see `LICENSE`_.\n\nData license\n============\nThe DWD has information about their data re-use policy in German and English.\nPlease refer to the respective Disclaimer\n(`de \u003chttps://www.dwd.de/DE/service/disclaimer/disclaimer_node.html\u003e`__,\n`en \u003chttps://www.dwd.de/EN/service/disclaimer/disclaimer.html\u003e`__)\nand Copyright\n(`de \u003chttps://www.dwd.de/DE/service/copyright/copyright_node.html\u003e`__,\n`en \u003chttps://www.dwd.de/EN/service/copyright/copyright_artikel.html\u003e`__)\ninformation.\n\nDisclaimer\n==========\nThe project and its authors are not affiliated with DWD, GPM, USA-NPN, or any\nother organization in any way. It is a sole project conceived by the community,\nin order to make data more accessible, in the spirit of `open data`_ and `open\nscientific data`_. The authors believe the world would be a better place if\npublic data could be loaded into `pandas`_ dataframes and `Xarray`_ datasets\neasily.\n\n\n.. _annual-reporters: https://www.dwd.de/DE/klimaumwelt/klimaueberwachung/phaenologie/daten_deutschland/jahresmelder/jahresmelder_node.html\n.. _development sandbox: doc/development.rst\n.. _DuckDB Python API: https://duckdb.org/docs/api/python/overview\n.. _examples directory: https://github.com/earthobservations/phenodata/tree/main/examples\n.. _immediate-reporters: https://www.dwd.de/DE/klimaumwelt/klimaueberwachung/phaenologie/daten_deutschland/sofortmelder/sofortmelder_node.html\n.. _LICENSE: https://github.com/earthobservations/phenodata/blob/main/LICENSE\n.. _Markdown: https://en.wikipedia.org/wiki/Markdown\n.. _open data: https://en.wikipedia.org/wiki/Open_data\n.. _open scientific data: https://en.wikipedia.org/wiki/Open_scientific_data\n.. _pandas: https://pandas.pydata.org/\n.. _presets.json: https://github.com/earthobservations/phenodata/blob/main/phenodata/dwd/presets.json\n.. _reStructuredText: https://en.wikipedia.org/wiki/ReStructuredText\n.. _share it back with us: https://github.com/earthobservations/phenodata/discussions/new?category=show-and-tell\n.. _SQLite: https://sqlite.org/\n.. _SQLite database export: https://phenodata.readthedocs.io/en/latest/export/sqlite.html\n.. _tabulate: https://github.com/astanin/python-tabulate\n.. _virtualenv: https://github.com/earthobservations/phenodata/blob/main/doc/virtualenv.rst\n.. _Xarray: https://xarray.dev/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearthobservations%2Fphenodata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fearthobservations%2Fphenodata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearthobservations%2Fphenodata/lists"}