• Анализ 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 мне был более удобен. Поэтому я использовал его. Anaconda Navigator

    2. Возникла трудность при установке необходимых библиотек. Почему-то в нативной папке roots некоторые библиотеки не хотели ставится. Проблему решил тем, что в Environments cделал отдельную категорию под Spyder. И именно в этой директории я делал последующую работу.

    3. Необходимые библиотеки, которые были нужны: netCDF4; numpy; pandas; Basemap.
    Их необходимо загрузить заранее также через стандартное средство Anaconda Navigator для загрузки библиотек.

    4. После установки библиотек мы создаем новый проект и там необходимо ввести такой код:
     
     
    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 (зеленая стрелка в панели инструментов наверху), в Консоли (правое нижнее окошко) будет выведено сообщение зеленым цветом, свидетельствующее о том, что все прошло успешно.
    Spyder_Code

    В противном случае, будет выдана ошибка красного цвета, которая, скорее всего, будет говорить о том, что какой-то библиотеки не хватает.

    5. Далее мы должны подготовить данные для комфортного открытия netCDF4, который содержит данные по NO2.
    первым делом в системе необходимо создать директорию, где будут хранится все наши данные, в том числе и сам netCDF4.
    Например, мои данные расположены по пути E:\Python\remote sensing\NO2\Astra. Там будут храниться и сами файлы Python, так и наш netCDF4.

    Теперь необходимо сказать Spyder о том, где брать наши данные. Для этого в верхнем левом углу есть специальное окошко для файлового менеджера. Путь к вашим данным задается через специальную кнопку, которая отображается в виде папки.
    например, на моем компьютере это выглядит так. Как видно, все отображается корректно.
    Spyder_Code_File_Manager

    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. Далее рекомендуется перезапустить ядро. Общий вид нашей рабочей области теперь должен выглядеть так:
    Spyder_Codding

    После этого можно приступить к запуску кода. Обратите внимание, что в консоли высветится надпись на русском языке:
    Вы действительно хотите начать работу с файлом (файлами) ... .

    А затем в скобках (Д/Н).

    Spyder_Codding2

    Мы, соответственно, нажимаем на клавиатуре русскую букву «Д» и жмем клавишу 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'
    ...
     
    

    S5P NO2_Data

    Таким образом, мы подготовили необходимые данные и положения, открыли netCDF4 файл средствами исключительно Python. На этом 1 часть настоящей статьи заканчивается. Продолжение анализа данных приведено во
    второй части .


    Прилагаю все необходимые файлы .py для удобства работы: Data_NO2.zip.

    TROPOMI-файл Вы можете скачать, по сути, любой. Они есть на официальном сайт Европейского Космического Агенства. Однако для удобства прилагаю файл, с которым работал я: Файл S5P_Tropomi_NO2.

    Опубликовано · Автор