{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Convert profiles vertical coordinate from Hybrid-Pressure to altitude" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:08.041895Z", "iopub.status.busy": "2025-01-13T11:35:08.040613Z", "iopub.status.idle": "2025-01-13T11:35:08.560516Z", "shell.execute_reply": "2025-01-13T11:35:08.560108Z" } }, "outputs": [], "source": [ "%matplotlib inline\n", "# for figures in notebook\n", "\n", "# import & initialize epygram\n", "import epygram\n", "epygram.init_env()\n", "\n", "import os\n", "INPUTS_DIR = os.path.join('..', 'inputs')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:08.562714Z", "iopub.status.busy": "2025-01-13T11:35:08.562501Z", "iopub.status.idle": "2025-01-13T11:35:08.697593Z", "shell.execute_reply": "2025-01-13T11:35:08.696937Z" } }, "outputs": [], "source": [ "r = epygram.resources.meta_resource(os.path.join(INPUTS_DIR, 'ICMSHAROM+0022'), 'r', 'CL') # CL = CombineLevels" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:08.700009Z", "iopub.status.busy": "2025-01-13T11:35:08.699731Z", "iopub.status.idle": "2025-01-13T11:35:08.702855Z", "shell.execute_reply": "2025-01-13T11:35:08.702513Z" } }, "outputs": [], "source": [ "# in a \"CL\" meta-resource, fields are to be grabbed through a GRIB2 nomenclature\n", "t_as_grib2 = dict(discipline=0, parameterCategory=0, parameterNumber=0, # this is temperature\n", " typeOfFirstFixedSurface=119) # hybrid-pressure levels" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:08.704231Z", "iopub.status.busy": "2025-01-13T11:35:08.704104Z", "iopub.status.idle": "2025-01-13T11:35:11.171718Z", "shell.execute_reply": "2025-01-13T11:35:11.171221Z" } }, "outputs": [], "source": [ "t3d = r.readfield(t_as_grib2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:11.173889Z", "iopub.status.busy": "2025-01-13T11:35:11.173664Z", "iopub.status.idle": "2025-01-13T11:35:11.292838Z", "shell.execute_reply": "2025-01-13T11:35:11.292379Z" } }, "outputs": [], "source": [ "t3d.sp2gp()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:11.294586Z", "iopub.status.busy": "2025-01-13T11:35:11.294433Z", "iopub.status.idle": "2025-01-13T11:35:11.306275Z", "shell.execute_reply": "2025-01-13T11:35:11.305851Z" } }, "outputs": [], "source": [ "# extract profiles\n", "profiles = []\n", "for position in [(6.1,46.2), (6.8,45.8), (6,46.5)]:\n", " profgeo = t3d.geometry.make_profile_geometry(*position) # make a V1D geometry at that position\n", " profiles.append(t3d.extract_subdomain(profgeo)) # extract subdomain corresponding to the geometry of the profile" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:11.307901Z", "iopub.status.busy": "2025-01-13T11:35:11.307693Z", "iopub.status.idle": "2025-01-13T11:35:11.690934Z", "shell.execute_reply": "2025-01-13T11:35:11.690320Z" } }, "outputs": [], "source": [ "fig = ax = None\n", "for p in profiles:\n", " fig, ax = p.plotfield(labels='Temperature @ ({}, {})'.format(p.geometry.grid['longitudes'][0],\n", " p.geometry.grid['latitudes'][0]),\n", " over=(fig, ax)) # superpose profiles" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## and now on an Altitude z-axis" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:11.692744Z", "iopub.status.busy": "2025-01-13T11:35:11.692612Z", "iopub.status.idle": "2025-01-13T11:35:12.054592Z", "shell.execute_reply": "2025-01-13T11:35:12.054042Z" } }, "outputs": [], "source": [ "# for the conversions, we need R and T profiles, so (at least) q and T\n", "q_as_grib2 = dict(discipline=0, parameterCategory=1, parameterNumber=0, # this is specific humidity\n", " typeOfFirstFixedSurface=119) # on hybrid-pressure levels\n", "q3d = r.readfield(q_as_grib2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:12.056671Z", "iopub.status.busy": "2025-01-13T11:35:12.056483Z", "iopub.status.idle": "2025-01-13T11:35:12.392355Z", "shell.execute_reply": "2025-01-13T11:35:12.391596Z" } }, "outputs": [], "source": [ "# but also Surface pressure and geopotential\n", "ps = epygram.open(r.resource.container.abspath, 'r').readfield('SURFPRESSION')\n", "zs = epygram.open(r.resource.container.abspath, 'r').readfield('SPECSURFGEOPOTEN')\n", "# Ps is spectral and ln(Ps)\n", "ps.sp2gp()\n", "ps.operation('exp')\n", "zs.sp2gp()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:12.394349Z", "iopub.status.busy": "2025-01-13T11:35:12.394217Z", "iopub.status.idle": "2025-01-13T11:35:12.415325Z", "shell.execute_reply": "2025-01-13T11:35:12.414894Z" } }, "outputs": [], "source": [ "from epygram.geometries.VGeometry import hybridP2altitude\n", "from bronx.meteo.conversion import q2R\n", "\n", "for p in profiles:\n", " q_profile = q3d.extract_subdomain(p.geometry).data # profile of q at the same place\n", " # specific humidity (and optionally hydrometeors) to moist air specific constant R\n", " R_profile = q2R(q_profile)\n", " t_profile = p.data\n", " ps_local = ps.getvalue_ll(p.geometry.grid['longitudes'][0],\n", " p.geometry.grid['latitudes'][0])\n", " zs_local = zs.getvalue_ll(p.geometry.grid['longitudes'][0],\n", " p.geometry.grid['latitudes'][0])\n", " # create the Z vertical coordinate\n", " p.geometry.vcoordinate = hybridP2altitude(p.geometry.vcoordinate,\n", " R_profile,\n", " t_profile,\n", " ps_local,\n", " vertical_mean='geometric',\n", " Phi_surf=zs_local,\n", " Pdep=None) # we could also provide a (NH) Pressure-departure profile for more accuracy" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2025-01-13T11:35:12.416848Z", "iopub.status.busy": "2025-01-13T11:35:12.416651Z", "iopub.status.idle": "2025-01-13T11:35:12.572542Z", "shell.execute_reply": "2025-01-13T11:35:12.572064Z" } }, "outputs": [], "source": [ "fig = ax = None\n", "for p in profiles:\n", " fig, ax = p.plotfield(labels='Temperature @ ({}, {})'.format(p.geometry.grid['longitudes'][0],\n", " p.geometry.grid['latitudes'][0]),\n", " over=(fig, ax)) # superpose profiles" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 1 }