Анализ NO2 c помощью Python. Часть 1.
Начало истории о том, как появилось желание попробовать провести анализ данных ДЗЗ для оценки NO2 только на основе Python. Описаны подготовительные работы с netCDF4 в среде Spyder, а также дана некоторая теоретическая информация про netCDF. Все необходимые лист-коды, а также сам файл netCDF4 для работы приведены в конце статьи.
Как-то раз, когда у нас в России началась ситуация самоизоляции из-за COVID-19, на просторах ВКонтакте часто мне попадалась анимация из нескольких космических снимков, показывающих состояние воздуха над городом Ухань после его изолирования. Затем стали появляться похожие данные и для других территорий. Мне стало интересно, как это можно создать, да и вообще какие данные могут подойти для этого. Когда один из знакомых студентов спросил у меня, нет ли у меня актуальных данных по поводу содержания различных газов в Астраханской области, мой интерес стал еще больше, ведь просто и быстро прямые результаты получить не получится. Тут я еще больше задумался по поводу того, как могут помочь данные ДЗЗ. Итак, начать необходимо с того, что на момент написания данных слов и данный момент (скорее всего, этот момент связан с уровнем моего развития) наиболее перспективным решением является применение данных аппарата Sentinel-5. Поглядев просторы интернета не один час и день, я бросил себе вызов мало-мальски разобраться в вопросах как данные открыть, как данные обработать именно с языком программирования, потому что чтение книжек и решение однотипных задач мне порядком надоело, а реально разбираться в языке и что-то делать на языке конкретное я так и не приступал. Поэтому все, что будет описано ниже носило исключительно образовательный характер. Мне был интересен сам принцип того, как можно получить данные, как их обработать именно в программной среде. Я не буду тут (по крайней мере именно в этой статье) писать о том, что из себя представляет данный аппарат и его необходимая нам аппаратура TROPOMI. Вся информация в удобном виде есть тут.
Плюс на сайте Европейского космического агентства как всегда тонны документалки. Поэтому опишу непосредственно процесс того, как непосредственно я попытался что-то сделать интересное в Python и с данными TROPOMI.
1. Я вспомнил о запылившемся на моем ноутбуке Anaconda Navigator и доступной там IDE для научных расчетов Spyder. Я как-то было тыкался в стандартом IDLE, но посидев какое-то время над изучением R в среде RStudio, Spyder мне был более удобен. Поэтому я использовал его.
2. Возникла трудность при установке необходимых библиотек. Почему-то в нативной папке roots некоторые библиотеки не хотели ставится. Проблему решил тем, что в Environments cделал отдельную категорию под Spyder. И именно в этой директории я делал последующую работу.
3. Необходимые библиотеки, которые были нужны: netCDF4; numpy; pandas; Basemap
.
Их необходимо загрузить заранее также через стандартное средство Anaconda Navigator для загрузки библиотек.
from netCDF4
import Dataset
import numpy as np
from numpy import unravel_index
import sys
import time
import calendar
import datetime as dt
import pandas as pd
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
Как видно из приведенных библиотек, некоторые из специально созданы для работы с геопространственными данными и их визуализацией.
Например, netCDF4 модуль может читать и записывать файлы netCDF.
В свою очередь netCDF4 это такой двоичный формат файлов, являющийся стандартом для обмена научными данными. Он широко используется специалистами метеорологами и океанографами для хранения переменных, как, например, данных о температуре, давлении, скорости ветра и высоте волн.
Говоря более проще (по крайней мере, как я понял сам) netCDF4 – массивный по информативности документ, представляющий собой набор полезной информации. Он чем-то похож, например, на Sentinel 2 metadata file. Однако netCDF4 не несет за собой никаких графических файлов типа tiff или JPEG2000, сам netCDF4 уже содержит все необходимое как для анализа, так и для визуализации.
Eсли все будет сделано правильно, то после нажатия Run (зеленая стрелка в панели инструментов наверху), в Консоли (правое нижнее окошко) будет выведено сообщение зеленым цветом, свидетельствующее о том, что все прошло успешно.
В противном случае, будет выдана ошибка красного цвета, которая, скорее всего, будет говорить о том, что какой-то библиотеки не хватает.
5. Далее мы должны подготовить данные для комфортного открытия netCDF4, который содержит данные по NO2.
первым делом в системе необходимо создать директорию, где будут хранится все наши данные, в том числе и сам netCDF4.
Например, мои данные расположены по пути E:\Python\remote sensing\NO2\Astra
. Там будут храниться и сами файлы Python, так и наш netCDF4.
Теперь необходимо сказать Spyder о том, где брать наши данные. Для этого в верхнем левом углу есть специальное окошко для файлового менеджера. Путь к вашим данным задается через специальную кнопку, которая отображается в виде папки.
например, на моем компьютере это выглядит так. Как видно, все отображается корректно.
5. После того, как наша директория будет готова к работе, в нашем каталоге необходимо через обыкновенный Блокнот создать файловый документ fileList, где нужно будет прописать имя нашего файла.
У меня это было S5P_OFFL_L2__NO2____20190330T092200_20190330T110331_07562_01_010300_20190405T105720.nc
6. После того, как мы подготовили наши данные и директорию необходимо создать новый код:
def print_var_recursively(grp):
for varname in list(grp.variables.keys()):
var = grp.variables[varname]
dims = var.dimensions
if not („scanline“ in dims and „ground_pixel“ in dims and „time“ in dims):
continue
if „corner“ in dims or varname == „time_utc“:
continue
# print(dims[„time“])
# print(varname,dims)
print(var)
def ncdump(nc_fid, verb=True):
„“„
ncdump выводит размеры, переменные и иную атрибутивную информацию.
Параметры
—————
nc_fid : netCDF4.Dataset
A netCDF4 dateset object
verb : Boolean
whether or not nc_attrs, nc_dims, and nc_vars are printed
Показывает
———-
nc_attrs : список
Python список глобальных атрибутов файлов NetCDF
nc_dims : список
Python список размеров файлов NetCDF
nc_vars : список
Список файловых переменных NetCDF на Python.
„“„
def print_ncattr(key):
«»«
Печатает атрибуты файла NetCDF
«»«
try:
print («\t\ttype:», repr(nc_fid.variables[key].dtype))
for ncattr in nc_fid.variables[key].ncattrs():
print („\t\t%s:“ % ncattr,\
repr(nc_fid.variables[key].getncattr(ncattr)))
except KeyError:
print («\t\tWARNING: %s does not contain variable attributes» % key)
# NetCDF global attributes
nc_attrs = nc_fid.ncattrs()
if verb:
print («NetCDF Global Attributes:»)
for nc_attr in nc_attrs:
print („\t%s:“ % nc_attr, repr(nc_fid.getncattr(nc_attr)))
nc_dims = [dim for dim in nc_fid.dimensions] # list of nc dimensions
# Dimension shape information.
if verb:
print («NetCDF dimension information:»)
for dim in nc_dims:
print («\tName:», dim)
print («\t\tsize:», len(nc_fid.dimensions[dim]))
print_ncattr(dim)
# Variable information.
nc_vars = [var for var in nc_fid.variables] # list of nc variables
if verb:
print («NetCDF variable information:»)
for var in nc_vars:
if var not in nc_dims:
print („\tName:“, var)
print («\t\tdimensions:», nc_fid.variables[var].dimensions)
print («\t\tsize:», nc_fid.variables[var].size)
print_ncattr(var)
return nc_attrs, nc_dims, nc_vars
#——————————————————————————————————-
#импортируем важное
import netCDF4
from netCDF4 import Dataset
#Находим созданную директорию и наши nc файлы
try:
fileList=open(„fileList.txt“,„r“)
except:
print(„Текстовый файл не найден. Проверьте, возможно есть несовпадения“)
sys.exit()
#циклы по всем файлам
for FILE_NAME in fileList:
FILE_NAME=FILE_NAME.strip()
user_input=input(„\nВы действительно хотите начать работу с файлом (файлами)\n“ + FILE_NAME + „\n\n(Д/Н)“)
if(user_input 'Н' or user_input „н“):
print(„Skipping…“)
continue
else:
nc_file = Dataset(FILE_NAME, „r“) # „r“ means that nc file is open in read-only mode
nc_attrs,nc_dims,nc_vars = ncdump(nc_file)
print_var_recursively (nc_file.groups[„PRODUCT“])
nc_file.close()
Данный код представляет собой набор функций по выводу данных netCDF4
Обратим внимание на строку fileList=open('fileList.txt','r')
. Именно в ней задана команда открыть наш fileList файл.
7. Далее рекомендуется перезапустить ядро. Общий вид нашей рабочей области теперь должен выглядеть так:
После этого можно приступить к запуску кода. Обратите внимание, что в консоли высветится надпись на русском языке:
Вы действительно хотите начать работу с файлом (файлами) ...
.
А затем в скобках (Д/Н)
.
Мы, соответственно, нажимаем на клавиатуре русскую букву «Д» и жмем клавишу Enter.
В консоли появится вся доступная информация по нашему файлу, например,
...
source: 'Sentinel 5 precursor, TROPOMI, space-borne remote sensing, L2'
summary: 'TROPOMI/S5P NO2 1-Orbit L2 Swath 7x3.5km'
tracking_id: '1889dac3-0246-4bbd-9dfa-9942c80f1008'
id: 'S5P_OFFL_L2__NO2____20190330T092200_20190330T110331_07562_01_010300_20190405T105720'
time_reference: '2019-03-30T00:00:00Z'
time_reference_days_since_1950: 25290
time_reference_julian_day: 2458572.5
time_reference_seconds_since_1970: 1553904000
time_coverage_start: '2019-03-30T09:43:35Z'
time_coverage_end: '2019-03-30T10:41:58Z'
time_coverage_duration: 'PT3503.438S'
time_coverage_resolution: 'PT1.080S'
orbit: 7562
references: 'http://www.tropomi.eu/data-products/nitrogen-dioxide'
processor_version: '1.3.0'
...
Таким образом, мы подготовили необходимые данные и положения, открыли netCDF4 файл средствами исключительно Python. На этом 1 часть настоящей статьи заканчивается. Продолжение анализа данных приведено во
второй части .
Прилагаю все необходимые файлы .py для удобства работы: Data_NO2.zip.
TROPOMI-файл Вы можете скачать, по сути, любой. Они есть на официальном сайт Европейского Космического Агенства. Однако для удобства прилагаю файл, с которым работал я: Файл S5P_Tropomi_NO2.
Опубликовано · Автор Victor