diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e964d2b916358df9cc30e1d60243b4773bcd6244 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +data-download/__pycache__/ +data-download/wget.sh-* +data-download/wget.sh-*.log +data-download/.wget.sh-* + +.ipynb_checkpoints + +analysis/*.nc +analysis/__pycache__/ +analysis/qualitycheck_dTdt*_*.pdf + +plots4paper/__pycache__/ + +acp/*/*.aux +acp/*/*.bbl +acp/*/*.blg +acp/*/*.log +acp/*/*.synctex.gz diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..d0d921c519c306a2a4fcdc97bec28e5dd8c9f1ed --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +The repository is licensed under the Creative Commons 4.0 BY licence, https://creativecommons.org/licenses/by/4.0/legalcode. \ No newline at end of file diff --git a/README.md b/README.md index 026032715903e046038044b111e9697d41640530..acba3b3f28a5c7c1c4f90d63715e0f65ae384e4f 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,22 @@ -# voigt-et-al-cmip-cloudradheating-acp2024 +# Git repository for "Atmospheric cloud-radiative heating in CMIP6 and observations, and its response to surface warming" by Aiko Voigt et al. +For the EGU ACP paper accepted in July 2024. +**Author:** Aiko Voigt, IMG, University of Vienna, aiko.voigt@univie.ac.at. -## Getting started +**The repository contains the following directories:** -To make it easy for you to get started with GitLab, here's a list of recommended next steps. + * acp: manuscript files for accepted version but before technical changes for production, allows to link the figure file names to the plotting scripts in the directory plots4paper + * analysis: scripts for postprocessing the data downloaded from ESGF, including the calculation of radiative heating rates, the thermal tropopause, and time and zonal means; note that geopotential height zg for UKESM and HadGEM models is directly put into the directory "mean" by the postprocessing script + * cfmip-sst: netcdf file with SST pattern change used in the CMIP6 amip-future4K simulations + * data-download: scripts for retrieving model output from ESGF + * obsdata: zonal-mean time-mean estimates of cloud-radiative heating from CCCM and 2B-FLXHR-LIDAR + * plots4paper: scripts to generate plots used in the paper, the plots are stored in the subdirectory "figures", from where they are accesses in the latex file; note: the directory contains also figures that were not included in the paper -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.phaidra.org/climate/voigt-et-al-cmip-cloudradheating-acp2024.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.phaidra.org/climate/voigt-et-al-cmip-cloudradheating-acp2024/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +The repo is a (subset) copy from the GitLab repo https://gitlab.phaidra.org/climate/cmip6-crh, commit 4b9920be928f3ac00e3ee9da0ae88f9522adb19a. The cmip6-crh repo is internal to the team "Climate Dynamics and Modeling" at IMG, University of Vienna. + + The directory paths will need to be adapated by the user to their own local infrastructure. This should be relatively straightforward. + + The postprocessing scripts for the cloud-radiative heating from CCCM and 2B-FLXHR-LIDAR are provided in a separate repository. Likewise, the CCCM/2B-FLXHR-LIDAR postprocessed data and the CMIP6 postprocessed data (mostly 12-month climatologies) are provided in separate repositories that are given in the data statement of the ACP paper. + +Good luck and enjoy! diff --git a/acp/accepted/copernicus.bst b/acp/accepted/copernicus.bst new file mode 100644 index 0000000000000000000000000000000000000000..9a68fcf48dab2bf47dab6b976e7d3c48e409cf62 --- /dev/null +++ b/acp/accepted/copernicus.bst @@ -0,0 +1,1726 @@ +%% +%% This is file `copernicus.bst', version 1.6 (October 2023) +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% merlin.mbs (with options: `head,ay,nat,seq-key,nm-rev,ed-rev,keyxyr,blkyear,dt-end,note-yr,atit-u,jttl-rm,vnum-x,volp-com,pgsep-s,num-xser,btit-rm,bt-rm,isbn,issn,doi,url-doi,edby,blk-com,au-col,in-col,pp,ed,abr,xedn,jabr,url,url-nt,nfss,') +%% ---------------------------------------- +%% *** For journals of Copernicus Publications *** +%% +%% Copyright 1994-2011 Patrick W Daly + % =============================================================== + % IMPORTANT NOTICE: + % This bibliographic style (bst) file has been generated from one or + % more master bibliographic style (mbs) files, listed above. + % + % This generated file can be redistributed and/or modified under the terms + % of the LaTeX Project Public License Distributed from CTAN + % archives in directory macros/latex/base/lppl.txt; either + % version 1 of the License, or any later version. + % =============================================================== + % Name and version information of the main mbs file: + % \ProvidesFile{merlin.mbs}[2011/11/18 4.33 (PWD, AO, DPC)] + % For use with BibTeX version 0.99a or later + %------------------------------------------------------------------- + % This bibliography style file is intended for texts in ENGLISH + % This is an author-year citation style bibliography. As such, it is + % non-standard LaTeX, and requires a special package file to function properly. + % Such a package is natbib.sty by Patrick W. Daly + % The form of the \bibitem entries is + % \bibitem[Jones et al.(1990)]{key}... + % \bibitem[Jones et al.(1990)Jones, Baker, and Smith]{key}... + % The essential feature is that the label (the part in brackets) consists + % of the author names, as they should appear in the citation, with the year + % in parentheses following. There must be no space before the opening + % parenthesis! + % With natbib v5.3, a full list of authors may also follow the year. + % In natbib.sty, it is possible to define the type of enclosures that is + % really wanted (brackets or parentheses), but in either case, there must + % be parentheses in the label. + % The \cite command functions as follows: + % \citet{key} ==>> Jones et al. (1990) + % \citet*{key} ==>> Jones, Baker, and Smith (1990) + % \citep{key} ==>> (Jones et al., 1990) + % \citep*{key} ==>> (Jones, Baker, and Smith, 1990) + % \citep[chap. 2]{key} ==>> (Jones et al., 1990, chap. 2) + % \citep[e.g.][]{key} ==>> (e.g. Jones et al., 1990) + % \citep[e.g.][p. 32]{key} ==>> (e.g. Jones et al., 1990, p. 32) + % \citeauthor{key} ==>> Jones et al. + % \citeauthor*{key} ==>> Jones, Baker, and Smith + % \citeyear{key} ==>> 1990 + %--------------------------------------------------------------------- + +%% Rolf Sander (2023): +%% - ISBN also for phdthesis and techreport +%% - urlprefix is now empty + +ENTRY + { address + author + booktitle + chapter + doi + edition + editor + eid + howpublished + institution + isbn + issn + journal + key + month + note + number + organization + pages + publisher + school + series + title + type + url + volume + year + } + {} + { label extra.label sort.label short.list } +INTEGERS { output.state before.all mid.sentence after.sentence after.block } +FUNCTION {init.state.consts} +{ #0 'before.all := + #1 'mid.sentence := + #2 'after.sentence := + #3 'after.block := +} +STRINGS { s t} +FUNCTION {output.nonnull} +{ 's := + output.state mid.sentence = + { ", " * write$ } + { output.state after.block = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { output.state before.all = + 'write$ + { add.period$ " " * write$ } + if$ + } + if$ + mid.sentence 'output.state := + } + if$ + s +} +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} +FUNCTION {output.check} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} +FUNCTION {fin.entry} +{ add.period$ + write$ + newline$ +} + +FUNCTION {new.block} +{ output.state before.all = + 'skip$ + { after.block 'output.state := } + if$ +} +FUNCTION {new.sentence} +{ output.state after.block = + 'skip$ + { output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ + } + if$ +} +FUNCTION {add.blank} +{ " " * before.all 'output.state := +} + +FUNCTION {add.colon} +{ duplicate$ empty$ + 'skip$ + { ":" * add.blank } + if$ +} + +FUNCTION {date.block} +{ + skip$ +} + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} +FUNCTION {and} +{ 'skip$ + { pop$ #0 } + if$ +} +FUNCTION {or} +{ { pop$ #1 } + 'skip$ + if$ +} +FUNCTION {new.block.checkb} +{ empty$ + swap$ empty$ + and + 'skip$ + 'new.block + if$ +} +FUNCTION {field.or.null} +{ duplicate$ empty$ + { pop$ "" } + 'skip$ + if$ +} +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ +} + +FUNCTION {capitalize} +{ "u" change.case$ "t" change.case$ } + +FUNCTION {space.word} +{ " " swap$ * " " * } + % Here are the language-specific definitions for explicit words. + % Each function has a name bbl.xxx where xxx is the English word. + % The language selected here is ENGLISH +FUNCTION {bbl.and} +{ "and"} + +FUNCTION {bbl.etal} +{ "et~al." } + +FUNCTION {bbl.editors} +{ "eds." } + +FUNCTION {bbl.editor} +{ "ed." } + +FUNCTION {bbl.edby} +{ "edited by" } + +FUNCTION {bbl.edition} +{ "edn." } + +FUNCTION {bbl.volume} +{ "vol." } + +FUNCTION {bbl.of} +{ "of" } + +FUNCTION {bbl.number} +{ "no." } + +FUNCTION {bbl.nr} +{ "no." } + +FUNCTION {bbl.in} +{ "in" } + +FUNCTION {bbl.pages} +{ "pp." } + +FUNCTION {bbl.page} +{ "p." } + +FUNCTION {bbl.chapter} +{ "chap." } + +FUNCTION {bbl.techrep} +{ "Tech. Rep." } + +FUNCTION {bbl.mthesis} +{ "Master's thesis" } + +FUNCTION {bbl.phdthesis} +{ "Ph.D. thesis" } + +MACRO {jan} {"Jan."} + +MACRO {feb} {"Feb."} + +MACRO {mar} {"Mar."} + +MACRO {apr} {"Apr."} + +MACRO {may} {"May"} + +MACRO {jun} {"Jun."} + +MACRO {jul} {"Jul."} + +MACRO {aug} {"Aug."} + +MACRO {sep} {"Sep."} + +MACRO {oct} {"Oct."} + +MACRO {nov} {"Nov."} + +MACRO {dec} {"Dec."} + + %------------------------------------------------------------------- + % Begin module: + % \ProvidesFile{physjour.mbs}[2002/01/14 2.2 (PWD)] +MACRO {aa}{"Astron. \& Astrophys."} +MACRO {aasup}{"Astron. \& Astrophys. Suppl. Ser."} +MACRO {aj} {"Astron. J."} +MACRO {aph} {"Acta Phys."} +MACRO {advp} {"Adv. Phys."} +MACRO {ajp} {"Amer. J. Phys."} +MACRO {ajm} {"Amer. J. Math."} +MACRO {amsci} {"Amer. Sci."} +MACRO {anofd} {"Ann. Fluid Dyn."} +MACRO {am} {"Ann. Math."} +MACRO {ap} {"Ann. Phys. (NY)"} +MACRO {adp} {"Ann. Phys. (Leipzig)"} +MACRO {ao} {"Appl. Opt."} +MACRO {apl} {"Appl. Phys. Lett."} +MACRO {app} {"Astroparticle Phys."} +MACRO {apj} {"Astrophys. J."} +MACRO {apjsup} {"Astrophys. J. Suppl."} +MACRO {apss} {"Astrophys. Space Sci."} +MACRO {araa} {"Ann. Rev. Astron. Astrophys."} +MACRO {baas} {"Bull. Amer. Astron. Soc."} +MACRO {baps} {"Bull. Amer. Phys. Soc."} +MACRO {cmp} {"Comm. Math. Phys."} +MACRO {cpam} {"Commun. Pure Appl. Math."} +MACRO {cppcf} {"Comm. Plasma Phys. \& Controlled Fusion"} +MACRO {cpc} {"Comp. Phys. Comm."} +MACRO {cqg} {"Class. Quant. Grav."} +MACRO {cra} {"C. R. Acad. Sci. A"} +MACRO {fed} {"Fusion Eng. \& Design"} +MACRO {ft} {"Fusion Tech."} +MACRO {grg} {"Gen. Relativ. Gravit."} +MACRO {ieeens} {"IEEE Trans. Nucl. Sci."} +MACRO {ieeeps} {"IEEE Trans. Plasma Sci."} +MACRO {ijimw} {"Interntl. J. Infrared \& Millimeter Waves"} +MACRO {ip} {"Infrared Phys."} +MACRO {irp} {"Infrared Phys."} +MACRO {jap} {"J. Appl. Phys."} +MACRO {jasa} {"J. Acoust. Soc. America"} +MACRO {jcp} {"J. Comp. Phys."} +MACRO {jetp} {"Sov. Phys.--JETP"} +MACRO {jfe} {"J. Fusion Energy"} +MACRO {jfm} {"J. Fluid Mech."} +MACRO {jmp} {"J. Math. Phys."} +MACRO {jne} {"J. Nucl. Energy"} +MACRO {jnec} {"J. Nucl. Energy, C: Plasma Phys., Accelerators, Thermonucl. Res."} +MACRO {jnm} {"J. Nucl. Mat."} +MACRO {jpc} {"J. Phys. Chem."} +MACRO {jpp} {"J. Plasma Phys."} +MACRO {jpsj} {"J. Phys. Soc. Japan"} +MACRO {jsi} {"J. Sci. Instrum."} +MACRO {jvst} {"J. Vac. Sci. \& Tech."} +MACRO {nat} {"Nature"} +MACRO {nature} {"Nature"} +MACRO {nedf} {"Nucl. Eng. \& Design/Fusion"} +MACRO {nf} {"Nucl. Fusion"} +MACRO {nim} {"Nucl. Inst. \& Meth."} +MACRO {nimpr} {"Nucl. Inst. \& Meth. in Phys. Res."} +MACRO {np} {"Nucl. Phys."} +MACRO {npb} {"Nucl. Phys. B"} +MACRO {nt/f} {"Nucl. Tech./Fusion"} +MACRO {npbpc} {"Nucl. Phys. B (Proc. Suppl.)"} +MACRO {inc} {"Nuovo Cimento"} +MACRO {nc} {"Nuovo Cimento"} +MACRO {pf} {"Phys. Fluids"} +MACRO {pfa} {"Phys. Fluids A: Fluid Dyn."} +MACRO {pfb} {"Phys. Fluids B: Plasma Phys."} +MACRO {pl} {"Phys. Lett."} +MACRO {pla} {"Phys. Lett. A"} +MACRO {plb} {"Phys. Lett. B"} +MACRO {prep} {"Phys. Rep."} +MACRO {pnas} {"Proc. Nat. Acad. Sci. USA"} +MACRO {pp} {"Phys. Plasmas"} +MACRO {ppcf} {"Plasma Phys. \& Controlled Fusion"} +MACRO {phitrsl} {"Philos. Trans. Roy. Soc. London"} +MACRO {prl} {"Phys. Rev. Lett."} +MACRO {pr} {"Phys. Rev."} +MACRO {physrev} {"Phys. Rev."} +MACRO {pra} {"Phys. Rev. A"} +MACRO {prb} {"Phys. Rev. B"} +MACRO {prc} {"Phys. Rev. C"} +MACRO {prd} {"Phys. Rev. D"} +MACRO {pre} {"Phys. Rev. E"} +MACRO {ps} {"Phys. Scripta"} +MACRO {procrsl} {"Proc. Roy. Soc. London"} +MACRO {rmp} {"Rev. Mod. Phys."} +MACRO {rsi} {"Rev. Sci. Inst."} +MACRO {science} {"Science"} +MACRO {sciam} {"Sci. Am."} +MACRO {sam} {"Stud. Appl. Math."} +MACRO {sjpp} {"Sov. J. Plasma Phys."} +MACRO {spd} {"Sov. Phys.--Doklady"} +MACRO {sptp} {"Sov. Phys.--Tech. Phys."} +MACRO {spu} {"Sov. Phys.--Uspeki"} +MACRO {st} {"Sky and Telesc."} + % End module: physjour.mbs + %------------------------------------------------------------------- + % Begin module: + % \ProvidesFile{geojour.mbs}[2002/07/10 2.0h (PWD)] +MACRO {aisr} {"Adv. Space Res."} +MACRO {ag} {"Ann. Geophys."} +MACRO {anigeo} {"Ann. Geofis."} +MACRO {angl} {"Ann. Glaciol."} +MACRO {andmet} {"Ann. d. Meteor."} +MACRO {andgeo} {"Ann. d. Geophys."} +MACRO {andphy} {"Ann. Phys.-Paris"} +MACRO {afmgb} {"Arch. Meteor. Geophys. Bioklimatol."} +MACRO {atph} {"Atm\'osphera"} +MACRO {aao} {"Atmos. Ocean"} +MACRO {ass}{"Astrophys. Space Sci."} +MACRO {atenv} {"Atmos. Environ."} +MACRO {aujag} {"Aust. J. Agr. Res."} +MACRO {aumet} {"Aust. Meteorol. Mag."} +MACRO {blmet} {"Bound.-Lay. Meteorol."} +MACRO {bams} {"Bull. Amer. Meteorol. Soc."} +MACRO {cch} {"Clim. Change"} +MACRO {cdyn} {"Clim. Dynam."} +MACRO {cbul} {"Climatol. Bull."} +MACRO {cap} {"Contrib. Atmos. Phys."} +MACRO {dsr} {"Deep-Sea Res."} +MACRO {dhz} {"Dtsch. Hydrogr. Z."} +MACRO {dao} {"Dynam. Atmos. Oceans"} +MACRO {eco} {"Ecology"} +MACRO {empl}{"Earth, Moon and Planets"} +MACRO {envres} {"Environ. Res."} +MACRO {envst} {"Environ. Sci. Technol."} +MACRO {ecms} {"Estuarine Coastal Mar. Sci."} +MACRO {expa}{"Exper. Astron."} +MACRO {geoint} {"Geofis. Int."} +MACRO {geopub} {"Geofys. Publ."} +MACRO {geogeo} {"Geol. Geofiz."} +MACRO {gafd} {"Geophys. Astrophys. Fluid Dyn."} +MACRO {gfd} {"Geophys. Fluid Dyn."} +MACRO {geomag} {"Geophys. Mag."} +MACRO {georl} {"Geophys. Res. Lett."} +MACRO {grl} {"Geophys. Res. Lett."} +MACRO {ga} {"Geophysica"} +MACRO {gs} {"Geophysics"} +MACRO {ieeetap} {"IEEE Trans. Antenn. Propag."} +MACRO {ijawp} {"Int. J. Air Water Pollut."} +MACRO {ijc} {"Int. J. Climatol."} +MACRO {ijrs} {"Int. J. Remote Sens."} +MACRO {jam} {"J. Appl. Meteorol."} +MACRO {jaot} {"J. Atmos. Ocean. Technol."} +MACRO {jatp} {"J. Atmos. Terr. Phys."} +MACRO {jastp} {"J. Atmos. Solar-Terr. Phys."} +MACRO {jce} {"J. Climate"} +MACRO {jcam} {"J. Climate Appl. Meteor."} +MACRO {jcm} {"J. Climate Meteor."} +MACRO {jcy} {"J. Climatol."} +MACRO {jgr} {"J. Geophys. Res."} +MACRO {jga} {"J. Glaciol."} +MACRO {jh} {"J. Hydrol."} +MACRO {jmr} {"J. Mar. Res."} +MACRO {jmrj} {"J. Meteor. Res. Japan"} +MACRO {jm} {"J. Meteor."} +MACRO {jpo} {"J. Phys. Oceanogr."} +MACRO {jra} {"J. Rech. Atmos."} +MACRO {jaes} {"J. Aeronaut. Sci."} +MACRO {japca} {"J. Air Pollut. Control Assoc."} +MACRO {jas} {"J. Atmos. Sci."} +MACRO {jmts} {"J. Mar. Technol. Soc."} +MACRO {jmsj} {"J. Meteorol. Soc. Japan"} +MACRO {josj} {"J. Oceanogr. Soc. Japan"} +MACRO {jwm} {"J. Wea. Mod."} +MACRO {lao} {"Limnol. Oceanogr."} +MACRO {mwl} {"Mar. Wea. Log"} +MACRO {mau} {"Mausam"} +MACRO {meteor} {"``Meteor'' Forschungsergeb."} +MACRO {map} {"Meteorol. Atmos. Phys."} +MACRO {metmag} {"Meteor. Mag."} +MACRO {metmon} {"Meteor. Monogr."} +MACRO {metrun} {"Meteor. Rundsch."} +MACRO {metzeit} {"Meteor. Z."} +MACRO {metgid} {"Meteor. Gidrol."} +MACRO {mwr} {"Mon. Weather Rev."} +MACRO {nwd} {"Natl. Weather Dig."} +MACRO {nzjmfr} {"New Zeal. J. Mar. Freshwater Res."} +MACRO {npg} {"Nonlin. Proc. Geophys."} +MACRO {om} {"Oceanogr. Meteorol."} +MACRO {ocac} {"Oceanol. Acta"} +MACRO {oceanus} {"Oceanus"} +MACRO {paleoc} {"Paleoceanography"} +MACRO {pce} {"Phys. Chem. Earth"} +MACRO {pmg} {"Pap. Meteor. Geophys."} +MACRO {ppom} {"Pap. Phys. Oceanogr. Meteor."} +MACRO {physzeit} {"Phys. Z."} +MACRO {pps} {"Planet. Space Sci."} +MACRO {pss} {"Planet. Space Sci."} +MACRO {pag} {"Pure Appl. Geophys."} +MACRO {qjrms} {"Quart. J. Roy. Meteorol. Soc."} +MACRO {quatres} {"Quat. Res."} +MACRO {rsci} {"Radio Sci."} +MACRO {rse} {"Remote Sens. Environ."} +MACRO {rgeo} {"Rev. Geophys."} +MACRO {rgsp} {"Rev. Geophys. Space Phys."} +MACRO {rdgeo} {"Rev. Geofis."} +MACRO {revmeta} {"Rev. Meteorol."} +MACRO {sgp}{"Surveys in Geophys."} +MACRO {sp} {"Solar Phys."} +MACRO {ssr} {"Space Sci. Rev."} +MACRO {tellus} {"Tellus"} +MACRO {tac} {"Theor. Appl. Climatol."} +MACRO {tagu} {"Trans. Am. Geophys. Union (EOS)"} +MACRO {wrr} {"Water Resour. Res."} +MACRO {weather} {"Weather"} +MACRO {wafc} {"Weather Forecast."} +MACRO {ww} {"Weatherwise"} +MACRO {wmob} {"WMO Bull."} +MACRO {zeitmet} {"Z. Meteorol."} + % End module: geojour.mbs +%% Copyright 1994-2006 Patrick W DalyMACRO {acmcs} {"ACM Comput. Surv."} + +MACRO {acta} {"Acta Inf."} + +MACRO {cacm} {"Commun. ACM"} + +MACRO {ibmjrd} {"IBM J. Res. Dev."} + +MACRO {ibmsj} {"IBM Syst.~J."} + +MACRO {ieeese} {"IEEE Trans. Software Eng."} + +MACRO {ieeetc} {"IEEE Trans. Comput."} + +MACRO {ieeetcad} + {"IEEE Trans. Comput. Aid. Des."} + +MACRO {ipl} {"Inf. Process. Lett."} + +MACRO {jacm} {"J.~ACM"} + +MACRO {jcss} {"J.~Comput. Syst. Sci."} + +MACRO {scp} {"Sci. Comput. Program."} + +MACRO {sicomp} {"SIAM J. Comput."} + +MACRO {tocs} {"ACM Trans. Comput. Syst."} + +MACRO {tods} {"ACM Trans. Database Syst."} + +MACRO {tog} {"ACM Trans. Graphic."} + +MACRO {toms} {"ACM Trans. Math. Software"} + +MACRO {toois} {"ACM Trans. Office Inf. Syst."} + +MACRO {toplas} {"ACM Trans. Progr. Lang. Syst."} + +MACRO {tcs} {"Theor. Comput. Sci."} + +FUNCTION {bibinfo.check} +{ swap$ + duplicate$ missing$ + { + pop$ pop$ + "" + } + { duplicate$ empty$ + { + swap$ pop$ + } + { swap$ + pop$ + } + if$ + } + if$ +} +FUNCTION {bibinfo.warn} +{ swap$ + duplicate$ missing$ + { + swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ + "" + } + { duplicate$ empty$ + { + swap$ "empty " swap$ * " in " * cite$ * warning$ + } + { swap$ + pop$ + } + if$ + } + if$ +} +INTEGERS { nameptr namesleft numnames } + + +STRINGS { bibinfo} + +FUNCTION {format.names} +{ 'bibinfo := + duplicate$ empty$ 'skip$ { + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv~}{ll}{, jj}{, f.}" + format.name$ + bibinfo bibinfo.check + 't := + nameptr #1 > + { + namesleft #1 > + { ", " * t * } + { + s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + numnames #2 > + { "," * } + 'skip$ + if$ + t "others" = + { + " " * bbl.etal * + } + { + bbl.and + space.word * t * + } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + } if$ +} +FUNCTION {format.names.ed} +{ + format.names +} +FUNCTION {format.key} +{ empty$ + { key field.or.null } + { "" } + if$ +} + +FUNCTION {format.authors} +{ author "author" format.names +} +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ + { + "," * + " " * + get.bbl.editor + * + } + if$ +} +FUNCTION {format.isbn} +{ isbn "isbn" bibinfo.check + duplicate$ empty$ 'skip$ + { + "ISBN " swap$ * + } + if$ +} + +FUNCTION {format.issn} +{ issn "issn" bibinfo.check + duplicate$ empty$ 'skip$ + { + "ISSN " swap$ * + } + if$ +} + +FUNCTION {format.doi} +{ doi "doi" bibinfo.check + duplicate$ empty$ 'skip$ + { + "\doi{" swap$ * "}" * + } + if$ +} +FUNCTION {format.note} +{ + doi empty$ + { url empty$ + 'skip$ + { "\urlprefix\url{" url * "}" * output } + if$ + } + 'skip$ + if$ + note empty$ + { "" } + { note #1 #1 substring$ + duplicate$ "{" = + 'skip$ + { output.state mid.sentence = + { "l" } + { "u" } + if$ + change.case$ + } + if$ + note #2 global.max$ substring$ * "note" bibinfo.check + } + if$ +} + +FUNCTION {format.title} +{ title + "title" bibinfo.check +} +FUNCTION {format.full.names} +{'s := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv~}{ll}" format.name$ + 't := + nameptr #1 > + { + namesleft #1 > + { ", " * t * } + { + s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + t "others" = + { + " " * bbl.etal * + } + { + numnames #2 > + { "," * } + 'skip$ + if$ + bbl.and + space.word * t * + } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {author.editor.key.full} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.full.names } + if$ + } + { author format.full.names } + if$ +} + +FUNCTION {author.key.full} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { author format.full.names } + if$ +} + +FUNCTION {editor.key.full} +{ editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.full.names } + if$ +} + +FUNCTION {make.full.names} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.full + { type$ "proceedings" = + 'editor.key.full + 'author.key.full + if$ + } + if$ +} + +FUNCTION {output.bibitem} +{ newline$ + "\bibitem[{" write$ + label write$ + ")" make.full.names duplicate$ short.list = + { pop$ } + { * } + if$ + "}]{" * write$ + cite$ write$ + "}" write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {if.digit} +{ duplicate$ "0" = + swap$ duplicate$ "1" = + swap$ duplicate$ "2" = + swap$ duplicate$ "3" = + swap$ duplicate$ "4" = + swap$ duplicate$ "5" = + swap$ duplicate$ "6" = + swap$ duplicate$ "7" = + swap$ duplicate$ "8" = + swap$ "9" = or or or or or or or or or +} +FUNCTION {n.separate} +{ 't := + "" + #0 'numnames := + { t empty$ not } + { t #-1 #1 substring$ if.digit + { numnames #1 + 'numnames := } + { #0 'numnames := } + if$ + t #-1 #1 substring$ swap$ * + t #-2 global.max$ substring$ 't := + numnames #5 = + { duplicate$ #1 #2 substring$ swap$ + #3 global.max$ substring$ + "\," swap$ * * + } + 'skip$ + if$ + } + while$ +} +FUNCTION {n.dashify} +{ + n.separate + 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + +FUNCTION {word.in} +{ bbl.in + ":" * + " " * } + +FUNCTION {format.date} +{ year "year" bibinfo.check duplicate$ empty$ + { + } + 'skip$ + if$ + extra.label * +} +FUNCTION {format.btitle} +{ title "title" bibinfo.check + duplicate$ empty$ 'skip$ + { + } + if$ +} +FUNCTION {either.or.check} +{ empty$ + 'pop$ + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} +FUNCTION {format.bvolume} +{ volume empty$ + { "" } + { bbl.volume volume tie.or.space.prefix + "volume" bibinfo.check * * + series "series" bibinfo.check + duplicate$ empty$ 'pop$ + { swap$ bbl.of space.word * swap$ + emphasize * } + if$ + "volume and number" number either.or.check + } + if$ +} +FUNCTION {format.number.series} +{ volume empty$ + { number empty$ + { series field.or.null } + { series empty$ + { number "number" bibinfo.check } + { output.state mid.sentence = + { bbl.number } + { bbl.number capitalize } + if$ + number tie.or.space.prefix "number" bibinfo.check * * + bbl.in space.word * + series "series" bibinfo.check * + } + if$ + } + if$ + } + { "" } + if$ +} + +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ + { + output.state mid.sentence = + { "l" } + { "t" } + if$ change.case$ + "edition" bibinfo.check + " " * bbl.edition * + } + if$ +} +INTEGERS { multiresult } +FUNCTION {multi.page.check} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ + { duplicate$ multi.page.check + { + bbl.pages swap$ + n.dashify + } + { + bbl.page swap$ + } + if$ + tie.or.space.prefix + "pages" bibinfo.check + * * + } + if$ +} +FUNCTION {format.journal.pages} +{ pages duplicate$ empty$ 'pop$ + { swap$ duplicate$ empty$ + { pop$ pop$ format.pages } + { + ", " * + swap$ + n.dashify + "pages" bibinfo.check + * + } + if$ + } + if$ +} +FUNCTION {format.journal.eid} +{ eid "eid" bibinfo.check + duplicate$ empty$ 'pop$ + { swap$ duplicate$ empty$ 'skip$ + { + ", " * + } + if$ + swap$ * + } + if$ +} +FUNCTION {format.vol.num.pages} +{ volume field.or.null + duplicate$ empty$ 'skip$ + { + "volume" bibinfo.check + } + if$ + eid empty$ + { format.journal.pages } + { format.journal.eid } + if$ +} + +FUNCTION {format.chapter.pages} +{ chapter empty$ + 'format.pages + { type empty$ + { bbl.chapter } + { type "l" change.case$ + "type" bibinfo.check + } + if$ + chapter tie.or.space.prefix + "chapter" bibinfo.check + * * + pages empty$ + 'skip$ + { ", " * format.pages * } + if$ + } + if$ +} + +FUNCTION {format.booktitle} +{ + booktitle "booktitle" bibinfo.check +} +FUNCTION {format.in.ed.booktitle} +{ format.booktitle duplicate$ empty$ 'skip$ + { + editor "editor" format.names.ed duplicate$ empty$ 'pop$ + { + bbl.edby + " " * swap$ * + swap$ + "," * + " " * swap$ + * } + if$ + word.in swap$ * + } + if$ +} +FUNCTION {format.thesis.type} +{ type duplicate$ empty$ + 'pop$ + { swap$ pop$ + "t" change.case$ "type" bibinfo.check + } + if$ +} +FUNCTION {format.tr.number} +{ number "number" bibinfo.check + type duplicate$ empty$ + { pop$ bbl.techrep } + 'skip$ + if$ + "type" bibinfo.check + swap$ duplicate$ empty$ + { pop$ "t" change.case$ } + { tie.or.space.prefix * * } + if$ +} +FUNCTION {format.article.crossref} +{ + word.in + " \cite{" * crossref * "}" * +} +FUNCTION {format.book.crossref} +{ volume duplicate$ empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + pop$ word.in + } + { bbl.volume + swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word * + } + if$ + " \cite{" * crossref * "}" * +} +FUNCTION {format.incoll.inproc.crossref} +{ + word.in + " \cite{" * crossref * "}" * +} +FUNCTION {format.org.or.pub} +{ 't := + "" + address empty$ t empty$ and + 'skip$ + { + t empty$ + { address "address" bibinfo.check * + } + { t * + address empty$ + 'skip$ + { ", " * address "address" bibinfo.check * } + if$ + } + if$ + } + if$ +} +FUNCTION {format.publisher.address} +{ publisher "publisher" bibinfo.warn format.org.or.pub +} + +FUNCTION {format.organization.address} +{ organization "organization" bibinfo.check format.org.or.pub +} + +FUNCTION {article} +{ output.bibitem + format.authors "author" output.check + author format.key output + add.colon + format.title "title" output.check + crossref missing$ + { + journal + "journal" bibinfo.check + "journal" output.check + format.vol.num.pages output + format.doi output + } + { format.article.crossref output.nonnull + format.pages output + } + if$ + format.note output + format.date "year" output.check + fin.entry +} +FUNCTION {book} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check + editor format.key output + add.colon + } + { format.authors output.nonnull + add.colon + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + format.btitle "title" output.check + crossref missing$ + { format.bvolume output + format.number.series output + format.publisher.address output + } + { + format.book.crossref output.nonnull + } + if$ + format.edition output + format.isbn output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} +FUNCTION {booklet} +{ output.bibitem + format.authors output + author format.key output + add.colon + format.title "title" output.check + howpublished "howpublished" bibinfo.check output + address "address" bibinfo.check output + format.isbn output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} + +FUNCTION {inbook} +{ output.bibitem + author empty$ + { format.editors "author and editor" output.check + editor format.key output + add.colon + } + { format.authors output.nonnull + add.colon + crossref missing$ + { "author and editor" editor either.or.check } + 'skip$ + if$ + } + if$ + format.btitle "title" output.check + crossref missing$ + { + format.bvolume output + format.chapter.pages "chapter and pages" output.check + format.number.series output + format.publisher.address output + } + { + format.chapter.pages "chapter and pages" output.check + format.book.crossref output.nonnull + } + if$ + format.edition output + crossref missing$ + { format.isbn output } + 'skip$ + if$ + format.doi output + format.note output + format.date "year" output.check + fin.entry +} + +FUNCTION {incollection} +{ output.bibitem + format.authors "author" output.check + author format.key output + add.colon + format.title "title" output.check + crossref missing$ + { format.in.ed.booktitle "booktitle" output.check + format.bvolume output + format.number.series output + format.chapter.pages output + format.publisher.address output + format.edition output + format.isbn output + } + { format.incoll.inproc.crossref output.nonnull + format.chapter.pages output + } + if$ + format.doi output + format.note output + format.date "year" output.check + fin.entry +} +FUNCTION {inproceedings} +{ output.bibitem + format.authors "author" output.check + author format.key output + add.colon + format.title "title" output.check + crossref missing$ + { format.in.ed.booktitle "booktitle" output.check + format.bvolume output + format.number.series output + format.pages output + publisher empty$ + { format.organization.address output } + { organization "organization" bibinfo.check output + format.publisher.address output + } + if$ + format.isbn output + format.issn output + } + { format.incoll.inproc.crossref output.nonnull + format.pages output + } + if$ + format.doi output + format.note output + format.date "year" output.check + fin.entry +} +FUNCTION {conference} { inproceedings } +FUNCTION {manual} +{ output.bibitem + format.authors output + author format.key output + add.colon + format.btitle "title" output.check + organization "organization" bibinfo.check output + address "address" bibinfo.check output + format.edition output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} + +FUNCTION {mastersthesis} +{ output.bibitem + format.authors "author" output.check + author format.key output + add.colon + format.btitle + "title" output.check + bbl.mthesis format.thesis.type output.nonnull + school "school" bibinfo.warn output + address "address" bibinfo.check output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} + +FUNCTION {misc} +{ output.bibitem + format.authors output + author format.key output + add.colon + format.title output + howpublished "howpublished" bibinfo.check output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} +FUNCTION {phdthesis} +{ output.bibitem + format.authors "author" output.check + author format.key output + add.colon + format.btitle + "title" output.check + bbl.phdthesis format.thesis.type output.nonnull + school "school" bibinfo.warn output + address "address" bibinfo.check output + format.isbn output + format.issn output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} + +FUNCTION {proceedings} +{ output.bibitem + format.editors output + editor format.key output + add.colon + format.btitle "title" output.check + format.bvolume output + format.number.series output + publisher empty$ + { format.organization.address output } + { organization "organization" bibinfo.check output + format.publisher.address output + } + if$ + format.isbn output + format.issn output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} + +FUNCTION {techreport} +{ output.bibitem + format.authors "author" output.check + author format.key output + add.colon + format.title + "title" output.check + format.tr.number output.nonnull + institution "institution" bibinfo.warn output + address "address" bibinfo.check output + format.isbn output + format.issn output + format.doi output + format.note output + format.date "year" output.check + fin.entry +} + +FUNCTION {unpublished} +{ output.bibitem + format.authors "author" output.check + author format.key output + add.colon + format.title "title" output.check + format.doi output + format.note "note" output.check + format.date output + fin.entry +} + +FUNCTION {default.type} { misc } +READ +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} +INTEGERS { len } +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + 's + if$ +} +FUNCTION {format.lab.names} +{ 's := + "" 't := + s #1 "{vv~}{ll}" format.name$ + s num.names$ duplicate$ + #2 > + { pop$ + " " * bbl.etal * + } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { + " " * bbl.etal * + } + { bbl.and space.word * s #2 "{vv~}{ll}" format.name$ + * } + if$ + } + if$ + } + if$ +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.label} +{ editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + 'key + if$ + } + { editor format.lab.names } + if$ +} + +FUNCTION {calc.short.authors} +{ type$ "book" = + type$ "inbook" = + or + 'author.editor.key.label + { type$ "proceedings" = + 'editor.key.label + 'author.key.label + if$ + } + if$ + 'short.list := +} + +FUNCTION {calc.label} +{ calc.short.authors + short.list + "(" + * + year duplicate$ empty$ + short.list key field.or.null = or + { pop$ "" } + 'skip$ + if$ + * + 'label := +} + +FUNCTION {sort.format.names} +{ 's := + #1 'nameptr := + "" + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" + format.name$ 't := + nameptr #1 > + { + " " * + namesleft #1 = t "others" = and + { "zzzzz" 't := } + 'skip$ + if$ + numnames #2 > nameptr #2 = and + { "zz" * year field.or.null * " " * + } + 'skip$ + if$ + t sortify * + } + { t sortify * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {sort.format.title} +{ 't := + "A " #2 + "An " #3 + "The " #4 t chop.word + chop.word + chop.word + sortify + #1 global.max$ substring$ +} +FUNCTION {author.sort} +{ author empty$ + { key empty$ + { "to sort, need author or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { author sort.format.names } + if$ +} +FUNCTION {author.editor.sort} +{ author empty$ + { editor empty$ + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ + } + { author sort.format.names } + if$ +} +FUNCTION {editor.sort} +{ editor empty$ + { key empty$ + { "to sort, need editor or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } + if$ +} +FUNCTION {presort} +{ calc.label + label sortify + " " + * + type$ "book" = + type$ "inbook" = + or + 'author.editor.sort + { type$ "proceedings" = + 'editor.sort + 'author.sort + if$ + } + if$ + #1 entry.max$ substring$ + 'sort.label := + sort.label + * + " " * cite$ * + #1 entry.max$ substring$ + 'sort.key$ := +} + +ITERATE {presort} +SORT +STRINGS { last.label next.extra } +INTEGERS { last.extra.num last.extra.num.extended last.extra.num.blank number.label } +FUNCTION {initialize.extra.label.stuff} +{ #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'last.extra.num := + "a" chr.to.int$ #1 - 'last.extra.num.blank := + last.extra.num.blank 'last.extra.num.extended := + #0 'number.label := +} +FUNCTION {forward.pass} +{ last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num "z" chr.to.int$ > + { "a" chr.to.int$ 'last.extra.num := + last.extra.num.extended #1 + 'last.extra.num.extended := + } + 'skip$ + if$ + last.extra.num.extended last.extra.num.blank > + { last.extra.num.extended int.to.chr$ + last.extra.num int.to.chr$ + * 'extra.label := } + { last.extra.num int.to.chr$ 'extra.label := } + if$ + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ + number.label #1 + 'number.label := +} +FUNCTION {reverse.pass} +{ next.extra "b" = + { "a" 'extra.label := } + 'skip$ + if$ + extra.label 'next.extra := + extra.label + duplicate$ empty$ + 'skip$ + { "{\natexlab{" swap$ * "}}" * } + if$ + 'extra.label := + label extra.label * 'label := +} +EXECUTE {initialize.extra.label.stuff} +ITERATE {forward.pass} +REVERSE {reverse.pass} +FUNCTION {bib.sort.order} +{ sort.label + " " + * + year field.or.null sortify + * + " " * cite$ * + #1 entry.max$ substring$ + 'sort.key$ := +} +ITERATE {bib.sort.order} +SORT +FUNCTION {begin.bib} +{ preamble$ empty$ + 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" number.label int.to.str$ * "}" * + write$ newline$ + "\providecommand{\natexlab}[1]{#1}" + write$ newline$ + "\providecommand{\url}[1]{\texttt{#1}}" + write$ newline$ + "\providecommand{\urlprefix}{}" + write$ newline$ + "\expandafter\ifx\csname urlstyle\endcsname\relax" + write$ newline$ + " \providecommand{\doi}[1]{https://doi.org/\discretionary{}{}{}#1}\else" + write$ newline$ + " \providecommand{\doi}{https://doi.org/\discretionary{}{}{}\begingroup \urlstyle{rm}\Url}\fi" + write$ newline$ +} +EXECUTE {begin.bib} +EXECUTE {init.state.consts} +ITERATE {call.type$} +FUNCTION {end.bib} +{ newline$ + "\end{thebibliography}" write$ newline$ +} +EXECUTE {end.bib} +%% End of customized bst file +%% +%% End of file `copernicus.bst'. diff --git a/acp/accepted/copernicus.cfg b/acp/accepted/copernicus.cfg new file mode 100644 index 0000000000000000000000000000000000000000..31ac16920bf594f12476ee3562dd52b1fc4acfc3 --- /dev/null +++ b/acp/accepted/copernicus.cfg @@ -0,0 +1,1117 @@ +\newif\ifprp \DeclareOption{prp} {\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue \@bartrue \prptrue} +\newif\ifgtes \DeclareOption{gtes} {\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue \@bartrue \gtestrue} +\newif\ifdwes \DeclareOption{dwes} {\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@twostagejnltrue \@barfalse\dwestrue} + \DeclareOption{dwesd} {\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@stage@finalfalse \dwestrue} +\newif\ifcopyediting \DeclareOption{copyediting}{\copyeditingtrue\@noreftrue} +\newif\ifsmsps \DeclareOption{smsps} { \smspstrue} +\newif\ifar \DeclareOption{ar}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@twostagejnltrue\artrue} + \DeclareOption{ard}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@stage@finalfalse\artrue} +\newif\ifsp \DeclareOption{sp}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@twostagejnltrue\sptrue} + \DeclareOption{spd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@stage@finalfalse\sptrue} +\newif\ifegusphere \DeclareOption{egusphere}{\@twostagejnltrue\eguspheretrue} + \DeclareOption{egusphered}{\@stage@finalfalse\eguspheretrue} +\newif\ifsand \DeclareOption{sand}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\sandtrue} +\newif\ifpolf \DeclareOption{polf}{\@sansseriffacetrue\@sansserifheadertrue\@bartrue\polftrue} +\newif\ifjbji \DeclareOption{jbji}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\jbjitrue} +\newif\ifmr \DeclareOption{mr}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@twostagejnltrue\mrtrue} + \DeclareOption{mrd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@stage@finalfalse\mrtrue} +\newif\ifejm \DeclareOption{ejm}{\@abstractcenteredtrue\@bartrue\ejmtrue} +\newif\ifwcd \DeclareOption{wcd}{\@twostagejnltrue\wcdtrue} + \DeclareOption{wcdd}{\@stage@finalfalse\wcdtrue} +\newif\ifgchron \DeclareOption{gchron}{\@sansseriffacetrue\@sansserifheadertrue\@twostagejnltrue\gchrontrue} + \DeclareOption{gchrond}{\@sansseriffacetrue\@sansserifheadertrue\@stage@finalfalse\gchrontrue} +\newif\ifdeuquasp \DeclareOption{deuquasp}{\@sansseriffacetrue\@sansserifheadertrue\@abstractindentedtrue\@bartrue\@seclinetrue\deuquasptrue} +\newif\ifgc \DeclareOption{gc}{\@sansseriffacetrue\@sansserifheadertrue\@bartrue\@twostagejnltrue\gctrue} + \DeclareOption{gcd}{\@sansseriffacetrue\@sansserifheadertrue\@bartrue\@stage@finalfalse\gctrue} +\newif\ifegqsj \DeclareOption{egqsj}{\@sansseriffacetrue\@sansserifheadertrue\@abstractindentedtrue\@bartrue\@seclinetrue\egqsjtrue} +\newif\ifjm \DeclareOption{jm}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\jmtrue} +\newif\ifwes \DeclareOption{wes}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@twostagejnltrue\westrue} + \DeclareOption{wesd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@stage@finalfalse\westrue} +\newif\ifaab \DeclareOption{aab}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\aabtrue} +\newif\ifpiahs \DeclareOption{piahs}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\piahstrue} +\newif\ifascmo \DeclareOption{ascmo}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@corrigendumtrue\@editorialnotetwoctrue\ascmotrue} +\newif\ifpb \DeclareOption{pb}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\pbtrue} +\newif\ifsoil \DeclareOption{soil}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@twostagejnltrue\soiltrue} + \DeclareOption{soild}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@stage@finalfalse\soiltrue} +\newif\ifangeocom \DeclareOption{angeocom}{\@bartrue\@twostagejnltrue\angeocomtrue} + \DeclareOption{angeocomd}{\@bartrue\@stage@finalfalse\angeocomtrue} +\newif\ifwe \DeclareOption{we}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\wetrue} +\newif\ifsdpd \DeclareOption{sdpd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\sdpdtrue} +\newif\ifsdwr \DeclareOption{sdwr}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\sdwrtrue} +\newif\ifsdtd \DeclareOption{sdtd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\sdtdtrue} +\newif\ifsdpr \DeclareOption{sdpr}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\sdprtrue} +\newif\ifsdsr \DeclareOption{sdsr}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\sdsrtrue} +\newif\ifasr \DeclareOption{asr}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\asrtrue} +\newif\ifms \DeclareOption{ms}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\mstrue} +\newif\ifjsss \DeclareOption{jsss}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\jssstrue} +\newif\ifhgss \DeclareOption{hgss}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@twostagejnltrue\hgsstrue} + \DeclareOption{hgssd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@stage@finalfalse\hgsstrue} +\newif\ifgh \DeclareOption{gh}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\ghtrue} +\newif\ifesurf \DeclareOption{esurf}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@twostagejnltrue\esurftrue} + \DeclareOption{esurfd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@stage@finalfalse\esurftrue} +\newif\ifessd \DeclareOption{essd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@twostagejnltrue\essdtrue} + \DeclareOption{essdd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@stage@finalfalse\essdtrue} +\newif\iftc \DeclareOption{tc}{\@twostagejnltrue\tctrue} + \DeclareOption{tcd}{\@stage@finalfalse\tctrue} +\newif\ifse \DeclareOption{se}{\@bartrue\@twostagejnltrue\setrue} + \DeclareOption{sed}{\@bartrue\@stage@finalfalse\setrue} +\newif\ifos \DeclareOption{os}{\@twostagejnltrue\ostrue} + \DeclareOption{osd}{\@stage@finalfalse\ostrue} +\newif\ifnpg \DeclareOption{npg}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@editorialnotedtrue\@twostagejnltrue\npgtrue} + \DeclareOption{npgd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@stage@finalfalse\npgtrue} +\newif\ifnhess \DeclareOption{nhess}{\@editorialnotedtrue\@twostagejnltrue\nhesstrue} + \DeclareOption{nhessd}{\@stage@finalfalse\nhesstrue} +\newif\ifhess \DeclareOption{hess}{\@twostagejnltrue\hesstrue} + \DeclareOption{hessd}{\@stage@finalfalse\hesstrue} +\newif\ifgmd \DeclareOption{gmd}{\@firstbartrue\@twostagejnltrue\gmdtrue} + \DeclareOption{gmdd}{\@firstbartrue\@stage@finalfalse\gmdtrue} +\newif\ifgi \DeclareOption{gi}{\@corrigendumtrue\@editorialnotetwoctrue\@editorialnotedtrue\@twostagejnltrue\gitrue} + \DeclareOption{gid}{\@stage@finalfalse\gitrue} +\newif\ifesd \DeclareOption{esd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@twostagejnltrue\esdtrue} + \DeclareOption{esdd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@bartrue\@stage@finalfalse\esdtrue} +\newif\ifcp \DeclareOption{cp}{\@sansseriffacetrue\@sansserifheadertrue\@twostagejnltrue\cptrue} + \DeclareOption{cpd}{\@sansseriffacetrue\@sansserifheadertrue\@stage@finalfalse\cptrue} +\newif\ifastra \DeclareOption{astra}{\astratrue} +\newif\ifars \DeclareOption{ars}{\arstrue} +\newif\ifangeo \DeclareOption{angeo}{\@twostagejnltrue\angeotrue} + \DeclareOption{angeod}{\@stage@finalfalse\angeotrue} +\newif\ifamt \DeclareOption{amt}{\@twostagejnltrue\amttrue} + \DeclareOption{amtd}{\@stage@finalfalse\amttrue} +\newif\ifadgeo \DeclareOption{adgeo}{\adgeotrue} +\newif\iffr \DeclareOption{fr}{\frtrue} +\newif\ifbg \DeclareOption{bg}{\@firstbartrue\@twostagejnltrue\bgtrue} + \DeclareOption{bgd}{\@firstbartrue\@stage@finalfalse\bgtrue} +\newif\ifacp \DeclareOption{acp}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@twostagejnltrue\acptrue} + \DeclareOption{acpd}{\@sansseriffacetrue\@sansserifheadertrue\@abstractcenteredtrue\@firstbartrue\@stage@finalfalse\acptrue} + + + +\def\@addjournalconfig{% + + +\ifcopyediting% Definition of layout used for copy-editing track changes document + \def\@journalurl{} + \def\@sentence{\textcolor[rgb]{1,0.58,0.25}{% + Copy-Editing track changes document -- Do not use for proof-reading}} + \let\@journalnameabbreviation\@sentence + \if@sansserifface + \definecolor{textcol}{rgb}{0,0,0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{gray}{0.8} + \definecolor{rulecol}{gray}{0.8} + \fi +\fi + +\ifacp%classical + \def\@journalname{Atmospheric Chemistry and Physics} + \def\@journalnameabbreviation{Atmos. Chem. Phys.} + \def\@journalnameshort{ACP} + \def\@journalnameshortlower{acp} + \def\@journalstartyear{2001} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.atmos-chem-phys.net} + \def\@journallogo{\includegraphics{ACP_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.447,0.737} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.0,0.447,0.737} + \else + \def\@journalurl{www.atmos-chem-phys-discuss.net} + \def\@journallogo{\includegraphics{ACPD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Atmospheric Chemistry\\ and Physics (ACP). Please refer to the corresponding final paper in ACP if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.0,0.58,0.91} + \definecolor{buttonbackground}{rgb}{0.0,0.58,0.91} + \definecolor{paneltext}{rgb}{0.0,0.58,0.91} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifbg%classical + \def\@journalname{Biogeosciences} + \def\@journalnameabbreviation{Biogeosciences} + \def\@journalnameshort{BG} + \def\@journalnameshortlower{bg} + \def\@journalstartyear{2004} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.biogeosciences.net} + \def\@journallogo{\includegraphics{BG_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.0,0.0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.612,0.698,0.145} + \else + \def\@journalurl{www.biogeosciences-discuss.net} + \def\@journallogo{\includegraphics{BGD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Biogeosciences (BG).\\ Please refer to the corresponding final paper in BG if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.612,0.698,0.145} + \definecolor{buttonbackground}{rgb}{0.612,0.698,0.145} + \definecolor{paneltext}{rgb}{0.612,0.698,0.145} + \definecolor{buttontext}{rgb}{0.612,0.0,0.055} + \fi + \fi +\fi +\iffr%classical + \def\@journalname{Fossil Record} + \def\@journalnameabbreviation{Foss. Rec.} + \def\@journalnameshort{FR} + \def\@journalnameshortlower{fr} + \def\@journalstartyear{1998} + \def\@sentence{Published by Copernicus Publications on behalf of the Museum f{\"u}r Naturkunde Berlin.} + \def\@journalurl{www.foss-rec.net} + \def\@journallogo{\includegraphics{FR_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifadgeo%classical + \def\@journalname{Advances in Geosciences} + \def\@journalnameabbreviation{Adv. Geosci.} + \def\@journalnameshort{ADGEO} + \def\@journalnameshortlower{adgeo} + \def\@journalstartyear{2013} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \def\@journalurl{www.adv-geosci.net} + \def\@journallogo{\includegraphics{ADGEO_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifamt%classical + \def\@journalname{Atmospheric Measurement Techniques} + \def\@journalnameabbreviation{Atmos. Meas. Tech.} + \def\@journalnameshort{AMT} + \def\@journalnameshortlower{amt} + \def\@journalstartyear{2008} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.atmos-meas-tech.net} + \def\@journallogo{\includegraphics{AMT_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.atmos-meas-tech-discuss.net} + \def\@journallogo{\includegraphics{AMTD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Atmospheric Measurement\\ Techniques (AMT). Please refer to the corresponding final paper in AMT if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.0,0.259,0.475} + \definecolor{buttonbackground}{rgb}{0.0,0.259,0.475} + \definecolor{paneltext}{rgb}{0.0,0.259,0.475} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifangeo%classical + \def\@journalname{Annales Geophysicae} + \def\@journalnameabbreviation{Ann. Geophys.} + \def\@journalnameshort{ANGEO} + \def\@journalnameshortlower{angeo} + \def\@journalstartyear{1983} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.ann-geophys.net} + \def\@journallogo{\includegraphics{ANGEO_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{} + \def\@journallogo{} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifars%classical + \def\@journalname{Advances in Radio Sciences} + \def\@journalnameabbreviation{Adv. Radio Sci.} + \def\@journalnameshort{ARS} + \def\@journalnameshortlower{ars} + \def\@journalstartyear{2003} + \def\@sentence{Published by Copernicus Publications on behalf of the URSI Landesausschuss in der Bundesrepublik Deutschland e.V.} + \def\@journalurl{www.adv-radio-sci.net} + \def\@journallogo{\includegraphics{ARS_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifastra%classical + \def\@journalname{Astrophysics and Space Sciences Transactions} + \def\@journalnameabbreviation{Astrophys. Space Sci. Trans.} + \def\@journalnameshort{ASTRA} + \def\@journalnameshortlower{astra} + \def\@journalstartyear{2004} + \def\@sentence{Published by Copernicus Publications on behalf of the Arbeitsgemeinschaft Extraterrestrische Forschung e.V.} + \def\@journalurl{www.astrophys-space-sci-trans.net} + \def\@journallogo{} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifcp%classical + \def\@journalname{Climate of the Past} + \def\@journalnameabbreviation{Clim. Past} + \def\@journalnameshort{CP} + \def\@journalnameshortlower{cp} + \def\@journalstartyear{2005} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.clim-past.net} + \def\@journallogo{\includegraphics{CP_Logo.pdf}} + \definecolor{textcol}{rgb}{0.357,0.039,0.475} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.clim-past-discuss.net} + \def\@journallogo{\includegraphics{CPD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Climate of the Past (CP).\\ Please refer to the corresponding final paper in CP if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.357,0.039,0.475} + \definecolor{buttonbackground}{rgb}{0.357,0.039,0.475} + \definecolor{paneltext}{rgb}{0.357,0.039,0.475} + \definecolor{buttontext}{rgb}{1.0,0.796,0.02} + \fi + \fi +\fi +\ifesd%classical + \def\@journalname{Earth System Dynamics} + \def\@journalnameabbreviation{Earth Syst. Dynam.} + \def\@journalnameshort{ESD} + \def\@journalnameshortlower{esd} + \def\@journalstartyear{2010} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.earth-syst-dynam.net} + \def\@journallogo{\includegraphics{ESD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.224,0.455} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.0,0.224,0.455} + \else + \def\@journalurl{www.earth-syst-dynam-discuss.net} + \def\@journallogo{\includegraphics{ESDD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Earth System\\ Dynamics (ESD). Please refer to the corresponding final paper in ESD if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.0,0.224,0.455} + \definecolor{buttonbackground}{rgb}{0.0,0.224,0.455} + \definecolor{paneltext}{rgb}{0.0,0.224,0.455} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifgi%classical + \def\@journalname{Geoscientific Instrumentation, Methods and Data Systems} + \def\@journalnameabbreviation{Geosci. Instrum. Method. Data Syst.} + \def\@journalnameshort{GI} + \def\@journalnameshortlower{gi} + \def\@journalstartyear{2012} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.geosci-instrum-method-data-syst.net} + \def\@journallogo{\includegraphics{GI_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.geosci-instrum-method-data-syst-discuss.net} + \def\@journallogo{\includegraphics{GID_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Geoscientific Instrumentation,\\ Methods and Data Systems (GI). Please refer to the corresponding final paper in GI if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.012,0.306,0.635} + \definecolor{buttonbackground}{rgb}{0.635,0.635,0.635} + \definecolor{paneltext}{rgb}{0.012,0.306,0.635} + \definecolor{buttontext}{rgb}{0.012,0.306,0.635} + \fi + \fi +\fi +\ifgmd%classical + \def\@journalname{Geoscientific Model Development} + \def\@journalnameabbreviation{Geosci. Model Dev.} + \def\@journalnameshort{GMD} + \def\@journalnameshortlower{gmd} + \def\@journalstartyear{2008} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.geosci-model-dev.net} + \def\@journallogo{\includegraphics{GMD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.0,0.0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.973,0.584,0.055} + \else + \def\@journalurl{www.geosci-model-dev-discuss.net} + \def\@journallogo{\includegraphics{GMDD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Geoscientific Model\\ Development (GMD). Please refer to the corresponding final paper in GMD if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.973,0.584,0.055} + \definecolor{buttonbackground}{rgb}{0.973,0.584,0.055} + \definecolor{paneltext}{rgb}{0.973,0.584,0.055} + \definecolor{buttontext}{rgb}{0.769,0.086,0.11} + \fi + \fi +\fi +\ifhess%classical + \def\@journalname{Hydrology and Earth System Sciences} + \def\@journalnameabbreviation{Hydrol. Earth Syst. Sci.} + \def\@journalnameshort{HESS} + \def\@journalnameshortlower{hess} + \def\@journalstartyear{1997} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.hydrol-earth-syst-sci.net} + \def\@journallogo{\includegraphics{HESS_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.hydrol-earth-syst-sci-discuss.net} + \def\@journallogo{\includegraphics{HESSD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Hydrology and Earth System\\ Sciences (HESS). Please refer to the corresponding final paper in HESS if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.38,0.643,0.161} + \definecolor{buttonbackground}{rgb}{0.38,0.643,0.161} + \definecolor{paneltext}{rgb}{0.38,0.643,0.161} + \definecolor{buttontext}{rgb}{0.122,0.153,0.498} + \fi + \fi +\fi +\ifnhess%classical + \def\@journalname{Natural Hazards and Earth System Sciences} + \def\@journalnameabbreviation{Nat. Hazards Earth Syst. Sci.} + \def\@journalnameshort{NHESS} + \def\@journalnameshortlower{nhess} + \def\@journalstartyear{2001} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.nat-hazards-earth-syst-sci.net} + \def\@journallogo{\includegraphics{NHESS_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.nat-hazards-earth-syst-sci-discuss.net} + \def\@journallogo{\includegraphics{NHESSD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Natural Hazards and Earth\\ System Sciences (NHESS). Please refer to the corresponding final paper in NHESS if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.263,0.416,0.702} + \definecolor{buttonbackground}{rgb}{0.69,0.639,0.576} + \definecolor{paneltext}{rgb}{0.263,0.416,0.702} + \definecolor{buttontext}{rgb}{0.263,0.416,0.702} + \fi + \fi +\fi +\ifnpg%classical + \def\@journalname{Nonlinear Processes in Geophysics} + \def\@journalnameabbreviation{Nonlin. Processes Geophys.} + \def\@journalnameshort{NPG} + \def\@journalnameshortlower{npg} + \def\@journalstartyear{1994} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union \& the American Geophysical Union.} + \if@stage@final + \def\@journalurl{www.nonlin-processes-geophys.net} + \def\@journallogo{\includegraphics{NPG_Logo.pdf}} + \definecolor{textcol}{rgb}{0.102,0.278,0.6} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.102,0.278,0.6} + \else + \def\@journalurl{www.nonlin-processes-geophys-discuss.net} + \def\@journallogo{\includegraphics{NPGD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Nonlinear Processes\\ in Geophysics (NPG). Please refer to the corresponding final paper in NPG if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.102,0.278,0.6} + \definecolor{buttonbackground}{rgb}{0.996,0.749,0.004} + \definecolor{paneltext}{rgb}{0.102,0.278,0.6} + \definecolor{buttontext}{rgb}{0.102,0.278,0.6} + \fi + \fi +\fi +\ifos%classical + \def\@journalname{Ocean Science} + \def\@journalnameabbreviation{Ocean Sci.} + \def\@journalnameshort{OS} + \def\@journalnameshortlower{os} + \def\@journalstartyear{2005} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.ocean-sci.net} + \def\@journallogo{\includegraphics{OS_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.ocean-sci-discuss.net} + \def\@journallogo{\includegraphics{OSD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Ocean Science (OS).\\ Please refer to the corresponding final paper in OS if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.039,0.282,0.494} + \definecolor{buttonbackground}{rgb}{0.039,0.282,0.494} + \definecolor{paneltext}{rgb}{0.039,0.282,0.494} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifse%classical + \def\@journalname{Solid Earth} + \def\@journalnameabbreviation{Solid Earth} + \def\@journalnameshort{SE} + \def\@journalnameshortlower{se} + \def\@journalstartyear{2010} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.solid-earth.net} + \def\@journallogo{\includegraphics{SE_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.solid-earth-discuss.net} + \def\@journallogo{\includegraphics{SED_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Solid Earth (SE).\\ Please refer to the corresponding final paper in SE if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.482,0.349,0.259} + \definecolor{buttonbackground}{rgb}{0.482,0.349,0.259} + \definecolor{paneltext}{rgb}{0.482,0.349,0.259} + \definecolor{buttontext}{rgb}{0.98,0.922,0.835} + \fi + \fi +\fi +\iftc%classical + \def\@journalname{The Cryosphere} + \def\@journalnameabbreviation{The Cryosphere} + \def\@journalnameshort{TC} + \def\@journalnameshortlower{tc} + \def\@journalstartyear{2007} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.the-cryosphere.net} + \def\@journallogo{\includegraphics{TC_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.the-cryosphere-discuss.net} + \def\@journallogo{\includegraphics{TCD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal The Cryosphere (TC).\\ Please refer to the corresponding final paper in TC if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.341,0.596,0.824} + \definecolor{buttonbackground}{rgb}{0.341,0.596,0.824} + \definecolor{paneltext}{rgb}{0.341,0.596,0.824} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifessd%classical + \def\@journalname{Earth System Science Data} + \def\@journalnameabbreviation{Earth Syst. Sci. Data} + \def\@journalnameshort{ESSD} + \def\@journalnameshortlower{essd} + \def\@journalstartyear{2009} + \def\@sentence{Published by Copernicus Publications.} + \if@stage@final + \def\@journalurl{www.earth-syst-sci-data.net} + \def\@journallogo{\includegraphics{ESSD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.102,0.4,0.573} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.earth-syst-sci-data-discuss.net} + \def\@journallogo{\includegraphics{ESSDD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Earth System Science\\ Data (ESSD). Please refer to the corresponding final paper in ESSD if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.102,0.4,0.573} + \definecolor{buttonbackground}{rgb}{0.102,0.4,0.573} + \definecolor{paneltext}{rgb}{0.102,0.4,0.573} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifesurf%classical + \def\@journalname{Earth Surface Dynamics} + \def\@journalnameabbreviation{Earth Surf. Dynam.} + \def\@journalnameshort{ESURF} + \def\@journalnameshortlower{esurf} + \def\@journalstartyear{2013} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.earth-surf-dynam.net} + \def\@journallogo{\includegraphics{ESURF_Logo.pdf}} + \definecolor{textcol}{rgb}{0.541,0.549,0.557} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.earth-surf-dynam-discuss.net} + \def\@journallogo{\includegraphics{ESURFD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Earth Surface Dynamics (ESurfD).\\ Please refer to the corresponding final paper in ESurf if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.0,0.0,0.0} + \definecolor{buttonbackground}{rgb}{0.541,0.549,0.557} + \definecolor{paneltext}{rgb}{0.0,0.0,0.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifgh%classical + \def\@journalname{Geographica Helvetica} + \def\@journalnameabbreviation{Geogr. Helv.} + \def\@journalnameshort{GH} + \def\@journalnameshortlower{gh} + \def\@journalstartyear{1946} + \def\@sentence{\small Published by Copernicus Publications for the Geographisch-Ethnographische Gesellschaft Z\"urich \& Association Suisse de G\'eographie.} + \def\@journalurl{www.geogr-helv.net} + \def\@journallogo{\includegraphics{GH_Logo.pdf}} + \definecolor{textcol}{rgb}{0.569,0.58,0.588} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.569,0.58,0.588} +\fi +\ifhgss%classical + \def\@journalname{History of Geo- and Space Sciences} + \def\@journalnameabbreviation{Hist. Geo Space Sci.} + \def\@journalnameshort{HGSS} + \def\@journalnameshortlower{hgss} + \def\@journalstartyear{2010} + \def\@sentence{Published by Copernicus Publications.} + \if@stage@final + \def\@journalurl{www.hist-geo-space-sci.net} + \def\@journallogo{\includegraphics{HGSS_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.443,0.706} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.0,0.443,0.706} + \else + \def\@journalurl{https://hgss.copernicus.org/preprints/preprints.html} + \def\@journallogo{\includegraphics{HGSSD_Logo.pdf}} + \def\@sentenceDiscussion{This preprint is/has been under review for the journal History of Geo- and Space Sciences (HGSS). Please refer to the corresponding final paper in HGSS if available.} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifjsss%classical + \def\@journalname{Journal of Sensors and Sensor Systems} + \def\@journalnameabbreviation{J. Sens. Sens. Syst.} + \def\@journalnameshort{JSSS} + \def\@journalnameshortlower{jsss} + \def\@journalstartyear{2012} + \def\@sentence{Published by Copernicus Publications on behalf of the AMA Association for Sensor Technology.} + \def\@journalurl{www.j-sens-sens-syst.net} + \def\@journallogo{\includegraphics{JSSS_Logo.pdf}} + \definecolor{textcol}{rgb}{0.051,0.298,0.561} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.051,0.298,0.561} +\fi +\ifms%classical + \def\@journalname{Mechanical Sciences} + \def\@journalnameabbreviation{Mech. Sci.} + \def\@journalnameshort{MS} + \def\@journalnameshortlower{ms} + \def\@journalstartyear{2010} + \def\@sentence{Published by Copernicus Publications.} + \def\@journalurl{www.mech-sci.net} + \def\@journallogo{\includegraphics{MS_Logo.pdf}} + \definecolor{textcol}{rgb}{0.471,0.655,0.808} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{0.0,0.0,0.0} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifasr%classical + \def\@journalname{Advances in Science and Research} + \def\@journalnameabbreviation{Adv. Sci. Res.} + \def\@journalnameshort{ASR} + \def\@journalnameshortlower{asr} + \def\@journalstartyear{2007} + \def\@sentence{Published by Copernicus Publications.} + \def\@journalurl{www.adv-sci-res.net} + \def\@journallogo{\includegraphics{ASR_Logo.pdf}} + \definecolor{textcol}{rgb}{0.004,0.302,0.545} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.004,0.302,0.545} +\fi +\ifsdsr%classical + \def\@journalname{Scientific Drilling - Science Reports} + \def\@journalnameabbreviation{Sci. Dril.} + \def\@journalnameshort{SD} + \def\@journalnameshortlower{sd} + \def\@journalstartyear{2013} + \def\@sentence{Published by Copernicus Publications on behalf of the IODP and the ICDP.} + \def\@journalurl{www.sci-dril.net} + \def\@journallogo{\includegraphics{SD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.075,0.239,0.553} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.075,0.239,0.553} +\fi +\ifsdpr%classical + \def\@journalname{Scientific Drilling - Progress Reports} + \def\@journalnameabbreviation{Sci. Dril.} + \def\@journalnameshort{SD} + \def\@journalnameshortlower{sd} + \def\@journalstartyear{2013} + \def\@sentence{Published by Copernicus Publications on behalf of the IODP and the ICDP.} + \def\@journalurl{www.sci-dril.net} + \def\@journallogo{\includegraphics{SD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.906,0.651,0.278} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.906,0.651,0.278} +\fi +\ifsdtd%classical + \def\@journalname{Scientific Drilling - Technical Developments} + \def\@journalnameabbreviation{Sci. Dril.} + \def\@journalnameshort{SD} + \def\@journalnameshortlower{sd} + \def\@journalstartyear{2013} + \def\@sentence{Published by Copernicus Publications on behalf of the IODP and the ICDP.} + \def\@journalurl{www.sci-dril.net} + \def\@journallogo{\includegraphics{SD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.722,0.094,0.141} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{0.722,0.094,0.141} +\fi +\ifsdwr%classical + \def\@journalname{Scientific Drilling - Workshop Reports} + \def\@journalnameabbreviation{Sci. Dril.} + \def\@journalnameshort{SD} + \def\@journalnameshortlower{sd} + \def\@journalstartyear{2013} + \def\@sentence{Published by Copernicus Publications on behalf of the IODP and the ICDP.} + \def\@journalurl{www.sci-dril.net} + \def\@journallogo{\includegraphics{SD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.486,0.298,0.216} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.486,0.298,0.216} +\fi +\ifsdpd%classical + \def\@journalname{Scientific Drilling - Program Developments} + \def\@journalnameabbreviation{Sci. Dril.} + \def\@journalnameshort{SD} + \def\@journalnameshortlower{sd} + \def\@journalstartyear{2013} + \def\@sentence{Published by Copernicus Publications on behalf of the IODP and the ICDP.} + \def\@journalurl{www.sci-dril.net} + \def\@journallogo{\includegraphics{SD_Logo.pdf}} + \definecolor{textcol}{rgb}{0.027,0.498,0.325} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.027,0.498,0.325} +\fi +\ifwe%classical + \def\@journalname{Web Ecology} + \def\@journalnameabbreviation{Web Ecol.} + \def\@journalnameshort{WE} + \def\@journalnameshortlower{we} + \def\@journalstartyear{2001} + \def\@sentence{Published by Copernicus Publications on behalf of the European Ecological Federation (EEF).} + \def\@journalurl{www.web-ecol.net} + \def\@journallogo{\includegraphics{WE_Logo.pdf}} + \definecolor{textcol}{rgb}{0.2,0.6,0.2} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.2,0.6,0.2} +\fi +\ifangeocom%classical + \def\@journalname{AnGeo Communicates} + \def\@journalnameabbreviation{Ann. Geophys.} + \def\@journalnameshort{ANGEOCOM} + \def\@journalnameshortlower{angeo} + \def\@journalstartyear{1983} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.ann-geophys.net} + \def\@journallogo{\includegraphics{ANGEO_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{0.851,0.851,0.851} + \definecolor{rulecol}{rgb}{0.0,0.0,0.0} + \else + \def\@journalurl{} + \def\@journallogo{} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifsoil%classical + \def\@journalname{SOIL} + \def\@journalnameabbreviation{SOIL} + \def\@journalnameshort{SOIL} + \def\@journalnameshortlower{soil} + \def\@journalstartyear{2015} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.soil-journal.net} + \def\@journallogo{\includegraphics{SOIL_Logo.pdf}} + \definecolor{textcol}{rgb}{0.29,0.267,0.165} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.29,0.267,0.165} + \else + \def\@journalurl{www.soil-discuss.net} + \def\@journallogo{\includegraphics{SOILD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal SOIL. Please refer to the\\ corresponding final paper in SOIL if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.29,0.267,0.165} + \definecolor{buttonbackground}{rgb}{0.29,0.267,0.165} + \definecolor{paneltext}{rgb}{0.29,0.267,0.165} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifpb%classical + \def\@journalname{Primate Biology} + \def\@journalnameabbreviation{Primate Biol.} + \def\@journalnameshort{PB} + \def\@journalnameshortlower{pb} + \def\@journalstartyear{2014} + \def\@sentence{Published by Copernicus Publications on behalf of the Deutsches Primatenzentrum GmbH (DPZ).} + \def\@journalurl{www.primate-biol.net} + \def\@journallogo{\includegraphics{PB_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.0,0.0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{0.0,0.0,0.0} +\fi +\ifascmo%classical + \def\@journalname{Advances in Statistical Climatology, Meteorology and Oceanography} + \def\@journalnameabbreviation{Adv. Stat. Clim. Meteorol. Oceanogr.} + \def\@journalnameshort{ASCMO} + \def\@journalnameshortlower{ascmo} + \def\@journalstartyear{2015} + \def\@sentence{Published by Copernicus Publications.} + \def\@journalurl{www.adv-stat-clim-meteorol-oceanogr.net} + \def\@journallogo{\includegraphics{ASCMO_Logo.pdf}} + \definecolor{textcol}{rgb}{0.392,0.039,0.039} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.392,0.039,0.039} +\fi +\ifpiahs%classical + \def\@journalname{Proceedings of the International Association of Hydrological Sciences} + \def\@journalnameabbreviation{Proc. IAHS} + \def\@journalnameshort{PIAHS} + \def\@journalnameshortlower{piahs} + \def\@journalstartyear{1924} + \def\@sentence{Published by Copernicus Publications on behalf of the International Association of Hydrological Sciences.} + \def\@journalurl{proc-iahs.net} + \def\@journallogo{\includegraphics{PIAHS_Logo.pdf}} + \definecolor{textcol}{rgb}{0.553,0.035,0.035} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.553,0.035,0.035} +\fi +\ifaab%classical + \def\@journalname{Archives Animal Breeding} + \def\@journalnameabbreviation{Arch. Anim. Breed.} + \def\@journalnameshort{AAB} + \def\@journalnameshortlower{aab} + \def\@journalstartyear{2015} + \def\@sentence{Published by Copernicus Publications on behalf of the Research Institute for Farm Animal Biology (FBN).} + \def\@journalurl{www.arch-anim-breed.net} + \def\@journallogo{\includegraphics{AAB_Logo.pdf}} + \definecolor{textcol}{rgb}{0.6,0.0,0.0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifwes%classical + \def\@journalname{Wind Energy Science} + \def\@journalnameabbreviation{Wind Energ. Sci.} + \def\@journalnameshort{WES} + \def\@journalnameshortlower{wes} + \def\@journalstartyear{2016} + \def\@sentence{Published by Copernicus Publications on behalf of the European Academy of Wind Energy e.V.} + \if@stage@final + \def\@journalurl{www.wind-energ-sci.net} + \def\@journallogo{\includegraphics{WES_Logo.pdf}} + \definecolor{textcol}{rgb}{0.075,0.263,0.565} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.075,0.263,0.565} + \else + \def\@journalurl{www.wind-energ-sci-discuss.net} + \def\@journallogo{\includegraphics{WESD_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Wind Energy Science (WES).\\ Please refer to the corresponding final paper in WES if available.} + \if@cop@home + \definecolor{journalname}{rgb}{0.075,0.263,0.565} + \definecolor{buttonbackground}{rgb}{0.075,0.263,0.565} + \definecolor{paneltext}{rgb}{0.075,0.263,0.565} + \definecolor{buttontext}{rgb}{0.584,0.761,0.239} + \fi + \fi +\fi +\ifjm%classical + \def\@journalname{Journal of Micropalaeontology} + \def\@journalnameabbreviation{J. Micropalaeontology} + \def\@journalnameshort{JM} + \def\@journalnameshortlower{jm} + \def\@journalstartyear{1982} + \def\@sentence{Published by Copernicus Publications on behalf of The Micropalaeontological Society.} + \def\@journalurl{www.j-micropalaeontol.net/} + \def\@journallogo{\includegraphics{JM_Logo.pdf}} + \definecolor{textcol}{rgb}{0.047,0.306,0.427} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{0.047,0.306,0.427} +\fi +\ifegqsj%classical + \def\@journalname{E&G Quaternary Science Journal} + \def\@journalnameabbreviation{E\&G Quaternary Sci. J.} + \def\@journalnameshort{EGQSJ} + \def\@journalnameshortlower{egqsj} + \def\@journalstartyear{1951} + \def\@sentence{Published by Copernicus Publications on behalf of the Deutsche Quart\"arvereinigung (DEUQUA) e.V.} + \def\@journalurl{www.eg-quaternary-sci-j.net} + \def\@journallogo{\includegraphics{EGQSJ_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.459,0.722} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifgc%classical + \def\@journalname{Geoscience Communication} + \def\@journalnameabbreviation{Geosci. Commun.} + \def\@journalnameshort{GC} + \def\@journalnameshortlower{gc} + \def\@journalstartyear{2018} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.geosci-commun.net} + \def\@journallogo{\includegraphics{GC_Logo.pdf}} + \definecolor{textcol}{rgb}{0.067,0.494,1.0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{0.067,0.494,1.0} + \else + \def\@journalurl{www.geosci-commun-discuss.net} + \def\@journallogo{\includegraphics{GCD_Logo.pdf}} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifdeuquasp%classical + \def\@journalname{DEUQUA Special Publications} + \def\@journalnameabbreviation{DEUQUA Spec. Pub.} + \def\@journalnameshort{DEUQUASP} + \def\@journalnameshortlower{deuquasp} + \def\@journalstartyear{2018} + \def\@sentence{Published by Copernicus Publications on behalf of the Deutsche Quart\"arvereinigung (DEUQUA) e.V.} + \def\@journalurl{www.deuqua-spec-pub.net} + \def\@journallogo{\includegraphics{DEUQUASP_Logo.pdf}} + \definecolor{textcol}{rgb}{0.529,0.533,0.541} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifgchron%classical + \def\@journalname{Geochronology} + \def\@journalnameabbreviation{Geochronology} + \def\@journalnameshort{GCHRON} + \def\@journalnameshortlower{gchron} + \def\@journalstartyear{2019} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.geochronology.net} + \def\@journallogo{\includegraphics{GCHRON_Logo.pdf}} + \definecolor{textcol}{rgb}{0.447,0.247,0.329} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.geochronology-discuss.net} + \def\@journallogo{\includegraphics{GCHROND_Logo.pdf}} + \def\@sentenceDiscussion{This discussion paper is/has been under review for the journal Geochronology (GChron).\\ Please refer to the corresponding final paper in GChron if available.} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifwcd%classical + \def\@journalname{Weather and Climate Dynamics} + \def\@journalnameabbreviation{Weather Clim. Dynam.} + \def\@journalnameshort{WCD} + \def\@journalnameshortlower{wcd} + \def\@journalstartyear{2019} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{www.weather-clim-dynam.net} + \def\@journallogo{\includegraphics{WCD_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{www.weather-clim-dynam-discuss.net} + \def\@journallogo{\includegraphics{WCDD_Logo.pdf}} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifejm%classical + \def\@journalname{European Journal of Mineralogy} + \def\@journalnameabbreviation{Eur. J. Mineral.} + \def\@journalnameshort{EJM} + \def\@journalnameshortlower{ejm} + \def\@journalstartyear{1989} + \def\@sentence{Published by Copernicus Publications on behalf of the European mineralogical societies DMG, SEM, SIMP \& SFMC.} + \def\@journalurl{www.eur-j-mineral.net} + \def\@journallogo{\includegraphics{EJM_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.0,0.0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifmr%classical + \def\@journalname{Magnetic Resonance} + \def\@journalnameabbreviation{Magn. Reson.} + \def\@journalnameshort{MR} + \def\@journalnameshortlower{mr} + \def\@journalstartyear{2020} + \def\@sentence{Published by Copernicus Publications on behalf of the Groupement AMPERE.} + \if@stage@final + \def\@journalurl{www.magn-reson.net} + \def\@journallogo{\includegraphics{MR_Logo.pdf}} + \definecolor{textcol}{rgb}{0.627,0.098,0.086} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{} + \def\@journallogo{\includegraphics{MRD_Logo.pdf}} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifjbji%classical + \def\@journalname{Journal of Bone and Joint Infection} + \def\@journalnameabbreviation{J. Bone Joint Infect.} + \def\@journalnameshort{JBJI} + \def\@journalnameshortlower{jbji} + \def\@journalstartyear{2016} + \def\@sentence{Published by Copernicus Publications on behalf of EBJIS and MSIS.} + \def\@journalurl{https://jbji.copernicus.org/} + \def\@journallogo{\includegraphics{JBJI_Logo.pdf}} + \definecolor{textcol}{rgb}{0.161,0.337,0.361} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.161,0.337,0.361} +\fi +\ifpolf%classical + \def\@journalname{Polarforschung - Journal of the German Society for Polar Research} + \def\@journalnameabbreviation{Polarforschung} + \def\@journalnameshort{POLF} + \def\@journalnameshortlower{polf} + \def\@journalstartyear{1931} + \def\@sentence{Published by Copernicus Publications on behalf of the Deutsche Gesellschaft für Polarforschung e.V.} + \def\@journalurl{https://polf.copernicus.org} + \def\@journallogo{\includegraphics{POLF_Logo.pdf}} + \definecolor{textcol}{rgb}{0.306,0.525,0.682} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} +\fi +\ifsand%classical + \def\@journalname{Safety of Nuclear Waste Disposal} + \def\@journalnameabbreviation{Saf. Nucl. Waste Disposal} + \def\@journalnameshort{SAND} + \def\@journalnameshortlower{sand} + \def\@journalstartyear{2021} + \def\@sentence{Published by Copernicus Publications on behalf of the Federal Office for the Safety of Nuclear Waste Management (BASE).} + \def\@journalurl{www.sand.copernicus.org} + \def\@journallogo{\includegraphics{SAND_Logo.pdf}} + \definecolor{textcol}{rgb}{0.0,0.0,0.0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.0,0.0,0.0} +\fi +\ifegusphere%classical + \def\@journalname{EGUsphere} + \def\@journalnameabbreviation{EGUsphere} + \def\@journalnameshort{EGUSPHERE} + \def\@journalnameshortlower{egusphere} + \def\@journalstartyear{2022} + \def\@sentence{Published by Copernicus Publications on behalf of the European Geosciences Union.} + \if@stage@final + \def\@journalurl{https://egusphere.copernicus.org} + \def\@journallogo{\includegraphics{EGUSPHERE_Logo.pdf}} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{rulecol}{rgb}{1.0,1.0,1.0} + \else + \def\@journalurl{https://egusphere.copernicus.org} + \def\@journallogo{\includegraphics{EGUSPHERE_Logo.pdf}} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{0.0,0.0,0.0} + \definecolor{buttonbackground}{rgb}{0.0,0.0,0.0} + \definecolor{paneltext}{rgb}{0.0,0.0,0.0} + \definecolor{buttontext}{rgb}{0.0,0.0,0.0} + \fi + \fi +\fi +\ifsp%classical + \def\@journalname{State of the Planet} + \def\@journalnameabbreviation{State Planet} + \def\@journalnameshort{SP} + \def\@journalnameshortlower{sp} + \def\@journalstartyear{2023} + \def\@sentence{Published by Copernicus Publications.} + \if@stage@final + \def\@journalurl{https://sp.copernicus.org/} + \def\@journallogo{\includegraphics{SP_Logo.pdf}} + \definecolor{textcol}{rgb}{0.008,0.239,0.365} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.008,0.239,0.365} + \else + \def\@journalurl{} + \def\@journallogo{\includegraphics{SPD_Logo.pdf}} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi +\ifar%classical + \def\@journalname{Aerosol Research} + \def\@journalnameabbreviation{Aerosol Res.} + \def\@journalnameshort{AR} + \def\@journalnameshortlower{ar} + \def\@journalstartyear{2023} + \def\@sentence{Published by Copernicus Publications on behalf of the European Aerosol Assembly (EAA).} + \if@stage@final + \def\@journalurl{https://ar.copernicus.org/} + \def\@journallogo{\includegraphics{AR_Logo.pdf}} + \definecolor{textcol}{rgb}{0.369,0.522,0.671} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1.0,1.0,1.0} + \definecolor{rulecol}{rgb}{0.369,0.522,0.671} + \else + \def\@journalurl{} + \def\@journallogo{\includegraphics{ARD_Logo.pdf}} + \def\@sentenceDiscussion{} + \if@cop@home + \definecolor{journalname}{rgb}{1.0,1.0,1.0} + \definecolor{buttonbackground}{rgb}{1.0,1.0,1.0} + \definecolor{paneltext}{rgb}{1.0,1.0,1.0} + \definecolor{buttontext}{rgb}{1.0,1.0,1.0} + \fi + \fi +\fi + +} \ No newline at end of file diff --git a/acp/accepted/copernicus.cls b/acp/accepted/copernicus.cls new file mode 100644 index 0000000000000000000000000000000000000000..68ae6219d8e915cfcf8ba81e5e3bfb0092e32cb4 --- /dev/null +++ b/acp/accepted/copernicus.cls @@ -0,0 +1,3080 @@ +%% +%% This is file `copernicus.cls', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% copernicus.dtx (with options: `class') +%% +%% ----------------------------------------------------------------- +%% Author: copernicus.org and le-tex publishing services +%% +%% This file is part of the copernicus package for papers +%% published by Copernicus Publications (Copernicus GmbH). +%% +%% Copyright (C) 2023 by Copernicus Publications +%% ----------------------------------------------------------------- +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesClass{copernicus} + [2023/10/11 10.1.10 Copernicus papers] +\frenchspacing +\clubpenalty10000 +\widowpenalty10000 +\RequirePackage{iftex} +%% protrudechars, \adjustspacing \hypenationmin, +%% lccode, \hjcode ???, exhyphenchar,\automatichyphenmode, hyphenchar +\newcommand*\@iflatexlater{\@ifl@t@r\fmtversion} +\@iflatexlater{2020/10/01}{}{\RequirePackage{ifluatex}\RequirePackage{ifxetex}} +\ifluatex + \let\pdfoutput\outputmode + \edef\pdfpageattr{\pdfvariable pageattr} + \RequirePackage{newunicodechar} +\fi +%% \RequirePackage{fixltx2e}[2006/03/24] +\protected@edef\CopernicusInfo#1{\protect\ClassInfo{copernicus}{#1}} +\protected@edef\CopernicusWarningNoLine#1{\protect\ClassWarningNoLine{copernicus}{#1}} +\protected@edef\CopernicusError#1#2{\protect\ClassError{copernicus}{#1}{#2}} +\let\@classfilename\@currname +\newcommand\UndefinedError[1] + {\CopernicusError{You must define #1}{Add #1 to your document!}} +\newcommand\NoSectionWarning[1] + {\CopernicusWarningNoLine{No section #1; proceeding without it}} +\newcommand\NoSectionError[2] + {\CopernicusError{You forgot the section: #1}{Add #2 to your document!}} +\renewcommand*\and{\@centercr} +\AtEndOfClass{% + \DeclareRobustCommand*{\vec}[1] + {\ensuremath{% + \mathchoice{\mbox{\boldmath$\displaystyle#1$}} + {\mbox{\boldmath$\textstyle#1$}} + {\mbox{\boldmath$\scriptstyle#1$}} + {\mbox{\boldmath$\scriptscriptstyle#1$}}}}} + +\newcommand{\xmp@keywords}[1]{% + \begingroup + \let\hack\@gobble + \protected@xdef\@xmp@keywords{#1}% + \endgroup +} +\xmp@keywords{}% +\newcommand{\xmp@title}[1]{% + \begingroup + \let\hack\@gobble + \let\@xmp@title\Hy@title + %\protected@xdef\@xmp@title{#1}% + \endgroup +} +\xmp@title{}% +\let\@xmp@authors\@empty +\let\@pdf@authors\@empty +\begingroup\obeyspaces +\gdef\xmp@author#1{% + \begingroup + \def~{ }% + \let\hack\@gobble + \def\nobreakspace{ }% + \protected@edef\@tempx{#1}% + \protected@xdef\@pdf@authors{\@pdf@authors\ifx\@pdf@authors\@empty\else, \fi\@tempx}% + \protected@xdef\@xmp@authors{\@xmp@authors <rdf:li>\@tempx</rdf:li>^^J}% + \endgroup +} +\endgroup +\thinmuskip=2mu +\medmuskip=3mu minus 3mu +\thickmuskip=4mu +\def\cop@opterrshort{Option "\CurrentOption" not supported} +\def\cop@opterrlong{% + The option "\CurrentOption" from article.cls is not supported by copernicus.cls.} +\DeclareOption{a4paper}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{a5paper}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{b5paper}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{letterpaper}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{legalpaper}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{executivepaper}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{landscape}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{10pt}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{11pt}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{12pt}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{oneside}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{twoside}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{titlepage}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{notitlepage}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{onecolumn}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{twocolumn}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\DeclareOption{fleqn}{\@latexerr{\cop@opterrshort}{\cop@opterrlong}} +\newif\if@stage@final \@stage@finaltrue +\newif\if@sansserifface +\newif\if@sansserifheader +\newif\if@abstractcentered +\newif\if@abstractindented +\newif\if@noauthor \DeclareOption{noauthor}{\@noauthortrue} +\newif\if@nolastpage \DeclareOption{nolastpage}{\@nolastpagetrue} +\newif\if@noref \DeclareOption{noref}{\@noreftrue} +\newif\if@copDebug \DeclareOption{debug}{\@copDebugtrue} +\newif\if@nohyperref \DeclareOption{nohyperref}{\@nohyperreftrue} +\newif\if@cop@home \IfFileExists{copernicuslogo.pdf}{\@cop@hometrue}{\@cop@homefalse} +\newif\ifonline \DeclareOption{online}{\onlinetrue} +\newif\if@twostagejnl +\newif\if@forHTML +\newif\if@manuscript \DeclareOption{manuscript}{\@manuscripttrue} +\newif\if@proof \DeclareOption{proof}{\@prooftrue} +\newif\if@noline \DeclareOption{noline}{\@nolinetrue}%classical +\DeclareOption{corrigendum} {\def\specialp@perstring{Corrigendum}} +\DeclareOption{editorialnote}{\def\specialp@perstring{Editorial note}} +\def\jurl@splitter#1.net\@nil{\def\jurl@first{#1}} +\DeclareOption{editorialnotediscussion}{% + \def\specialp@perstring{Editorial note}% + \@noreftrue + \AtEndOfClass{% + \edef\@journalnameabbreviation{\@journalnameabbreviation\space Discuss.}% + \expandafter\jurl@splitter\@journalurl\@nil + \edef\@journalurl{\jurl@first-discuss.net}}} +\newif\if@preface%ask Lupino +\DeclareOption{preface} {\@prefacetrue} +\DeclareOption{forHTML} {\@forHTMLtrue} +\newif\if@corrigendum%ask Jasch +\newif\if@editorialnotetwoc%ask Jasch +\newif\if@editorialnoted%ask Jasch +\newif\if@secline% Underlined Sections, lup 2017-11-06 +\newif\if@dolinesec\@dolinesecfalse +\newif\if@bar %only used under \if@stage@final and \@cop@hometrue; for modern layout as well as for the classically layouted sub-journal "angeocom" +\newif\if@firstbar %only used under \if@stage@final and \@cop@hometrue; for modern layout as well as for the classically layouted sub-journal "angeocom" +\newif\if@hvmath \DeclareOption{hvmath}{\@hvmathtrue}%only used for discussions and only under \@cop@hometrue +\InputIfFileExists{copernicus.cfg}% + {\typeout{Additional configuration file copernicus.cfg used}}% + {\CopernicusError{No additional configuration file copernicus.cfg} + {Please provide copernicus.cfg with the journal configurations.}} + +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} +\ProcessOptions +\if@stage@final\else\@twostagejnltrue\fi +\if@cop@home\else + \if@stage@final\else\@stage@finaltrue\@manuscripttrue\fi +\fi +\if@manuscript + \@sansseriffacefalse + \@sansserifheaderfalse + \@abstractcenteredfalse + \@abstractindentedfalse +\fi +\AtEndOfClass{\ifcopyediting\let\@msnumber\relax\fi} +\LoadClass[fleqn]{article} +\AtBeginDocument{\mathindent\z@} +\if@stage@final + \if@manuscript + \oddsidemargin16.4mm + \evensidemargin16.4mm + \textwidth177mm + \textheight\dimexpr660\p@-37mm+11.4mm\relax + \headheight\z@ + \headsep\z@ + \topmargin10mm + \footskip30pt + \else + \let\footnotesize\small + \oddsidemargin16.4mm + \evensidemargin16.4mm + \textwidth177mm + \headheight16.4mm + \headsep5mm + \topskip12pt + \footskip30pt + \textheight54\baselineskip + \advance\textheight by\topskip + \topmargin\z@ + \fi +\else + \renewcommand\normalsize{% + \@setfontsize\normalsize\@xipt{13.6}% + \abovedisplayskip 11\p@ \@plus3\p@ \@minus6\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6.5\p@ \@plus3.5\p@ \@minus3\p@ + \belowdisplayskip \abovedisplayskip + \let\@listi\@listI} + \normalsize + \renewcommand\small{% + \@setfontsize\small\@xpt\@xiipt + \abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@ + \abovedisplayshortskip \z@ \@plus3\p@ + \belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@ + \def\@listi{\leftmargin\leftmargini + \topsep 6\p@ \@plus2\p@ \@minus2\p@ + \parsep 3\p@ \@plus2\p@ \@minus\p@ + \itemsep \parsep}% + \belowdisplayskip \abovedisplayskip} + \let\footnotesize\small + \def\scriptsize{\@setfontsize\scriptsize\@viiipt{9.5}} + \def\tiny{\@setfontsize\tiny\@vipt\@viipt} + \headheight\z@ + \headsep\z@ + \topskip\z@ + \footskip5mm + \textwidth146mm + \textheight140mm + \advance\textheight by\topskip + \oddsidemargin-15.4mm + \evensidemargin-15.4mm + \topmargin-18.4mm +\fi +\parindent1em +\newdimen\bleed \bleed3mm\relax +\if@stage@final + \hoffset\dimexpr-1in+\bleed\relax + \voffset\dimexpr-1in+\bleed\relax + \if@manuscript + \paperheight\dimexpr240mm+2\bleed\relax%2015-12-14 + \else + \paperheight\dimexpr277mm+2\bleed\relax + \fi + \paperwidth\dimexpr210mm+2\bleed\relax + \@tempdima\dimexpr1in+\hoffset\relax + \@tempdimb\dimexpr\@tempdima+\paperwidth-2\bleed\relax + \@tempdima\dimexpr\@tempdima*7200/7227\relax\edef\l@offset{\strip@pt\@tempdima} + \@tempdimb\dimexpr\@tempdimb*7200/7227\relax\edef\r@offset{\strip@pt\@tempdimb} + \@tempdima\dimexpr1in+\voffset\relax + \@tempdimb\dimexpr\@tempdima+\paperheight-2\bleed\relax + \@tempdima\dimexpr\@tempdima*7200/7227\relax\edef\u@offset{\strip@pt\@tempdima} + \@tempdimb\dimexpr\@tempdimb*7200/7227\relax\edef\o@offset{\strip@pt\@tempdimb} + %and now for the bleed box: + \@tempdima\dimexpr1in+\hoffset-\bleed\relax + \@tempdimb\dimexpr\@tempdima+\paperwidth+2\bleed\relax + \@tempdima\dimexpr\@tempdima*7200/7227\relax\edef\b@l@offset{\strip@pt\@tempdima} + \@tempdimb\dimexpr\@tempdimb*7200/7227\relax\edef\b@r@offset{\strip@pt\@tempdimb} + \@tempdima\dimexpr1in+\voffset-\bleed\relax + \@tempdimb\dimexpr\@tempdima+\paperheight+2\bleed\relax + \@tempdima\dimexpr\@tempdima*7200/7227\relax\edef\b@u@offset{\strip@pt\@tempdima} + \@tempdimb\dimexpr\@tempdimb*7200/7227\relax\edef\b@o@offset{\strip@pt\@tempdimb} + \ifnum\pdfoutput=\z@ + \newcommand{\@setPdfBoxes}{% + \ifx\@processPdfBoxSpec\@empty\relax + \else + {% + \special{!userdict begin + /bop-hook {^^J + \@processPdfBoxSpec} def + end}} + \fi} + \let\@processPdfBoxSpec\@empty + \newcommand\@setPdfBox[2]{% + \xdef\@processPdfBoxSpec{% + \@processPdfBoxSpec + [ {ThisPage} << /#1 [#2] >> /PUT pdfmark} } + \@setPdfBox{TrimBox}{\l@offset\space\u@offset\space\r@offset\space\o@offset} + \@setPdfBox{CropBox}{\l@offset\space\u@offset\space\r@offset\space\o@offset} + \@setPdfBox{BleedBox}{\b@l@offset\space\b@u@offset\space\b@r@offset\space\b@o@offset} + \@setPdfBoxes + \@onlypreamble\@setPdfBoxes + \else + \edef\@tempa{% + /TrimBox [\l@offset\space\u@offset\space\r@offset\space\o@offset] + /CropBox [\l@offset\space\u@offset\space\r@offset\space\o@offset] + /BleedBox[\b@l@offset\space\b@u@offset\space\b@r@offset\space\b@o@offset]} + \expandafter\pdfpageattr\expandafter{\@tempa} + \fi +\else%discussions + \paperheight159mm + \paperwidth166mm +\fi +\parskip0pt% plus 1pt +\def\topfraction{1}%standard is .7 +\def\textfraction{0}%standard is .2 +\def\floatpagefraction{.7}%standard is .5 +\def\dbltopfraction{1}%standard is .7 +\def\dblfloatpagefraction{.7}%standard is .5 +\if@stage@final + \def\@ddsidemarginbar{% + \rlap{% + \@tempdima-6.5mm\kern-\@tempdima + \@tempdima\dimexpr\@tempdima+\paperwidth-\textwidth-\oddsidemargin+\bleed\relax + \@tempdimb\dimexpr\headheight+\topmargin\relax + \@tempdimc\dimexpr\paperheight-\@tempdimb\relax + \advance\@tempdimb\bleed + \advance\@tempdimc\bleed + \smash{\vrule\@width\@tempdima\@height\@tempdimb\@depth\@tempdimc}}} + \def\@vensidemarginbar{% + \llap{% + \@tempdima\dimexpr1in+\evensidemargin+\bleed\relax + \@tempdimb\dimexpr\headheight+\topmargin\relax + \@tempdimc\dimexpr\paperheight-\@tempdimb\relax + \advance\@tempdimb\bleed + \advance\@tempdimc\bleed + \smash{\vrule\@width\@tempdima\@height\@tempdimb\@depth\@tempdimc}% + \kern6.5mm}} + \def\@ddsidemarginrule{% + \rlap{% + \@tempdima0.8\p@ + \kern6.5mm\kern-0.5\@tempdima + \@tempdimb\dimexpr\headheight+\topmargin\relax + \@tempdimc\dimexpr\paperheight-\@tempdimb\relax + \advance\@tempdimb\bleed + \advance\@tempdimc\bleed + \smash{\vrule\@width\@tempdima\@height\@tempdimb\@depth\@tempdimc}}} + \def\@vensidemarginrule{% + \llap{% + \@tempdima0.8\p@ + \@tempdimb\dimexpr\headheight+\topmargin\relax + \@tempdimc\dimexpr\paperheight-\@tempdimb\relax + \advance\@tempdimb\bleed + \advance\@tempdimc\bleed + \smash{\vrule\@width\@tempdima\@height\@tempdimb\@depth\@tempdimc}% + \kern6.5mm\kern-0.5\@tempdima}} +\fi +\def\check@journalnameabbreviation#1 Discuss.#2\@nil{#2} +\def\@journalInfo{% + \ifx\specialp@perstring\@undefined\else + {\specialp@perstring} to\space + %check for configured line breaks: + \def\1{Corrigendum}\ifx\specialp@perstring\1\if@corrigendum\hfil\break\fi\else + \def\1{Editorial note}\ifx\specialp@perstring\1 + \edef\1{\expandafter\expandafter\expandafter\check@journalnameabbreviation\expandafter\@journalnameabbreviation\space Discuss.\@nil}% + \ifx\1\@empty\if@editorialnotetwoc\hfil\break\fi\else + \if@editorialnoted\hfil\break\fi\fi\fi + \fi + \fi + \@journalnameabbreviation + \ifcopyediting\else\if@noref,\space\@msnumber\else,\space\@pvol, \@fpage\if@nolastpage\else{--\@lpage}\fi\fi, \@pyear\fi} +\def\@journalurlInfo{% + %% URL raus, DOI rein; 2020-05-15 + \if@preface + %\@journalurl\ifcopyediting\else/\preface@abbrev.pdf\fi + https://doi.org/10.5194/\preface@abbrev.pdf + \else + https://doi.org/10.5194/\if@noref\@msnumber\else\@journalnameshortlower-\@pvol-\@fpage-\@pyear\fi + %\@journalurl\ifcopyediting\else/\if@noref\@msnumber\else\@pvol/\@fpage/\@pyear\fi/\fi + \fi} +\def\runningheaderfont{% + \if@stage@final%spec. obsolete ? + \if@sansserifheader + \reset@font\sffamily\mathversion{sans}\normalsize\color{textcol}% + \else + \bfseries + \fi + \fi} +\def\prefacetype#1{% + \if@preface + \def\@argi{#1}% + \def\1{volume}\ifx\@argi\1 + \ifx\v@num\@undefined\CopernicusError{\string\prefacetype{} is "volume", but no {\string\vnumber} was given!}{\string\prefacetype{} is "volume", but no {\string\vnumber} was given!}\fi + \gdef\preface@abbrev{\@journalnameshortlower-volume\v@num-preface}% + \else + \def\1{issue}\ifx\@argi\1 + \ifx\i@num\@undefined\CopernicusError{\string\prefacetype{} is "issue", but no {\string\inumber} was given!}{\string\prefacetype{} is "isue", but no {\string\inumber} was given!}\fi + \ifx\v@num\@undefined\CopernicusError{\string\prefacetype{} is "issue", but no {\string\vnumber} was given!}{\string\prefacetype{} is "issue", but no {\string\vnumber} was given!}\fi + \gdef\preface@abbrev{\@journalnameshortlower-volume\v@num-issue\i@num-preface}% + \else + \def\1{SI}\ifx\@argi\1 + \ifx\SI@num\@undefined\CopernicusError{\string\prefacetype{} is "SI", but no {\string\sinumber} was given!}{\string\prefacetype{} is "issue", but no {\string\sinumber} was given!}\fi + \gdef\preface@abbrev{\@journalnameshortlower-special\_issue\SI@num-preface}% + \else + \CopernicusError{Empty \string\prefacetype{} not allowed!} + {\string\prefacetype{} must be on of: "volume", "issue", or "SI"} + \fi + \fi + \fi + \else + \CopernicusError{Found \string\prefacetype{#1} in an article without the preface class option!}{Please do not use \string\prefacetype\space unless you chose preface^^Jas class option to \string\documentclass{copernicus}}% + \fi +}% +\def\vnumber#1{\if@preface\gdef\v@num{#1}\else\CopernicusError{\string\vnumber\space is only available in preface papers!}{Omit \string\vnumber\space and use \string\publvol\space or \string\origpublvol\space instread.}\fi} +\def\sinumber#1{\if@preface\gdef\SI@num{#1}\else\CopernicusError{\string\sinumber\space is only available in preface papers!}{Omit \string\sinumber\space when articly type is not preface.}\fi} +\def\inumber#1{\if@preface\gdef\i@num{#1}\else\CopernicusError{\string\inumber\space is only available in preface papers!}{Omit \string\inumber\space and use \string\articlenumber\space instread.}\fi} +\def\@manuscriptInfo{% + % Manuscript prepared for \@journalnameabbreviation\\ + % with version \csname ver@\@classfilename.cls\endcsname\ % + % of the \LaTeX\ class \@classfilename.cls.\\ + % Date: \number\day~\ifcase\month\or January\or February\or + % March\or April\or May\or June\or July\or August\or September\or + % October\or November\or December\fi~\number\year + %~\\[12pt] + } +\if@stage@final + \def\ps@plain{%only used for manuscript + \let\@mkboth\@gobbletwo + \def\@oddhead{\if@proof\watermark\fi} + \let\@evenhead\@oddhead + \def\@oddfoot{\reset@font\bfseries\hfil\thepage\hfil}% + \let\@evenfoot\@oddfoot} + \def\ps@headings{% + \def\@oddhead{% + \runningheaderfont + \if@proof\watermark\fi + \@runhd\hfil\llap{\thepage}% + \if@cop@home\if@bar + \textcolor{barcol}{\@ddsidemarginbar}% + %\textcolor{textcol}{\@ddsidemarginrule}% + \textcolor{rulecol}{\@ddsidemarginrule}% + \fi\fi} + \def\@evenhead{% + \if@firstbar\global\@barfalse\fi + \if@proof\watermark\fi + \if@cop@home\if@bar + \textcolor{barcol}{\@vensidemarginbar}% + %\textcolor{textcol}{\@vensidemarginrule}% + \textcolor{rulecol}{\@vensidemarginrule}% + \fi\fi + \runningheaderfont + \rlap{\thepage}\hfil\@runhd}% + \let\@oddfoot\@empty + \let\@evenfoot\@empty + \if@cop@home + \def\@oddfoot{\if@proof\else\edit@rnotereminder\runningheaderfont\if@preface \@journalurlInfo\hfil Preface\else\@journalurlInfo\hfil\ifx\specialp@perstring\@undefined\@journalInfo\else\specialp@perstring\fi\fi\fi} + \def\@evenfoot{\if@proof\else\edit@rnotereminder\runningheaderfont\if@preface Preface\hfil\@journalurlInfo\else\ifx\specialp@perstring\@undefined\@journalInfo\else\specialp@perstring\fi\hfil\@journalurlInfo\fi\fi} + \fi + \let\@mkboth\@gobbletwo} +\else%discussions + \def\ps@headings{% + \def\@oddhead{% + \if@firstbar\global\@barfalse\fi + \if@proof\watermark\fi + \hfil + \rlap{% + \kern5mm + \@tempdimb\dimexpr\headheight+\topmargin+1in\relax + \@tempdimc\dimexpr\paperheight-\@tempdimb\relax + \advance\@tempdimb\bleed + \advance\@tempdimc\bleed + \color{discussion_bartext_background}\smash{\vrule\@width5mm\@height\@tempdimb\@depth\@tempdimc}}% + \rlap{% + \kern5.7mm + \rotatebox{-90}{% + \fontsize{10}{10}\usefont{T1}{ma1}{m}{n}% + \textcolor{discussion_bartext}{\kern-0.5mm% + Discussion Paper \quad | \quad Discussion Paper \quad | \quad Discussion Paper \quad | \quad Discussion Paper \quad |}}}} + \let\@evenhead\@oddhead + \def\@oddfoot{\if@cop@home\edit@rnotereminder\fi\hfil\thepage\hfil} + \let\@evenfoot\@oddfoot} +\fi +\if@stage@final + \if@firstbar\@bartrue\fi + \if@bar + \def\@titlebar{% + \textcolor{barcol}{\@ddsidemarginbar}% + %\textcolor{textcol}{\@ddsidemarginrule}% + \textcolor{rulecol}{\@ddsidemarginrule}% + \rlap{\kern7.5mm\smash{% + \raise3mm\hbox{\rotatebox[origin=Bl]{-90}{\reset@font\sffamily\Large\textcolor{textcol}{\@btext\strut}}}}}} + \fi + \def\ps@titlepage{% + \if@cop@home + \ifcopyediting + \def\@oddhead{% + \parbox[t] + {\textwidth} + {{\runningheaderfont\@sentence}\\ + \color[gray]{0.55}\put(0.7,0){\rule[1mm]{\textwidth}{0.1mm}}\\ + \textcolor[gray]{0.55}{Your manuscript was typeset and received English language copy-editing.\\ + The resulting file is available for proof-reading in the final journal style.\\ + The present document is only to review the language changes.}}% + \if@bar\@titlebar\fi} + \else + \def\@oddhead{% + \parbox[t] + {0.6\textwidth} + {\if@sansserifheader\leavevmode\runningheaderfont\fi + \if@preface + doi:10.5194/\preface@abbrev% + \else + \@journalInfo\\ + %\@journalurlInfo\\ %raus laut Ticket 4529 + https://doi.org/10.5194/% + \if@noref + \@msnumber + \else + \@journalnameshortlower + -\@pvol-\@fpage-\@pyear + \fi + \fi + \ifx\specialp@perstring\@undefined\else-\def\1{Corrigendum}\ifx\specialp@perstring\1corrigendum\else editorial-note\fi\fi + \\ + \@journalcopyright + %\includegraphics[width=1.5cm]{CreativeCommons_Attribution_License.png}% + }% + \hfill + \setbox\z@\hbox{\@journallogo}% + \@tempdima\ht\z@\advance\@tempdima-8\p@\lower\@tempdima\box\z@\\ + \ifangeocom + \textcolor{barcol}{\@ddsidemarginbar}% + %\textcolor{textcol}{\@ddsidemarginrule}% + \textcolor{rulecol}{\@ddsidemarginrule}% + \rlap{\kern9mm\smash{% + \@tempdimc\headsep\advance\@tempdimc\textheight\advance\@tempdimc\footskip + \lower\@tempdimc\hbox{\rotatebox[origin=lB]{90}{\fontsize{15}{15}\usefont{T1}{ma1}{m}{n}AnGeo Communicates}}}}% + \else + \if@bar\@titlebar\fi + \fi} + \fi + \def\@oddfoot{\edit@rnotereminder\runningheaderfont\@sentence\hfil} + \else + \def\@oddhead{\parbox[t]{0.6\textwidth}{\@manuscriptInfo}} + \let\@oddfoot\@empty + \fi + \let\@mkboth\@gobbletwo + } +\fi +\AtEndDocument{% + \clearpage + \addtocounter{page}{-1}% + \immediate\write\@auxout{\string\newlabel{LastPage}{{}{\thepage}{}{}{}}}% + \addtocounter{page}{1}% + %\@create@xmp{\@xmp@preamble \@xmp@postamble}% +} +\AtBeginDocument{% +} +\if@stage@final + \def\@lpage{\hypersetup{linkcolor=textcol}\pageref{LastPage}} +\else + \def\@lpage{\pageref*{LastPage}} +\fi +\newcommand\sw@and{% + \end{minipage}\\[1em]% + \begin{minipage}[t]{\hsize}% + \flushleft\baselineskip12pt} +\def\@runtest{% + \if@noauthor\else\if!\@runauth!\UndefinedError{\string\runningauthor}\fi\fi + \if!\@runtit!\UndefinedError{\string\runningtitle}\fi} +\let\ltx@title\title +\let\@letex@textit\textit +\ifx\xmltexversion\@undefined + \ifcopyediting + \let\title\ltx@title + \else + \def\title#1{\ltx@title{#1}\hypersetup{pdftitle=\@title}\xmp@title{#1}} + \fi +\else + \def\title#1{\ltx@title{#1}\xmp@title{#1}} +\fi +\def\maketitle{% + \gdef\supplement##1{% + \href{https://doi.org/10.5194/\@journalnameshortlower-\@pvol-\@fpage-\@pyear-supplement}% + {https://doi.org/10.5194/\@journalnameshortlower-\@pvol-\@fpage-\@pyear-supplement}}% + \ifnum\@fpage<0 + \CopernicusError{No article number given but citation by article number required} + {Please provide \string\articlenumber.} + \fi + \ifx\citati@nbyarticlenumber\@undefined + \ifodd\@fpage\else + \CopernicusError + {Starting page must be odd!}{change the firstpage command}% + \fi + \ifx\specialp@perstring\@undefined + \setcounter{page}{\@fpage}% + \fi + \fi + \setcounter{footnote}{0}% + \if@stage@final\if@manuscript\else\if@proof\thispagestyle{plain}\else\thispagestyle{titlepage}\fi\fi\fi + \begingroup + \parindent=\z@ + \@maketitle + \endgroup + \global\let\thanks\relax + \global\let\maketitle\relax + \global\let\@thanks\@empty + \global\let\@author\@empty + \global\let\@title\@empty + \if@stage@final + \if@manuscript\gdef\baselinestretch{1.4}\reset@font\normalsize\fi + \fi + \@runtest} +\if@stage@final + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% This is taken from `long2.sty'. + %% Author: Tomas "tohecz" Hejda <tohecz@gmail.com> + %% Licenced under LaTeX-Project Public License version 1.3 or newer. + \newlength\longtwo@top + \newlength\longtwo@bottom + \newsavebox\longtwo@box + \def\longtwo@repeat{% + \longtwo@column[{\@twocolumnfalse + \ifdim\ht\longtwo@box>1.00\textheight%1 + \begingroup + \vbadness10000 + \setbox0\vsplit\longtwo@box to 1.00\textheight%1 + \setbox1\vbox{\unvbox\longtwo@box} + \global\setbox\longtwo@box\vbox{\unvbox1}% + \setbox2\vbox to \textheight{\unvbox0}% + \ht2=0.9\textheight + \box2 + \endgroup + \else + \ifdim\ht\longtwo@box>0.84\textheight + \global\let\longtwo@repeat\clearpage + \else + \global\let\longtwo@repeat\relax + \fi + \unvbox\longtwo@box + \vspace{15pt plus 15pt}% + \fi + }]% + \longtwo@repeat} + \long\def\longtwo@[#1]{% + \begingroup + \let\longtwo@column\twocolumn + \let\longtwo@mkttl\maketitle + \def\maketitle{% + \begingroup + \let\newpage\relax + \longtwo@mkttl + \endgroup} + \longtwo@column[{\@twocolumnfalse + \global\setbox\longtwo@box\vbox{#1}% + \ifdim\ht\longtwo@box>\textheight + \begingroup + \vbadness10000 + \setbox0\vsplit\longtwo@box to 1.00\textheight%1 + \setbox1\vbox{\unvbox\longtwo@box}% + \global\setbox\longtwo@box\vbox{\unvbox1}% + \setbox2\vbox to \textheight{\unvbox0}% + \ht2=0.9\textheight + \box2 + \endgroup + \else + \ifdim\ht\longtwo@box>0.87\textheight + \global\let\longtwo@repeat\clearpage + \else + \global\let\longtwo@repeat\relax + \fi + \unvbox\longtwo@box + \fi + }]% + \longtwo@repeat + \endgroup} + \def\longtwocolumn{\@ifnextchar[\longtwo@\twocolumn} + %% End of file `long2.sty'. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \def\@maketitle{% + \if@manuscript%layout for first page in one-column mode + \@@maketitlemanuscript + \else%layout for first page in two-column mode + \if@twocolumn + \longtwocolumn[\@@maketitlefinal]% + \else%allows output of heads larger than one page + \@@maketitlefinal + \fi + \fi} + \def\@@maketitlemanuscript{% + \global\@topnum\z@ + \begin{nolinenumbers}% + \parbox[t]{\textwidth}{\@manuscriptInfo}\par + \vskip\baselineskip + \raggedright + \let\footnotesize\normalsize + \let\footnoterule\relax + \def\thefootnote{\fnsymbol{footnote}}% + \def\@mpfn{footnote}% + \let\thempfn=\thefootnote + \renewcommand\@makefntext[1]{\parindent1em\noindent\@makefnmark##1}% + {\LARGE\bfseries\if@sansserifface\mathversion{sansbold}\else\mathversion{bold}\fi\@title\par}% + \if@noauthor + \else + {\large + \renewcommand\Authfont{\normalfont}% + \renewcommand\Affilfont{\normalsize\normalfont}% + \setlength\affilsep{4pt}% + \let\and=\sw@and + \flushleft + \@author\\[4pt] + \ifnum\corr@cnt=\z@\relax\else\textbf{{\if@sansserifface\sffamily\fi\upshape\noindent\color{textcol} Correspondence:}} \@corresp\ifx\@howtocite\@empty\else\\[4pt]\fi\fi + \ifx\@howtocite\@empty\else\textbf{{\if@sansserifface\sffamily\fi\upshape\noindent\color{textcol} How to cite:}} \@howtocite\fi + \par}% + \fi + \@thanks + \vspace{\baselineskip}% + \end{nolinenumbers}} + \def\@maketitle@setup{% + \let\footnotesize\normalsize + \let\footnoterule\relax + \def\thefootnote{\fnsymbol{footnote}}% + \def\@mpfn{footnote}% + \let\thempfn=\thefootnote + \renewcommand\@makefntext[1]{\parindent1em\noindent\@makefnmark##1}} + \if@abstractcentered%modern + \def\@@maketitlefinal{% + \vspace*{31mm}% + {\list{}{\leftmargin10mm\rightmargin\leftmargin}% + \item\relax + \hsize\linewidth + \@maketitle@setup + \centering + \center{\LARGE\bfseries\if@sansserifface\sffamily\mathversion{sansbold}\else\mathversion{bold}\fi\color{textcol}% + \ifx\specialp@perstring\@undefined\else\textit{{\specialp@perstring} to}\break``\fi + \@title + \ifx\specialp@perstring\@undefined + \else + ''\if@noref,\else\space published in\fi\space + \@journalnameabbreviation , + \if@noref\@msnumber \else \@pvol, \@fpage\if@nolastpage\else{--\@lpage}\fi\fi, \@pyear + \fi + \par}% + \vspace{10pt}% + \if@noauthor + \else + {\normalsize + \renewcommand\Authfont{\bfseries}% + \renewcommand\Affilfont{\reset@font}% + \setlength\affilsep{4pt}% + \let\and=\sw@and + \@author\par}% + \vskip-0.5\baselineskip + \fi + \ifnum\corr@cnt=\z@\relax\else\vskip\topsep\centering\textbf{{\if@sansserifface\sffamily\fi\upshape\noindent\color{textcol} Correspondence:}}\space\@corresp\fi + \ifx\@howtocite\@empty\else\vskip.5\topsep\centering\textbf{{\if@sansserifface\sffamily\fi\upshape\noindent\color{textcol} How to cite:}}\space\@howtocite\fi + \par\vskip0.33\baselineskip + {\small + \ifx\specialp@perstring\@undefined + \if!\@recvd! + \else + Received: \@recvd + \def\datesep{ -- }% + \if@twostagejnl\ifx\@pubdiscuss\@empty\else + \datesep Discussion started:\nobreakspace\@pubdiscuss\def\datesep{\break\def\datesep{ -- }}% + \fi\fi + \if!\@revsd!\else\datesep Revised:\nobreakspace\@revsd\fi + \if!\@accptd!\else\datesep Accepted:\nobreakspace\@accptd\fi + \ifx\@published\@undefined\else\datesep\fi + \fi + \fi + \ifx\@published\@undefined\else Published:\nobreakspace\@published\fi + }% + \ifx\abstractexists\@undefined + \else + \par\vskip0.5\baselineskip + \bgroup + \advance\hsize-2\fboxsep\advance\hsize-2\fboxrule + \parskip\z@ + \trivlist\item\relax + \textcolor{textcol}{\reset@font\normalsize\if@sansserifface\sffamily\fi\bfseries\abstractname.}% + \enspace\ignorespaces\@abstr + \ifx\second@bstract\@undefined\else\par\vspace{1.7mm}\noindent + \second@bstract + \fi + \if!\@keyw!\else + \par\vspace{1.7mm}\noindent + \textcolor{textcol}{\reset@font\normalsize\if@sansserifface\sffamily\fi\bfseries Keywords.}% + \enspace\ignorespaces\@keyw + \fi + \endtrivlist + \egroup + \fi + \endlist + \par\vspace{1.5\baselineskip}}} + \else%classical or indented + \if@abstractindented%% indented + \def\@@maketitlefinal{% + \vspace*{36mm}% + {\@maketitle@setup + \raggedright + {\LARGE\bfseries\if@sansserifface\sffamily\mathversion{sansbold}\else\mathversion{bold}\fi\color{textcol}% + \ifx\specialp@perstring\@undefined\else\textit{{\specialp@perstring} to}\break``\fi + \@title + \ifx\specialp@perstring\@undefined + \else + ''\if@noref,\else\space published in\fi\space + \@journalnameabbreviation, + \if@noref\@msnumber \else \@pvol, \@fpage\if@nolastpage\else{--\@lpage}\fi\fi, \@pyear + \fi + \par}% + \if@noauthor + \else + \vspace{\baselineskip}% + {\normalsize + \renewcommand\Authfont{\bfseries}% + \renewcommand\Affilfont{\mdseries}% + \setlength\affilsep{4pt}% + \let\and=\sw@and + \@author\par}% + \vskip-0.25\baselineskip + \fi + \@thanks} + %% NEU: + \ifnum\ifnum\corr@cnt=\z@\relax\ifx\@howtocite\@empty\if!\@recvd!\ifx\abstractexists\@undefined\ifx\@published\@undefined0\else1\fi\else1\fi\else1\fi\else1\fi\else1\fi=1\relax + \par\vskip1.5\baselineskip + \def\labelfont{\bfseries\if@sansserifface\sffamily\fi\upshape\noindent\color{textcol}}% + \list{}{\labelwidth35mm% + \leftmargin\labelwidth + \itemsep4mm + \labelsep\z@ + \xdef\@indescription{}% + \def\makelabel##1{\labelfont##1\hss}}% + \ifnum\corr@cnt=\z@\relax\else\item[{Correspondence:}]\@corresp\fi + \ifnum\ifx\@published\@undefined\ifx\specialp@perstring\@undefined\if!\@recvd!0\else1\fi\else0\fi\else1\fi=1\relax + \item[{Relevant dates:}]% + \fi + \bgroup\raggedright + \ifx\specialp@perstring\@undefined + \if!\@recvd! + \else + \setbox\z@\hbox\bgroup + \strut\hbox{Received:\nobreakspace\@recvd}% + \def\datesep{ -- }% + \if@twostagejnl\ifx\@pubdiscuss\@empty\else + \datesep \hbox{Discussion started:\nobreakspace\@pubdiscuss}\def\datesep{\newline\def\datesep{ -- }}% + \fi + \fi + \if!\@revsd!\else\datesep \hbox{Revised:\nobreakspace\@revsd}\fi + \if!\@accptd!\else\datesep \hbox{Accepted:\nobreakspace\@accptd}\fi + \ifx\@published\@undefined\else\datesep\fi + \egroup + \unhcopy\z@ + \ifdim\wd\z@>100mm\strut\newline\strut\fi + \fi + \fi + \ifx\@published\@undefined\else \strut\hbox{Published:\nobreakspace\@published}\fi + \strut\par\egroup + \ifx\@howtocite\@empty\else\item[{How to cite:}]\@howtocite\fi + \ifx\abstractexists\@undefined + \else + \item[\abstractname:]\@abstr% + \ifx\second@bstract\@undefined\else\item[\secabstractname:]\second@bstract\fi + \if!\@keyw!\else\item[Keywords:]\@keyw\fi + \fi + \endlist + \fi + \vspace{20pt}} + \else%% classical + \def\@@maketitlefinal{% + \vspace*{36mm}% + {\@maketitle@setup + \raggedright + {\LARGE\bfseries\if@sansserifface\if@sansserifface\sffamily\fi\mathversion{sansbold}\else\mathversion{bold}\fi\color{textcol}% + \ifx\specialp@perstring\@undefined\else\textit{{\specialp@perstring} to}\break``\fi + \@title + \ifx\specialp@perstring\@undefined + \else + ''\if@noref,\else\space published in\fi\space + \@journalnameabbreviation, + \if@noref\@msnumber \else \@pvol, \@fpage\if@nolastpage\else{--\@lpage}\fi\fi, \@pyear + \fi + \par}% + \if@noauthor + \else + \vspace{\baselineskip}% + {\normalsize + \renewcommand\Authfont{\bfseries}% + \renewcommand\Affilfont{\mdseries}% + \setlength\affilsep{4pt}% + \let\and=\sw@and + \@author\par}% + \vskip-0.25\baselineskip + \fi + \@thanks + \ifnum\corr@cnt=\z@\relax\else\vskip\baselineskip\textbf{{\if@sansserifface\sffamily\fi\upshape\noindent\color{textcol} Correspondence:}}\space\@corresp\fi + \ifx\@howtocite\@empty\else\vskip.75\baselineskip\textbf{{\if@sansserifface\sffamily\fi\upshape\noindent\color{textcol} How to cite:}}\space\@howtocite\fi + \par\vspace{10pt}% + \ifx\specialp@perstring\@undefined + \if!\@recvd! + \else + Received: \@recvd + \def\datesep{ -- }% + \if@twostagejnl\ifx\@pubdiscuss\@empty\else + \datesep Discussion started:\nobreakspace\@pubdiscuss\def\datesep{\newline\def\datesep{ -- }}% + \fi\fi + \if!\@revsd!\else\datesep Revised:\nobreakspace\@revsd\fi + \if!\@accptd!\else\datesep Accepted:\nobreakspace\@accptd\fi + \ifx\@published\@undefined\else\datesep\fi + \fi + \fi + \ifx\@published\@undefined\else Published: \@published\fi + \vspace{20pt}}} + \fi + \fi +\else%discussions + \def\titleheight#1{\def\@tithei{#1}} \def\@tithei{7.5cm}%reserved for future usage + \def\@maketitle{% + \global\@topnum\z@ + \if@cop@home\ifonline + \hypertarget{title}{}% + \hypersetup{pdftitle={\@xmp@title}}% + \hypersetup{pdfauthor={\@pdf@authors}}% + % \hypersetup{pdfauthor={\@runauth}}% + % \hypersetup{pdftitle={\@runtit}}% + \fi\fi + \begin{nolinenumbers}% + \if@cop@home + \ifx\@msnumber\@undefined + \CopernicusError{Please add \string\msnumber{...}}{You must provide the number of the manuscript}% + \global\let\@msnumber\@empty + \else + \ifx\@msnumber\@empty + \CopernicusError{Please fill \string\msnumber{...}}{You must provide the number of the manuscript}% + \fi\fi + \parbox[b]{107mm}{\fontsize{8}{11}\usefont{T1}{ma1}{m}{n}% + %\@journalInfo\\ + %\@journalurlInfo\\ + %\if@noref\else + % https://doi.org/10.5194/\@journalnameshortlower-\@pvol-\@fpage-\@pyear + %\fi\\ + %\@journalcopyright + \ifx\specialp@perstring\@undefined\else{\specialp@perstring} to\space\fi + \@journalnameabbreviation, % + \ifx\specialp@perstring\@undefined + \if@noref\else\doi{10.5194/\@msnumber}, \@pyear\fi\\ + Manuscript under review for journal \@journalnameabbreviationbase + \else + \@msnumber\\\@journalurl/\@msnumber/% + \fi + \\ + \ifx\specialp@perstring\@undefined + Published:\nobreakspace\@published + \else + \if@noref\else\doi{10.5194/\@msnumber-editorial-note}\fi + \fi + \\ + \copyright\ Author(s) \@pyear. CC-BY 3.0 License.% + %\\[1mm]\includegraphics[width=1.5cm]{CreativeCommons_Attribution_License.png}% + }% + \hfill + \setbox\z@\hbox{\@journallogo}\@tempdima\dimexpr\ht\z@-17mm\relax + \smash{\lower\dimexpr3mm+\@tempdima\relax\llap{\@journallogo}}%war2.5mm + \vskip5mm + \ifacp\vskip1.5mm\fi + \ifamt\vskip1.5mm\fi + \ifhess\vskip1.5mm\fi + {\fboxsep2mm + \colorbox{discussion_bartext_background} + {\advance\hsize-2\fboxsep + \parbox{\hsize} + {\color{discussion_bartext}\fontsize{9.5}{13}\usefont{T1}{ma1}{m}{n}% + \@sentenceDiscussion\par}}}% + \else + \parbox[t]{\textwidth}{\@manuscriptInfo}% + \fi + \vskip13.6\p@ + \raggedright + {\huge\bfseries\mathversion{bold}% + \ifx\specialp@perstring\@undefined\else{\large\specialp@perstring\space to\\}``\fi + \@title + \ifx\specialp@perstring\@undefined\else''\\[1mm]\large\@journalnameabbreviation, \@msnumber, \@pyear\fi + \\[5mm]}% + \if@noauthor\else + \def\Authfont{\rmfamily\bfseries}% + \def\Affilfont{\@affilfontsize\rmfamily\mdseries}% + \affilsep3mm + \@author\\[3mm] + \fi + \if@cop@home + {\small Received:\nobreakspace\@recvd\ -- Accepted:\nobreakspace\@accptd\ -- Published:\nobreakspace\@published\\*[2mm] + \if@noauthor\else Correspondence:\nobreakspace\@corresp\fi\\*[2mm] + \@sentence} + \else + \if@noauthor\else + {\small Correspondence: \@corresp}% + \fi + \fi + \end{nolinenumbers}% + \vfill + \clearpage} +\fi%stage +\if@stage@final + \if@sansserifface + \def\section{\@dolinesectrue\@startsection{section}{1}{\z@} + {-3.5ex\@plus-1ex\@minus-0.2ex} + {\if@secline2.3ex\else2.3ex\@plus0.2ex\fi} + {\raggedright\normalsize\sffamily\bfseries\mathversion{sansbold}\upshape\noindent\color{textcol}}} + \def\subsection{\@dolinesectrue\@startsection{subsection}{2}{\z@} + {\if@secline-3ex\@plus-1ex\@minus-0.2ex\else-3.25ex\@plus-1ex\@minus-0.2ex\fi} + {\if@secline1.25ex\else1.5ex\@plus0.2ex\fi} + {\raggedright\normalsize\sffamily\mdseries\mathversion{sans}\upshape\noindent\color{textcol}}} + \def\subsubsection{\@dolinesectrue\@startsection{subsubsection}{3}{\z@} + {\if@secline-3ex\@plus-1ex\@minus-0.2ex\else-3.25ex\@plus-1ex\@minus-0.2ex\fi} + {\if@secline1.25ex\else1.5ex\@plus0.2ex\fi} + {\raggedright\normalsize\sffamily\mdseries\mathversion{sans}\upshape\noindent\color{textcol}}} + \else%classical + \def\section{\@dolinesectrue\@startsection{section}{1}{\z@} + {-2em\@plus-1ex\@minus-.2ex} + {\if@secline1.15em\else1em\@plus.2ex\fi} + {\raggedright\normalfont\normalsize\bfseries\mathversion{bold}}} + \def\subsection{\@dolinesectrue\@startsection{subsection}{2}{\z@} + {-1em\@plus-0.25ex\@minus-.2ex} + {\if@secline1.15em\else1em\@plus.2ex\fi} + {\raggedright\normalfont\normalsize\bfseries\mathversion{bold}}} + \def\subsubsection{\@dolinesectrue\@startsection{subsubsection}{3}{\z@} + {-1em\@plus-0.25ex\@minus-.2ex} + {\if@secline1.15em\else1em\@plus.2ex\fi} + {\raggedright\normalsize\normalfont\bfseries\mathversion{bold}}} + \fi%final +\else%discussions + \def\section{\@dolinesectrue\@startsection{section}{1}{\z@} + {-2em\@plus-1ex\@minus-.2ex} + {1em\@plus.2ex} + {\raggedright\normalfont\normalsize\bfseries\mathversion{bold}}} + \def\subsection{\@dolinesectrue\@startsection{subsection}{2}{\z@} + {-1em\@plus-0.25ex\@minus-.2ex} + {1em\@plus.2ex} + {\raggedright\normalfont\normalsize\bfseries\mathversion{bold}}} + \def\subsubsection{\@dolinesectrue\@startsection{subsubsection}{3}{\z@} + {-1em\@plus-0.25ex\@minus-.2ex} + {1em\@plus.2ex} + {\raggedright\normalfont\normalsize\bfseries\mathversion{bold}}} +\fi +\def\@startsection#1#2#3#4#5#6{% + \gdef\cur@secdepth{#2}% + \if@noskipsec \leavevmode \fi + \par + \@tempskipa #4\relax + \@afterindenttrue + \ifdim \@tempskipa <\z@ + \@tempskipa -\@tempskipa \@afterindentfalse + \fi + \if@nobreak + \everypar{}% + \else + \addpenalty\@secpenalty\addvspace\@tempskipa + \fi + \if@secline\let\@secline@omitted\relax\fi + \@ifstar + {\@ssect{#3}{#4}{#5}{#6}}% + {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}} +\def\@afterheading{% + \@nobreaktrue + \everypar{% + \if@nobreak + \@nobreakfalse + \clubpenalty \@M + \if@afterindent \else + {\setbox\z@\lastbox}% + \fi + \if@secline + \if@dolinesec + \if@sansserifface + \rlap{\smash{\expandafter\ifnum\cur@secdepth>\@ne\raise1.2\baselineskip\else\raise1.5\baselineskip\fi\hbox{\vrule width\hsize height\arrayrulewidth\relax}}}% + \else + \rlap{\smash{\raise1.5\baselineskip\hbox{\vrule width\hsize height\arrayrulewidth\relax}}}% + \fi + \fi% + \@dolinesecfalse + \global\let\@secline@omitted\@undefined + \fi + \else + \clubpenalty \@clubpenalty + \everypar{}% + \fi}% +} +\let\paragraph=\subsubsection +\let\subparagraph=\paragraph +\if@stage@final + \if@manuscript + \else + \leftmargini2em + \leftmarginii1.75em + \leftmarginiii1.5em + \leftmarginiv1em + \leftmarginv0.5em + \leftmarginvi0.5em + \fi +\fi +\def\labelitemi{\bfseries\textendash} +\def\labelitemii{\bfseries\textendash} +\def\labelitemiii{$\m@th\bullet$} +\def\labelitemiv{$\m@th\cdot$} +\def\copstartlist{% + \if@secline + \ifx\@secline@omitted\relax + \leavevmode + \nobreak + \vspace*{-1.72\baselineskip}% + \global\let\@secline@omitted\@undefined + \fi + \fi +} + +\def\itemize{% + \copstartlist + \ifnum \@itemdepth >\thr@@\@toodeep\else + \advance\@itemdepth\@ne + \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% + \expandafter + \list + \csname\@itemitem\endcsname + {\def\makelabel##1{\hss\llap{##1}}}% + \fi} + +\newenvironment{itemizewithoutindent}{% + \copstartlist + \ifnum \@itemdepth >\thr@@\@toodeep\else + \advance\@itemdepth\@ne + \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% + \expandafter + \list + \csname\@itemitem\endcsname + {\leftmargin\z@ + \itemindent\z@ + \labelwidth\z@ + \labelsep\z@ + \def\makelabel##1{\if!##1!\else##1\enskip\fi}}% + \fi +}{\endlist} + +\newenvironment{plainlistindent}{% + \copstartlist + \ifnum \@itemdepth >\thr@@\@toodeep\else + \advance\@itemdepth\@ne + \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% + \expandafter + \list + \csname\@itemitem\endcsname + {\itemsep\z@ + \topsep\z@ + \parsep\z@ + \itemindent=\dimexpr-\labelwidth-\itemsep\relax + \def\makelabel##1{%##1% + \edef\@tempa{##1}% + \ifx\@tempa\@empty + \hspace*{\labelwidth}% + \else + \hspace*{\dimexpr\labelwidth+\labelsep\relax}##1 + \fi\ignorespaces + }}% + \fi +}{\endlist} + +\let\@abslang\relax +\long\def\secondabstract#1{% + \subpdfbookmark{\secabstractname.}{\secabstractname.}% + \toks@{% + \if@abstractindented\else\if@stage@final + \noindent\textcolor{textcol}{\reset@font\normalsize\if@sansserifface\sffamily\fi\bfseries \secabstractname.} \ignorespaces\enskip + \fi\fi + #1} + \immediate\write\@auxout{\string\gdef\string\second@bstract{\the\toks@}}% + \if@abstractindented\else + \if@stage@final + \else + \section*{\secabstractname} + \second@bstract + \fi + \fi +} +\if@stage@final + \ifnum\if@abstractcentered1\else\if@abstractindented1\else0\fi\fi=1\relax%modern oder indented + \long\def\abstract{% + \immediate\write\@auxout{\string\gdef\string\abstractexists{true}}% + \iflanguage{ngerman}{\@abslang}{\iflanguage{german}{\@abslang}{}}% + \subpdfbookmark{\abstractname}{abstract}% + \edef\ABS@{\@currenvir}% + \toks@{}\ABS@get@body} + \let\endabstract\relax + \long\def\ABS@get@body#1\end + {\toks@\expandafter{\the\toks@\parindent1em\relax#1}\ABS@find@end} + \def\ABS@find@end#1{% + \def\@tempa{#1}% + \ifx\@tempa\ABS@ + \expandafter\ABS@endabstract + \else + \toks@\expandafter{\the\toks@\end{#1}}\expandafter\ABS@get@body + \fi} + \def\ABS@{abstract} + \def\ABS@endabstract{% + \immediate\write\@auxout{\string\gdef\string\@abstr{\the\toks@}}% + \iflanguage{ngerman}% + {\gdef\@abslang{\selectlanguage{english}}}% + {\iflanguage{german}% + {\gdef\@abslang{\selectlanguage{english}}}% + {\gdef\@abslang{\selectlanguage{ngerman}}}} + \expandafter\end\expandafter{\ABS@}} + \else%classical + \renewenvironment{abstract} + {\gdef\abstractexists{true}% + \iflanguage{ngerman}{\@abslang}{\iflanguage{german}{\@abslang}{}}% + \reset@font\normalsize\par\noindent + \subpdfbookmark{\abstractname}{abstract}% + \textcolor{textcol}{\reset@font\normalsize\if@sansserifface\sffamily\fi\bfseries\abstractname.} \ignorespaces} + {\ifx\second@bstract\@undefined\else\vskip\baselineskip\second@bstract\fi + \if!\@keyw!\else + \par\vspace{1.7mm}\noindent + \textbf{Keywords.}\enspace\ignorespaces\@keyw + \fi + \if@manuscript\else\if@noline\else + \par\vskip\baselineskip + \fi\fi + \iflanguage{ngerman} + {\gdef\@abslang{\selectlanguage{english}}}% + {\iflanguage{german}% + {\gdef\@abslang{\selectlanguage{english}}}% + {\gdef\@abslang{\selectlanguage{german}}% + \if@manuscript\else\if@noline\else + \hrule\par% #9055 + \vskip2\baselineskip\relax% #9055 + \ifx\xmltexversion\@undefined\else\aftergroup\aftergroup\fi\aftergroup\@afterindentfalse% #9055 + \ifx\xmltexversion\@undefined\else\aftergroup\aftergroup\fi\aftergroup\@afterheading% #9055 + \fi\fi}}} + \fi +\else%discussions + \renewenvironment{abstract} + {\gdef\abstractexists{true}% + \iflanguage{ngerman}{\@abslang}{\iflanguage{german}{\@abslang}{}}% + \section*{\abstractname\if@cop@home\ifonline\hypertarget{abstr}{}\fi\fi}} + {\iflanguage{ngerman}% + {\gdef\@abslang{\selectlanguage{english}}}% + {\iflanguage{german}% + {\gdef\@abslang{\selectlanguage{english}}}% + {\gdef\@abslang{\selectlanguage{ngerman}}}}} +\fi%stage +%%make sure the author doesn't forget anything +\AtEndDocument{% + \@ifundefined{abstractexists} + {\NoSectionWarning{Abstract}} + {}} +\if@stage@final + \let\@oxfloat=\@xfloat +\else + \let\orig@xfloat\@xfloat + \def\@oxfloat#1[#2]{% + \clearpage + \@nodocument + \begin{nolinenumbers}% + \def\@captype{#1}% + \null\vfill} + \let\orig@end@float\end@float + \def\end@float{% + \vfill + \end{nolinenumbers}} +\fi +\def\@xfloat#1[#2]{% + \@oxfloat#1[#2]% + \if@stage@final\vspace*{2mm}\fi + \centering + \small} +\if@stage@final + \if@sansserifface + \def\fnum@figure{\sffamily\color{textcol}\figurename\nobreakspace\thefigure} + \def\fnum@table{\sffamily\color{textcol}\tablename\nobreakspace\thetable} + \fi +\else + \def\fnum@figure{\rmfamily\bfseries\figurename\nobreakspace\thefigure} + \def\fnum@table{\rmfamily\bfseries\tablename\nobreakspace\thetable} +\fi +\def\mytextcircled#1{% + \textcircled{\ifx\in@caption\relax + \check@mathfonts\fontsize\ssf@size\z@\math@fontsfalse\selectfont\kern-1\p@ + \else + \check@mathfonts\fontsize\sf@size\z@\math@fontsfalse\selectfont + \fi #1}} +\long\def\@makecaption#1#2{% + \def\@tempa{figure}\ifx\@captype\@tempa + \if@stage@final + \vskip0.7\abovecaptionskip + \else + \vskip\abovecaptionskip\goodbreak + \fi + \fi + {\let\in@caption\relax\reset@font\small{\bfseries#1.} #2\par}% + \if@cop@home\ifonline\ifnum\csname c@\@captype\endcsname=1 % for 1st fig or tab only + \immediate\write\@auxout{\string\gdef\string\@num\@captype{}}% + \hypertarget{\@captype}{}% + \fi\fi\fi + \def\@tempa{table}\ifx\@captype\@tempa + \vskip\abovecaptionskip + \if@stage@final\else\goodbreak\fi + \fi} +\if@stage@final + \if@manuscript + \else + \columnsep7mm\relax + \fi +\else + \columnsep7mm\relax +\fi +\if@stage@final + \if@manuscript + \pagestyle{plain} + \else + \pagestyle{headings} + \fi +\else + \pagestyle{headings} +\fi +\if@stage@final + \if@manuscript + \else + \@twosidetrue + \@twocolumntrue + \sloppy + \flushbottom + \fi +\fi +\RequirePackage[normalem]{ulem}% +\RequirePackage[T1]{fontenc} +\RequirePackage{textcomp} +\if@cop@home + \RequirePackage{fontawesome5} + \ifluatex + \newcommand*{\faicon}[1]{{\csname faicon@#1\endcsname}} + \input{fontawesomesymbols-generic.tex} + \DeclareRobustCommand\FAone{\fontencoding{U}\fontfamily{fontawesomeone}\selectfont} + \DeclareRobustCommand\FAtwo{\fontencoding{U}\fontfamily{fontawesometwo}\selectfont} + \DeclareRobustCommand\FAthree{\fontencoding{U}\fontfamily{fontawesomethree}\selectfont} + \input{fontawesomesymbols-pdftex.tex} + \renewcommand{\faHourglass}[1][]{\faicon{hourglass\if\relax\detokenize{#1}\relax\else-#1\fi}} + \renewcommand{\faBattery}[1][4]{\faicon{battery-#1}} + \else + \RequirePackage{fontawesome} + \fi +\fi +\usepackage{upquote}%% #7510 +\usepackage{regexpatch} +\def\active@text@prime{\ifin@texttt\textquotesingle\else'\fi} +\def\active@math@prime{^\bgroup\prim@s} +\newif\ifin@texttt +\regexpatchcmd{\pr@m@s}{\'}{\cA\'}{}{} +\xapptocmd{\ttfamily}{\in@texttttrue}{}{} +\begingroup\lccode`\~=`\' +\lowercase{\endgroup\protected\def~}{% + \ifmmode + \expandafter\active@math@prime + \else + \expandafter\active@text@prime + \fi} +\AtBeginDocument{% 0821: \AtBeginDocument is applied AFTER the .aux is read… If '' is in aux, it will throw an error. + \immediate\write\@auxout{\string\catcode\string`\string\'\string=\string\active}% + \catcode`\'=\active} +\ifx\xmltexversion\@undefined +\begingroup +\obeylines\obeyspaces% +\gdef\@resetactivechars{% +\def^^M{\@activechar@info{EOL}\space}% +\def {\@activechar@info{space}\space}% +}% +\endgroup +\fi +\ifx\xmltexversion\@undefined + \ifluatex\else\RequirePackage[utf8]{inputenc}\fi + \def\strip@x#1x#2\@nil{#1}% + \IfFileExists{ucharacters.sty}{% + \ifluatex + % \RequirePackage{luacode} + % \def\DefineCharacter##1##2##3{% + % \expandafter\def\expandafter\@argii\expandafter{\strip@x##2x\@nil}% + % \begingroup\lccode`|=\string"\@argii\relax + % \lowercase{\endgroup\newunicodechar{|}}{##3}}% + % \usepackage{ucharacters}% + \else + \def\DefineCharacter##1##2##3{\expandafter\def\expandafter\@argii\expandafter{\strip@x##2x\@nil}\DeclareUnicodeCharacter{\@argii}{##3}}% + \usepackage{ucharacters}% + \fi + }{}% +\fi +\def\cmrng{{\fontfamily{cmr}\selectfont\ng}} +\let\old@classoptionslist\@classoptionslist +\edef\@classoptionslist{english,\old@classoptionslist} +\RequirePackage{babel} +\let\@classoptionslist\old@classoptionslist +\ifx\StandardLayout\@undefined\let\StandardLayout\relax\fi +\def\@tempa{french}\ifx\bbl@main@language\@tempa + \StandardLayout + %% Switch to quotation marks with additional horizontal spacing + \let\update@frenchlists\relax + \bbl@frenchguillemets + \global\let\flqq\og \global\let\frqq\fg + \ifx\xmltexversion\@undefined\else + \begingroup + \catcode`\!=\active\gdef!{\utfeightax!}% + \catcode`\?=\active\gdef?{\utfeightax?}% + \catcode`\:=\active\gdef:{\utfeightax:}% + \catcode`\;=\active\gdef;{\utfeightax;}% + \endgroup + \fi +\fi +\expandafter\ifx\csname l@ngerman\endcsname\relax + \chardef\l@ngerman="FD +\fi +\expandafter\ifx\csname l@german\endcsname\relax + \chardef\l@german="FE +\fi +\def\@tempa{% + \def\introductionname{Introduction}% + \def\authorcontributionname{Author contributions}% + \def\secabstractname{Kurzfassung}% + \def\conclusionname{Conclusions}% + \def\copyrightstatementname{Copyright statement}% + \def\codeavailabilityname{Code availability}% + \def\dataavailabilityname{Data availability}% + \def\ercavailabilityname{Interactive computing environment}% + \def\codedataavailabilityname{Code and data availability}% + \def\sampleavailabilityname{Sample availability}% + \def\competinginterestsname{Competing interests}% + \def\videosupplementname{Video supplement}% + \def\dosupplementname{Supplement}% + \def\teamlistname{Team list}% + \def\disclaimername{Disclaimer}% + \def\sistatementname{Special issue statement}% + \def\financialsupportname{Financial support}% + \def\reviewstatementname{Review statement}% + \def\acknowledgementname{Acknowledgement}% + \def\acknowledgementsname{Acknowledgements}% + \if@cop@home + \def\equationname{Eq.}% + \def\sectionname{Sect.}% + \fi} +\expandafter\addto\expandafter\captionsbritish\expandafter{\@tempa} +\expandafter\addto\expandafter\captionsUKenglish\expandafter{\@tempa} +\expandafter\addto\expandafter\captionsenglish\expandafter{\@tempa} +\expandafter\addto\expandafter\captionsamerican\expandafter{\@tempa} +\expandafter\addto\expandafter\captionsUSenglish\expandafter{\@tempa} +\def\@tempa{% + \def\figurename{Abb.}% + \def\abstractname{Kurzfassung}% + \def\secabstractname{Abstract}% + \def\introductionname{Einleitung}% + \def\conclusionname{Fazit}% + \def\copyrightstatementname{Urheberrechtserklärung}% + \def\codeavailabilityname{Codeverfügbarkeit}% + \def\dataavailabilityname{Datenverfügbarkeit}% + \def\ercavailabilityname{Interactive computing environment}% + \def\codedataavailabilityname{Code- und Datenverfügbarkeit}% + \def\sampleavailabilityname{Probenverfügbarkeit}% + \def\authorcontributionname{Autor:innenmitwirkung}% + \def\competinginterestsname{Interessenkonflikt}% + \def\videosupplementname{Videoanhang}% + \def\dosupplementname{Supplement}% + \def\teamlistname{Gruppenautorenschaft}% + \def\disclaimername{Haftungsausschluss}% + \def\sistatementname{Erklärung zum Sonderheft}% + %% TBD + \def\financialsupportname{Finanzierung}% + \def\reviewstatementname{Begutachtung}% + \def\acknowledgementname{Danksagung}% + \def\acknowledgementsname{Danksagung}% + \if@cop@home + \def\equationname{Gl.}% + \def\sectionname{Kap.}% + \fi} +\expandafter\addto\expandafter\captionsngerman\expandafter{\@tempa} +\expandafter\addto\expandafter\captionsgerman\expandafter{\@tempa} +\def\@tempa{% + \def\figurename{Figure}% + \def\tablename{Tableau}% + \def\secabstractname{Kurzfassung}% + \def\introductionname{Introduction}% + \def\conclusionname{Conclusion}% + \def\copyrightstatementname{Affirmation du droit d'auteur}% + \def\codeavailabilityname{Disponibilité du code}% + \def\dataavailabilityname{Disponibilité des données}% + \def\ercavailabilityname{Interactive computing environment}% + \def\sampleavailabilityname{Disponibilité des examples}% + \def\codedataavailabilityname{Disponibilité du code et des données}% + \def\authorcontributionname{Collaborateurs}% + \def\competinginterestsname{Intérêts concurrents}% + \def\videosupplementname{Annexes vidéo}% + \def\dosupplementname{Supplement}% + \def\teamlistname{Liste d'auteurs}% + \def\disclaimername{Clause de non-responsabilité}% + \def\sistatementname{Déclaration du numéro spécial}% + %% TBD + \def\financialsupportname{Financement}% + \def\reviewstatementname{Contr\^{o}le par les pairs}% + \def\acknowledgementname{Remerciements}% + \def\acknowledgementsname{Remerciements}% + \if@cop@home + \def\equationname{Éq.}% + \def\sectionname{Sect.}% + \fi} +\expandafter\addto\expandafter\captionsfrench\expandafter{\@tempa} +\expandafter\addto\expandafter\captionsfrancais\expandafter{\@tempa} +\expandafter\addto\expandafter\captionscanadien\expandafter{\@tempa} +\expandafter\addto\expandafter\captionsacadian\expandafter{\@tempa} +\RequirePackage{array} +\def\@cline#1-#2\@nil{% + \noalign{% + \ifx\@clinecorr\@undefined + \vskip0.5mm% + \global\let\@clinecorr\relax + \else + \vskip-1.5mm% + \fi}% + \omit + \@multicnt#1% + \advance\@multispan\m@ne + \ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi + \@multicnt#2% + \advance\@multicnt-#1% + \advance\@multispan\@ne + \leaders\hrule\@height\arrayrulewidth\hfill + \cr + \noalign{% + \vskip-\arrayrulewidth + \vskip1.5mm}} +\def\@arraycr{\relax\iffalse{\fi\ifnum 0=`}\fi + \global\let\@clinecorr\@undefined + \@ifstar \@xarraycr \@xarraycr} +\RequirePackage{tabularx} +\IfFileExists{graphicx.sty} + {\RequirePackage{graphicx}% + \ifnum\pdfoutput=\z@ + \DeclareGraphicsExtensions{.eps,.ps}% + \else + \DeclareGraphicsExtensions{.pdf,.png,.jpg} + \fi} + {\CopernicusWarningNoLine{Cannot find graphicx.sty; proceeding without it}} +\IfFileExists{color.sty} + {\RequirePackage{color}} + {\CopernicusWarningNoLine{Cannot find color.sty; proceeding without it}} +\IfFileExists{amssymb.sty} + {\RequirePackage{amssymb}} + {\CopernicusWarningNoLine{Cannot find amssymb.sty; proceeding without it}} +\IfFileExists{amsmath.sty} + {\RequirePackage[intlimits,fleqn,tbtags]{amsmath} + \ifx\xmltexversion\@undefined + \else + \renewcommand{\allowdisplaybreaks}[1][4]{% + \global\interdisplaylinepenalty\getdsp@pen{##1}\relax}% + \fi} + {\CopernicusWarningNoLine{Cannot find amsmath.sty; proceeding without it}} +\RequirePackage{amsthm} +\newcommand\Authfont{\normalfont} +\newcommand\Affilfont{\normalfont} +\newcommand\Authsep{, } +\newcommand\Authands{, and } +\newcommand\Authand{ and } +\newlength\affilsep\setlength{\affilsep}{1em} +\newlength\@affilsep +\newcounter{Maxaffil} +\setcounter{Maxaffil}{2} +\newcounter{authors} +\newcounter{affil} +\newif\ifnewaffil \newaffiltrue +\newcommand\AB@authnote[1]{\textsuperscript{\normalfont#1}} +\newcommand\AB@affilnote[1]{\textsuperscript{\normalfont#1}} +\providecommand\textsuperscript[1]{$^{#1}$} +\newcommand\AB@blk@and{\protect\Authfont\protect\AB@setsep} +\newcommand\AB@pand{\protect\and \protect\Authfont \protect\AB@setsep} +\@namedef{@sep1}{} +\@namedef{@sep2}{\Authand} +\newcommand\AB@affilsep{\protect\Affilfont} +\newcommand\AB@affilsepx{\protect\\\protect\Affilfont} +\newcommand\AB@setsep{\setlength{\@affilsep}{\affilsep}} +\newcommand\AB@resetsep{\setlength{\@affilsep}{\z@}} +\newcommand\AB@authlist{} +\newcommand\AB@affillist{} +\newcommand\AB@authors{} +\newcommand\AB@empty{} +\xdef\AB@author{\noexpand\AB@blk@and\@author} +\def\true{true}% +\newcounter{authnum} +\global\let\@@deceased\relax +\global\let\@@econtrib\relax + +\renewcommand\author[2][]% + {\ifnewaffil\addtocounter{affil}{1}% + \xdef\AB@thenote{\arabic{affil}}% + \fi + \ifcopyediting\else + \xmp@author{#2}% + \fi + \global\advance\c@authnum\@ne + \if@cop@home + \expandafter\ifx\csname deceased@\the\c@authnum\endcsname\true\relax\def\@@deceased{$^{,\text{\faCross}}$}\fi + \expandafter\ifx\csname econtrib@\the\c@authnum\endcsname\true\relax\def\@@econtrib{$^{,\text{\faStar}}$}\fi + \fi + \def\@tempa{#1}\ifx\@tempa\@empty\def\AB@note{\AB@thenote}\else\def\AB@note{#1}% + \setcounter{Maxaffil}{0}\fi + \ifnum\value{authors}>1\relax + \expandafter\gdef\csname @sep\number\c@authors\endcsname{\Authsep}% + \fi + \addtocounter{authors}{1}% + \begingroup + \let\protect\@unexpandable@protect \let\and\AB@pand + \def\thanks{\protect\thanks}\def\footnote{\protect\footnote}% + \@temptokena=\expandafter{\AB@authors}% + {\def\\{\protect\\[\@affilsep]\protect\Affilfont + \protect\AB@resetsep}% + \protected@xdef\AB@author{\AB@blk@and#2}% + \ifnewaffil\gdef\AB@las{}\gdef\AB@lasx{\protect\Authand}\gdef\AB@as{}% + \xdef\AB@authors{\the\@temptokena\AB@blk@and}% + \else + \xdef\AB@authors{\the\@temptokena\AB@as\AB@au@str}% + \global\let\AB@las\AB@lasx\gdef\AB@lasx{\protect\Authands}% + \gdef\AB@as{\Authsep}% + \fi + \gdef\AB@au@str{#2}}% + \@temptokena=\expandafter{\AB@authlist}% + \let\\=\authorcr + \protected@xdef\AB@authlist{\the\@temptokena + \protect\@nameuse{@sep\number\c@authors}% + \protect\Authfont#2\AB@authnote{\AB@note}% + \@@econtrib + \@@deceased}% + \endgroup + \ifnum\value{authors}>2\relax + \expandafter\gdef\csname @sep\number\c@authors\endcsname{\Authands}% + \fi + \newaffilfalse +\global\let\@@deceased\relax\global\let\@@econtrib\relax} +\newcommand\authorcr{\protect\\ \protect\Authfont \protect\AB@setsep}% +\newcommand\affil[2][]% + {\newaffiltrue\let\AB@blk@and\AB@pand + \def\@tempa{#1}\ifx\@tempa\@empty\def\AB@note{\AB@thenote}\else\def\AB@note{#1}% + \setcounter{Maxaffil}{0}\fi + \begingroup + \let\protect\@unexpandable@protect + \def\thanks{\protect\thanks}\def\footnote{\protect\footnote}% + \@temptokena=\expandafter{\AB@authors}% + {\def\\{\protect\\\protect\Affilfont}\protected@xdef\AB@temp{#2}}% + \protected@xdef\AB@authors{\the\@temptokena\AB@las\AB@au@str + \protect\\[\affilsep]\protect\Affilfont\AB@temp}% + \gdef\AB@las{}\gdef\AB@au@str{}% + {\def\\{, \ignorespaces}\protected@xdef\AB@temp{#2}}% + \@temptokena=\expandafter{\AB@affillist}% + \protected@xdef\AB@affillist{\the\@temptokena \AB@affilsep + \AB@affilnote{\AB@note}\protect\Affilfont\AB@temp}% + \endgroup + \let\AB@affilsep\AB@affilsepx +} +\def\@author{} +\renewcommand\@author{% + \let\no@par\relax + \ifx\AB@affillist\AB@empty\AB@author\else + \ifnum\value{affil}>\value{Maxaffil}% + \AB@authlist\\[\affilsep]\AB@affillist + \else + \AB@authors + \fi + \fi} + +\def\deceased@sep#1,#2\@nil{% + \immediate\write\@auxout{\string\expandafter\string\gdef\string\csname\space deceased@#1\endcsname{true}}% + \if!#2!\else\deceased@sep#2\@nil\fi} +\def\econtrib@sep#1,#2\@nil{% + \immediate\write\@auxout{\string\expandafter\string\gdef\string\csname\space econtrib@#1\endcsname{true}}% + \if!#2!\else\econtrib@sep#2\@nil\fi} + +\newcommand\deceased[2][]{\gdef\@deceasedtext{#1}\@deceased{#2}} +\if@cop@home +\def\@deceased#1{% + \ifx\@deceasedtext\@empty\gdef\@deceasedNote{deceased}\else\gdef\@deceasedNote{deceased, \@deceasedtext}\fi + \deceased@sep#1,\@nil + \@temptokena=\expandafter{\AB@affillist}% + \protected@xdef\AB@affillist{\the\@temptokena \AB@affilsep + \AB@affilnote{\faCross}\protect\Affilfont\@deceasedNote}% + } +\newcommand\equalcontrib[1]{% + \gdef\@econtribNote{These authors contributed equally to this work.}% + \econtrib@sep#1,\@nil + \@temptokena=\expandafter{\AB@affillist}% + \protected@xdef\AB@affillist{\the\@temptokena \AB@affilsep + \AB@affilnote{\faStar}\protect\Affilfont\@econtribNote}% + } +\else + \let\equalcontrib\@gobble + \let\@deceased\@gobble +\fi +\newcount\corr@cnt \corr@cnt\z@\relax +\newcount\curr@corr@cnt \curr@corr@cnt\z@\relax +\def\Author{\let\curr@corr\@empty\@ifnextchar[\@Author{\@Author[]}}%] +\def\@Author[#1]{% + \def\@tempa{#1}% + \@ifnextchar[\@@Author{\@@Author[]}%] +}% +\def\@@Author[#1]{% + \if!#1!\else + \global\advance\corr@cnt\@ne + \parse@corr{#1}% + \fi% + \@ifnextchar(\@@@Author{\@@@Author()}%) +} +\def\parse@corr#1{% + \curr@corr@cnt\z@ + \let\curr@corr\relax + \@parse@corr#1,,\@nil + \ifnum\curr@corr@cnt=\@ne\relax + \edef\curr@corr{\csname curr@corr@1\endcsname}% + \else + \ifnum\curr@corr@cnt=\tw@\relax + \edef\curr@corr{% + \csname curr@corr@1\endcsname\Authsep + \csname curr@corr@2\endcsname}% + \else + \@tempcntb\z@ + \let\curr@corr\@empty% + \loop + \advance\@tempcntb\@ne + \expandafter\edef\expandafter\curr@corr\expandafter{\curr@corr\csname curr@corr@\the\@tempcntb\endcsname}% + \ifnum\@tempcntb<\numexpr\curr@corr@cnt+\m@ne\relax\relax + \expandafter\edef\expandafter\curr@corr\expandafter{\curr@corr\Authsep}% + \repeat + \expandafter\edef\expandafter\curr@corr\expandafter{\curr@corr\Authands\csname curr@corr@\the\curr@corr@cnt\endcsname}% + \fi + \fi +} +\def\@parse@corr #1,#2,\@nil{% + \if!#1!\else + \advance\curr@corr@cnt\@ne + \expandafter\def\csname curr@corr@\the\curr@corr@cnt\endcsname{#1}% + \if!#2!\else + \@parse@corr#2,\@nil% + \fi + \fi +} +\def\@@@Author(#1){% + \def\@tempb{#1}% + \@ifnextchar(\@@@@Author{\@@@@Author()}}%) +\def\@@@@Author(#1)#2#3{% + \def\@tempc{#1}% + \protected@edef\@tempd{% + \ifx\@tempb\@empty\else\@tempb\noexpand\nobreakspace\fi + #2\noexpand\nobreakspace + #3% + \ifx\@tempc\@empty\else\noexpand\nobreakspace\@tempc\fi}% + \ifx\curr@corr\@empty\else + \expandafter\expandafter\expandafter\xdef\csname corresp-\the\corr@cnt\expandafter\endcsname\expandafter{\@tempd\noexpand\space(\curr@corr)}% + \fi + \expandafter\expandafter\expandafter\author\expandafter\expandafter\expandafter + [\expandafter\@tempa\expandafter]\expandafter{\@tempd}} +\providecommand\appendixname{Appendix} +\let\orisection=\section +\let\theolds=\thesection +\let\theoldss=\thesubsection +\def\appendix{\par + \setcounter{section}{0}% + \setcounter{subsection}{0}% + \def\thesection{\@Alph\c@section}% + \def\thesubsection{\thesection\@arabic\c@subsection}% + \setcounter{secnumdepth}{4}% + \@addtoreset{equation}{section}% + \setcounter{equation}{0}% + \setcounter{reaction}{0}% + \def\theequation{\thesection\@arabic\c@equation}% + \def\thereaction{\thesection R\@arabic\c@reaction}% + \let\c@org@lst\c@listings% + \let\c@org@alg\c@algorithms% + \let\c@org@eq\c@equation% + \let\org@theeq\theequation% + \if@stage@final + \@addtoreset{figure}{section}% + \setcounter{figure}{0}% + \def\thefigure{\thesection\@arabic\c@figure}% + \@addtoreset{table}{section}% + \setcounter{table}{0}% + \def\thetable{\thesection\@arabic\c@table}% + \@addtoreset{listings}{section}% + \setcounter{listings}{0}% + \def\thelistings{\thesection\@arabic\c@listings}% + \@addtoreset{algorithm}{section}% + \setcounter{algorithm}{0}% + \def\thealgorithm{\thesection\@arabic\c@algorithm} + \fi + \global\let\old@sect\@sect + \def\@sect##1##2##3##4##5##6[##7]##8{% + \ifnum ##2>\c@secnumdepth + \let\@svsec\@empty + \else + \refstepcounter{##1}% + \ifnum ##2=\@ne + \def\@tempa{##8}% + \protected@edef\@svsec{% + \appendixname\space\csname the##1\endcsname + \ifx\@tempa\@empty\else:\enskip\fi\relax}% + \else + \protected@edef\@svsec{\@seccntformat{##1}\relax}% + \fi + \fi + \@tempskipa ##5\relax + \ifdim \@tempskipa>\z@ + \begingroup + \ifnum ##2=\@ne\let\@hangfrom\noindent\fi + ##6{% + \@hangfrom{\hskip ##3\relax\@svsec}% + \interlinepenalty \@M ##8\@@par}% + \endgroup + \csname ##1mark\endcsname{##7}% + \addcontentsline{toc}{##1}{% + \appendixname\space\csname the##1\endcsname\if!##7!\else:\space\fi%for bookmarks + ##7}% + \else + \def\@svsechd{% + ##6{\hskip ##3\relax + \@svsec ##8}% + \csname ##1mark\endcsname{##7}% + \addcontentsline{toc}{##1}{% + \appendixname\space\csname the##1\endcsname\if!##7!\else:\space\fi%for bookmarks + ##7}}% + \fi + \@xsect{##5}} + \global\let\old@ssect\@ssect + \def\@ssect##1##2##3##4##5{% + \@tempskipa ##3\relax + \ifdim \@tempskipa>\z@ + \begingroup + ##4{% + \@hangfrom{\hskip ##1}% + \@tempskipa##2\relax + \ifdim\@tempskipa<-17\p@%check for sectionlevel=1 + \appendixname + \def\@tempa{##5}\ifx\@tempa\@empty\else:\enskip\fi + \fi + \interlinepenalty \@M ##5\@@par}% + \endgroup + \else + \def\@svsechd{##4{\hskip ##1\relax ##5}}% + \fi + \@xsect{##3}}} +\def\noappendix{\setcounter{secnumdepth}{0}% + \global\let\section=\orisection + \global\let\thesection=\theolds + \global\let\thesubsection=\theoldss + \ifx\old@sect\@undefined\else\global\let\@sect\old@sect\fi + \ifx\old@ssect\@undefined\else\global\let\@ssect\old@ssect\fi + \def\thefigure{\@arabic\c@figure}% + \def\thelistings{\@arabic\c@listings}% + \def\thealgorithms{\@arabic\c@algorithms}% + \def\thetable{\@arabic\c@table}} +\IfFileExists{url.sty} + {\RequirePackage{url}\urlstyle{same}}% + {\CopernicusWarningNoLine{Cannot find url.sty; proceeding without it}% + \def\url#1{% + \CopernicusError{To use \string\url, you must have url.sty}{Install url.sty}}} +\newcommand\doitext{\hbox{https://doi.org/}} +\newcommand*\doi{% + \begingroup + \lccode`\~=`\#\relax + \lowercase{\def~{\#}}% + \lccode`\~=`\_\relax + \lowercase{\def~{\_}}% + \lccode`\~=`\<\relax + \lowercase{\def~{\textless}}% + \lccode`\~=`\>\relax + \lowercase{\def~{\textgreater}}% + \lccode`\~=0\relax + \catcode`\#=\active + \catcode`\_=\active + \catcode`\<=\active + \catcode`\>=\active + %catcode change won't work after \bibitem while backref.sty + % grabs for the whole entry + \@doi} +\def\@doi#1{% + \let\#\relax + \let\_\relax + \let\textless\relax + \let\textgreater\relax + \edef\x{\toks0={{#1}}}% + \x + \edef\#{\@percentchar23}% + \edef\_{_}% + \edef\textless{\@percentchar3C}% instead of {\string<} for Apple + \edef\textgreater{\@percentchar3E}% instead of {\sting>} for Apple + \edef\x{\toks1={\noexpand\href{https://doi.org/#1}}}% + \x + \edef\x{\endgroup\doitext\the\toks1 \the\toks0}% + \x} +\IfFileExists{accents.sty} + {\RequirePackage{accents}} + {\CopernicusWarningNoLine{Cannot find accents.sty; proceeding without it}} +\IfFileExists{cancel.sty} + {\RequirePackage{cancel}} + {\CopernicusWarningNoLine{Cannot find cancel.sty; proceeding without it}} +\IfFileExists{multirow.sty} + {\RequirePackage{multirow}} + {\CopernicusWarningNoLine{Cannot find multirow.sty; proceeding without it}} +\IfFileExists{supertabular.sty} + {\RequirePackage{supertabular}% + \let\old@tablecaption\tablecaption + \def\tablecaption{\def\@captype{table}\old@tablecaption} + \let\old@supertabular\supertabular + \def\supertabular{% + \clearpage + \centering + \small + \old@supertabular} + \@namedef{supertabular*}##1{% + \clearpage + \centering + \small + \@ifnextchar[{\@nameuse{@supertabular*}{##1}}% + {\@nameuse{@supertabular*}{##1}[]}%] + } + \let\old@endsupertabular\endsupertabular + \def\ud@captype{\let\@captype\@undefined} + \def\ud@cr{\let\\\@normalcr} + \long\def\endsupertabular{% + \old@endsupertabular\par + \global\let\@table@first@head\undefined + \global\let\@table@last@tail\undefined + \tablehead{}% + \tabletail{}% + \aftergroup\ud@captype + \aftergroup\ud@cr} + \expandafter\let\csname endsupertabular*\endcsname\endsupertabular} + {\CopernicusWarningNoLine{Cannot find supertabular.sty; proceeding without it}} +\IfFileExists{algorithmic.sty} + {\RequirePackage{algorithmic}} + {\CopernicusWarningNoLine{Cannot find algorithmic.sty; proceeding without it}} +\IfFileExists{algorithm.sty} + {\if@stage@final + \else + \def\extra@float##1{% + \@ifnextchar[%] + {\orig@xfloat{##1}}% + {\edef\reserved@a{\noexpand\orig@xfloat{##1}[\csname fps@##1\endcsname]}% + \reserved@a}} + \RequirePackage{float}% + \def\float@restyle##1{\expandafter\edef\csname + fst@##1\endcsname{\expandafter\noexpand\csname + fs@\float@style\endcsname}% + \@namedef{##1}{\@nameuse{fst@##1}% + \@float@setevery{##1}\extra@float{##1}}% + \@namedef{##1*}{\@nameuse{fst@##1}% + \@float@setevery{##1}\@dblfloat{##1}}% + \expandafter\let\csname end##1\endcsname\float@end + \expandafter\let\csname end##1*\endcsname\float@dblend + \expandafter\let\csname @float@c@##1\endcsname=\float@caption + \@ifundefined{@float@every@##1}{% + \expandafter\newtoks\csname @float@every@##1\endcsname}{}% + \@nameuse{@float@every@##1}={}} + \def\float@end{\@endfloatbox + \global\setbox\@currbox\float@makebox\columnwidth + \let\@endfloatbox\relax\orig@end@float} + \fi + \RequirePackage{algorithm} + \def\theHalgorithm{\@arabic\c@algorithm} + } + {\CopernicusWarningNoLine{Cannot find algorithm.sty; proceeding without it}} +\let\cop@makecaption\@makecaption +\let\c@org@fig\c@figure +\let\@orgfigurename\figurename +\def\setfigures{\global\let\c@figure\c@org@fig\global\let\figurename\@orgfigurename} +\@definecounter{figscheme} +\def\schemename{Scheme} +\let\figschemename\schemename +\def\setschemes{\global\let\c@figure\c@figscheme\global\let\figurename\figschemename} +\@definecounter{plates} +\def\platesname{Plate} +\def\setplates{\global\let\c@figure\c@plates\global\let\figurename\platesname} +\@definecounter{listings} +\def\listingsname{Listing} +\def\setlistings{\global\let\c@figure\c@listings\global\let\figurename\listingsname} +\@definecounter{boxes} +\def\boxesname{Box} +\def\setboxes{\global\let\c@figure\c@boxes\global\let\figurename\boxesname} +\if@stage@final + \IfFileExists{caption.sty} + {\RequirePackage{caption}} + {\CopernicusWarningNoLine{Cannot find caption.sty; proceeding without it}} +\else + \IfFileExists{subfig.sty} + {\RequirePackage{subfig}} + {\CopernicusWarningNoLine{Cannot find subfig.sty; proceeding without it}} +\fi +\let\@makecaption\cop@makecaption +\RequirePackage{listings} +\newdimen\listingnumwidth \listingnumwidth=1.25em\relax +\renewcommand*\thelstnumber{\hb@xt@\listingnumwidth{\hss\the\c@lstnumber:}} +\lstset{% + basicstyle=\small,% + numbers=left,% + numbersep=0.5em,% + numberstyle=\footnotesize,% + frame=lines,% + xleftmargin=\dimexpr\listingnumwidth+0.5em\relax,% + %showspaces=true, + keepspaces=true, + framexleftmargin=\dimexpr\listingnumwidth+0.5em\relax, +} +\newenvironment{listing}[1][] + {\edef\@argi{#1}% + \ifx\@argi\@empty\def\@argi{htbp}\fi + \setlistings + \lstset{aboveskip=0pt,belowskip=0pt}% + \def\@tempa{\begin{figure}}% + \expandafter\@tempa\expandafter[\@argi]} + {\end{figure}% + \setfigures} + + % \gdef\xml@preformat@content#1{% + % \begingroup + % \utfeight@protect@internal + % \nfss@catcodes + % \xdef\x{\endgroup\noexpand\gdef\noexpand\xml@@preformat@content{#1}}\x + % } + + % \begingroup + % \XML@reset + % \gdef\xml@lstlisting#1{% + % \xml@preformat@content{#1}% + % \message{^^J==> xml@preformat@content: \meaning\xml@@preformat@content}% + % \begingroup + % \XML@reset + % \edef\@tempa{\noexpand\lstlisting[\@lstlistingArgument]}% + % \expandafter\@tempa\xml@@preformat@content + % \endlstlisting + % \endgroup + % } + % \endgroup + + +\IfFileExists{subfloat.sty} + {\RequirePackage{subfloat}% + \protected@xdef\themainfigure{\thefigure}% + \protected@xdef\themaintable{\thetable}% + \g@addto@macro\subfiguresbegin{\global\let\theHfigure\thesubfloatfigure} + \g@addto@macro\subtablesbegin{\global\let\theHtable\thesubfloattable} + \g@addto@macro\subfiguresend{\global\let\theHfigure\thefigure@original} + \g@addto@macro\subtablesend{\global\let\theHtable\thetable@original}} + {\CopernicusWarningNoLine{Cannot find subfloat.sty; proceeding without it}} + +\newif\ifNAT@openbib +\IfFileExists{natbib.sty} + {\RequirePackage[authoryear,round]{natbib} + \bibpunct{(}{)}{;}{a}{,}{,~} + \def\NAT@sort{0}\def\NAT@cmprs{0} + \setlength\bibsep\z@ + \let\bibfont\small + \renewcommand\bibitem{\@ifnextchar[{\@lbibitem}{\@lbibitem[??(????)]}}%] + \ifx\xmltexversion\@undefined\else + \NAT@set@cites + \let\NAT@set@cites\relax + \fi + \AtBeginDocument{\let\@citex\NAT@citex} + \ifx\AddToHook\@undefined\else\AddToHook{begindocument/end}[copernicus/natbib]{\let\@citex\NAT@citex}\fi + \newcommand\urlprefix{} + \renewenvironment{thebibliography}[1] + {\bibsection + \if@secline\leavevmode\vspace*{-\baselineskip}\nobreak\fi + \parindent\z@ + \bibpreamble + \bibfont + \list{\@biblabel{\arabic{NAT@ctr}}}{\@bibsetup{##1}% + \setcounter{NAT@ctr}{0}}% + \ifNAT@openbib + \renewcommand\newblock{\par} + \else + \renewcommand\newblock{\hskip .11em \@plus.33em \@minus.07em}% + \fi + \sloppy + % \clubpenalty4000\widowpenalty4000 + \sfcode`\.=1000\relax + \let\citeN\cite \let\shortcite\cite + \let\citeasnoun\cite} + {\def\@noitemerr{% + \PackageWarning{natbib}{Empty `thebibliography' environment}}% + \endlist\vskip-\lastskip} + \def\bibsection{% + \if@stage@final + \if@manuscript\newpage\fi + \pdfbookmark[1]{\refname}{biblio}% + \fi + \noappendix\section*{\refname\if@cop@home\ifonline\hypertarget{references}{}\fi\fi}} + }{\CopernicusWarningNoLine{Cannot find natbib.sty; proceeding without it}} +\RequirePackage{rotating} +\def\@rotxdblfloat#1[#2]{% + \@float{#1}[#2]% + \hsize\textwidth\linewidth\textwidth + \begin{lrbox}\rot@float@box + \begin{minipage}\textheight +} +\IfFileExists{lineno.sty} + {\RequirePackage[mathlines,modulo]{lineno}% + \if@stage@final + \if@manuscript + \linenumbers\renewcommand\linenumberfont{\normalfont\small\sffamily}% + \else + \setpagewiselinenumbers\switchlinenumbers%cf. the switch option + \linenumbersep3\p@ + \if@cop@home + \nolinenumbers + \else%new, 2015-12-14 + \linenumbers + \fi + \fi + \else + \setpagewiselinenumbers + \if@cop@home\linenumbers\fi + \fi + \g@addto@macro\nolinenumbers{\linenopenalty\z@}%avoids problems with \patchAmsMathEnvironmentForLinenoX while \nolinenumbers + \newcommand*\patchAmsMathEnvironmentForLineno[1]{% + \expandafter\let\csname old##1\expandafter\endcsname\csname ##1\endcsname + \expandafter\let\csname oldend##1\expandafter\endcsname\csname end##1\endcsname + \renewenvironment{##1}% + {\linenomath\csname old##1\endcsname}% + {\csname oldend##1\endcsname\endlinenomath}}% + \newcommand*\patchBothAmsMathEnvironmentsForLineno[1]{% + \patchAmsMathEnvironmentForLineno{##1}% + \patchAmsMathEnvironmentForLineno{##1*}}% + \newcommand*\patchAmsMathEnvironmentForLinenoX[1]{% + \expandafter\let\csname old##1\expandafter\endcsname\csname ##1\endcsname + \expandafter\let\csname oldend##1\expandafter\endcsname\csname end##1\endcsname + \renewenvironment{##1}% + {\linenomath\advance + \postdisplaypenalty-\linenopenalty + \csname old##1\endcsname}% + {\csname oldend##1\endcsname\endlinenomath}}% + \newcommand*\patchBothAmsMathEnvironmentsForLinenoX[1]{% + \patchAmsMathEnvironmentForLinenoX{##1}% + \patchAmsMathEnvironmentForLinenoX{##1*}}% + \AtBeginDocument{% + \patchBothAmsMathEnvironmentsForLineno{equation}% + \patchBothAmsMathEnvironmentsForLinenoX{align}% + \patchBothAmsMathEnvironmentsForLinenoX{flalign}% + \patchBothAmsMathEnvironmentsForLinenoX{alignat}% + \patchBothAmsMathEnvironmentsForLinenoX{gather}% + \patchBothAmsMathEnvironmentsForLinenoX{multline}}} + {\CopernicusWarningNoLine{Cannot find lineno.sty; proceeding without it}% + \let\nolinenumbers\bgroup\let\endnolinenumbers\egroup} +\IfFileExists{times.sty} + {\RequirePackage{times} + \def\Hv@scale{0.95}} + {\CopernicusWarningNoLine{Cannot find times.sty; proceeding without it}} +\if@stage@final + \if@cop@home + \let\vec\@undefined + \let\grave\@undefined + \let\acute\@undefined + \let\check\@undefined + \let\breve\@undefined + \let\bar\@undefined + \let\hat\@undefined + \let\dot\@undefined + \let\tilde\@undefined + \let\ddot\@undefined + \ifx\xmltexversion\@undefined\else{\catcode`\_=\active\global\let\xmltexUndersc@re_}\fi + \def\provide@orig@symbol#1{\expandafter\let\csname orig#1\expandafter\endcsname\csname#1\endcsname} + \provide@orig@symbol{Gamma} + \provide@orig@symbol{Delta} + \provide@orig@symbol{Theta} + \provide@orig@symbol{Lambda} + \provide@orig@symbol{Xi} + \provide@orig@symbol{Pi} + \provide@orig@symbol{Sigma} + \provide@orig@symbol{Upsilon} + \provide@orig@symbol{Phi} + \provide@orig@symbol{Psi} + \provide@orig@symbol{Omega} + \usepackage{etoolbox}% + \ifluatex\else + %% Fix fuer #6924, vgl https://tex.stackexchange.com/questions/561236/setmathalphabet-messes-with-rm + \@iflatexlater{2020/10/01}{}{\patchcmd\document@select@group{#1{#4}}{\expandafter#1\ifx\math@bgroup\bgroup{#4}\else#4\fi}{}{}}% + \fi + \RequirePackage[mtbold]{mathtime} + \DeclareSymbolFont{largesymbolsA}{U}{esint}{m}{n}%from esint.sty + \DeclareMathSymbol{\oiintop}{\mathop}{largesymbolsA}{'015}%from esint.sty + \def\oiint{\oiintop\nolimits}%from esint.sty + \DeclareMathSymbol{\fintop}{\mathop}{largesymbolsA}{'037}%from esint.sty + \def\fint{\fintop\nolimits}%from esint.sty + \ifx\xmltexversion\@undefined\else{\catcode`\_=\active\global\let_\xmltexUndersc@re}\fi + \if@sansserifface + \DeclareMathVersion{sans} + \DeclareMathVersion{sansbold} + \def\mversion@sans{sans}\def\mversion@sansbold{sansbold} + \SetSymbolFont{operators}{sans}{OT1}{hvr}{m}{n}% + \SetSymbolFont{letters}{sans}{OML}{hvm}{m}{it}% + \SetSymbolFont{symbols} {sans}{MY2}{mtt}{m}{n}%because +=; reencoded in mathtime.sty + \SetSymbolFont{largesymbols}{sans}{OMX}{hvex}{m}{n}% + \SetSymbolFont{operators}{sansbold}{OT1}{hvr}{bx}{n}% + \SetSymbolFont{letters}{sansbold}{OML}{hvm}{b}{it}% + \SetSymbolFont{symbols} {sansbold}{MY2}{mtt}{b}{n}%because +=; reencoded in mathtime.sty + \def\provide@fontspec@symbol#1{% + \expandafter\let\csname mt#1\expandafter\endcsname\csname#1\endcsname + \expandafter\DeclareRobustCommand\expandafter*\csname #1\endcsname{% + \ifx\math@version\mversion@sans\csname orig#1\endcsname + \else\ifx\math@version\mversion@sansbold\csname orig#1\endcsname + \else\csname mt#1\endcsname\fi\fi}} + \provide@fontspec@symbol{Gamma} + \provide@fontspec@symbol{Delta} + \provide@fontspec@symbol{Theta} + \provide@fontspec@symbol{Lambda} + \provide@fontspec@symbol{Xi} + \provide@fontspec@symbol{Pi} + \provide@fontspec@symbol{Sigma} + \provide@fontspec@symbol{Upsilon} + \provide@fontspec@symbol{Phi} + \provide@fontspec@symbol{Psi} + \provide@fontspec@symbol{Omega} + \DeclareMathDelimiter{(}{\mathopen} {operators}{"28}{largesymbols}{"00}%was reencoded in mathtime.sty + \DeclareMathDelimiter{)}{\mathclose}{operators}{"29}{largesymbols}{"01}%was reencoded in mathtime.sty + \SetMathAlphabet\mathrm{sans}{OT1}{hvr}{m}{n}%mind! (gives more flexibility) + \SetMathAlphabet\mathrm{sansbold}{OT1}{hvr}{bx}{n}%mind! (gives more flexibility) + \SetMathAlphabet\mathit{sans}{OT1}{hvr}{m}{it}% + \SetMathAlphabet\mathit{sansbold}{OT1}{hvr}{bx}{it}% + \SetMathAlphabet\mathbf{sans}{OT1}{hvr}{bx}{n}% + \SetMathAlphabet\mathbf{sansbold}{OT1}{hvr}{bx}{n}% + \RequirePackage{hvams} + %neu: + \DeclareFontShape{U}{msb}{m}{n}{<-6>msbm5<6-8>msbm7<8->msbm10}{}%aus amsfonts.sty + \DeclareFontFamily{U}{msbhv}{}%umbenannt aus hvams.sty + \DeclareFontShape{U}{msbhv}{m}{n}{<->\@l@scale hvbm10}{}%umbenannt aus hvams.sty + \SetMathAlphabet\mathbb{sans}{U}{msbhv}{m}{n}% + \SetMathAlphabet\mathbb{sansbold}{U}{msbhv}{m}{n}% + %Ende neu + \DeclareMathAlphabet\mathbold{MY1}{mtt}{b}{\greekshape}% + \SetMathAlphabet\mathbold{sans}{OML}{hvm}{b}{it}% + \SetMathAlphabet\mathbold{sansbold}{OML}{hvm}{bx}{it}% + \fi + \else + \if@sansserifface + \DeclareMathVersion{sans} + \DeclareMathVersion{sansbold} + \SetSymbolFont{operators}{sansbold}{OT1}{cmr} {bx}{n} + \SetSymbolFont{letters} {sansbold}{OML}{cmm} {b}{it} + \SetSymbolFont{symbols} {sansbold}{OMS}{cmsy}{b}{n} + \SetMathAlphabet\mathsf{sansbold}{OT1}{cmss}{bx}{n} + \SetMathAlphabet\mathit{sansbold}{OT1}{cmr}{bx}{it} + \DeclareMathAlphabet\mathbold{OML}{cmm}{b}{it}% + \fi + \fi +\else%discussions + \if@cop@home + \if@hvmath + \RequirePackage{hvmath} + \expandafter\let\csname\expandafter\string\csname T1\endcsname\string\'-\string y\endcsname\relax%patching wrong glyph in hvr, slot 253 + \DeclareMathSymbol{,}{\mathpunct}{operators}{"2C} + \DeclareMathSymbol{.}{\mathord}{operators}{"2E} + \RequirePackage{hvams} + \else + \let\rmdefault\sfdefault + \DeclareSymbolFont{operators}{OT1}{cmss} {m}{n} + \DeclareMathAlphabet{\mathbf}{OT1}{cmss}{bx}{n} + \fi + \else + \let\rmdefault\sfdefault + \DeclareSymbolFont{operators}{OT1}{cmss} {m}{n} + \DeclareMathAlphabet{\mathbf}{OT1}{cmss}{bx}{n} + \fi +\fi +\DeclareMathAlphabet{\mathbbs}{U}{BOONDOX-ds}{m}{n} +\DeclareMathAlphabet{\mathblackbold}{U}{dsrom}{m}{n} +\let\ltx@mathbb\mathbb + +\def\mathbb#1{% + \sbox\z@{\@tempcnta 0#1}% + \ifdim\wd\z@>\z@\relax + \edef\@tempb{#1}\@tempcnta=\expandafter`\@tempb\relax% + \ifnum\@tempcnta>96\relax + \mathbbs{#1}%% Kleinbuchstabe + \else + \ltx@mathbb{#1}%% Großbuchstabe + \fi + \else + \mathblackbold{#1}%% Zahl + \fi} + +\RequirePackage{pifont} +\if@cop@home + \if@nohyperref + \else + \if@stage@final\else + \PassOptionsToPackage{pagebackref,pdffitwindow}{hyperref} + \fi + %\@pdfa@pre@hyper + \@iflatexlater{2020/10/01}{% + \usepackage[bookmarks=true,colorlinks]{hyperref} + \hypersetup{anchorcolor=black,citecolor=black,filecolor=black,linkcolor=black,unicode,% + menucolor=black,urlcolor=black}%% + }{% + \usepackage[\ifcopyediting bookmarks=false\else bookmarks=true\fi,colorlinks]{hyperref} + \hypersetup{anchorcolor=black,citecolor=black,filecolor=black,linkcolor=black,% + menucolor=black,pagecolor=black,urlcolor=black} + }% + \let\old@Hy@backout\Hy@backout\def\Hy@backout{\leavevmode\old@Hy@backout}%bug-fixing, to be checked + \ifnum\pdfoutput=\z@\RequirePackage{breakurl}\fi + \pdfstringdefDisableCommands{\let\boldsymbol\relax\let\vec\relax} + \fi + \edef\@pdfcreator{% + copernicus.cls% + \space Version \csname ver@copernicus.cls\endcsname + \ifx\xmltexversion\@undefined\else, produced from XML\fi} + % \if@nohyperref + \AtEndDocument{% + \ifx\xmltexversion\@undefined + \ifluatex + \def\Hy@tempx{\pdfextension info} + \else + \def\Hy@tempx{\pdfinfo} + \fi% + \let\Hy@author\@pdf@authors\Hy@UseMaketitleString{author}% + \let\Hy@title\@xmp@title\Hy@UseMaketitleString{title}% + \ifx\@xmp@keywords\@empty\else + \let\Hy@keywords\@xmp@keywords\Hy@UseMaketitleString{keywords}% + \fi + \Hy@tempx{% + /Title (\@pdftitle) + /Author (\@pdfauthor) + \ifx\@pdfkeywords\@empty\else/Keywords (\@pdfkeywords)\fi + /Creator (\@pdfcreator) + }% + \else + % \protected@edef\@pdftitle{\xml@pdftitle}% + % \protected@edef\@pdfauthor{\@pdf@authors}% + % \ifx\@keywords\@undefined\else\protected@edef\@pdfkeywords{\@keywords}\fi% + \fi + }% + % \fi +\else + %\@pdfa@pre@hyper + \usepackage[bookmarks=false,pdfborder={0 0 0}]{hyperref} + \pdfstringdefDisableCommands{\let\boldsymbol\relax\let\vec\relax} +\fi +\ifx\xmltexversion\@undefined +\else + \ifnum\pdfoutput=\z@ + \def\ReadBookmarks{% + \begingroup + \escapechar=`\\% + \let\escapechar\@gobble % + \def\@@BOOKMARK[##1][##2]##3##4##5{\calc@bm@number{##5}}% + \@inputtoc{\jobname.out}{}{}% + \ifx\WriteBookmarks\relax + \global\let\WriteBookmarks\relax + \fi + \def\@@BOOKMARK[##1][##2]##3##4##5{% + \def\Hy@temp{##4}% + \pdfmark{% + pdfmark=/OUT,% + Count={##2\check@bm@number{##3}},% + Dest={##3},% + Title=\expandafter\strip@prefix\meaning\Hy@temp + }% + }% + {% + \def\WriteBookmarks{0}% + \@inputtoc{\jobname.out}{}{}% + }% + %{\escapechar\m@ne\InputIfFileExists{\jobname.out}{}{}}% + \ifx\WriteBookmarks\relax + \else + \if@filesw + \newwrite\@outlinefile + \immediate\openout\@outlinefile=\jobname.out\relax + \ifHy@typexml + \immediate\write\@outlinefile{<relaxxml>\relax}% + \fi + \fi + \fi + \endgroup} + \else + \def\ReadBookmarks{% + \begingroup + \escapechar=`\\% + \let\escapechar\@gobble % + \def\@@BOOKMARK[##1][##2]##3##4##5{\calc@bm@number{##5}}% + \@inputtoc{\jobname.out}{}{}% + \ifx\WriteBookmarks\relax + \global\let\WriteBookmarks\relax + \fi + \def\@@BOOKMARK[##1][##2]##3##4##5{% + \def\Hy@temp{##4}% + \Hy@pstringdef\Hy@pstringName{\HyperDestNameFilter{##3}}% + \Hy@OutlineName{}\Hy@pstringName{% + ##2\check@bm@number{##3}% + }{% + \expandafter\strip@prefix\meaning\Hy@temp + }% + }% + {% + \def\WriteBookmarks{0}% + \@inputtoc{\jobname.out}{}{}% + }% + %{\escapechar\m@ne\InputIfFileExists{\jobname.out}{}{}}% + \ifx\WriteBookmarks\relax + \else + \if@filesw + \newwrite\@outlinefile + \immediate\openout\@outlinefile=\jobname.out\relax + \ifHy@typexml + \immediate\write\@outlinefile{<relaxxml>\relax}% + \fi + \fi + \fi + \endgroup} + \fi +\fi +\if@stage@final\else + \if@cop@home + \ifonline + \let\orig@psheadings\ps@headings + \let\orig@abstractname\abstractname + \let\orig@pdfcreator\@pdfcreator + \usepackage[screen,rightpanel]{pdfscreencop} + \let\ps@headings\orig@psheadings \pagestyle{headings}%because pdfscreencop overwrites it + \let\abstractname\orig@abstractname%because pdfscreencop overwrites it + \let\@pdfcreator\orig@pdfcreator%because pdfscreencop overwrites it + \setcounter{secnumdepth}{3}%because pdfscreencop sets it to 4 + \setlength\footskip{5mm}%because pdfscreencop overwrites it + \def\addButton#1#2{\begingroup\normalsfcodes\fboxsep\z@ + \sffamily\colorbox{buttonbackground}{\hbox to#1{\hfil\Black\st#2\hfil}}\endgroup} + \@iflatexlater{2020/10/01}{% + \hypersetup{anchorcolor=black,citecolor=black,filecolor=black,linkcolor=black,% + menucolor=black,urlcolor=black,% + pdfcenterwindow=false,pdfmenubar=true,pdftoolbar=true,pdfwindowui=true}%% + }{% + \hypersetup{anchorcolor=black,citecolor=black,filecolor=black,linkcolor=black,% + menucolor=black,pagecolor=black,urlcolor=black,% + pdfcenterwindow=false,pdfmenubar=true,pdftoolbar=true,pdfwindowui=true} + }% + % because pdfscreencop overwrites it + \def\PDFSCR@Warning#1{}% no more "No overlay specified" warnings + \setlength\panelwidth{5cm}% + \newlength\bigbutton\setlength\bigbutton{0.75\panelwidth}% + \newlength\buttongap\setlength\buttongap{0.06\panelwidth}% + \newlength\smallbutton\setlength\smallbutton{0.5\bigbutton}% + \addtolength\smallbutton{-0.5\buttongap-0.5pt}% + \def\panelfont{\rmfamily\scriptsize}% + \margins{10mm}{10mm}{7mm}{7mm}% + \screensize{15.9cm}{21.6cm}% + \definecolor{backgroundcolor}{rgb}{1.,1.,1.}%white + \backgroundcolor{backgroundcolor}% + \definecolor{section0}{rgb}{0.,0.,0.}%black + \definecolor{section1}{rgb}{0.,0.,0.}%black + \definecolor{section2}{rgb}{0.,0.,0.}%black + \definecolor{section3}{rgb}{0.,0.,0.}%black + \definecolor{section4}{rgb}{0.,0.,0.}%black + \def\panel{% + \colorbox[rgb]{0.94,0.95,0.95}% + {\begin{minipage}[t][\paperheight][t]{\panelwidth} + %% set default font for panel: + \fontseries{m}\fontshape{n}\fontsize{11}{13.7pt}\rmfamily + %% journal name, volume, pages, year, runningtitle, runningauthor: + \null\vspace*{7mm}% + \centering + \parbox[t]{0.8\panelwidth}% + {\centering\color{paneltext}% + {\Large\bfseries + %overwrite of default urlcolor=black to journal-specific color @journalname + %for the @journalnameshort link to the journal webpage on the panel + \hypersetup{urlcolor=journalname}% + \href{http://\@journalurl}{\@journalnameshort}}\\[2mm] + \if@noref + \else + {\fontsize{8.7}{11}\selectfont + %\@pvol, \@fpage\if@nolastpage\else{--\@lpage}\fi, \@pyear + \hypersetup{urlcolor=paneltext}\doi{10.5194/\@msnumber}% + }\\[1mm]% + \fi + \rule{0.8\panelwidth}{1.1pt}\\[1mm] + {\bfseries\mathversion{bold}% + \leavevmode\null + \ifx\firstruntit@utput\@undefined + \global\let\firstruntit@utput\relax + \else + \def\blackb@x[##1]##2{\relax}% + \fi + \@runtit}% + \if@noauthor\else\\[3mm]{\small\leavevmode\null\@runauth}\fi + \\[0mm]% + \rule{0.8\panelwidth}{1.1pt}\\[5mm]} %keep this blank! + %% the buttons: + \addButton{\bigbutton} + {\hyperlink{title}{\hfill\color{buttontext}Title Page\hfill}}% + \\[1.5mm] + \addButton{\smallbutton} + {\hyperlink{abstr}{\hfill\color{buttontext}Abstract\hfill}}% + \hspace{\buttongap}% + \ifessd + \addButton{\smallbutton} + {\hyperlink{instru}{\hfill\color{buttontext}Instruments\hfill}}% + \\[1.5mm] + \else + \addButton{\smallbutton} + {\hyperlink{intro}{\hfill\color{buttontext}Introduction\hfill}}% + \\[1.5mm] + \fi + \ifessd + \addButton{\bigbutton} + {\hyperlink{datastruct}{\hfill\color{buttontext}Data Provenance \& Structure\hfill}}% + \\[1.5mm] + \else + \addButton{\smallbutton} + {\hyperlink{conclusions}{\hfill\color{buttontext}Conclusions\hfill}}% + \hspace{\buttongap}% + \addButton{\smallbutton} + {\hyperlink{references}{\hfill\color{buttontext}References\hfill}}% + \\[1.5mm] + \fi + \addButton{\smallbutton} + {\@ifundefined{@numtable}%automatically defined via \@num\@captype + {\hfill\color{buttontext}Tables\hfill} + {\hyperlink{table}{\hfill\color{buttontext}Tables\hfill}}}% + \hspace{\buttongap}% + \addButton{\smallbutton} + {\@ifundefined{@numfigure}% automatically defined via \@num\@captype + {\hfill\color{buttontext}Figures\hfill} + {\hyperlink{figure}{\hfill\color{buttontext}Figures\hfill}}}% + \\[4mm]% + \Acrobatmenu{FirstPage}{\addButton{\smallbutton}% + {\color{buttontext}$\rule[-0.144ex]{0.35ex}{1.244ex}\!\blacktriangleleft$}}% + \hspace{\buttongap}% + \Acrobatmenu{LastPage} + {\addButton{\smallbutton}% + {\color{buttontext}$\blacktriangleright\!\rule[-0.144ex]{0.35ex}{1.244ex}$}}% + \\[1.5mm] + \Acrobatmenu{PrevPage} + {\addButton{\smallbutton}{\color{buttontext}$\blacktriangleleft$}}% + \hspace{\buttongap}% + \Acrobatmenu{NextPage} + {\addButton{\smallbutton}{\color{buttontext}$\blacktriangleright$}}% + \\[1.5mm] + \Acrobatmenu{GoBack}{\addButton{\smallbutton}{\color{buttontext}Back}}% + \hspace{\buttongap}% + \Acrobatmenu{Close}{\addButton{\smallbutton}{\color{buttontext}Close}}% + \\[1.5mm] + \Acrobatmenu{FullScreen}{\addButton{\bigbutton}{\color{buttontext}Full Screen / Esc}}% + \\[4mm] + \addButton{\bigbutton} + {\href{http://\@journalurl/\@pvol/\@fpage/\@pyear/\@journalnameshortlower-\@pvol-\@fpage-\@pyear-print.pdf}% + {\hfill\color{buttontext}Printer-friendly Version\hfill}}% + \\[1.5mm] + \addButton{\bigbutton} + {\href{http://\@journalurl/\@pvol/\@fpage/\@pyear/\@journalnameshortlower-\@pvol-\@fpage-\@pyear-discussion.html}% + {\hfill\color{buttontext}Interactive Discussion\hfill}}% + \\[4mm] + \href{http://creativecommons.org/licenses/by/3.0/}{\includegraphics[width=1.7cm]{CreativeCommons_Attribution_License.png}}% + \null\vspace*{10mm}% + \end{minipage}}} + \fi + \fi +\fi +%% some of the following commands are only active if \@cop@hometrue +\def\texlicencestatement#1#2{\gdef\@texlicencestatement{#1}\gdef\@texlicencelogo{#2}}% + \def\@texlicencestatement{\CopernicusError{Please add \string\texlicencestatement}{You must provide the licence statement before \string\maketitle"}} +\def\received#1{\if@cop@home\def\@recvd{#1}\fi} \def\@recvd{}%+1,+2,+d +\def\pubdiscuss#1{\if@cop@home\def\@pubdiscuss{#1}\fi} \def\@pubdiscuss{}%+1,+2,-d -- twostagejnltrue +\def\revised#1{\if@cop@home\def\@revsd{#1}\fi} \def\@revsd{}%+1,+2,-d +\def\accepted#1{\if@cop@home\def\@accptd{#1}\fi} \def\@accptd{}%+1,+2,+d +\def\published#1{\if@cop@home\gdef\@published{#1}\fi} \if@stage@final\else\def\@published{}\fi%+1,+2,+d +\def\firstpage#1{\if@cop@home\ifx\specialp@perstring\@undefined\ifx\citati@nbyarticlenumber\@undefined\gdef\@fpage{#1}\fi\fi\fi} + \def\@fpage{1}%+1,+2,+d +\def\articlenumber#1{\if@cop@home\ifx\specialp@perstring\@undefined\ifx\citati@nbyarticlenumber\relax\gdef\@fpage{#1}\gdef\article@number{#1}\fi\fi\fi} +\def\citationbyarticlenumber{% + \@nolastpagetrue + \let\citati@nbyarticlenumber\relax + \def\@fpage{-1}} +\ifx\xmltexversion\@undefined + \@onlypreamble\citationbyarticlenumber +\fi +\def\pubyear#1{\if@cop@home\ifx\specialp@perstring\@undefined\gdef\@pyear{#1}\fi\gdef\@cyear{#1}\fi} + \def\@pyear{\number\year}%+1,+2,+d + \let\@cyear\@pyear +\def\pubvol#1{\if@cop@home\ifx\specialp@perstring\@undefined\gdef\@pvol{#1}\fi\fi}%+1,+2,+d +\let\pubnum\@gobble%not for TeX, only for secondary data use +\def\@corresp{% + \ifnum\corr@cnt=\@ne\relax + \csname corresp-1\endcsname% + \else + \ifnum\corr@cnt=\tw@\relax + \csname corresp-1\endcsname\Authand\csname corresp-2\endcsname% + \else + \@tempcnta\z@ + \loop + \advance\@tempcnta\@ne + \csname corresp-\the\@tempcnta\endcsname% + \ifnum\@tempcnta<\numexpr\corr@cnt+\m@ne\relax\relax + \Authsep + \repeat + \Authands\csname corresp-\the\corr@cnt\endcsname% + \fi + \fi +} +\def\correspondence#1{\gdef\@corresp{#1}}% +\def\citationstatement#1{% + \edef\@@doi{https://doi.org/10.5194/\@journalnameshortlower-\@pvol-\@fpage-\@pyear}% + \def\@tempa{#1}% + \ifx\@tempa\@empty + \gdef\@howtocite{}% + \else + \ifcopyediting + \gdef\@howtocite{}% + \else + \gdef\@howtocite{#1, \@journalnameabbreviation, \@pvol, \@fpage--\@lpage, \expandafter\url{\@@doi}, \@pyear.}% + \fi + \fi +}\def\@howtocite{}%+1,+2,+d +\def\msnumber#1{\if@cop@home\gdef\@msnumber{#1}\fi} +\if@stage@final +\else + \def\affilfontsize#1{\def\@affilfontsize{#1}} + \def\@affilfontsize{\small} +\fi +\if@stage@final + \def\bartext#1{\gdef\@btext{#1}} \def\@btext{} +\fi +\if@cop@home + \newcounter{jnlvolume}%the journal volume + \setcounter{jnlvolume}{\number\year} + \addtocounter{jnlvolume}{1} + \AtBeginDocument{\addtocounter{jnlvolume}{-\@journalstartyear}} + \def\@pvol{\arabic{jnlvolume}} + \if@stage@final + \ifadgeo\def\@pvol{1}\fi + \ifasr\def\@pvol{1}\fi + \fi + \AtBeginDocument{% + \ifx\specialp@perstring\@undefined\else + \def\origfirstpage#1{\ifx\citati@nbyarticlenumber\@undefined\gdef\@fpage{#1}\fi} + \def\origlastpage#1{\gdef\@lpage{#1}} + \def\origpubyear#1{\gdef\@pyear{#1}} + \def\origpubvol#1{\gdef\@pvol{#1}} + \def\origarticlenumber#1{\ifx\citati@nbyarticlenumber\relax\gdef\@fpage{#1}\fi} + \fi} +\else + \def\@pvol{0} +\fi +\if@stage@final + \def\keywords#1{% + \ifcopyediting\else\xmp@keywords{#1}\fi% + \def\@keyw{#1}% + } + \def\@keyw{} +\else + \def\keywords#1{% + \ifcopyediting\else\xmp@keywords{#1}\fi% + \CopernicusWarningNoLine{Keywords are not supported.}% + \vspace{1.7mm}\par\noindent\textbf{Keywords.}\enspace\ignorespaces#1} +\fi +\newcommand*\editorthanks[3] + {\ifthenelse{\equal{#2}{}}% check if the first referee exits, if not write: + {\\ \hspace*{4mm} Topical Editor\ #1\ thanks two unknown referees % + for their help in evaluating this paper.} + {\ifthenelse{\equal{#3}{}}% check if second referee exist, if not write: + {\\ \hspace*{4mm}Topical Editor\ #1\ thanks\ #2\ and another % + referee for their help in evaluating this paper.}% + {\\ \hspace*{4mm}Topical Editor\ #1\ thanks\ #2\ and\ #3\ for their % + help in evaluating this paper.}}} +\def\runningauthor#1{\def\@runauth{#1}} +\def\@runauth{} +\def\runningtitle#1{\def\@runtit{#1}} +\def\@runtit{} +\if@stage@final + \def\runninghead#1{\def\@runhd{#1}} + \def\@runhd{% + \ifx\firstrunhd@utput\@undefined + \global\let\firstrunhd@utput\relax + \else + \def\blackb@x[##1]##2{\relax}% + \fi + \if@noauthor\else\@runauth: \fi\@runtit} +\fi +\DeclareRobustCommand*\degree{\ensuremath{^{\circ}}} +\DeclareRobustCommand*\permil{\ifmmode\text{\textperthousand}\else\textperthousand\fi} +\def\@Radical{\put(2.0,2.0){\circle*{1.5}}\kern3.5\p@} +\def\@RadicalC{\raise0.25ex\hbox{\@Radical}} +\DeclareRobustCommand*\Radical{% + \ifmmode\mathchoice{\@RadicalC}{\@RadicalC}{\@Radical}{\@Radical}\else\@RadicalC\fi} +\def\testbx{bx} +\DeclareRobustCommand*\chem[1] + {\ensuremath{% + {\mathcode`\-="0200\mathcode`\=="003D% no space around "-" and "=" + \ifx\f@series\testbx\mathbf{#1}\else\mathrm{#1}\fi}}} +\@ifpackageloaded{hyperref} + {\begingroup + \toks0=\expandafter{\pdfstringdefPreHook}% + \xdef\pdfstringdefPreHook{% + \the\toks0 % + \let\noexpand\hack\noexpand\@gobble + \let\noexpand\chem\noexpand\@firstofone}% + \endgroup} + {\relax} +\DeclareRobustCommand*\unit[1] + {\ensuremath{% + {\thinmuskip3mu\relax + \def\mu{\text{\textmu}}\def~{\,}% + \ifx\f@series\testbx\mathbf{#1}\else\mathrm{#1}\fi}}} +\@definecounter{reaction} +\def\thereaction{R\@arabic\c@reaction} +\let\c@org@eq\c@equation +\let\org@theeq\theequation +\def\setreaction{% + \global\let\c@equation\c@reaction + \global\let\theequation\thereaction} +\def\setequation{% + \global\let\c@equation\c@org@eq + \global\let\theequation\org@theeq} +\newenvironment{reaction} + {\let\c@equation\c@reaction + \let\theequation\thereaction + \incr@eqnum + \mathdisplay@push + \st@rredfalse \global\@eqnswtrue + \mathdisplay{equation}} + {\endmathdisplay{equation}% + \mathdisplay@pop + \ignorespacesafterend} +\IfFileExists{lineno.sty} + {\AtBeginDocument{% + \patchAmsMathEnvironmentForLineno{reaction}}} + {} +\newenvironment{rxnarray} + {\let\c@equation\c@reaction + \let\theequation\thereaction + \eqnarray} + {\endeqnarray + \let\c@equation\c@reaction + \let\theequation\thereaction} +\if@stage@final\else + \newcounter{parentreaction} + \newenvironment{subreactions} + {\refstepcounter{reaction}% + \protected@edef\theparentreaction{\thereaction}% + \setcounter{parentreaction}{\value{reaction}}% + \setcounter{reaction}{0}% + \def\thereaction{\theparentreaction\alph{reaction}}% + \ignorespaces} + {\setcounter{reaction}{\value{parentreaction}}% + \ignorespacesafterend} +\fi +\newcommand\tophline{\hline\noalign{\vspace{1mm}}} +\newcommand\middlehline{\noalign{\vspace{1mm}}\hline\noalign{\vspace{1mm}}} +\newcommand\bottomhline{\noalign{\vspace{1mm}}\hline} +\newcommand\hhline{\noalign{\vspace{1mm}}\hline\noalign{\vspace{1mm}}} +\newdimen\tabularwidth +\def\@tabular{% + \leavevmode + \setbox\z@ + \hbox \bgroup $\col@sep\tabcolsep \let\d@llarbegin\begingroup + \let\d@llarend\endgroup + \@tabarray} +\def\endtabular{\endarray $\egroup + \global\tabularwidth\wd\z@ + \unhbox\z@} +\expandafter\let\csname endtabular*\endcsname=\endtabular +\DeclareRobustCommand\belowtable[1]{% + \par\vspace{1ex}% + {\if@stage@final\else\def\@tempa{table}\ifx\@captype\@tempa\else\centering\fi\fi + \ifdim\tabularwidth<10mm\tabularwidth\hsize\fi + \leavevmode\vrule\@width\z@\@height2ex\@depth\z@ + \parbox{\tabularwidth}{\raggedright\scriptsize#1}% + \if@stage@final\else\par\fi}} +\ifessd + \newcommand\instrumentation[1][Instrumentation] + {\section[#1]{#1\if@cop@home\ifonline\hypertarget{instru}{}\fi\fi}} + \newcommand\datastructure[1][Data Provenance and Structure] + {\section[#1]{#1\if@cop@home\ifonline\hypertarget{datastruct}{}\fi\fi}} +\fi +\newcommand\introduction[1][\introductionname] + {\section[#1]{#1\if@cop@home\ifonline\hypertarget{intro}{}\fi\fi}} +\newcommand\conclusions[1][\conclusionname] + {\section[#1]{#1\if@cop@home\ifonline\hypertarget{conclusions}{}\fi\fi}} +\newcommand\Supplementary[2][]{{% + \advance\partopsep0.5\baselineskip + % %2- und 3-zeilige Supplement-Blöcke sollen den gleichen vertikalen Raum in Anspruch nehmen;%% Nicht mehr seit 2018-11-07 + % \setbox\longtwo@box\hbox{\supplement{#1}.}% + \begin{trivlist}% + \if@stage@final + \let\\\@centercr%\@rightskip\z@\@plus\tw@ em + %\rightskip\@rightskip + \parindent\z@ + \fi + \let\do@skip\relax + \def\@argi{#1}\ifx\@argi\@empty\else\let\do@skip\space\fi% + \item \dosupplement{#1\do@skip The supplement related to this article is available online at: + \if@stage@final\else\\\fi + \supplement{#2}.}% + \end{trivlist}% + }} +\def\generateCommand#1#2{% + \expandafter\long\expandafter\def\csname#1\endcsname##1{% + \if@stage@final\ifhmode\vskip2\baselineskip\else\addvspace{2\baselineskip}\fi\fi + \bgroup + \list{}{\labelwidth\z@ \leftmargin\z@ \itemindent-\leftmargin + \parsep\z@ + \listparindent\parindent + \def\makelabel####1{% + \hspace\labelsep + \if@stage@final + \if@sansserifface + \sffamily\bfseries\mathversion{sansbold}\textcolor{textcol}{####1.}% + \else + \itshape####1.% + \fi + \pdfbookmark[1]{\csname #1name\endcsname}{#1}% + \else + \itshape####1.% + \fi}% + \reset@font\small}% + \item[\csname #1name\endcsname]% + ##1#2}} +\generateCommand{copyrightstatement}{\endlist\egroup} +\ifessd + \long\def\codeavailability#1{\ifx\thesection\theolds\else\noappendix\fi\section{\codeavailabilityname}#1} + \long\def\dataavailability#1{\ifx\thesection\theolds\else\noappendix\fi\section{\dataavailabilityname}#1} + \long\def\codedataavailability#1{\ifx\thesection\theolds\else\noappendix\fi\section{\codedataavailabilityname}#1} + \long\def\ercavailability#1{\ifx\thesection\theolds\else\noappendix\fi\section{\ercavailabilityname}#1} +\else + \generateCommand{codeavailability} {\endlist\egroup} + \generateCommand{dataavailability} {\endlist\egroup} + \generateCommand{codedataavailability}{\endlist\egroup} + \generateCommand{ercavailability}{\endlist\egroup} +\fi +\generateCommand{authorcontribution}{\endlist\egroup} +\generateCommand{sampleavailability}{\endlist\egroup} +\generateCommand{competinginterests}{\endlist\egroup} +\generateCommand{teamlist} {\endlist\egroup} +\generateCommand{videosupplement} {\endlist\egroup} +\generateCommand{disclaimer} {\endlist\egroup} +\generateCommand{sistatement} {\endlist\egroup} +\generateCommand{dosupplement} {\endlist\egroup} +\generateCommand{financialsupport} {\endlist\egroup} +\generateCommand{reviewstatement} {\endlist\egroup} +\long\def\specialsection#1#2{% + \expandafter\def\csname specialsection-#1name\endcsname{#1}% + \expandafter\ifx\csname specialsection-#1name\endcsname\@empty + \PackageError{copernicus.cls}{\string\specialsection\space needs a heading.}{Make sure that \string\specialsection{}{}\space has two arguments and that the first argument contains a heading.}% + \else + \generateCommand{specialsection-#1} {\endlist\egroup}% + \csname specialsection-#1\endcsname{#2}% + \fi} + +\generateCommand{acknowledgement} {} \def\endacknowledgement{\endlist\egroup} +\generateCommand{acknowledgements} {} \def\endacknowledgements{\endlist\egroup} +\iffalse %instead of \if@stage@final, to check what they want + \def\appendixfigures{% + \ifx\afterfirstappendixfigures\@undefined + \let\afterfirstappendixfigures\relax + \fi + \setcounter{figure}{0}% + \def\thefigure{A\@arabic\c@figure}% + \let\theHfigure\thefigure} + \def\appendixtables{% + \ifx\afterfirstappendixtables\@undefined + \let\afterfirstappendixtables\relax + \fi + \setcounter{table}{0}% + \def\thetable{A\@arabic\c@table}% + \let\theHtable\thetable} +\else + \def\appendixfigures{% + \ifx\afterfirstappendixfigures\@undefined + \let\afterfirstappendixfigures\relax + \setcounter{section}{0}% + \def\thesection{\Alph{section}}% + \let\theHsection\thesection + \fi + \refstepcounter{section}% + \setcounter{figure}{0}% + \def\thefigure{\thesection\@arabic\c@figure}% + \let\theHfigure\thefigure} + \def\appendixtables{% + \ifx\afterfirstappendixtables\@undefined + \let\afterfirstappendixtables\relax + \setcounter{section}{0}% + \def\thesection{\Alph{section}}% + \let\theHsection\thesection + \fi + \refstepcounter{section}% + \setcounter{table}{0}% + \def\thetable{\thesection\@arabic\c@table}% + \let\theHtable\thetable} +\fi +\if@cop@home + \newcounter{CEnote} + \newcounter{TSnote} + \def\theCEnote{\@arabic\c@CEnote} + \def\theTSnote{\@arabic\c@TSnote} + \newtoks\CEnotes + \newtoks\TSnotes + \global\let\edit@rnotereminder\@empty%initialising + \def\n@telabel#1{\noexpand\n@tel@bel{#1\csname the#1note\endcsname}} + \def\n@tel@bel#1{% + \smash{\raisebox{0.2ex}{\bfseries\scriptsize\fboxsep1pt + \colorbox[RGB]{255,149,64}{\textcolor[RGB]{255,255,255}{#1}}}}} + \DeclareRobustCommand\blackbox{\@ifnextchar[\blackb@x{\blackb@x[TS]}}%] + \def\blackb@x[#1]#2{% + \refstepcounter{#1note}% + \CopernicusWarningNoLine{Editor's note on page \thepage}% + \hypertarget{#1\csname the#1note\endcsname} + {\hyperlink{#1\csname the#1note\endcsname R} + {\n@tel@bel{#1\csname the#1note\endcsname}}}% + \gdef\edit@rnotereminder{% + \smash{% + \if@stage@final + \llap{\rotatebox{90}{\scriptsize + \else + \tiny + \fi + \lower1ex\rlap{\fboxsep0.5ex\colorbox[RGB]{255,149,64}{\bfseries\strut + \textcolor[RGB]{255,255,255} + {Please note the remarks at the end of the manuscript.}}}% + \if@stage@final + }\kern\marginparsep}% + \fi + }% + \global\let\edit@rnotereminder\@empty}% + \edef\@tempa{\leavevmode + \noexpand\hypertarget{#1\csname the#1note\endcsname R} + {\noexpand\hyperlink{#1\csname the#1note\endcsname} + {\noexpand\hb@xt@10mm{\n@telabel{#1}\hss}}}}% + \global\csname #1notes\endcsname\expandafter\expandafter\expandafter{% + \the\expandafter\csname #1notes\expandafter\endcsname\@tempa\mdseries#2\par}} + \AtEndDocument{% + \if@stage@final + \onecolumn + \else + \clearpage + \fi + \if@proof\@prooffalse\fi + \thispagestyle{plain}% + \parindent\z@ + \begin{nolinenumbers}% + \expandafter\def\expandafter\@tempa\expandafter{\the\CEnotes}% + \expandafter\def\expandafter\@tempb\expandafter{\the\TSnotes}% + \ifx\@tempa\@empty + \else + \@tempcnta-\c@page + \section*{Remarks from the language copy-editor} + \hangindent10mm + \@tempa + \fi + \ifx\@tempb\@empty + \ifx\@tempa\@empty + \else + \advance\@tempcnta\c@page\advance\@tempcnta\@ne + \CopernicusInfo{Pages with editing remarks: \the\@tempcnta.}% + \fi + \else + \ifx\@tempa\@empty\@tempcnta-\c@page\fi + \section*{Remarks from the typesetter} + \hangindent10mm + \@tempb + \advance\@tempcnta\c@page\advance\@tempcnta\@ne + \CopernicusInfo{Pages with editing remarks: \the\@tempcnta.}% + \fi + \end{nolinenumbers}} +\fi +\def\iftwocol#1#2{\if@twocolumn#1\else #2\fi} +\let\hack\@firstofone +\let\notforhtml\@firstofone +\newcommand\@journalname{Journalname} +\newcommand\@journalnameabbreviation{J. Name} +\newcommand\@journalnameshort{JN} +\newcommand\@journalnameshortlower{jn} +\newcommand\@journalurl{www.jn.net} +\newcommand\@journalpublisher{Copernicus Publications} +\newcommand\@journalcopyright{% + %\copyright\ Author(s)\ \@cyear. % + \if!\@texlicencestatement!% + \CopernicusError{\string\texlicencestatement{} must have content}{Say, e.g., "\string\texlicencestatement{CC Attribution 4.0 License.}"}% + \else + \@texlicencestatement + \if!\@texlicencelogo!\else + \def\@optarg{width=1.5cm}% + \\[1mm] + \expandafter\expandafter\expandafter\includegraphics\expandafter\expandafter\expandafter[\expandafter\@optarg\expandafter]\expandafter{\@texlicencelogo} + \fi + \fi} +\newcommand\@journalstartyear{2013} +\newcommand\@journallogo{Journallogo} +\newcommand\@sentence{Sentence.} +\newcommand\@sentenceDisc{Sentence.} +\def\watermark{% + \smash{\rlap{% + \lower\dimexpr\paperheight-\headheight-\topmargin\relax\hbox{\hskip-\oddsidemargin\includegraphics{cop_watermark.pdf}}% + }} +} +\if@stage@final + \definecolor{watermark}{gray}{.85} + \definecolor{textcol}{rgb}{0,0,0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1,1,1} +\else + \definecolor{discussion_bartext}{gray}{0.5} + \definecolor{discussion_bartext_background}{gray}{0.85} +\fi +%%Now, journal configuration from copernicus.cfg: +\@addjournalconfig +%%Now, additions the manuscript and for the the discussion stage: +\if@stage@final + \if@manuscript + \definecolor{textcol}{rgb}{0,0,0} + \definecolor{bgcol}{rgb}{1,1,1} + \definecolor{barcol}{rgb}{1,1,1} + \fi +\else + \edef\@journalname{\@journalname\space Discussions} + \let\@journalnameabbreviationbase\@journalnameabbreviation + \edef\@journalnameabbreviation{\@journalnameabbreviation\space Discuss.} + \edef\@journalnameshort{\@journalnameshort D} + \edef\@journalnameshortlower{\@journalnameshortlower d} +\fi +\def\bElementCitation{} +\def\bUri#1{#1} +\def\bDate#1{#1} +\def\bYear#1{#1} +\def\bMonth#1{#1} +\def\bDay#1{#1} +\def\bPubId{} +\def\bLpage#1{#1} +\def\bFpage#1{#1} +\def\bPersonGroup#1{#1} +\def\bPersonGroup#1{#1} +\def\bName#1{#1} +\def\bName#1{#1} +\def\bCollab#1{#1} +\def\bCollab#1{#1} +\def\bSurname#1{#1} +\def\bSurname#1{#1} +\def\bGivenNames#1{#1} +\def\bSuffix#1{#1} +\def\bSuffix#1{#1} +\def\bParticle#1{#1} +\def\bParticle#1{#1} +\def\bVolume#1{#1} +\def\bIssue#1{#1} +\def\bSource#1{#1} +\def\bSource#1{#1} +\def\bChapterTitle#1{#1} +\def\bComment#1{#1} +\def\bArticleTitle#1{#1} +\def\bSource#1{#1} +\def\bChapterTitle#1{#1} +\def\bSource#1{#1} +\def\bEtal#1{#1} +\def\bEtal#1{#1} +\def\bPublisherName#1{#1} +\def\bPublisherLoc#1{#1} +\def\bIsbn#1{#1} +\def\bDateInCitation#1{#1} +\def\bDateInCitation#1{#1} +\def\bEdition#1{#1} +\def\bConfName#1{#1} +\def\bConfLoc#1{#1} +\def\bConfDate#1{#1} +\def\bComment#1{#1} +\def\bPatent#1{#1} +\def\bSeries#1{#1} +\def\bStd#1{#1} +\def\bELocationID#1{#1} +\def\bAttribute#1#2{} + %% LEGACY + \def\Etal#1{#1} + \def\Issue#1{#1} + \def\Particle#1{#1} + \def\Link#1{#1} + \def\Year#1{#1} + \def\Lpage#1{#1} + \def\Fpage#1{#1} + \def\Volume#1{#1} + \def\Source#1{#1} + \def\Articletitle#1{#1} + \def\Givennames#1{#1} + \def\Surname#1{#1} + \def\FirstName#1{#1} + \def\Stringname#1{#1} + \def\Persongroup#1{#1} + \def\Journal#1{#1} + \def\Uri#1{#1} + \def\Content#1{#1} + \def\Book#1{#1} + \def\PublisherName#1{#1} + \def\PublisherLoc#1{#1} + %% /LEGACY +\def\mathring{\mathaccent6} + +\newenvironment{plainlist} +{\advance\@itemdepth\@ne + \expandafter + \list{} + {\leftmargin\z@ + \labelwidth\z@ + \labelsep\z@ + \itemsep\z@ + \topsep1\baselineskip + \parsep\p@\partopsep\z@ + \def\makelabel##1{\hss##1\if!##1!\else\enskip\fi}}% +} +{\endlist} + +\if@copDebug + \ifx\xmltexversion\@undefined + \DeclareUnicodeCharacter{200B}{{\unskip\;\color{red}\vrule \@width1ex \@height1ex}} + \fi +\fi +\endinput +%% +%% End of file `copernicus.cls'. diff --git a/acp/accepted/diff.pdf b/acp/accepted/diff.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dbd7c2cd874baed95d6af9c766a862273f97d8d8 Binary files /dev/null and b/acp/accepted/diff.pdf differ diff --git a/acp/accepted/diff.tex b/acp/accepted/diff.tex new file mode 100644 index 0000000000000000000000000000000000000000..fb5568a43f877291cca1ebd7d67bca8c1ec99bf7 --- /dev/null +++ b/acp/accepted/diff.tex @@ -0,0 +1,538 @@ +%% Copernicus Publications Manuscript Preparation Template for LaTeX Submissions +%DIF LATEXDIFF DIFFERENCE FILE +%DIF DEL ../revision/revised.tex Tue May 21 01:50:05 2024 +%DIF ADD revised2.tex Tue Jun 18 11:37:54 2024 +%% --------------------------------- +%% This template should be used for copernicus.cls +%% The class file and some style files are bundled in the Copernicus Latex Package, which can be downloaded from the different journal webpages. +%% For further assistance please contact Copernicus Publications at: production@copernicus.org +%% https://publications.copernicus.org/for_authors/manuscript_preparation.html + + +%% Please use the following documentclass and journal abbreviations for preprints and final revised papers. + +%% 2-column papers and preprints +\documentclass[acp, manuscript]{copernicus} + + + + +%% \usepackage commands included in the copernicus.cls: +%\usepackage[german, english]{babel} +%\usepackage{tabularx} +%\usepackage{cancel} +%\usepackage{multirow} +%\usepackage{supertabular} +%\usepackage{algorithmic} +%\usepackage{algorithm} +%\usepackage{amsthm} +%\usepackage{float} +%\usepackage{subfig} +%\usepackage{rotating} +%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF +%DIF UNDERLINE PREAMBLE %DIF PREAMBLE +\RequirePackage[normalem]{ulem} %DIF PREAMBLE +\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} %DIF PREAMBLE +\providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}} %DIF PREAMBLE +\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} %DIF PREAMBLE +%DIF SAFE PREAMBLE %DIF PREAMBLE +\providecommand{\DIFaddbegin}{} %DIF PREAMBLE +\providecommand{\DIFaddend}{} %DIF PREAMBLE +\providecommand{\DIFdelbegin}{} %DIF PREAMBLE +\providecommand{\DIFdelend}{} %DIF PREAMBLE +\providecommand{\DIFmodbegin}{} %DIF PREAMBLE +\providecommand{\DIFmodend}{} %DIF PREAMBLE +%DIF FLOATSAFE PREAMBLE %DIF PREAMBLE +\providecommand{\DIFaddFL}[1]{\DIFadd{#1}} %DIF PREAMBLE +\providecommand{\DIFdelFL}[1]{\DIFdel{#1}} %DIF PREAMBLE +\providecommand{\DIFaddbeginFL}{} %DIF PREAMBLE +\providecommand{\DIFaddendFL}{} %DIF PREAMBLE +\providecommand{\DIFdelbeginFL}{} %DIF PREAMBLE +\providecommand{\DIFdelendFL}{} %DIF PREAMBLE +%DIF LISTINGS PREAMBLE %DIF PREAMBLE +\RequirePackage{listings} %DIF PREAMBLE +\RequirePackage{color} %DIF PREAMBLE +\lstdefinelanguage{DIFcode}{ %DIF PREAMBLE +%DIF DIFCODE_UNDERLINE %DIF PREAMBLE + moredelim=[il][\color{red}\sout]{\%DIF\ <\ }, %DIF PREAMBLE + moredelim=[il][\color{blue}\uwave]{\%DIF\ >\ } %DIF PREAMBLE +} %DIF PREAMBLE +\lstdefinestyle{DIFverbatimstyle}{ %DIF PREAMBLE + language=DIFcode, %DIF PREAMBLE + basicstyle=\ttfamily, %DIF PREAMBLE + columns=fullflexible, %DIF PREAMBLE + keepspaces=true %DIF PREAMBLE +} %DIF PREAMBLE +\lstnewenvironment{DIFverbatim}{\lstset{style=DIFverbatimstyle}}{} %DIF PREAMBLE +\lstnewenvironment{DIFverbatim*}{\lstset{style=DIFverbatimstyle,showspaces=true}}{} %DIF PREAMBLE +%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF + +\begin{document} + +\title{Atmospheric cloud-radiative heating in CMIP6 and observations, and its response to surface warming} + +% \Author[affil]{given_name}{surname} +\Author[1][aiko.voigt@univie.ac.at]{Aiko}{Voigt} +\Author[1]{Stefanie}{North} +\Author[1]{Bla\v{z}}{Gasparini} +\Author[2]{Seung-Hee}{Ham} + +\affil[1]{Department of Meteorology and Geophysics, University of Vienna, Vienna, Austria} +\affil[2]{Analytical Mechanics Associates (AMA), Hampton, +VA, USA} + +\correspondence{Aiko Voigt (aiko.voigt@univie.ac.at)} + +\runningtitle{Cloud-radiative heating in CMIP6} + +\runningauthor{A. Voigt} + +\received{} +\pubdiscuss{} %% only important for two-stage journals +\revised{} +\accepted{} +\published{} + +%% These dates will be inserted by Copernicus Publications during the typesetting process. + + +\firstpage{1} + +\maketitle + +\begin{abstract} +Cloud-radiation-interactions are key to Earth's climate and its susceptibility to change. While their impact on Earth's energy budget has been studied in great detail, their effect on atmospheric temperatures has received little attention, despite its importance for the planetary circulation of the atmosphere and hence for regional climate and weather. Here, we present the first systematic assessment of vertically-resolved cloud-radiative heating within the atmosphere in 20 CMIP6 models, including a comparison to satellite-based estimates. Our analysis highlights model differences in cloud-radiative heating in both the lower and upper troposphere, as well as uncertainties related to cloud ice processes. It also illustrates limitations of our ability to observe cloud-radiative heating. Not surprisingly, the response of cloud-radiative heating to surface warming is also uncertain across models. Yet, in the upper troposphere the response is very well predicted by an upward shift of the present-day heating, which we show results from the fact that cloud-radiative heating in the upper troposphere is a function of air temperature and thus decoupled from surface temperature. Our results have three important implications for upper-tropospheric cloud-radiative heating: they establish a new null hypothesis for its response to warming, offer a physics-based prediction of its response to warming based on present-day observations, and emphasize the need for improving its representation in simulations of the present-day climate, possibly by combining the benefits of upcoming km-scale models and satellite observations. +\end{abstract} + + +\introduction +\DIFaddbegin \label{sec:introduction} +\DIFaddend + + +The interactions of tiny cloud particles with even tinier photons are key to climate and its susceptibility to change. It is well understood that clouds regulate Earth's energy balance by scattering photons back to space in the shortwave domain of the electromagnetic spectrum, and by intercepting and re-emitting photons in the longwave domain \citep{ramanathan_erbe_science1989,loeb_ceresebaf_ed4_jclim2018}. The interaction between clouds and radiation is often characterized by so-called cloud-radiative effects at the top of the atmosphere, which quantify the cloud impact by the difference between the energy balance of Earth and a hypothetical clear-sky climate in which clouds are assumed transparent to radiation. This widely-used top-of-atmosphere view forms the basis for much of our understanding of cloud-radiative feedbacks and their contribution to climate sensitivity \citep{sherwood_ecs_review_revgeo2020}. In this study, however, we take a different view and focus instead on cloud-radiation-interactions within the atmosphere, i.e., the radiative effect of clouds on atmospheric heating and cooling. + + +To quantify cloud-radiation-interactions within the atmosphere, we study the atmospheric cloud-radiative heating, a quantity sometimes also referred to as atmospheric cloud-radiative effects. Cloud-radiative heating is defined as +\begin{linenomath*} +\begin{equation} +\label{eq:crh_tntr_intro} + CRH(\lambda,\varphi,p,t) = \frac{\partial T}{\partial t}\bigg\vert^\textrm{all-sky}_\textrm{radiation} - \frac{\partial T}{\partial t}\bigg\vert^\textrm{clear-sky}_\textrm{radiation}. +\end{equation} +\end{linenomath*} +The coordinates $(\lambda,\varphi,p,t)$ emphasize that $CRH$ is a time-varying function of pressure, or altitude, and geographical location. The first term of the right hand side of the equation is the radiative heating of the all-sky atmosphere that includes cloud-radiation-interactions. The second term is the radiative heating of a hypothetical clear-sky atmosphere that is identical to the all-sky atmosphere apart from the fact that clouds are not interacting with radiation. +The philosophy behind cloud-radiative heating is the same as that behind top-of-atmosphere cloud-radiative effects, yet cloud-radiative heating is the more challenging quantity: very different vertical profiles of cloud-radiative properties and heating can lead to the same top-of-atmosphere cloud-radiative effects, and diagnosing cloud-radiative heating requires knowledge of the vertical distribution of clouds. It seems likely that this diagnostic challenge is one reason for why the vast majority of studies have focused on top-of-atmosphere cloud-radiative effects, while studies of cloud-radiative heating have remained relatively rare. + +There is no shortage of reasons to understand cloud-radiative heating, however. Cloud-radiative heating influences the clouds that underlie its very existence, e.g., it prolongs the lifetime of tropical anvil clouds \citep{wall_tropicalanvils_radiativeheating_jclim2020,gasparini_cloudanvil_diurnalcycle_jclim2022} and fuels the convective mixing that feeds subtropical marine low-level clouds \citep{stevens_moistconvection_areps2005,wood_stratocumulusclouds_mwr2012}. +Radiative cooling from low-level cloud tops drives tropical shallow overturning circulations \citep{naumann_shallowcirculation_radiation_jas2019} and modulates the intensity of extratropical cyclones \citep{grise_cloudheating_stormtracks_grl2019,voigt_cyclones_lowhighclouds_grl2023}. Radiative warming from tropical upper-tropospheric clouds narrows the intertropical convergence zone and decreases tropical-mean rainfall \citep{albern_cookie_hadleycell_grl2018,harrop_itczwidth_cookie_jclim2016}. Cloud-radiative heating has also been shown to alter the internal variability of the climate system to varying degrees, including the Madden-Julian-Oscillation \citep{benedict_cloudradiation_tropicaldisturbances_grl2020}, the El-Nino Southern Oscillation \citep{raedel_cloudheating_elnino_natgeo2016} and the North Atlantic Oscillation \citep{li_annularmode_clouds_grl2014,papavasileiou_nao_clouds_qjrms2020}, +and to be essential to the response of the planetary-scale circulation of the atmosphere to global warming \citep{voigt_clouds_atmpathway_jclim2019,ceppi_clouds_circulation_cmip5_jclim2017,albern_clouds_jet_james2019}. +Cloud-radiation interactions can further change the reservoir of available potential energy that is tapped by atmospheric motions \citep{stuhlmann_cloudradheating_ape_jas1988,romanski_diabaticheating_ape_jclim2013,kato_cloudradheating_ape_jgr2018}. +Given the range of scales on which cloud-radiative heating affects the atmospheric circulation, this list is clearly non-exhaustive. For a comprehensive review of the cloud-radiative heating impact on climate time scales we refer to \cite{voigt_clouds_radiation_circulation_wirescc2021}; a discussion of the impact of cloud-radiative heating on extratropical weather systems can be found in \cite{keshtgar_cyclone_cloud_radiation_wcd2023}. + + +A major motivation of our study is to provide a comprehensive assessment of atmospheric cloud radiative heating across global climate models. To this end, we compute and analyse cloud-radiative heating from model simulations of phase 6 of the Climate Model Intercomparison Project \citep{eyring_cmip6_gmd2016}. We are able to compute vertically-resolved cloud-radiative heating for 20 models. Previous model assessments were limited to a handful of models at most. Specifically, five models were compared in \cite{cesana_cloudradiativeheating_jclim2019} and three models in \cite{voigt_clouds_atmpathway_jclim2019}; other studies only used one model or were restricted to specific regions \citep{johansson_cloudradheating_ecearth_gmd2021,li_cookie_atmospherecirculation_jclim2015}. While \cite{luo_acre_cloudclasses_acp2023} used the CMIP6 model ensemble, they studied only the vertically-integrated heating derived from the difference in top-of-atmosphere and surface cloud-radiative fluxes. We further compare models to satellite-based estimates of cloud-radiative heating from CERES-CALIPSO-CloudSat-MODIS \citep{kato_cccm_jgr2011,ham_cccm_jamc2022} and CloudSat/CALIPSO \citep{lecuyer_cloudradheating_cloudsat_jgr2008,henderson_heatingrates_cloudsatcalipso_jamc2013}. + +Although previous assessments of cloud-radiative heating in models remained largely anecdotal, these studies collectively provided evidence that cloud-radiative heating varies substantially between models and that poorly-constrained parameterizations such as cloud microphysics and aerosol-cloud-interactions strongly affect cloud-radiative heating. For example, using the ICON model with km-scale resolution over the Asian monsoon region, \cite{sullivan_cloudice_radheating_commee2021} found that cloud-radiative heating in the tropical upper-troposphere changes by more than a factor of four when the model's 1-moment cloud microphysics scheme is replaced by a 2-moment scheme and microphysical information of the cloud particle effective radius is considered in the radiation scheme. Similarly, using the ICON model over the North Atlantic region, \cite{sullivan_nawdexhackathon_gmd2023} reported strong sensitivity of cloud-radiative heating to cloud microphysics and the treatment of convection, and highlighted the influence of partitioning frozen hydrometeors into cloud ice, which is suspended in the atmosphere and taken into account in radiation calculations, and precipitating snow and ice, whose effects on radiation are typically neglected in models \citep{waliser_snow_radiation_grl2011,li_clouds_radiation_cmip5_cmip6_jgr2022}. Differences in cloud-radiative heating are also large between atmospheric reanalyses \citep{zhang_diabaticheating_reanalyses_clidyn2017,wright_cloudradheating_highclouds_reanalysis_acp2020,sparc_srip_finalreport_dlr2022}, indicating that much of the challenge in correctly representing cloud-radiation-interactions in models does not stem from the large-scale circulation but small-scale cloud and radiative processes. + +Studies with global climate models and atmospheric reanalyses have in particular highlighted shortcomings in upper-tropospheric cloud-radiative heating due to ice clouds \citep{voigt_clouds_atmpathway_jclim2019,voigt_clouds_radiation_circulation_wirescc2021,cesana_cloudradiativeheating_jclim2019,johansson_cloudradheating_ecearth_gmd2021,wright_cloudradheating_highclouds_reanalysis_acp2020,sparc_srip_finalreport_dlr2022}. Ice clouds and their radiative heating are a key challenge for current models, both at coarse resolutions of 100\,km and fine km-scale resolutions \citep{gasparini_cirrus_opinionpiece_acpd2023}. The challenging nature of ice clouds is unsurprising given the intricacies of their microphysical and radiative properties \citep{kraemer_microphysics_cirrus_part1_acp2016,zhang_radiation_cirrus_ar1999}, yet understanding how they respond to warming is believed to be crucial to reduce uncertainty in climate sensitivity \citep{sherwood_ecs_review_revgeo2020,sokol_anvilcloud_thinning_natgeo2024} and to anticipate the response of the large-scale atmospheric circulation to warming \citep{voigt_clouds_atmpathway_jclim2019,albern_clouds_jet_james2019,li_cloudrise_jetshift_jclim2019}. + +While ice clouds are inherently complex, one important aspect of their response to warming is simple: ice clouds, or upper-tropospheric clouds more generally, tend to remain at roughly the same temperature as the climate warms. This behavior is an expression of the ``fixed-anvil temperature hypothesis (FAT)'' \citep{hartmann_fat_grl2002} that results from a well-understood thermodynamic control of convective outflow due to the rapid drop of clear-sky radiative cooling and water vapor near the tropopause. While originally developed for the tropics, FAT equally applies in the midlatitudes \citep{thompson_globalfat_pnas2017}. FAT establishes an important expectation regarding the response of upper-tropospheric clouds to warming: because their temperature is constrained, ice clouds, and with them their radiative heating, will shift upward as the surface warms. Modeling and observational analyses unequivocally support an upward shift of upper-tropospheric clouds in response to surface warming \citep{kuang_fat_cloudresolvingmodels_jclim2007,norris_cloudchange_satobservations_nature2016,pochedley_clouds_rh_rise_constraint_grl2019,richardson_cloudrise_satobs_grl2022,zelinka_highclouds_sensitivity_observations_jgr2011,zelinka_cloudfeedback_decomposition_grl2016}. +The upward shift suggests that the response of upper-tropospheric cloud-radiative heating to warming can be ``predicted'' by an upward shift of the present-day cloud radiative heating. This idea is supported by the findings +of \cite{singh_upwardshift_jclim2012} and \cite{voigt_clouds_atmpathway_jclim2019}; here we show it also holds across the CMIP6 model ensemble. This establishes a strong constraint on the global warming response of ice clouds, and hence their radiative impact on atmospheric circulation and regional climate change. + +Throughout the paper, our focus is on the representation of cloud-radiative heating within the atmosphere in global climate models for two reasons. First, by contributing to the diabatic heating of the atmosphere, cloud-radiative heating is relevant to the atmospheric circulation. And second, a systematic study of cloud-radiative heating in models is lacking, in contrast to cloud mass and fraction \citep{li_cloudice_cmip_jgr2012,lauer_clouds_cmip5_cmip6_satellite_jclim2023}. +\DIFaddbegin \DIFadd{Because cloud-radiative heating is defined as the difference between all-sky and clear-sky radiative heating, it depends not only on the cloud field itself but also the clear-sky background state of the atmosphere, an effect known as ``cloud-masking'' \mbox{%DIFAUXCMD +\citep{soden_cloudmasking_jclim2004,huang_radheating_radkernels_essoa2024}}\hspace{0pt}%DIFAUXCMD +. Differences in cloud-radiative heating between models, between models and observations, or between different climate states may thus be influenced by non-cloud fields such as temperature and water vapor. These clear-sky effects could be quantified by explicit radiative transfer calculations or radiative kernel methods, but given the paucity of studies on atmospheric cloud-radiative heating we leave such refinements to future work. +} + + +\DIFaddend Our manuscript is organized as follows. Sect.\,\ref{sec:methods_data} describes the calculation of cloud-radiative heating in CMIP6 models and observational estimates of cloud-radiative heating in today's climate. +Sect.\,\ref{sec:results_amip} studies cloud-radiative heating in simulations of present-day climate. Sects.\,\ref{sec:results_amipp4K} and \ref{sec:results_amipfuture4K} address how cloud-radiative heating responds to uniform and non-uniform surface warming. Sect.\,\ref{sec:prediction} asks to what extent the response can be predicted from the present-day climate. The paper concludes in Sect.\,\ref{sec:conclusions}, where we articulate three important consequences of our work. + + + +\section{CMIP6 simulations and satellite-based estimates of CRH} +\label{sec:methods_data} + +\subsection{CMIP6 simulations} + +We use model output from the amip, amip-p4K and amip-future4K simulations of CMIP6 \citep{eyring_cmip6_gmd2016,webb_cfmip4cmip6_gmd2017}. In the amip simulation, sea-surface temperatures, sea ice, well-mixed greenhouse gases and aerosols are prescribed to observed values from 1979 to 2014. This enables a clean comparison between models as well as between models and observations. In the amip-p4K simulation, sea-surface temperatures are uniformly increased by 4\,K. In the amip-future4K simulation, sea-surface temperatures are also increased by 4\,K in the global mean, but the increase varies spatially according to a pattern derived from coupled climate models. The amip-p4K and amip-future4K simulations allow us to study the response of cloud-radiative heating to surface warming and to assess to what extent the response depends on the pattern of surface warming. + +We use amip simulations from 20 CMIP6 models for which we were able to retrieve the all-sky and clear-sky radiative fluxes or heating rates from the CMIP6 ESGF archive that are necessary to calculate cloud-radiative heating, as described in the following subsection. The models are listed in Tab.\,\ref{tab:models}. Seven of the 20 models moreover provide the necessary output for the amip-p4K and amip-future4K simulations. We further retrieve atmospheric temperature, based on which we calculate the thermal tropopause as defined by the World Meteorological Organization \citep{wmo_meteorology_wmobull1957} using the PyTropD python package of \cite{adam_tropd_gmd2018}. All data retrieval and analysis scripts are included in the accompanying data. + +\subsection{Calculation of cloud-radiative heating from CMIP6 model output} +\label{sec:methods_data:crhcalculation} + + +\begin{center} +\begin{table} +\caption{CMIP6 models for which cloud-radiative heating is calculated. The approach used to calculate cloud-radiative heating depends on the data availability and is indicated by the checkmarks. See the manuscript text for an explanation of the three approaches.} +\begin{tabular}{llccc} +\hline\hline +Simulation & Model & Radiative fluxes & Temperature tendencies & Zonal-mean temperature \\ + & & (approach 1) & (approach 2) & tendencies (approach 3)\\ +\hline +amip & BCC-CSM2-MR & \checkmark & & \\ + & CESM2 & & & \checkmark \\ + & CESM2-FV2 & & & \checkmark \\ + & CESM2-WACCM & & & \checkmark \\ + & CESM2-WACCM-FV2 & & & \checkmark \\ + & CNRM-CM6-1 & \checkmark & \checkmark &\\ + & CNRM-ESM2-1 & \checkmark & \checkmark & \\ + & EC-Earth3 & & & \checkmark \\ + & GFDL-AM4 & & \checkmark & \\ + & GFDL-CM4 & & \checkmark & \\ + & GFDL-ESM4 & & & \checkmark \\ + & HadGEM3-GC31-LL & \checkmark & \checkmark & \\ + & HadGEM3-GC31-MM & \checkmark & & \\ + & INM-CM4-8 & \checkmark & & \\ + & INM-CM5-0 & \checkmark & &\\ + & IPSL-CM6A-LR & \checkmark & & \\ + & MIROC-ES2L & \checkmark & & \\ + & MIROC6 & \checkmark & & \\ + & MRI-ESM2-0 & \checkmark & &\\ + & UKESM1-0-LL & \checkmark & \checkmark & \\ +\hline +amip-p4K & BCC-CSM2-MR & \checkmark & & \\ + & CNRM-CM6-1 & \checkmark & &\\ + & GFDL-CM4 & & \checkmark & \\ + & HadGEM3-GC31-LL & \checkmark & \checkmark & \\ + & IPSL-CM6A-LR & \checkmark & & \\ + & MIROC6 & \checkmark & & \\ + & MRI-ESM2-0 & \checkmark & &\\ +\hline +amip-future4K & BCC-CSM2-MR & \checkmark & \\ + & CNRM-CM6-1 & \checkmark & \\ + & GFDL-CM4 & & & \checkmark \\ + & HadGEM3-GC31-LL & \checkmark & \checkmark &\\ + & IPSL-CM6A-LR & \checkmark & \\ + & MIROC6 & \checkmark & & \\ + & MRI-ESM2-0 & \checkmark & & \\ +\hline\hline +\end{tabular} +\label{tab:models} +\end{table} +\end{center} + +According to Eq.\,\ref{eq:crh_tntr_intro} cloud-radiative heating is given as the difference in all-sky and clear-sky radiative heating rates within the atmosphere. Since radiative heating rates are given by the radiative flux divergence divided by the mass of air, cloud-radiative heating can be calculated either directly from heating rates or indirectly from radiative fluxes: +\begin{eqnarray} + CRH & = & \frac{\partial T}{\partial t}\bigg\vert^\textrm{all-sky}_\textrm{radiation} - \frac{\partial T}{\partial t}\bigg\vert^\textrm{clear-sky}_\textrm{radiation} \label{eq:crh_tntr}\\ + & = & - \frac{g}{c_p}\cdot\frac{\partial}{\partial p}\left(F^\textrm{all-sky}-F^\textrm{clear-sky}\right) \label{eq:crh_radplev}\\ + & = & \frac{1}{\rho\,c_p}\cdot\frac{\partial}{\partial z}\left(F^\textrm{all-sky}-F^\textrm{clear-sky}\right). \label{eq:crh_radzlev} +\end{eqnarray} +Here, $\rho$ is the air density, $c_p$ is the heat capacity of air at constant pressure, $g$ is gravitational acceleration, and $F$ denotes the radiative fluxes in all-sky and clear-sky conditions, respectively (fluxes are defined as positive downward). We follow three approaches to calculate cloud-radiative heating, depending on the available output: +\begin{enumerate} + \item If the full set of all-sky and clear-sky radiative fluxes is available from the CFmon table, we first calculate individual heating rates from the radiative flux divergence following Eqs.\,\ref{eq:crh_radplev} and \ref{eq:crh_radzlev}, respectively, and then calculate cloud-radiative heating from the heating rates using Eq.\,\ref{eq:crh_tntr}. Eq.\,\ref{eq:crh_radplev} is used for models with pressure-based vertical coordinates, Eq.\,\ref{eq:crh_radzlev} for models with height-based vertical coordinates. + \item If all-sky and clear-sky radiative heating rates are available from the CFmon, AERmon or Emon tables, we calculate cloud-radiative heating directly from the difference in heating rates using Eq.\,\ref{eq:crh_tntr}. + \item If the zonally-averaged radiative heating rates are provided as part of the EmonZ table, we use these to calculate cloud-radiative heating from Eq.\,\ref{eq:crh_tntr}. +\end{enumerate} +For approaches 1 and 2, cloud-radiative heating is calculated on model levels and subsequently interpolated vertically to a set of 100 common pressure levels from 1000 to 0\,\unit{hPa} with a level spacing of 10\,hPa. For approach 1 it is essential to derive heating rates from radiative fluxes on model levels; computing heating rates from fluxes interpolated to pressure levels can result in substantial errors. This is illustrated in the additional figure A1. Cloud-radiative heating from approach 3 is interpolated from the EmonZ pressure levels to the common pressure levels. All calculations use monthly mean model output. The heat capacity of dry air, $c_p=1005\,\unit{J}\unit{kg^{-1}}\unit{K^{-1}}$, is used; the impact of humidity on $c_p$ is well below a few percent \citep{rogers_cloudphysics_elsevier1989} and can be neglected for the purpose of our study. The additional figures A2, A3 and A4 illustrate cloud-radiative heating calculated from the three approaches, showing that approaches 1 and 2 give indistinguishable results. For the analysis, we preferably use cloud-radiative heating calculated by approach 1 because it is applicable to the majority of the models. If approach 1 is not possible, we use approach 2, if possible, or approach 3. + +Two notes are in order for the models HadGEM3-GC31-LL, HadGEM3-GC31-MM and UKESM1-0-LL, which differ from the rest of the models by using a vertical grid based on height. The first note concerns the calculation of cloud-radiative heating from the flux divergence using Eq.\,\ref{eq:crh_radzlev}. The calculation requires the factor $\rho \cdot c_p$ that depends on time, latitude, longitude and model level. We obtain this factor from the ratio of the all-sky radiative heating rate and the all-sky radiative flux as $\rho \cdot c_p = \partial_z F^\textrm{all-sky} / \partial_t T \vert^\textrm{all-sky}_\textrm{radiation}$. The factor is then used to convert radiative fluxes to heating rates for all components of radiation, i.e., shortwave and longwave as well as clear-sky and all-sky fluxes. The second note concerns the vertical interpolation. The heating rates for the three model are interpolated to a common height grid extending from 0 to 20\,km with a level spacing of 200\,m. Where needed, e.g., for plots across all models, we convert from altitude levels to pressure levels using the geopotential height variable \verb+zg+ from the Amon table. + + +\subsection{Satellite-based estimates of cloud-radiative heating} + +We compare the amip simulations to two estimates of cloud-radiative heating based on active satellite measurements. \cite{kato_cloudradheating_ape_jgr2018} demonstrated the need for active measurements of clouds to derive radiative heating rates within the atmosphere. The first estimate is from the RelD1 product of CERES-CALIPSO-CloudSat-MODIS \citep[CCCM;][]{kato_cccm_reld1_nasa2021}, the second estimate from the 2B-FLXHR-LIDAR product of CloudSat/CALIPSO \citep{lecuyer_cloudradheating_cloudsat_jgr2008,henderson_heatingrates_cloudsatcalipso_jamc2013}. Both products combine the satellite measurements with radiative transfer calculations to derive all-sky and clear-sky radiative heating rates, from which cloud-radiative heating can be calculated. For the CCCM estimate, we follow the procedure described in \cite{ham_cccm_cloudradheating_jgr2017} and derive heating rates on height levels from daytime radiative fluxes following Eq.\,\ref{eq:crh_radzlev}, with shortwave heating rates scaled by monthly gridded solar incoming flux from the CERES SYN product. For the 2B-FLXHR-LIDAR estimate, we use the release R05 and derive cloud-radiative heating following the approach described in \cite{papavasileiou_nao_clouds_qjrms2020}: heating rates are derived for each CloudSat/CALIPSO granule using Eq.\,\ref{eq:crh_radplev} and ancillary information from the ECMWF-AUX, and then binned into 2.5\,deg\,lon\,x\,2.5\,deg\,lat averages for time periods of 5 days. Similar to the CCCM estimate, shortwave heating rates are scaled by daily-mean radiative insolation obtained from the CLIMLAB python package of \cite{rose_climlab_joss2018}. We average the pentad values in time to obtain the climatological cloud-radiative heating. We also derive cloud-radiative heating for the earlier R04 release of 2B-FLXHR-LIDAR analyzed by \cite{papavasileiou_nao_clouds_qjrms2020}, but if not noted otherwise we use the R05 release. The comparison between the estimate from CCCM and the two releases of 2B-FLXHR-LIDAR allows us to illustrate current uncertainties in observing cloud-radiative heating. + +For both CCCM and 2B-FLXHR-LIDAR, we analyze the time period from 2007-2010 and convert from altitude to pressure levels by means of the MetPy implementation \citep{may_metpy_bam2022} of the {U.\,S.} standard atmosphere \citep{noaa_standardatmosphere_usgov1976}. + + +\subsection{Cloud fraction} + +To allow the reader to connect the spatial pattern of cloud-radiative heating to cloud fraction, we include the latter in some of our figures. For the models, cloud fraction is taken from the variable \verb+cl+ of the Amon table and interpolated from model levels to pressure levels in the same manner as radiative heating rates. For observations, we use the CloudSat/CALIPSO based community product of \cite{bertrand_cloudcover_cloudsatcalipso_essd2024} for years 2007-2010. It should be noted, however, that cloud-radiative heating also depends on cloud liquid and ice content and the radiative treatment of clouds \citep[e.g.,][]{keshtgar_cloudradheating_cyclone_acp2024} \DIFaddbegin \DIFadd{and may be affected by cloud masking (cf. Sect.\,\ref{sec:introduction})}\DIFaddend . Differences in cloud-radiative heating between models and between models and observations are thus not explained by cloud fraction alone. + + +\section{Cloud-radiative heating in the present-day climate} +\label{sec:results_amip} + + +We begin with the zonal-mean time-mean cloud-radiative heating in the amip simulations shown in Fig.\,\ref{fig:crh_zonaltimemean_xypanelplot_amip}. The models agree on the overall pattern of cloud-radiative heating: clouds radiatively heat the upper troposphere at low latitudes and cool the lower troposphere, consistent with the meridional distribution of high-level and low-level clouds shown in Fig.\,\DIFdelbegin \DIFdel{\ref{fig:crh_zonaltimemean_xypanelplot_amip}}\DIFdelend \DIFaddbegin \DIFadd{\ref{fig:cl_zonaltimemean_xypanelplot_amip}}\DIFaddend . The two figures illustrate the well-known pattern of warming in the lower part of the cloud and cooling in its upper part that results from the absorption and emission of longwave radiation \cite[cf. Fig.\,3 of][]{slingo_cloudlwforcing_part1_qjrms1988}. This dipole pattern is for example evident for low-level clouds in the subtropics and extratropics and high-level clouds in the extratropical storm track regions. For tropical high-level clouds, the upper part of the cloud is warming instead of cooling because shortwave heating is larger and the low optical thickness that is typical for many high-level tropical clouds reduces their emission of longwave radiation. + +Beyond this basic agreement, however, the models show substantial differences in cloud-radiative heating at all latitudes. In the tropics, the maximum radiative heating in the upper troposphere ranges from 0.3\,K\,day$^\text{-1}$ in the family of CESM2 models to 0.9\,K\,day$^\text{-1}$ in the family of GFDL models, and the vertical distribution of cloud-radiative heating ranges from a clear maximum in the upper troposphere, e.g., in the GFDL and MIROC models, to a rather uniform heating within the free troposphere, e.g., in the CNRM and INM models. In the extratropics, between 30 and 60\,deg\,latitude, the maximum cloud-radiative cooling in the lower troposphere varies by a factor of four between -0.4\,K\,day$^\text{-1}$ in EC-Earth3 to -1.6\,K\,day$^\text{-1}$ in IPSL-CM6A-LR, and while some models show a dipole of cloud-radiative cooling near the tropopause and heating below (e.g., BCC-CSM2-MR and the two MIROC models), cloud-radiative heating is negative or close to zero throughout the extratropical free troposphere in other models (e.g., IPSL-CM6A-LR as well as the CESM and INM models). + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_zonaltimemean_xypanelplot_amip-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip simulations of 20 CMIP6 models. The gray lines mark the 0 and -38\,deg\,C isotherms to loosely distinguish regions of liquid, mixed-phase and ice clouds. The green line marks the thermal tropopause. Cloud-radiative heating in the CESM2 models is not shown below 500\,hPa because their EmonZ model output is affected by surface topography (cf. additional figure A2). + \label{fig:crh_zonaltimemean_xypanelplot_amip}} +\end{center} +\end{figure} + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/cl_zonaltimemean_xypanelplot_amip-crop.pdf} + \caption{Zonal-mean time-mean cloud fraction in amip simulations. The gray lines mark the 0 and -38\,deg\,C isotherms to loosely distinguish regions of liquid, mixed-phase and ice clouds. The white line marks the thermal tropopause. Note that for some models cloud fraction is not available from the ESGF archive; for CESM2-FV2 cloud fraction is restricted to above 500\,hPa. + \DIFdelbeginFL %DIFDELCMD < \label{fig:crh_zonaltimemean_xypanelplot_amip}%%% +\DIFdelendFL \DIFaddbeginFL \label{fig:cl_zonaltimemean_xypanelplot_amip}\DIFaddendFL } +\end{center} +\end{figure} + + +To quantify the model differences in cloud-radiative heating, the top row of Fig.\,\ref{fig:crh_zonaltimemean_amip_median_std_obs} shows the model median and the standard deviation across models. Consistent with the findings above and with findings from the five GASS-YOTC models \citep{jiang_mjo_gassyotc_jgr2015,klingaman_mjo_gassyotc_jgr2015} compared in \cite{cesana_cloudradiativeheating_jclim2019}, the figure highlights two regions. First, model differences are large in the lower troposphere, in particular in the Southern Hemisphere extratropics, where mixed-phase clouds dominate and the standard deviation across models is almost as large as the model median. Second, model differences are pronounced in the upper troposphere around the -38\,deg\,C isotherm, where ice clouds prevail as a consequence of convective motions and large-scale ascent. In comparison, model differences are small in the mid troposphere. + +Model differences in cloud-radiative heating are not simply a result of clear-sky differences but truly reflect differences in the radiative interactions of clouds and translate to model differences in all-sky radiative heating. This is illustrated in Fig.\,\ref{fig:radheating_zonaltimemean_amip_variance}, which shows the variance in all-sky, clear-sky and cloud-radiative heating across all amip models. Mathematically, the variance in all-sky heating, $\sigma^2_\textrm{all-sky}$, can be decomposed into the variances in cloud and clear-sky heating and their covariance, +\begin{equation} + \sigma^2_\textrm{all-sky} = \sigma^2_\textrm{cloud} + \sigma^2_\textrm{clear-sky} + 2\cdot \textrm{cov}(\textrm{cloud, clear-sky}). +\end{equation} +Model differences in all-sky radiative heating overall are dominated by cloud-radiative heating. Moreover, although differences in cloud-radiative heating are in some regions co-related to clear-sky differences (e.g., in the tropical upper troposphere), they do not appear to be driven primarily by the latter. \DIFaddbegin \DIFadd{Future work that takes into account cloud-masking effects would be helpful to quantify the sources of model differences in all-sky and cloud-radiative heating, for example by means of radiative kernels \mbox{%DIFAUXCMD +\citep{huang_radkernels_era5_essd2023,huang_radheating_radkernels_essoa2024}}\hspace{0pt}%DIFAUXCMD +. +}\DIFaddend + + +To put the model simulations into perspective, Fig.\,\ref{fig:crh_zonaltimemean_amip_median_std_obs} also shows the satellite-based estimates of cloud-radiative heating in panels c-e, together with the observed cloud fraction in panel f. A somewhat sobering aspect is that the difference between satellite-based estimates of cloud-radiative heating from 2B-FLXHR-LIDAR and CCCM is about as large as the standard deviation across models. \cite{ham_cccm_cloudradheating_jgr2017} showed that assumptions regarding cloud detection thresholds, cloud merging and cloud optical properties substantially affect cloud-radiative heating rates and explain the differences between 2B-FLXHR-LIDAR and CCCM. For example, in the tropical upper troposphere, cloud-radiative heating is more positive in CCCM because the larger ice cloud extinction coefficient and particle size leads to stronger absorption in both the shortwave and longwave domains. The differences between R05 and R04 of 2B-FLXHR-LIDAR result from improvements in cloud microphysics, surface albedo and cloud detection \citep{cloudsat-2bflxhrlidar-r05_nasa2023}. Overall, the differences in the satellite-based estimates illustrate the challenges in establishing an observational baseline for cloud-radiative heating. + + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/crh_zonaltimemean_amip_median_std_obs-crop.pdf} + \caption{Agreement and disagreement in cloud-radiative heating in models and observations. The upper row show the model median (panel a) of zonal-mean time-mean cloud-radiative heating and the standard deviation (panel b) across the amip simulations of the 20 CMIP6 models. The middle and lower rows shows the satellite-based estimates of cloud-radiative heating from the 2B-FLXHR-LR R05 and R04 (panels c and d) and CCCM (panel e). Observed cloud fraction is shown in panel f. In all panels, the gray lines mark the model median of the 0 and -38\,deg\,C isotherms and the green line marks the model median of the thermal tropopause (white line in panel f). + \label{fig:crh_zonaltimemean_amip_median_std_obs}} +\end{center} +\end{figure} + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/radheating_zonaltimemean_amip_variance-crop.pdf} + \caption{Variance across amip model simulations for zonal-mean time-mean all-sky, cloud and clear-sky radiative heating in panels a-c. Panel d shows the covariance between the cloud and clear-sky radiative heating across models, multiplied by a factor of two. By design, panel a is the sum of panels b-d. + \label{fig:radheating_zonaltimemean_amip_variance}} +\end{center} +\end{figure} + + +Fig.\,\ref{fig:crh_5xdomaintimemean_amip} characterizes the cloud-radiative heating by means of vertical profiles over five domains that separate tropical ascending motion (15\,deg\,S - 15\,deg\,N) from subtropical descending motion (15\,deg\,N/S - 35\,deg\,N/S) and extratropical regions dominated by midlatitude cyclones (35\,deg\,N/S - 70\,deg\,N/S). The model simulations are shown in gray, the satellite-based estimates in blue. Again, the lower and upper troposphere emerge as regions with large differences between models as well as between the satellite-based estimates, while the differences are smaller in the mid-troposphere. In the Southern hemisphere extratropics and in the subtropics of both hemispheres, low-level cloud-radiative cooling in most of the models peaks at too low altitudes compared to the satellite-based estimates, consistent with \cite{cesana_cloudradiativeheating_jclim2019}. High-level cloud-radiative heating in the tropical upper troposphere is lower in the models compared to the CCCM estimate, in contrast to \cite{cesana_cloudradiativeheating_jclim2019}. + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_5xdomaintimemean_amip-crop.pdf} + \caption{Time-mean cloud-radiative heating averaged over the domains of the extratropical storm track (70-35\,deg\,lat), subtropical descent (35-15\,deg\,lat) and tropical ascent (equatorward of 15\,deg\,lat). The black line shows the model median. The blue lines show the cloud-radiative heating estimated by 2B-FLXHR-LIDAR R05 (solid) and CCCM (dashed). + \label{fig:crh_5xdomaintimemean_amip}} +\end{center} +\end{figure} + + + +\section{Response to uniform ocean surface warming} +\label{sec:results_amipp4K} + + +We now study the response of cloud-radiative heating to climate change. To this end, we analyze the amip-p4K simulations in which the ocean surface is warmed uniformly by 4\,K. We will show that the response of cloud-radiative heating to surface warming differs markedly between models, and that the model differences in the upper troposphere are nearly entirely caused by model differences in the present-day climate. The latter leads to the possibility to predict the response of upper-tropospheric cloud-radiative heating to surface warming based on the present-day climate. + +Fig.\,\ref{fig:crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip} shows the response of zonal-mean time-mean cloud radiative heating in the amip-p4K simulation relative to the amip simulations. Note that only seven models provide the output to calculate cloud-radiative heating in the amip-p4K simulations. The response shows a very complicated pattern, and it is difficult to identify aspects that robustly emerge in models. This is in particular the case in the lower troposphere, where the response of cloud-radiative heating is tied to model-dependent changes in low-level warm clouds in the tropics and subtropics and low-level mixed-phase clouds in the extratropics. + +In the upper troposphere, however, cloud-radiative heating responds to surface warming in a manner that is more robust across models. Despite large differences between models, all models simulate an arc-like pattern of anomalous positive cloud-radiative heating that extends from the tropics into the extratropics and is roughly aligned with the -38\,deg\,C isotherm. For example, the arc is very well developed in the BCC-CSM2-MR model. Models differ in terms of the extent of the arc towards the poles as well as its altitude and position relative to the -38\,deg\,C isotherm, yet they agree that the upper-tropospheric response of cloud-radiative heating includes the arc-like pattern. In fact, this pattern was reported previously by \cite{voigt_clouds_jetshifts_jclim2016,voigt_clouds_atmpathway_jclim2019} and \cite{voigt_clouds_radiation_circulation_wirescc2021}, who attributed it to the upward extension of the tropopause and the associated upward shift of clouds. + +We now demonstrate that the upper-tropospheric response of cloud-radiative heating response, i.e., above 500\,hPa, is very well predicted from an upward shift of cloud-radiative heating simulated in the models for the present-day climate. The prediction is anchored in the fact that upper-tropospheric clouds are strongly tied to atmospheric temperature (see also further below) via the fixed-anvil temperature hypothesis \citep{hartmann_fat_grl2002,thompson_globalfat_pnas2017}. The prediction follows \cite{singh_upwardshift_jclim2012}, who developed a framework to describe the upward extension of the tropopause with warming by rescaling the pressure coordinate. Eq.\,13g of \cite{singh_upwardshift_jclim2012} in particular predicts the upward shift of atmospheric radiative heating by shifting the pressure levels $p$ to new pressure levels $p^\prime = p/\beta$. $\beta$ is larger than 1, which implies $p^\prime <p$ and thus an upward shift. With this, the response of cloud-radiative heating can be predicted as +\begin{linenomath*} +\begin{equation} + \label{eq:dcrh_upwardshift} + dCRH(p, \varphi) = CRH(p, \varphi) - CRH(\beta p, \varphi). +\end{equation} +\end{linenomath*} +$\beta$ depends on the magnitude of surface warming. To derive its value, we compute the warming in the amip-p4K simulations at 800\,hPa averaged between 70\,deg\,N/S, yielding a model mean of 4.8\,K. Using a rounded value of 5\,K and Eq.\,15 of \cite{singh_upwardshift_jclim2012}, we obtain $\beta=1.2$. We use the same value for all models to highlight that the knowledge of the surface warming is sufficient to predict the upward shift of cloud-radiative heating. + + +Fig.\,\ref{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip} shows the cloud-radiative heating response averaged over the five extratropical, subtropical and tropical domains of Fig.\,\ref{fig:crh_5xdomaintimemean_amip}. The upper row includes all seven models and illustrates the large model differences in the response. The rows below show the individual models as well as the predicted response as blue lines. For almost all models and domains, the prediction captures the actual response extremely well. This is not only evident from the visual inspection of Fig.\,\ref{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip} but also from the correlation coefficients between the vertical profiles of the actual and the predicted responses. The correlation coefficients are calculated as the Pearson product-moment correlation coefficients and are typically larger than 0.9. We note that while the prediction has been successfully applied previously in \cite{voigt_clouds_atmpathway_jclim2019} for two of \DIFdelbegin \DIFdel{the }\DIFdelend \DIFaddbegin \DIFadd{their }\DIFaddend three considered models, here we show that indeed it holds broadly across global climate models. + + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf} + \caption{Response of zonal-mean time-mean cloud-radiative heating to a uniform 4\,K warming of the ocean surface in amip-p4K simulations with 7 CMIP6 models. The gray lines mark the 0 and -38\,deg\,C isotherms and the green lines the thermal tropopause for the amip simulation. + \label{fig:crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip}} +\end{center} +\end{figure} + + + +\begin{figure} +\begin{center} + \includegraphics[height=0.9\textheight]{../../plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip-crop.pdf} + \caption{Response of cloud-radiative heating to surface warming averaged over the domains of the extratropical storm track (70-35\,deg\,lat), subtropical descent (35-15\,deg\,lat) and tropical ascent (equatorward of 15\,deg\,lat). The blue line shows the response predicted by the upward shift of cloud-radiative heating in the present-day climate. The numbers give the correlation coefficient between the actual and the predicted response between 100 and 500\,hPa. + \label{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip}} +\end{center} +\end{figure} + + +A drawback of the domain averages on pressure levels is that they tend to obscure the dependence of clouds on atmospheric temperature that underlies the successful prediction in Fig.\,\ref{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip}. Another drawback is that domain averages on pressure levels are affected by a cancellation between positive and negative values of cloud-radiative heating in the extratropics, where meridional temperature gradients are strong and isotherms and isobars are not aligned with each other (see, e.g., Figs.\,\ref{fig:crh_zonaltimemean_xypanelplot_amip} and \ref{fig:crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip}). +To address these drawbacks, we also calculate cloud-radiative heating as a function of atmospheric temperature, i.e., we use temperature instead of pressure as the vertical coordinate. When remapping from pressure levels to temperature levels, we use the zonal-mean time-mean temperature and only consider levels below the tropopause since the increase in temperature above the tropopause makes the mapping non-unique. For reference, the zonal-mean time-mean cloud-radiative heating in the amip simulations sampled as a function of temperature is shown in additional figure A5. Here, we focus on the response of cloud-radiative heating to surface warming in the amip-p4K simulations. + + +Fig.\,\ref{fig:crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip} shows that apart from the region of the boundary layer, the cloud-radiative heating is remarkably similar between the amip and amip-p4K simulations when expressed as a function of temperature. In 5 of the 7 models, the difference in cloud-radiative heating between the two climates is within $\pm$\,0.1\,K/day and hence close to zero. In IPSL-CM6A-LR and CRNM-CM6-1, cloud-radiative heating increases by roughly 30\% in the tropical mid and upper troposphere, yet the increase is closely aligned with the cloud-radiative heating in the present-day climate. This suggests that it results largely from an increase in cloud ice content or cloud fraction. Although future work should address why cloud-radiative heating increases in these two models but not in the other models, our analysis clearly establishes a helpful null hypothesis: cloud-radiative heating does not change with warming apart from an upward shift to lower pressures so as to stay at the same air temperature. +%We note that that within and near the boundary layer, changes in cloud-radiative heating are large for the simple reason that the boundary layer warms by about 4\,K everywhere, which implies a shift of boundary layer clouds to higher temperatures and hence strong changes in cloud-radiative heating. + +Expressing cloud-radiative heating as a function of temperature thus shows that the upward shift is an excellent prediction of the response of upper-tropospheric cloud-radiative heating to surface warming because clouds and their radiative heating are invariant to climate change when viewed not in terms of pressure but air temperature. This view is in line with the work of \cite{jeevanjee_precipitation_warming_pnas2018}, who combined theory, idealized modeling and global climate model analysis to show that sufficiently away from the surface, all-sky and clear-sky radiative fluxes are independent of climate when measured as a function of temperature. Here, we have extended the view to the radiative heating rates (instead of fluxes) and to clouds (instead of the all-sky or clear-sky atmosphere). + + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf} + \caption{Response of cloud-radiative heating to a uniform 4\,K ocean surface warming as a function of air temperature. The sampling is limited to the troposphere so that the upper limit of the plotted data marks the tropopause temperature and the lower limit marks the surface temperature. The black lines show the cloud-radiative heating in the amip simulations with a contour spacing of 0.1\,K/day. For the latter, only levels with pressures smaller than 750\,hPa are taken into account to avoid line cluttering near the surface. + \label{fig:crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip}} +\end{center} +\end{figure} + + +In summary, our comparison of the amip-p4K and amip simulations identifies the upward shift as an excellent prediction of the response of upper-tropospheric cloud-radiative heating to surface warming and shows that the successful prediction results from the strong dependence of clouds and their radiative heating on atmospheric temperature. +An important implication is that changes in clouds with warming that go beyond the upward shift are secondary in the global climate models considered and that the overwhelming part of the model differences in the response of cloud-radiative heating to warming is caused by model differences in the simulation of cloud-radiative heating in the present-day climate. This highlights that a prime target for model development should be the improvement of cloud-radiative heating in the present-day climate, for which satellite-based estimates, despite their own uncertainties, can serve as helpful guidelines. + + + +\section{Response to non-uniform warming of the ocean surface} +\label{sec:results_amipfuture4K} + +We now study to what extent the pattern of ocean surface warming affects cloud-radiative heating. To this end, we repeat the analysis of Sec.\,\ref{sec:results_amipp4K} for the amip-future4K simulations. In these, sea-surface temperature is increased according to a pattern derived from coupled climate models and scaled to an ice-free ocean mean warming of 4\,K \citep{webb_cfmip4cmip6_gmd2017}. The time-mean SST increase is shown in Fig.\,\ref{fig:dsst_amipfuture4K}. In the amip-future4K simulations, the tropical ocean warms more than in the amip-4K simulations, in some places by more than 5 instead of the 4\,K of the amip-p4K simulations. The ocean warming is muted over the Southern Ocean and the North Atlantic because of ocean heat uptake and changes in the ocean circulation \citep{armour_southernocean_heatuptake_natgeo2016,keil_northatlanticwarminghole_natcc2020}. An analysis of simulations with stronger warming patterns would be desirable, for example the CMIP6 CFMIP simulations piSST, piSST-pxK and a4SST \citep{webb_cfmip4cmip6_gmd2017}. Yet, only very few models submitted the latter simulations, and no model included the output needed to diagnose cloud-radiative heating. + +\begin{figure} +\begin{center} + \includegraphics[width=0.5\textwidth]{../../plots4paper/figures/dsst_amipfuture4K-crop.pdf} + \caption{Time-mean change in sea-surface temperature (SST) imposed in the amip-future4K simulations. The color map is centered at the global-mean ocean surface warming of 4\,K. + \label{fig:dsst_amipfuture4K}} +\end{center} +\end{figure} + +Overall, the results from the amip-future4K simulations closely mirror the results from the amip-p4K simulations. Model differences in cloud-radiative heating are essentially as large in the amip-future4K simulations as in the amip-p4K simulations, and the upper-tropospheric response is very well captured by the same prediction as for the amip-p4K simulations. Because the results are essentially the same, they are not shown in separate figures. + +Our main interest here is to show that the pattern of surface warming has little impact on the upper-tropospheric response of cloud-radiative heating, but some impact on the response in the lower troposphere. This is illustrated in Fig.\,\ref{fig:crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K}, which shows the difference in the cloud-radiative heating between the amip-future4K and amip-p4K simulations. The difference quantifies the extent to which the response of cloud-radiative heating to surface warming depends on the pattern of surface warming. In the upper troposphere, the two sets of simulations agree very well. Thus, sufficiently away from the surface where air temperatures are mixed by the atmospheric circulation and less strongly tied to spatial variations in surface temperature, cloud-radiative heating is essentially independent of the pattern of surface warming and to first order controlled by the magnitude of global-mean warming. This finding is in line with our previous result that cloud-radiative heating in the upper troposphere is, to very good approximation, a function of atmospheric temperature. The latter implies that cloud-radiative heating is not dependent on how exactly the surface warms, but rather that the surface warming is communicated to the upper troposphere, where it varies much less spatially. A corollary is that that the upward shift of cloud-radiative heating is as good a predictor for the amip-future4K response as the amip-4K response (using a $\beta$ value of 1.2; not shown). + +We note that low-level clouds and cloud-radiative heating do not follow this paradigm. The response of cloud-radiative heating in the lower troposphere differs between the amip-future4K and amip-p4K simulations, in particular over the Southern Ocean. This is unsurprising since low-level clouds are known to be strongly controlled by sea-surface temperature and lower-tropospheric stability \citep{wood_stratocumulusclouds_mwr2012,bretherton_lowclouds_ptrs2015}. + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K-crop.pdf} + \caption{Difference between the zonal-mean time-mean cloud-radiative heating in the amip-future4K and amip-p4K simulations (amip-future4K - amip-p4K). The darker gray contour lines show the difference in zonal-mean time-mean cloud fraction between the two simulations (amip-future4K - amip-p4K; solid for positive and dashed for negative values, contour spacing of 0.01). For GFDL-CM4, cloud fraction is not available and cloud-radiative heating is restricted to above 500\,hPa because it is derived from zonal-mean heating rates in the amip-future4K simulation but zonally-resolved heating rates in the amip-p4K simulation (cf. Tab.\,\ref{tab:models}). This leads to spurious differences below 500\,hPa due to topography. The gray lines mark the 0 and -38\,deg\,C isotherms and the green lines the thermal tropopause for the amip simulations. + \label{fig:crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K}} +\end{center} +\end{figure} + + +In summary, the comparison between the amip-future4K and amip-p4K simulations demonstrates that the response of upper-tropospheric cloud-radiative heating is essentially insensitive to the details of the surface warming. This means that it can be considered a function of the global-mean surface warming, and hence a function of the product of climate sensitivity and radiative forcing. + + +\section{Prediction of the response in the upper troposphere from observations} +\label{sec:prediction} + + +The final step of our analysis is to predict how cloud-radiative heating in the upper troposphere responds to warming. The prediction is independent of the climate models and is obtained solely by combining the physical understanding of cloud-radiative heating and observations. The prediction takes advantage of our findings from global climate models that, first, the response is dominated by an upward shift of the present-day cloud-radiative heating and, second, the pattern of surface warming has little impact on the response. + +With these ingredients, the prediction is straightforward to obtain from the approach described in Sect.\,\ref{sec:results_amipp4K}. We shift the present-day cloud-radiative heating upward according to Eq.\,\ref{eq:dcrh_upwardshift}, using $\beta=1.2$. This is the same value as for the model simulations and corresponds to a global-mean ocean surface warming of 4\,K (see Sect.\,\ref{sec:results_amipp4K}). For the present-day cloud-radiative heating, we use the satellite-based estimates from both 2B-FLXHR-LIDAR R05 and CCCM. + +Fig.\,\ref{fig:obs_prediction} shows the predicted response. Because the prediction is only valid for the upper troposphere, the figure is limited to pressure levels above 600\,hPa. Both 2B-FLXHR-LIDAR and CCCM support the arc of anomalous positive cloud-radiative heating in the upper troposphere that extends from the tropics into the high latitudes, consistent with the behavior of the climate models. The arc is more pronounced for CCCM because the present-day cloud-radiative heating in the upper troposphere is stronger and more positive in CCCM than in 2B-FLXHR-LIDAR, as described in Sect.\,\ref{sec:results_amip}. In the tropics and subtropics the prediction is, in a qualitative sense, robust with respect to the satellite product, as is shown by the vertical profiles in the lower panels of Fig.\,\ref{fig:obs_prediction}. In the extratropics, however, the prediction has a different sign for CCCM and 2B-FLXHR-LIDAR. Thus, the uncertainty in current estimates of cloud-radiative heating precludes a robust prediction in the extratropics. + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/obs_prediction-crop.pdf} + \caption{Prediction of the response of upper-tropospheric cloud-radiative heating to warming by combining satellite observations from 2B-FLXHR-LIDAR and CCCM with physical understanding. Release R05 of 2B-FLXHR-LIDAR is used. The prediction assumes as global-mean ocean surface warming of 4\,K, in line with the amip-p4K and amip-future4K simulations. + \label{fig:obs_prediction}} +\end{center} +\end{figure} + + +\conclusions +\label{sec:conclusions} + +We study cloud-radiative heating in an ensemble of 20 CMIP6 models. To this end, we combine model output from four different CMIP6 output tables and, depending on the output available for a given model and simulation, derive cloud-radiative heating either by converting radiative fluxes to heating rates or by directly using the radiative heating rates provided in the CMIP6 archive of the Earth System Grid Foundation. By doing so, we generate the most comprehensive assessment of cloud-radiative heating in global climate models to date, overcoming a limitation of previous work that used only single models \citep{li_cookie_atmospherecirculation_jclim2015,johansson_cloudradheating_ecearth_gmd2021} or small ensembles of 5 models or less \citep{cesana_cloudradiativeheating_jclim2019,voigt_clouds_atmpathway_jclim2019}. + +Using simulations of the present-day climate in which sea-surface temperatures are prescribed to observed values, we identify large model differences in cloud-radiative heating in both the lower and upper troposphere. These differences are not unexpected from previous work, which illustrated large model differences in cloud fraction and cloud hydrometeors \citep{lauer_clouds_cmip5_cmip6_satellite_jclim2023,li_cloudice_obs_cmipmodels_mm2016}. Differences between models are particularly large in regions where the frozen phase of atmospheric water is prevalent, i.e., in the low-level mixed-phase clouds of the Southern Ocean and the upper-tropospheric ice clouds of the tropics and extratropics. This highlights the challenge of adequately representing cloud ice processes and their interaction with radiation in climate models. + +Using simulations in which the ocean surface is warmed, we demonstrate that cloud-radiative heating in the upper troposphere is first and foremost a function of the local air temperature, not surface temperature, and that the response of cloud-radiative heating above 500\,hPa to warming is therefore governed by an upward shift of the present-day cloud-radiative heating. This has three important consequences. + +\begin{enumerate} + \item The first consequence is a new null hypothesis for the response of upper-tropospheric cloud-radiative heating to warming. Because of the tight coupling between clouds and atmospheric temperature in the upper troposphere, the null hypothesis is an upward shift that ensures that cloud-radiative heating is conserved when measured as a function of atmospheric temperature. Other changes, such as changes in cloud fraction and cloud ice, are then second order. A corollary of the null hypothesis is that the response of cloud-radiative heating, or more generally clouds, in the upper troposphere should be considered together with, and not separately from, the response of upper-tropospheric temperature. This supports the recent proposal of \cite{yoshimori_fatfeedback_newdecomposition_jclim2020} for an alternative view on high cloud feedbacks and is analogous to the warming response of water vapor and lapse rates, which are tightly coupled and whose radiative feedbacks on Earth's energy balance are much better understood when considered in combination rather than in isolation \citep{held_watervapor_lapserate_feedbacks_jclim2012}. The null hypothesis may also help explain why the impact of cloud-radiative changes on the circulation response to warming diagnosed by cloud locking modeling studies can depend on the locked reference state, since cloud locking explicitly breaks the link between clouds and temperature \citep{albern_clouds_jetexit_erl2021,ceppi_clouds_circulation_warming_jclim2016,ceppi_clouds_circulation_cmip5_jclim2017,huber_cloud_locking_mscthesis_univie2022}. + + \item The second consequence is a physics-based prediction. The response of upper-tropospheric cloud-radiative heating is very well predicted by an upward shift of the present-day cloud-radiative heating, with the magnitude of the shift being a function of global-mean surface warming. The prediction is a direct consequence of the null hypothesis described above, and is thus rooted in physical understanding. The prediction captures the upper-tropospheric response independent of the pattern of surface warming because upper-tropospheric temperatures are not strongly sensitive to the details of surface warming thanks due to the homogenizing effect of the atmospheric circulation. This implies that the response of upper-tropospheric cloud-radiative heating can be predicted from the present-day cloud-radiative heating as a function of the magnitude of global-mean surface warming, i.e., it can be predicted by combining knowledge on climate sensitivity and radiative forcing. Notably, the prediction is based entirely on observations of cloud-radiative heating and is thus independent of climate models. However, observational uncertainties limit the prediction currently to the tropics and subtropics. Future work is needed to verify that the prediction is also supported by kilometer-scale climate models, where changes in cloud fraction and cloud hydrometeors might be more pronounced than in the coarse-resolution 50-100\,km models used in CMIP6. Future work is also needed to translate the cloud-radiative heating into changes in temperatures and ultimately winds, a task that is non-trivial due to the non-linear nature of the atmospheric circulation and the interaction of radiation with other small-scale diabatic processes. + + \item The third consequence is a call to action for model development. Because the present-day cloud-radiative heating provides a tight constraint on the response of cloud-radiative heating to warming in the upper troposphere, future model development efforts should explicitly target cloud-radiative heating. Past efforts have focused on top-of-atmosphere cloud-radiative effects. Despite their uncertainties, satellite observations provide a helpful baseline of the vertical structure of cloud-radiative heating within the atmosphere that has been underutilized for model development and evaluation. Modeling efforts should further include the upcoming km-scale climate models, whose high resolution provides a particular advantage for joint analyses of modeled and observed data, including from upcoming satellite Earth observations such as EarthCare \citep{illingworth_earthcare_bams2015}. +\end{enumerate} + + +Future work should address whether model biases in the simulation of the present-day circulation on climate and weather time scales are related to model differences in cloud-radiative heating. For example, such studies could examine the relationship between the upper-tropospheric tropical cloud-radiative heating and the extratropical jet stream, or the relationship between the extratropical lower- and upper-tropospheric cloud-radiative heating and extratropical cyclones \citep{voigt_cyclones_lowhighclouds_grl2023}. These topics are left for future work. + + + + +\codedataavailability{Upon acceptance of the paper, the analysis scripts will made available on the GitLab server of the University of Vienna and will be archived in the Phaidra repository for the permanent secure storage of digital assets at the University of Vienna. During the review phase, the scripts are provided as a tarfile that is included in the submission. +The CMIP6 model data can be obtained from the Earth System Grid Foundation. +The data for the 2B-FLXHR-LIDAR and CCCM products are available from the CloudSat Data Processing Center (http://www.cloudsat.cira.colostate.edu) and the Atmospheric +Science Data Center data (https://eosweb.larc.nasa.gov/).} + +\clearpage +\newpage + +%\appendix +\section*{Appendix A: additional figures} +\appendixfigures + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/illustrate_order_of_computation-crop.pdf} +\caption{Zonal-mean all-sky radiative heating rates in the BCC-CSM2-MR model for January 2013. Panels a and b show radiative heating rates computed from radiative fluxes. For panel a, fluxes are first interpolated from model levels to common pressure levels and heating rates are computed from these interpolated fluxes. For panel b, heating rates are first computed from fluxes on model levels, and these heating rates are then interpolated from model levels to common pressure levels. Throughout the manuscript, we use the order of computation of panel b. Panel c shows the ``native'' heating rates that were directly output by the model and that we interpolated from model levels to pressure levels. The agreement between panels b and c validates our method to derive heating rates from radiative fluxes (cf. approach 1 of Sect.\,\,\ref{sec:methods_data:crhcalculation}), whereas the disagreement between panels a and c illustrates the importance to derive heating rates on model levels. The right panel illustrates this also for a grid point over the Southern Ocean (67\,deg\,S; 68\,deg\,E).} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1.pdf} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip simulations diagnosed according to the three approaches outlined in Sect.\,2 and Tab.\,1.} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[height=40pc]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip-p4K simulations diagnosed according to the three approaches outlined in Sect.\,2 and Tab.\,1.} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[height=40pc]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip-future4K simulations diagnosed according to the three approaches outlined in Sect.\,2 and Tab.\,1.} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip simulations with 20 CMIP6 models sampled as function of air temperature. The sampling is only done within the troposphere so that the upper limit of the plotted data marks the tropopause temperature and the lower limit marks the surface temperature.} +\end{center} +\end{figure} + +\noappendix + +\authorcontribution{The study was designed by AV. Initial exploratory data analysis was performed by SN with input from AV; the data analysis was then extended and finalized by AV. SH calculated the CCCM cloud-radiative heating rates. AV led the writing process of the paper, with input from all authors. The work is based on the BSc thesis of SN at the Department of Meteorology and Geophysics of the University of Vienna.} + +\competinginterests{The contact author has declared that none of the authors has any competing interests.} + +\begin{acknowledgements} +We acknowledge the World Climate Research Programme, which, through its Working Group on Coupled Modelling, coordinated and promoted CMIP6. We thank the climate modeling groups for producing and making available their model output, the Earth System Grid Federation (ESGF) for archiving the data and providing access, and the multiple funding agencies who support CMIP6 and ESGF. We thank the developers and maintainers of the open source Python packages NumPy \citep{harris_numpy_nature2020}, Xarray \citep{hoyer_xarray_jors2017}, Matplotlib \citep{hunter_matplotlib_cse2007}, MetPy \citep{may_metpy_bam2022}, PyTropD \citep{adam_tropd_gmd2018} and CLIMLAB \citep{rose_climlab_joss2018}. Writing was assisted by the AI tool DeepL Write in terms of grammar and wording. +\end{acknowledgements} + + +\bibliographystyle{copernicus} +\DIFdelbegin %DIFDELCMD < \bibliography{/home/voigta80/Dropbox/BibTEX/my_entire_bibliography} +%DIFDELCMD < %%% +\DIFdelend \DIFaddbegin \bibliography{/home/aiko/Dropbox/BibTEX/my_entire_bibliography} +\DIFaddend + +\end{document} diff --git a/acp/accepted/response2reviewers2.pdf b/acp/accepted/response2reviewers2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..438b37e38f3057c74b0afb9c59ac16f9e322710e Binary files /dev/null and b/acp/accepted/response2reviewers2.pdf differ diff --git a/acp/accepted/response2reviewers2.tex b/acp/accepted/response2reviewers2.tex new file mode 100644 index 0000000000000000000000000000000000000000..2f1ab813294ae640bde539b94e7da0ed005dc0e7 --- /dev/null +++ b/acp/accepted/response2reviewers2.tex @@ -0,0 +1,97 @@ +\documentclass[11pt]{article} + +\usepackage{fullpage} +\usepackage{setspace} +\usepackage{parskip} +\usepackage{titlesec} +\usepackage[section]{placeins} +\usepackage{xcolor} +\usepackage{breakcites} +\usepackage{lineno} +\usepackage{hyphenat} +\usepackage{times} +\usepackage{natbib} + + +\usepackage{authblk} + + +\usepackage{graphicx} +\usepackage[space]{grffile} +\usepackage{latexsym} +\usepackage{textcomp} +\usepackage{longtable} +\usepackage{tabulary} +\usepackage{booktabs,array,multirow} +\usepackage{amsfonts,amsmath,amssymb} +%\providecommand\citet{\cite} +%\providecommand\citep{\cite} +%\providecommand\citealt{\cite} +% You can conditionalize code for latexml or normal latex using this. +%\newif\iflatexml\latexmlfalse +\providecommand{\tightlist}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}% + +\AtBeginDocument{\DeclareGraphicsExtensions{.pdf,.PDF,.eps,.EPS,.png,.PNG,.tif,.TIF,.jpg,.JPG,.jpeg,.JPEG}} + +\usepackage[utf8]{inputenc} +\usepackage[english]{babel} + +\newcommand{\msun}{\,\mathrm{M}_\odot} + +\begin{document} + +\section*{Atmospheric cloud-radiative heating in CMIP6 and observations, and its response to surface warming - Response to Reviewers 2} + +\noindent\textbf{Aiko Voigt, Stefanie North, Blaz Gasparini, and Seung-Hee Ham} + + +% figure counter in response letter material +\renewcommand{\thefigure}{R\arabic{figure}} +\setcounter{figure}{0} + +We thank the reviewers for their second round of thoughtful evaluations. We are particulary grateful to reviewer 2 for their valuable comment on ``cloud masking.'' In fact, this was a misunderstanding from our side and we have revised the manuscript to properly address this point, as detailed below. + +Reviewer comments are in bold, our response is normal font. Quotes from the revised manuscript are in blue (line numbers refer to the tracked-changes version). + +We also found an error in figure reference that we have corrected (L194). + +\section*{Reviewer 1} + +\textbf{I commend the authors on a nice paper and recommend that it be accepted at this time.} + +Thank you! + + +\section*{Reviewer 2} + +\textbf{The authors addressed most of my comments and I appreciated that. I think the paper has significantly improved as a result.} + +Thank you. + +\textbf{I do still have some questions/comments about the ``masking effect''. I’d like to note again that CRH, as defined as all-sky and clear-sky heating rate difference, is unable to accurately represent CRH change caused by cloud change, because it potentially aliases the masking effect of cloud ``existence'' as the effect of cloud ``change''. Do the cited/added results (Eq. 5 and Fig 4) really rule out this potential aliasing issue? I don’t think so. These results showed the variance of all-sky heating isn’t explained by clear-sky (which I agree), but can't tell if the dominant cloud term (sigma\_cloud) is really due to cloud change or cloud existence (the ``masking effect''). One must decompose the CRH term to know if, or to what extent, the masking effect is an issue. +Although it is probably beyond the scope to do this decomposition within this paper, this issue should be properly acknowledged by referencing the relevant literature and (e.g., heating rate kernels). This paper can also motivate future work to elucidate and mitigate the issue - with regard to this, I am unclear why the authors, in their reply, seem to suggest it is not feasible to use the heating rate kernels for this purpose. Please clarify.} + +Agreed! We have revised the manuscript to discuss the issue of cloud masking and added references to \cite{soden_cloudmasking_jclim2004}, \cite{huang_radkernels_era5_essd2023} and \cite{huang_radheating_radkernels_essoa2024}. The latter manuscript is currently in review and particularly relevant to our work. + +\textcolor{blue}{ +L97-104 (Introduction): Because cloud-radiative heating is defined as the difference between all-sky and clear-sky radiative heating, it depends not only on the cloud field itself but also the clear-sky background state of the atmosphere, an effect known as ``cloud-masking'' +\citep{soden_cloudmasking_jclim2004,huang_radheating_radkernels_essoa2024}. +Differences in cloud-radiative heating between models, between models and observations, or between different climate states may thus be influenced by non-cloud fields such as temperature and water vapor. These clear-sky effects could be quantified by explicit radiative transfer calculations or radiative kernel methods, but given the paucity of studies on atmospheric cloud-radiative heating we leave such refinements to future work.} + +\textcolor{blue}{ +L188-189 (Sect.\,2.4): ... and may be affected by cloud masking (cf. Sect.\,1).} + +\textcolor{blue}{ +L223-225 (Sect.\,3): Future work that takes into account cloud-masking effects would be helpful to quantify the sources of model differences in all-sky and cloud-radiative heating, for example by means of radiative kernels \citep{huang_radkernels_era5_essd2023,huang_radheating_radkernels_essoa2024}.} + + + + +\selectlanguage{english} +\FloatBarrier +\bibliographystyle{/home/aiko/Dropbox/BibTEX/myametsoc.bst} +\bibliography{/home/aiko/Dropbox/BibTEX/my_entire_bibliography} + + +\end{document} + diff --git a/acp/accepted/revised2.pdf b/acp/accepted/revised2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bbf36e4730c10875e6175876152cfed4a2da0fdb Binary files /dev/null and b/acp/accepted/revised2.pdf differ diff --git a/acp/accepted/revised2.tex b/acp/accepted/revised2.tex new file mode 100644 index 0000000000000000000000000000000000000000..e2b5149f84b7aa5593504c290cdc65d7abdd73f3 --- /dev/null +++ b/acp/accepted/revised2.tex @@ -0,0 +1,488 @@ +%% Copernicus Publications Manuscript Preparation Template for LaTeX Submissions +%% --------------------------------- +%% This template should be used for copernicus.cls +%% The class file and some style files are bundled in the Copernicus Latex Package, which can be downloaded from the different journal webpages. +%% For further assistance please contact Copernicus Publications at: production@copernicus.org +%% https://publications.copernicus.org/for_authors/manuscript_preparation.html + + +%% Please use the following documentclass and journal abbreviations for preprints and final revised papers. + +%% 2-column papers and preprints +\documentclass[acp, manuscript]{copernicus} + + + + +%% \usepackage commands included in the copernicus.cls: +%\usepackage[german, english]{babel} +%\usepackage{tabularx} +%\usepackage{cancel} +%\usepackage{multirow} +%\usepackage{supertabular} +%\usepackage{algorithmic} +%\usepackage{algorithm} +%\usepackage{amsthm} +%\usepackage{float} +%\usepackage{subfig} +%\usepackage{rotating} + + +\begin{document} + +\title{Atmospheric cloud-radiative heating in CMIP6 and observations, and its response to surface warming} + +% \Author[affil]{given_name}{surname} +\Author[1][aiko.voigt@univie.ac.at]{Aiko}{Voigt} +\Author[1]{Stefanie}{North} +\Author[1]{Bla\v{z}}{Gasparini} +\Author[2]{Seung-Hee}{Ham} + +\affil[1]{Department of Meteorology and Geophysics, University of Vienna, Vienna, Austria} +\affil[2]{Analytical Mechanics Associates (AMA), Hampton, +VA, USA} + +\correspondence{Aiko Voigt (aiko.voigt@univie.ac.at)} + +\runningtitle{Cloud-radiative heating in CMIP6} + +\runningauthor{A. Voigt} + +\received{} +\pubdiscuss{} %% only important for two-stage journals +\revised{} +\accepted{} +\published{} + +%% These dates will be inserted by Copernicus Publications during the typesetting process. + + +\firstpage{1} + +\maketitle + +\begin{abstract} +Cloud-radiation-interactions are key to Earth's climate and its susceptibility to change. While their impact on Earth's energy budget has been studied in great detail, their effect on atmospheric temperatures has received little attention, despite its importance for the planetary circulation of the atmosphere and hence for regional climate and weather. Here, we present the first systematic assessment of vertically-resolved cloud-radiative heating within the atmosphere in 20 CMIP6 models, including a comparison to satellite-based estimates. Our analysis highlights model differences in cloud-radiative heating in both the lower and upper troposphere, as well as uncertainties related to cloud ice processes. It also illustrates limitations of our ability to observe cloud-radiative heating. Not surprisingly, the response of cloud-radiative heating to surface warming is also uncertain across models. Yet, in the upper troposphere the response is very well predicted by an upward shift of the present-day heating, which we show results from the fact that cloud-radiative heating in the upper troposphere is a function of air temperature and thus decoupled from surface temperature. Our results have three important implications for upper-tropospheric cloud-radiative heating: they establish a new null hypothesis for its response to warming, offer a physics-based prediction of its response to warming based on present-day observations, and emphasize the need for improving its representation in simulations of the present-day climate, possibly by combining the benefits of upcoming km-scale models and satellite observations. +\end{abstract} + + +\introduction +\label{sec:introduction} + + +The interactions of tiny cloud particles with even tinier photons are key to climate and its susceptibility to change. It is well understood that clouds regulate Earth's energy balance by scattering photons back to space in the shortwave domain of the electromagnetic spectrum, and by intercepting and re-emitting photons in the longwave domain \citep{ramanathan_erbe_science1989,loeb_ceresebaf_ed4_jclim2018}. The interaction between clouds and radiation is often characterized by so-called cloud-radiative effects at the top of the atmosphere, which quantify the cloud impact by the difference between the energy balance of Earth and a hypothetical clear-sky climate in which clouds are assumed transparent to radiation. This widely-used top-of-atmosphere view forms the basis for much of our understanding of cloud-radiative feedbacks and their contribution to climate sensitivity \citep{sherwood_ecs_review_revgeo2020}. In this study, however, we take a different view and focus instead on cloud-radiation-interactions within the atmosphere, i.e., the radiative effect of clouds on atmospheric heating and cooling. + + +To quantify cloud-radiation-interactions within the atmosphere, we study the atmospheric cloud-radiative heating, a quantity sometimes also referred to as atmospheric cloud-radiative effects. Cloud-radiative heating is defined as +\begin{linenomath*} +\begin{equation} +\label{eq:crh_tntr_intro} + CRH(\lambda,\varphi,p,t) = \frac{\partial T}{\partial t}\bigg\vert^\textrm{all-sky}_\textrm{radiation} - \frac{\partial T}{\partial t}\bigg\vert^\textrm{clear-sky}_\textrm{radiation}. +\end{equation} +\end{linenomath*} +The coordinates $(\lambda,\varphi,p,t)$ emphasize that $CRH$ is a time-varying function of pressure, or altitude, and geographical location. The first term of the right hand side of the equation is the radiative heating of the all-sky atmosphere that includes cloud-radiation-interactions. The second term is the radiative heating of a hypothetical clear-sky atmosphere that is identical to the all-sky atmosphere apart from the fact that clouds are not interacting with radiation. +The philosophy behind cloud-radiative heating is the same as that behind top-of-atmosphere cloud-radiative effects, yet cloud-radiative heating is the more challenging quantity: very different vertical profiles of cloud-radiative properties and heating can lead to the same top-of-atmosphere cloud-radiative effects, and diagnosing cloud-radiative heating requires knowledge of the vertical distribution of clouds. It seems likely that this diagnostic challenge is one reason for why the vast majority of studies have focused on top-of-atmosphere cloud-radiative effects, while studies of cloud-radiative heating have remained relatively rare. + +There is no shortage of reasons to understand cloud-radiative heating, however. Cloud-radiative heating influences the clouds that underlie its very existence, e.g., it prolongs the lifetime of tropical anvil clouds \citep{wall_tropicalanvils_radiativeheating_jclim2020,gasparini_cloudanvil_diurnalcycle_jclim2022} and fuels the convective mixing that feeds subtropical marine low-level clouds \citep{stevens_moistconvection_areps2005,wood_stratocumulusclouds_mwr2012}. +Radiative cooling from low-level cloud tops drives tropical shallow overturning circulations \citep{naumann_shallowcirculation_radiation_jas2019} and modulates the intensity of extratropical cyclones \citep{grise_cloudheating_stormtracks_grl2019,voigt_cyclones_lowhighclouds_grl2023}. Radiative warming from tropical upper-tropospheric clouds narrows the intertropical convergence zone and decreases tropical-mean rainfall \citep{albern_cookie_hadleycell_grl2018,harrop_itczwidth_cookie_jclim2016}. Cloud-radiative heating has also been shown to alter the internal variability of the climate system to varying degrees, including the Madden-Julian-Oscillation \citep{benedict_cloudradiation_tropicaldisturbances_grl2020}, the El-Nino Southern Oscillation \citep{raedel_cloudheating_elnino_natgeo2016} and the North Atlantic Oscillation \citep{li_annularmode_clouds_grl2014,papavasileiou_nao_clouds_qjrms2020}, +and to be essential to the response of the planetary-scale circulation of the atmosphere to global warming \citep{voigt_clouds_atmpathway_jclim2019,ceppi_clouds_circulation_cmip5_jclim2017,albern_clouds_jet_james2019}. +Cloud-radiation interactions can further change the reservoir of available potential energy that is tapped by atmospheric motions \citep{stuhlmann_cloudradheating_ape_jas1988,romanski_diabaticheating_ape_jclim2013,kato_cloudradheating_ape_jgr2018}. +Given the range of scales on which cloud-radiative heating affects the atmospheric circulation, this list is clearly non-exhaustive. For a comprehensive review of the cloud-radiative heating impact on climate time scales we refer to \cite{voigt_clouds_radiation_circulation_wirescc2021}; a discussion of the impact of cloud-radiative heating on extratropical weather systems can be found in \cite{keshtgar_cyclone_cloud_radiation_wcd2023}. + + +A major motivation of our study is to provide a comprehensive assessment of atmospheric cloud radiative heating across global climate models. To this end, we compute and analyse cloud-radiative heating from model simulations of phase 6 of the Climate Model Intercomparison Project \citep{eyring_cmip6_gmd2016}. We are able to compute vertically-resolved cloud-radiative heating for 20 models. Previous model assessments were limited to a handful of models at most. Specifically, five models were compared in \cite{cesana_cloudradiativeheating_jclim2019} and three models in \cite{voigt_clouds_atmpathway_jclim2019}; other studies only used one model or were restricted to specific regions \citep{johansson_cloudradheating_ecearth_gmd2021,li_cookie_atmospherecirculation_jclim2015}. While \cite{luo_acre_cloudclasses_acp2023} used the CMIP6 model ensemble, they studied only the vertically-integrated heating derived from the difference in top-of-atmosphere and surface cloud-radiative fluxes. We further compare models to satellite-based estimates of cloud-radiative heating from CERES-CALIPSO-CloudSat-MODIS \citep{kato_cccm_jgr2011,ham_cccm_jamc2022} and CloudSat/CALIPSO \citep{lecuyer_cloudradheating_cloudsat_jgr2008,henderson_heatingrates_cloudsatcalipso_jamc2013}. + +Although previous assessments of cloud-radiative heating in models remained largely anecdotal, these studies collectively provided evidence that cloud-radiative heating varies substantially between models and that poorly-constrained parameterizations such as cloud microphysics and aerosol-cloud-interactions strongly affect cloud-radiative heating. For example, using the ICON model with km-scale resolution over the Asian monsoon region, \cite{sullivan_cloudice_radheating_commee2021} found that cloud-radiative heating in the tropical upper-troposphere changes by more than a factor of four when the model's 1-moment cloud microphysics scheme is replaced by a 2-moment scheme and microphysical information of the cloud particle effective radius is considered in the radiation scheme. Similarly, using the ICON model over the North Atlantic region, \cite{sullivan_nawdexhackathon_gmd2023} reported strong sensitivity of cloud-radiative heating to cloud microphysics and the treatment of convection, and highlighted the influence of partitioning frozen hydrometeors into cloud ice, which is suspended in the atmosphere and taken into account in radiation calculations, and precipitating snow and ice, whose effects on radiation are typically neglected in models \citep{waliser_snow_radiation_grl2011,li_clouds_radiation_cmip5_cmip6_jgr2022}. Differences in cloud-radiative heating are also large between atmospheric reanalyses \citep{zhang_diabaticheating_reanalyses_clidyn2017,wright_cloudradheating_highclouds_reanalysis_acp2020,sparc_srip_finalreport_dlr2022}, indicating that much of the challenge in correctly representing cloud-radiation-interactions in models does not stem from the large-scale circulation but small-scale cloud and radiative processes. + +Studies with global climate models and atmospheric reanalyses have in particular highlighted shortcomings in upper-tropospheric cloud-radiative heating due to ice clouds \citep{voigt_clouds_atmpathway_jclim2019,voigt_clouds_radiation_circulation_wirescc2021,cesana_cloudradiativeheating_jclim2019,johansson_cloudradheating_ecearth_gmd2021,wright_cloudradheating_highclouds_reanalysis_acp2020,sparc_srip_finalreport_dlr2022}. Ice clouds and their radiative heating are a key challenge for current models, both at coarse resolutions of 100\,km and fine km-scale resolutions \citep{gasparini_cirrus_opinionpiece_acpd2023}. The challenging nature of ice clouds is unsurprising given the intricacies of their microphysical and radiative properties \citep{kraemer_microphysics_cirrus_part1_acp2016,zhang_radiation_cirrus_ar1999}, yet understanding how they respond to warming is believed to be crucial to reduce uncertainty in climate sensitivity \citep{sherwood_ecs_review_revgeo2020,sokol_anvilcloud_thinning_natgeo2024} and to anticipate the response of the large-scale atmospheric circulation to warming \citep{voigt_clouds_atmpathway_jclim2019,albern_clouds_jet_james2019,li_cloudrise_jetshift_jclim2019}. + +While ice clouds are inherently complex, one important aspect of their response to warming is simple: ice clouds, or upper-tropospheric clouds more generally, tend to remain at roughly the same temperature as the climate warms. This behavior is an expression of the ``fixed-anvil temperature hypothesis (FAT)'' \citep{hartmann_fat_grl2002} that results from a well-understood thermodynamic control of convective outflow due to the rapid drop of clear-sky radiative cooling and water vapor near the tropopause. While originally developed for the tropics, FAT equally applies in the midlatitudes \citep{thompson_globalfat_pnas2017}. FAT establishes an important expectation regarding the response of upper-tropospheric clouds to warming: because their temperature is constrained, ice clouds, and with them their radiative heating, will shift upward as the surface warms. Modeling and observational analyses unequivocally support an upward shift of upper-tropospheric clouds in response to surface warming \citep{kuang_fat_cloudresolvingmodels_jclim2007,norris_cloudchange_satobservations_nature2016,pochedley_clouds_rh_rise_constraint_grl2019,richardson_cloudrise_satobs_grl2022,zelinka_highclouds_sensitivity_observations_jgr2011,zelinka_cloudfeedback_decomposition_grl2016}. +The upward shift suggests that the response of upper-tropospheric cloud-radiative heating to warming can be ``predicted'' by an upward shift of the present-day cloud radiative heating. This idea is supported by the findings +of \cite{singh_upwardshift_jclim2012} and \cite{voigt_clouds_atmpathway_jclim2019}; here we show it also holds across the CMIP6 model ensemble. This establishes a strong constraint on the global warming response of ice clouds, and hence their radiative impact on atmospheric circulation and regional climate change. + +Throughout the paper, our focus is on the representation of cloud-radiative heating within the atmosphere in global climate models for two reasons. First, by contributing to the diabatic heating of the atmosphere, cloud-radiative heating is relevant to the atmospheric circulation. And second, a systematic study of cloud-radiative heating in models is lacking, in contrast to cloud mass and fraction \citep{li_cloudice_cmip_jgr2012,lauer_clouds_cmip5_cmip6_satellite_jclim2023}. +Because cloud-radiative heating is defined as the difference between all-sky and clear-sky radiative heating, it depends not only on the cloud field itself but also the clear-sky background state of the atmosphere, an effect known as ``cloud-masking'' \citep{soden_cloudmasking_jclim2004,huang_radheating_radkernels_essoa2024}. Differences in cloud-radiative heating between models, between models and observations, or between different climate states may thus be influenced by non-cloud fields such as temperature and water vapor. These clear-sky effects could be quantified by explicit radiative transfer calculations or radiative kernel methods, but given the paucity of studies on atmospheric cloud-radiative heating we leave such refinements to future work. + + +Our manuscript is organized as follows. Sect.\,\ref{sec:methods_data} describes the calculation of cloud-radiative heating in CMIP6 models and observational estimates of cloud-radiative heating in today's climate. +Sect.\,\ref{sec:results_amip} studies cloud-radiative heating in simulations of present-day climate. Sects.\,\ref{sec:results_amipp4K} and \ref{sec:results_amipfuture4K} address how cloud-radiative heating responds to uniform and non-uniform surface warming. Sect.\,\ref{sec:prediction} asks to what extent the response can be predicted from the present-day climate. The paper concludes in Sect.\,\ref{sec:conclusions}, where we articulate three important consequences of our work. + + + +\section{CMIP6 simulations and satellite-based estimates of CRH} +\label{sec:methods_data} + +\subsection{CMIP6 simulations} + +We use model output from the amip, amip-p4K and amip-future4K simulations of CMIP6 \citep{eyring_cmip6_gmd2016,webb_cfmip4cmip6_gmd2017}. In the amip simulation, sea-surface temperatures, sea ice, well-mixed greenhouse gases and aerosols are prescribed to observed values from 1979 to 2014. This enables a clean comparison between models as well as between models and observations. In the amip-p4K simulation, sea-surface temperatures are uniformly increased by 4\,K. In the amip-future4K simulation, sea-surface temperatures are also increased by 4\,K in the global mean, but the increase varies spatially according to a pattern derived from coupled climate models. The amip-p4K and amip-future4K simulations allow us to study the response of cloud-radiative heating to surface warming and to assess to what extent the response depends on the pattern of surface warming. + +We use amip simulations from 20 CMIP6 models for which we were able to retrieve the all-sky and clear-sky radiative fluxes or heating rates from the CMIP6 ESGF archive that are necessary to calculate cloud-radiative heating, as described in the following subsection. The models are listed in Tab.\,\ref{tab:models}. Seven of the 20 models moreover provide the necessary output for the amip-p4K and amip-future4K simulations. We further retrieve atmospheric temperature, based on which we calculate the thermal tropopause as defined by the World Meteorological Organization \citep{wmo_meteorology_wmobull1957} using the PyTropD python package of \cite{adam_tropd_gmd2018}. All data retrieval and analysis scripts are included in the accompanying data. + +\subsection{Calculation of cloud-radiative heating from CMIP6 model output} +\label{sec:methods_data:crhcalculation} + + +\begin{center} +\begin{table} +\caption{CMIP6 models for which cloud-radiative heating is calculated. The approach used to calculate cloud-radiative heating depends on the data availability and is indicated by the checkmarks. See the manuscript text for an explanation of the three approaches.} +\begin{tabular}{llccc} +\hline\hline +Simulation & Model & Radiative fluxes & Temperature tendencies & Zonal-mean temperature \\ + & & (approach 1) & (approach 2) & tendencies (approach 3)\\ +\hline +amip & BCC-CSM2-MR & \checkmark & & \\ + & CESM2 & & & \checkmark \\ + & CESM2-FV2 & & & \checkmark \\ + & CESM2-WACCM & & & \checkmark \\ + & CESM2-WACCM-FV2 & & & \checkmark \\ + & CNRM-CM6-1 & \checkmark & \checkmark &\\ + & CNRM-ESM2-1 & \checkmark & \checkmark & \\ + & EC-Earth3 & & & \checkmark \\ + & GFDL-AM4 & & \checkmark & \\ + & GFDL-CM4 & & \checkmark & \\ + & GFDL-ESM4 & & & \checkmark \\ + & HadGEM3-GC31-LL & \checkmark & \checkmark & \\ + & HadGEM3-GC31-MM & \checkmark & & \\ + & INM-CM4-8 & \checkmark & & \\ + & INM-CM5-0 & \checkmark & &\\ + & IPSL-CM6A-LR & \checkmark & & \\ + & MIROC-ES2L & \checkmark & & \\ + & MIROC6 & \checkmark & & \\ + & MRI-ESM2-0 & \checkmark & &\\ + & UKESM1-0-LL & \checkmark & \checkmark & \\ +\hline +amip-p4K & BCC-CSM2-MR & \checkmark & & \\ + & CNRM-CM6-1 & \checkmark & &\\ + & GFDL-CM4 & & \checkmark & \\ + & HadGEM3-GC31-LL & \checkmark & \checkmark & \\ + & IPSL-CM6A-LR & \checkmark & & \\ + & MIROC6 & \checkmark & & \\ + & MRI-ESM2-0 & \checkmark & &\\ +\hline +amip-future4K & BCC-CSM2-MR & \checkmark & \\ + & CNRM-CM6-1 & \checkmark & \\ + & GFDL-CM4 & & & \checkmark \\ + & HadGEM3-GC31-LL & \checkmark & \checkmark &\\ + & IPSL-CM6A-LR & \checkmark & \\ + & MIROC6 & \checkmark & & \\ + & MRI-ESM2-0 & \checkmark & & \\ +\hline\hline +\end{tabular} +\label{tab:models} +\end{table} +\end{center} + +According to Eq.\,\ref{eq:crh_tntr_intro} cloud-radiative heating is given as the difference in all-sky and clear-sky radiative heating rates within the atmosphere. Since radiative heating rates are given by the radiative flux divergence divided by the mass of air, cloud-radiative heating can be calculated either directly from heating rates or indirectly from radiative fluxes: +\begin{eqnarray} + CRH & = & \frac{\partial T}{\partial t}\bigg\vert^\textrm{all-sky}_\textrm{radiation} - \frac{\partial T}{\partial t}\bigg\vert^\textrm{clear-sky}_\textrm{radiation} \label{eq:crh_tntr}\\ + & = & - \frac{g}{c_p}\cdot\frac{\partial}{\partial p}\left(F^\textrm{all-sky}-F^\textrm{clear-sky}\right) \label{eq:crh_radplev}\\ + & = & \frac{1}{\rho\,c_p}\cdot\frac{\partial}{\partial z}\left(F^\textrm{all-sky}-F^\textrm{clear-sky}\right). \label{eq:crh_radzlev} +\end{eqnarray} +Here, $\rho$ is the air density, $c_p$ is the heat capacity of air at constant pressure, $g$ is gravitational acceleration, and $F$ denotes the radiative fluxes in all-sky and clear-sky conditions, respectively (fluxes are defined as positive downward). We follow three approaches to calculate cloud-radiative heating, depending on the available output: +\begin{enumerate} + \item If the full set of all-sky and clear-sky radiative fluxes is available from the CFmon table, we first calculate individual heating rates from the radiative flux divergence following Eqs.\,\ref{eq:crh_radplev} and \ref{eq:crh_radzlev}, respectively, and then calculate cloud-radiative heating from the heating rates using Eq.\,\ref{eq:crh_tntr}. Eq.\,\ref{eq:crh_radplev} is used for models with pressure-based vertical coordinates, Eq.\,\ref{eq:crh_radzlev} for models with height-based vertical coordinates. + \item If all-sky and clear-sky radiative heating rates are available from the CFmon, AERmon or Emon tables, we calculate cloud-radiative heating directly from the difference in heating rates using Eq.\,\ref{eq:crh_tntr}. + \item If the zonally-averaged radiative heating rates are provided as part of the EmonZ table, we use these to calculate cloud-radiative heating from Eq.\,\ref{eq:crh_tntr}. +\end{enumerate} +For approaches 1 and 2, cloud-radiative heating is calculated on model levels and subsequently interpolated vertically to a set of 100 common pressure levels from 1000 to 0\,\unit{hPa} with a level spacing of 10\,hPa. For approach 1 it is essential to derive heating rates from radiative fluxes on model levels; computing heating rates from fluxes interpolated to pressure levels can result in substantial errors. This is illustrated in the additional figure A1. Cloud-radiative heating from approach 3 is interpolated from the EmonZ pressure levels to the common pressure levels. All calculations use monthly mean model output. The heat capacity of dry air, $c_p=1005\,\unit{J}\unit{kg^{-1}}\unit{K^{-1}}$, is used; the impact of humidity on $c_p$ is well below a few percent \citep{rogers_cloudphysics_elsevier1989} and can be neglected for the purpose of our study. The additional figures A2, A3 and A4 illustrate cloud-radiative heating calculated from the three approaches, showing that approaches 1 and 2 give indistinguishable results. For the analysis, we preferably use cloud-radiative heating calculated by approach 1 because it is applicable to the majority of the models. If approach 1 is not possible, we use approach 2, if possible, or approach 3. + +Two notes are in order for the models HadGEM3-GC31-LL, HadGEM3-GC31-MM and UKESM1-0-LL, which differ from the rest of the models by using a vertical grid based on height. The first note concerns the calculation of cloud-radiative heating from the flux divergence using Eq.\,\ref{eq:crh_radzlev}. The calculation requires the factor $\rho \cdot c_p$ that depends on time, latitude, longitude and model level. We obtain this factor from the ratio of the all-sky radiative heating rate and the all-sky radiative flux as $\rho \cdot c_p = \partial_z F^\textrm{all-sky} / \partial_t T \vert^\textrm{all-sky}_\textrm{radiation}$. The factor is then used to convert radiative fluxes to heating rates for all components of radiation, i.e., shortwave and longwave as well as clear-sky and all-sky fluxes. The second note concerns the vertical interpolation. The heating rates for the three model are interpolated to a common height grid extending from 0 to 20\,km with a level spacing of 200\,m. Where needed, e.g., for plots across all models, we convert from altitude levels to pressure levels using the geopotential height variable \verb+zg+ from the Amon table. + + +\subsection{Satellite-based estimates of cloud-radiative heating} + +We compare the amip simulations to two estimates of cloud-radiative heating based on active satellite measurements. \cite{kato_cloudradheating_ape_jgr2018} demonstrated the need for active measurements of clouds to derive radiative heating rates within the atmosphere. The first estimate is from the RelD1 product of CERES-CALIPSO-CloudSat-MODIS \citep[CCCM;][]{kato_cccm_reld1_nasa2021}, the second estimate from the 2B-FLXHR-LIDAR product of CloudSat/CALIPSO \citep{lecuyer_cloudradheating_cloudsat_jgr2008,henderson_heatingrates_cloudsatcalipso_jamc2013}. Both products combine the satellite measurements with radiative transfer calculations to derive all-sky and clear-sky radiative heating rates, from which cloud-radiative heating can be calculated. For the CCCM estimate, we follow the procedure described in \cite{ham_cccm_cloudradheating_jgr2017} and derive heating rates on height levels from daytime radiative fluxes following Eq.\,\ref{eq:crh_radzlev}, with shortwave heating rates scaled by monthly gridded solar incoming flux from the CERES SYN product. For the 2B-FLXHR-LIDAR estimate, we use the release R05 and derive cloud-radiative heating following the approach described in \cite{papavasileiou_nao_clouds_qjrms2020}: heating rates are derived for each CloudSat/CALIPSO granule using Eq.\,\ref{eq:crh_radplev} and ancillary information from the ECMWF-AUX, and then binned into 2.5\,deg\,lon\,x\,2.5\,deg\,lat averages for time periods of 5 days. Similar to the CCCM estimate, shortwave heating rates are scaled by daily-mean radiative insolation obtained from the CLIMLAB python package of \cite{rose_climlab_joss2018}. We average the pentad values in time to obtain the climatological cloud-radiative heating. We also derive cloud-radiative heating for the earlier R04 release of 2B-FLXHR-LIDAR analyzed by \cite{papavasileiou_nao_clouds_qjrms2020}, but if not noted otherwise we use the R05 release. The comparison between the estimate from CCCM and the two releases of 2B-FLXHR-LIDAR allows us to illustrate current uncertainties in observing cloud-radiative heating. + +For both CCCM and 2B-FLXHR-LIDAR, we analyze the time period from 2007-2010 and convert from altitude to pressure levels by means of the MetPy implementation \citep{may_metpy_bam2022} of the {U.\,S.} standard atmosphere \citep{noaa_standardatmosphere_usgov1976}. + + +\subsection{Cloud fraction} + +To allow the reader to connect the spatial pattern of cloud-radiative heating to cloud fraction, we include the latter in some of our figures. For the models, cloud fraction is taken from the variable \verb+cl+ of the Amon table and interpolated from model levels to pressure levels in the same manner as radiative heating rates. For observations, we use the CloudSat/CALIPSO based community product of \cite{bertrand_cloudcover_cloudsatcalipso_essd2024} for years 2007-2010. It should be noted, however, that cloud-radiative heating also depends on cloud liquid and ice content and the radiative treatment of clouds \citep[e.g.,][]{keshtgar_cloudradheating_cyclone_acp2024} and may be affected by cloud masking (cf. Sect.\,\ref{sec:introduction}). Differences in cloud-radiative heating between models and between models and observations are thus not explained by cloud fraction alone. + + +\section{Cloud-radiative heating in the present-day climate} +\label{sec:results_amip} + + +We begin with the zonal-mean time-mean cloud-radiative heating in the amip simulations shown in Fig.\,\ref{fig:crh_zonaltimemean_xypanelplot_amip}. The models agree on the overall pattern of cloud-radiative heating: clouds radiatively heat the upper troposphere at low latitudes and cool the lower troposphere, consistent with the meridional distribution of high-level and low-level clouds shown in Fig.\,\ref{fig:cl_zonaltimemean_xypanelplot_amip}. The two figures illustrate the well-known pattern of warming in the lower part of the cloud and cooling in its upper part that results from the absorption and emission of longwave radiation \cite[cf. Fig.\,3 of][]{slingo_cloudlwforcing_part1_qjrms1988}. This dipole pattern is for example evident for low-level clouds in the subtropics and extratropics and high-level clouds in the extratropical storm track regions. For tropical high-level clouds, the upper part of the cloud is warming instead of cooling because shortwave heating is larger and the low optical thickness that is typical for many high-level tropical clouds reduces their emission of longwave radiation. + +Beyond this basic agreement, however, the models show substantial differences in cloud-radiative heating at all latitudes. In the tropics, the maximum radiative heating in the upper troposphere ranges from 0.3\,K\,day$^\text{-1}$ in the family of CESM2 models to 0.9\,K\,day$^\text{-1}$ in the family of GFDL models, and the vertical distribution of cloud-radiative heating ranges from a clear maximum in the upper troposphere, e.g., in the GFDL and MIROC models, to a rather uniform heating within the free troposphere, e.g., in the CNRM and INM models. In the extratropics, between 30 and 60\,deg\,latitude, the maximum cloud-radiative cooling in the lower troposphere varies by a factor of four between -0.4\,K\,day$^\text{-1}$ in EC-Earth3 to -1.6\,K\,day$^\text{-1}$ in IPSL-CM6A-LR, and while some models show a dipole of cloud-radiative cooling near the tropopause and heating below (e.g., BCC-CSM2-MR and the two MIROC models), cloud-radiative heating is negative or close to zero throughout the extratropical free troposphere in other models (e.g., IPSL-CM6A-LR as well as the CESM and INM models). + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_zonaltimemean_xypanelplot_amip-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip simulations of 20 CMIP6 models. The gray lines mark the 0 and -38\,deg\,C isotherms to loosely distinguish regions of liquid, mixed-phase and ice clouds. The green line marks the thermal tropopause. Cloud-radiative heating in the CESM2 models is not shown below 500\,hPa because their EmonZ model output is affected by surface topography (cf. additional figure A2). + \label{fig:crh_zonaltimemean_xypanelplot_amip}} +\end{center} +\end{figure} + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/cl_zonaltimemean_xypanelplot_amip-crop.pdf} + \caption{Zonal-mean time-mean cloud fraction in amip simulations. The gray lines mark the 0 and -38\,deg\,C isotherms to loosely distinguish regions of liquid, mixed-phase and ice clouds. The white line marks the thermal tropopause. Note that for some models cloud fraction is not available from the ESGF archive; for CESM2-FV2 cloud fraction is restricted to above 500\,hPa. + \label{fig:cl_zonaltimemean_xypanelplot_amip}} +\end{center} +\end{figure} + + +To quantify the model differences in cloud-radiative heating, the top row of Fig.\,\ref{fig:crh_zonaltimemean_amip_median_std_obs} shows the model median and the standard deviation across models. Consistent with the findings above and with findings from the five GASS-YOTC models \citep{jiang_mjo_gassyotc_jgr2015,klingaman_mjo_gassyotc_jgr2015} compared in \cite{cesana_cloudradiativeheating_jclim2019}, the figure highlights two regions. First, model differences are large in the lower troposphere, in particular in the Southern Hemisphere extratropics, where mixed-phase clouds dominate and the standard deviation across models is almost as large as the model median. Second, model differences are pronounced in the upper troposphere around the -38\,deg\,C isotherm, where ice clouds prevail as a consequence of convective motions and large-scale ascent. In comparison, model differences are small in the mid troposphere. + +Model differences in cloud-radiative heating are not simply a result of clear-sky differences but truly reflect differences in the radiative interactions of clouds and translate to model differences in all-sky radiative heating. This is illustrated in Fig.\,\ref{fig:radheating_zonaltimemean_amip_variance}, which shows the variance in all-sky, clear-sky and cloud-radiative heating across all amip models. Mathematically, the variance in all-sky heating, $\sigma^2_\textrm{all-sky}$, can be decomposed into the variances in cloud and clear-sky heating and their covariance, +\begin{equation} + \sigma^2_\textrm{all-sky} = \sigma^2_\textrm{cloud} + \sigma^2_\textrm{clear-sky} + 2\cdot \textrm{cov}(\textrm{cloud, clear-sky}). +\end{equation} +Model differences in all-sky radiative heating overall are dominated by cloud-radiative heating. Moreover, although differences in cloud-radiative heating are in some regions co-related to clear-sky differences (e.g., in the tropical upper troposphere), they do not appear to be driven primarily by the latter. Future work that takes into account cloud-masking effects would be helpful to quantify the sources of model differences in all-sky and cloud-radiative heating, for example by means of radiative kernels \citep{huang_radkernels_era5_essd2023,huang_radheating_radkernels_essoa2024}. + + +To put the model simulations into perspective, Fig.\,\ref{fig:crh_zonaltimemean_amip_median_std_obs} also shows the satellite-based estimates of cloud-radiative heating in panels c-e, together with the observed cloud fraction in panel f. A somewhat sobering aspect is that the difference between satellite-based estimates of cloud-radiative heating from 2B-FLXHR-LIDAR and CCCM is about as large as the standard deviation across models. \cite{ham_cccm_cloudradheating_jgr2017} showed that assumptions regarding cloud detection thresholds, cloud merging and cloud optical properties substantially affect cloud-radiative heating rates and explain the differences between 2B-FLXHR-LIDAR and CCCM. For example, in the tropical upper troposphere, cloud-radiative heating is more positive in CCCM because the larger ice cloud extinction coefficient and particle size leads to stronger absorption in both the shortwave and longwave domains. The differences between R05 and R04 of 2B-FLXHR-LIDAR result from improvements in cloud microphysics, surface albedo and cloud detection \citep{cloudsat-2bflxhrlidar-r05_nasa2023}. Overall, the differences in the satellite-based estimates illustrate the challenges in establishing an observational baseline for cloud-radiative heating. + + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/crh_zonaltimemean_amip_median_std_obs-crop.pdf} + \caption{Agreement and disagreement in cloud-radiative heating in models and observations. The upper row show the model median (panel a) of zonal-mean time-mean cloud-radiative heating and the standard deviation (panel b) across the amip simulations of the 20 CMIP6 models. The middle and lower rows shows the satellite-based estimates of cloud-radiative heating from the 2B-FLXHR-LR R05 and R04 (panels c and d) and CCCM (panel e). Observed cloud fraction is shown in panel f. In all panels, the gray lines mark the model median of the 0 and -38\,deg\,C isotherms and the green line marks the model median of the thermal tropopause (white line in panel f). + \label{fig:crh_zonaltimemean_amip_median_std_obs}} +\end{center} +\end{figure} + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/radheating_zonaltimemean_amip_variance-crop.pdf} + \caption{Variance across amip model simulations for zonal-mean time-mean all-sky, cloud and clear-sky radiative heating in panels a-c. Panel d shows the covariance between the cloud and clear-sky radiative heating across models, multiplied by a factor of two. By design, panel a is the sum of panels b-d. + \label{fig:radheating_zonaltimemean_amip_variance}} +\end{center} +\end{figure} + + +Fig.\,\ref{fig:crh_5xdomaintimemean_amip} characterizes the cloud-radiative heating by means of vertical profiles over five domains that separate tropical ascending motion (15\,deg\,S - 15\,deg\,N) from subtropical descending motion (15\,deg\,N/S - 35\,deg\,N/S) and extratropical regions dominated by midlatitude cyclones (35\,deg\,N/S - 70\,deg\,N/S). The model simulations are shown in gray, the satellite-based estimates in blue. Again, the lower and upper troposphere emerge as regions with large differences between models as well as between the satellite-based estimates, while the differences are smaller in the mid-troposphere. In the Southern hemisphere extratropics and in the subtropics of both hemispheres, low-level cloud-radiative cooling in most of the models peaks at too low altitudes compared to the satellite-based estimates, consistent with \cite{cesana_cloudradiativeheating_jclim2019}. High-level cloud-radiative heating in the tropical upper troposphere is lower in the models compared to the CCCM estimate, in contrast to \cite{cesana_cloudradiativeheating_jclim2019}. + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_5xdomaintimemean_amip-crop.pdf} + \caption{Time-mean cloud-radiative heating averaged over the domains of the extratropical storm track (70-35\,deg\,lat), subtropical descent (35-15\,deg\,lat) and tropical ascent (equatorward of 15\,deg\,lat). The black line shows the model median. The blue lines show the cloud-radiative heating estimated by 2B-FLXHR-LIDAR R05 (solid) and CCCM (dashed). + \label{fig:crh_5xdomaintimemean_amip}} +\end{center} +\end{figure} + + + +\section{Response to uniform ocean surface warming} +\label{sec:results_amipp4K} + + +We now study the response of cloud-radiative heating to climate change. To this end, we analyze the amip-p4K simulations in which the ocean surface is warmed uniformly by 4\,K. We will show that the response of cloud-radiative heating to surface warming differs markedly between models, and that the model differences in the upper troposphere are nearly entirely caused by model differences in the present-day climate. The latter leads to the possibility to predict the response of upper-tropospheric cloud-radiative heating to surface warming based on the present-day climate. + +Fig.\,\ref{fig:crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip} shows the response of zonal-mean time-mean cloud radiative heating in the amip-p4K simulation relative to the amip simulations. Note that only seven models provide the output to calculate cloud-radiative heating in the amip-p4K simulations. The response shows a very complicated pattern, and it is difficult to identify aspects that robustly emerge in models. This is in particular the case in the lower troposphere, where the response of cloud-radiative heating is tied to model-dependent changes in low-level warm clouds in the tropics and subtropics and low-level mixed-phase clouds in the extratropics. + +In the upper troposphere, however, cloud-radiative heating responds to surface warming in a manner that is more robust across models. Despite large differences between models, all models simulate an arc-like pattern of anomalous positive cloud-radiative heating that extends from the tropics into the extratropics and is roughly aligned with the -38\,deg\,C isotherm. For example, the arc is very well developed in the BCC-CSM2-MR model. Models differ in terms of the extent of the arc towards the poles as well as its altitude and position relative to the -38\,deg\,C isotherm, yet they agree that the upper-tropospheric response of cloud-radiative heating includes the arc-like pattern. In fact, this pattern was reported previously by \cite{voigt_clouds_jetshifts_jclim2016,voigt_clouds_atmpathway_jclim2019} and \cite{voigt_clouds_radiation_circulation_wirescc2021}, who attributed it to the upward extension of the tropopause and the associated upward shift of clouds. + +We now demonstrate that the upper-tropospheric response of cloud-radiative heating response, i.e., above 500\,hPa, is very well predicted from an upward shift of cloud-radiative heating simulated in the models for the present-day climate. The prediction is anchored in the fact that upper-tropospheric clouds are strongly tied to atmospheric temperature (see also further below) via the fixed-anvil temperature hypothesis \citep{hartmann_fat_grl2002,thompson_globalfat_pnas2017}. The prediction follows \cite{singh_upwardshift_jclim2012}, who developed a framework to describe the upward extension of the tropopause with warming by rescaling the pressure coordinate. Eq.\,13g of \cite{singh_upwardshift_jclim2012} in particular predicts the upward shift of atmospheric radiative heating by shifting the pressure levels $p$ to new pressure levels $p^\prime = p/\beta$. $\beta$ is larger than 1, which implies $p^\prime <p$ and thus an upward shift. With this, the response of cloud-radiative heating can be predicted as +\begin{linenomath*} +\begin{equation} + \label{eq:dcrh_upwardshift} + dCRH(p, \varphi) = CRH(p, \varphi) - CRH(\beta p, \varphi). +\end{equation} +\end{linenomath*} +$\beta$ depends on the magnitude of surface warming. To derive its value, we compute the warming in the amip-p4K simulations at 800\,hPa averaged between 70\,deg\,N/S, yielding a model mean of 4.8\,K. Using a rounded value of 5\,K and Eq.\,15 of \cite{singh_upwardshift_jclim2012}, we obtain $\beta=1.2$. We use the same value for all models to highlight that the knowledge of the surface warming is sufficient to predict the upward shift of cloud-radiative heating. + + +Fig.\,\ref{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip} shows the cloud-radiative heating response averaged over the five extratropical, subtropical and tropical domains of Fig.\,\ref{fig:crh_5xdomaintimemean_amip}. The upper row includes all seven models and illustrates the large model differences in the response. The rows below show the individual models as well as the predicted response as blue lines. For almost all models and domains, the prediction captures the actual response extremely well. This is not only evident from the visual inspection of Fig.\,\ref{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip} but also from the correlation coefficients between the vertical profiles of the actual and the predicted responses. The correlation coefficients are calculated as the Pearson product-moment correlation coefficients and are typically larger than 0.9. We note that while the prediction has been successfully applied previously in \cite{voigt_clouds_atmpathway_jclim2019} for two of their three considered models, here we show that indeed it holds broadly across global climate models. + + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf} + \caption{Response of zonal-mean time-mean cloud-radiative heating to a uniform 4\,K warming of the ocean surface in amip-p4K simulations with 7 CMIP6 models. The gray lines mark the 0 and -38\,deg\,C isotherms and the green lines the thermal tropopause for the amip simulation. + \label{fig:crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip}} +\end{center} +\end{figure} + + + +\begin{figure} +\begin{center} + \includegraphics[height=0.9\textheight]{../../plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip-crop.pdf} + \caption{Response of cloud-radiative heating to surface warming averaged over the domains of the extratropical storm track (70-35\,deg\,lat), subtropical descent (35-15\,deg\,lat) and tropical ascent (equatorward of 15\,deg\,lat). The blue line shows the response predicted by the upward shift of cloud-radiative heating in the present-day climate. The numbers give the correlation coefficient between the actual and the predicted response between 100 and 500\,hPa. + \label{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip}} +\end{center} +\end{figure} + + +A drawback of the domain averages on pressure levels is that they tend to obscure the dependence of clouds on atmospheric temperature that underlies the successful prediction in Fig.\,\ref{fig:crh_changewithwarming_5xdomaintimemean_amipp4K-amip}. Another drawback is that domain averages on pressure levels are affected by a cancellation between positive and negative values of cloud-radiative heating in the extratropics, where meridional temperature gradients are strong and isotherms and isobars are not aligned with each other (see, e.g., Figs.\,\ref{fig:crh_zonaltimemean_xypanelplot_amip} and \ref{fig:crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip}). +To address these drawbacks, we also calculate cloud-radiative heating as a function of atmospheric temperature, i.e., we use temperature instead of pressure as the vertical coordinate. When remapping from pressure levels to temperature levels, we use the zonal-mean time-mean temperature and only consider levels below the tropopause since the increase in temperature above the tropopause makes the mapping non-unique. For reference, the zonal-mean time-mean cloud-radiative heating in the amip simulations sampled as a function of temperature is shown in additional figure A5. Here, we focus on the response of cloud-radiative heating to surface warming in the amip-p4K simulations. + + +Fig.\,\ref{fig:crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip} shows that apart from the region of the boundary layer, the cloud-radiative heating is remarkably similar between the amip and amip-p4K simulations when expressed as a function of temperature. In 5 of the 7 models, the difference in cloud-radiative heating between the two climates is within $\pm$\,0.1\,K/day and hence close to zero. In IPSL-CM6A-LR and CRNM-CM6-1, cloud-radiative heating increases by roughly 30\% in the tropical mid and upper troposphere, yet the increase is closely aligned with the cloud-radiative heating in the present-day climate. This suggests that it results largely from an increase in cloud ice content or cloud fraction. Although future work should address why cloud-radiative heating increases in these two models but not in the other models, our analysis clearly establishes a helpful null hypothesis: cloud-radiative heating does not change with warming apart from an upward shift to lower pressures so as to stay at the same air temperature. +%We note that that within and near the boundary layer, changes in cloud-radiative heating are large for the simple reason that the boundary layer warms by about 4\,K everywhere, which implies a shift of boundary layer clouds to higher temperatures and hence strong changes in cloud-radiative heating. + +Expressing cloud-radiative heating as a function of temperature thus shows that the upward shift is an excellent prediction of the response of upper-tropospheric cloud-radiative heating to surface warming because clouds and their radiative heating are invariant to climate change when viewed not in terms of pressure but air temperature. This view is in line with the work of \cite{jeevanjee_precipitation_warming_pnas2018}, who combined theory, idealized modeling and global climate model analysis to show that sufficiently away from the surface, all-sky and clear-sky radiative fluxes are independent of climate when measured as a function of temperature. Here, we have extended the view to the radiative heating rates (instead of fluxes) and to clouds (instead of the all-sky or clear-sky atmosphere). + + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf} + \caption{Response of cloud-radiative heating to a uniform 4\,K ocean surface warming as a function of air temperature. The sampling is limited to the troposphere so that the upper limit of the plotted data marks the tropopause temperature and the lower limit marks the surface temperature. The black lines show the cloud-radiative heating in the amip simulations with a contour spacing of 0.1\,K/day. For the latter, only levels with pressures smaller than 750\,hPa are taken into account to avoid line cluttering near the surface. + \label{fig:crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip}} +\end{center} +\end{figure} + + +In summary, our comparison of the amip-p4K and amip simulations identifies the upward shift as an excellent prediction of the response of upper-tropospheric cloud-radiative heating to surface warming and shows that the successful prediction results from the strong dependence of clouds and their radiative heating on atmospheric temperature. +An important implication is that changes in clouds with warming that go beyond the upward shift are secondary in the global climate models considered and that the overwhelming part of the model differences in the response of cloud-radiative heating to warming is caused by model differences in the simulation of cloud-radiative heating in the present-day climate. This highlights that a prime target for model development should be the improvement of cloud-radiative heating in the present-day climate, for which satellite-based estimates, despite their own uncertainties, can serve as helpful guidelines. + + + +\section{Response to non-uniform warming of the ocean surface} +\label{sec:results_amipfuture4K} + +We now study to what extent the pattern of ocean surface warming affects cloud-radiative heating. To this end, we repeat the analysis of Sec.\,\ref{sec:results_amipp4K} for the amip-future4K simulations. In these, sea-surface temperature is increased according to a pattern derived from coupled climate models and scaled to an ice-free ocean mean warming of 4\,K \citep{webb_cfmip4cmip6_gmd2017}. The time-mean SST increase is shown in Fig.\,\ref{fig:dsst_amipfuture4K}. In the amip-future4K simulations, the tropical ocean warms more than in the amip-4K simulations, in some places by more than 5 instead of the 4\,K of the amip-p4K simulations. The ocean warming is muted over the Southern Ocean and the North Atlantic because of ocean heat uptake and changes in the ocean circulation \citep{armour_southernocean_heatuptake_natgeo2016,keil_northatlanticwarminghole_natcc2020}. An analysis of simulations with stronger warming patterns would be desirable, for example the CMIP6 CFMIP simulations piSST, piSST-pxK and a4SST \citep{webb_cfmip4cmip6_gmd2017}. Yet, only very few models submitted the latter simulations, and no model included the output needed to diagnose cloud-radiative heating. + +\begin{figure} +\begin{center} + \includegraphics[width=0.5\textwidth]{../../plots4paper/figures/dsst_amipfuture4K-crop.pdf} + \caption{Time-mean change in sea-surface temperature (SST) imposed in the amip-future4K simulations. The color map is centered at the global-mean ocean surface warming of 4\,K. + \label{fig:dsst_amipfuture4K}} +\end{center} +\end{figure} + +Overall, the results from the amip-future4K simulations closely mirror the results from the amip-p4K simulations. Model differences in cloud-radiative heating are essentially as large in the amip-future4K simulations as in the amip-p4K simulations, and the upper-tropospheric response is very well captured by the same prediction as for the amip-p4K simulations. Because the results are essentially the same, they are not shown in separate figures. + +Our main interest here is to show that the pattern of surface warming has little impact on the upper-tropospheric response of cloud-radiative heating, but some impact on the response in the lower troposphere. This is illustrated in Fig.\,\ref{fig:crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K}, which shows the difference in the cloud-radiative heating between the amip-future4K and amip-p4K simulations. The difference quantifies the extent to which the response of cloud-radiative heating to surface warming depends on the pattern of surface warming. In the upper troposphere, the two sets of simulations agree very well. Thus, sufficiently away from the surface where air temperatures are mixed by the atmospheric circulation and less strongly tied to spatial variations in surface temperature, cloud-radiative heating is essentially independent of the pattern of surface warming and to first order controlled by the magnitude of global-mean warming. This finding is in line with our previous result that cloud-radiative heating in the upper troposphere is, to very good approximation, a function of atmospheric temperature. The latter implies that cloud-radiative heating is not dependent on how exactly the surface warms, but rather that the surface warming is communicated to the upper troposphere, where it varies much less spatially. A corollary is that that the upward shift of cloud-radiative heating is as good a predictor for the amip-future4K response as the amip-4K response (using a $\beta$ value of 1.2; not shown). + +We note that low-level clouds and cloud-radiative heating do not follow this paradigm. The response of cloud-radiative heating in the lower troposphere differs between the amip-future4K and amip-p4K simulations, in particular over the Southern Ocean. This is unsurprising since low-level clouds are known to be strongly controlled by sea-surface temperature and lower-tropospheric stability \citep{wood_stratocumulusclouds_mwr2012,bretherton_lowclouds_ptrs2015}. + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K-crop.pdf} + \caption{Difference between the zonal-mean time-mean cloud-radiative heating in the amip-future4K and amip-p4K simulations (amip-future4K - amip-p4K). The darker gray contour lines show the difference in zonal-mean time-mean cloud fraction between the two simulations (amip-future4K - amip-p4K; solid for positive and dashed for negative values, contour spacing of 0.01). For GFDL-CM4, cloud fraction is not available and cloud-radiative heating is restricted to above 500\,hPa because it is derived from zonal-mean heating rates in the amip-future4K simulation but zonally-resolved heating rates in the amip-p4K simulation (cf. Tab.\,\ref{tab:models}). This leads to spurious differences below 500\,hPa due to topography. The gray lines mark the 0 and -38\,deg\,C isotherms and the green lines the thermal tropopause for the amip simulations. + \label{fig:crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K}} +\end{center} +\end{figure} + + +In summary, the comparison between the amip-future4K and amip-p4K simulations demonstrates that the response of upper-tropospheric cloud-radiative heating is essentially insensitive to the details of the surface warming. This means that it can be considered a function of the global-mean surface warming, and hence a function of the product of climate sensitivity and radiative forcing. + + +\section{Prediction of the response in the upper troposphere from observations} +\label{sec:prediction} + + +The final step of our analysis is to predict how cloud-radiative heating in the upper troposphere responds to warming. The prediction is independent of the climate models and is obtained solely by combining the physical understanding of cloud-radiative heating and observations. The prediction takes advantage of our findings from global climate models that, first, the response is dominated by an upward shift of the present-day cloud-radiative heating and, second, the pattern of surface warming has little impact on the response. + +With these ingredients, the prediction is straightforward to obtain from the approach described in Sect.\,\ref{sec:results_amipp4K}. We shift the present-day cloud-radiative heating upward according to Eq.\,\ref{eq:dcrh_upwardshift}, using $\beta=1.2$. This is the same value as for the model simulations and corresponds to a global-mean ocean surface warming of 4\,K (see Sect.\,\ref{sec:results_amipp4K}). For the present-day cloud-radiative heating, we use the satellite-based estimates from both 2B-FLXHR-LIDAR R05 and CCCM. + +Fig.\,\ref{fig:obs_prediction} shows the predicted response. Because the prediction is only valid for the upper troposphere, the figure is limited to pressure levels above 600\,hPa. Both 2B-FLXHR-LIDAR and CCCM support the arc of anomalous positive cloud-radiative heating in the upper troposphere that extends from the tropics into the high latitudes, consistent with the behavior of the climate models. The arc is more pronounced for CCCM because the present-day cloud-radiative heating in the upper troposphere is stronger and more positive in CCCM than in 2B-FLXHR-LIDAR, as described in Sect.\,\ref{sec:results_amip}. In the tropics and subtropics the prediction is, in a qualitative sense, robust with respect to the satellite product, as is shown by the vertical profiles in the lower panels of Fig.\,\ref{fig:obs_prediction}. In the extratropics, however, the prediction has a different sign for CCCM and 2B-FLXHR-LIDAR. Thus, the uncertainty in current estimates of cloud-radiative heating precludes a robust prediction in the extratropics. + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/obs_prediction-crop.pdf} + \caption{Prediction of the response of upper-tropospheric cloud-radiative heating to warming by combining satellite observations from 2B-FLXHR-LIDAR and CCCM with physical understanding. Release R05 of 2B-FLXHR-LIDAR is used. The prediction assumes as global-mean ocean surface warming of 4\,K, in line with the amip-p4K and amip-future4K simulations. + \label{fig:obs_prediction}} +\end{center} +\end{figure} + + +\conclusions +\label{sec:conclusions} + +We study cloud-radiative heating in an ensemble of 20 CMIP6 models. To this end, we combine model output from four different CMIP6 output tables and, depending on the output available for a given model and simulation, derive cloud-radiative heating either by converting radiative fluxes to heating rates or by directly using the radiative heating rates provided in the CMIP6 archive of the Earth System Grid Foundation. By doing so, we generate the most comprehensive assessment of cloud-radiative heating in global climate models to date, overcoming a limitation of previous work that used only single models \citep{li_cookie_atmospherecirculation_jclim2015,johansson_cloudradheating_ecearth_gmd2021} or small ensembles of 5 models or less \citep{cesana_cloudradiativeheating_jclim2019,voigt_clouds_atmpathway_jclim2019}. + +Using simulations of the present-day climate in which sea-surface temperatures are prescribed to observed values, we identify large model differences in cloud-radiative heating in both the lower and upper troposphere. These differences are not unexpected from previous work, which illustrated large model differences in cloud fraction and cloud hydrometeors \citep{lauer_clouds_cmip5_cmip6_satellite_jclim2023,li_cloudice_obs_cmipmodels_mm2016}. Differences between models are particularly large in regions where the frozen phase of atmospheric water is prevalent, i.e., in the low-level mixed-phase clouds of the Southern Ocean and the upper-tropospheric ice clouds of the tropics and extratropics. This highlights the challenge of adequately representing cloud ice processes and their interaction with radiation in climate models. + +Using simulations in which the ocean surface is warmed, we demonstrate that cloud-radiative heating in the upper troposphere is first and foremost a function of the local air temperature, not surface temperature, and that the response of cloud-radiative heating above 500\,hPa to warming is therefore governed by an upward shift of the present-day cloud-radiative heating. This has three important consequences. + +\begin{enumerate} + \item The first consequence is a new null hypothesis for the response of upper-tropospheric cloud-radiative heating to warming. Because of the tight coupling between clouds and atmospheric temperature in the upper troposphere, the null hypothesis is an upward shift that ensures that cloud-radiative heating is conserved when measured as a function of atmospheric temperature. Other changes, such as changes in cloud fraction and cloud ice, are then second order. A corollary of the null hypothesis is that the response of cloud-radiative heating, or more generally clouds, in the upper troposphere should be considered together with, and not separately from, the response of upper-tropospheric temperature. This supports the recent proposal of \cite{yoshimori_fatfeedback_newdecomposition_jclim2020} for an alternative view on high cloud feedbacks and is analogous to the warming response of water vapor and lapse rates, which are tightly coupled and whose radiative feedbacks on Earth's energy balance are much better understood when considered in combination rather than in isolation \citep{held_watervapor_lapserate_feedbacks_jclim2012}. The null hypothesis may also help explain why the impact of cloud-radiative changes on the circulation response to warming diagnosed by cloud locking modeling studies can depend on the locked reference state, since cloud locking explicitly breaks the link between clouds and temperature \citep{albern_clouds_jetexit_erl2021,ceppi_clouds_circulation_warming_jclim2016,ceppi_clouds_circulation_cmip5_jclim2017,huber_cloud_locking_mscthesis_univie2022}. + + \item The second consequence is a physics-based prediction. The response of upper-tropospheric cloud-radiative heating is very well predicted by an upward shift of the present-day cloud-radiative heating, with the magnitude of the shift being a function of global-mean surface warming. The prediction is a direct consequence of the null hypothesis described above, and is thus rooted in physical understanding. The prediction captures the upper-tropospheric response independent of the pattern of surface warming because upper-tropospheric temperatures are not strongly sensitive to the details of surface warming thanks due to the homogenizing effect of the atmospheric circulation. This implies that the response of upper-tropospheric cloud-radiative heating can be predicted from the present-day cloud-radiative heating as a function of the magnitude of global-mean surface warming, i.e., it can be predicted by combining knowledge on climate sensitivity and radiative forcing. Notably, the prediction is based entirely on observations of cloud-radiative heating and is thus independent of climate models. However, observational uncertainties limit the prediction currently to the tropics and subtropics. Future work is needed to verify that the prediction is also supported by kilometer-scale climate models, where changes in cloud fraction and cloud hydrometeors might be more pronounced than in the coarse-resolution 50-100\,km models used in CMIP6. Future work is also needed to translate the cloud-radiative heating into changes in temperatures and ultimately winds, a task that is non-trivial due to the non-linear nature of the atmospheric circulation and the interaction of radiation with other small-scale diabatic processes. + + \item The third consequence is a call to action for model development. Because the present-day cloud-radiative heating provides a tight constraint on the response of cloud-radiative heating to warming in the upper troposphere, future model development efforts should explicitly target cloud-radiative heating. Past efforts have focused on top-of-atmosphere cloud-radiative effects. Despite their uncertainties, satellite observations provide a helpful baseline of the vertical structure of cloud-radiative heating within the atmosphere that has been underutilized for model development and evaluation. Modeling efforts should further include the upcoming km-scale climate models, whose high resolution provides a particular advantage for joint analyses of modeled and observed data, including from upcoming satellite Earth observations such as EarthCare \citep{illingworth_earthcare_bams2015}. +\end{enumerate} + + +Future work should address whether model biases in the simulation of the present-day circulation on climate and weather time scales are related to model differences in cloud-radiative heating. For example, such studies could examine the relationship between the upper-tropospheric tropical cloud-radiative heating and the extratropical jet stream, or the relationship between the extratropical lower- and upper-tropospheric cloud-radiative heating and extratropical cyclones \citep{voigt_cyclones_lowhighclouds_grl2023}. These topics are left for future work. + + + + +\codedataavailability{Upon acceptance of the paper, the analysis scripts will made available on the GitLab server of the University of Vienna and will be archived in the Phaidra repository for the permanent secure storage of digital assets at the University of Vienna. During the review phase, the scripts are provided as a tarfile that is included in the submission. +The CMIP6 model data can be obtained from the Earth System Grid Foundation. +The data for the 2B-FLXHR-LIDAR and CCCM products are available from the CloudSat Data Processing Center (http://www.cloudsat.cira.colostate.edu) and the Atmospheric +Science Data Center data (https://eosweb.larc.nasa.gov/).} + +\clearpage +\newpage + +%\appendix +\section*{Appendix A: additional figures} +\appendixfigures + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/illustrate_order_of_computation-crop.pdf} +\caption{Zonal-mean all-sky radiative heating rates in the BCC-CSM2-MR model for January 2013. Panels a and b show radiative heating rates computed from radiative fluxes. For panel a, fluxes are first interpolated from model levels to common pressure levels and heating rates are computed from these interpolated fluxes. For panel b, heating rates are first computed from fluxes on model levels, and these heating rates are then interpolated from model levels to common pressure levels. Throughout the manuscript, we use the order of computation of panel b. Panel c shows the ``native'' heating rates that were directly output by the model and that we interpolated from model levels to pressure levels. The agreement between panels b and c validates our method to derive heating rates from radiative fluxes (cf. approach 1 of Sect.\,\,\ref{sec:methods_data:crhcalculation}), whereas the disagreement between panels a and c illustrates the importance to derive heating rates on model levels. The right panel illustrates this also for a grid point over the Southern Ocean (67\,deg\,S; 68\,deg\,E).} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1.pdf} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=0.8\textwidth]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip simulations diagnosed according to the three approaches outlined in Sect.\,2 and Tab.\,1.} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[height=40pc]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip-p4K simulations diagnosed according to the three approaches outlined in Sect.\,2 and Tab.\,1.} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[height=40pc]{../../plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip-future4K simulations diagnosed according to the three approaches outlined in Sect.\,2 and Tab.\,1.} +\end{center} +\end{figure} + +\clearpage + +\begin{figure} +\begin{center} + \includegraphics[width=1.0\textwidth]{../../plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip-crop.pdf} + \caption{Zonal-mean time-mean cloud-radiative heating in amip simulations with 20 CMIP6 models sampled as function of air temperature. The sampling is only done within the troposphere so that the upper limit of the plotted data marks the tropopause temperature and the lower limit marks the surface temperature.} +\end{center} +\end{figure} + +\noappendix + +\authorcontribution{The study was designed by AV. Initial exploratory data analysis was performed by SN with input from AV; the data analysis was then extended and finalized by AV. SH calculated the CCCM cloud-radiative heating rates. AV led the writing process of the paper, with input from all authors. The work is based on the BSc thesis of SN at the Department of Meteorology and Geophysics of the University of Vienna.} + +\competinginterests{The contact author has declared that none of the authors has any competing interests.} + +\begin{acknowledgements} +We acknowledge the World Climate Research Programme, which, through its Working Group on Coupled Modelling, coordinated and promoted CMIP6. We thank the climate modeling groups for producing and making available their model output, the Earth System Grid Federation (ESGF) for archiving the data and providing access, and the multiple funding agencies who support CMIP6 and ESGF. We thank the developers and maintainers of the open source Python packages NumPy \citep{harris_numpy_nature2020}, Xarray \citep{hoyer_xarray_jors2017}, Matplotlib \citep{hunter_matplotlib_cse2007}, MetPy \citep{may_metpy_bam2022}, PyTropD \citep{adam_tropd_gmd2018} and CLIMLAB \citep{rose_climlab_joss2018}. Writing was assisted by the AI tool DeepL Write in terms of grammar and wording. +\end{acknowledgements} + + +\bibliographystyle{copernicus} +\bibliography{/home/aiko/Dropbox/BibTEX/my_entire_bibliography} + +\end{document} diff --git a/analysis/GFDL-AM4-CM4_tntr_amip.ipynb b/analysis/GFDL-AM4-CM4_tntr_amip.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..32134eb2a2e2e613aabbd34b8eb25047e8718a83 --- /dev/null +++ b/analysis/GFDL-AM4-CM4_tntr_amip.ipynb @@ -0,0 +1,245 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b35a2bc7-7ace-4379-a5aa-d43fa2312838", + "metadata": {}, + "source": [ + "## Manual treatment of GFDL-AM4 and CM4 tntr data for amip simulations" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "24889400-079a-4d1e-a804-9bb822f33942", + "metadata": {}, + "outputs": [], + "source": [ + "path=\"/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/\"\n", + "\n", + "import sys\n", + "sys.path.append(\"/users/staff/avoigt/cmip-acre/analysis\")\n", + "import cmip6radheating\n", + "\n", + "import xarray as xr" + ] + }, + { + "cell_type": "markdown", + "id": "4880bef0-86b9-43ea-b9e4-54f6754cd4d0", + "metadata": {}, + "source": [ + "## 0. Define function to compute radiative heating rate from tntr, taken from batchcompute_dtdt-from-tntr.py" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "16e0e964-e52f-46a0-968f-d2f839df2e55", + "metadata": {}, + "outputs": [], + "source": [ + "# function that computes radiative heating rates\n", + "# below we loop over the function using multiprocessing\n", + "def compute_dtdt_from_tntr(_ds_list, _var_list, _varout):\n", + " \"\"\" Computes heating rates for a list of one or several data sets\n", + " that each contain a radiative heating rate. The net radiative \n", + " heating rate is calculated as the sum of the input radiative heating rates.\n", + " \n", + " _ds_list: list of radiative heating rate datasets\n", + " _var_list: list of the variable names of the radiative heating rates in _ds_list\n", + " \"\"\"\n", + " import shutil \n", + " _model = _ds_list[0].attrs[\"source_id\"]\n", + " # compute net radiative heating rate from the sum of input radiative heating rates\n", + " _dtdt = cmip6radheating.add_heatingrate(_ds_list, _var_list)\n", + " _dtdt = cmip6radheating.addpressure2dataset(_dtdt, model=_model, levtype=\"full\")\n", + " _levint = cmip6radheating.define_targetlevels()\n", + " _dtdt_int = cmip6radheating.interpolate2pressure(_dtdt, [\"dTdt\"], _levint).rename({'dTdt': _varout})\n", + " # write interpolated heating rate to zarr store\n", + " _path = \"/scratch/das/avoigt/cmip6-acre-data/postprocessed/\"\n", + " _mod = _dtdt_int.attrs[\"source_id\"]\n", + " _exp = _dtdt_int.attrs[\"experiment_id\"]\n", + " _tab = _dtdt_int.attrs[\"table_id\"]\n", + " _out = _path+_varout+\"_\"+_tab+\"_\"+_mod+\"_\"+_exp+\".zarr\"\n", + " try:\n", + " shutil.rmtree(_out, ignore_errors=False, onerror=None)\n", + " except:\n", + " pass\n", + " _dtdt_int.to_zarr(_out)\n", + " print(_model, \"finished\")\n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "f62caf50-8ccc-4111-9788-f728966f9aeb", + "metadata": { + "tags": [] + }, + "source": [ + "## 1. GFDL-AM4\n", + "\n", + "Loads tntr data." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "424d54d5-71fd-47f8-8558-69600cf9e1f9", + "metadata": {}, + "outputs": [], + "source": [ + "exp=\"amip\"\n", + "tab=\"AERmon\"\n", + "flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab, mod=\"GFDL-AM4\")\n", + "ds_tntrs = cmip6radheating.load_data(flist_tntrs)[0]\n", + "ds_tntrl = cmip6radheating.load_data(flist_tntrl)[0]\n", + "\n", + "exp=\"amip\"\n", + "tab=\"Emon\"\n", + "flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab, mod=\"GFDL-AM4\")\n", + "ds_tntrscs = cmip6radheating.load_data(flist_tntrscs)[0]\n", + "ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs)[0]" + ] + }, + { + "cell_type": "markdown", + "id": "593e2885-7183-4c24-8bc0-48d0d64105e3", + "metadata": {}, + "source": [ + "Adds ps to tntr datasets." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "abfbff89-7798-483c-ad0e-3cc2dc06de22", + "metadata": {}, + "outputs": [], + "source": [ + "ds_ps = xr.open_dataset(path+\"/ps/Amon/ps_Amon_GFDL-AM4_amip_r1i1p1f1_gr1_198001-201412.nc\")\n", + "\n", + "ds_tntrs = xr.merge([ds_tntrs, ds_ps])\n", + "ds_tntrl = xr.merge([ds_tntrl, ds_ps])\n", + "ds_tntrscs = xr.merge([ds_tntrscs, ds_ps])\n", + "ds_tntrlcs = xr.merge([ds_tntrlcs, ds_ps])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6e488ad-26e6-4d6b-80d2-d1d540f67e1c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "GFDL-AM4 finished\n", + "GFDL-AM4 finished\n" + ] + } + ], + "source": [ + "compute_dtdt_from_tntr([ds_tntrs, ds_tntrl], [\"tntrs\", \"tntrl\"], \"dTdt-as-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrs], [\"tntrs\"], \"dTdts-as-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrl], [\"tntrl\"], \"dTdtl-as-from-tntr\")\n", + "\n", + "compute_dtdt_from_tntr([ds_tntrscs, ds_tntrlcs], [\"tntrscs\", \"tntrlcs\"], \"dTdt-cs-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrscs], [\"tntrscs\"], \"dTdts-cs-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrlcs], [\"tntrlcs\"], \"dTdtl-cs-from-tntr\")" + ] + }, + { + "cell_type": "markdown", + "id": "7bfecb0d-31c3-490a-96dd-3f9278b63e71", + "metadata": {}, + "source": [ + "## 2. GFDL-CM4\n", + "\n", + "Loads tntr data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8056c697-9af9-4f95-af87-a9d2ebd323ee", + "metadata": {}, + "outputs": [], + "source": [ + "exp=\"amip\"\n", + "tab=\"AERmon\"\n", + "flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab, mod=\"GFDL-CM4\")\n", + "ds_tntrs = cmip6radheating.load_data(flist_tntrs)[0]\n", + "ds_tntrl = cmip6radheating.load_data(flist_tntrl)[0]\n", + "\n", + "exp=\"amip\"\n", + "tab=\"Emon\"\n", + "flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab, mod=\"GFDL-CM4\")\n", + "ds_tntrscs = cmip6radheating.load_data(flist_tntrscs)[0]\n", + "ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs)[0]" + ] + }, + { + "cell_type": "markdown", + "id": "b2cd479a-77e0-487e-8dd1-a1d3870544d7", + "metadata": {}, + "source": [ + "Adds ps to tntr datasets." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88d221f4-b234-4a76-b4dd-bd45083293cf", + "metadata": {}, + "outputs": [], + "source": [ + "ds_ps = xr.open_mfdataset(path+\"/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_*01-*12.nc\")\n", + "\n", + "ds_tntrs = xr.merge([ds_tntrs, ds_ps])\n", + "ds_tntrl = xr.merge([ds_tntrl, ds_ps])\n", + "ds_tntrscs = xr.merge([ds_tntrscs, ds_ps])\n", + "ds_tntrlcs = xr.merge([ds_tntrlcs, ds_ps])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42b7ad41-8d96-4246-b787-37ea6f80f44b", + "metadata": {}, + "outputs": [], + "source": [ + "compute_dtdt_from_tntr([ds_tntrs, ds_tntrl], [\"tntrs\", \"tntrl\"], \"dTdt-as-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrs], [\"tntrs\"], \"dTdts-as-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrl], [\"tntrl\"], \"dTdtl-as-from-tntr\")\n", + "\n", + "compute_dtdt_from_tntr([ds_tntrscs, ds_tntrlcs], [\"tntrscs\", \"tntrlcs\"], \"dTdt-cs-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrscs], [\"tntrscs\"], \"dTdts-cs-from-tntr\")\n", + "compute_dtdt_from_tntr([ds_tntrlcs], [\"tntrlcs\"], \"dTdtl-cs-from-tntr\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/analysis/available_postprocessed_data.ipynb b/analysis/available_postprocessed_data.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..0ec4057fba194a60542be1de78ffec77a3fc40dd --- /dev/null +++ b/analysis/available_postprocessed_data.ipynb @@ -0,0 +1,151 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "55bd3a14-6f26-413b-b6b0-c821dab842f8", + "metadata": {}, + "source": [ + "# Obtain an overview over the available postprocessed data.\n", + "\n", + "Note: the availability of \"raw\" CMIP6 data is checked in model_data_matrx.ipynb." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "640c82c4-ca9a-4085-9b44-6e6d19d2d35c", + "metadata": {}, + "outputs": [], + "source": [ + "path = \"/scratch/das/avoigt/cmip6-acre-data/postprocessed/\"\n", + "\n", + "import os\n", + "\n", + "def available_models(var, exp):\n", + " modlist = list()\n", + " for dir in os.listdir(path):\n", + " if var in dir and exp+\".\" in dir:\n", + " modlist.append(dir.rsplit(\"_\")[2])\n", + " modlist = sorted(modlist)\n", + " print(\"Available models for\", var, exp, \":\", modlist)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "34ae7e87-c8d4-404e-9712-94d99cbcfe0b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available models for dTdt-as-from-flx amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MPI-ESM-1-2-HAM', 'MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-flx amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-flx amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n" + ] + } + ], + "source": [ + "for var in [\"dTdt-as-from-flx\", \"dTdt-cs-from-flx\"]:\n", + " for exp in [\"amip\", \"amip-p4K\", \"amip-future4K\"]:\n", + " available_models(var, exp)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d7b43e7b-9315-472c-8f30-210319c3315c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available models for dTdt-as-from-tntr amip : ['BCC-CSM2-MR', 'BCC-ESM1', 'CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'EC-Earth3', 'GFDL-AM4', 'GFDL-CM4', 'GFDL-ESM4', 'INM-CM4-8', 'INM-CM4-8', 'INM-CM5-0', 'INM-CM5-0', 'MIROC-ES2L', 'MPI-ESM-1-2-HAM', 'MPI-ESM-1-2-HAM', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr amip-p4K : ['BCC-CSM2-MR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr amip-future4K : []\n", + "Available models for dTdt-cs-from-tntr amip : ['CESM2', 'CESM2', 'CESM2-FV2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'EC-Earth3', 'GFDL-AM4', 'GFDL-CM4', 'GFDL-ESM4', 'IPSL-CM6A-LR', 'MIROC6']\n", + "Available models for dTdt-cs-from-tntr amip-p4K : ['CESM2', 'CNRM-CM6-1', 'MIROC6']\n", + "Available models for dTdt-cs-from-tntr amip-future4K : ['CESM2', 'CNRM-CM6-1']\n" + ] + } + ], + "source": [ + "for var in [\"dTdt-as-from-tntr\", \"dTdt-cs-from-tntr\"]:\n", + " for exp in [\"amip\", \"amip-p4K\", \"amip-future4K\"]:\n", + " available_models(var, exp)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "466b490f-20ea-407e-94d7-029fc09a6861", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available models for dTdt-as-from-flx aqua-control : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-flx aqua-p4K : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx aqua-control : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx aqua-p4K : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n" + ] + } + ], + "source": [ + "for var in [\"dTdt-as-from-flx\", \"dTdt-cs-from-flx\"]:\n", + " for exp in [\"aqua-control\", \"aqua-p4K\"]:\n", + " available_models(var, exp)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "de442bd3-3f68-43af-93f9-7f9687496f88", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available models for dTdt-as-from-tntr aqua-control : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr aqua-p4K : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-tntr aqua-control : ['CESM2', 'CNRM-CM6-1', 'MIROC6']\n", + "Available models for dTdt-cs-from-tntr aqua-p4K : ['CESM2', 'CNRM-CM6-1', 'MIROC6']\n" + ] + } + ], + "source": [ + "for var in [\"dTdt-as-from-tntr\", \"dTdt-cs-from-tntr\"]:\n", + " for exp in [\"aqua-control\", \"aqua-p4K\"]:\n", + " available_models(var, exp)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/analysis/batchcompute_cl.py b/analysis/batchcompute_cl.py new file mode 100644 index 0000000000000000000000000000000000000000..3541f39ed153d3246bd88e61d9116be2a7a765ef --- /dev/null +++ b/analysis/batchcompute_cl.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 batchcompute_cl.py amip Amon +# +# interpolate cloud fraction from model levels to pressure levels or height levels (for HadGEM and UK models) + +import warnings +warnings.simplefilter("ignore") + +import sys +args = sys.argv +# args[0]: name of the script +# args[1]: experiment, first argument passed in +# args[2]: table, second argument passed in +# etc. +exp=args[1] +tab=args[2] + +import cmip6radheating +from multiprocessing import Process + +# list of models for which we also have cloud-radiative heating rates +# we only calculate cloud cover for these models, but note that cloud +# cover is not available for all of these models +modlist=["BCC-CSM2-MR", "CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2", "CNRM-CM6-1", + "CNRM-ESM2-1", "EC-Earth3", "GFDL-AM4", "GFDL-CM4", "GFDL-ESM4", "HadGEM3-GC31-LL", + "HadGEM3-GC31-MM", "INM-CM4-8", "INM-CM5-0", "IPSL-CM6A-LR", "MIROC-ES2L", "MIROC6", + "MRI-ESM2-0", "UKESM1-0-LL"] + + +flist = [] +for mod in modlist: + templist = cmip6radheating.list_files(var="cl", tab=tab, exp=exp, mod=mod) + [flist.append(temp) for temp in templist] +ds_list = cmip6radheating.load_data(flist) + +print("The script will work on the following models:") +for aux in ds_list: + print(aux.attrs["source_id"]) +print("This mean a total number of models of ", len(ds_list)) + + +def compute_cl(_ds, _exp): + """ Interpolate cloud cover from model levels to pressure levels. + + input: _ds: a single cloud cover dataset + """ + import shutil + import traceback + import xarray as xr + + _model = _ds.attrs["source_id"] + try: + # special treatment for GFDL-AM4 and GFDL-CM4 --> need to add ps + if _model=="GFDL-AM4": + if _exp=="amip": + _ps=xr.open_mfdataset("/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/ps/Amon/ps_Amon_GFDL-AM4_amip_r1i1p1f1_gr1_198001-201412.nc") + _ds["ps"]=_ps["ps"] + if _model=="GFDL-CM4": + if exp=="amip": + _ps=xr.open_mfdataset("/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_*01-*12.nc") + _ds["ps"]=_ps["ps"] + if _exp=="amip-p4K": + _ps=xr.open_dataset("/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/ps/Amon/ps_Amon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc") + _ds["ps"]=_ps["ps"] + cmip6radheating.addpressure2dataset(_ds, model=_model, levtype="full") + # need special treatment for IPSL-CM6A-LR --> move from half to full levels + if _model=="IPSL-CM6A-LR": + _pres=0.5*(_ds["pres"].isel(lev=slice(0,79)).values + _ds["pres"].isel(lev=slice(1,80)).values) + _lev=_ds.lev[0:79] + _ds=_ds.drop(["lev","pres","ap","b","ap_bnds","b_bnds"]) + _ds["pres"] = xr.DataArray(_pres, name="pres", dims=("time", "lev", "lat", "lon"), + coords={"time": _ds.time, "lev": _lev , "lat": _ds.lat, "lon": _ds.lon}) + _levint = cmip6radheating.define_targetlevels() + _ds_int = cmip6radheating.interpolate2pressure(_ds, ["cl"], _levint) + # write interpolated cloud cover to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _ds_int.attrs["source_id"] + _exp = _ds_int.attrs["experiment_id"] + _tab = _ds_int.attrs["table_id"] + _out = _path+"/cl_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _ds_int.to_zarr(_out) + print(_model, "successfully calculated from model levels to pressure levels!") + except Exception as error: + print("---------------------------------------------------------") + print(_model, "cannot be calculated for model levels to pressure") + print(error) + traceback.print_exc() + print("---------------------------------------------------------") + + # special treatment of hadgem and uk models, which use height-based grid + if _model in ["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"]: + try: + _hgtint = cmip6radheating.define_targetlevels_hgt() + _ds_int = cmip6radheating.interpolate2height(_ds, ["cl"], _hgtint) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _ds_int.attrs["source_id"] + _exp = _ds_int.attrs["experiment_id"] + _tab = _ds_int.attrs["table_id"] + _out = _path+"/cl_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _ds_int.to_zarr(_out) + print(_model, "successfully calculated from model levels to height levels") + except Exception as error: + print("---------------------------------------------------------") + print(_model, "cannot be calculated for model height levels to height") + print(error) + traceback.print_exc() + print("---------------------------------------------------------") + + +processes = [Process(target=compute_cl, + args=(ds_list[i], exp),) for i in range(0, len(ds_list))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete diff --git a/analysis/batchcompute_dtdt-from-radflx.py b/analysis/batchcompute_dtdt-from-radflx.py new file mode 100644 index 0000000000000000000000000000000000000000..560103ece49e20d05e0004f928792af02147670a --- /dev/null +++ b/analysis/batchcompute_dtdt-from-radflx.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 batchcompute_dtdt-from-radflx.py amip CFmon + +import sys +args = sys.argv +# args[0]: name of the script +# args[1]: experiment, first argument passed in +# args[2]: table, second argument passed in +# etc. +exp=args[1] +tab=args[2] + +import cmip6radheating +from multiprocessing import Process + +flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=exp, tab=tab) +ds_rsd = cmip6radheating.load_data(flist_rsd) +ds_rsu = cmip6radheating.load_data(flist_rsu) +ds_rld = cmip6radheating.load_data(flist_rld) +ds_rlu = cmip6radheating.load_data(flist_rlu) + +flist_rsdcs, flist_rsucs, flist_rldcs, flist_rlucs = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab) +ds_rsdcs = cmip6radheating.load_data(flist_rsdcs) +ds_rsucs = cmip6radheating.load_data(flist_rsucs) +ds_rldcs = cmip6radheating.load_data(flist_rldcs) +ds_rlucs = cmip6radheating.load_data(flist_rlucs) + + +# below we loop over the function using multiprocessing +def compute_dtdt_from_flx(_ds_list, _var_list, _sign_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative flux. The net radiative + flux is calculated as the sum or difference of the input radiative fluxes. + + _ds_list: list of radiative flux datasets + _var_list: list of the variable names of the radiative fluxes in _ds_list + _sign_list: list of +-1 that defines whether a flux needs to be added or subtracted + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + # compute net radiative flux from the sum of input radiative fluxes + _ds_flx = cmip6radheating.add_radflx(_ds_list, _var_list, _sign_list) + try: + _ds_flx = cmip6radheating.addpressure2dataset(_ds_flx, model=_model, levtype="half") + _dtdt = cmip6radheating.compute_heatingrates_modellevels(_ds_flx) + _levint = cmip6radheating.define_targetlevels() + _dtdt_int = cmip6radheating.interpolate2pressure(_dtdt, ["dTdt"], _levint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + print(_model, "finished") + except: + print(_model, "cannot be calculated") + + +# all-sky radiative heating rate +processes = [Process(target=compute_dtdt_from_flx, + args=([ds_rsd[i], ds_rsu[i], ds_rld[i], ds_rlu[i]], + ["rsd", "rsu", "rld", "rlu"], [+1, -1, +1, -1], "dTdt-as-from-flx"),) for i in range(0, len(ds_rsd))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_flx, + args=([ds_rsd[i], ds_rsu[i]], + ["rsd", "rsu"], [+1, -1], "dTdts-as-from-flx"),) for i in range(0, len(ds_rsd))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_flx, + args=([ds_rld[i], ds_rlu[i]], + ["rld", "rlu"], [+1, -1], "dTdtl-as-from-flx"),) for i in range(0, len(ds_rsd))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + + +# clear-sky radiative heating rate +processes = [Process(target=compute_dtdt_from_flx, + args=([ds_rsdcs[i], ds_rsucs[i], ds_rldcs[i], ds_rlucs[i]], + ["rsdcs", "rsucs", "rldcs", "rlucs"], [+1, -1, +1, -1], "dTdt-cs-from-flx"),) for i in range(0, len(ds_rsdcs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_flx, + args=([ds_rsdcs[i], ds_rsucs[i]], + ["rsdcs", "rsucs"], [+1, -1], "dTdts-cs-from-flx"),) for i in range(0, len(ds_rsdcs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_flx, + args=([ds_rldcs[i], ds_rlucs[i]], + ["rldcs", "rlucs"], [+1, -1], "dTdtl-cs-from-flx"),) for i in range(0, len(ds_rsdcs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete \ No newline at end of file diff --git a/analysis/batchcompute_dtdt-from-radflx_repair_dTdts-cs-from-flx_CFmon_INM-CM5-0_amip.zarr.py b/analysis/batchcompute_dtdt-from-radflx_repair_dTdts-cs-from-flx_CFmon_INM-CM5-0_amip.zarr.py new file mode 100644 index 0000000000000000000000000000000000000000..c88d62756b768bc941f167247ed3a50ecb34bf79 --- /dev/null +++ b/analysis/batchcompute_dtdt-from-radflx_repair_dTdts-cs-from-flx_CFmon_INM-CM5-0_amip.zarr.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 batchcompute_dtdt-from-radflx.py amip CFmon + +import sys +#args = sys.argv +## args[0]: name of the script +## args[1]: experiment, first argument passed in +## args[2]: table, second argument passed in +## etc. +#exp=args[1] +#tab=args[2] + +exp="amip" +tab="CFmon" +mod="INM-CM5-0" + +import cmip6radheating +from multiprocessing import Process + +flist_rsdcs, flist_rsucs, _, _ = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsdcs = cmip6radheating.load_data(flist_rsdcs) +ds_rsucs = cmip6radheating.load_data(flist_rsucs) + +# below we loop over the function using multiprocessing +def compute_dtdt_from_flx(_ds_list, _var_list, _sign_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative flux. The net radiative + flux is calculated as the sum or difference of the input radiative fluxes. + + _ds_list: list of radiative flux datasets + _var_list: list of the variable names of the radiative fluxes in _ds_list + _sign_list: list of +-1 that defines whether a flux needs to be added or subtracted + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + # compute net radiative flux from the sum of input radiative fluxes + _ds_flx = cmip6radheating.add_radflx(_ds_list, _var_list, _sign_list) + try: + _ds_flx = cmip6radheating.addpressure2dataset(_ds_flx, model=_model, levtype="half") + _dtdt = cmip6radheating.compute_heatingrates_modellevels(_ds_flx) + _levint = cmip6radheating.define_targetlevels() + _dtdt_int = cmip6radheating.interpolate2pressure(_dtdt, ["dTdt"], _levint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + print(_model, "finished") + except: + print(_model, "cannot be calculated") + + +# clear-sky radiative heating rate +processes = [Process(target=compute_dtdt_from_flx, + args=([ds_rsdcs[i], ds_rsucs[i]], + ["rsdcs", "rsucs"], [+1, -1], "dTdts-cs-from-flx"),) for i in range(0, len(ds_rsdcs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete diff --git a/analysis/batchcompute_dtdt-from-tntr.py b/analysis/batchcompute_dtdt-from-tntr.py new file mode 100644 index 0000000000000000000000000000000000000000..9c39d26f52866dfe923ddef394a8955b096f267c --- /dev/null +++ b/analysis/batchcompute_dtdt-from-tntr.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 batchcompute_dtdt-from-tntr.py amip AERmon + +import warnings +warnings.simplefilter("ignore") + +import sys +args = sys.argv +# args[0]: name of the script +# args[1]: experiment, first argument passed in +# args[2]: table, second argument passed in +# etc. +exp=args[1] +tab=args[2] + +import cmip6radheating +from multiprocessing import Process + +flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab) +ds_tntrs = cmip6radheating.load_data(flist_tntrs) +ds_tntrl = cmip6radheating.load_data(flist_tntrl) + +flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab) +ds_tntrscs = cmip6radheating.load_data(flist_tntrscs) +ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs) + +# function that computes radiative heating rates +# below we loop over the function using multiprocessing +def compute_dtdt_from_tntr(_ds_list, _var_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative heating rate. The net radiative + heating rate is calculated as the sum of the input radiative heating rates. + + _ds_list: list of radiative heating rate datasets + _var_list: list of the variable names of the radiative heating rates in _ds_list + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + # compute net radiative heating rate from the sum of input radiative heating rates + _dtdt = cmip6radheating.add_heatingrate(_ds_list, _var_list) + try: + _dtdt = cmip6radheating.addpressure2dataset(_dtdt, model=_model, levtype="full") + _levint = cmip6radheating.define_targetlevels() + _dtdt_int = cmip6radheating.interpolate2pressure(_dtdt, ["dTdt"], _levint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + print(_model, "finished") + except: + print(_model, "cannot be calculated") + + +# all-sky radiative heating rate +processes = [Process(target=compute_dtdt_from_tntr, + args=([ds_tntrs[i], ds_tntrl[i]], + ["tntrs", "tntrl"], "dTdt-as-from-tntr"),) for i in range(0, len(ds_tntrs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr, + args=([ds_tntrs[i]], + ["tntrs"], "dTdts-as-from-tntr"),) for i in range(0, len(ds_tntrs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr, + args=([ds_tntrl[i]], + ["tntrl"], "dTdtl-as-from-tntr"),) for i in range(0, len(ds_tntrs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +# clear-sky radiative heating rate +processes = [Process(target=compute_dtdt_from_tntr, + args=([ds_tntrscs[i], ds_tntrlcs[i]], + ["tntrscs", "tntrlcs"], "dTdt-cs-from-tntr"),) for i in range(0, len(ds_tntrscs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr, + args=([ds_tntrscs[i]], + ["tntrscs"], "dTdts-cs-from-tntr"),) for i in range(0, len(ds_tntrscs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr, + args=([ds_tntrlcs[i]], + ["tntrlcs"], "dTdtl-cs-from-tntr"),) for i in range(0, len(ds_tntrscs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete \ No newline at end of file diff --git a/analysis/batchcompute_dtdt-from-tntr_EmonZ.py b/analysis/batchcompute_dtdt-from-tntr_EmonZ.py new file mode 100644 index 0000000000000000000000000000000000000000..99c75e5fcfb393e1c9a6a4f78cb4ed5b333e0a3f --- /dev/null +++ b/analysis/batchcompute_dtdt-from-tntr_EmonZ.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 batchcompute_dtdt-from-tntr_EmonZ.py amip + +import sys +args = sys.argv +# args[0]: name of the script +# args[1]: experiment, first argument passed in +exp=args[1] +tab="EmonZ" + +import warnings +warnings.simplefilter("ignore") + +import cmip6radheating +from multiprocessing import Process + +flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab) +ds_tntrs = cmip6radheating.load_data(flist_tntrs) +ds_tntrl = cmip6radheating.load_data(flist_tntrl) + +flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab) +ds_tntrscs = cmip6radheating.load_data(flist_tntrscs) +ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs) + +# function that computes radiative heating rates +# below we loop over the function using multiprocessing +def compute_dtdt_from_tntr_EmonZ(_ds_list, _var_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative heating rate. The net radiative + heating rate is calculated as the sum of the input radiative heating rates. + + _ds_list: list of radiative heating rate datasets + _var_list: list of the variable names of the radiative heating rates in _ds_list + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + _levint = cmip6radheating.define_targetlevels() + try: + # add pressure to datasets, note that EmonZ data is already on pressure levels + _ds_list_withlev = list() + for i in range(0, len(_ds_list)): + _ds = _ds_list[i] + _ds["pres"] = (_ds.plev + 0.0*_ds[_var_list[i]]).transpose("time", "plev", "lat").rename({"plev": "lev"}) + _ds_list_withlev.append(_ds) + # compute net radiative heating rate from the sum of input radiative heating rates + _dtdt = cmip6radheating.add_heatingrate_Z(_ds_list_withlev, _var_list) + # interpolate to new pressure levels + _dtdt_int = cmip6radheating.interpolate2pressure_Z(_dtdt, ["dTdt"], _levint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + print(_model, "finished") + except: + print(_model, "cannot be calculated") + + +# all-sky radiative heating rate +processes = [Process(target=compute_dtdt_from_tntr_EmonZ, + args=([ds_tntrs[i], ds_tntrl[i]], + ["tntrs", "tntrl"], "dTdt-as-from-tntr"),) for i in range(0, len(ds_tntrs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr_EmonZ, + args=([ds_tntrs[i]], + ["tntrs"], "dTdts-as-from-tntr"),) for i in range(0, len(ds_tntrs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr_EmonZ, + args=([ds_tntrl[i]], + ["tntrl"], "dTdtl-as-from-tntr"),) for i in range(0, len(ds_tntrs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +# clear-sky radiative heating rate +processes = [Process(target=compute_dtdt_from_tntr_EmonZ, + args=([ds_tntrscs[i], ds_tntrlcs[i]], + ["tntrscs", "tntrlcs"], "dTdt-cs-from-tntr"),) for i in range(0, len(ds_tntrscs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr_EmonZ, + args=([ds_tntrscs[i]], + ["tntrscs"], "dTdts-cs-from-tntr"),) for i in range(0, len(ds_tntrscs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete + +processes = [Process(target=compute_dtdt_from_tntr_EmonZ, + args=([ds_tntrlcs[i]], + ["tntrlcs"], "dTdtl-cs-from-tntr"),) for i in range(0, len(ds_tntrscs))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete \ No newline at end of file diff --git a/analysis/batchcompute_ta_Amon.py b/analysis/batchcompute_ta_Amon.py new file mode 100644 index 0000000000000000000000000000000000000000..60bc281a5ef9f59f17e6e1f5b738c94b46feb5c0 --- /dev/null +++ b/analysis/batchcompute_ta_Amon.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 batchcompute_ta_Amon.py amip + +import sys +args = sys.argv +# args[0]: name of the script +# args[1]: experiment, first argument passed in +# args[2]: table, second argument passed in +# etc. +exp=args[1] +tab="Amon" + +import warnings +warnings.simplefilter("ignore") + +import cmip6radheating +from multiprocessing import Process + +flist = cmip6radheating.filelist_ta(exp=exp, tab=tab) +ds = cmip6radheating.load_data(flist) + +# function that interpolates ta to pressure target levels, note that ta from Amon table +# is already on pressure levels +# below we loop over the function using multiprocessing +def interpolate_ta_Amon(_ds): + """ Interpolates temperature from Amon pressure levels to target pressure levels. + + _ds: input xarray dataset with ta + """ + import shutil + _model = _ds.attrs["source_id"] + _levint = cmip6radheating.define_targetlevels() + try: + # add pressure to datasets, note that EmonZ data is already on pressure levels + _ds["pres"] = (_ds.plev + 0.0*_ds["ta"]).transpose("time", "plev", "lat", "lon").rename({"plev": "lev"}) + # interpolate to new pressure levels + _ds_int = cmip6radheating.interpolate2pressure(_ds, ["ta"], _levint) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _ds_int.attrs["source_id"] + _exp = _ds_int.attrs["experiment_id"] + _tab = _ds_int.attrs["table_id"] + _out = _path+"ta_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _ds_int.to_zarr(_out) + print(_model, "finished") + except: + print(_model, "cannot be calculated") + + +processes = [Process(target=interpolate_ta_Amon, + args=(ds[i],)) for i in range(0, len(ds))] +for process in processes: process.start() # start all processes +for process in processes: process.join() # wait for all processes to complete \ No newline at end of file diff --git a/analysis/batchcompute_toa-sfc-cre-from-radflx.py b/analysis/batchcompute_toa-sfc-cre-from-radflx.py new file mode 100644 index 0000000000000000000000000000000000000000..beaa84d97fee59d978111e76b4e76f9a2fed2ba7 --- /dev/null +++ b/analysis/batchcompute_toa-sfc-cre-from-radflx.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# compute toa and sfc cloud-radiative effects from 3d radiative flux fields +# data is always from CFmon tab +# we consider exp amip, amip-p4K and amip-future4K +# +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 batchcompute_toa-sfc-cre-from-radflx.py + +import numpy as np +import cmip6radheating +from multiprocessing import Process + +# below we loop over the function using multiprocessing +def compute_toa_sfc_radflux_from_flx(_ds_list, _var_list, _sign_list, _varout): + """ Computes TOA and SFC radiative fluxes for a list of one or several data sets + that each contain a radiative flux. The net radiative + flux is calculated as the sum or difference of the input radiative fluxes. + + _ds_list: list of radiative flux datasets + _var_list: list of the variable names of the radiative fluxes in _ds_list + _sign_list: list of +-1 that defines whether a flux needs to be added or subtracted + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + # compute net radiative flux from the sum of input radiative fluxes + _ds_flx = cmip6radheating.add_radflx(_ds_list, _var_list, _sign_list).rename({"radflx": _varout}) + # figure out, which level is toa and which is sfc + _ilev_sfc = np.argmax(_ds_flx.lev.values) + _ilev_toa = np.argmin(_ds_flx.lev.values) + # manual treatment of _ilev_sfc and _ile_toa for models IPSL-CM6A-LR, HadGEM3-GC31-LL, HadGEM3-GC31-MM and UKESM1-0-LL + if _model == "IPSL-CM6A-LR": # lev is an index from 1 .. 79 + _ilev_sfc = np.argmin(_ds_flx.lev.values) + _ilev_toa = np.argmax(_ds_flx.lev.values) + if _model == "HadGEM3-GC31-LL" or _model == "HadGEM3-GC31-MM" or _model == "UKESM1-0-LL": # lev corresponds to height above surface + _ilev_sfc = np.argmin(_ds_flx.lev.values) + _ilev_toa = np.argmax(_ds_flx.lev.values) + # write toa and sfc flux to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _ds_flx.attrs["source_id"] + _exp = _ds_flx.attrs["experiment_id"] + _tab = _ds_flx.attrs["table_id"] + # toa + _out = _path+_varout+"t_"+_tab+"_"+_mod+"_"+_exp+".nc" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _ds_flx[_varout].isel(lev=_ilev_toa).rename(_varout+"t").to_netcdf(_out, mode="w") + # sfc + _out = _path+_varout+"s_"+_tab+"_"+_mod+"_"+_exp+".nc" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _ds_flx[_varout].isel(lev=_ilev_sfc).rename(_varout+"s").to_netcdf(_out, mode="w") + print(_model, "finished") + return + +tab="CFmon" + +# loop over experiments +for exp in["amip", "amip-p4K", "amip-future4K"]: + + flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=exp, tab=tab) + ds_rsd = cmip6radheating.load_data(flist_rsd) + ds_rsu = cmip6radheating.load_data(flist_rsu) + ds_rld = cmip6radheating.load_data(flist_rld) + ds_rlu = cmip6radheating.load_data(flist_rlu) + + flist_rsdcs, flist_rsucs, flist_rldcs, flist_rlucs = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab) + ds_rsdcs = cmip6radheating.load_data(flist_rsdcs) + ds_rsucs = cmip6radheating.load_data(flist_rsucs) + ds_rldcs = cmip6radheating.load_data(flist_rldcs) + ds_rlucs = cmip6radheating.load_data(flist_rlucs) + + # all-sky fluxes + processes = [Process(target=compute_toa_sfc_radflux_from_flx, + args=([ds_rsd[i], ds_rsu[i]], ["rsd" , "rsu"], [+1, -1], "rsn"),) for i in range(0, len(ds_rsd))] + for process in processes: process.start() + for process in processes: process.join() + processes = [Process(target=compute_toa_sfc_radflux_from_flx, + args=([ds_rld[i], ds_rlu[i]], ["rld" , "rlu"], [+1, -1], "rln"),) for i in range(0, len(ds_rld))] + for process in processes: process.start() + for process in processes: process.join() + + # clear-sky fluxes + processes = [Process(target=compute_toa_sfc_radflux_from_flx, + args=([ds_rsdcs[i], ds_rsucs[i]], ["rsdcs" , "rsucs"], [+1, -1], "rsncs"),) for i in range(0, len(ds_rsdcs))] + for process in processes: process.start() + for process in processes: process.join() + processes = [Process(target=compute_toa_sfc_radflux_from_flx, + args=([ds_rldcs[i], ds_rlucs[i]], ["rldcs" , "rlucs"], [+1, -1], "rlncs"),) for i in range(0, len(ds_rldcs))] + for process in processes: process.start() + for process in processes: process.join() \ No newline at end of file diff --git a/analysis/cmip6radheating.py b/analysis/cmip6radheating.py new file mode 100644 index 0000000000000000000000000000000000000000..8e5a0cac912a4e73f867cc1d5468a670ffd22ffa --- /dev/null +++ b/analysis/cmip6radheating.py @@ -0,0 +1,521 @@ +# target pressure levels + +def define_targetlevels(): + """ Defines the pressure levels for the interpolation. """ + import numpy as _np + return _np.arange(1000e2, 0, -10e2) + +#----------------------------------------------- + +def define_targetlevels_hgt(): + """ Defines the height levels for the interpolation. """ + import numpy as _np + return _np.arange(0,20e3,2e2) + +#----------------------------------------------- + +def addpressure2dataset(ds, model, levtype="half"): + """ Adds atmospheric pressure to the dataset for a given model. Pressure can be + for full levels or half levels, depending on levtype. + + Pressure is calculated based on surface pressure and model dependent parameters + of the vertical grid that are read from a separate netcdf file. + + The default is to add the pressure of half levels (i.e., for radiative fluexes). + To add pressure on full levels (i.e., for temperature and heating rates), + levtype needs to be set to "full". """ + + import numpy as np + import xarray as xr + + if model in ["UKESM1-0-LL", "HadGEM3-GC31-LL","HadGEM3-GC31-MM"]: # height based models + print("WARNING in addpressure2dataset: height based model, treated differently, air pressure not added", + "model:", model, flush=True) + return + + path = "/users/staff/avoigt/cmip6-crh/analysis/vgrid_information/" + + if levtype == "half": + ds_vgrid = xr.load_dataset(path+"/"+"vgrid_halflevels_"+model+".nc") + elif levtype =="full": + ds_vgrid = xr.load_dataset(path+"/"+"vgrid_fulllevels_"+model+".nc") + else: + print("WARNING in addpressure2dataset: levtype", levtype, "unknown, air pressure not added", flush=True) + + if model in ["CNRM-CM6-1", "CNRM-ESM2-1", "GFDL-AM4", "GFDL-CM4", + "IPSL-CM6A-LR", "MPI-ESM1-2-HR", "MPI-ESM1-2-LR", "MPI-ESM-1-2-HAM"]: + pres = ds_vgrid["ap"] + ds["ps"]*ds_vgrid["b"] + elif model in ["BCC-CSM2-MR", "BCC-ESM1", "CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2", "MIROC-ES2L", "MIROC6", "MRI-ESM2-0"]: + pres = ds_vgrid["a"]*ds_vgrid["p0"] + ds["ps"]*ds_vgrid["b"] + elif model in ["INM-CM4-8", "INM-CM5-0"]: + pres = ds_vgrid["ptop"] + ds_vgrid["lev"]*(ds["ps"] - ds_vgrid["ptop"]) + else: + print("WARNING in addpressure2dataset: model", model, "unknown, air pressure not added", flush=True) + + # add pressure to input dataset + pres = pres.transpose("time", "lev", "lat", "lon").values + ds["pres"] = xr.DataArray(pres, name="pres", dims=("time", "lev", "lat", "lon"), + coords={"time": ds.time, "lev": ds.lev, "lat": ds.lat, "lon": ds.lon}) + + return ds + +#----------------------------------------------- + +def interpolate2pressure(ds, varnames, lev_int): + """Interpolate data onto pressure levels using numpy interp. + + lev_int is the target pressure levels in Pa.""" + + import xarray as xr + import numpy as np + + # dimensions of input data + ntim = ds.time.size + nlat = ds.lat.size + nlon = ds.lon.size + + # output dataset with vertically interpolated 3d fields + ds_int = xr.Dataset() + ds_int.attrs = ds.attrs + + # compute datset once and load to local dataset + # this seems to increase performance, but I assume only matters when we use chunked arrays + _ds = ds.compute() + + # loop over requested variables + for varname in varnames: + var = _ds[varname].values + lev = _ds["pres"].values + var_int = np.zeros((ntim, lev_int.size, nlat, nlon)) + np.nan + for t in range(ntim): + for j in range(nlat): + for i in range(nlon): + var_int[t,:,j,i] = np.interp(lev_int[::-1], lev[t,::-1,j,i], var[t,::-1,j,i], + left=np.nan, right=np.nan)[::-1] + # convert varint into dataarray and add to dataset + da_varint = xr.DataArray(var_int, name=varname, dims=("time", "lev", "lat", "lon"), + coords={"time": ds.time, "lev": lev_int, "lat": ds.lat, "lon": ds.lon}) + ds_int[varname] = da_varint + + _ds.close() + + return ds_int + +#----------------------------------------------- + +def interpolate2pressure_Z(ds, varnames, lev_int): + """Interpolate data onto pressure levels using numpy interp. Input data is zonal mean, i.e. + has no longitude. This is indicated by the _Z in the function name. + + lev_int is the target pressure levels in Pa.""" + + import xarray as xr + import numpy as np + + # dimensions of input data + ntim = ds.time.size + nlat = ds.lat.size + + # output dataset with vertically interpolated 3d fields + ds_int = xr.Dataset() + ds_int.attrs = ds.attrs + + # compute datset once and load to local dataset + # this seems to increase performance, but I assume only matters when we use chunked arrays + _ds = ds.compute() + + # loop over requested variables + for varname in varnames: + var = _ds[varname].values + lev = _ds["pres"].values + var_int = np.zeros((ntim, lev_int.size, nlat)) + np.nan + for t in range(ntim): + for j in range(nlat): + var_int[t,:,j] = np.interp(lev_int[::-1], lev[t,::-1,j], var[t,::-1,j], + left=np.nan, right=np.nan)[::-1] + # convert varint into dataarray and add to dataset + da_varint = xr.DataArray(var_int, name=varname, dims=("time", "lev", "lat"), + coords={"time": ds.time, "lev": lev_int, "lat": ds.lat}) + ds_int[varname] = da_varint + _ds.close() + + return ds_int + +#----------------------------------------------- + +def interpolate2height(ds, varnames, hgt_int): + """Interpolate data onto height levels using numpy interp. + + hgt_int is the target height levels in m. + + Used for HadGEM3 and UKESM models.""" + + import xarray as xr + import numpy as np + + # dimensions of input data + ntim = ds.time.size + nlat = ds.lat.size + nlon = ds.lon.size + + # output dataset with vertically interpolated 3d fields + ds_int = xr.Dataset() + ds_int.attrs = ds.attrs + + # compute datset once and load to local dataset + # this seems to increase performance, but I assume only matters when we use chunked arrays + _ds = ds.compute() + + # loop over requested variables + for varname in varnames: + var = _ds[varname].values + var_int = np.zeros((ntim, hgt_int.size, nlat, nlon)) + np.nan + # if _ds["b"] and _ds["orog"] are time dependent: + try: + hgt = (_ds["lev"] + _ds["b"] * _ds["orog"]).transpose("time", "lev", "lat", "lon") + for t in range(ntim): + for j in range(nlat): + for i in range(nlon): + var_int[t,:,j,i] = np.interp(hgt_int, hgt[t,:,j,i], var[t,:,j,i], + left=np.nan, right=np.nan) + except: + pass + # if _ds["b"] and _ds["orog"] are not time dependent: + try: + hgt = (_ds["lev"] + _ds["b"] * _ds["orog"]).transpose("lev", "lat", "lon") + for t in range(ntim): + for j in range(nlat): + for i in range(nlon): + var_int[t,:,j,i] = np.interp(hgt_int, hgt[:,j,i], var[t,:,j,i], + left=np.nan, right=np.nan) + except: + pass + # convert varint into dataarray and add to dataset + da_varint = xr.DataArray(var_int, name=varname, dims=("time", "hgt", "lat", "lon"), + coords={"time": ds.time, "hgt": hgt_int, "lat": ds.lat, "lon": ds.lon}) + ds_int[varname] = da_varint + + _ds.close() + + return ds_int + +#----------------------------------------------- + +def compute_heatingrates_modellevels(ds): + """Derive radiative heating rates directly on model levels for a + radiative flux. The function assumes that the radiative flux is called "radflx". + + The function assumes that the input dataset ds contains the pressure + of the radiative fluxes as the variable pres in units of Pa. + + It is also important that the flux divergence is computed as a difference + between adjacent layers, and not as a higher-order gradient. This is achieved + by numpy.diff.""" + + import xarray as xr + import numpy as np + + # dimensions of input data + ntim = ds.time.size + nlev = ds["pres"][0,:,0,0].values.size + nlat = ds.lat.size + nlon = ds.lon.size + + _ds = ds.compute() + + # radiative fluxes + _radflx = _ds["radflx"].values + + # pressure levels of the radiative fluxes + _pres = _ds["pres"].values + + # compute heating rates + _hr = -86400 * 9.81/1005 * np.diff(_radflx, axis=1)/np.diff(_pres,axis=1) + + # pressure levels of heating rates is in the middle of those of the radiative fluxes + _pres_hr = 0.5*(_pres[:,1:,:,:]+_pres[:,0:nlev-1,:,:]) + + # output dataset with heating rates + ds_hr = xr.Dataset() + ds_hr.attrs = ds.attrs + + ds_hr["dTdt"] = xr.DataArray(_hr, name="dTdt", dims=("time", "lev", "lat", "lon"), + coords={"time": _ds.time, "lev": np.arange(0,nlev-1), "lat": _ds.lat, "lon": _ds.lon}) + ds_hr["pres"] = xr.DataArray(_pres_hr, name="pres_hr", dims=("time", "lev", "lat", "lon"), + coords={"time": _ds.time, "lev": np.arange(0,nlev-1), "lat": _ds.lat, "lon": _ds.lon}) + + return ds_hr + +#----------------------------------------------- + +def list_models(var="*",tab="*",exp="*",ripf="*"): + """ Returns all available models. Sister function to "list_files". + + Only criteria that are passed as arguments are used for filtering. + Other criteria are replaced by *.""" + import os + import fnmatch + import xarray as xr + path = "/scratch/das/avoigt/cmip6-acre-data/CMIP6/" + modlist = list() + for dirpath, dirs, files in os.walk(path): + for filename in fnmatch.filter(files,var+"_"+tab+"_*_"+exp+"_"+ripf+"_*.nc"): + fname = os.path.join(dirpath,filename) + # only add model name to list if file is intact + try: + xr.open_dataset(fname) + modlist.append(fname.rsplit("/")[-1].rsplit("_")[2]) + except: + pass + # remove duplicates + modlist=list(dict.fromkeys(modlist)) + return sorted(sorted(modlist), key=len) + +#----------------------------------------------- + +def list_files(mod="*", var="*", tab="*", exp="*", ripf="*"): + """ Returns a list of all intact files. + + The list can be constrained by specifying a model mod, variable var, table tab, experiment exp, and member ripf. """ + import os + import fnmatch + import xarray as xr + path = "/scratch/das/avoigt/cmip6-acre-data/CMIP6/" + f_list = list() + for dirpath, dirs, files in os.walk(path): + for filename in fnmatch.filter(files,var+"_"+tab+"_"+mod+"_"+exp+"_"+ripf+"_*.nc"): + fname = os.path.join(dirpath,filename) + # only add file to list if file is intact + try: + xr.open_dataset(fname) + f_list.append(fname) + except: + pass + return sorted(sorted(f_list), key=len) + +#----------------------------------------------- + +def filelist_allsky_radfluxes(exp, tab, mod="*"): + rsd = list_files(var="rsd", tab=tab, exp=exp, mod=mod) + rsu = list_files(var="rsu", tab=tab, exp=exp, mod=mod) + rld = list_files(var="rld", tab=tab, exp=exp, mod=mod) + rlu = list_files(var="rlu", tab=tab, exp=exp, mod=mod) + # find all files that hold all all-sky radiative fluxes + rsd = [x.replace("rsd", "VAR") for x in rsd] + rsu = [x.replace("rsu", "VAR") for x in rsu] + rld = [x.replace("rld", "VAR") for x in rld] + rlu = [x.replace("rlu", "VAR") for x in rlu] + # find all files that have all all-sky radiative fluxes + joint = list(set(rsd) & set(rsu) & set(rld) & set(rlu)) + # replace VAR again with actual variable name + rsd = [x.replace("VAR", "rsd") for x in joint] + rsu = [x.replace("VAR", "rsu") for x in joint] + rld = [x.replace("VAR", "rld") for x in joint] + rlu = [x.replace("VAR", "rlu") for x in joint] + return rsd, rsu, rld, rlu + +#----------------------------------------------- + +def filelist_clrsky_radfluxes(exp, tab, mod="*"): + rsdcs = list_files(var="rsdcs", tab=tab, exp=exp, mod=mod) + rsucs = list_files(var="rsucs", tab=tab, exp=exp, mod=mod) + rldcs = list_files(var="rldcs", tab=tab, exp=exp, mod=mod) + rlucs = list_files(var="rlucs", tab=tab, exp=exp, mod=mod) + # find all files that hold all clear-sky radiative fluxes + rsdcs = [x.replace("rsdcs", "VAR") for x in rsdcs] + rsucs = [x.replace("rsucs", "VAR") for x in rsucs] + rldcs = [x.replace("rldcs", "VAR") for x in rldcs] + rlucs = [x.replace("rlucs", "VAR") for x in rlucs] + # find all files that have all clear-sky radiative fluxes + joint = list(set(rsdcs) & set(rsucs) & set(rldcs) & set(rlucs)) + # replace VAR again with actual variable name + rsdcs = [x.replace("VAR", "rsdcs") for x in joint] + rsucs = [x.replace("VAR", "rsucs") for x in joint] + rldcs = [x.replace("VAR", "rldcs") for x in joint] + rlucs = [x.replace("VAR", "rlucs") for x in joint] + return rsdcs, rsucs, rldcs, rlucs + +#----------------------------------------------- + +def filelist_allsky_tntr(exp, tab, mod="*"): + tntrs = list_files(var="tntrs", tab=tab, exp=exp, mod=mod) + tntrl = list_files(var="tntrl", tab=tab, exp=exp, mod=mod) + # find all files that hold all all-sky radiative fluxes + tntrs = [x.replace("tntrs", "VAR") for x in tntrs] + tntrl = [x.replace("tntrl", "VAR") for x in tntrl] + # find all files that have all all-sky radiative fluxes + joint = list(set(tntrs) & set(tntrl)) + # replace VAR again with actual variable name + tntrs = [x.replace("VAR", "tntrs") for x in joint] + tntrl = [x.replace("VAR", "tntrl") for x in joint] + return tntrs, tntrl + +#----------------------------------------------- + +def filelist_allsky_tntronly(exp, tab, mod="*"): + tntr = list_files(var="tntr", tab=tab, exp=exp, mod=mod) + return tntr + +#----------------------------------------------- + +def filelist_clrsky_tntr(exp, tab, mod="*"): + tntrscs = list_files(var="tntrscs", tab=tab, exp=exp, mod=mod) + tntrlcs = list_files(var="tntrlcs", tab=tab, exp=exp, mod=mod) + # find all files that hold all clear-sky radiative fluxes + tntrscs = [x.replace("tntrscs", "VAR") for x in tntrscs] + tntrlcs = [x.replace("tntrlcs", "VAR") for x in tntrlcs] + # find all files that have all clear-sky radiative fluxes + joint = list(set(tntrscs) & set(tntrlcs)) + # replace VAR again with actual variable name + tntrscs = [x.replace("VAR", "tntrscs") for x in joint] + tntrlcs = [x.replace("VAR", "tntrlcs") for x in joint] + return tntrscs, tntrlcs + +#----------------------------------------------- + +def filelist_ta(exp, tab, mod="*"): + tntr = list_files(var="ta", tab=tab, exp=exp, mod=mod) + return tntr + +#----------------------------------------------- + +def load_data(flist): + import os + import fnmatch + import xarray as xr + path = "/scratch/das/avoigt/cmip6-acre-data/CMIP6/" + + # generate list of models from flist + modlist = list() + for f in flist: + modlist.append(f.rsplit("/")[-1].rsplit("_")[2]) + # remove duplicates + modlist=list(dict.fromkeys(modlist)) + + ds_list = list() + for mod in modlist: + # get all files for model mod + flist_mod = list() + # to distinguish model names such as CESM2 and CESM2-FV2, + # we need to require that "_"+mod+"_" is in file name, not just mod + [flist_mod.append(x) for x in flist if "_"+mod+"_" in x]; + + # screen for ripf number + ripf_list = list() + for file in flist_mod: + ripf = file.rsplit("/")[-1].rsplit("_")[4] + ripf_list.append(ripf) + # remove duplicates and sort so that r1i1p1f1 is first when available + ripf_list=list(dict.fromkeys(ripf_list)) + ripf_list=sorted(sorted(ripf_list), key=len) + + # load only files for the first ripf member + ripf = ripf_list[0] + flist_mod_ripf = list() + [flist_mod_ripf.append(x) for x in flist_mod if ripf in x]; + + # manual correction of date, e.g., for IPSL models + def correct_data(ds): + # need to rename level dimensions for IPSL models + try: + ds = ds.rename({'klev': 'lev'}) + except: + try: + ds = ds.rename({'klevp1': 'lev'}) + except: + pass + # need to correct sign of rldcs in IPSL-CM6A-LR + if ds.attrs["source_id"] == "IPSL-CM6A-LR": + try: + ds["rldcs"] = - 1*ds["rldcs"] + except: + pass + return ds + + try: + ds = xr.open_mfdataset(flist_mod_ripf) + ds = correct_data(ds) + ds_list.append(ds) + except: + print("Warning: cannot load data for model", mod, " and ripf", ripf, ";", flist_mod_ripf) + + return ds_list + +#----------------------------------------------- + +def add_radflx(ds_list, var_list, sign_list): + """ Adds radiative fluxes from the input datasets given by ds_list, with + the variable names given by var_list. The input list sign_list defines + whether a flux needs to be added (for downward fluxes) or subtracted + (for upward fluxes). + + Output is the radiative flux "radflx". """ + import xarray as xr + radflx = ds_list[0][var_list[0]] + for i in range(1, len(ds_list)): + radflx += sign_list[i]*ds_list[i][var_list[i]] + radflx.attrs["standard_name"] = "generic radiative flux" + radflx.attrs["long_name"] = "generic radiative flux" + radflx.attrs["comment"] = "generic radiative flux" + radflx.attrs["original_name"] = "generic radiative flux" + # make sure that sfc pressure etc is part of rad flux dataset + ds_flx = ds_list[0].copy(deep=True) + ds_flx["radflx"] = xr.DataArray(radflx, name="radflx", dims=("time", "lev", "lat", "lon"), + coords={"time": ds_list[0].time, "lev": ds_list[0].lev, + "lat": ds_list[0].lat, "lon": ds_list[0].lon}) + # only keep radflx variable and sfc pressure information + ds_flx = ds_flx.drop_vars(var_list[0]) + return ds_flx + +#----------------------------------------------- + +def add_heatingrate(ds_list, var_list): + """ Adds heating rates from the input datasets given by ds_list, with + the variable names given by var_list. + + Output is the heating rate "dTdt" in units of K/day. """ + import xarray as xr + # convert from units of K s-1 to K day-1 + dTdt = 86400*ds_list[0][var_list[0]] + for i in range(1, len(ds_list)): + dTdt += 86400*ds_list[i][var_list[i]] + dTdt.attrs["standard_name"] = "generic heating rate" + dTdt.attrs["long_name"] = "generic heating rate" + dTdt.attrs["comment"] = "generic heating rate" + dTdt.attrs["original_name"] = "generic heating rate" + dTdt.attrs["units"] = "K day-1" + # make sure that sfc pressure etc is part of heating rate dataset + ds_dTdt = ds_list[0].copy(deep=True) + ds_dTdt["dTdt"] = xr.DataArray(dTdt, name="dTdt", dims=("time", "lev", "lat", "lon"), + coords={"time": ds_list[0].time, "lev": ds_list[0].lev, + "lat": ds_list[0].lat, "lon": ds_list[0].lon}) + # only keep tntr variable and sfc pressure information + ds_dTdt = ds_dTdt.drop_vars(var_list[0]) + return ds_dTdt + +#----------------------------------------------- + +def add_heatingrate_Z(ds_list, var_list): + """ Adds heating rates from the input datasets given by ds_list, with + the variable names given by var_list. Input data is zonal mean, i.e. + has no longitude. This is indicated by the _Z in the function name. + + Output is the heating rate "dTdt" in units of K/day. """ + import xarray as xr + # convert from units of K s-1 to K day-1 + dTdt = 86400*ds_list[0][var_list[0]] + for i in range(1, len(ds_list)): + dTdt += 86400*ds_list[i][var_list[i]] + dTdt.attrs["standard_name"] = "generic heating rate" + dTdt.attrs["long_name"] = "generic heating rate" + dTdt.attrs["comment"] = "generic heating rate" + dTdt.attrs["original_name"] = "generic heating rate" + dTdt.attrs["units"] = "K day-1" + # make sure that sfc pressure etc is part of heating rate dataset + ds_dTdt = ds_list[0].copy(deep=True) + ds_dTdt["dTdt"] = xr.DataArray(dTdt, name="dTdt", dims=("time", "lev", "lat"), + coords={"time": ds_list[0].time, "lev": ds_list[0].lev, + "lat": ds_list[0].lat}) + # only keep tntr variable and sfc pressure information + ds_dTdt = ds_dTdt.drop_vars(var_list[0]) + return ds_dTdt \ No newline at end of file diff --git a/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-future4K_CFmon.py b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-future4K_CFmon.py new file mode 100644 index 0000000000000000000000000000000000000000..51bf5c7d6065b893897b1ece07a42b3eaa3ba7c4 --- /dev/null +++ b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-future4K_CFmon.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# coding: utf-8 + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-future4K_CFmon.py + +# # Postprocess heating rates for amip-future4K simulation of HadGEM3-GC31-LL model from radiative fluxes +# +# The HadGEM3-GC31-LL model is on height levels and we need to use the CMIP6-provided all-sky heating rate tntr to convert CFmon fluxes to heating rates. This is needed since the radiative flux files do not contain air density. + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating +import numpy as np +import xarray as xr + +# ### First load data. + +# We only consider the amip-future4K simulation and radiative fluxes from the CFmon table. + +exp="amip-future4K" +tab="CFmon" +mod="HadGEM3-GC31-LL" + +# Loads radiative fluxes. +flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsd = cmip6radheating.load_data(flist_rsd)[0] +ds_rsu = cmip6radheating.load_data(flist_rsu)[0] +ds_rld = cmip6radheating.load_data(flist_rld)[0] +ds_rlu = cmip6radheating.load_data(flist_rlu)[0] +flist_rsdcs, flist_rsucs, flist_rldcs, flist_rlucs = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsdcs = cmip6radheating.load_data(flist_rsdcs)[0] +ds_rsucs = cmip6radheating.load_data(flist_rsucs)[0] +ds_rldcs = cmip6radheating.load_data(flist_rldcs)[0] +ds_rlucs = cmip6radheating.load_data(flist_rlucs)[0] + +# Loads tntr, which we need for the conversion of flux divergence to heating rate. +flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) +ds_tntr = (cmip6radheating.load_data(flist_tntr)[0]) + +# Merges data into a single dataset. Radiative flux data is on levhalf, tntr on lev vertical grid. +ds_flx = ( xr.merge([ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs]). + drop_vars("orog").rename({"b": "bhalf", "lev": "levhalf"}) ) +ds = xr.merge([ds_flx, ds_tntr]) +del ds_flx, ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs, ds_tntr + + +# ### Introduce functions to convert fluxes to heating rates. + +def compute_flux_divergence(flx): + """Computes vertical divergence of input radiative flux flx on levhalf levels. Output is on lev levels.""" + flxdiv = flx.diff(dim="levhalf", n=1).rename({"levhalf": "lev"}) + flxdiv = xr.where(flxdiv==0.0, np.nan, flxdiv) + flxdiv = flxdiv.rename("flxdiv").assign_coords(lev=ds.lev) + return flxdiv + +def compute_conv_factor(ds): + """Computes conversion factor from flux divergence to heating rate from CMIP6 + provided tntr all-sky heating rate and derived all-sky flux divergence.""" + #all-sky radiative flux + asflx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") + # back out conversion factor as data array + conv = (ds["tntr"] / compute_flux_divergence(asflx)).rename("conv").assign_coords(lev=ds.lev).astype("float64") + del asflx + return conv + +def compute_dTdt_from_flx(flx, conv): + """Computes heating rate dTdt in K/day from input fields of radiative flux and conversion factor. + Output is an xarray data array.""" + flxdiv = compute_flux_divergence(flx) + dTdt = 86400*(conv * flxdiv).rename("dTdt") + # note: replace +-inf with nan + dTdt = xr.where(dTdt==+np.inf, np.nan, dTdt) + dTdt = xr.where(dTdt==-np.inf, np.nan, dTdt) + return dTdt + +# Computes conversion factor. +conv = compute_conv_factor(ds) + +# ### Now work through the radiative fluxes. +import shutil + +def compute_dTdt_save2zarr(radflx, conv, ds, varout): + """"Wrapper function to i) compute heating rate from input datarray radflx, ii) interpolate to height levels, + and iii) save to zarr store.""" + # i) compute heating rate + dTdt = xr.merge([compute_dTdt_from_flx(radflx, conv), ds.b, ds.orog]) + # ii) vertical interpolation + hgtint = cmip6radheating.define_targetlevels_hgt() # target heights + dTdt_int = cmip6radheating.interpolate2height(dTdt, ["dTdt"], hgtint).rename({"dTdt": varout}) + # iii) save to zarr store + path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + out = path+varout+"_CFmon_"+mod+"_"+exp+".zarr" + try: + shutil.rmtree(out, ignore_errors=False, onerror=None) + except: + pass + dTdt_int.to_zarr(out) + +# All-sky heating rates. + +flx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-as-from-flx") +del flx + +flx = (ds["rsd"]-ds["rsu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-as-from-flx") +del flx + +flx = (ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-as-from-flx") +del flx + +# Clear-sky heating rates. + +flx = (ds["rsdcs"]-ds["rsucs"]+ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-cs-from-flx") +del flx + +flx = (ds["rsdcs"]-ds["rsucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-cs-from-flx") +del flx + +flx = (ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-cs-from-flx") +del flx diff --git a/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-p4K_CFmon.py b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-p4K_CFmon.py new file mode 100644 index 0000000000000000000000000000000000000000..23cdf7d5be929e7229bbc052b5b980e61fb7ad08 --- /dev/null +++ b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-p4K_CFmon.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# coding: utf-8 + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_dtdt-from-flx_HadGEM3-GC31-LL_amip-p4K_CFmon.py + +# # Postprocess heating rates for amip-p4K simulation of HadGEM3-GC31-LL model from radiative fluxes +# +# The HadGEM3-GC31-LL model is on height levels and we need to use the CMIP6-provided all-sky heating rate tntr to convert CFmon fluxes to heating rates. This is needed since the radiative flux files do not contain air density. + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating +import numpy as np +import xarray as xr + +# ### First load data. + +# We only consider the amip-p4K simulation and radiative fluxes from the CFmon table. + +exp="amip-p4K" +tab="CFmon" +mod="HadGEM3-GC31-LL" + +# Loads radiative fluxes. +flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsd = cmip6radheating.load_data(flist_rsd)[0] +ds_rsu = cmip6radheating.load_data(flist_rsu)[0] +ds_rld = cmip6radheating.load_data(flist_rld)[0] +ds_rlu = cmip6radheating.load_data(flist_rlu)[0] +flist_rsdcs, flist_rsucs, flist_rldcs, flist_rlucs = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsdcs = cmip6radheating.load_data(flist_rsdcs)[0] +ds_rsucs = cmip6radheating.load_data(flist_rsucs)[0] +ds_rldcs = cmip6radheating.load_data(flist_rldcs)[0] +ds_rlucs = cmip6radheating.load_data(flist_rlucs)[0] + +# Loads tntr, which we need for the conversion of flux divergence to heating rate. +flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) +ds_tntr = (cmip6radheating.load_data(flist_tntr)[0]) + +# Merges data into a single dataset. Radiative flux data is on levhalf, tntr on lev vertical grid. +ds_flx = ( xr.merge([ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs]). + drop_vars("orog").rename({"b": "bhalf", "lev": "levhalf"}) ) +ds = xr.merge([ds_flx, ds_tntr]) +del ds_flx, ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs, ds_tntr + + +# ### Introduce functions to convert fluxes to heating rates. + +def compute_flux_divergence(flx): + """Computes vertical divergence of input radiative flux flx on levhalf levels. Output is on lev levels.""" + flxdiv = flx.diff(dim="levhalf", n=1).rename({"levhalf": "lev"}) + flxdiv = xr.where(flxdiv==0.0, np.nan, flxdiv) + flxdiv = flxdiv.rename("flxdiv").assign_coords(lev=ds.lev) + return flxdiv + +def compute_conv_factor(ds): + """Computes conversion factor from flux divergence to heating rate from CMIP6 + provided tntr all-sky heating rate and derived all-sky flux divergence.""" + #all-sky radiative flux + asflx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") + # back out conversion factor as data array + conv = (ds["tntr"] / compute_flux_divergence(asflx)).rename("conv").assign_coords(lev=ds.lev).astype("float64") + del asflx + return conv + +def compute_dTdt_from_flx(flx, conv): + """Computes heating rate dTdt in K/day from input fields of radiative flux and conversion factor. + Output is an xarray data array.""" + flxdiv = compute_flux_divergence(flx) + dTdt = 86400*(conv * flxdiv).rename("dTdt") + # note: replace +-inf with nan + dTdt = xr.where(dTdt==+np.inf, np.nan, dTdt) + dTdt = xr.where(dTdt==-np.inf, np.nan, dTdt) + return dTdt + +# Computes conversion factor. +conv = compute_conv_factor(ds) + +# ### Now work through the radiative fluxes. +import shutil + +def compute_dTdt_save2zarr(radflx, conv, ds, varout): + """"Wrapper function to i) compute heating rate from input datarray radflx, ii) interpolate to height levels, + and iii) save to zarr store.""" + # i) compute heating rate + dTdt = xr.merge([compute_dTdt_from_flx(radflx, conv), ds.b, ds.orog]) + # ii) vertical interpolation + hgtint = cmip6radheating.define_targetlevels_hgt() # target heights + dTdt_int = cmip6radheating.interpolate2height(dTdt, ["dTdt"], hgtint).rename({"dTdt": varout}) + # iii) save to zarr store + path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + out = path+varout+"_CFmon_"+mod+"_"+exp+".zarr" + try: + shutil.rmtree(out, ignore_errors=False, onerror=None) + except: + pass + dTdt_int.to_zarr(out) + +# All-sky heating rates. + +flx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-as-from-flx") +del flx + +flx = (ds["rsd"]-ds["rsu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-as-from-flx") +del flx + +flx = (ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-as-from-flx") +del flx + +# Clear-sky heating rates. + +flx = (ds["rsdcs"]-ds["rsucs"]+ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-cs-from-flx") +del flx + +flx = (ds["rsdcs"]-ds["rsucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-cs-from-flx") +del flx + +flx = (ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-cs-from-flx") +del flx diff --git a/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip_CFmon.py b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip_CFmon.py new file mode 100644 index 0000000000000000000000000000000000000000..f2332d6efbebcee6b93b0eccda7ec4da73f12fb8 --- /dev/null +++ b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-LL_amip_CFmon.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# coding: utf-8 + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_dtdt-from-flx_HadGEM3-GC31-LL_amip_CFmon.py + +# # Postprocess heating rates for amip simulation of HadGEM3-GC31-LL model from radiative fluxes +# +# The HadGEM3-GC31-LL model is on height levels and we need to use the CMIP6-provided all-sky heating rate tntr to convert CFmon fluxes to heating rates. This is needed since the radiative flux files do not contain air density. + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating +import numpy as np +import xarray as xr + +# ### First load data. + +# We only consider the amip simulation and radiative fluxes from the CFmon table. + +exp="amip" +tab="CFmon" +mod="HadGEM3-GC31-LL" + +# Loads radiative fluxes. +flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsd = cmip6radheating.load_data(flist_rsd)[0] +ds_rsu = cmip6radheating.load_data(flist_rsu)[0] +ds_rld = cmip6radheating.load_data(flist_rld)[0] +ds_rlu = cmip6radheating.load_data(flist_rlu)[0] +flist_rsdcs, flist_rsucs, flist_rldcs, flist_rlucs = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsdcs = cmip6radheating.load_data(flist_rsdcs)[0] +ds_rsucs = cmip6radheating.load_data(flist_rsucs)[0] +ds_rldcs = cmip6radheating.load_data(flist_rldcs)[0] +ds_rlucs = cmip6radheating.load_data(flist_rlucs)[0] + +# Loads tntr, which we need for the conversion of flux divergence to heating rate. +flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) +ds_tntr = (cmip6radheating.load_data(flist_tntr)[0]) + +# Merges data into a single dataset. Radiative flux data is on levhalf, tntr on lev vertical grid. +ds_flx = ( xr.merge([ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs]). + drop_vars("orog").rename({"b": "bhalf", "lev": "levhalf"}) ) +ds = xr.merge([ds_flx, ds_tntr]) +del ds_flx, ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs, ds_tntr + + +# ### Introduce functions to convert fluxes to heating rates. + +def compute_flux_divergence(flx): + """Computes vertical divergence of input radiative flux flx on levhalf levels. Output is on lev levels.""" + flxdiv = flx.diff(dim="levhalf", n=1).rename({"levhalf": "lev"}) + flxdiv = xr.where(flxdiv==0.0, np.nan, flxdiv) + flxdiv = flxdiv.rename("flxdiv").assign_coords(lev=ds.lev) + return flxdiv + +def compute_conv_factor(ds): + """Computes conversion factor from flux divergence to heating rate from CMIP6 + provided tntr all-sky heating rate and derived all-sky flux divergence.""" + #all-sky radiative flux + asflx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") + # back out conversion factor as data array + conv = (ds["tntr"] / compute_flux_divergence(asflx)).rename("conv").assign_coords(lev=ds.lev).astype("float64") + del asflx + return conv + +def compute_dTdt_from_flx(flx, conv): + """Computes heating rate dTdt in K/day from input fields of radiative flux and conversion factor. + Output is an xarray data array.""" + flxdiv = compute_flux_divergence(flx) + dTdt = 86400*(conv * flxdiv).rename("dTdt") + # note: replace +-inf with nan + dTdt = xr.where(dTdt==+np.inf, np.nan, dTdt) + dTdt = xr.where(dTdt==-np.inf, np.nan, dTdt) + return dTdt + +# Computes conversion factor. +conv = compute_conv_factor(ds) + +# ### Now work through the radiative fluxes. +import shutil + +def compute_dTdt_save2zarr(radflx, conv, ds, varout): + """"Wrapper function to i) compute heating rate from input datarray radflx, ii) interpolate to height levels, + and iii) save to zarr store.""" + # i) compute heating rate + dTdt = xr.merge([compute_dTdt_from_flx(radflx, conv), ds.b, ds.orog]) + # ii) vertical interpolation + hgtint = cmip6radheating.define_targetlevels_hgt() # target heights + dTdt_int = cmip6radheating.interpolate2height(dTdt, ["dTdt"], hgtint).rename({"dTdt": varout}) + # iii) save to zarr store + path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + out = path+varout+"_CFmon_"+mod+"_"+exp+".zarr" + try: + shutil.rmtree(out, ignore_errors=False, onerror=None) + except: + pass + dTdt_int.to_zarr(out) + +# All-sky heating rates. + +flx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-as-from-flx") +del flx + +flx = (ds["rsd"]-ds["rsu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-as-from-flx") +del flx + +flx = (ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-as-from-flx") +del flx + +# Clear-sky heating rates. + +flx = (ds["rsdcs"]-ds["rsucs"]+ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-cs-from-flx") +del flx + +flx = (ds["rsdcs"]-ds["rsucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-cs-from-flx") +del flx + +flx = (ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-cs-from-flx") +del flx diff --git a/analysis/compute_dtdt-from-flx_HadGEM3-GC31-MM_amip_CFmon.py b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-MM_amip_CFmon.py new file mode 100644 index 0000000000000000000000000000000000000000..d087467e8ce53ea376c38235ff332e462694fc86 --- /dev/null +++ b/analysis/compute_dtdt-from-flx_HadGEM3-GC31-MM_amip_CFmon.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# coding: utf-8 + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_dtdt-from-flx_HadGEM3-GC31-MM_amip_CFmon.py + +# # Postprocess heating rates for amip simulation of HadGEM3-GC31-MM model from radiative fluxes +# +# The HadGEM3-GC31-MM model is on height levels and we need to use the CMIP6-provided all-sky heating rate tntr to convert CFmon fluxes to heating rates. This is needed since the radiative flux files do not contain air density. + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating +import numpy as np +import xarray as xr + +# ### First load data. + +# We only consider the amip simulation and radiative fluxes from the CFmon table. + +exp="amip" +tab="CFmon" +mod="HadGEM3-GC31-MM" + +# Loads radiative fluxes. +flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsd = cmip6radheating.load_data(flist_rsd)[0] +ds_rsu = cmip6radheating.load_data(flist_rsu)[0] +ds_rld = cmip6radheating.load_data(flist_rld)[0] +ds_rlu = cmip6radheating.load_data(flist_rlu)[0] +flist_rsdcs, flist_rsucs, flist_rldcs, flist_rlucs = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsdcs = cmip6radheating.load_data(flist_rsdcs)[0] +ds_rsucs = cmip6radheating.load_data(flist_rsucs)[0] +ds_rldcs = cmip6radheating.load_data(flist_rldcs)[0] +ds_rlucs = cmip6radheating.load_data(flist_rlucs)[0] + +# Loads tntr, which we need for the conversion of flux divergence to heating rate. +flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) +ds_tntr = (cmip6radheating.load_data(flist_tntr)[0]) + +# Merges data into a single dataset. Radiative flux data is on levhalf, tntr on lev vertical grid. +ds_flx = ( xr.merge([ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs]). + drop_vars("orog").rename({"b": "bhalf", "lev": "levhalf"}) ) +ds = xr.merge([ds_flx, ds_tntr]) +del ds_flx, ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs, ds_tntr + + +# ### Introduce functions to convert fluxes to heating rates. + +def compute_flux_divergence(flx): + """Computes vertical divergence of input radiative flux flx on levhalf levels. Output is on lev levels.""" + flxdiv = flx.diff(dim="levhalf", n=1).rename({"levhalf": "lev"}) + flxdiv = xr.where(flxdiv==0.0, np.nan, flxdiv) + flxdiv = flxdiv.rename("flxdiv").assign_coords(lev=ds.lev) + return flxdiv + +def compute_conv_factor(ds): + """Computes conversion factor from flux divergence to heating rate from CMIP6 + provided tntr all-sky heating rate and derived all-sky flux divergence.""" + #all-sky radiative flux + asflx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") + # back out conversion factor as data array + conv = (ds["tntr"] / compute_flux_divergence(asflx)).rename("conv").assign_coords(lev=ds.lev).astype("float64") + del asflx + return conv + +def compute_dTdt_from_flx(flx, conv): + """Computes heating rate dTdt in K/day from input fields of radiative flux and conversion factor. + Output is an xarray data array.""" + flxdiv = compute_flux_divergence(flx) + dTdt = 86400*(conv * flxdiv).rename("dTdt") + # note: replace +-inf with nan + dTdt = xr.where(dTdt==+np.inf, np.nan, dTdt) + dTdt = xr.where(dTdt==-np.inf, np.nan, dTdt) + return dTdt + +# Computes conversion factor. +conv = compute_conv_factor(ds) + +# ### Now work through the radiative fluxes. +import shutil + +def compute_dTdt_save2zarr(radflx, conv, ds, varout): + """"Wrapper function to i) compute heating rate from input datarray radflx, ii) interpolate to height levels, + and iii) save to zarr store.""" + # i) compute heating rate + dTdt = xr.merge([compute_dTdt_from_flx(radflx, conv), ds.b, ds.orog]) + # ii) vertical interpolation + hgtint = cmip6radheating.define_targetlevels_hgt() # target heights + dTdt_int = cmip6radheating.interpolate2height(dTdt, ["dTdt"], hgtint).rename({"dTdt": varout}) + # iii) save to zarr store + path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + out = path+varout+"_CFmon_HadGEM3-GC31-MM_amip.zarr" + try: + shutil.rmtree(out, ignore_errors=False, onerror=None) + except: + pass + dTdt_int.to_zarr(out) + +# All-sky heating rates. + +flx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-as-from-flx") +del flx + +flx = (ds["rsd"]-ds["rsu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-as-from-flx") +del flx + +flx = (ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-as-from-flx") +del flx + +# Clear-sky heating rates. + +flx = (ds["rsdcs"]-ds["rsucs"]+ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-cs-from-flx") +del flx + +flx = (ds["rsdcs"]-ds["rsucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-cs-from-flx") +del flx + +flx = (ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-cs-from-flx") +del flx diff --git a/analysis/compute_dtdt-from-flx_UKESM1-0-LL_amip_CFmon.py b/analysis/compute_dtdt-from-flx_UKESM1-0-LL_amip_CFmon.py new file mode 100644 index 0000000000000000000000000000000000000000..ba90ceade0a489e26ed0d74502b7b16605d8c20e --- /dev/null +++ b/analysis/compute_dtdt-from-flx_UKESM1-0-LL_amip_CFmon.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# coding: utf-8 + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_dtdt-from-flx_UKESM1-0-LL_amip_CFmon.py + +# # Postprocess heating rates for amip simulation of UKESM1-0-LL model from radiative fluxes +# +# The UKESM1-0-LL model is on height levels and we need to use the CMIP6-provided all-sky heating rate tntr to convert CFmon fluxes to heating rates. This is needed since the radiative flux files do not contain air density. + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating +import numpy as np +import xarray as xr + +# ### First load data. + +# We only consider the amip simulation and radiative fluxes from the CFmon table. + +exp="amip" +tab="CFmon" +mod="UKESM1-0-LL" + +# Loads radiative fluxes. +flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsd = cmip6radheating.load_data(flist_rsd)[0] +ds_rsu = cmip6radheating.load_data(flist_rsu)[0] +ds_rld = cmip6radheating.load_data(flist_rld)[0] +ds_rlu = cmip6radheating.load_data(flist_rlu)[0] +flist_rsdcs, flist_rsucs, flist_rldcs, flist_rlucs = cmip6radheating.filelist_clrsky_radfluxes(exp=exp, tab=tab, mod=mod) +ds_rsdcs = cmip6radheating.load_data(flist_rsdcs)[0] +ds_rsucs = cmip6radheating.load_data(flist_rsucs)[0] +ds_rldcs = cmip6radheating.load_data(flist_rldcs)[0] +ds_rlucs = cmip6radheating.load_data(flist_rlucs)[0] + +# Loads tntr, which we need for the conversion of flux divergence to heating rate. +flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) +ds_tntr = (cmip6radheating.load_data(flist_tntr)[0]) + +# Merges data into a single dataset. Radiative flux data is on levhalf, tntr on lev vertical grid. +ds_flx = ( xr.merge([ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs]). + drop_vars("orog").rename({"b": "bhalf", "lev": "levhalf"}) ) +ds = xr.merge([ds_flx, ds_tntr]) +del ds_flx, ds_rsd, ds_rsu, ds_rld, ds_rlu, ds_rsdcs, ds_rsucs, ds_rldcs, ds_rlucs, ds_tntr + + +# ### Introduce functions to convert fluxes to heating rates. + +def compute_flux_divergence(flx): + """Computes vertical divergence of input radiative flux flx on levhalf levels. Output is on lev levels.""" + flxdiv = flx.diff(dim="levhalf", n=1).rename({"levhalf": "lev"}) + flxdiv = xr.where(flxdiv==0.0, np.nan, flxdiv) + flxdiv = flxdiv.rename("flxdiv").assign_coords(lev=ds.lev) + return flxdiv + +def compute_conv_factor(ds): + """Computes conversion factor from flux divergence to heating rate from CMIP6 + provided tntr all-sky heating rate and derived all-sky flux divergence.""" + #all-sky radiative flux + asflx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") + # back out conversion factor as data array + conv = (ds["tntr"] / compute_flux_divergence(asflx)).rename("conv").assign_coords(lev=ds.lev).astype("float64") + del asflx + return conv + +def compute_dTdt_from_flx(flx, conv): + """Computes heating rate dTdt in K/day from input fields of radiative flux and conversion factor. + Output is an xarray data array.""" + flxdiv = compute_flux_divergence(flx) + dTdt = 86400*(conv * flxdiv).rename("dTdt") + # note: replace +-inf with nan + dTdt = xr.where(dTdt==+np.inf, np.nan, dTdt) + dTdt = xr.where(dTdt==-np.inf, np.nan, dTdt) + return dTdt + +# Computes conversion factor. +conv = compute_conv_factor(ds) + +# ### Now work through the radiative fluxes. +import shutil + +def compute_dTdt_save2zarr(radflx, conv, ds, varout): + """"Wrapper function to i) compute heating rate from input datarray radflx, ii) interpolate to height levels, + and iii) save to zarr store.""" + # i) compute heating rate + dTdt = xr.merge([compute_dTdt_from_flx(radflx, conv), ds.b, ds.orog]) + # ii) vertical interpolation + hgtint = cmip6radheating.define_targetlevels_hgt() # target heights + dTdt_int = cmip6radheating.interpolate2height(dTdt, ["dTdt"], hgtint).rename({"dTdt": varout}) + # iii) save to zarr store + path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + out = path+varout+"_CFmon_"+mod+"_"+exp+".zarr" + try: + shutil.rmtree(out, ignore_errors=False, onerror=None) + except: + pass + dTdt_int.to_zarr(out) + +# All-sky heating rates. + +flx = (ds["rsd"]-ds["rsu"]+ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-as-from-flx") +del flx + +flx = (ds["rsd"]-ds["rsu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-as-from-flx") +del flx + +flx = (ds["rld"]-ds["rlu"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-as-from-flx") +del flx + +# Clear-sky heating rates. + +flx = (ds["rsdcs"]-ds["rsucs"]+ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdt-cs-from-flx") +del flx + +flx = (ds["rsdcs"]-ds["rsucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdts-cs-from-flx") +del flx + +flx = (ds["rldcs"]-ds["rlucs"]).rename("radflx") +compute_dTdt_save2zarr(flx, conv, ds, varout="dTdtl-cs-from-flx") +del flx diff --git a/analysis/compute_dtdt-from-tntr_Emon.ipynb b/analysis/compute_dtdt-from-tntr_Emon.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..1aa5e3399afd7ecbcedf1f02be64721f1203e897 --- /dev/null +++ b/analysis/compute_dtdt-from-tntr_Emon.ipynb @@ -0,0 +1,295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7e15340d-f472-429c-a32e-e0beda68edb6", + "metadata": {}, + "source": [ + "# Compute radiative heating rate from tntr variables for Emon table\n", + "\n", + "Emon is treated separately here from AERmon, for which batchcompute_dtdt-from-tntr.py can be used. One reason is that some model provide model level data for Emon, and others data interpolated to pressure levels. This can be cumbersome to handle in a general script." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7ff2e2ba-5e46-4568-9ef2-b789f6f19615", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "import cmip6radheating\n", + "from multiprocessing import Process\n", + "\n", + "import warnings\n", + "warnings.simplefilter(\"ignore\") " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "258ac97f-fe44-4887-bfaf-f9552b1eaf7c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Working on experiment amip\n", + "MPI-ESM-1-2-HAM cannot be calculated\n", + "MPI-ESM-1-2-HAM cannot be calculated\n", + "MPI-ESM-1-2-HAM cannot be calculated\n", + "IPSL-CM6A-LR early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CESM2-WACCM-FV2 early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: UKESM1-0-LL\n", + "UKESM1-0-LL cannot be calculated\n", + "GFDL-AM4 cannot be calculated\n", + "CESM2-FV2 finished\n", + "GFDL-CM4 finished\n", + "CNRM-CM6-1 finished\n", + "CNRM-ESM2-1 finished\n", + "CESM2 finished\n", + "CESM2-WACCM finished\n", + "IPSL-CM6A-LR early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CESM2-WACCM-FV2 early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: UKESM1-0-LL\n", + "UKESM1-0-LL cannot be calculated\n", + "GFDL-AM4 cannot be calculated\n", + "CESM2-FV2 finished\n", + "GFDL-CM4 finished\n", + "CNRM-ESM2-1 finished\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "CESM2-WACCM finished\n", + "IPSL-CM6A-LR early return without actually computationWARNING in addpressure2dataset: height based model, treated differently, air pressure not added\n", + " model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CESM2-WACCM-FV2 early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: UKESM1-0-LL\n", + "UKESM1-0-LL cannot be calculated\n", + "GFDL-AM4 cannot be calculated\n", + "CESM2-FV2 finished\n", + "CNRM-CM6-1 finished\n", + "CNRM-ESM2-1 finished\n", + "GFDL-CM4 finished\n", + "CESM2 finished\n", + "CESM2-WACCM finished\n", + "Working on experiment amip-p4K\n", + "IPSL-CM6A-LR early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "GFDL-CM4 cannot be calculated\n", + "CESM2 finished\n", + "CNRM-CM6-1 finished\n", + "IPSL-CM6A-LR early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "GFDL-CM4 cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "IPSL-CM6A-LR early return without actually computation\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "GFDL-CM4 cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "Working on experiment amip-future4K\n", + "IPSL-CM6A-LR cannot be calculated\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CESM2 finished\n", + "CNRM-CM6-1 finished\n", + "IPSL-CM6A-LR cannot be calculated\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "IPSL-CM6A-LR cannot be calculated\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "Working on experiment aqua-control\n", + "GFDL-CM4WARNING in addpressure2dataset: height based model, treated differently, air pressure not added cannot be calculated \n", + "model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "IPSL-CM6A-LR cannot be calculated\n", + "CESM2 finished\n", + "CNRM-CM6-1 finished\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added GFDL-CM4 model:cannot be calculated \n", + "HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "IPSL-CM6A-LR cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "GFDL-CM4WARNING in addpressure2dataset: height based model, treated differently, air pressure not added cannot be calculatedmodel:\n", + " HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "IPSL-CM6A-LR cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "Working on experiment aqua-p4K\n", + "IPSL-CM6A-LR cannot be calculated\n", + "GFDL-CM4 WARNING in addpressure2dataset: height based model, treated differently, air pressure not addedcannot be calculated \n", + "model: HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "IPSL-CM6A-LRcannot be calculated \n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not added model:GFDL-CM4 HadGEM3-GC31-LLcannot be calculated\n", + "\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CNRM-CM6-1 finished\n", + "CESM2 finished\n", + "IPSL-CM6A-LR cannot be calculated\n", + "WARNING in addpressure2dataset: height based model, treated differently, air pressure not addedGFDL-CM4 model: cannot be calculated\n", + "HadGEM3-GC31-LL\n", + "HadGEM3-GC31-LL cannot be calculated\n", + "CESM2 finished\n", + "CNRM-CM6-1 finished\n" + ] + } + ], + "source": [ + "# function that computes radiative heating rates\n", + "# below we loop over the function using multiprocessing\n", + "# adapted from compute_dtdt_from_tntr in batchcompute_dtdt-from-tntr.py\n", + "def compute_dtdt_from_tntr_Emon(_ds_list, _var_list, _varout):\n", + " \"\"\" Computes heating rates for a list of one or several data sets\n", + " that each contain a radiative heating rate. The net radiative \n", + " heating rate is calculated as the sum of the input radiative heating rates.\n", + " \n", + " _ds_list: list of radiative heating rate datasets\n", + " _var_list: list of the variable names of the radiative heating rates in _ds_list\n", + " \"\"\"\n", + " import shutil \n", + " _mod = _ds_list[0].attrs[\"source_id\"]\n", + " _exp = _ds_list[0].attrs[\"experiment_id\"]\n", + " \n", + " # for models that have faulty or difficult to handel data, return early\n", + " # we save the work to adapt the script for those models as their data\n", + " # is very likely already available from the other tables\n", + " if _exp == \"amip\":\n", + " if _mod == \"IPSL-CM6A-LR\" or _mod == \"CESM2-WACCM-FV2\":\n", + " print(_mod, \"early return without actually computation\")\n", + " return None \n", + " if _exp == \"amip-p4K\":\n", + " if _mod == \"IPSL-CM6A-LR\":\n", + " print(_mod, \"early return without actually computation\")\n", + " return None \n", + " \n", + " try:\n", + " # compute net radiative heating rate from the sum of input radiative heating rates\n", + " _dtdt = cmip6radheating.add_heatingrate(_ds_list, _var_list)\n", + " _dtdt = cmip6radheating.addpressure2dataset(_dtdt, model=_mod, levtype=\"full\")\n", + " _levint = cmip6radheating.define_targetlevels()\n", + " _dtdt_int = cmip6radheating.interpolate2pressure(_dtdt, [\"dTdt\"], _levint).rename({'dTdt': _varout})\n", + " # write interpolated heating rate to zarr store\n", + " _path = \"/scratch/das/avoigt/cmip6-acre-data/postprocessed/\"\n", + " _mod = _dtdt_int.attrs[\"source_id\"]\n", + " _exp = _dtdt_int.attrs[\"experiment_id\"]\n", + " _tab = _dtdt_int.attrs[\"table_id\"]\n", + " _out = _path+_varout+\"_\"+_tab+\"_\"+_mod+\"_\"+_exp+\".zarr\"\n", + " try:\n", + " shutil.rmtree(_out, ignore_errors=False, onerror=None)\n", + " except:\n", + " pass\n", + " _dtdt_int.to_zarr(_out)\n", + " print(_mod, \"finished\")\n", + " except:\n", + " print(_mod, \"cannot be calculated\")\n", + " \n", + " return None\n", + "\n", + "tab=\"Emon\"\n", + "\n", + "for exp in [\"amip\", \"amip-p4K\", \"amip-future4K\", \"aqua-control\", \"aqua-p4K\"]:\n", + " \n", + " print(\"Working on experiment\", exp)\n", + "\n", + " # all-sky radiative heating rate\n", + " flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab)\n", + " ds_tntrs = cmip6radheating.load_data(flist_tntrs)\n", + " ds_tntrl = cmip6radheating.load_data(flist_tntrl)\n", + " \n", + " processes = [Process(target=compute_dtdt_from_tntr_Emon, \n", + " args=([ds_tntrs[i], ds_tntrl[i]], \n", + " [\"tntrs\", \"tntrl\"], \"dTdt-as-from-tntr\"),) for i in range(0, len(ds_tntrs))]\n", + " for process in processes: process.start() # start all processes\n", + " for process in processes: process.join() # wait for all processes to complete\n", + " \n", + " processes = [Process(target=compute_dtdt_from_tntr_Emon, \n", + " args=([ds_tntrs[i]], \n", + " [\"tntrs\"], \"dTdts-as-from-tntr\"),) for i in range(0, len(ds_tntrs))]\n", + " for process in processes: process.start() # start all processes\n", + " for process in processes: process.join() # wait for all processes to complete\n", + " \n", + " processes = [Process(target=compute_dtdt_from_tntr_Emon, \n", + " args=([ds_tntrl[i]], \n", + " [\"tntrl\"], \"dTdtl-as-from-tntr\"),) for i in range(0, len(ds_tntrs))]\n", + " for process in processes: process.start() # start all processes\n", + " for process in processes: process.join() # wait for all processes to complete\n", + " \n", + " del ds_tntrs, ds_tntrl\n", + " \n", + " # clear-sky radiative heating rate\n", + " flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab)\n", + " ds_tntrscs = cmip6radheating.load_data(flist_tntrscs)\n", + " ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs)\n", + " \n", + " processes = [Process(target=compute_dtdt_from_tntr_Emon, \n", + " args=([ds_tntrscs[i], ds_tntrlcs[i]], \n", + " [\"tntrscs\", \"tntrlcs\"], \"dTdt-cs-from-tntr\"),) for i in range(0, len(ds_tntrscs))]\n", + " for process in processes: process.start() # start all processes\n", + " for process in processes: process.join() # wait for all processes to complete\n", + " \n", + " processes = [Process(target=compute_dtdt_from_tntr_Emon, \n", + " args=([ds_tntrscs[i]], \n", + " [\"tntrscs\"], \"dTdts-cs-from-tntr\"),) for i in range(0, len(ds_tntrscs))]\n", + " for process in processes: process.start() # start all processes\n", + " for process in processes: process.join() # wait for all processes to complete\n", + " \n", + " processes = [Process(target=compute_dtdt_from_tntr_Emon, \n", + " args=([ds_tntrlcs[i]], \n", + " [\"tntrlcs\"], \"dTdtl-cs-from-tntr\"),) for i in range(0, len(ds_tntrscs))]\n", + " for process in processes: process.start() # start all processes\n", + " for process in processes: process.join() # wait for all processes to complete \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b8eabf5a-4551-4a94-a834-21001af6be16", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/analysis/compute_dtdt-from-tntr_HadGEM3-GC31-LL_UKESM1-0-LL.py b/analysis/compute_dtdt-from-tntr_HadGEM3-GC31-LL_UKESM1-0-LL.py new file mode 100644 index 0000000000000000000000000000000000000000..12ce4eb9cc391e2d1db4a485c4e43283453378dd --- /dev/null +++ b/analysis/compute_dtdt-from-tntr_HadGEM3-GC31-LL_UKESM1-0-LL.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on IMG SRVX1, call the python script as: +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_dtdt-from-tntr_HadGEM3-GC31-LL_UKESM1-0-LL.py + +# # Postprocess heating rates for UK and HadGEM models, which are on height levels +# Models of interest: "HadGEM3-GC31-LL", "UKESM1-0-LL". + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating + +import numpy as np +import xarray as xr +import zarr + + +# Defines function that contains all steps to compute radiative heating rate from tntr variables. +def compute_dtdt_from_tntr(_ds_list, _var_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative heating rate. The net radiative + heating rate is calculated as the sum of the input radiative heating rates. + + _ds_list: list of radiative heating rate datasets + _var_list: list of the variable names of the radiative heating rates in _ds_list + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + # compute net radiative heating rate from the sum of input radiative heating rates + _dtdt = cmip6radheating.add_heatingrate(_ds_list, _var_list) + # height levels for interpolation + _hgtint = np.arange(0,20e3,2e2) + _dtdt_int = cmip6radheating.interpolate2height(_dtdt, ["dTdt"], _hgtint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + + +# Loops over experiments, tables and the two models. +for exp in ["amip", "amip-p4K", "amip-future4K", "aqua-control", "aqua-p4K"]: + for tab in ["AERmon", "Emon"]: + for mod in ["HadGEM3-GC31-LL", "UKESM1-0-LL"]: + # all-sky radiative heating + print("Working on all-sky radiative heating", exp, tab, mod) + flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, + tab=tab, mod=mod) + if len(flist_tntrs)>0 and len(flist_tntrl)>0: + ds_tntrs = (cmip6radheating.load_data(flist_tntrs)[0]) + ds_tntrl = (cmip6radheating.load_data(flist_tntrl)[0]) + compute_dtdt_from_tntr([ds_tntrs, ds_tntrl], ["tntrs", "tntrl"], + "dTdt-as-from-tntr") + compute_dtdt_from_tntr([ds_tntrs], ["tntrs"], "dTdts-as-from-tntr") + compute_dtdt_from_tntr([ds_tntrl], ["tntrl"], "dTdtl-as-from-tntr") + print("Finished all-sky computation for", exp, tab, mod) + else: + print("No all-sky data available for", exp, tab, mod, "; hence no computation done") + # clear-sky radiative heating + print("Working on clr-sky radiative heating", exp, tab, mod) + flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, + tab=tab, mod=mod) + if len(flist_tntrscs)>0 and len(flist_tntrlcs)>0: + ds_tntrscs = (cmip6radheating.load_data(flist_tntrscs)[0]) + ds_tntrlcs = (cmip6radheating.load_data(flist_tntrlcs)[0]) + compute_dtdt_from_tntr([ds_tntrscs, ds_tntrlcs], ["tntrscs", "tntrlcs"], + "dTdt-cs-from-tntr") + compute_dtdt_from_tntr([ds_tntrscs], ["tntrscs"], "dTdts-cs-from-tntr") + compute_dtdt_from_tntr([ds_tntrlcs], ["tntrlcs"], "dTdtl-cs-from-tntr") + print("Finished clr-sky computation for", exp, tab, mod) + else: + print("No clr-sky data available for", exp, tab, mod, "; hence no computation done") \ No newline at end of file diff --git a/analysis/compute_dtdt-from-tntr_HadGEM3-GC31-LL_amipp4K_amipfuture4K.py b/analysis/compute_dtdt-from-tntr_HadGEM3-GC31-LL_amipp4K_amipfuture4K.py new file mode 100644 index 0000000000000000000000000000000000000000..a154b3af37244bd76591ae166183460df8b6fb4c --- /dev/null +++ b/analysis/compute_dtdt-from-tntr_HadGEM3-GC31-LL_amipp4K_amipfuture4K.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# on IMG SRVX1, call the python script as: +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_dtdt-from-tntr_HadGEM3-GC31-LL_amipp4K_amipfuture4K.py + +# # Postprocess heating rates for HadGEM3-GC31-LL model, which is on height levels, +# for amip-p4K and amip-future4K simulations +# +# Special treatment is necessary because for this model and these simulations, the following data +# needs to be used: +# - tntr from CFmon +# - tntrlcs and tntrscs from Emon + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating + +import numpy as np +import xarray as xr +import zarr + + +# Defines function that contains all steps to compute radiative heating rate from tntr variables. +def compute_dtdt_from_tntr(_ds_list, _var_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative heating rate. The net radiative + heating rate is calculated as the sum of the input radiative heating rates. + + _ds_list: list of radiative heating rate datasets + _var_list: list of the variable names of the radiative heating rates in _ds_list + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + # compute net radiative heating rate from the sum of input radiative heating rates + _dtdt = cmip6radheating.add_heatingrate(_ds_list, _var_list) + # height levels for interpolation + _hgtint = np.arange(0,20e3,2e2) + _dtdt_int = cmip6radheating.interpolate2height(_dtdt, ["dTdt"], _hgtint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + + +mod="HadGEM3-GC31-LL" + +# Loops over experiments, tables and the two models. +for exp in ["amip-p4K", "amip-future4K"]: + # all-sky radiative heating + tab="CFmon" + print("Working on all-sky radiative heating", exp, tab, mod) + flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) + ds_tntr = (cmip6radheating.load_data(flist_tntr)[0]) + compute_dtdt_from_tntr([ds_tntr], ["tntr"], "dTdt-as-from-tntr") + print("Finished all-sky computation for", exp, tab, mod) + # clear-sky radiative heating + tab="Emon" + print("Working on clr-sky radiative heating", exp, tab, mod) + flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab, mod=mod) + if len(flist_tntrscs)>0 and len(flist_tntrlcs)>0: + ds_tntrscs = (cmip6radheating.load_data(flist_tntrscs)[0]) + ds_tntrlcs = (cmip6radheating.load_data(flist_tntrlcs)[0]) + compute_dtdt_from_tntr([ds_tntrscs, ds_tntrlcs], ["tntrscs", "tntrlcs"], + "dTdt-cs-from-tntr") + compute_dtdt_from_tntr([ds_tntrscs], ["tntrscs"], "dTdts-cs-from-tntr") + compute_dtdt_from_tntr([ds_tntrlcs], ["tntrlcs"], "dTdtl-cs-from-tntr") + print("Finished clr-sky computation for", exp, tab, mod) \ No newline at end of file diff --git a/analysis/compute_tntr_GFDL-CM4_amipp4K_amipfuture4K.py b/analysis/compute_tntr_GFDL-CM4_amipp4K_amipfuture4K.py new file mode 100644 index 0000000000000000000000000000000000000000..ac08e8d7e07701154f76b35353fd88a8ed4e7ea5 --- /dev/null +++ b/analysis/compute_tntr_GFDL-CM4_amipp4K_amipfuture4K.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python +# coding: utf-8 + +# # Manual treatment of GFDL-CM4 tntr data for amip-p4K and amip-future4K simulations +# on srvx1 of IMG UNIVIE call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 compute_tntr_GFDL-CM4_amipp4K_amipfuture4K.py + +path="/scratch/das/avoigt/cmip6-acre-data/CMIP6/" + +import sys +sys.path.append("/users/staff/avoigt/cmip-acre/analysis") +import cmip6radheating +import xarray as xr + + +# ## 0. Define functions to compute radiative heating rate from tntr, taken from batchcompute_dtdt-from-tntr.py + +# function that computes radiative heating rates +# below we loop over the function using multiprocessing +def compute_dtdt_from_tntr(_ds_list, _var_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative heating rate. The net radiative + heating rate is calculated as the sum of the input radiative heating rates. + + _ds_list: list of radiative heating rate datasets + _var_list: list of the variable names of the radiative heating rates in _ds_list + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + # compute net radiative heating rate from the sum of input radiative heating rates + _dtdt = cmip6radheating.add_heatingrate(_ds_list, _var_list) + _dtdt = cmip6radheating.addpressure2dataset(_dtdt, model=_model, levtype="full") + _levint = cmip6radheating.define_targetlevels() + _dtdt_int = cmip6radheating.interpolate2pressure(_dtdt, ["dTdt"], _levint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + print(_model, "finished") + +# function that computes radiative heating rates for EMonZ table data, , taken from batchcompute_dtdt-from-tntr_EmonZ.py +def compute_dtdt_from_tntr_EmonZ(_ds_list, _var_list, _varout): + """ Computes heating rates for a list of one or several data sets + that each contain a radiative heating rate. The net radiative + heating rate is calculated as the sum of the input radiative heating rates. + + _ds_list: list of radiative heating rate datasets + _var_list: list of the variable names of the radiative heating rates in _ds_list + """ + import shutil + _model = _ds_list[0].attrs["source_id"] + _levint = cmip6radheating.define_targetlevels() + try: + # add pressure to datasets, note that EmonZ data is already on pressure levels + _ds_list_withlev = list() + for i in range(0, len(_ds_list)): + _ds = _ds_list[i] + _ds["pres"] = (_ds.plev + 0.0*_ds[_var_list[i]]).transpose("time", "plev", "lat").rename({"plev": "lev"}) + _ds_list_withlev.append(_ds) + # compute net radiative heating rate from the sum of input radiative heating rates + _dtdt = cmip6radheating.add_heatingrate_Z(_ds_list_withlev, _var_list) + # interpolate to new pressure levels + _dtdt_int = cmip6radheating.interpolate2pressure_Z(_dtdt, ["dTdt"], _levint).rename({'dTdt': _varout}) + # write interpolated heating rate to zarr store + _path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + _mod = _dtdt_int.attrs["source_id"] + _exp = _dtdt_int.attrs["experiment_id"] + _tab = _dtdt_int.attrs["table_id"] + _out = _path+_varout+"_"+_tab+"_"+_mod+"_"+_exp+".zarr" + try: + shutil.rmtree(_out, ignore_errors=False, onerror=None) + except: + pass + _dtdt_int.to_zarr(_out) + print(_model, "finished") + except: + print(_model, "cannot be calculated") + + +## We are only workin on GFDL-CM4 model +mod="GFDL-CM4" + +# ## 1. amip-p4K +# * we use tntr from CFmon +# * we use tntrs and tntrl from AERmon +# * we use tntrscs and tntrlcs from Emon + +exp="amip-p4K" + +tab="CFmon" +flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) +ds_tntr = cmip6radheating.load_data(flist_tntr)[0] + +tab="AERmon" +flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab, mod=mod) +ds_tntrs = cmip6radheating.load_data(flist_tntrs)[0] +ds_tntrl = cmip6radheating.load_data(flist_tntrl)[0] + +tab="Emon" +flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab, mod=mod) +ds_tntrscs = cmip6radheating.load_data(flist_tntrscs)[0] +ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs)[0] + +# Adds ps to tntr datasets. +ds_ps = xr.open_dataset(path+"/amip-p4K/ps/Amon/ps_Amon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc") +ds_tntr = xr.merge([ds_tntr , ds_ps]) +ds_tntrs = xr.merge([ds_tntrs , ds_ps]) +ds_tntrl = xr.merge([ds_tntrl , ds_ps]) +ds_tntrscs = xr.merge([ds_tntrscs, ds_ps]) +ds_tntrlcs = xr.merge([ds_tntrlcs, ds_ps]) + +# compute radiative heating rates +compute_dtdt_from_tntr([ds_tntr], ["tntr"], "dTdt-as-from-tntr") + +compute_dtdt_from_tntr([ds_tntrs, ds_tntrl], ["tntrs", "tntrl"], "dTdt-as-from-tntr") +compute_dtdt_from_tntr([ds_tntrs], ["tntrs"], "dTdts-as-from-tntr") +compute_dtdt_from_tntr([ds_tntrl], ["tntrl"], "dTdtl-as-from-tntr") + +compute_dtdt_from_tntr([ds_tntrscs, ds_tntrlcs], ["tntrscs", "tntrlcs"], "dTdt-cs-from-tntr") +compute_dtdt_from_tntr([ds_tntrscs], ["tntrscs"], "dTdts-cs-from-tntr") +compute_dtdt_from_tntr([ds_tntrlcs], ["tntrlcs"], "dTdtl-cs-from-tntr") + +# clean up +del flist_tntr, flist_tntrs, flist_tntrl, flist_tntrscs, flist_tntrlcs +del ds_tntr, ds_tntrs, ds_tntrl, ds_tntrscs, ds_tntrlcs + + +# ## 2. amip-future4K +# * we use tntr from CFmon +# * we use tntrs, tntrscs, tntrl, tntrlcs from EmonZ, which are already on pressure levels + +exp="amip-future4K" + +tab="CFmon" +flist_tntr = cmip6radheating.filelist_allsky_tntronly(exp=exp, tab=tab, mod=mod) +ds_tntr = cmip6radheating.load_data(flist_tntr)[0] + +tab="EmonZ" +flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab, mod=mod) +ds_tntrs = cmip6radheating.load_data(flist_tntrs)[0] +ds_tntrl = cmip6radheating.load_data(flist_tntrl)[0] +flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab, mod=mod) +ds_tntrscs = cmip6radheating.load_data(flist_tntrscs)[0] +ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs)[0] + +# Adds ps to tntr datasets, only needed for tntr from CFmon table +ds_ps = xr.open_dataset(path+"/amip-future4K/ps/Amon/ps_Amon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc") +ds_tntr = xr.merge([ds_tntr , ds_ps]) + +# compute radiative heating rates +compute_dtdt_from_tntr([ds_tntr], ["tntr"], "dTdt-as-from-tntr") + +compute_dtdt_from_tntr_EmonZ([ds_tntrs, ds_tntrl], ["tntrs", "tntrl"], "dTdt-as-from-tntr") +compute_dtdt_from_tntr_EmonZ([ds_tntrs], ["tntrs"], "dTdts-as-from-tntr") +compute_dtdt_from_tntr_EmonZ([ds_tntrl], ["tntrl"], "dTdtl-as-from-tntr") + +compute_dtdt_from_tntr_EmonZ([ds_tntrscs, ds_tntrlcs], ["tntrscs", "tntrlcs"], "dTdt-cs-from-tntr") +compute_dtdt_from_tntr_EmonZ([ds_tntrscs], ["tntrscs"], "dTdts-cs-from-tntr") +compute_dtdt_from_tntr_EmonZ([ds_tntrlcs], ["tntrlcs"], "dTdtl-cs-from-tntr") diff --git a/analysis/compute_tropopause.ipynb b/analysis/compute_tropopause.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..a18153861a8a32b24ed30e08d64dddb9ff29482a --- /dev/null +++ b/analysis/compute_tropopause.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "55099610-27e4-4422-a0f5-9117e91d9434", + "metadata": {}, + "source": [ + "# Compute tropopause based on zonal-mean time-mean climatology of air temperature interpolated to set of common 100 pressure levels\n", + "\n", + "Data is assumed as zonal-mean time-mean climatology of ta and so is taken from postprocessed means, which on srvx1 of IMG UNIVIE are stored in /scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/.\n", + "\n", + "Tropopause calculation is done by means of PyTropD python package of Ori Adam et al.: https://tropd.github.io/pytropd/index.html, https://github.com/TropD/pytropd, https://gmd.copernicus.org/articles/11/4339/2018/. Function used is pytropd.TropD_Calculate_TropopauseHeight." + ] + }, + { + "cell_type": "markdown", + "id": "9bcf0e5d-a9f5-4888-8028-cade2c30971d", + "metadata": {}, + "source": [ + "Installs pytropd package if not yet available and loads futher required packages." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f6fc69ce-3c6b-4f87-ad79-fd124e6d83c5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Defaulting to user installation because normal site-packages is not writeable\n", + "Requirement already satisfied: pytropd in /mnt/users/staff/avoigt/.local/lib/python3.10/site-packages (2.12)\n", + "Requirement already satisfied: numpy>=1.19 in /home/swd/manual/nwp/2023.1/lib/python3.10/site-packages (from pytropd) (1.23.5)\n", + "Requirement already satisfied: scipy>=1.5 in /home/swd/manual/nwp/2023.1/lib/python3.10/site-packages (from pytropd) (1.10.0)\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install pytropd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6dbf6f83-5ada-4673-872d-d683004c5cf6", + "metadata": {}, + "outputs": [], + "source": [ + "import pytropd\n", + "import numpy as np\n", + "import xarray as xr\n", + "import zarr\n", + "import os\n", + "import shutil" + ] + }, + { + "cell_type": "markdown", + "id": "afecbd4d-acc7-41e2-9d4a-24e53a86f63b", + "metadata": {}, + "source": [ + "Directory in which climatological ta data is stored." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4aace642-baba-4b5b-b25e-ef2710ac3ac2", + "metadata": {}, + "outputs": [], + "source": [ + "path = \"/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/\"" + ] + }, + { + "cell_type": "markdown", + "id": "5bbf88a0-0786-46af-a4cc-dd6bb437a1d7", + "metadata": {}, + "source": [ + "Loops over all netcdf files that contain ta --> compute tropopause and store in netcdf file in directory given by path." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "725d9ebe-3f56-45e4-bf94-fad37f0ab5f1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_INM-CM5-0_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_INM-CM4-8_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_UKESM1-0-LL_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_HadGEM3-GC31-LL_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_IPSL-CM6A-LR_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CNRM-ESM2-1_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_MIROC-ES2L_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CNRM-CM6-1_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CESM2-FV2_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CESM2-WACCM-FV2_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_MIROC6_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_MRI-ESM2-0_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_GFDL-AM4_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_BCC-CSM2-MR_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_GFDL-CM4_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_GFDL-ESM4_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CESM2_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CESM2-WACCM_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_HadGEM3-GC31-MM_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_EC-Earth3_amip.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_IPSL-CM6A-LR_amip-p4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_HadGEM3-GC31-LL_amip-p4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CNRM-CM6-1_amip-p4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_MIROC6_amip-p4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_BCC-CSM2-MR_amip-p4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_MRI-ESM2-0_amip-p4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_GFDL-CM4_amip-p4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_IPSL-CM6A-LR_amip-future4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_HadGEM3-GC31-LL_amip-future4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_MIROC6_amip-future4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_CNRM-CM6-1_amip-future4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_BCC-CSM2-MR_amip-future4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_MRI-ESM2-0_amip-future4K.nc\n", + "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/tropop_Amon_GFDL-CM4_amip-future4K.nc\n" + ] + } + ], + "source": [ + "for ncfile in os.listdir(path):\n", + " fname=str(ncfile).split(\".\")[0]\n", + " if \".nc\" in str(ncfile) and \"ta_\" in str(ncfile):\n", + " fname=str(ncfile).split(\".\")[0]\n", + " # derive tab, mod and exp from file name\n", + " [_, tab, mod, exp] = fname.split(\"_\")\n", + " # open netcdf file as xarray dataset\n", + " ds = xr.open_dataset(path+\"/\"+ncfile)\n", + " # atmospheric temperature, lev needs to be last dimension\n", + " T = ds.ta.mean([\"month\", \"lon\"]).transpose(\"lat\", \"lev\").squeeze().values\n", + " # atmospheric pressure, needs to be in units of hPa\n", + " P = 0.01*ds.lev.values\n", + " trop = pytropd.TropD_Calculate_TropopauseHeight(T=T, P=P)\n", + " # store tropopause as netcdf file via xarray dataset functionality\n", + " da_tropo = xr.DataArray(trop, name=\"trop\", dims=(\"lat\"), coords={\"lat\": ds.lat})\n", + " # add attributes\n", + " da_tropo.attrs = ds.attrs \n", + " da_tropo.attrs[\"source_id\"] = mod\n", + " da_tropo.attrs[\"experiment_id\"] = exp\n", + " da_tropo.attrs[\"tab_id\"] = tab\n", + " da_tropo.attrs[\"description\"] = str(\"tropopause height in hPa calculated from time-mean zonal-mean air\"+\n", + " \" temperature using TropD_Calculate_TropopauseHeight of pytropd\")\n", + " out = path+\"tropop_\"+tab+\"_\"+mod+\"_\"+exp+\".nc\"\n", + " print(out)\n", + " try:\n", + " shutil.rmtree(out, ignore_errors=False, onerror=None)\n", + " except:\n", + " pass\n", + " da_tropo.to_netcdf(out)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/analysis/compute_zg_timemean-zonalmean_HadGEM-UKESM_amip_amipp4K_amipfuture4K.sh b/analysis/compute_zg_timemean-zonalmean_HadGEM-UKESM_amip_amipp4K_amipfuture4K.sh new file mode 100755 index 0000000000000000000000000000000000000000..6be654eb412791bec222e17f11652a8d294419fa --- /dev/null +++ b/analysis/compute_zg_timemean-zonalmean_HadGEM-UKESM_amip_amipp4K_amipfuture4K.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Compute climatology of time-mean zonal-mean zg from Amon table for HadGEM and UKESM models for +# amip, amip-p4K and amip-future4K simulations an +# on srvx1 of IMG UNIVIE call as +# ./compute_zg_timemean-zonalmean_HadGEM-UKESM_amip_amipp4K_amipfuture4K.sh + +module load cdo + +datadir="/scratch/das/avoigt/cmip6-acre-data/CMIP6/" +outdir="/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/" +scriptdir="/users/staff/avoigt/cmip6-crh/analysis" + +echo "Moving into data directory" +cd $datadir + +echo "1st step: working on amip" +cd amip/zg/Amon + +cdo -zonmean -timmean -yearmonmean -selyear,1980/2014 zg_Amon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-201412.nc ${outdir}/zg_Amon_HadGEM3-GC31-LL_amip.timmean.zonmean.nc +cdo -zonmean -timmean -yearmonmean -selyear,1980/2014 -mergetime zg_Amon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-198912.nc zg_Amon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_199001-200912.nc zg_Amon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_201001-201412.nc ${outdir}/zg_Amon_HadGEM3-GC31-MM_amip.timmean.zonmean.nc +cdo -zonmean -timmean -yearmonmean -selyear,1980/2014 zg_Amon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-201412.nc ${outdir}/zg_Amon_UKESM1-0-LL_amip.timmean.zonmean.nc + +echo "2nd step: working on amip-p4K" +cd ${datadir}/amip-p4K/zg/Amon +cdo -zonmean -timmean -yearmonmean -selyear,1980/2014 -mergetime zg_Amon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-201412.nc ${outdir}/zg_Amon_HadGEM3-GC31-LL_amip-p4K.timmean.zonmean.nc + +echo "3rd step: working on amip-future4K" +cd ${datadir}/amip-future4K/zg/Amon +cdo -zonmean -timmean -yearmonmean -selyear,1980/2014 -mergetime zg_Amon_HadGEM3-GC31-LL_amip-future4K_r5i1p1f3_gn_197901-201412.nc ${outdir}/zg_Amon_HadGEM3-GC31-LL_amip-future4K.timmean.zonmean.nc + +echo "Moving back to script directory" +cd $scriptdir diff --git a/analysis/get_vgrid_information.py b/analysis/get_vgrid_information.py new file mode 100644 index 0000000000000000000000000000000000000000..83767f1c5282bf7abba447be4a591836fae72ef8 --- /dev/null +++ b/analysis/get_vgrid_information.py @@ -0,0 +1,164 @@ +# Obtain vertical grid information and store in separate netcdf file for later use + +import numpy as np +import xarray as xr + +path = "/users/staff/avoigt/cmip6-crh/analysis/vgrid_information/" + +def vgrid_halflevels(ds): + """ Stores halflevel information for later use. + + Note: requires python >=3.10 because of the match construct. + + Further notes: + - the HadGEM, UKESM and KACE models use height levels, this requires special treatment and is not covered here """ + + mod = ds.attrs["source_id"] # model name + var = ds.attrs["variable_id"] # variable name + + if not var in ["rsd", "rsu", "rld", "rlu", "rsdcs", "rsucs", "rldcs", "rlucs"]: + print("WARNING: vgrid_halflevels requires radiative fluxes inside the atmosphere!") + print("WARNING: Because these are not in the input data set, the function will return no vgrid information!") + return + + # for some models it is necessary to remove time axis + def remove_time(ds): + if "time" in ds.dims: + ds=ds.isel(time=0).squeeze() + return ds + + if "HadGEM" in mod or "UKESM" in mod or "KACE" in mod: + print("vgrid_halflevels: model", mod, "is height based and needs special treatment") + raise exception + + match mod: + case "AWI-ESM-1-1-LR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "BCC-CSM2-MR": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "CNRM-CM6-1": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "CNRM-ESM2-1": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "INM-CM4-8": + remove_time(ds[["ptop", "lev"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "INM-CM5-0": + remove_time(ds[["ptop", "lev"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "IPSL-CM5A2-INCA": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "IPSL-CM6A-LR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "IPSL-CM6A-LR-INCA": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "MIROC-ES2H": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "MIROC-ES2L": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "MIROC6": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "MPI-ESM-1-2-HAM": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "MPI-ESM1-2-HR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "MPI-ESM1-2-LR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "MRI-ESM2-0": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case "GFDL-CM4": + ds = remove_time(ds) + ap = np.zeros(34) + np.nan + b = np.zeros(34) + np.nan + ap[0:33] = ds["ap_bnds"].values[0:33,0] + ap[33] = ds["ap_bnds"].values[32,1] + b[0:33] = ds["b_bnds" ].values[0:33,0] + b [33] = ds["b_bnds"] .values[32,1] + ds_vgrid = xr.Dataset() + ds_vgrid.attrs = ds.attrs + ds_vgrid["ap"] = xr.DataArray(ap, name="ap", dims=("lev"), coords={"lev": np.arange(0,34)}) + ds_vgrid["b" ] = xr.DataArray(b , name="b" , dims=("lev"), coords={"lev": np.arange(0,34)}) + ds_vgrid.to_netcdf(path+"vgrid_halflevels_"+mod+".nc") + case other: + print("vgrid_fulllevels, model not known", mod) + raise exception + + +def vgrid_fulllevels(ds): + """ Stores fulllevel information for later use. Sister function to vgrid_halflevels. + + Note: requires python >=3.10 because of the match construct. + + Further notes: + - the HadGEM, UKESM and KACE models use height levels, this requires special + treatment and is not covered here """ + + mod = ds.attrs["source_id"] # model name + var = ds.attrs["variable_id"] # variable name + + if not var in ["tntr", "tntrs", "tntrl", "tntrscs", "tntrlcs"]: + print("WARNING: vgrid_fulllevels requires radiative heating rates inside the atmosphere!") + print("WARNING: Because these are not in the input data set,", + "the function will return no vgrid information!") + return + + # for some models it is necessary to remove time axis + def remove_time(ds): + if "time" in ds.dims: + ds=ds.isel(time=0).squeeze() + return ds + + if "HadGEM" in mod or "UKESM" in mod or "KACE" in mod: + print("vgrid_fulllevels: model", mod, "is height based and needs special treatment") + raise exception + + match mod: + case "AWI-ESM-1-1-LR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "BCC-CSM2-MR": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "BCC-ESM1": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "BCC-ESM1": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "CESM2": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "CESM2-FV2": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "CESM2-WACCM": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "CESM2-WACCM-FV2": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "CNRM-CM6-1": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "CNRM-ESM2-1": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "GFDL-AM4": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "GFDL-CM4": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "INM-CM4-8": + remove_time(ds[["ptop", "lev"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "INM-CM5-0": + remove_time(ds[["ptop", "lev"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "IPSL-CM5A2-INCA": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "IPSL-CM6A-LR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "IPSL-CM6A-LR-INCA": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "MIROC-ES2H": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "MIROC-ES2L": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "MIROC6": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "MPI-ESM-1-2-HAM": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "MPI-ESM1-2-HR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "MPI-ESM1-2-LR": + remove_time(ds[["ap", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case "MRI-ESM2-0": + remove_time(ds[["a", "p0", "b"]]).to_netcdf(path+"vgrid_fulllevels_"+mod+".nc") + case other: + print("vgrid_fulllevels, model not known", mod) + raise exception \ No newline at end of file diff --git a/analysis/make_mean_data.py b/analysis/make_mean_data.py new file mode 100644 index 0000000000000000000000000000000000000000..35aed5e19e1fb75759c7ca4dacc0d4962d027ed7 --- /dev/null +++ b/analysis/make_mean_data.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# Make climatological means over zarr stores of postprocessed data +# +# on srvx1 of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_mean_data.py + +import xarray as xr +import os +import subprocess + +def removefirst12months(ds): + """Removes the first 12 months of a dataset.""" + ntim = ds.time.size + ds = ds.isel(time=slice(12, ntim)) + return ds + +# directory of zarr stores for which mean is computed +path="/scratch/das/avoigt/cmip6-acre-data/postprocessed/" + +# location of computes means +path_mean=path+"/mean/" + +# create directory for means if it does not already exist +subprocess.run(["mkdir", "-p", path_mean]) + +# switches to only process part of the data +lzarr=False +lnetcdf=False +lzarr_cl=True + +# loop over all zarr stores +if lzarr: + for zstore in os.listdir(path): + if ".zarr" in str(zstore): + try: + fname=str(zstore).split(".")[0] + ds = xr.open_dataset(path+"/"+zstore, chunks="auto", engine="zarr") + ds = removefirst12months(ds) + ds_clim = ds.groupby("time.month").mean("time") + # set time axis + ds_clim["time"] = ds.time[0:12] + # include first and time step that enters the climatology as dataset attributes + ds_clim.attrs["firstimestep"] = str(ds.time[0].values) + ds_clim.attrs["lasttimestep"] = str(ds.time[-1].values) + # output netcdf file name + ncout = path_mean+"/"+fname+".ymonmean.nc" + # remove ncout if it already exists, needed as otherwise nc write operation might fail in unpredictable manner + subprocess.run(["rm", "-f", ncout]) + ds_clim.to_netcdf(ncout, mode="w") + except: + print("Mean operation failed for:", zstore) + pass + +# loop over all netcdf files +if lnetcdf: + for ncfile in os.listdir(path): + if ".nc" in str(ncfile): + try: + fname=str(ncfile).split(".")[0] + ds = xr.open_dataset(path+"/"+ncfile) + ds = removefirst12months(ds) + ds_clim = ds.groupby("time.month").mean("time") + # set time axis + ds_clim["time"] = ds.time[0:12] + # include first and time step that enters the climatology as dataset attributes + ds_clim.attrs["firstimestep"] = str(ds.time[0].values) + ds_clim.attrs["lasttimestep"] = str(ds.time[-1].values) + # output netcdf file name + ncout = path_mean+"/"+fname+".ymonmean.nc" + # remove ncout if it already exists, needed as otherwise nc write operation might fail in unpredictable manner + subprocess.run(["rm", "-f", ncout]) + ds_clim.to_netcdf(ncout, mode="w") + except: + print("Mean operation failed for:", ncfile) + pass + +# loop over all zarr stores with cloud fraction data +if lzarr_cl: + for zstore in os.listdir(path): + if "cl_Amon" in str(zstore) and ".zarr" in str(zstore): + try: + fname=str(zstore).split(".")[0] + ds = xr.open_dataset(path+"/"+zstore, chunks="auto", engine="zarr") + ds = removefirst12months(ds) + ds_clim = ds.groupby("time.month").mean("time") + # set time axis + ds_clim["time"] = ds.time[0:12] + # include first and time step that enters the climatology as dataset attributes + ds_clim.attrs["firstimestep"] = str(ds.time[0].values) + ds_clim.attrs["lasttimestep"] = str(ds.time[-1].values) + # output netcdf file name + ncout = path_mean+"/"+fname+".ymonmean.nc" + # remove ncout if it already exists, needed as otherwise nc write operation might fail in unpredictable manner + subprocess.run(["rm", "-f", ncout]) + ds_clim.to_netcdf(ncout, mode="w") + except: + print("Mean operation failed for:", zstore) + pass diff --git a/analysis/model_data_matrix.ipynb b/analysis/model_data_matrix.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..15f224844002ebab31bead9c6ff5c22a93b91ef2 --- /dev/null +++ b/analysis/model_data_matrix.ipynb @@ -0,0 +1,612 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2a39f5a3-6a97-46aa-94e3-6fb15617039d", + "metadata": {}, + "source": [ + "# Model-data matrix\n", + "\n", + "Creates an xarray-dataarray matrix that encodes availability of data as a function of model, variable, experiment and table. The matrix is based on the \"raw\" CMIP6 data, this allows one to check whether there is raw data that still needs to be postprocessed.\n", + "\n", + "* 1: data available and intact (meaning it can be loaded by xarray)\n", + "* 0: no data available" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "9875bc6a-2f8a-43cc-b39e-0b8d7cc68c68", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import xarray as xr\n", + "\n", + "import cmip6radheating\n", + "\n", + "import warnings\n", + "warnings.simplefilter(\"ignore\") " + ] + }, + { + "cell_type": "markdown", + "id": "c09c2b69-f8e1-416b-9118-60014fe84d90", + "metadata": {}, + "source": [ + "Defines lists of variables, experiments and tables of interest." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "885fdb4a-0d61-4a01-b1b9-b15b7f41166d", + "metadata": {}, + "outputs": [], + "source": [ + "var = [\"rld\", \"rldcs\", \"rlu\", \"rlucs\", \"rsd\", \"rsdcs\", \"rsu\", \"rsucs\", \"tntr\", \"tntrl\", \"tntrlcs\", \"tntrs\" ,\"tntrscs\"]\n", + "tab = [\"AERmon\", \"CFmon\", \"Emon\", \"EmonZ\"]\n", + "exp = [\"amip\", \"amip-p4K\", \"amip-future4K\", \"aqua-control\", \"aqua-p4K\"]" + ] + }, + { + "cell_type": "markdown", + "id": "65dab6f9-fe23-4871-9ec3-7ea3cdd7b036", + "metadata": {}, + "source": [ + "## The steps below only need to be done if the model-data-matrix has not been computed already or needs to be recomputed. Otherwise, proceed to the step \"Load precomputed model-data-matrix." + ] + }, + { + "cell_type": "markdown", + "id": "d87ea95b-7f90-473d-8b9b-306f16860188", + "metadata": {}, + "source": [ + "First, we create the list of models for which at least one variable for one experiment and one table is available.\n", + "\n", + "This list is stored in \"mod\" and printed below for reference." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "235a1122-bf94-45cc-87cd-846b448186a3", + "metadata": {}, + "outputs": [], + "source": [ + "def find_models(_var, _tab, _exp):\n", + " models = list()\n", + " for varid in _var:\n", + " for tabid in _tab:\n", + " for expid in _exp:\n", + " models.append(cmip6radheating.list_models(var=varid, tab=tabid, exp=expid, ripf=\"*\"))\n", + " # flatten the list of list of models\n", + " models = [item for sublist in models for item in sublist]\n", + " # remove duplicates and sort\n", + " models=list(dict.fromkeys(models))\n", + " models=sorted(models)\n", + " return models\n", + "\n", + "mod = find_models(_var=var, _tab=tab, _exp=exp)" + ] + }, + { + "cell_type": "markdown", + "id": "157b304c-c38f-4b5b-a059-808a15240ab4", + "metadata": {}, + "source": [ + "Creates an xarray dataarray filled with zeros with coordinates models, experiments, variables and tables. Below, the dataarray will be filled with \"1\"s if data is available for the specific combination of model x experiment x variable x table." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2d75894f-3c92-4cac-9ecd-b81048860827", + "metadata": {}, + "outputs": [], + "source": [ + "mdm = xr.DataArray(np.zeros((len(mod), len(exp), len(var), len(tab))), \n", + " dims=[\"mod\", \"exp\", \"var\", \"tab\"], \n", + " coords={\"mod\": mod, \"exp\": exp, \"var\": var, \"tab\": tab})" + ] + }, + { + "cell_type": "markdown", + "id": "89425ef5-9d31-4260-836b-d10b143bcbf1", + "metadata": {}, + "source": [ + "Fill data matrix and save to disk." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "2524bc65-1243-4d09-861f-ce9ce2a8298c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Working on model BCC-CSM2-MR\n", + "Working on model BCC-ESM1\n", + "Working on model CESM2\n", + "Working on model CESM2-FV2\n", + "Working on model CESM2-WACCM\n", + "Working on model CESM2-WACCM-FV2\n", + "Working on model CNRM-CM6-1\n", + "Working on model CNRM-ESM2-1\n", + "Working on model EC-Earth3\n", + "Working on model GFDL-AM4\n", + "Working on model GFDL-CM4\n", + "Working on model GFDL-ESM4\n", + "Working on model HadGEM3-GC31-LL\n", + "Working on model HadGEM3-GC31-MM\n", + "Working on model INM-CM4-8\n", + "Working on model INM-CM5-0\n", + "Working on model IPSL-CM6A-LR\n", + "Working on model KACE-1-0-G\n", + "Working on model MIROC-ES2L\n", + "Working on model MIROC6\n", + "Working on model MPI-ESM-1-2-HAM\n", + "Working on model MPI-ESM1-2-HR\n", + "Working on model MPI-ESM1-2-LR\n", + "Working on model MRI-ESM2-0\n", + "Working on model UKESM1-0-LL\n" + ] + } + ], + "source": [ + "for i in range(0, len(mod)):\n", + " print(\"Working on model \", str(mdm[\"mod\"][i].values))\n", + " for j in range(0, len(exp)):\n", + " for k in range(0, len(var)):\n", + " for l in range(0, len(tab)):\n", + " model=str(mdm[\"mod\"][i].values)\n", + " exper=str(mdm[\"exp\"][j].values)\n", + " varia=str(mdm[\"var\"][k].values)\n", + " table=str(mdm[\"tab\"][l].values)\n", + " #print(model,exper,varia,table)\n", + " files=cmip6radheating.list_files(mod=model, var=varia, tab=table, exp=exper, ripf=\"*\")\n", + " if len(files) >0:\n", + " mdm[i,j,k,l]=1" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "814b5a40-dfef-49a8-812d-3466d6c7f934", + "metadata": {}, + "outputs": [], + "source": [ + "mdm.to_netcdf(\"model_data_matrix.nc\")" + ] + }, + { + "cell_type": "markdown", + "id": "afb97fb1-ee92-42e6-9c39-82a740eae5cf", + "metadata": {}, + "source": [ + "## Loads precomputed model-data-matrix." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "612811d1-fd21-46d8-bce3-ed2ffd1ad5cc", + "metadata": {}, + "outputs": [], + "source": [ + "mdm = xr.open_dataarray(\"model_data_matrix.nc\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "53d4adb1-5136-4024-b5c4-ec3b2a6e978a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overall available models: ['BCC-CSM2-MR', 'BCC-ESM1', 'CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'EC-Earth3', 'GFDL-AM4', 'GFDL-CM4', 'GFDL-ESM4', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'KACE-1-0-G', 'MIROC-ES2L', 'MIROC6', 'MPI-ESM-1-2-HAM', 'MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0', 'UKESM1-0-LL']\n" + ] + } + ], + "source": [ + "# model list\n", + "mod = list(mdm.mod.values)\n", + "print(\"Overall available models: \", mod)" + ] + }, + { + "cell_type": "markdown", + "id": "c446d02d-a9c5-45f7-b638-866658f996b7", + "metadata": {}, + "source": [ + "## Finds models for which specific data is available" + ] + }, + { + "cell_type": "markdown", + "id": "71feae38-e40d-4eab-9225-c40d9298e2cf", + "metadata": {}, + "source": [ + "### Radiative fluxes" + ] + }, + { + "cell_type": "markdown", + "id": "d94cf555-f3da-442d-9a03-1e8019f93f4e", + "metadata": {}, + "source": [ + "Finds all models that have data to calculate all-sky heating rates from radiative fluxes for a specific experiment. It is allowed that the radiative fluxes are distributed over two or more tables." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "361dd42e-0119-4d48-a61c-52e20faf2b79", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "------------------------------------------\n", + "ALL-SKY RADIATIVE FLUXES\n", + "------------------------------------------\n", + "\n", + "16 models available for all-sky fluxes for experiment amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'KACE-1-0-G', 'MIROC-ES2L', 'MIROC6', 'MPI-ESM-1-2-HAM', 'MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "6 models available for all-sky fluxes for experiment amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "6 models available for all-sky fluxes for experiment amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky fluxes for experiment aqua-control : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky fluxes for experiment aqua-p4K : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "\n", + "Again but with EmonZ table excluded\n", + "\n", + "16 models available for all-sky fluxes for experiment amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'KACE-1-0-G', 'MIROC-ES2L', 'MIROC6', 'MPI-ESM-1-2-HAM', 'MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "6 models available for all-sky fluxes for experiment amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "6 models available for all-sky fluxes for experiment amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky fluxes for experiment aqua-control : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky fluxes for experiment aqua-p4K : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "\n", + "------------------------------------------\n", + "CLEAR-SKY RADIATIVE FLUXES\n", + "------------------------------------------\n", + "\n", + "12 models available for clear-sky fluxes for experiment amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "6 models available for clear-sky fluxes for experiment amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "6 models available for clear-sky fluxes for experiment amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for clear-sky fluxes for experiment aqua-control : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for clear-sky fluxes for experiment aqua-p4K : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "\n", + "Again but with EmonZ table excluded\n", + "\n", + "12 models available for clear-sky fluxes for experiment amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "6 models available for clear-sky fluxes for experiment amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "6 models available for clear-sky fluxes for experiment amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for clear-sky fluxes for experiment aqua-control : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for clear-sky fluxes for experiment aqua-p4K : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "\n", + "------------------------------------------\n", + "ALL-SKY AND CLEAR-SKY RADIATIVE FLUXES\n", + "------------------------------------------\n", + "\n", + "12 models available for all-sky and clear-sky fluxes for experiment amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "6 models available for all-sky and clear-sky fluxes for experiment amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "6 models available for all-sky and clear-sky fluxes for experiment amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky and clear-sky fluxes for experiment aqua-control : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky and clear-sky fluxes for experiment aqua-p4K : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "\n", + "Again but with EmonZ table excluded\n", + "\n", + "12 models available for all-sky and clear-sky fluxes for experiment amip : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'HadGEM3-GC31-LL', 'HadGEM3-GC31-MM', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "6 models available for all-sky and clear-sky fluxes for experiment amip-p4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "6 models available for all-sky and clear-sky fluxes for experiment amip-future4K : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky and clear-sky fluxes for experiment aqua-control : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "5 models available for all-sky and clear-sky fluxes for experiment aqua-p4K : ['CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n" + ] + } + ], + "source": [ + "def allsky_fluxes(expid, _mdm=mdm):\n", + " sw = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rsd\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rsu\"]).squeeze()))\n", + " lw = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rld\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rlu\"]).squeeze()))\n", + " tmp = (np.logical_and(sw, lw)).squeeze().sum(\"tab\").values\n", + " ind=np.argwhere(tmp>=1).squeeze()\n", + " modlist = [mod[i] for i in ind]\n", + " print(len(modlist), \"models available for all-sky fluxes for experiment\", expid, \":\", modlist)\n", + " return modlist\n", + "\n", + "def clrsky_fluxes(expid, _mdm=mdm):\n", + " sw = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rsdcs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rsucs\"]).squeeze()))\n", + " lw = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rldcs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rlucs\"]).squeeze()))\n", + " tmp = (np.logical_and(sw, lw)).squeeze().sum(\"tab\").values\n", + " ind=np.argwhere(tmp>=1).squeeze()\n", + " modlist = [mod[i] for i in ind]\n", + " print(len(modlist), \"models available for clear-sky fluxes for experiment\", expid, \":\", modlist)\n", + " return modlist\n", + "\n", + "def allsky_and_clrsky_fluxes(expid, _mdm=mdm):\n", + " # all-sky\n", + " sw = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rsd\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rsu\"]).squeeze()))\n", + " lw = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rld\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rlu\"]).squeeze()))\n", + " tmp = (np.logical_and(sw, lw)).squeeze().sum(\"tab\").values\n", + " ind=np.argwhere(tmp>=1).squeeze()\n", + " # clear-sky\n", + " swcs = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rsdcs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rsucs\"]).squeeze()))\n", + " lwcs = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"rldcs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"rlucs\"]).squeeze()))\n", + " tmpcs = (np.logical_and(swcs, lwcs)).squeeze().sum(\"tab\").values\n", + " indcs=np.argwhere(tmpcs>=1).squeeze()\n", + " # model with all-sky and clear-sky data\n", + " indjoint = list(set(ind) & set(indcs))\n", + " modlist = [mod[i] for i in indjoint] \n", + " print(len(modlist), \"models available for all-sky and clear-sky fluxes for experiment\", expid, \":\", modlist)\n", + " return modlist\n", + "\n", + "\n", + "print(\"\\n------------------------------------------\")\n", + "print(\"ALL-SKY RADIATIVE FLUXES\")\n", + "print(\"------------------------------------------\\n\")\n", + "\n", + "_ = allsky_fluxes(expid=\"amip\")\n", + "_ = allsky_fluxes(expid=\"amip-p4K\")\n", + "_ = allsky_fluxes(expid=\"amip-future4K\")\n", + "\n", + "_ = allsky_fluxes(expid=\"aqua-control\")\n", + "_ = allsky_fluxes(expid=\"aqua-p4K\")\n", + "\n", + "print(\"\\nAgain but with EmonZ table excluded\\n\")\n", + "\n", + "_ = allsky_fluxes(expid=\"amip\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_fluxes(expid=\"amip-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_fluxes(expid=\"amip-future4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "_ = allsky_fluxes(expid=\"aqua-control\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_fluxes(expid=\"aqua-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "print(\"\\n------------------------------------------\")\n", + "print(\"CLEAR-SKY RADIATIVE FLUXES\")\n", + "print(\"------------------------------------------\\n\")\n", + "\n", + "_ = clrsky_fluxes(expid=\"amip\")\n", + "_ = clrsky_fluxes(expid=\"amip-p4K\")\n", + "_ = clrsky_fluxes(expid=\"amip-future4K\")\n", + "\n", + "_ = clrsky_fluxes(expid=\"aqua-control\")\n", + "_ = clrsky_fluxes(expid=\"aqua-p4K\")\n", + "\n", + "print(\"\\nAgain but with EmonZ table excluded\\n\")\n", + "\n", + "_ = clrsky_fluxes(expid=\"amip\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = clrsky_fluxes(expid=\"amip-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = clrsky_fluxes(expid=\"amip-future4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "_ = clrsky_fluxes(expid=\"aqua-control\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = clrsky_fluxes(expid=\"aqua-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + " \n", + "print(\"\\n------------------------------------------\")\n", + "print(\"ALL-SKY AND CLEAR-SKY RADIATIVE FLUXES\")\n", + "print(\"------------------------------------------\\n\")\n", + "\n", + "_ = allsky_and_clrsky_fluxes(expid=\"amip\")\n", + "_ = allsky_and_clrsky_fluxes(expid=\"amip-p4K\")\n", + "_ = allsky_and_clrsky_fluxes(expid=\"amip-future4K\")\n", + "\n", + "_ = allsky_and_clrsky_fluxes(expid=\"aqua-control\")\n", + "_ = allsky_and_clrsky_fluxes(expid=\"aqua-p4K\")\n", + "\n", + "print(\"\\nAgain but with EmonZ table excluded\\n\")\n", + "\n", + "_ = allsky_and_clrsky_fluxes(expid=\"amip\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_and_clrsky_fluxes(expid=\"amip-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_and_clrsky_fluxes(expid=\"amip-future4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "_ = allsky_and_clrsky_fluxes(expid=\"aqua-control\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_and_clrsky_fluxes(expid=\"aqua-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))" + ] + }, + { + "cell_type": "markdown", + "id": "12f16a5e-d6d9-48af-8012-bd7e46a7fc5c", + "metadata": {}, + "source": [ + "### Radiative temperature tendencies (tntr)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "cbe01d2e-23e1-423c-8385-11602e8164be", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "------------------------------------------\n", + "ALL-SKY RADIATIVE HEATING RATES\n", + "------------------------------------------\n", + "\n", + "19 models available for all-sky radiative heating rates for experiment amip : ['BCC-CSM2-MR', 'BCC-ESM1', 'CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'EC-Earth3', 'GFDL-AM4', 'GFDL-CM4', 'GFDL-ESM4', 'HadGEM3-GC31-LL', 'INM-CM4-8', 'INM-CM5-0', 'MIROC-ES2L', 'MPI-ESM-1-2-HAM', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "4 models available for all-sky radiative heating rates for experiment amip-p4K : ['BCC-CSM2-MR', 'GFDL-CM4', 'MIROC6', 'MRI-ESM2-0']\n", + "4 models available for all-sky radiative heating rates for experiment amip-future4K : ['BCC-CSM2-MR', 'GFDL-CM4', 'MIROC6', 'MRI-ESM2-0']\n", + "3 models available for all-sky radiative heating rates for experiment aqua-control : ['GFDL-CM4', 'MIROC6', 'MRI-ESM2-0']\n", + "3 models available for all-sky radiative heating rates for experiment aqua-p4K : ['GFDL-CM4', 'MIROC6', 'MRI-ESM2-0']\n", + "\n", + "Again but with EmonZ table excluded\n", + "\n", + "13 models available for all-sky radiative heating rates for experiment amip : ['BCC-CSM2-MR', 'BCC-ESM1', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'GFDL-AM4', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'INM-CM4-8', 'INM-CM5-0', 'MIROC-ES2L', 'MPI-ESM-1-2-HAM', 'MRI-ESM2-0', 'UKESM1-0-LL']\n", + "4 models available for all-sky radiative heating rates for experiment amip-p4K : ['BCC-CSM2-MR', 'GFDL-CM4', 'MIROC6', 'MRI-ESM2-0']\n", + "3 models available for all-sky radiative heating rates for experiment amip-future4K : ['BCC-CSM2-MR', 'MIROC6', 'MRI-ESM2-0']\n", + "3 models available for all-sky radiative heating rates for experiment aqua-control : ['GFDL-CM4', 'MIROC6', 'MRI-ESM2-0']\n", + "3 models available for all-sky radiative heating rates for experiment aqua-p4K : ['GFDL-CM4', 'MIROC6', 'MRI-ESM2-0']\n", + "\n", + "------------------------------------------\n", + "CLEAR-SKY RADIATIVE HEATING RATES\n", + "------------------------------------------\n", + "\n", + "14 models available for clear-sky radiative heating rates for experiment amip : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'EC-Earth3', 'GFDL-AM4', 'GFDL-CM4', 'GFDL-ESM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6', 'UKESM1-0-LL']\n", + "6 models available for clear-sky radiative heating rates for experiment amip-p4K : ['CESM2', 'CNRM-CM6-1', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6']\n", + "6 models available for clear-sky radiative heating rates for experiment amip-future4K : ['CESM2', 'CNRM-CM6-1', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6']\n", + "6 models available for clear-sky radiative heating rates for experiment aqua-control : ['CESM2', 'CNRM-CM6-1', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6']\n", + "6 models available for clear-sky radiative heating rates for experiment aqua-p4K : ['CESM2', 'CNRM-CM6-1', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'MIROC6']\n", + "\n", + "Again but with EmonZ table excluded\n", + "\n", + "11 models available for clear-sky radiative heating rates for experiment amip : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'GFDL-AM4', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR', 'UKESM1-0-LL']\n", + "5 models available for clear-sky radiative heating rates for experiment amip-p4K : ['CESM2', 'CNRM-CM6-1', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR']\n", + "4 models available for clear-sky radiative heating rates for experiment amip-future4K : ['CESM2', 'CNRM-CM6-1', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR']\n", + "5 models available for clear-sky radiative heating rates for experiment aqua-control : ['CESM2', 'CNRM-CM6-1', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR']\n", + "5 models available for clear-sky radiative heating rates for experiment aqua-p4K : ['CESM2', 'CNRM-CM6-1', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'IPSL-CM6A-LR']\n", + "\n", + "------------------------------------------\n", + "ALL-SKY AND CLEAR-SKY RADIATIVE HEATING RATES\n", + "------------------------------------------\n", + "\n", + "12 models available for all-sky and clear-sky radiative heating rates for experiment amip : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'EC-Earth3', 'GFDL-AM4', 'GFDL-CM4', 'GFDL-ESM4', 'HadGEM3-GC31-LL', 'UKESM1-0-LL']\n", + "2 models available for all-sky and clear-sky radiative heating rates for experiment amip-p4K : ['GFDL-CM4', 'MIROC6']\n", + "2 models available for all-sky and clear-sky radiative heating rates for experiment amip-future4K : ['GFDL-CM4', 'MIROC6']\n", + "2 models available for all-sky and clear-sky radiative heating rates for experiment aqua-control : ['GFDL-CM4', 'MIROC6']\n", + "2 models available for all-sky and clear-sky radiative heating rates for experiment aqua-p4K : ['GFDL-CM4', 'MIROC6']\n", + "\n", + "Again but with EmonZ table excluded\n", + "\n", + "6 models available for all-sky and clear-sky radiative heating rates for experiment amip : ['CNRM-CM6-1', 'CNRM-ESM2-1', 'GFDL-AM4', 'GFDL-CM4', 'HadGEM3-GC31-LL', 'UKESM1-0-LL']\n", + "1 models available for all-sky and clear-sky radiative heating rates for experiment amip-p4K : ['GFDL-CM4']\n", + "0 models available for all-sky and clear-sky radiative heating rates for experiment amip-future4K : []\n", + "1 models available for all-sky and clear-sky radiative heating rates for experiment aqua-control : ['GFDL-CM4']\n", + "1 models available for all-sky and clear-sky radiative heating rates for experiment aqua-p4K : ['GFDL-CM4']\n" + ] + } + ], + "source": [ + "def allsky_tntr(expid, _mdm=mdm):\n", + " tmp = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"tntrs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"tntrl\"]).squeeze()))\n", + " tmp = tmp.squeeze().sum(\"tab\").values\n", + " ind=np.argwhere(tmp>=1).squeeze()\n", + " modlist = [mod[i] for i in ind]\n", + " print(len(modlist), \"models available for all-sky radiative heating rates for experiment\", expid, \":\", modlist)\n", + " return modlist\n", + "\n", + "def clrsky_tntr(expid, _mdm=mdm):\n", + " tmp = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"tntrscs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"tntrlcs\"]).squeeze()))\n", + " tmp = tmp.squeeze().sum(\"tab\").values\n", + " ind=np.argwhere(tmp>=1).squeeze()\n", + " modlist = [mod[i] for i in ind]\n", + " print(len(modlist), \"models available for clear-sky radiative heating rates for experiment\", expid, \":\", modlist)\n", + " return modlist\n", + "\n", + "def allsky_and_clrsky_tntr(expid, _mdm=mdm):\n", + " # all-sky\n", + " tmp = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"tntrs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"tntrl\"]).squeeze()))\n", + " tmp = tmp.squeeze().sum(\"tab\").values\n", + " ind=np.argwhere(tmp>=1).squeeze()\n", + " # clear-sky\n", + " tmpcs = (np.logical_and(_mdm.sel(exp=expid).sel(var=[\"tntrscs\"]).squeeze(), _mdm.sel(exp=expid).sel(var=[\"tntrlcs\"]).squeeze()))\n", + " tmpcs = tmpcs.squeeze().sum(\"tab\").values\n", + " indcs=np.argwhere(tmpcs>=1).squeeze() \n", + " # model with all-sky and clear-sky data\n", + " indjoint = list(set(ind) & set(indcs))\n", + " modlist = [mod[i] for i in indjoint] \n", + " print(len(modlist), \"models available for all-sky and clear-sky radiative heating rates for experiment\", expid, \":\", modlist)\n", + " return modlist\n", + "\n", + "\n", + "print(\"\\n------------------------------------------\")\n", + "print(\"ALL-SKY RADIATIVE HEATING RATES\")\n", + "print(\"------------------------------------------\\n\")\n", + "\n", + "_ = allsky_tntr(expid=\"amip\")\n", + "_ = allsky_tntr(expid=\"amip-p4K\")\n", + "_ = allsky_tntr(expid=\"amip-future4K\")\n", + "\n", + "_ = allsky_tntr(expid=\"aqua-control\")\n", + "_ = allsky_tntr(expid=\"aqua-p4K\")\n", + "\n", + "print(\"\\nAgain but with EmonZ table excluded\\n\")\n", + "\n", + "_ = allsky_tntr(expid=\"amip\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_tntr(expid=\"amip-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_tntr(expid=\"amip-future4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "_ = allsky_tntr(expid=\"aqua-control\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_tntr(expid=\"aqua-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "print(\"\\n------------------------------------------\")\n", + "print(\"CLEAR-SKY RADIATIVE HEATING RATES\")\n", + "print(\"------------------------------------------\\n\")\n", + "\n", + "_ = clrsky_tntr(expid=\"amip\")\n", + "_ = clrsky_tntr(expid=\"amip-p4K\")\n", + "_ = clrsky_tntr(expid=\"amip-future4K\")\n", + "\n", + "_ = clrsky_tntr(expid=\"aqua-control\")\n", + "_ = clrsky_tntr(expid=\"aqua-p4K\")\n", + "\n", + "print(\"\\nAgain but with EmonZ table excluded\\n\")\n", + "\n", + "_ = clrsky_tntr(expid=\"amip\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = clrsky_tntr(expid=\"amip-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = clrsky_tntr(expid=\"amip-future4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "_ = clrsky_tntr(expid=\"aqua-control\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = clrsky_tntr(expid=\"aqua-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "\n", + "print(\"\\n------------------------------------------\")\n", + "print(\"ALL-SKY AND CLEAR-SKY RADIATIVE HEATING RATES\")\n", + "print(\"------------------------------------------\\n\")\n", + "\n", + "_ = allsky_and_clrsky_tntr(expid=\"amip\")\n", + "_ = allsky_and_clrsky_tntr(expid=\"amip-p4K\")\n", + "_ = allsky_and_clrsky_tntr(expid=\"amip-future4K\")\n", + "\n", + "_ = allsky_and_clrsky_tntr(expid=\"aqua-control\")\n", + "_ = allsky_and_clrsky_tntr(expid=\"aqua-p4K\")\n", + "\n", + "print(\"\\nAgain but with EmonZ table excluded\\n\")\n", + "\n", + "_ = allsky_and_clrsky_tntr(expid=\"amip\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_and_clrsky_tntr(expid=\"amip-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_and_clrsky_tntr(expid=\"amip-future4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "\n", + "_ = allsky_and_clrsky_tntr(expid=\"aqua-control\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))\n", + "_ = allsky_and_clrsky_tntr(expid=\"aqua-p4K\", _mdm=mdm.sel(tab=[\"AERmon\", \"CFmon\", \"Emon\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2061b067-411e-460b-8f08-1c2814ad8ca6", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/analysis/obtain_vgrid_information.ipynb b/analysis/obtain_vgrid_information.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..3eb2bf85046d5bf9c9ca2a7bd81dc7cb630ef30f --- /dev/null +++ b/analysis/obtain_vgrid_information.ipynb @@ -0,0 +1,302 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9edf7c2e-5876-4fea-8407-a9084b5a6732", + "metadata": {}, + "source": [ + "# Obtain and store information on vertical grid for half levels and full levels" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "97cba687-6481-4df0-a410-fbb5e885a84e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import xarray as xr\n", + "import cmip6radheating\n", + "from get_vgrid_information import vgrid_halflevels, vgrid_fulllevels" + ] + }, + { + "cell_type": "markdown", + "id": "40e67bac-224d-433f-9e8c-4a0f93c29c14", + "metadata": {}, + "source": [ + "Silences xarray warnings that occur when some data is loaded." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c10c12be-e5bd-4b2e-acc5-e348693e3bd1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.simplefilter(\"ignore\") " + ] + }, + { + "cell_type": "markdown", + "id": "c6ce2581-fc65-47c4-98d4-395d11d19d8d", + "metadata": {}, + "source": [ + "### Take care of full levels first.\n", + "\n", + "To this end we loop over a few variables, experiments and table so as to catch all models." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a0bc87f8-82d8-48ce-bdac-af8be46b0777", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "vgrid_fulllevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon tntr /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntr/CFmon/tntr_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon tntr /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntr/CFmon/tntr_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon tntr /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntr/CFmon/tntr_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon tntr /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/tntr/CFmon/tntr_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon tntr /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/tntr/CFmon/tntr_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon tntr /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/tntr/CFmon/tntr_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_fulllevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip AERmon tntrs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip AERmon tntrs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_HadGEM3-GC31-LL_amip_r5i1p1f3_gn_197901-199912.nc\n", + "Vgrid information could not be retrieved for: MPI-ESM-1-2-HAM amip Emon tntrs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/Emon/tntrs_Emon_MPI-ESM-1-2-HAM_amip_r1i1p1f1_gn_197901-199812.nc\n", + "vgrid_fulllevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip AERmon tntrl /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip AERmon tntrl /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_HadGEM3-GC31-LL_amip_r5i1p1f3_gn_197901-199912.nc\n", + "Vgrid information could not be retrieved for: CESM2 amip Emon tntrl /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/Emon/tntrl_Emon_CESM2_amip_r1i1p1f1_gn_195001-201412.nc\n", + "Vgrid information could not be retrieved for: CESM2-FV2 amip Emon tntrl /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/Emon/tntrl_Emon_CESM2-FV2_amip_r1i1p1f1_gn_195001-199912.nc\n", + "Vgrid information could not be retrieved for: CESM2-WACCM amip Emon tntrl /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/Emon/tntrl_Emon_CESM2-WACCM_amip_r1i1p1f1_gn_195001-201412.nc\n", + "Vgrid information could not be retrieved for: CESM2-WACCM-FV2 amip Emon tntrl /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/Emon/tntrl_Emon_CESM2-WACCM-FV2_amip_r1i1p1f1_gn_195001-199912.nc\n", + "Vgrid information could not be retrieved for: MPI-ESM-1-2-HAM amip Emon tntrl /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/Emon/tntrl_Emon_MPI-ESM-1-2-HAM_amip_r1i1p1f1_gn_197901-199812.nc\n", + "vgrid_fulllevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip Emon tntrscs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrscs/Emon/tntrscs_Emon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip Emon tntrscs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrscs/Emon/tntrscs_Emon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K Emon tntrscs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/tntrscs/Emon/tntrscs_Emon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control Emon tntrscs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/tntrscs/Emon/tntrscs_Emon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K Emon tntrscs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/tntrscs/Emon/tntrscs_Emon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_fulllevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip Emon tntrlcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrlcs/Emon/tntrlcs_Emon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip Emon tntrlcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrlcs/Emon/tntrlcs_Emon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K Emon tntrlcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/tntrlcs/Emon/tntrlcs_Emon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control Emon tntrlcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/tntrlcs/Emon/tntrlcs_Emon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_fulllevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K Emon tntrlcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/tntrlcs/Emon/tntrlcs_Emon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n" + ] + } + ], + "source": [ + "for var in [\"tntr\", \"tntrs\", \"tntrl\", \"tntrscs\", \"tntrlcs\"]:\n", + " for exp in [\"amip\", \"amip-p4K\" ,\"amip-p4Kfuture\", \"aqua-control\", \"aqua-p4K\"]:\n", + " for tab in [\"CFmon\", \"AERmon\", \"Emon\"]:\n", + " mod_list = cmip6radheating.list_models(var=var, exp=exp, tab=tab)\n", + " #print(\"Available models for\", var, exp, tab, \":\\n\", mod_list)\n", + " for mod in mod_list:\n", + " f_list = cmip6radheating.list_files(mod=mod, var=var, tab=tab, exp=exp, ripf=\"*\")\n", + " try: \n", + " ds = cmip6radheating.load_data(f_list)[0]\n", + " vgrid_fulllevels(ds)\n", + " except:\n", + " print(\"Vgrid information could not be retrieved for:\", mod, exp, tab, var, f_list[0])" + ] + }, + { + "cell_type": "markdown", + "id": "1a8d45f9-814f-413f-a5f7-175a8b720e64", + "metadata": {}, + "source": [ + "### Now take care of half levels." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "b3b12298-84b5-4d63-adb0-38cf9ab1475b", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "vgrid_halflevels: model KACE-1-0-G is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: KACE-1-0-G amip CFmon rsd /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsd/CFmon/rsd_CFmon_KACE-1-0-G_amip_r1i1p1f1_gr_197901-201412.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rsd /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsd/CFmon/rsd_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rsd /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsd/CFmon/rsd_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rsd /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsd/CFmon/rsd_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rsd /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rsd/CFmon/rsd_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rsd /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rsd/CFmon/rsd_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rsd /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rsd/CFmon/rsd_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model KACE-1-0-G is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: KACE-1-0-G amip CFmon rsu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsu/CFmon/rsu_CFmon_KACE-1-0-G_amip_r1i1p1f1_gr_197901-201412.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rsu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsu/CFmon/rsu_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rsu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsu/CFmon/rsu_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rsu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsu/CFmon/rsu_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rsu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rsu/CFmon/rsu_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rsu /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rsu/CFmon/rsu_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rsu /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rsu/CFmon/rsu_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model KACE-1-0-G is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: KACE-1-0-G amip CFmon rsdcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsdcs/CFmon/rsdcs_CFmon_KACE-1-0-G_amip_r1i1p1f1_gr_197901-201412.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rsdcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsdcs/CFmon/rsdcs_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rsdcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsdcs/CFmon/rsdcs_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rsdcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsdcs/CFmon/rsdcs_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rsdcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rsdcs/CFmon/rsdcs_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rsdcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rsdcs/CFmon/rsdcs_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rsdcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rsdcs/CFmon/rsdcs_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model KACE-1-0-G is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: KACE-1-0-G amip CFmon rsucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsucs/CFmon/rsucs_CFmon_KACE-1-0-G_amip_r1i1p1f1_gr_197901-201412.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rsucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsucs/CFmon/rsucs_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rsucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsucs/CFmon/rsucs_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rsucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rsucs/CFmon/rsucs_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rsucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rsucs/CFmon/rsucs_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rsucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rsucs/CFmon/rsucs_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rsucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rsucs/CFmon/rsucs_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model KACE-1-0-G is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: KACE-1-0-G amip CFmon rld /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rld/CFmon/rld_CFmon_KACE-1-0-G_amip_r1i1p1f1_gr_197901-201412.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rld /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rld/CFmon/rld_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rld /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rld/CFmon/rld_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rld /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rld/CFmon/rld_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rld /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rld/CFmon/rld_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rld /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rld/CFmon/rld_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rld /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rld/CFmon/rld_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model KACE-1-0-G is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: KACE-1-0-G amip CFmon rlu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rlu/CFmon/rlu_CFmon_KACE-1-0-G_amip_r1i1p1f1_gr_197901-201412.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rlu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rlu/CFmon/rlu_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rlu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rlu/CFmon/rlu_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rlu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rlu/CFmon/rlu_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rlu /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rlu/CFmon/rlu_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rlu /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rlu/CFmon/rlu_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rlu /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rlu/CFmon/rlu_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model KACE-1-0-G is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: KACE-1-0-G amip CFmon rldcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rldcs/CFmon/rldcs_CFmon_KACE-1-0-G_amip_r1i1p1f1_gr_197901-201412.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rldcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rldcs/CFmon/rldcs_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rldcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rldcs/CFmon/rldcs_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rldcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rldcs/CFmon/rldcs_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rldcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rldcs/CFmon/rldcs_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rldcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rldcs/CFmon/rldcs_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rldcs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rldcs/CFmon/rldcs_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model UKESM1-0-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: UKESM1-0-LL amip CFmon rlucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rlucs/CFmon/rlucs_CFmon_UKESM1-0-LL_amip_r1i1p1f4_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip CFmon rlucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rlucs/CFmon/rlucs_CFmon_HadGEM3-GC31-LL_amip_r1i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-MM is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-MM amip CFmon rlucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/rlucs/CFmon/rlucs_CFmon_HadGEM3-GC31-MM_amip_r1i1p1f3_gn_197901-197912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL amip-p4K CFmon rlucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/amip-p4K/rlucs/CFmon/rlucs_CFmon_HadGEM3-GC31-LL_amip-p4K_r5i1p1f3_gn_197901-199912.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-control CFmon rlucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-control/rlucs/CFmon/rlucs_CFmon_HadGEM3-GC31-LL_aqua-control_r1i1p1f3_gn_197901-198812.nc\n", + "vgrid_halflevels: model HadGEM3-GC31-LL is height based and needs special treatment\n", + "Vgrid information could not be retrieved for: HadGEM3-GC31-LL aqua-p4K CFmon rlucs /scratch/das/avoigt/cmip6-acre-data/CMIP6/aqua-p4K/rlucs/CFmon/rlucs_CFmon_HadGEM3-GC31-LL_aqua-p4K_r1i1p1f3_gn_197901-198812.nc\n" + ] + } + ], + "source": [ + "for var in [\"rsd\", \"rsu\", \"rsdcs\", \"rsucs\", \"rld\", \"rlu\", \"rldcs\", \"rlucs\"]:\n", + " for exp in [\"amip\", \"amip-p4K\" ,\"amip-p4Kfuture\", \"aqua-control\", \"aqua-p4K\"]:\n", + " for tab in [\"CFmon\", \"AERmon\", \"Emon\"]:\n", + " mod_list = cmip6radheating.list_models(var=var, exp=exp, tab=tab)\n", + " #print(\"Available models for\", var, exp, tab, \":\\n\", mod_list)\n", + " for mod in mod_list:\n", + " f_list = cmip6radheating.list_files(mod=mod, var=var, tab=tab, exp=exp, ripf=\"*\")\n", + " try: \n", + " ds = cmip6radheating.load_data(f_list)[0]\n", + " vgrid_halflevels(ds)\n", + " except:\n", + " print(\"Vgrid information could not be retrieved for:\", mod, exp, tab, var, f_list[0])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/analysis/qualitycheck.ipynb b/analysis/qualitycheck.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..8db73ce3d12fb04445f6f8141e757405dbadbade --- /dev/null +++ b/analysis/qualitycheck.ipynb @@ -0,0 +1,226 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f93cb3fa-0d98-4f58-b80c-99cdc84fb855", + "metadata": {}, + "source": [ + "# Quality check: zonal-mean time-mean plots of heating rates for all available models and vars\n", + "\n", + "Makes plots for all models, exps, vars and tabs and merges them into one large pdf for easy visual inspection.\n", + "The merged pdf is qualitycheck_allpdfs.pdf. The individual pdfs are deleted afterwards." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "25a530f7-5d57-49fe-a598-948b61d9e3f9", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import numpy as np\n", + "import xarray as xr\n", + "import matplotlib.pyplot as plt " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5775d27b-49fb-43e3-940c-2286aa0d8d49", + "metadata": {}, + "outputs": [], + "source": [ + "def available_models(var, exp, tab):\n", + " \"\"\" Returns list of all models for which variable var is available for simulation exp and table tab. \"\"\"\n", + " path = \"/scratch/das/avoigt/cmip6-acre-data/postprocessed/\"\n", + " modlist = list()\n", + " for dir in os.listdir(path):\n", + " if var in dir and exp+\".\" in dir and tab in dir:\n", + " modlist.append(dir.rsplit(\"_\")[2])\n", + " modlist = sorted(modlist)\n", + " return modlist\n", + "\n", + "def qc_plot(var, exp, tab, plev=3*np.linspace(-1,1,11)):\n", + " \"\"\" Makes panel plots of zonal-mean time-mean of variable var for experiment exp and table tab\n", + " for all available models.\"\"\"\n", + " path = \"/scratch/das/avoigt/cmip6-acre-data/postprocessed/\"\n", + " mods = available_models(var, exp, tab)\n", + " print(\"Available models for\", var, exp, tab, \":\", modlist)\n", + " nmods = len(mods) # number of available models\n", + " nrows = int(np.floor((nmods-1)/4) + 1) # number of rows for panel plot\n", + " fig=plt.figure(figsize=(20,nrows*4))\n", + " for i in range(0, nmods):\n", + " plt.subplot(nrows,4,i+1)\n", + " ds=xr.open_dataset(path+\"/\"+var+\"_\"+tab+\"_\"+mods[i]+\"_\"+exp+\".zarr\", engine=\"zarr\", chunks=\"auto\")\n", + " # skip the first year for the time average\n", + " ntime=ds.time.size\n", + " try: # data with longitude --> CFmon, AERmon\n", + " plt.contourf(ds.lat, ds.lev/100, ds[var].isel(time=slice(12, ntime)).mean([\"time\", \"lon\"]), plev, cmap=\"RdBu_r\", extend=\"both\")\n", + " except: # data without longitude --> EmonZ\n", + " plt.contourf(ds.lat, ds.lev/100, ds[var].isel(time=slice(12, ntime)).mean([\"time\"]), plev, cmap=\"RdBu_r\", extend=\"both\")\n", + " plt.ylim(1000,10)\n", + " plt.colorbar()\n", + " if i == 0:\n", + " plt.title(var+\", \"+tab+\", \"+exp+\"\\n\"+mods[i])\n", + " else:\n", + " plt.title(mods[i])\n", + " plt.savefig(\"qualitycheck_\"+var+\"_\"+tab+\"_\"+exp+\".pdf\")\n", + " plt.close(fig) " + ] + }, + { + "cell_type": "markdown", + "id": "6d42f462-2220-4942-87b9-19e7598489d4", + "metadata": {}, + "source": [ + "## aquaplanet control and aqua-p4K" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "64950620-a07e-4e0a-9d53-e089ff8017b3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available models for dTdt-as-from-flx aqua-control CFmon : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-flx aqua-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx aqua-control CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx aqua-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-as-from-flx aqua-control CFmon : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-as-from-flx aqua-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-cs-from-flx aqua-control CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-cs-from-flx aqua-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-as-from-flx aqua-control CFmon : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-as-from-flx aqua-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-cs-from-flx aqua-control CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-cs-from-flx aqua-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr aqua-control AERmon : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr aqua-p4K AERmon : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-tntr aqua-control EmonZ : ['MIROC6']\n", + "Available models for dTdt-cs-from-tntr aqua-p4K EmonZ : ['MIROC6']\n", + "Available models for dTdts-as-from-tntr aqua-control AERmon : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-as-from-tntr aqua-p4K AERmon : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-cs-from-tntr aqua-control EmonZ : ['MIROC6']\n", + "Available models for dTdts-cs-from-tntr aqua-p4K EmonZ : ['MIROC6']\n", + "Available models for dTdtl-as-from-tntr aqua-control AERmon : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-as-from-tntr aqua-p4K AERmon : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-cs-from-tntr aqua-control EmonZ : ['MIROC6']\n", + "Available models for dTdtl-cs-from-tntr aqua-p4K EmonZ : ['MIROC6']\n" + ] + } + ], + "source": [ + "for var in [\"dTdt-as-from-flx\", \"dTdt-cs-from-flx\", \"dTdts-as-from-flx\", \"dTdts-cs-from-flx\", \"dTdtl-as-from-flx\", \"dTdtl-cs-from-flx\",\n", + " \"dTdt-as-from-tntr\", \"dTdt-cs-from-tntr\", \"dTdts-as-from-tntr\", \"dTdts-cs-from-tntr\", \"dTdtl-as-from-tntr\", \"dTdtl-cs-from-tntr\"]:\n", + " for tab in [\"CFmon\", \"AERmon\", \"EmonZ\"]:\n", + " for exp in [\"aqua-control\", \"aqua-p4K\"]:\n", + " modlist = available_models(var, exp, tab)\n", + " # generate plot if modlist is not empty\n", + " if len(modlist)>0:\n", + " qc_plot(var=var, exp=exp, tab=tab)" + ] + }, + { + "cell_type": "markdown", + "id": "e06c5176-44b6-4530-bf2f-dcd8cb84ee8e", + "metadata": {}, + "source": [ + "## amip and amip-p4K" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9f2065b7-f9ae-47db-a522-032e5846b680", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available models for dTdt-as-from-flx amip CFmon : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MPI-ESM-1-2-HAM', 'MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-flx amip-p4K CFmon : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx amip CFmon : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-cs-from-flx amip-p4K CFmon : ['BCC-CSM2-MR', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-as-from-flx amip CFmon : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0']\n", + "Available models for dTdts-as-from-flx amip-p4K CFmon : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-cs-from-flx amip-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-as-from-flx amip CFmon : ['BCC-CSM2-MR', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'IPSL-CM6A-LR', 'MIROC-ES2L', 'MIROC6', 'MPI-ESM1-2-HR', 'MPI-ESM1-2-LR', 'MRI-ESM2-0']\n", + "Available models for dTdtl-as-from-flx amip-p4K CFmon : ['CNRM-CM6-1', 'IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdtl-cs-from-flx amip-p4K CFmon : ['IPSL-CM6A-LR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr amip AERmon : ['BCC-CSM2-MR', 'BCC-ESM1', 'CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'MIROC-ES2L', 'MPI-ESM-1-2-HAM', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr amip-p4K AERmon : ['BCC-CSM2-MR', 'MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdt-as-from-tntr amip EmonZ : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'EC-Earth3', 'GFDL-ESM4', 'INM-CM4-8', 'INM-CM5-0', 'MPI-ESM-1-2-HAM']\n", + "Available models for dTdt-cs-from-tntr amip EmonZ : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'EC-Earth3', 'GFDL-ESM4', 'IPSL-CM6A-LR', 'MIROC6']\n", + "Available models for dTdt-cs-from-tntr amip-p4K EmonZ : ['MIROC6']\n", + "Available models for dTdts-as-from-tntr amip AERmon : ['CNRM-CM6-1', 'CNRM-ESM2-1', 'INM-CM4-8', 'INM-CM5-0', 'MIROC-ES2L', 'MPI-ESM-1-2-HAM', 'MRI-ESM2-0']\n", + "Available models for dTdts-as-from-tntr amip-p4K AERmon : ['MIROC6', 'MRI-ESM2-0']\n", + "Available models for dTdts-as-from-tntr amip EmonZ : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'EC-Earth3', 'GFDL-ESM4', 'INM-CM4-8', 'INM-CM5-0', 'MPI-ESM-1-2-HAM']\n", + "Available models for dTdts-cs-from-tntr amip EmonZ : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'EC-Earth3', 'GFDL-ESM4', 'IPSL-CM6A-LR', 'MIROC6']\n", + "Available models for dTdts-cs-from-tntr amip-p4K EmonZ : ['MIROC6']\n", + "Available models for dTdtl-as-from-tntr amip AERmon : ['CNRM-CM6-1', 'INM-CM4-8', 'INM-CM5-0', 'MIROC-ES2L', 'MPI-ESM-1-2-HAM', 'MRI-ESM2-0']\n", + "Available models for dTdtl-as-from-tntr amip EmonZ : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'EC-Earth3', 'GFDL-ESM4', 'INM-CM4-8', 'INM-CM5-0', 'MPI-ESM-1-2-HAM']\n", + "Available models for dTdtl-cs-from-tntr amip EmonZ : ['CESM2', 'CESM2-FV2', 'CESM2-WACCM', 'CESM2-WACCM-FV2', 'EC-Earth3', 'GFDL-ESM4', 'IPSL-CM6A-LR', 'MIROC6']\n", + "Available models for dTdtl-cs-from-tntr amip-p4K EmonZ : ['MIROC6']\n" + ] + } + ], + "source": [ + "for var in [\"dTdt-as-from-flx\", \"dTdt-cs-from-flx\", \"dTdts-as-from-flx\", \"dTdts-cs-from-flx\", \"dTdtl-as-from-flx\", \"dTdtl-cs-from-flx\",\n", + " \"dTdt-as-from-tntr\", \"dTdt-cs-from-tntr\", \"dTdts-as-from-tntr\", \"dTdts-cs-from-tntr\", \"dTdtl-as-from-tntr\", \"dTdtl-cs-from-tntr\"]:\n", + " for tab in [\"CFmon\", \"AERmon\", \"EmonZ\"]:\n", + " for exp in [\"amip\", \"amip-p4K\"]:\n", + " modlist = available_models(var, exp, tab)\n", + " # generate plot if modlist is not empty\n", + " if len(modlist)>0:\n", + " qc_plot(var=var, exp=exp, tab=tab)" + ] + }, + { + "cell_type": "markdown", + "id": "a55b485b-2346-4ec5-8dfc-7ce6611b7cd3", + "metadata": {}, + "source": [ + "## Merge all pdfs into a single pdf and delete individual pdfs" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f5eb2803-020f-492c-87d9-bd3c30608d69", + "metadata": {}, + "outputs": [], + "source": [ + "!rm -f qualitycheck_allpdfs.pdf\n", + "!convert qualitycheck*pdf qualitycheck_allpdfs.pdf\n", + "!rm -f qualitycheck_dTdt-*_*_*.pdf" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/analysis/qualitycheck_allpdfs.pdf b/analysis/qualitycheck_allpdfs.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fc4022cc233dfdf353ede352f48b104709d2fb06 Binary files /dev/null and b/analysis/qualitycheck_allpdfs.pdf differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_BCC-CSM2-MR.nc b/analysis/vgrid_information/vgrid_fulllevels_BCC-CSM2-MR.nc new file mode 100644 index 0000000000000000000000000000000000000000..ad833eb8d52a5aa1cdebb734bb942a42e94ef0d3 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_BCC-CSM2-MR.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_BCC-ESM1.nc b/analysis/vgrid_information/vgrid_fulllevels_BCC-ESM1.nc new file mode 100644 index 0000000000000000000000000000000000000000..76f1e966c58e213e4fd54c9f50ced7b1502af6ec Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_BCC-ESM1.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_CESM2-FV2.nc b/analysis/vgrid_information/vgrid_fulllevels_CESM2-FV2.nc new file mode 100644 index 0000000000000000000000000000000000000000..1a79cc07b3f46e2193e4dc9072b983b773cb0b81 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_CESM2-FV2.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_CESM2-WACCM-FV2.nc b/analysis/vgrid_information/vgrid_fulllevels_CESM2-WACCM-FV2.nc new file mode 100644 index 0000000000000000000000000000000000000000..c3490b34816ec995d366641af425aa8b22b2bbe4 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_CESM2-WACCM-FV2.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_CESM2-WACCM.nc b/analysis/vgrid_information/vgrid_fulllevels_CESM2-WACCM.nc new file mode 100644 index 0000000000000000000000000000000000000000..7b74b96af0aceebbe3c99e340ce9fdee6aca5eb4 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_CESM2-WACCM.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_CESM2.nc b/analysis/vgrid_information/vgrid_fulllevels_CESM2.nc new file mode 100644 index 0000000000000000000000000000000000000000..2b334557894898fa7b0ca09c79d3ab46d9536cb2 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_CESM2.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_CNRM-CM6-1.nc b/analysis/vgrid_information/vgrid_fulllevels_CNRM-CM6-1.nc new file mode 100644 index 0000000000000000000000000000000000000000..87085f647db97c75f182dc4fdfcc8b118544a234 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_CNRM-CM6-1.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_CNRM-ESM2-1.nc b/analysis/vgrid_information/vgrid_fulllevels_CNRM-ESM2-1.nc new file mode 100644 index 0000000000000000000000000000000000000000..ffd33d55bfd2ec726895b0fb37b5779e18836f07 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_CNRM-ESM2-1.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_GFDL-AM4.nc b/analysis/vgrid_information/vgrid_fulllevels_GFDL-AM4.nc new file mode 100644 index 0000000000000000000000000000000000000000..929dd402d2556c3a6758b2beff5d77b2517ef1e2 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_GFDL-AM4.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_GFDL-CM4.nc b/analysis/vgrid_information/vgrid_fulllevels_GFDL-CM4.nc new file mode 100644 index 0000000000000000000000000000000000000000..a79cbe8df4b5b5dfa78be97155d1c7ed5495788c Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_GFDL-CM4.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_INM-CM4-8.nc b/analysis/vgrid_information/vgrid_fulllevels_INM-CM4-8.nc new file mode 100644 index 0000000000000000000000000000000000000000..3282108818decd95773422b333966d0efd5b746e Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_INM-CM4-8.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_INM-CM5-0.nc b/analysis/vgrid_information/vgrid_fulllevels_INM-CM5-0.nc new file mode 100644 index 0000000000000000000000000000000000000000..659b39c1bb28d6296f914bd97a65ee001606d43f Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_INM-CM5-0.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_IPSL-CM6A-LR.nc b/analysis/vgrid_information/vgrid_fulllevels_IPSL-CM6A-LR.nc new file mode 100644 index 0000000000000000000000000000000000000000..a4f6b9432a29e69697aae163bb5799b7f5758b61 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_IPSL-CM6A-LR.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_MIROC-ES2L.nc b/analysis/vgrid_information/vgrid_fulllevels_MIROC-ES2L.nc new file mode 100644 index 0000000000000000000000000000000000000000..1aec48d51647d032eccf16afb15abebc2a3da49c Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_MIROC-ES2L.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_MIROC6.nc b/analysis/vgrid_information/vgrid_fulllevels_MIROC6.nc new file mode 100644 index 0000000000000000000000000000000000000000..06059a7c78d3488e8150ae24f80da33ed028fca6 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_MIROC6.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_MPI-ESM-1-2-HAM.nc b/analysis/vgrid_information/vgrid_fulllevels_MPI-ESM-1-2-HAM.nc new file mode 100644 index 0000000000000000000000000000000000000000..a0cfd9103d1a5cbcf8fb74e5f322465adabbe308 Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_MPI-ESM-1-2-HAM.nc differ diff --git a/analysis/vgrid_information/vgrid_fulllevels_MRI-ESM2-0.nc b/analysis/vgrid_information/vgrid_fulllevels_MRI-ESM2-0.nc new file mode 100644 index 0000000000000000000000000000000000000000..f9aaa6608f72affa6fda1fe74221b010adc4f65f Binary files /dev/null and b/analysis/vgrid_information/vgrid_fulllevels_MRI-ESM2-0.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_BCC-CSM2-MR.nc b/analysis/vgrid_information/vgrid_halflevels_BCC-CSM2-MR.nc new file mode 100644 index 0000000000000000000000000000000000000000..9da64fc851d187dbd67991313206a3f1b1b1fe55 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_BCC-CSM2-MR.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_CNRM-CM6-1.nc b/analysis/vgrid_information/vgrid_halflevels_CNRM-CM6-1.nc new file mode 100644 index 0000000000000000000000000000000000000000..9212fac5800589e6928afa7d0587746b5c61817a Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_CNRM-CM6-1.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_CNRM-ESM2-1.nc b/analysis/vgrid_information/vgrid_halflevels_CNRM-ESM2-1.nc new file mode 100644 index 0000000000000000000000000000000000000000..c512d369ba3c9cc2881f27b72f49623dd6c4fce6 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_CNRM-ESM2-1.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_GFDL-CM4.nc b/analysis/vgrid_information/vgrid_halflevels_GFDL-CM4.nc new file mode 100644 index 0000000000000000000000000000000000000000..1145ba4c341a23a296c74db971e7b9bea75a4383 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_GFDL-CM4.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_INM-CM4-8.nc b/analysis/vgrid_information/vgrid_halflevels_INM-CM4-8.nc new file mode 100644 index 0000000000000000000000000000000000000000..58511549374ba9281163ea2e7c4910fe1794367c Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_INM-CM4-8.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_INM-CM5-0.nc b/analysis/vgrid_information/vgrid_halflevels_INM-CM5-0.nc new file mode 100644 index 0000000000000000000000000000000000000000..973ec821647ca99177d330243d196f084004a957 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_INM-CM5-0.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_IPSL-CM6A-LR.nc b/analysis/vgrid_information/vgrid_halflevels_IPSL-CM6A-LR.nc new file mode 100644 index 0000000000000000000000000000000000000000..65a9738b2eb9cba5088c7cbe93df9f26ab469e97 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_IPSL-CM6A-LR.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_MIROC-ES2L.nc b/analysis/vgrid_information/vgrid_halflevels_MIROC-ES2L.nc new file mode 100644 index 0000000000000000000000000000000000000000..fb2bc7f2064ff8d18606fb38ab05e92eb754a93c Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_MIROC-ES2L.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_MIROC6.nc b/analysis/vgrid_information/vgrid_halflevels_MIROC6.nc new file mode 100644 index 0000000000000000000000000000000000000000..b0a6309b37ffac8a818224748f1f4b0c3baff3d7 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_MIROC6.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_MPI-ESM-1-2-HAM.nc b/analysis/vgrid_information/vgrid_halflevels_MPI-ESM-1-2-HAM.nc new file mode 100644 index 0000000000000000000000000000000000000000..8bfb65749194d8a1d2894ca74c5248648f635723 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_MPI-ESM-1-2-HAM.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_MPI-ESM1-2-HR.nc b/analysis/vgrid_information/vgrid_halflevels_MPI-ESM1-2-HR.nc new file mode 100644 index 0000000000000000000000000000000000000000..2845dccf5f5db4e5148990e46552f3723e72acfd Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_MPI-ESM1-2-HR.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_MPI-ESM1-2-LR.nc b/analysis/vgrid_information/vgrid_halflevels_MPI-ESM1-2-LR.nc new file mode 100644 index 0000000000000000000000000000000000000000..e1f457db66d96bfc9bc0f5ef70de13c4c0d98afc Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_MPI-ESM1-2-LR.nc differ diff --git a/analysis/vgrid_information/vgrid_halflevels_MRI-ESM2-0.nc b/analysis/vgrid_information/vgrid_halflevels_MRI-ESM2-0.nc new file mode 100644 index 0000000000000000000000000000000000000000..251a6be104a2de31781e6342765b1fa02cc7b108 Binary files /dev/null and b/analysis/vgrid_information/vgrid_halflevels_MRI-ESM2-0.nc differ diff --git a/cfmip2-sst/cfmip2_4k_patterned_sst_forcing.vn1.0.nc b/cfmip2-sst/cfmip2_4k_patterned_sst_forcing.vn1.0.nc new file mode 100644 index 0000000000000000000000000000000000000000..4a045b3e136a432a0da26a8aefe733d17d796fab Binary files /dev/null and b/cfmip2-sst/cfmip2_4k_patterned_sst_forcing.vn1.0.nc differ diff --git a/data-download/GFDL-AM4_amip_ps.ipynb b/data-download/GFDL-AM4_amip_ps.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..6beb8604312ab3eea46efb956e8e1322d5db6e85 --- /dev/null +++ b/data-download/GFDL-AM4_amip_ps.ipynb @@ -0,0 +1,172 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "283a8ae6-b44b-4f43-bb81-5368c0845922", + "metadata": {}, + "source": [ + "## Manual download of ps variable for GFDL-AM4 amip simulation since the model do not have ps included in the tntr files" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5b92e2fe-b162-48f7-b2c8-9e2a347de968", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "sys.path.append(\"/users/staff/avoigt/cmip-acre/analysis\")\n", + "import cmip6radheating\n", + "\n", + "exp=\"amip\"\n", + "tab=\"AERmon\"\n", + "\n", + "flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab, mod=\"GFDL-AM4\")\n", + "ds_tntrs = cmip6radheating.load_data(flist_tntrs)\n", + "ds_tntrl = cmip6radheating.load_data(flist_tntrl)\n", + "\n", + "flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab, mod=\"GFDL-AM4\")\n", + "ds_tntrscs = cmip6radheating.load_data(flist_tntrscs)\n", + "ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1698cb7f-1728-4113-8a8d-71435f949012", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_GFDL-AM4_amip_r1i1p1f1_gr1_198001-201412.nc']\n", + "['/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_GFDL-AM4_amip_r1i1p1f1_gr1_198001-201412.nc']\n", + "[]\n", + "[]\n" + ] + } + ], + "source": [ + "## Which ps-files do we need to retrieve from ESGF?\n", + "print(flist_tntrs)\n", + "print(flist_tntrl)\n", + "print(flist_tntrscs)\n", + "print(flist_tntrlcs)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c6b0800b-e35d-4e5c-9a14-8f67bc0a4adc", + "metadata": {}, + "outputs": [], + "source": [ + "base = \"http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true\"\n", + "request = base + \"&experiment_id=amip&variable=ps&source_id=GFDL-AM4\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "44149307-0044-4c3b-b17c-f86da84c21a0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-03-15 17:46:48-- https://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true&experiment_id=amip&variable=ps&source_id=GFDL-AM4\n", + "Resolving esgf-data.dkrz.de (esgf-data.dkrz.de)... 136.172.34.77\n", + "Connecting to esgf-data.dkrz.de (esgf-data.dkrz.de)|136.172.34.77|:443... connected.\n", + "HTTP request sent, awaiting response... 200 200\n", + "Length: 33801 (33K) [text/x-sh]\n", + "Saving to: ‘wget.sh-ps-amip-GFDL-AM4’\n", + "\n", + "wget.sh-ps-amip-GFD 100%[===================>] 33.01K --.-KB/s in 0.03s \n", + "\n", + "2023-03-15 17:46:50 (1.09 MB/s) - ‘wget.sh-ps-amip-GFDL-AM4’ saved [33801/33801]\n", + "\n" + ] + } + ], + "source": [ + "# -O allows us to specify the name of the generated bash-wget script\n", + "!wget \"$request\" -O wget.sh-ps-amip-GFDL-AM4" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "dbaff5e7-1c23-4cbd-84e1-a7c6a5f031dc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mnt/scratch/scratch/avoigt/cmip6-acre-data\n", + "********************************************************************************\n", + "* *\n", + "* Note that new functionality to allow authentication without the need for *\n", + "* certificates is available with this version of the wget script. To enable, *\n", + "* use the \"-H\" option and enter your OpenID and password when prompted: *\n", + "* *\n", + "* $ wget.sh-ps-amip-GFDL-AM4 -H [options...] *\n", + "* *\n", + "* For a full description of the available options use the help option: *\n", + "* *\n", + "* $ wget.sh-ps-amip-GFDL-AM4 -h *\n", + "* *\n", + "********************************************************************************\n", + "Running wget.sh-ps-amip-GFDL-AM4 version: 1.3.2\n", + "Use wget.sh-ps-amip-GFDL-AM4 -h for help.\n", + "\n", + "There were files with the same name which were requested to be download to the same directory. To avoid overwriting the previous downloaded one they were skipped.\n", + "Please use the parameter 'download_structure' to set up unique directories for them.\n", + "Script created for 1 file(s)\n", + "(The count won't match if you manually edit this file!)\n", + "\n", + "\n", + "\n", + "CMIP6/amip/ps/Amon/ps_Amon_GFDL-AM4_amip_r1i1p1f1_gr1_198001-201412.nc ...Already downloaded and verified\n", + "done\n", + "/mnt/users/staff/avoigt/cmip-acre/data-download\n" + ] + } + ], + "source": [ + "# -s: allows us to retrieve unrestricted data without providing ESGF\n", + "# -n: triggers a dry run that does not actually downloads data but lists all files that would be downloaded\n", + "# -h: provides help information for bash wget script\n", + "%cd /scratch/das/avoigt/cmip6-acre-data/\n", + "!bash /mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-ps-amip-GFDL-AM4 -s\n", + "%cd /mnt/users/staff/avoigt/cmip-acre/data-download/" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/data-download/GFDL-CM4_amip_ps.ipynb b/data-download/GFDL-CM4_amip_ps.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..23b6d235ce55954675f768d6d76a99d7f24b7d53 --- /dev/null +++ b/data-download/GFDL-CM4_amip_ps.ipynb @@ -0,0 +1,209 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "283a8ae6-b44b-4f43-bb81-5368c0845922", + "metadata": {}, + "source": [ + "## Manual download of ps variable for GFDL-CM4 amip simulation since the model do not have ps included in the tntr files" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "5b92e2fe-b162-48f7-b2c8-9e2a347de968", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "sys.path.append(\"/users/staff/avoigt/cmip-acre/analysis\")\n", + "import cmip6radheating\n", + "\n", + "exp=\"amip\"\n", + "tab=\"AERmon\"\n", + "\n", + "flist_tntrs, flist_tntrl = cmip6radheating.filelist_allsky_tntr(exp=exp, tab=tab, mod=\"GFDL-CM4\")\n", + "ds_tntrs = cmip6radheating.load_data(flist_tntrs)\n", + "ds_tntrl = cmip6radheating.load_data(flist_tntrl)\n", + "\n", + "flist_tntrscs, flist_tntrlcs = cmip6radheating.filelist_clrsky_tntr(exp=exp, tab=tab, mod=\"GFDL-CM4\")\n", + "ds_tntrscs = cmip6radheating.load_data(flist_tntrscs)\n", + "ds_tntrlcs = cmip6radheating.load_data(flist_tntrlcs)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1698cb7f-1728-4113-8a8d-71435f949012", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_200901-201412.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_197901-198412.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_198501-199012.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_199701-200212.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_200301-200812.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrs/AERmon/tntrs_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_199101-199612.nc']\n", + "['/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_200901-201412.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_197901-198412.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_198501-199012.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_199701-200212.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_200301-200812.nc', '/scratch/das/avoigt/cmip6-acre-data/CMIP6/amip/tntrl/AERmon/tntrl_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_199101-199612.nc']\n", + "[]\n", + "[]\n" + ] + } + ], + "source": [ + "## Which ps-files do we need to retrieve from ESGF?\n", + "print(flist_tntrs)\n", + "print(flist_tntrl)\n", + "print(flist_tntrscs)\n", + "print(flist_tntrlcs)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c6b0800b-e35d-4e5c-9a14-8f67bc0a4adc", + "metadata": {}, + "outputs": [], + "source": [ + "base = \"http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true\"\n", + "request = base + \"&experiment_id=amip&variable=ps&source_id=GFDL-CM4\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "44149307-0044-4c3b-b17c-f86da84c21a0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-03-15 17:44:39-- https://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true&experiment_id=amip&variable=ps&source_id=GFDL-CM4\n", + "Resolving esgf-data.dkrz.de (esgf-data.dkrz.de)... 136.172.34.77\n", + "Connecting to esgf-data.dkrz.de (esgf-data.dkrz.de)|136.172.34.77|:443... connected.\n", + "HTTP request sent, awaiting response... 200 200\n", + "Length: 43255 (42K) [text/x-sh]\n", + "Saving to: ‘wget.sh-ps-amip-GFDL-CM4’\n", + "\n", + "wget.sh-ps-amip-GFD 100%[===================>] 42.24K --.-KB/s in 0.06s \n", + "\n", + "2023-03-15 17:44:40 (722 KB/s) - ‘wget.sh-ps-amip-GFDL-CM4’ saved [43255/43255]\n", + "\n" + ] + } + ], + "source": [ + "# -O allows us to specify the name of the generated bash-wget script\n", + "!wget \"$request\" -O wget.sh-ps-amip-GFDL-CM4" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "dbaff5e7-1c23-4cbd-84e1-a7c6a5f031dc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mnt/scratch/scratch/avoigt/cmip6-acre-data\n", + "********************************************************************************\n", + "* *\n", + "* Note that new functionality to allow authentication without the need for *\n", + "* certificates is available with this version of the wget script. To enable, *\n", + "* use the \"-H\" option and enter your OpenID and password when prompted: *\n", + "* *\n", + "* $ wget.sh-ps-amip-GFDL-CM4 -H [options...] *\n", + "* *\n", + "* For a full description of the available options use the help option: *\n", + "* *\n", + "* $ wget.sh-ps-amip-GFDL-CM4 -h *\n", + "* *\n", + "********************************************************************************\n", + "Running wget.sh-ps-amip-GFDL-CM4 version: 1.3.2\n", + "Use wget.sh-ps-amip-GFDL-CM4 -h for help.\n", + "\n", + "There were files with the same name which were requested to be download to the same directory. To avoid overwriting the previous downloaded one they were skipped.\n", + "Please use the parameter 'download_structure' to set up unique directories for them.\n", + "Script created for 30 file(s)\n", + "(The count won't match if you manually edit this file!)\n", + "\n", + "\n", + "\n", + "CMIP6/amip/ps/AERmon/ps_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_197901-198412.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/AERmon/ps_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_198501-199012.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/AERmon/ps_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_199101-199612.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/AERmon/ps_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_199701-200212.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/AERmon/ps_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_200301-200812.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/AERmon/ps_AERmon_GFDL-CM4_amip_r1i1p1f1_gr1_200901-201412.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_197901-198412.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_198501-199012.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_199101-199612.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_199701-200212.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_200301-200812.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Amon/ps_Amon_GFDL-CM4_amip_r1i1p1f1_gr1_200901-201412.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFday/ps_CFday_GFDL-CM4_amip_r1i1p1f1_gr2_19790101-19841231.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFday/ps_CFday_GFDL-CM4_amip_r1i1p1f1_gr2_19850101-19901231.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFday/ps_CFday_GFDL-CM4_amip_r1i1p1f1_gr2_19910101-19961231.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFday/ps_CFday_GFDL-CM4_amip_r1i1p1f1_gr2_19970101-20021231.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFday/ps_CFday_GFDL-CM4_amip_r1i1p1f1_gr2_20030101-20081231.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFday/ps_CFday_GFDL-CM4_amip_r1i1p1f1_gr2_20090101-20141231.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFmon/ps_CFmon_GFDL-CM4_amip_r1i1p1f1_gr1_197901-198412.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFmon/ps_CFmon_GFDL-CM4_amip_r1i1p1f1_gr1_198501-199012.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFmon/ps_CFmon_GFDL-CM4_amip_r1i1p1f1_gr1_199101-199612.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFmon/ps_CFmon_GFDL-CM4_amip_r1i1p1f1_gr1_199701-200212.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFmon/ps_CFmon_GFDL-CM4_amip_r1i1p1f1_gr1_200301-200812.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/CFmon/ps_CFmon_GFDL-CM4_amip_r1i1p1f1_gr1_200901-201412.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Emon/ps_Emon_GFDL-CM4_amip_r1i1p1f1_gr1_197901-198412.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Emon/ps_Emon_GFDL-CM4_amip_r1i1p1f1_gr1_198501-199012.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Emon/ps_Emon_GFDL-CM4_amip_r1i1p1f1_gr1_199101-199612.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Emon/ps_Emon_GFDL-CM4_amip_r1i1p1f1_gr1_199701-200212.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Emon/ps_Emon_GFDL-CM4_amip_r1i1p1f1_gr1_200301-200812.nc ...Already downloaded and verified\n", + "CMIP6/amip/ps/Emon/ps_Emon_GFDL-CM4_amip_r1i1p1f1_gr1_200901-201412.nc ...Already downloaded and verified\n", + "done\n", + "/mnt/users/staff/avoigt/cmip-acre/data-download\n" + ] + } + ], + "source": [ + "# -s: allows us to retrieve unrestricted data without providing ESGF\n", + "# -n: triggers a dry run that does not actually downloads data but lists all files that would be downloaded\n", + "# -h: provides help information for bash wget script\n", + "%cd /scratch/das/avoigt/cmip6-acre-data/\n", + "!bash /mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-ps-amip-GFDL-CM4 -s\n", + "%cd /mnt/users/staff/avoigt/cmip-acre/data-download/" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d619458c-d80d-486e-a18b-0e5570aef10d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/data-download/GFDL-CM4_amipp4K_amipfuture4K_ps.ipynb b/data-download/GFDL-CM4_amipp4K_amipfuture4K_ps.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..35743bba6fea14cd10e21e68c5a944d2901d1db4 --- /dev/null +++ b/data-download/GFDL-CM4_amipp4K_amipfuture4K_ps.ipynb @@ -0,0 +1,446 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "283a8ae6-b44b-4f43-bb81-5368c0845922", + "metadata": {}, + "source": [ + "## Manual download of ps variable for GFDL-CM4 amip-p4K and amip-future4K simulation since the model does not have ps included in the tntr files\n", + "\n", + "We need the following ps values:\n", + "\n", + "### amip-p4K\n", + "\n", + " * tntr from CFmon\n", + " * tntrs, tntrl from AERmon\n", + " * tntrscs, tntrlcs from Emon\n", + " \n", + "### amip-future4K\n", + " \n", + " * tntr from CFmon\n", + " * tntrs, tntrscs, tntrl, tntrlcs are from EmonZ and are already on pressure levels\n", + " \n", + "The approach is as follows: We simply download all ps files for the amip-p4K and amip-futur4K simulations that are available from ESGF for GFDL-CM4." + ] + }, + { + "cell_type": "markdown", + "id": "2f209d37-e296-429e-bec1-3adbfba77d2b", + "metadata": {}, + "source": [ + "## amip-p4K" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "54cb7d89-4ce5-4ca2-ba3a-d64edade5283", + "metadata": {}, + "outputs": [], + "source": [ + "base = \"http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true\"\n", + "request = base + \"&experiment_id=amip-p4K&variable=ps&source_id=GFDL-CM4\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c044a59d-33da-466b-ae41-afb55278a1c2", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:17:44-- https://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true&experiment_id=amip-p4K&variable=ps&source_id=GFDL-CM4\n", + "Resolving esgf-data.dkrz.de (esgf-data.dkrz.de)... 136.172.34.77\n", + "Connecting to esgf-data.dkrz.de (esgf-data.dkrz.de)|136.172.34.77|:443... connected.\n", + "HTTP request sent, awaiting response... 200 200\n", + "Length: 36262 (35K) [text/x-sh]\n", + "Saving to: ‘wget.sh-ps-amip-p4K-GFDL-CM4’\n", + "\n", + "wget.sh-ps-amip-p4K 100%[===================>] 35.41K --.-KB/s in 0.03s \n", + "\n", + "2023-06-04 12:17:45 (1.15 MB/s) - ‘wget.sh-ps-amip-p4K-GFDL-CM4’ saved [36262/36262]\n", + "\n" + ] + } + ], + "source": [ + "# -O allows us to specify the name of the generated bash-wget script\n", + "!wget \"$request\" -O wget.sh-ps-amip-p4K-GFDL-CM4" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "94192835-28f7-457c-aab0-96a0e4ff7e28", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mnt/scratch/scratch/avoigt/cmip6-acre-data\n", + "********************************************************************************\n", + "* *\n", + "* Note that new functionality to allow authentication without the need for *\n", + "* certificates is available with this version of the wget script. To enable, *\n", + "* use the \"-H\" option and enter your OpenID and password when prompted: *\n", + "* *\n", + "* $ wget.sh-ps-amip-p4K-GFDL-CM4 -H [options...] *\n", + "* *\n", + "* For a full description of the available options use the help option: *\n", + "* *\n", + "* $ wget.sh-ps-amip-p4K-GFDL-CM4 -h *\n", + "* *\n", + "********************************************************************************\n", + "Running wget.sh-ps-amip-p4K-GFDL-CM4 version: 1.3.2\n", + "Use wget.sh-ps-amip-p4K-GFDL-CM4 -h for help.\n", + "\n", + "There were files with the same name which were requested to be download to the same directory. To avoid overwriting the previous downloaded one they were skipped.\n", + "Please use the parameter 'download_structure' to set up unique directories for them.\n", + "Script created for 8 file(s)\n", + "(The count won't match if you manually edit this file!)\n", + "\n", + "\n", + "\n", + "CMIP6/amip-p4K/ps/AERmon/ps_AERmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:17:51-- https://esgf-data1.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/AERmon/ps/gr1/v20180701/ps_AERmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc\n", + "Resolving esgf-data1.llnl.gov (esgf-data1.llnl.gov)... 198.128.245.147\n", + "Connecting to esgf-data1.llnl.gov (esgf-data1.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 51123670 (49M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/AERmon/ps_AERmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/A 100%[===================>] 48.75M 14.8MB/s in 3.9s \n", + "\n", + "2023-06-04 12:17:56 (12.4 MB/s) - ‘CMIP6/amip-p4K/ps/AERmon/ps_AERmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’ saved [51123670/51123670]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-p4K/ps/Amon/ps_Amon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:17:56-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/Amon/ps/gr1/v20180701/ps_Amon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 51123672 (49M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/Amon/ps_Amon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/A 100%[===================>] 48.75M 9.70MB/s in 5.9s \n", + "\n", + "2023-06-04 12:18:03 (8.27 MB/s) - ‘CMIP6/amip-p4K/ps/Amon/ps_Amon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’ saved [51123672/51123672]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19790101-19981231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:18:03-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/CFday/ps/gr1/v20180701/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19790101-19981231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 888038023 (847M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19790101-19981231.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/C 100%[===================>] 846.90M 9.86MB/s in 67s \n", + "\n", + "2023-06-04 12:19:11 (12.7 MB/s) - ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19790101-19981231.nc’ saved [888038023/888038023]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19990101-20141231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:19:13-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/CFday/ps/gr1/v20180701/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19990101-20141231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 710218892 (677M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19990101-20141231.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/C 100%[===================>] 677.32M 10.9MB/s in 46s \n", + "\n", + "2023-06-04 12:20:01 (14.6 MB/s) - ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_19990101-20141231.nc’ saved [710218892/710218892]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19790101-19981231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:20:03-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/CFday/ps/gr2/v20180701/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19790101-19981231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 238191683 (227M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19790101-19981231.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/C 100%[===================>] 227.16M 13.2MB/s in 21s \n", + "\n", + "2023-06-04 12:20:25 (10.9 MB/s) - ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19790101-19981231.nc’ saved [238191683/238191683]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19990101-20141231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:20:25-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/CFday/ps/gr2/v20180701/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19990101-20141231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 190551117 (182M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19990101-20141231.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/C 100%[===================>] 181.72M 14.5MB/s in 18s \n", + "\n", + "2023-06-04 12:20:44 (10.3 MB/s) - ‘CMIP6/amip-p4K/ps/CFday/ps_CFday_GFDL-CM4_amip-p4K_r1i1p1f1_gr2_19990101-20141231.nc’ saved [190551117/190551117]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-p4K/ps/CFmon/ps_CFmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:20:45-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/CFmon/ps/gr1/v20180701/ps_CFmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 51123669 (49M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/CFmon/ps_CFmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/C 100%[===================>] 48.75M 11.8MB/s in 5.4s \n", + "\n", + "2023-06-04 12:20:51 (9.01 MB/s) - ‘CMIP6/amip-p4K/ps/CFmon/ps_CFmon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’ saved [51123669/51123669]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-p4K/ps/Emon/ps_Emon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:20:51-- https://esgf-data1.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-p4K/r1i1p1f1/Emon/ps/gr1/v20180701/ps_Emon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc\n", + "Resolving esgf-data1.llnl.gov (esgf-data1.llnl.gov)... 198.128.245.147\n", + "Connecting to esgf-data1.llnl.gov (esgf-data1.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 51123672 (49M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-p4K/ps/Emon/ps_Emon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’\n", + "\n", + "CMIP6/amip-p4K/ps/E 100%[===================>] 48.75M 5.40MB/s in 8.3s \n", + "\n", + "2023-06-04 12:21:01 (5.85 MB/s) - ‘CMIP6/amip-p4K/ps/Emon/ps_Emon_GFDL-CM4_amip-p4K_r1i1p1f1_gr1_197901-201412.nc’ saved [51123672/51123672]\n", + "\n", + " sha256 ok. done!\n", + "done\n", + "/mnt/users/staff/avoigt/cmip-acre/data-download\n" + ] + } + ], + "source": [ + "# -s: allows us to retrieve unrestricted data without providing ESGF\n", + "# -n: triggers a dry run that does not actually downloads data but lists all files that would be downloaded\n", + "# -h: provides help information for bash wget script\n", + "%cd /scratch/das/avoigt/cmip6-acre-data/\n", + "!bash /mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-ps-amip-p4K-GFDL-CM4 -s\n", + "%cd /mnt/users/staff/avoigt/cmip-acre/data-download/" + ] + }, + { + "cell_type": "markdown", + "id": "d6ac0fc3-5735-430f-bca8-eb4c86a9ed4b", + "metadata": {}, + "source": [ + "## amip-future4K" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a34bd18e-7e03-49df-b46a-f9ebf4e02a80", + "metadata": {}, + "outputs": [], + "source": [ + "base = \"http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true\"\n", + "request = base + \"&experiment_id=amip-future4K&variable=ps&source_id=GFDL-CM4\"" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a266b5b5-cd07-4c91-b1ed-bde3001c16cb", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:21:01-- https://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true&experiment_id=amip-future4K&variable=ps&source_id=GFDL-CM4\n", + "Resolving esgf-data.dkrz.de (esgf-data.dkrz.de)... 136.172.34.77\n", + "Connecting to esgf-data.dkrz.de (esgf-data.dkrz.de)|136.172.34.77|:443... connected.\n", + "HTTP request sent, awaiting response... 200 200\n", + "Length: 35698 (35K) [text/x-sh]\n", + "Saving to: ‘wget.sh-ps-amip-future4K-GFDL-CM4’\n", + "\n", + "wget.sh-ps-amip-fut 100%[===================>] 34.86K --.-KB/s in 0.03s \n", + "\n", + "2023-06-04 12:21:03 (1.13 MB/s) - ‘wget.sh-ps-amip-future4K-GFDL-CM4’ saved [35698/35698]\n", + "\n" + ] + } + ], + "source": [ + "# -O allows us to specify the name of the generated bash-wget script\n", + "!wget \"$request\" -O wget.sh-ps-amip-future4K-GFDL-CM4" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "507f28da-12f5-4088-98ca-7057f1c82b4c", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mnt/scratch/scratch/avoigt/cmip6-acre-data\n", + "********************************************************************************\n", + "* *\n", + "* Note that new functionality to allow authentication without the need for *\n", + "* certificates is available with this version of the wget script. To enable, *\n", + "* use the \"-H\" option and enter your OpenID and password when prompted: *\n", + "* *\n", + "* $ wget.sh-ps-amip-future4K-GFDL-CM4 -H [options...] *\n", + "* *\n", + "* For a full description of the available options use the help option: *\n", + "* *\n", + "* $ wget.sh-ps-amip-future4K-GFDL-CM4 -h *\n", + "* *\n", + "********************************************************************************\n", + "Running wget.sh-ps-amip-future4K-GFDL-CM4 version: 1.3.2\n", + "Use wget.sh-ps-amip-future4K-GFDL-CM4 -h for help.\n", + "\n", + "There were files with the same name which were requested to be download to the same directory. To avoid overwriting the previous downloaded one they were skipped.\n", + "Please use the parameter 'download_structure' to set up unique directories for them.\n", + "Script created for 6 file(s)\n", + "(The count won't match if you manually edit this file!)\n", + "\n", + "\n", + "\n", + "CMIP6/amip-future4K/ps/Amon/ps_Amon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:21:04-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-future4K/r1i1p1f1/Amon/ps/gr1/v20180701/ps_Amon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 51135950 (49M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-future4K/ps/Amon/ps_Amon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc’\n", + "\n", + "CMIP6/amip-future4K 100%[===================>] 48.77M 7.55MB/s in 7.0s \n", + "\n", + "2023-06-04 12:21:13 (6.93 MB/s) - ‘CMIP6/amip-future4K/ps/Amon/ps_Amon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc’ saved [51135950/51135950]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19790101-19981231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:21:13-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-future4K/r1i1p1f1/CFday/ps/gr1/v20180701/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19790101-19981231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 888198919 (847M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19790101-19981231.nc’\n", + "\n", + "CMIP6/amip-future4K 100%[===================>] 847.05M 7.07MB/s in 75s \n", + "\n", + "2023-06-04 12:22:29 (11.2 MB/s) - ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19790101-19981231.nc’ saved [888198919/888198919]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19990101-20141231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:22:32-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-future4K/r1i1p1f1/CFday/ps/gr1/v20180701/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19990101-20141231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 710416979 (678M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19990101-20141231.nc’\n", + "\n", + "CMIP6/amip-future4K 100%[===================>] 677.51M 10.4MB/s in 64s \n", + "\n", + "2023-06-04 12:23:36 (10.6 MB/s) - ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_19990101-20141231.nc’ saved [710416979/710416979]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19790101-19981231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:23:38-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-future4K/r1i1p1f1/CFday/ps/gr2/v20180701/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19790101-19981231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 238216903 (227M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19790101-19981231.nc’\n", + "\n", + "CMIP6/amip-future4K 100%[===================>] 227.18M 15.5MB/s in 18s \n", + "\n", + "2023-06-04 12:23:57 (12.4 MB/s) - ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19790101-19981231.nc’ saved [238216903/238216903]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19990101-20141231.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:23:58-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-future4K/r1i1p1f1/CFday/ps/gr2/v20180701/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19990101-20141231.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 190592524 (182M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19990101-20141231.nc’\n", + "\n", + "CMIP6/amip-future4K 100%[===================>] 181.76M 8.10MB/s in 19s \n", + "\n", + "2023-06-04 12:24:17 (9.71 MB/s) - ‘CMIP6/amip-future4K/ps/CFday/ps_CFday_GFDL-CM4_amip-future4K_r1i1p1f1_gr2_19990101-20141231.nc’ saved [190592524/190592524]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6/amip-future4K/ps/CFmon/ps_CFmon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc ...Downloading\n", + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-06-04 12:24:18-- https://aims3.llnl.gov/thredds/fileServer/css03_data/CMIP6/CFMIP/NOAA-GFDL/GFDL-CM4/amip-future4K/r1i1p1f1/CFmon/ps/gr1/v20180701/ps_CFmon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc\n", + "Resolving aims3.llnl.gov (aims3.llnl.gov)... 198.128.245.147\n", + "Connecting to aims3.llnl.gov (aims3.llnl.gov)|198.128.245.147|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 51135947 (49M) [application/x-netcdf]\n", + "Saving to: ‘CMIP6/amip-future4K/ps/CFmon/ps_CFmon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc’\n", + "\n", + "CMIP6/amip-future4K 100%[===================>] 48.77M 8.29MB/s in 6.9s \n", + "\n", + "2023-06-04 12:24:26 (7.07 MB/s) - ‘CMIP6/amip-future4K/ps/CFmon/ps_CFmon_GFDL-CM4_amip-future4K_r1i1p1f1_gr1_197901-201412.nc’ saved [51135947/51135947]\n", + "\n", + " sha256 ok. done!\n", + "done\n", + "/mnt/users/staff/avoigt/cmip-acre/data-download\n" + ] + } + ], + "source": [ + "# -s: allows us to retrieve unrestricted data without providing ESGF\n", + "# -n: triggers a dry run that does not actually downloads data but lists all files that would be downloaded\n", + "# -h: provides help information for bash wget script\n", + "%cd /scratch/das/avoigt/cmip6-acre-data/\n", + "!bash /mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-ps-amip-future4K-GFDL-CM4 -s\n", + "%cd /mnt/users/staff/avoigt/cmip-acre/data-download/" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp 2023.1 - 3.10", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/data-download/cmip6-metagrid_batchdownload.py b/data-download/cmip6-metagrid_batchdownload.py new file mode 100644 index 0000000000000000000000000000000000000000..86576b4f3df4595b587a1ab5827eb57aec7c3966 --- /dev/null +++ b/data-download/cmip6-metagrid_batchdownload.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# coding: utf-8 +# # Download CMIP6 data from Metagrid in batch mode: many experiments, tables and variables + +# Import lists for experiment, table and variable. +import lists as lists +import subprocess +import os + +# which variables do we download, from which list and which experiments +varlist = lists.list_cl +#tablist=lists.list_tb +tablist = ["Amon"] # cl is in Amon +explist = lists.list_ex + +# Generate wget scripts. +#base = "http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=false" +base = "http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true" + +for var in varlist: + for exp in explist: + for tab in tablist: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + script="/users/staff/avoigt/cmip6-crh/data-download/wget.sh-"+exp+"-"+tab+"-"+var + subprocess.run(["wget", "--quiet", "-O", script, request]) + +# Execute wget scripts to retrieve data. Make sure to temporarily move to scratch disk for data download. +def valid_wget_script(script): + """ Tests if wget bash script is valid, i.e., does not contain "No files were found that matched the query" """ + valid=True + file = open(script, "r") + if file.read() == "No files were found that matched the query": + valid=False + file.close() + return valid + +os.chdir("/scratch/das/avoigt/cmip6-acre-data/") +for var in varlist: + for exp in explist: + for tab in tablist: + script="/users/staff/avoigt/cmip6-crh/data-download/wget.sh-"+exp+"-"+tab+"-"+var + if valid_wget_script(script): + fname="/users/staff/avoigt/cmip6-crh/data-download/wget.sh-"+exp+"-"+tab+"-"+var+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() +os.chdir("/users/staff/avoigt/cmip6-crh/data-download/") diff --git a/data-download/cmip6-metagrid_batchdownload_ptp_AERmon.py b/data-download/cmip6-metagrid_batchdownload_ptp_AERmon.py new file mode 100644 index 0000000000000000000000000000000000000000..97eaed668ca5a5f5d38ae691e0dc54902361379d --- /dev/null +++ b/data-download/cmip6-metagrid_batchdownload_ptp_AERmon.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# coding: utf-8 +# # Download CMIP6 data from Metagrid in batch mode: tropopause pressure from AERmon table, only consider models for which CRH can be calculated + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 cmip6-metagrid_batchdownload_ptp_AERmon.py + +# Import lists for experiment, table and variable. +import lists as lists +import subprocess +import os + +# Generate wget scripts. +base = "http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true" + +# list of models for which CRH can be calculated, taken from ../plots4paper/helpers.py +import sys +sys.path.append("../plots4paper/") +from helpers import models_amip, models_amipp4K, models_amipfuture4K + +tab="AERmon" +var="ptp" + +for exp in ["amip", "amip-p4K", "amip-future4K"]: + if exp == "amip": + for mod in models_amip: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + if exp == "amip-p4K": + for mod in models_amipp4K: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + if exp == "amip-future4K": + for mod in models_amipfuture4K: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + +# Execute wget scripts to retrieve data. Make sure to temporarily move to scratch disk for data download. +def valid_wget_script(script): + """ Tests if wget bash script is valid, i.e., does not contain "No files were found that matched the query" """ + valid=True + file = open(script, "r") + if file.read() == "No files were found that matched the query": + valid=False + file.close() + return valid + +os.chdir("/scratch/das/avoigt/cmip6-acre-data/") +for exp in ["amip", "amip-p4K", "amip-future4K"]: + if exp == "amip": + for mod in models_amip: + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() + if exp == "amip-p4K": + for mod in models_amipp4K: + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() + if exp == "amip-future4K": + for mod in models_amipfuture4K: + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() +os.chdir("/mnt/users/staff/avoigt/cmip-acre/data-download/") diff --git a/data-download/cmip6-metagrid_batchdownload_ta_Amon_CFmon.py b/data-download/cmip6-metagrid_batchdownload_ta_Amon_CFmon.py new file mode 100644 index 0000000000000000000000000000000000000000..6ad76c3ab3bb6053b109d5b12a5472e38de5f010 --- /dev/null +++ b/data-download/cmip6-metagrid_batchdownload_ta_Amon_CFmon.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# coding: utf-8 +# # Download CMIP6 data from Metagrid in batch mode: atmospheric temperature ta from Amon and CFmon tables, only consider models for which CRH can be calculated + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 cmip6-metagrid_batchdownload_ta_Amon_CFmon.py + +# Import lists for experiment, table and variable. +import lists as lists +import subprocess +import os + +# Generate wget scripts. +base = "http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true" + +# list of models for which CRH can be calculated, taken from ../plots4paper/helpers.py +import sys +sys.path.append("../plots4paper/") +from helpers import models_amip, models_amipp4K, models_amipfuture4K + +var="ta" + +for tab in ["Amon", "CFmon"]: + for exp in ["amip", "amip-p4K", "amip-future4K"]: + if exp == "amip": + for mod in models_amip: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + if exp == "amip-p4K": + for mod in models_amipp4K: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + if exp == "amip-future4K": + for mod in models_amipfuture4K: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + +# Execute wget scripts to retrieve data. Make sure to temporarily move to scratch disk for data download. +def valid_wget_script(script): + """ Tests if wget bash script is valid, i.e., does not contain "No files were found that matched the query" """ + valid=True + file = open(script, "r") + if file.read() == "No files were found that matched the query": + valid=False + file.close() + return valid + +os.chdir("/scratch/das/avoigt/cmip6-acre-data/") +for tab in ["Amon", "CFmon"]: + for exp in ["amip", "amip-p4K", "amip-future4K"]: + if exp == "amip": + for mod in models_amip: + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() + if exp == "amip-p4K": + for mod in models_amipp4K: + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() + if exp == "amip-future4K": + for mod in models_amipfuture4K: + script="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname="/mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() +os.chdir("/mnt/users/staff/avoigt/cmip-acre/data-download/") diff --git a/data-download/cmip6-metagrid_batchdownload_zg_Amon_HadGEM-UKESM.py b/data-download/cmip6-metagrid_batchdownload_zg_Amon_HadGEM-UKESM.py new file mode 100644 index 0000000000000000000000000000000000000000..adbcbe4e1bf47b83b1ace0ab057a6b1bdf91343c --- /dev/null +++ b/data-download/cmip6-metagrid_batchdownload_zg_Amon_HadGEM-UKESM.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# coding: utf-8 +# Download CMIP6 data from Metagrid in batch mode: geopotential height zg from Amon table for HadGEM3 and UKESM +# Limit to the models for which CRH can be calculated + +# on srvx1 call as +# /home/swd/manual/nwp/2023.1/bin/python3.10 cmip6-metagrid_batchdownload_zg_Amon_HadGEM-UKESM.py + +# Import lists for experiment, table and variable. +import lists as lists +import subprocess +import os + +scriptdir="/users/staff/avoigt/cmip6-crh/data-download/" +datadir="/scratch/das/avoigt/cmip6-acre-data/" + +# Generate wget scripts. +base = "http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment_id,variable,table_id&project=CMIP6&latest=true&replica=true" + +tab="Amon" +var="zg" + +models_amip=["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"] +models_amipp4K=["HadGEM3-GC31-LL"] +models_amipfuture4K=["HadGEM3-GC31-LL"] + +for exp in ["amip", "amip-p4K", "amip-future4K"]: + if exp == "amip": + for mod in models_amip: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + print(["wget", "--quiet", "-O", script, request]) + subprocess.run(["wget", "--quiet", "-O", script, request]) + if exp == "amip-p4K": + for mod in models_amipp4K: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + if exp == "amip-future4K": + for mod in models_amipfuture4K: + request = base + "&experiment_id=" + exp + "&table_id=" + tab + "&variable=" + var + "&source_id=" + mod + script=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + subprocess.run(["wget", "--quiet", "-O", script, request]) + +# Execute wget scripts to retrieve data. Make sure to temporarily move to scratch disk for data download. +def valid_wget_script(script): + """ Tests if wget bash script is valid, i.e., does not contain "No files were found that matched the query" """ + valid=True + file = open(script, "r") + if file.read() == "No files were found that matched the query": + valid=False + file.close() + return valid + +os.chdir(datadir) +for exp in ["amip", "amip-p4K", "amip-future4K"]: + if exp == "amip": + for mod in models_amip: + script=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() + if exp == "amip-p4K": + for mod in models_amipp4K: + script=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() + if exp == "amip-future4K": + for mod in models_amipfuture4K: + script=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod + if valid_wget_script(script): + fname=scriptdir+"wget.sh-"+exp+"-"+tab+"-"+var+"-"+mod+".log" + logfile = open(fname, "w") + subprocess.Popen(["bash", script, "-s"], stdout=logfile) + logfile.flush() + logfile.close() +os.chdir(datadir) diff --git a/data-download/cmip6-metagrid_demonstration.ipynb b/data-download/cmip6-metagrid_demonstration.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..686dc4ae523c7add221e43d36ee86287927a48d7 --- /dev/null +++ b/data-download/cmip6-metagrid_demonstration.ipynb @@ -0,0 +1,183 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "25fe1154-f2c3-42c1-b98b-b90d36702011", + "metadata": {}, + "source": [ + "# Download CMIP6 data from Metagrid: demonstration example\n", + "\n", + "Strategy:\n", + "1. Obtain wget download script from ESGF Restful API\n", + "2. Execute wget script to download data to scratch disk" + ] + }, + { + "cell_type": "markdown", + "id": "e784f171-d7cf-4195-89c4-fa2c6078b6ab", + "metadata": {}, + "source": [ + "Specify experiment, table and variable." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "bff12bcb-9fa8-4fdb-8c27-5eec6200d770", + "metadata": {}, + "outputs": [], + "source": [ + "exp = \"amip\"\n", + "tab = \"CFmon\"\n", + "var = \"rsd\"" + ] + }, + { + "cell_type": "markdown", + "id": "fb0d75e8-43ad-4810-ae3a-af48cce98512", + "metadata": {}, + "source": [ + "Obtain wget script." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6db08a8d-ffab-43b7-b9c4-caea535889a4", + "metadata": {}, + "outputs": [], + "source": [ + "base = \"http://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment,variable&project=CMIP6&latest=true&replica=false\"\n", + "request = base + \"&experiment_id=\" + exp + \"&table_id=\" + tab + \"&variable=\" + var" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "d6512099-afa6-41fc-86bd-0c4812155b7a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "URL transformed to HTTPS due to an HSTS policy\n", + "--2023-02-15 09:37:49-- https://esgf-data.dkrz.de/esg-search/wget?download_structure=project,experiment,variable&project=CMIP6&latest=true&replica=false&experiment_id=amip&table_id=CFmon&variable=rsd\n", + "Resolving esgf-data.dkrz.de (esgf-data.dkrz.de)... 136.172.34.77\n", + "Connecting to esgf-data.dkrz.de (esgf-data.dkrz.de)|136.172.34.77|:443... connected.\n", + "HTTP request sent, awaiting response... 200 200\n", + "Length: 76102 (74K) [text/x-sh]\n", + "Saving to: ‘wget.sh-demonstration-amip-CFmon-rsd’\n", + "\n", + "wget.sh-demonstrati 100%[===================>] 74.32K --.-KB/s in 0.06s \n", + "\n", + "2023-02-15 09:37:51 (1.22 MB/s) - ‘wget.sh-demonstration-amip-CFmon-rsd’ saved [76102/76102]\n", + "\n" + ] + } + ], + "source": [ + "# -O allows us to specify the name of the generated bash-wget script\n", + "!wget \"$request\" -O wget.sh-demonstration-$exp-$tab-$var" + ] + }, + { + "cell_type": "markdown", + "id": "80672375-b1da-4d32-b91a-312ba78b5bff", + "metadata": {}, + "source": [ + "Download data. Make sure to temporarily move to scratch disk for data download." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "19f2e3eb-aa46-42dc-adb6-e0f04a2e6b53", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mnt/scratch/scratch/avoigt/demonstration-cmip6-acre-data\n", + "********************************************************************************\n", + "* *\n", + "* Note that new functionality to allow authentication without the need for *\n", + "* certificates is available with this version of the wget script. To enable, *\n", + "* use the \"-H\" option and enter your OpenID and password when prompted: *\n", + "* *\n", + "* $ wget.sh-demonstration-amip-CFmon-rsd -H [options...] *\n", + "* *\n", + "* For a full description of the available options use the help option: *\n", + "* *\n", + "* $ wget.sh-demonstration-amip-CFmon-rsd -h *\n", + "* *\n", + "********************************************************************************\n", + "Running wget.sh-demonstration-amip-CFmon-rsd version: 1.3.2\n", + "Use wget.sh-demonstration-amip-CFmon-rsd -h for help.\n", + "\n", + "Script created for 134 file(s)\n", + "(The count won't match if you manually edit this file!)\n", + "\n", + "\n", + "\n", + "CMIP6//rsd/rsd_CFmon_BCC-CSM2-MR_amip_r1i1p1f1_gn_197901-199312.nc ...Downloading\n", + "--2023-02-15 09:38:46-- http://cmip.bcc.cma.cn/thredds/fileServer/cmip6_data/CFMIP/BCC/BCC-CSM2-MR/amip/r1i1p1f1/CFmon/rsd/gn/v20190801/rsd_CFmon_BCC-CSM2-MR_amip_r1i1p1f1_gn_197901-199312.nc\n", + "Resolving cmip.bcc.cma.cn (cmip.bcc.cma.cn)... 210.73.54.55\n", + "Connecting to cmip.bcc.cma.cn (cmip.bcc.cma.cn)|210.73.54.55|:80... connected.\n", + "HTTP request sent, awaiting response... 200 200\n", + "Length: 1769506688 (1.6G) [application/x-netcdf]\n", + "Saving to: ‘CMIP6//rsd/rsd_CFmon_BCC-CSM2-MR_amip_r1i1p1f1_gn_197901-199312.nc’\n", + "\n", + "CMIP6//rsd/rsd_CFmo 100%[===================>] 1.65G 11.9MB/s in 2m 43s \n", + "\n", + "2023-02-15 09:41:31 (10.4 MB/s) - ‘CMIP6//rsd/rsd_CFmon_BCC-CSM2-MR_amip_r1i1p1f1_gn_197901-199312.nc’ saved [1769506688/1769506688]\n", + "\n", + " sha256 ok. done!\n", + "CMIP6//rsd/rsd_CFmon_BCC-CSM2-MR_amip_r1i1p1f1_gn_199401-200812.nc ...Downloading\n", + "--2023-02-15 09:41:35-- http://cmip.bcc.cma.cn/thredds/fileServer/cmip6_data/CFMIP/BCC/BCC-CSM2-MR/amip/r1i1p1f1/CFmon/rsd/gn/v20190801/rsd_CFmon_BCC-CSM2-MR_amip_r1i1p1f1_gn_199401-200812.nc\n", + "Resolving cmip.bcc.cma.cn (cmip.bcc.cma.cn)... 210.73.54.55\n", + "Connecting to cmip.bcc.cma.cn (cmip.bcc.cma.cn)|210.73.54.55|:80... connected.\n", + "HTTP request sent, awaiting response... 200 200\n", + "Length: 1769506688 (1.6G) [application/x-netcdf]\n", + "Saving to: ‘CMIP6//rsd/rsd_CFmon_BCC-CSM2-MR_amip_r1i1p1f1_gn_199401-200812.nc’\n", + "\n", + "f1_gn_199401-200812 19%[==> ] 331.16M 7.44MB/s eta 2m 9s ^C\n", + "/mnt/users/staff/avoigt/cmip-acre/data-download\n" + ] + } + ], + "source": [ + "# -s: allows us to retrieve unrestricted data without providing ESGF\n", + "# -n: triggers a dry run that does not actually downloads data but lists all files that would be downloaded\n", + "# -h: provides help information for bash wget script\n", + "%rm -rf /scratch/das/avoigt/demonstration-cmip6-acre-data/\n", + "%mkdir /scratch/das/avoigt/demonstration-cmip6-acre-data/\n", + "%cd /scratch/das/avoigt/demonstration-cmip6-acre-data/\n", + "!bash /mnt/users/staff/avoigt/cmip-acre/data-download/wget.sh-demonstration-$exp-$tab-$var -s\n", + "%cd /mnt/users/staff/avoigt/cmip-acre/data-download/" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "JHubPy - 3.9.6", + "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.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/data-download/lists.py b/data-download/lists.py new file mode 100644 index 0000000000000000000000000000000000000000..a725b6673ee0903d2a5ff1f6ac88688d300903ab --- /dev/null +++ b/data-download/lists.py @@ -0,0 +1,6 @@ +list_hr = ["tntr", "tntrs", "tntrscs", "tntrl", "tntrlcs"] +list_fx = ["rsd", "rsu", "rsdcs", "rsucs", "rld", "rlu", "rldcs", "rlucs"] +list_cl = ["cl"] #, "cli", "clw"] + +list_tb = ["CFmon", "Emon", "EmonZ", "AERmon"] +list_ex = ["amip", "amip-p4K", "amip-future4K"] diff --git a/obsdata/2B-FLXHR-LIDAR.P2_R04.heatingrates_binned.2007-2010.zonmean.timmean.nc b/obsdata/2B-FLXHR-LIDAR.P2_R04.heatingrates_binned.2007-2010.zonmean.timmean.nc new file mode 100644 index 0000000000000000000000000000000000000000..9b64ebac1679119ee15d597b66f8bd1b72c91c5f Binary files /dev/null and b/obsdata/2B-FLXHR-LIDAR.P2_R04.heatingrates_binned.2007-2010.zonmean.timmean.nc differ diff --git a/obsdata/2B-FLXHR-LIDAR.P2_R05.heatingrates_binned.2007-2010.zonmean.timmean.nc b/obsdata/2B-FLXHR-LIDAR.P2_R05.heatingrates_binned.2007-2010.zonmean.timmean.nc new file mode 100644 index 0000000000000000000000000000000000000000..8d652ec71fbe5d8acca125d07700aaf89d15d825 Binary files /dev/null and b/obsdata/2B-FLXHR-LIDAR.P2_R05.heatingrates_binned.2007-2010.zonmean.timmean.nc differ diff --git a/obsdata/README_obsdata.txt b/obsdata/README_obsdata.txt new file mode 100644 index 0000000000000000000000000000000000000000..cb5875176a134128a0b7c89f8524ed9b2cefd565 --- /dev/null +++ b/obsdata/README_obsdata.txt @@ -0,0 +1,28 @@ +2B-FLXHR-LIDAR data was processed by Aiko Voigt for release R05 and R04, see https://gitlab.phaidra.org/climate/cloudsat-calipso-heating-rates + +---------------------------------------------------------------------------------------------------------- + +voigtetal2019_cloudsatcalipso_acre-zontimmean.nc contains the CRH data used in Voigt et al., 2019, J. Climate, https://journals.ametsoc.org/view/journals/clim/32/10/JCLI-D-18-0810.1.xml. However, this data is deprecated - instead the 2B-FLXHR-LIDAR datasets should be used. + +---------------------------------------------------------------------------------------------------------- + +Information by email from Seung-Hee Ham on the CCCM CRH dataset (email from June 23, 2023): + +Dear Aiko, + +I sent an invitation to access the folder I placed the gridded dataset. +If you have not received the email, please let me know. + +In the folder, the file "Y2007-2010_cim_CRE_on_HR.nc" includes cloud radiative effects on SW and LW heating rate profiles. +The heating rate profiles for all sky and clear sky are from CCCM RelD level product, available at https://ceres-tool.larc.nasa.gov/ord-tool/products?CERESProducts=CCCM . +SW heating rates are scaled by monthly gridded solar incoming flux using CERES SYN product. + +I would like to let you know that the RelD CCCM product includes a bug that sometimes cloud base heights of deep convective clouds are overestimated since some of the CloudSat clouds were not included. This issue will be addressed in the future version, but no specific timeline is planned for future processing. Since the total column optical depth is constrained by MODIS, the issue should not affect the total cloud optical depth. + +Please also note that daytime LW heating rates are more accurate than nighttime LW heating rates. This is in part because nighttime cloud optical depth tends to be underestimated due to the limitation of IR retrievals. + +If you need any further information or have any problems with opening the file, please let me know. +If you can provide any feedback about the product, that would be great for future improvement as well. + +Best, +Seung-Hee Ham \ No newline at end of file diff --git a/obsdata/seungheeham_cccm_acre-zontimmmean.nc b/obsdata/seungheeham_cccm_acre-zontimmmean.nc new file mode 100644 index 0000000000000000000000000000000000000000..a4f485cb8c4d74b2699dba574d06d911bc916d56 Binary files /dev/null and b/obsdata/seungheeham_cccm_acre-zontimmmean.nc differ diff --git a/obsdata/voigtetal2019_cloudsatcalipso_acre-zontimmean.nc b/obsdata/voigtetal2019_cloudsatcalipso_acre-zontimmean.nc new file mode 100644 index 0000000000000000000000000000000000000000..a9bdc0ec0c3d9fb81514ff4acb7b7e4c16c11495 Binary files /dev/null and b/obsdata/voigtetal2019_cloudsatcalipso_acre-zontimmean.nc differ diff --git a/plots4paper/dsst_amipfuture4K.ipynb b/plots4paper/dsst_amipfuture4K.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..26931285f86faa2245b8418452be86eb7895fef3 --- /dev/null +++ b/plots4paper/dsst_amipfuture4K.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e20e06b0-71dd-42fe-899b-5e64707ee25f", + "metadata": {}, + "source": [ + "# Plot time-mean SST pattern in the amip-future4K simulations\n", + "\n", + "The sst is obtained from the supplement of Webb et al., 2017, GMD, The Cloud Feedback Model Intercomparison Project (CFMIP) contribution to CMIP6, https://gmd.copernicus.org/articles/10/359/2017/." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0432119a-e551-4e15-bffe-2163d58a2d09", + "metadata": {}, + "outputs": [], + "source": [ + "import xarray as xr\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import cartopy.crs as ccrs\n", + "from cartopy.util import add_cyclic_point" + ] + }, + { + "cell_type": "markdown", + "id": "458c285e-964f-463a-b90f-d72449582d55", + "metadata": {}, + "source": [ + "Loads time-mean sst." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c1949692-d794-4ab6-81c8-b93f9f862453", + "metadata": {}, + "outputs": [], + "source": [ + "sst = xr.open_dataset(\"/users/staff/avoigt/cmip6-crh/cfmip2-sst/cfmip2_4k_patterned_sst_forcing.vn1.0.nc\", \n", + " decode_times=False).drop(\"level001\").mean(\"time\").squeeze()[\"dt\"]" + ] + }, + { + "cell_type": "markdown", + "id": "b215de1c-006b-4c34-97f9-33f9ea5c1607", + "metadata": {}, + "source": [ + "Makes plot." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "fe6791bb-ef9c-4666-9c6e-f663ed81f18a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 600x400 with 2 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "clev = np.delete(np.linspace(-4,4,17),8)\n", + "\n", + "plt.figure(figsize=(6,4))\n", + "pdata, lons = add_cyclic_point(sst.values-4, coord=sst.longitude)\n", + "lats = sst.latitude\n", + "ax = plt.axes(projection=ccrs.Robinson())\n", + "cnt=plt.contourf(lons, lats, np.clip(pdata,a_max=4,a_min=-4), levels=clev,\n", + " transform=ccrs.PlateCarree(), cmap=\"RdBu_r\")\n", + "for c in cnt.collections: c.set_edgecolor(\"face\")\n", + "ax.coastlines(resolution=\"110m\", linewidth=0.75)\n", + "cb=plt.colorbar(aspect=25,fraction=0.019)\n", + "cb.set_ticks([-4,-3,-2,-1,0,1,2,3,4])\n", + "cb.set_ticklabels([0,1,2,3,4,5,6,7,r\"8$\\,$K\"])\n", + "cb.ax.tick_params(labelsize=8)\n", + "plt.title(\"SST pattern in amip-future4K simulations\", fontsize=10)\n", + "\n", + "plt.savefig(\"figures/dsst_amipfuture4K.pdf\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62a8f2f8-de89-416c-b2a7-0e3a3702f834", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp2023.1 - 3.10.9", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/plots4paper/figures/cl_5xdomaintimemean_amip-crop.pdf b/plots4paper/figures/cl_5xdomaintimemean_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7cfc09e00bab282b52b4fa5ae37757a851a83d65 Binary files /dev/null and b/plots4paper/figures/cl_5xdomaintimemean_amip-crop.pdf differ diff --git a/plots4paper/figures/cl_5xdomaintimemean_amip-future4K-crop.pdf b/plots4paper/figures/cl_5xdomaintimemean_amip-future4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..18b9edce933c2755b5b1f1de23bee367c133589e Binary files /dev/null and b/plots4paper/figures/cl_5xdomaintimemean_amip-future4K-crop.pdf differ diff --git a/plots4paper/figures/cl_5xdomaintimemean_amip-future4K.pdf b/plots4paper/figures/cl_5xdomaintimemean_amip-future4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..95bbc09e091aaee7a7990c3bf59807a27d18ce78 Binary files /dev/null and b/plots4paper/figures/cl_5xdomaintimemean_amip-future4K.pdf differ diff --git a/plots4paper/figures/cl_5xdomaintimemean_amip-p4K-crop.pdf b/plots4paper/figures/cl_5xdomaintimemean_amip-p4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c98ea362c5857ad172a77721fe2742b0d4681133 Binary files /dev/null and b/plots4paper/figures/cl_5xdomaintimemean_amip-p4K-crop.pdf differ diff --git a/plots4paper/figures/cl_5xdomaintimemean_amip-p4K.pdf b/plots4paper/figures/cl_5xdomaintimemean_amip-p4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f765258803858a41d897ab6316e3d20d4cf9247f Binary files /dev/null and b/plots4paper/figures/cl_5xdomaintimemean_amip-p4K.pdf differ diff --git a/plots4paper/figures/cl_5xdomaintimemean_amip.pdf b/plots4paper/figures/cl_5xdomaintimemean_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6b1e37fb86919df13c0d06d626a1f9c20ccaab20 Binary files /dev/null and b/plots4paper/figures/cl_5xdomaintimemean_amip.pdf differ diff --git a/plots4paper/figures/cl_zonaltimemean_xypanelplot_amip-crop.pdf b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a20eeb088191737193b17ee1eac75c66413f5fad Binary files /dev/null and b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amip-crop.pdf differ diff --git a/plots4paper/figures/cl_zonaltimemean_xypanelplot_amip.pdf b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6fa4833a5e60ecc90858f4467258619a936f6587 Binary files /dev/null and b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amip.pdf differ diff --git a/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8212a08c9cea20120faf7e73697f85f1dc3908d2 Binary files /dev/null and b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf differ diff --git a/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipfuture4K.pdf b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipfuture4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a1b7d51e0f1a918aab46dc8609f9aa61ee08723a Binary files /dev/null and b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipfuture4K.pdf differ diff --git a/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipp4K-crop.pdf b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipp4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9218e9f2d8e9726207d10f24e10d30953f9d719b Binary files /dev/null and b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipp4K-crop.pdf differ diff --git a/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipp4K.pdf b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipp4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a2cb4175c65aabe13df981307c32b98148530cea Binary files /dev/null and b/plots4paper/figures/cl_zonaltimemean_xypanelplot_amipp4K.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amip-crop.pdf b/plots4paper/figures/crh_5xdomaintimemean_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2e352288c37574cadfde270377a32b6197061b0a Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amip-crop.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amip-future4K-crop.pdf b/plots4paper/figures/crh_5xdomaintimemean_amip-future4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1ee54574eb1fdfef6e4bf9730dfb9e9a68b80ae5 Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amip-future4K-crop.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amip-future4K.pdf b/plots4paper/figures/crh_5xdomaintimemean_amip-future4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..83dfbd70a080f1cb52cbc9e1ff74b2a3510f60c8 Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amip-future4K.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amip-p4K-crop.pdf b/plots4paper/figures/crh_5xdomaintimemean_amip-p4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2c2b800bbe5dfde45a7956b9923b0432bc06fc97 Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amip-p4K-crop.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amip-p4K.pdf b/plots4paper/figures/crh_5xdomaintimemean_amip-p4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1ab202ba3a66a2758e217efb867f36da6fbd69d2 Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amip-p4K.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amip.pdf b/plots4paper/figures/crh_5xdomaintimemean_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..278cc709c8d1abb26e293b23e143ab61f453a55b Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amip.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amipfuture4K-amipp4K-crop.pdf b/plots4paper/figures/crh_5xdomaintimemean_amipfuture4K-amipp4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a4079e3e5399b05bcbe15e26daf863510f397cfc Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amipfuture4K-amipp4K-crop.pdf differ diff --git a/plots4paper/figures/crh_5xdomaintimemean_amipfuture4K-amipp4K.pdf b/plots4paper/figures/crh_5xdomaintimemean_amipfuture4K-amipp4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fba12149daab33ee8390ce15e94eb33db01e14cd Binary files /dev/null and b/plots4paper/figures/crh_5xdomaintimemean_amipfuture4K-amipp4K.pdf differ diff --git a/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-crop.pdf b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2bef6c4e8ff2ff7273896c1f9d540b180a090cd8 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-crop.pdf differ diff --git a/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-future4K-crop.pdf b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-future4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1c505b63f3634545faa94e9bb4e0e95d9188c694 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-future4K-crop.pdf differ diff --git a/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-future4K.pdf b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-future4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..be62a5b3f21e88e190ee42b09c3d839545238840 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-future4K.pdf differ diff --git a/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-p4K-crop.pdf b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-p4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f0e48a2d769614080b21beb2790ea0d32cae0c9d Binary files /dev/null and b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-p4K-crop.pdf differ diff --git a/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-p4K.pdf b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-p4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..19d5d7aeaa27d274a276a89b58afc17d92dc945b Binary files /dev/null and b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip-p4K.pdf differ diff --git a/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip.pdf b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ed15497694ea371b084372def16c0af1a778ed75 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_5xdomaintimemean_amip.pdf differ diff --git a/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip-crop.pdf b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8ef0814ce171b66c4323a89972b006cf6cf41e70 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip-crop.pdf differ diff --git a/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip.pdf b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2017cede851dbf8327304c1d5e4e10e21dc0b234 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amip.pdf differ diff --git a/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..23ab2b55385fe3679574e3b32b1d4a88b05f040c Binary files /dev/null and b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf differ diff --git a/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipfuture4K.pdf b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipfuture4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d88fc97e9ef6ba85b56c7c4f1620479f9c9087c4 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipfuture4K.pdf differ diff --git a/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipp4K-crop.pdf b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipp4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..eeacda6b6990be642f304e0b2aebce886a1a0b46 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipp4K-crop.pdf differ diff --git a/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipp4K.pdf b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipp4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4f5949b40a6d8ac6fb418f04845857f927d28208 Binary files /dev/null and b/plots4paper/figures/crh_Tlev_zonaltimemean_xypanelplot_amipp4K.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipfuture4K-amip-crop.pdf b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipfuture4K-amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7341adf4bd1bc0e538e1b2601f834bd103fbcf3d Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipfuture4K-amip-crop.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipfuture4K-amip.pdf b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipfuture4K-amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..db1cc18a5d83b48079a8b964f008e20a9d9a16d2 Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipfuture4K-amip.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip-crop.pdf b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ad24eda64c292b1c81b6a5771917e082c253104b Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip-crop.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip.pdf b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..048e2057606de3d513474c64aac7d0a26a984c67 Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipfuture4K-amip-crop.pdf b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipfuture4K-amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a6e65ac83e2508dab3b72fbe1284fb4851f7bb8d Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipfuture4K-amip-crop.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..15458f3fad3722c08c23e8500b42330beec6e1ab Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a0ded29258479ba2b7a968fea1188b0ff2c7248d Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip.pdf b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2fd4e77349838f5e532b98d5431221dec8869619 Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipfuture4K-amip-crop.pdf b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipfuture4K-amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0e26b6bb4e9f4697421865561c716eec851bdff7 Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipfuture4K-amip-crop.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e15f788794d377f58625ea2e95ebd9a7733270fa Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2557b0cf24fd919493d1a53db99e2226225b719d Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip-crop.pdf differ diff --git a/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip.pdf b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e42aa2d1178e6433048157ce80775970a747d589 Binary files /dev/null and b/plots4paper/figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-crop.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ea1ef13f149563691619adc8d34b00fda4377fb9 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K-crop.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..179c0eeb2b8aa1f582fd4d6fb771c0454445e70c Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..40e672c5201007db890f1faf6500c5c59bcf1562 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-future4K.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K-crop.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..69755707fdaea1f5e2775cfad91ac2ef0bea0308 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ffc040511dd8b8b3f5aeff8e1c3b62f57d9ff033 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-p4K.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1-crop.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4e83e32c805d40dd470018361b0f81918ffa901c Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..853f33773a3d088d9ad676deb19ba1af5c0685fb Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part1.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2-crop.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1c5d5c0be1591c26261d9f5e8b983148d5b8f80e Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d28f6c541df538a7587ccf93e3da4ab6cc11b742 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip-part2.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_3approaches_amip.pdf b/plots4paper/figures/crh_zonaltimemean_3approaches_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9205fb34b9d14d22a08249af9711736db9f1cbee Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_3approaches_amip.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_amip_median_std_obs-crop.pdf b/plots4paper/figures/crh_zonaltimemean_amip_median_std_obs-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..29211599833b7cb72eb6e7224e42a5b6b264c9c6 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_amip_median_std_obs-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_amip_median_std_obs.pdf b/plots4paper/figures/crh_zonaltimemean_amip_median_std_obs.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0c5033f0da33c3df36c0b7955d9aabad3efd88a5 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_amip_median_std_obs.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amip-crop.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2ecb9df1e9f3c045184b054a2b0f0370ef6c941b Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amip-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amip.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cd875ecf76456752f5493502b2a4ed098b95dd9e Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amip.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K-crop.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..05db39eee1e1a9563d8f21a6ae73d1f7fc5b773b Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..15899784f894c0e537d21fe9e98185121c91551e Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a14812a2d6609e42665796295cf537d0b8c950ca Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b64ba980df3a593f949807f4aec835bd17303ce6 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipfuture4K.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipp4K-crop.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipp4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c1d4bdab771c6e666654776b77856ecad1787322 Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipp4K-crop.pdf differ diff --git a/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipp4K.pdf b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipp4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ffd07f4e0115b233fc174a7a58de2a8abe25e82c Binary files /dev/null and b/plots4paper/figures/crh_zonaltimemean_xypanelplot_amipp4K.pdf differ diff --git a/plots4paper/figures/csrh_5xdomaintimemean_amip-crop.pdf b/plots4paper/figures/csrh_5xdomaintimemean_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..41781e9553f96e998eddc64d5d1a28916b47e508 Binary files /dev/null and b/plots4paper/figures/csrh_5xdomaintimemean_amip-crop.pdf differ diff --git a/plots4paper/figures/csrh_5xdomaintimemean_amip-future4K-crop.pdf b/plots4paper/figures/csrh_5xdomaintimemean_amip-future4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7fd074de20138ac3ee0be0752b202b9b2a7d0933 Binary files /dev/null and b/plots4paper/figures/csrh_5xdomaintimemean_amip-future4K-crop.pdf differ diff --git a/plots4paper/figures/csrh_5xdomaintimemean_amip-future4K.pdf b/plots4paper/figures/csrh_5xdomaintimemean_amip-future4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..82b50050cc73200bde11ce2bcb5ff38d83849455 Binary files /dev/null and b/plots4paper/figures/csrh_5xdomaintimemean_amip-future4K.pdf differ diff --git a/plots4paper/figures/csrh_5xdomaintimemean_amip-p4K-crop.pdf b/plots4paper/figures/csrh_5xdomaintimemean_amip-p4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5f3605d3b72c9e0f4739f19fee9bd3ce46e26913 Binary files /dev/null and b/plots4paper/figures/csrh_5xdomaintimemean_amip-p4K-crop.pdf differ diff --git a/plots4paper/figures/csrh_5xdomaintimemean_amip-p4K.pdf b/plots4paper/figures/csrh_5xdomaintimemean_amip-p4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3bc5a71274ffde37ebe96a7021d675b763935225 Binary files /dev/null and b/plots4paper/figures/csrh_5xdomaintimemean_amip-p4K.pdf differ diff --git a/plots4paper/figures/csrh_5xdomaintimemean_amip.pdf b/plots4paper/figures/csrh_5xdomaintimemean_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..08d1f343f6258ccd330c625173cb4580a0aeb834 Binary files /dev/null and b/plots4paper/figures/csrh_5xdomaintimemean_amip.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-crop.pdf b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e41eb78b95c2881e6d0826d736c64f0e5d8f96ef Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-crop.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-future4K-crop.pdf b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-future4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5e231afbef1d444f8da5bbb6e8a59f1ed3a0cbc6 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-future4K-crop.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-future4K.pdf b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-future4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8756223b215d4b6a4667c648cb0f9e867ba6d1f7 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-future4K.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-p4K-crop.pdf b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-p4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5f96b94fe5131bcb89864a7763adc7fe18264d8e Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-p4K-crop.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-p4K.pdf b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-p4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..94be2e362cc841486d178c3b4f8ef3d777421297 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip-p4K.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_3approaches_amip.pdf b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b2191e5cf2055d0088b21d66170a0e6593d979e4 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_3approaches_amip.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amip-crop.pdf b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amip-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..90fca4c78d61039ddd18d1a619e9545e09d34d21 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amip-crop.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amip.pdf b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amip.pdf new file mode 100644 index 0000000000000000000000000000000000000000..66668a59eca2c3fc6a6736122a35791919f3f833 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amip.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7f2053a21f86635e31f9467d9960ddf99552f9de Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipfuture4K-crop.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipfuture4K.pdf b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipfuture4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..758f112344f60e9b2fb7288e713756805c8f1c29 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipfuture4K.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipp4K-crop.pdf b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipp4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d91c5e58e4711e04ee211686aa7927557c06b7e1 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipp4K-crop.pdf differ diff --git a/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipp4K.pdf b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipp4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..848e43d97b17fa819882381ad9d194be18e6a8d6 Binary files /dev/null and b/plots4paper/figures/csrh_zonaltimemean_xypanelplot_amipp4K.pdf differ diff --git a/plots4paper/figures/dsst_amipfuture4K-crop.pdf b/plots4paper/figures/dsst_amipfuture4K-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8493425db4a675b3d95364defb9dd399d1e9fcf7 Binary files /dev/null and b/plots4paper/figures/dsst_amipfuture4K-crop.pdf differ diff --git a/plots4paper/figures/dsst_amipfuture4K.pdf b/plots4paper/figures/dsst_amipfuture4K.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e72c47a2220426761da3b3a49c93d05e73df0b3d Binary files /dev/null and b/plots4paper/figures/dsst_amipfuture4K.pdf differ diff --git a/plots4paper/figures/illustrate_order_of_computation-crop.pdf b/plots4paper/figures/illustrate_order_of_computation-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..37b3105d864630bb18d1f45237cc578fe890dc9d Binary files /dev/null and b/plots4paper/figures/illustrate_order_of_computation-crop.pdf differ diff --git a/plots4paper/figures/illustrate_order_of_computation.pdf b/plots4paper/figures/illustrate_order_of_computation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6e2cf3fadc38f493f82f7ae139734e98026fdd73 Binary files /dev/null and b/plots4paper/figures/illustrate_order_of_computation.pdf differ diff --git a/plots4paper/figures/obs_prediction-crop.pdf b/plots4paper/figures/obs_prediction-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..58e3989ee4c537c4b926ab3d96f5e9cc3315810e Binary files /dev/null and b/plots4paper/figures/obs_prediction-crop.pdf differ diff --git a/plots4paper/figures/obs_prediction.pdf b/plots4paper/figures/obs_prediction.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a2faf06b39bc4ee44eb17dbadb3535797e31967b Binary files /dev/null and b/plots4paper/figures/obs_prediction.pdf differ diff --git a/plots4paper/figures/radheating_zonaltimemean_amip_variance-crop.pdf b/plots4paper/figures/radheating_zonaltimemean_amip_variance-crop.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cf490c3495505be1b5254bdebff8354d8274e003 Binary files /dev/null and b/plots4paper/figures/radheating_zonaltimemean_amip_variance-crop.pdf differ diff --git a/plots4paper/figures/radheating_zonaltimemean_amip_variance.pdf b/plots4paper/figures/radheating_zonaltimemean_amip_variance.pdf new file mode 100644 index 0000000000000000000000000000000000000000..595e4c6624de7ef23e5d473558caa0626e265ad4 Binary files /dev/null and b/plots4paper/figures/radheating_zonaltimemean_amip_variance.pdf differ diff --git a/plots4paper/helpers.py b/plots4paper/helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..a343d82ee1ac94367ee6c966c42fe6a7f6b5f72d --- /dev/null +++ b/plots4paper/helpers.py @@ -0,0 +1,694 @@ +import xarray as xr +import numpy as np +import scipy as sci + +# lists of models for which crh is available for simulations +# the list is generated by means of model_data_matrix.ipynb +models_amip = ["BCC-CSM2-MR", "CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2", "CNRM-CM6-1", "CNRM-ESM2-1", + "EC-Earth3", "GFDL-AM4", "GFDL-CM4", "GFDL-ESM4", "HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "INM-CM4-8", + "INM-CM5-0", "IPSL-CM6A-LR", "MIROC-ES2L", "MIROC6", "MRI-ESM2-0", "UKESM1-0-LL"] +models_amip_flx = ["BCC-CSM2-MR", "CNRM-CM6-1", "CNRM-ESM2-1", "HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "INM-CM4-8", "INM-CM5-0", + "IPSL-CM6A-LR", "MIROC-ES2L", "MIROC6", "MRI-ESM2-0", "UKESM1-0-LL"] +models_amip_tntr = ["CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2", "CNRM-CM6-1", "CNRM-ESM2-1", "EC-Earth3", + "GFDL-AM4", "GFDL-CM4", "GFDL-ESM4", "HadGEM3-GC31-LL", "UKESM1-0-LL"] + +models_amipp4K = ["BCC-CSM2-MR", "CNRM-CM6-1", "GFDL-CM4", "HadGEM3-GC31-LL", "IPSL-CM6A-LR", "MIROC6", "MRI-ESM2-0"] +models_amipp4K_flx = ["BCC-CSM2-MR", "CNRM-CM6-1", "HadGEM3-GC31-LL", "IPSL-CM6A-LR", "MIROC6", "MRI-ESM2-0"] +models_amipp4K_tntr = ["GFDL-CM4", "MIROC6"] + +models_amipfuture4K = ["BCC-CSM2-MR", "CNRM-CM6-1", "GFDL-CM4", "HadGEM3-GC31-LL", "IPSL-CM6A-LR", "MIROC6", "MRI-ESM2-0"] +models_amipfuture4K_flx = ["BCC-CSM2-MR", "CNRM-CM6-1", "HadGEM3-GC31-LL", "IPSL-CM6A-LR", "MIROC6", "MRI-ESM2-0"] +models_amipfuture4K_tntr = ["GFDL-CM4", "MIROC6"] + + +# path of postprocessed data on srvx1 of IMG UNIVIE +path = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/" +# derived mean fields +path_mean = "/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean/" + + +def removefirst12months(ds): + """Removes the first 12 months of a dataset.""" + ntim = ds.time.size + ds = ds.isel(time=slice(12, ntim)) + return ds + + +def compute_timedomainmean(_crh, lats, latn, skipna=True): + """Computes time-lat-lon mean over domain specified by lats and latn. Averages over + all input timesteps and longitudes.""" + if "lon" in _crh.dims: + _crh = _crh.mean(["time", "lon"]).sel(lat=slice(lats, latn)) + else: # for EmonZ data + _crh = _crh.mean(["time"]).sel(lat=slice(lats, latn)) + _weights = np.cos(_crh.lat*np.pi/180) + _crh_weights = _crh.weighted(_weights) + return _crh_weights.mean(["lat"], skipna=skipna) + + +def compute_domainmean(_crh, lats, latn, skipna=True): + """Computes lat-lon mean over domain specified by lats and latn. Averages over + all input timesteps and longitudes.""" + _crh = _crh.sel(lat=slice(lats, latn)) + if "lon" in _crh.dims: + _crh = _crh.mean(["lon"]) + _weights = np.cos(_crh.lat*np.pi/180) + _crh_weights = _crh.weighted(_weights) + return _crh_weights.mean(["lat"], skipna=skipna) + + +def crh_from_flx(mod, exp): + """ + Loads CRH zarr store calculated from fluxes as a function of (time, pressure, lat, lon). Removes the first 12 months. + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + crh as xarray dataarray + + Note: crh from fluxes is always from the CFmon table.""" + + import os.path + asfile = path+"dTdt-as-from-flx"+"_CFmon_"+mod+"_"+exp+".zarr" + csfile = path+"dTdt-cs-from-flx"+"_CFmon_"+mod+"_"+exp+".zarr" + if os.path.exists(asfile) and os.path.exists(csfile): + asky = xr.open_dataset(asfile, engine="zarr", chunks="auto") + csky = xr.open_dataset(csfile, engine="zarr", chunks="auto") + else: + return None + crh = removefirst12months(asky["dTdt-as-from-flx"]-csky["dTdt-cs-from-flx"]) + return crh + + +def crh_from_flx_ymonmean(mod, exp): + """ + Loads netcdf file of 12-month climatology of CRH calculated from fluxes as a + function of (time, pressure, lat, lon). + + Sister function of crh_from_flx. + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + crh as xarray dataarray + + Note: crh from fluxes is always from the CFmon table.""" + + import os.path + asfile = path_mean+"dTdt-as-from-flx"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc" + csfile = path_mean+"dTdt-cs-from-flx"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc" + if os.path.exists(asfile) and os.path.exists(csfile): + asky = xr.open_dataset(asfile, chunks="auto") + csky = xr.open_dataset(csfile, chunks="auto") + else: + return None + return asky["dTdt-as-from-flx"]-csky["dTdt-cs-from-flx"] + + +def csrh_from_flx_ymonmean(mod, exp): + """ + Loads netcdf file of 12-month climatology of clear-sky radiative heating calculated from fluxes as a + function of (time, pressure, lat, lon). + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + csrh as xarray dataarray + + Note: csrh from fluxes is always from the CFmon table.""" + + import os.path + csfile = path_mean+"dTdt-cs-from-flx"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc" + if os.path.exists(csfile): + csrh = xr.open_dataset(csfile, chunks="auto") + else: + return None + return csrh["dTdt-cs-from-flx"] + + +def crh_from_tntr(mod, exp): + """ + Loads CRH zarr store calculated from heating rates as a function of (time, pressure, lat, lon). Removes the first 12 months. + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + crh as xarray dataarray + + Note: crh from heating rates can be part of CFmon, AERmon and Emon tables. Look for postprocessed + data in the order CFmon, AERmon, Emon. + """ + + import os.path + if os.path.exists(path+"dTdt-as-from-tntr"+"_CFmon_"+mod+"_"+exp+".zarr"): + asky = xr.open_dataset(path+"dTdt-as-from-tntr"+"_CFmon_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + elif os.path.exists(path+"dTdt-as-from-tntr"+"_AERmon_"+mod+"_"+exp+".zarr"): + asky = xr.open_dataset(path+"dTdt-as-from-tntr"+"_AERmon_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + elif os.path.exists(path+"dTdt-as-from-tntr"+"_Emon_"+mod+"_"+exp+".zarr"): + asky = xr.open_dataset(path+"dTdt-as-from-tntr"+"_Emon_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + else: + return None + if os.path.exists(path+"dTdt-cs-from-tntr"+"_CFmon_"+mod+"_"+exp+".zarr"): + csky = xr.open_dataset(path+"dTdt-cs-from-tntr"+"_CFmon_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + elif os.path.exists(path+"dTdt-cs-from-tntr"+"_AERmon_"+mod+"_"+exp+".zarr"): + csky = xr.open_dataset(path+"dTdt-cs-from-tntr"+"_AERmon_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + elif os.path.exists(path+"dTdt-cs-from-tntr"+"_Emon_"+mod+"_"+exp+".zarr"): + csky = xr.open_dataset(path+"dTdt-cs-from-tntr"+"_Emon_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + else: + return None + crh = removefirst12months(asky["dTdt-as-from-tntr"]-csky["dTdt-cs-from-tntr"]) + return crh + + +def crh_from_tntr_ymonmean(mod, exp): + """ + Loads netcdf file of 12-month climatology of CRH calculated from heating rates as a + function of (time, pressure, lat, lon). + + Sister function of crh_from_tntr. + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + crh as xarray dataarray + + Note: crh from heating rates can be part of CFmon, AERmon and Emon tables. Look for postprocessed + data in the order CFmon, AERmon, Emon. + """ + + import os.path + if os.path.exists(path_mean+"dTdt-as-from-tntr"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc"): + asky = xr.open_dataset(path_mean+"dTdt-as-from-tntr"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + elif os.path.exists(path_mean+"dTdt-as-from-tntr"+"_AERmon_"+mod+"_"+exp+".ymonmean.nc"): + asky = xr.open_dataset(path_mean+"dTdt-as-from-tntr"+"_AERmon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + elif os.path.exists(path_mean+"dTdt-as-from-tntr"+"_Emon_"+mod+"_"+exp+".ymonmean.nc"): + asky = xr.open_dataset(path_mean+"dTdt-as-from-tntr"+"_Emon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + else: + return None + if os.path.exists(path_mean+"dTdt-cs-from-tntr"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc"): + csky = xr.open_dataset(path_mean+"dTdt-cs-from-tntr"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + elif os.path.exists(path_mean+"dTdt-cs-from-tntr"+"_AERmon_"+mod+"_"+exp+".ymonmean.nc"): + csky = xr.open_dataset(path_mean+"dTdt-cs-from-tntr"+"_AERmon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + elif os.path.exists(path_mean+"dTdt-cs-from-tntr"+"_Emon_"+mod+"_"+exp+".ymonmean.nc"): + csky = xr.open_dataset(path_mean+"dTdt-cs-from-tntr"+"_Emon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + else: + return None + return asky["dTdt-as-from-tntr"]-csky["dTdt-cs-from-tntr"] + + +def csrh_from_tntr_ymonmean(mod, exp): + """ + Loads netcdf file of 12-month climatology of clear-sky radiative heating calculated from heating rates as a + function of (time, pressure, lat, lon). + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + csrh as xarray dataarray + + Note: csrh from heating rates can be part of CFmon, AERmon and Emon tables. Look for postprocessed + data in the order CFmon, AERmon, Emon. + """ + + import os.path + if os.path.exists(path_mean+"dTdt-cs-from-tntr"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc"): + csrh = xr.open_dataset(path_mean+"dTdt-cs-from-tntr"+"_CFmon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + elif os.path.exists(path_mean+"dTdt-cs-from-tntr"+"_AERmon_"+mod+"_"+exp+".ymonmean.nc"): + csrh = xr.open_dataset(path_mean+"dTdt-cs-from-tntr"+"_AERmon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + elif os.path.exists(path_mean+"dTdt-cs-from-tntr"+"_Emon_"+mod+"_"+exp+".ymonmean.nc"): + csrh = xr.open_dataset(path_mean+"dTdt-cs-from-tntr"+"_Emon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + else: + return None + # tntr csrh for CESM2 and CESM2-WACCM is broken, so manually catch this here + if mod in ["CESM2", "CESM2-WACCM"]: + return None + return csrh["dTdt-cs-from-tntr"] + + +def crh_from_tntr_EmonZ(mod, exp): + """ + Loads CRH zarr store calculated from heating rates and EmonZ table as a function of (time, pressure, lat). Removes the first 12 months. + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + crh as xarray dataarray + """ + import os.path + if os.path.exists(path+"dTdt-as-from-tntr"+"_EmonZ_"+mod+"_"+exp+".zarr") and os.path.exists(path+"dTdt-cs-from-tntr"+"_EmonZ_"+mod+"_"+exp+".zarr"): + asky = xr.open_dataset(path+"dTdt-as-from-tntr"+"_EmonZ_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + csky = xr.open_dataset(path+"dTdt-cs-from-tntr"+"_EmonZ_"+mod+"_"+exp+".zarr", engine="zarr", chunks="auto") + else: + return None + crh = removefirst12months(asky["dTdt-as-from-tntr"]-csky["dTdt-cs-from-tntr"]) + return crh + + +def crh_from_tntr_EmonZ_ymonmean(mod, exp): + """ + Loads netcdf file of 12-month climatology of CRH calculated from heating rates and EmonZ table as a + function of (time, pressure, lat). + + Sister function of crh_from_tntr_EmonZ. + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + crh as xarray dataarray + """ + import os.path + asfile=path_mean+"dTdt-as-from-tntr"+"_EmonZ_"+mod+"_"+exp+".ymonmean.nc" + csfile=path_mean+"dTdt-cs-from-tntr"+"_EmonZ_"+mod+"_"+exp+".ymonmean.nc" + if os.path.exists(asfile) and os.path.exists(csfile): + asky = xr.open_dataset(asfile, chunks="auto") + csky = xr.open_dataset(csfile, chunks="auto") + else: + return None + return asky["dTdt-as-from-tntr"]-csky["dTdt-cs-from-tntr"] + + +def csrh_from_tntr_EmonZ_ymonmean(mod, exp): + """ + Loads netcdf file of 12-month climatology of clear-sky radiative heating calculated from heating rates and EmonZ table as a + function of (time, pressure, lat). + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + csrh as xarray dataarray + """ + import os.path + csrh=path_mean+"dTdt-cs-from-tntr"+"_EmonZ_"+mod+"_"+exp+".ymonmean.nc" + if os.path.exists(csrh): + csrh = xr.open_dataset(csrh, chunks="auto") + else: + return None + return csrh["dTdt-cs-from-tntr"] + + +def ta_Amon_ymonmean(mod, exp): + """ + Loads netcdf file of 12-month climatology of air temperature ta from Amon table as a + function of (time, pressure, lat, lon). + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + ta as xarray dataarray + """ + + import os.path + if os.path.exists(path_mean+"ta_Amon_"+mod+"_"+exp+".ymonmean.nc"): + ta = xr.open_dataset(path_mean+"ta_Amon_"+mod+"_"+exp+".ymonmean.nc", chunks="auto") + else: + return None + return ta + + +def tropo_Amon_zontimmean(mod, exp): + """ + Loads netcdf file of zonal-mean time-mean tropopause calculated from air temperature ta from Amon table. + + Inputs: + mod = model id, string + exp = experiment id, string + Output: + tropopause as xarray dataarray + """ + + import os.path + if os.path.exists(path_mean+"tropop_Amon_"+mod+"_"+exp+".nc"): + tropo = xr.open_dataset(path_mean+"tropop_Amon_"+mod+"_"+exp+".nc") + else: + tropo=None + # for BCC-CSM2-MR model, need to correct tropopause in deep tropics by hand + # in amip-p4K and amip-future4K simulations + if mod=="BCC-CSM2-MR" and exp=="amip-p4K": + tropo = tropo.where(tropo>95, 95) + if mod=="BCC-CSM2-MR" and exp=="amip-future4K": + tropo = tropo.where(tropo>95, 95) + return tropo + + +def height2pressure(hgt): + """ + Converts height levels to pressure level according to the U.S. Standard Atmosphere using + the implementation of MetPy. + + Inputs: + hgt: array of height levels in m + Output: + pres: array of pressure levels in Pa + """ + from metpy.calc import height_to_pressure_std + from metpy.units import units + return 100*height_to_pressure_std(hgt*units("m")).magnitude # pressure in Pa + + +def height2pressure_zg(data,mod,exp): + """ + Converts input data from height levels to pressure level using zg from Amon table. + Written for HadGEM and UKESM models. Works for zonal-mean time-mean data. + + Input variables mod and exp are needed to load time-mean zonal-mean geopotential height. + + Inputs: + data: zonal-mean time-mean input data on height levels + mod: model name + exp: simulation name + Output: + data_int: data interpolated to common set of pressure levels in Pa + _lev_int: output pressure levels + """ + import sys + sys.path.append("../analysis/") + import cmip6radheating as c6rh + + # target pressure levels in Pa + _lev_int = c6rh.define_targetlevels() + + # load time-mean zonal-mean zg + _path="/scratch/das/avoigt/cmip6-acre-data/postprocessed/mean" + _zg = xr.open_dataset(_path+"/zg_Amon_"+mod+"_"+exp+".timmean.zonmean.nc").squeeze() + + data_int=np.zeros((_lev_int.size, _zg.lat.size))+np.nan + for j in range(_zg.lat.size): + # interpolation function from height to pressure computed based on Amon zg to Amon pressure levels + f_z2p = sci.interpolate.interp1d(_zg["zg"][:,j].values, _zg.plev.values, fill_value="extrapolate") + # we now use this to convert from height levels of input data to common pressure levels _lev_int + f_p2pint = sci.interpolate.interp1d(f_z2p(data.hgt), data[:,j].values, fill_value="extrapolate") + data_int[:,j] = f_p2pint(_lev_int) + + return data_int, _lev_int + + +def load_crh_zontimmean(mod, exp): + """ + For given model and experiment, load zonal-mean time-mean crh. Look for data in the following order, + and use the first available data: + 1. crh from fluxes from CFmon + 2. crh from tntr from CFmon, AERmon, Emon + 3. crh from tntr from EmonZ + + Input: + mod: model name (string) + exp: experiment name (string) + Output: + zonal-mean time-mean crh as xarray dataset + """ + # 1. fluxes + crh = crh_from_flx_ymonmean(mod, exp) + if crh is not None: + return crh.mean(["month", "lon"]).persist() + # 2. tntr from CFmon, AERmon, Emon + crh = crh_from_tntr_ymonmean(mod, exp) + if crh is not None: + return crh.mean(["month", "lon"]).persist() + # 3. tntr from EmonZ + crh = crh_from_tntr_EmonZ_ymonmean(mod, exp) + if crh is not None: + crh_mean = crh.mean(["month"]) + # for CESM family of models, set all levels below 500hPa to nan + # because EmonZ data has artifical zeros below 500hPa + if mod in ["CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2"]: + crh_mean = crh_mean.where(crh_mean.lev<500e2) + return crh_mean.persist() + # if no data could be found, print warning and return None + print("ATTENTION: no data for zonal-mean time-mean crh found for model ", mod, " and experiment ", exp) + return None + + +def load_csrh_zontimmean(mod, exp): + """ + For given model and experiment, load zonal-mean time-mean clear-sky radiative heating (csrh). Look for data in the following order, + and use the first available data: + 1. csrh from fluxes from CFmon + 2. csrh from tntr from CFmon, AERmon, Emon + 3. csrh from tntr from EmonZ + + Input: + mod: model name (string) + exp: experiment name (string) + Output: + zonal-mean time-mean csrh as xarray dataset + """ + # 1. fluxes + csrh = csrh_from_flx_ymonmean(mod, exp) + if csrh is not None: + return csrh.mean(["month", "lon"]).persist() + # 2. tntr from CFmon, AERmon, Emon + csrh = csrh_from_tntr_ymonmean(mod, exp) + if csrh is not None: + return csrh.mean(["month", "lon"]).persist() + # 3. tntr from EmonZ + csrh = csrh_from_tntr_EmonZ_ymonmean(mod, exp) + if csrh is not None: + csrh_mean = csrh.mean(["month"]) + # for CESM family of models, set all levels below 500hPa to nan + # because EmonZ data has artifical zeros below 500hPa + if mod in ["CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2"]: + csrh_mean = csrh_mean.where(csrh_mean.lev<500e2) + return csrh_mean.persist() + # if no data could be found, print warning and return None + print("ATTENTION: no data for zonal-mean time-mean clear-sky radiative heating found for model ", mod, " and experiment ", exp) + return None + + +def load_cl_zontimmean(mod, exp): + """ + For given model and experiment, load zonal-mean time-mean cloud cover. All + cloud cover is assumed to be in the Amon table. + + Input: + mod: model name (string) + exp: experiment name (string) + Output: + zonal-mean time-mean cloud cover as xarray dataset + """ + import os.path + file=path_mean+"cl_Amon_"+mod+"_"+exp+".ymonmean.nc" + if os.path.exists(file): + cl = xr.open_dataset(file, chunks="auto").mean(["month", "lon"])["cl"] + else: + cl = None + return cl + + +def crh_zonaltimemean_Tlevels(mod, exp, Tint=np.linspace(100,320,221), remove_pbl=False): + """ + Generates zonal-mean time-mean CRH sampled on temperature levels. Only treats levels below the tropopause + to avoid problems from temperatures increasing again with height. + + Optional: Remove CRH values in PBL between surface and 800 hPa to avoid cluttering of near-surface values. + + Input: + mod: model name (string) + exp: experiment name (string) + Tint: temperatures for interpolation (optional) + remove_pbl: remove near-sfc values (optional) + Output: + xarray dataarray of zonal-mean time-mean CRH interpolated to temperature levels + """ + # load temperature, tropopause and crh + ta = ta_Amon_ymonmean(mod=mod, exp=exp)["ta"].mean(["month", "lon"]).persist() + tp = tropo_Amon_zontimmean(mod=mod, exp=exp)["trop"].persist() + crh = load_crh_zontimmean(mod=mod, exp=exp).persist() + # for HadGEM and UKESM models: need to change crh coords from hgt to lev and interpolate crh to pressure levels + if mod in ["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"]: + lat = crh.lat + crh_int, lev = height2pressure_zg(crh, mod=mod, exp=exp) + # crh_int is a numpy array, need to transform back to dataarray crh + crh = xr.DataArray(crh_int, name="crh", dims=("lev", "lat"), + coords={"lev": lev, "lat": lat}) + # merge into one dataset, ignore eps differences in coordinates + ds = xr.merge([tp.to_dataset(name="tp"), ta.to_dataset(name="ta"), crh.to_dataset(name="crh")], + join="override") + # set regions above tropopause to nan + ds["crh"] = ds["crh"].where(ds.lev>ds["tp"]*100) + ds["ta"] = ds["ta"].where(ds.lev>ds["tp"]*100) + # remove near-surface values + if remove_pbl: + ds["crh"] = ds["crh"].where(ds.lev<750e2) + ds["ta"] = ds["ta"].where(ds.lev<750e2) + # interpolate to temperature levels + crh_Tint= np.array([np.interp(Tint, ds["ta"].isel(lat=i)[::-1], ds["crh"].isel(lat=i)[::-1], left=np.nan, right=np.nan) + for i in range(ds.lat.size)]) + crh_Tint = np.transpose(crh_Tint) + # return crh_Tint as xarray datarray + return xr.DataArray(crh_Tint, name="crh_Tint", dims=("Tint", "lat"), + coords={"Tint": Tint, "lat": ds.lat}) + +#------------------------------------------------------------- +# functions related to observational data + +def acre_obs_2bflxhrlidar_r05(): + """ + Loads time-mean zonal-mean CRH from 2B-FLXHR-LIDAR R05 averaged between 2007 and 2010. + Returns CRH as xarray dataarray on interpolated to the same pressure levels as model data, use standard + atmosphere to convert from height to pressure. + """ + import sys + sys.path.append("../analysis/") + from cmip6radheating import define_targetlevels + ds = xr.open_dataset("../obsdata/2B-FLXHR-LIDAR.P2_R05.heatingrates_binned.2007-2010.zonmean.timmean.nc") + ds["crh"] = (ds["HR_allsky_sw"]+ds["HR_allsky_lw"]-(ds["HR_clrsky_sw"]+ds["HR_clrsky_lw"])).squeeze() + # interpolation to pressure + ds = ds.sel(height=slice(80e4,0)) + lev = height2pressure(ds.height.values) + ds = ds.assign_coords(lev=("height", lev)).swap_dims({"height":"lev"}).drop("height") + ds = ds.interp(lev=define_targetlevels()) + ds = ds.rename({"y": "lat"}) + return ds["crh"] + + +def acre_obs_2bflxhrlidar_r04(): + """ + Loads time-mean zonal-mean CRH from 2B-FLXHR-LIDAR R04 averaged between 2007 and 2010. + Returns CRH as xarray dataarray on interpolated to the same pressure levels as model data, use standard + atmosphere to convert from height to pressure. + """ + import sys + sys.path.append("../analysis/") + from cmip6radheating import define_targetlevels + ds = xr.open_dataset("../obsdata/2B-FLXHR-LIDAR.P2_R04.heatingrates_binned.2007-2010.zonmean.timmean.nc") + ds["crh"] = (ds["HR_allsky_sw"]+ds["HR_allsky_lw"]-(ds["HR_clrsky_sw"]+ds["HR_clrsky_lw"])).squeeze() + # interpolation to pressure + ds = ds.sel(height=slice(80e4,0)) + lev = height2pressure(ds.height.values) + ds = ds.assign_coords(lev=("height", lev)).swap_dims({"height":"lev"}).drop("height") + ds = ds.interp(lev=define_targetlevels()) + ds = ds.rename({"y": "lat"}) + return ds["crh"] + + +def acre_obs_voigt2019(): + """ + Loads time-mean zonal-mean ACRE estimated by Cloudsat/Calipso dataset used in Voigt et al., 2019, + J. Climate, https://doi.org/10.1175/JCLI-D-18-0810.1. + Returns ACRE as xarray dataarray on same interpolated pressure levels as model data. + + Note: Missing values below 900 hPa. + """ + # import pressure levels of interpolated data + import sys + sys.path.append("../analysis/") + from cmip6radheating import define_targetlevels + tmp = xr.open_dataset("../obsdata/voigtetal2019_cloudsatcalipso_acre-zontimmean.nc") + tmp_int = np.zeros((np.size(define_targetlevels()), tmp.lat.size)) + for ilat in range(tmp.lat.size): + tmp_int[:, ilat] = np.interp(define_targetlevels()[::-1], tmp.lev[::-1].values, tmp["acre"][::-1, ilat])[::-1] + # convert to dataarray + obs = xr.DataArray(tmp_int, name="acre_obs", dims=("lev", "lat"), + coords={"lev": define_targetlevels(), "lat": tmp.lat}) + return obs + + +def acre_obs_cccm(): + """ + Loads time-mean zonal-mean ACRE estimated by Seung-Hee Ham from CCCM dataset for years 2007-2010; + for CCCM ACRE see JGR-Atmospheres, 2017, https://doi.org/10.1002/2017JD026725. + Returns ACRE as xarray dataarray on interpolated pressure levels as model data, use standard + atmosphere to convert from height to pressure. + """ + # import pressure levels of interpolated data + import sys + sys.path.append("../analysis/") + from cmip6radheating import define_targetlevels + ds = xr.open_dataset("../obsdata/seungheeham_cccm_acre-zontimmmean.nc") + # clean up coordinates + ds = ds.rename({"dim nlat": "lat"}).drop("lon") + ds = ds.rename({"dim nhgt": "hgt"}) + # interpolation to pressure + ds = ds.isel(hgt=slice(10,137)) # remove levels with negative height + lev = height2pressure(1000*ds.hgt.values) + ds = ds.assign_coords(lev=("hgt", lev)).swap_dims({"hgt":"lev"}).drop("hgt") + ds = ds.interp(lev=define_targetlevels()) + # return net ACRE from SW day and LW day + return (ds["Clim_CRE_sw_HR_Day"]+ds["Clim_CRE_lw_HR_Day"]) + + +def cc_obs_voigt2019(): + """ + Loads time-mean zonal-mean cloud cover averaged between June 2006 and April 2011 from + CloudSat/CALIPSO. Taken from Voigt et al., WIRES CC, 2021, https://doi.org/10.1002/wcc.694. + Returns cloud cover as xarray dataarray on interpolated pressure levels as model data, use standard + atmosphere to convert from height to pressure. + """ + import sys + sys.path.append("../analysis/") + from cmip6radheating import define_targetlevels + ds = xr.open_dataset("../obsdata/voigtetal2021wirescc_CloudSatCALIPSO_cloud_fraction_bin_sum_200606-201104.clim.nc") + ds = ds.rename({"cloud_fraction": "cl", "lev": "hgt"}).mean("lon").squeeze() + # interpolation to pressure + ds = ds.isel(hgt=slice(0,104)) # remove levels with negative height + lev = height2pressure(ds.hgt.values) + ds = ds.assign_coords(lev=("hgt", lev)).swap_dims({"hgt":"lev"}).drop("hgt") + ds = ds.interp(lev=define_targetlevels()) + return ds["cl"] + + +def cc_obs_bertrand2024(): + """ + Loads time-mean zonal-mean cloud cover averaged between 2007 and 2010 from + CloudSat/CALIPSO as derived by Bertrand et al., 2024, ESSD. See https://essd.copernicus.org/articles/16/1301/2024/essd-16-1301-2024.html. + Returns cloud cover as xarray dataarray on interpolated pressure levels as model data, use standard + atmosphere to convert from height to pressure. + """ + import sys + sys.path.append("../analysis/") + from cmip6radheating import define_targetlevels + # location where Bertrand data is hosted + path="/scratch/das/avoigt/bertrand2024-3S-GEOPROF-COMB/radarlidar_monthly_2.5x2.5/" + lat = xr.open_dataset(path+"/2010-01_CSCAL_3S-GEOPROF-COMB_2.5x2.5_v8.2_beta.nc").lat.values + hgt = xr.open_dataset(path+"/2010-01_CSCAL_3S-GEOPROF-COMB_2.5x2.5_v8.2_beta.nc").height.values + # loop over all months from 2006 to 2010 + cc=np.zeros((4,12,72,78)) + np.NaN + iyear=0 + for year in ["2007", "2008", "2009", "2010"]: + imonth=0 + for month in ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]: + try: + ds = xr.open_dataset(path+"/"+year+"-"+month+"_CSCAL_3S-GEOPROF-COMB_2.5x2.5_v8.2_beta.nc" ) + cc[iyear,imonth] = ds.isel(doop=1)["cloud_fraction_on_levels"].mean("lon").values + except: + print(path+"/"+year+"-"+month+"_CSCAL_3S-GEOPROF-COMB_2.5x2.5_v8.2_beta.nc", "not found!") + imonth+=1 + iyear+=1 + # mean over years and months + cc=np.nanmean(np.nanmean(cc,axis=0), axis=0) + # convert to data array + cc = xr.DataArray(cc, name="cl", dims=("lat", "hgt"), + coords={"lat": lat, "hgt": hgt}) + # interpolation to pressure + cc = cc.sel(hgt=slice(80e4,0)) + lev = height2pressure(cc.hgt.values) + cc = cc.assign_coords(lev=("hgt", lev)).swap_dims({"hgt":"lev"}).drop("hgt") + cc = cc.interp(lev=define_targetlevels()) + cc = cc.transpose() + return cc + + +#------------------------------------------------------------- +# functions related to plotting layout etc. + +def spacing_subplots(): + # set the spacing between subplots + import matplotlib.pyplot as plt + plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, + wspace=0.08, hspace=0.1) + +def spacing_subplots_v2(): + # set the spacing between subplots + import matplotlib.pyplot as plt + plt.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, + wspace=0.08, hspace=0.2) \ No newline at end of file diff --git a/plots4paper/illustrate_order_of_computation.ipynb b/plots4paper/illustrate_order_of_computation.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..931de1d7c7bb38069d7c0d563dac39d8a24895c8 --- /dev/null +++ b/plots4paper/illustrate_order_of_computation.ipynb @@ -0,0 +1,311 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "59bcfc23-56fb-4398-9996-daeebbfa1521", + "metadata": {}, + "source": [ + "# Show that to compute radiative heating rates from radiative fluxes, one needs to first compute heating rates on model levels before interpolating to pressure levels" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "9ef8643d-acbd-45e8-9f73-09e4ef501a74", + "metadata": {}, + "outputs": [], + "source": [ + "import xarray as xr\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib as mpl\n", + "\n", + "import helpers as hlp\n", + "import sys\n", + "sys.path.append(\"../analysis/\")\n", + "import cmip6radheating" + ] + }, + { + "cell_type": "markdown", + "id": "0518f44e-0e78-4ea2-bc2f-a8fdf7af7655", + "metadata": {}, + "source": [ + "We illustrate this for the all-sky radiative heating of the BCC-CSM2-MR and the second-to-last year (2013)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e2cf7eeb-8616-4965-843d-31e4f9506515", + "metadata": {}, + "outputs": [], + "source": [ + "model=\"BCC-CSM2-MR\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "05088bac-48b7-4883-a6c3-f89afd411cc9", + "metadata": {}, + "outputs": [], + "source": [ + "flist_rsd, flist_rsu, flist_rld, flist_rlu = cmip6radheating.filelist_allsky_radfluxes(exp=\"amip\", tab=\"CFmon\", mod=model)\n", + "ds_rsd = cmip6radheating.load_data(flist_rsd)[0].isel(time=slice(-24,-12))\n", + "ds_rsu = cmip6radheating.load_data(flist_rsu)[0].isel(time=slice(-24,-12))\n", + "ds_rld = cmip6radheating.load_data(flist_rld)[0].isel(time=slice(-24,-12))\n", + "ds_rlu = cmip6radheating.load_data(flist_rlu)[0].isel(time=slice(-24,-12))\n", + "\n", + "ds_asflx = (ds_rsd[\"rsd\"]-ds_rsu[\"rsu\"]+ds_rld[\"rld\"]-ds_rlu[\"rlu\"]).rename(\"radflx\").to_dataset()\n", + "ds_asflx = xr.merge([ds_rsd, ds_asflx])" + ] + }, + { + "cell_type": "markdown", + "id": "82fe3c43-2779-4200-847d-ce5f26964f89", + "metadata": {}, + "source": [ + "Add pressure and interpolate radiative fluxes to pressure levels." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "9cd16c2f-056d-4720-8d31-3bf1efadede5", + "metadata": {}, + "outputs": [], + "source": [ + "ds_asflx = cmip6radheating.addpressure2dataset(ds_asflx, model=model, levtype=\"half\")\n", + "ds_asflx_int = cmip6radheating.interpolate2pressure(ds_asflx, [\"radflx\"], cmip6radheating.define_targetlevels())" + ] + }, + { + "cell_type": "markdown", + "id": "0b637584-264d-4be0-b9fb-6d132ccca8a0", + "metadata": {}, + "source": [ + "Now we compute radiative heating from interpolated radiative fluxes." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "7fcf747b-904b-4aec-8d72-8120564c6d25", + "metadata": {}, + "outputs": [], + "source": [ + "def compute_heatingrates_plevels(ds):\n", + " # radiative flux\n", + " radflx = ds[\"radflx\"].values\n", + " # pressure levels of the radiative fluxes\n", + " lev = ds.lev.values\n", + " nlev = np.size(lev)\n", + " # compute heating rates\n", + " dradflx = np.diff(radflx, axis=1)\n", + " dlev = np.broadcast_to(np.diff(lev)[None,:,None,None], dradflx.shape)\n", + " hr = -86400 * 9.81/1005 * dradflx/dlev\n", + " # pressure levels of heating rates is in the middle of those of the radiative fluxes\n", + " lev_hr = 0.5*(lev[1:]+lev[0:nlev-1])\n", + " # output dataset with heating rates\n", + " ds_hr = xr.Dataset()\n", + " ds_hr.attrs = ds.attrs\n", + " ds_hr[\"dTdt\"] = xr.DataArray(hr, name=\"dTdt\", dims=(\"time\", \"lev\", \"lat\", \"lon\"), \n", + " coords={\"time\": ds.time, \"lev\": lev_hr, \"lat\": ds.lat, \"lon\": ds.lon})\n", + " return ds_hr" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "3bae9f53-47da-4f2d-8922-dfabea3059ca", + "metadata": {}, + "outputs": [], + "source": [ + "dTdtas_int = compute_heatingrates_plevels(ds_asflx_int)" + ] + }, + { + "cell_type": "markdown", + "id": "1523ab1b-d1ea-49f0-adcb-a87a82c5dd5d", + "metadata": {}, + "source": [ + "For comparison, we load the radiative heating derived from radiative flux divergence on model levels, as well as the radiative heating rate directly output by the model." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "629aa42a-816b-4ca0-aa71-635785870d71", + "metadata": {}, + "outputs": [], + "source": [ + "dTdtas_flx = xr.open_dataset(\"/scratch/das/avoigt/cmip6-acre-data/postprocessed/dTdt-as-from-flx_CFmon_\"+model+\"_amip.zarr\", engine=\"zarr\").isel(time=slice(-24,-12))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "86fbd730-d1c3-489a-8522-a14385f7b705", + "metadata": {}, + "outputs": [], + "source": [ + "dTdtas_tntr = xr.open_dataset(\"/scratch/das/avoigt/cmip6-acre-data/postprocessed/dTdt-as-from-tntr_AERmon_\"+model+\"_amip.zarr\", engine=\"zarr\").isel(time=slice(-24,-12))" + ] + }, + { + "cell_type": "markdown", + "id": "86bd9f38-71f3-4ac2-888e-e5bb2d26c922", + "metadata": {}, + "source": [ + "### Plotting" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "85cc72f6-a2c3-4314-a303-3896aaf19061", + "metadata": {}, + "outputs": [], + "source": [ + "clev=np.delete(2.0*np.linspace(-1,1,21),10) # contour levels, remove 0" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "70a8d2c1-c905-41b5-9e63-7709a3091051", + "metadata": {}, + "outputs": [], + "source": [ + "def make_nice_axes(ax):\n", + " plt.ylim(1000,10)\n", + " plt.yticks([800,600,400,200],[\"800\", \"600\",\"400\",\"200\"], size=10);\n", + " plt.ylabel(\"pressure / hPa\", loc=\"top\", fontsize=12)\n", + " plt.xlim(-88,88)\n", + " plt.xticks([-60,-30,0,30,60],[\" \", \" \", \" \", \" \", \" \"], size=10, va=\"top\");\n", + " ax.tick_params(direction=\"in\", length=6)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "fe8eadaa-9cc9-4f5d-b475-a487a7188238", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Latitude: -66.7283256028822\n", + "Longitude: 67.5\n" + ] + }, + { + "data": { + "image/png": "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59rtXrp0KTfccAPvvPMO9957r73c7NmzmTdvHj/99BNDhw4FXDufhYWFPP3006xYsYKUlBT0ej0tW7bkgQce4IYbbqiynYDDsogAZtf2qQblu+xVPUQ3sGgPyQLFBdaXTI6k9QGdLzKlaxEFtiUr5QUZyIrzMPuFg1JTmxZXGyEiCLyd//77j9WrVzN9+nT788zChQspLCxkzJgx/Pzzz5w7dw5fX18uu+wyLr/8cvsUw88//xyA1atXs3r1agAGDBjAwIEDAWtE4MaNGzl9+jRGo5GwsDD69evn9LBpO/7NN9/M3r17OXz4MIWFhTzxxBNs3ryZjRs3cuedd/LHH39w/PhxZDIZrVq1YtiwYU7ChyRJ/PXXX/z7779kZ2ej0WhITExk8ODBVSbJ2rZtG/v27SMjIwOj0UhQUBCdOnWid+/eKBQKe5+cOnUKsGYhtzF79mwAzGYzf/75J7t377Yfv1WrVgwZMsTJTrPZzO+//86uXbsoKSkhKiqKYcOGVXmeHPv7woULdhumT59ebvlvv/2WkydPlolO3LBhAxs3brTbvXfvXlasWMGIESPo2bOnvdz69evZtGkTN910kz1Zmivn02g0sn79eg4cOEBeXh4qlYqgoCD69OlT5rlQIKguKcdTWPXRQjJURUhKBchkBJ44iW++D1e/+BpRiU17Xr6nEf5vxbg8YbUiRbwpKuXnzp0jJCSEF198kbCwMC5cuMDnn39Or169+Pfff2ndurVT+YEDB7J8+XIkSapWf6WmpnLTTTfxwAMPMHv2bFatWsVjjz1GdHQ0t956K926dWPBggXcfvvtPPnkk1xzzTUAdmd9/fr1DB8+nF69evHBBx8QEBDA0qVLmThxIoWFhWXm+99xxx1cc801LFq0iIKCArvjDjB27FgmTJjA3Xffzb59+3jqqafYv38/f//9t73cPffcw0cffcS9997LyJEjOXnyJE899RQbNmxg586dhIaGVtjWY8eOceONNxIfH49arWbXrl0899xzHDx4kM8++wyA999/nzvvvJNjx46xatUqp/0tFgtjxoxh06ZNPPzww/Tt25dTp04xe/ZsBg4cyD///INOZ52TPGXKFL744gsefPBBhg4dyt69exk3bhx5eZVn5+/WrRtbtmxh7NixJCQk8OqrrwIQFRVFSkpKVaezQq6//no2btzIAw88QO/evenevTu///478+bN4/HHH7eLB66ez1mzZrFo0SLmzZtH165dKSgoYO/evWRmZlbbRncxppys1n6qqDganEDgDpIFivKgKA/JPwSZ1vWRUBmAuQRl9hlMgbHWKRJNhEhftVclVBQ0PvLz81m5ciV9+vRhwIABHDhwgN9++w0/Pz86d+5MVFQUY8aMYfXq1fTv359WrVoB2J31EydOsHjxYpo1a8bIkSPRaDTs27ePb775BqPRWGaK4erVq0lKSmLs2LEYDAankcOvv/6a9u3b0717d9LT01m/fj3nz5/n//7v/+wO/vfff8/OnTvp0aMHrVq1Ijs7m/Xr13Py5EnuuuuuStd8z8rKomPHjgQGBqJQKEhLS2PTpk1kZGQwZswYwDq1cs2aNWRlZTFx4kSn/SVJYunSpZw6dYrLL7+cmJgYsrOz2bBhA8nJyUyZMsX+XLBmzRp27dpF3759admyJenp6Xz99dcYDJV/n6Oiopg8eTJff/01QUFBXHXVVQD4+vqSn59f1emskA4dOnDy5El+/vlnmjdvTnR0NCdOnGDTpk3069fPLh64ej7XrVvH7t27GTRoEFFRURgMBtLT0ykqqp9lYQWNi30bdvPnJwu4EC6jJCAAUKA7n0kY4Qx5+Bli2sXUt4mNFuH/lo/LAsKgQYPKDYnp37+/03aZTEZOTsWZ3BsDV1xxBVdccYX9b7PZzDXXXEP79u358MMPy4xid+vWjfnz53Po0CGn8DtXyczMZO3atXaVfMiQIWzYsIElS5Zw66234u/vT4eL670mJCSUmac4depU2rdvz++//25PDDls2DAyMjJ4/PHHufXWW53O4eDBg/nwww/LtWXcuHG8/PLLAFx11VVERERw0003sWzZMm666SYOHjzIRx99xNSpU3nnnXfs+3Xt2pVevXrxxhtv8Nxzz1XYVse+s1gs9O/fn5CQEG6//XZee+01goKCaNeuHYGBgWg0mjJtXbZsGT/99BMrVqxg3Lhx9u2dO3emR48eLFy4kHvuuYeDBw/y+eefM3PmTHt7hg4dam9PZfj7+9O7d280Gg2BgYEenRf65ptv8vfffzNhwgR++OEHbrzxRvr372+PJAHXz+eff/7JVVddxcyZM+372sSlmlJdYaC+6rcKEl6IRg+qakYRKKx5FQQCgecoKiripptuolmzZgC0bNmSU6dOsWfP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XYfrr78ew4cPx0svveTTbZ3I25VXXom+vj4sWrQInZ2dmDJlCt577z3k5eV5tuF7GSXCqaeeivb2dtxyyy1obGzEuHHj8M4772Do0KEx71MQRVGUsI1ERERERERElIY4BwIRERERERERhcUAgYiIiIiIiIjCYoBARERERERERGExQCAiIiIiIiKisBggEBEREREREVFYDBCIiIiIiIiIKCwGCEREREREREQUFgMEIiIiIiIioggtX74cgiDg66+/9rm+ra0NBx54IAwGA1atWuW5vqOjA1qtFq+++mrI/QqCgJtuuikRTZaMRu4GEBEREREREaWy3bt3Y/bs2Whubsb777+Pgw8+2HPb66+/Dp1Oh2OOOUbGFkqDAQIRERERERFRjH755RcceeSRsNvtWLNmDcaPH+9z+7/+9S8cd9xxyM7OlqmF0uEQBiIiIiIiIqIYrF27Foceeig0Gg0++eSTQeGB2WzG+++/j5NPPtnnugsuuADFxcUwGAw45phjsGnTpkH73rx5M8477zyMHDkSOTk5qK6uxgknnIAff/zRs01PTw8KCgqwcOHCQfffvn071Go17r77bsmOlwECERERERERUZQ++eQTzJw5E2VlZfjkk08wbNiwQdu8+eabEAQBxx9/PABAFEWcdNJJePbZZ3HZZZfh1VdfxcEHH4xjjz120H0bGhpQXFyMO++8E//5z3/wyCOPQKPRYMqUKdi4cSMAwGAw4He/+x2ef/55dHV1+dz/0UcfhU6nw+9+9zvJjjkjhzC4XC40NDQgLy8PgiDI3RwiIiJFE0UR3d3dqKqqgkrF7x6IiIgA4M9//jOMRiM++OADlJaWBtzmX//6F4466ijk5eUBAN599118+OGH+Otf/4qLL74YADB79mzodDpce+21PvedPn06pk+f7vnd6XTi+OOPx7777ou//e1vuO+++wAAF110Ef7617/i6aefxuLFiwEA/f39eOqpp3D66aejuLhYsmPOyAChoaEBtbW1cjeDiIgopezatQs1NTVyN4OIiEgR5s6dizfeeAOLFy/GP/7xD6jVap/bLRYL3n33XSxbtsxz3YcffggAOPPMM322PeOMMwYFCA6HA0uXLsVzzz2HzZs3w263e25bv3695+dhw4Zhzpw5ePTRR3HJJZdAEASsWLEC7e3tuOiiiyQ7XiBDAwR3+vPRd+th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rq4ubM8W73PktttuQ319PfR6PT788EP09/fjsssuw8SJE2E0GlFUVIRDDjkEr7/+us8+BEGAxWLBM8884zmumTNnem5vamrCwoULUVNTA51Oh/r6etx8881wOHy/8V62bBn2228/GAwG5OXlYfTo0bjmmmtCtj/VKD1EICIiIqL0E/HXRMHGhEcyVjxd/eY3v8GCBQvwhz/8AevWrcP111+Pn3/+GV988YXPUpYzZ87EVVddhdWrV+OEE2JbKu7//u//cPzxx2PFihXYtWsXrrjiCpx11ln44IMPAACvvvoq5s+fD6PRiEcffRQAoNfrAQC9vb2YMWMGdu/ejWuuuQYTJkzAunXrcMMNN+DHH3/E+++/7/M6vvbaa/j4449xww03oKKiAmVlZZ7bHn74YQwdOhQPPPAAXC4Xli5dimOPPRZr1qzBIYccAgBYs2YNZs+ejQkTJuDJJ5+EXq/Ho48+ihNOOAEvvPACTj311KDHuX37dowaNQqnnXYaioqK0NjYiGXLlmHy5Mn4+eefUVJSguOPPx5LlizBNddcg0ceecSzzql7ZZDnnnsO55xzDk488UQ888wz0Gq1+Nvf/oajjz4a7777LmbNmgUA+O9//4sTTzwRhxxyCF588UU4nU4sXboUzc3NEb8uTU1NOPPMM3HZZZfhxhtvxKuvvoq//OUvqKqqwjnnnBP1879lyxacccYZnqDh+++/x+23344NGzbgqaeeAjAwVOX3v/89tmzZgldffTXitoY7hwDgvPPOw0svvYQrr7wSRxxxBH7++Wf85je/gdlsjvhxHnzwQeyzzz645557kJ+fj5EjR8JqtaKjowOXX345qqurYbPZ8P7772PevHl4+umnPc/V559/jiOOOAKHH344rr/+egDwzPje1NSEgw46CCqVCjfccAOGDx+Ozz//HLfddhu2b9+Op59+GsDAkKtFixbhT3/6E+655x6oVCps3rwZP//8c8THkCxiy86YhjK4ads2K3Y4Q6JwCAMRERGRfCIOEA4//HCoVIM7LBx22GE+1wuCgK4uZc1onijz5s3D0qVLAQBHHXUUysvLceaZZ+Lll1/GmWee6dlu0qRJEAQBn376acwBwjHHHIMHH3zQ83tHRweuvPJKNDU1oaKiApMmTUJ27f8CQwAA3khJREFUdjby8/Nx8MEH+9z3wQcfxA8//IAv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btw4AMDjjz+OvLw8ZGVlob6+HsXFxXjooYfw29/+Fh0dHZg/fz7KysrQ2tqK77//Hq2trVi2bBkA4NZbb8UxxxyD2bNn47LLLoPT6cRdd92F3NzciHs8RCLS53/27NnQ6XQ4/fTTceWVV6K/vx/Lli1DZ2fnoH2OHz8eK1euxLJly3DAAQdApVJ5JmiM1b777ovTTz8d9957L9RqNY444gisW7cO9957L4xGY8BJVCM1Z84crFy5EosWLcL8+fOxa9cu3HrrraisrMQvv/wy6NhWr16NN998E5WVlcjLy8OoUaNwyy23YNWqVZg6dSouvvhijBo1Cv39/di+fTveeecdPPbYY6ipqcEFF1yA7OxsTJs2DZWVlWhqasIdd9wBo9GIyZMnB22jvXE7tJV1MR0fexnIgyECERERUXJFHSBceOGF6O/vx0svvYQJEyYM+rY4k6xcuRI33XQTli1bBkEQcMIJJ+CBBx6ATuc70ddrr72G8ePHY/z48Qltz80334zGxkZccMEF6O7uxtChQ7F9+3bk5ubi448/xp133onHH38c27ZtQ3Z2NoYMGYIjjzwyqlUHLrroIvT39+Piiy9GS0sL9t13X7z99tuYNm2aZ5sZM2bggw8+wI033ohzzz0XLpcL++23H9544w3MmTMn5P5XrFiBSy65BFdeeSUcDgemTZuGVatW4fjjj/fZrr6+Hg888AD++te/YubMmXA6nXj66adx7rnn4qyzzsKQIUOwdOlSLFy4EN3d3SgrK8PEiRNx7rnnevYxe/ZsvPbaa7juuutw6qmnoqKiAosWLUJfX59PIBKvSJ//0aNH45VXXsF1112HefPmobi4GGeccQYuvfRSn1UyAOCSSy7BunXrcM0116CrqwuiKAYM9KL19NNPo7KyEk8++STuv/9+TJw4ES+//DKOOeaYQSFONM477zy0tLTgsccew1NPPYVhw4bh6quvxu7duwc913/9619x4YUX4rTTTvMsgbl69WpUVlbi66+/xq233oq7774bu3fvRl5eHurr63HMMcd4eiUcdthhWL58OV5++WXP0KFDDz0U//jHP1BaWhrP0xOQVOFBOoUGu7rj67ESDffEigwSiIiIiBJPEKOsOoxGI5544olB37KnErPZDKPRiG8374YhLz/gNr858jDMOGwaHnnkkbgfq6qqCvfffz8uuOCC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TwoSvEMEMxZWDBoe+v0dAAL/LSgs1Pf9IPdahbsLhplSc3JRbPYgiIiIyHQMEFSSugrUimrZyfd3LQYjkKvOzzj3/0EuN/OjEIs9oPGq+sELZ33bc41qf1dCGkewdSSMDhm0eG5ChQfehanaQtVp4cH5mcGfy3DDA//bkAsRJOE+52q2cZULD4ItpNoiNyngkf3mOWefM6ljSOl45T6HSqYtBAt4vKeIyL3Xve8j0vd2sOl4/s9lWl4e6k+fVHX7REREZE+ODBDcbjcAoKLCnK3IrEB6brR+jqZcmY+565UvhNgmpQl+OuI7hpxU4NCRs1+W5b7UpmYl4MypajTPSURdTeQFrvf9KSGNSa8v3MGOmOp9NFVr9adPeqZ8SL8DwIEDR9GqVePL/7BX2esp93qVHw3+epQfCX18NTUnN+j53o/FW2FhtadQjdTp6iaNTzt59nmpCbCYIgC0So1HdWWlJmPIigIOlNf8bzxnn2vps+a9EKb0nAd7bisP70FyvvwCsXKXDUbaalB6H505Bc/fAel58/+bUlfj+7fE/3N7/JeTnmkO5UfP/b//roY5qfD5eyP3Op2fmYiaqtCvgf9zKjlzqjrgZ1wad7DtFr2fP3d97dn/njkte9ny/T8gOb8tUnNyUX/6JJL+l4dI/34SERGRM7ncDvw2cPDgQbRs2dLsYRAREVnKL7/8ghYtrL12DxEREYXPkQFCQ0MDDh8+jOTkZLhcLrOHQ0REJDS3243Kykrk5+ejSZPG3RVERETkDI4MEIiIiIiIiIhIHR5GICIiIiIiIqKQGCAQERERERERUUgMEIiIiIiIiIgoJAYIRERERERERBQSAwQiIiIiIiIiCokBAhERERERERGFxACBiIiIiIiIiEJigEBEREREREREITFAICIiIiIiIqKQGCAQERERERERUUgMEIiIiIiIiIgoJAYIRERERERERBQSAwQiIiIiIiIiCokBAhERERERERGFxACBiIiIiIiIiEJigEBEREREREREITFAICIiIiIiIqKQGCAQERERERERUUgMEIiIiIiIiIgoJAYIRERERERERBQSAwQiIiIiIiIiCokBAhERERERERGFxACBiIiIiIiIiEJigEBEREREREREITFAICIiIiIiIqKQGCAQERERERERUUjRZg/ADA0NDTh8+DCSk5PhcrnMHg4REZHQ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r3PllVfi3Xff9Tlt7dq1uPzyy7n+ARER2YbiAKFfv35o0qRxw8JVV13lc7rL5fIsNmRXkydPRnR0NL7++mufInT06NGNLtu1a1fMmzcP1dXVAbd+ktTW1uLxxx/3HFHu378/tmzZgpUrV/oECK+++qrn/xsaGtC3b1+43W78+c9/xowZM+ByudClSxfEx8cjJSUl5HSF6Oho3HrrrViyZAnKy8s9RfzOnTvx9ddfY/HixZ7LTpgwAZdccgn+85//eBbTGzRoEI4dO4ZHH30UY8aMkX2feEtOTsZ7772HqKizban5+fm44oor8MEHH2DkyJGq7ueiiy7yBCTA2e2+Bg0ahMLCQjz77LPo27cv4uLi0K1bNwBAixYtFE/fOH78ON5//33P/uEDBgzAp59+ipUrV3oChGeeeQYnTpzAZ599hg4dOgAAhgwZgsGDB/t0NIRy++23e9ZokNx000246aabfB7b0KFDkZOTg5UrV+Lee+9FVlYW2rU7u1tIhw4dfB7byZMncd9992Ho0KFYs2aN5/TrrrsOXbt2xaOPPor/9//+HwDgiy++wO9//3vcddddnsvdcMMNiscvskAhh8jBAsljeEBGmThxIlauXIm3334bycnJns6C1NRUxMefXTRz6tSpOHToEP72t78BAO655x4899xzmDx5Mu666y58+eWXWLp0Kd544w3THgcREZHWFAUIt99+u97jsIyTJ09iw4YNGDdunKJ589nZ2WhoaEBxcXHIRQtdLheGDRvmc1rnzp3xn//8x+e0//znP5g7dy42b96MiooKn/NKSkoaLeKkxJ133omFCxdi9erVuPvuuwGcDSri4uIwatQoAMCePXuwa9cuPP300wCAM2fOzXG+7rrr8N5772H37t24+OKLg97X9ddf7wkPpMcIwNOar/Z+XnjhBbz00kv48ccffaZ7tG/fXvXz4C03N9cTHniP9dtvv/X8vmHDBnTs2NETHkhuueUWfPTRR4rvS26Lr6qqKjzxxBN48803UVhYiPr6es95O3fuDHmbmzZtwokTJ3D77bf7PIfA2T3OFyxY4Am2rrjiCixbtgwZGRkYMGAAunXrZvsjZnVFhQwRLIbrH5BRlixZAqDxorveuxcVFRXhwIFza8C0adMG77//Pu6//3785S9/QX5+Pp599llu4UhERLaiKEDwPuLtdKWlpaiv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\n", + "text/plain": [ + "<Figure size 1200x1200 with 5 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig=plt.figure(figsize=(6*2,4*3))\n", + "\n", + "ax=plt.subplot(3,2,1)\n", + "cnt=plt.contourf(dTdtas_int.lat, dTdtas_int.lev/100, dTdtas_int[\"dTdt\"].isel(time=0).mean(\"lon\"), clev, cmap=\"RdBu_r\", extend=\"both\")\n", + "for c in cnt.collections: c.set_edgecolor(\"face\")\n", + "make_nice_axes(ax)\n", + "ax.text(0.03,0.96, \"a) interpolated fluxes\", ha=\"left\", va=\"top\", transform=ax.transAxes, backgroundcolor=\"white\", \n", + " size=12, bbox=dict(facecolor=\"white\", edgecolor=\"k\", boxstyle=\"round,pad=0.3\")) \n", + "\n", + "ax.text(1.0,1.1, model+\", January 2013, all-sky radiative heating rates\", ha=\"center\", va=\"top\", transform=ax.transAxes, backgroundcolor=\"white\", \n", + " size=12, fontweight=\"bold\") \n", + "\n", + "ax=plt.subplot(3,2,3)\n", + "cnt=plt.contourf(dTdtas_flx.lat, dTdtas_flx.lev/100, dTdtas_flx[\"dTdt-as-from-flx\"].isel(time=0).mean(\"lon\"), clev, cmap=\"RdBu_r\", extend=\"both\")\n", + "for c in cnt.collections: c.set_edgecolor(\"face\")\n", + "make_nice_axes(ax)\n", + "ax.text(0.03,0.96, \"b) interpolated heating rates\", ha=\"left\", va=\"top\", transform=ax.transAxes, backgroundcolor=\"white\", \n", + " size=12, bbox=dict(facecolor=\"white\", edgecolor=\"k\", boxstyle=\"round,pad=0.3\")) \n", + "\n", + "ax=plt.subplot(3,2,5)\n", + "cnt=plt.contourf(dTdtas_tntr.lat, dTdtas_tntr.lev/100, dTdtas_tntr[\"dTdt-as-from-tntr\"].isel(time=0).mean(\"lon\"), clev, cmap=\"RdBu_r\", extend=\"both\")\n", + "for c in cnt.collections: c.set_edgecolor(\"face\")\n", + "make_nice_axes(ax)\n", + "plt.xlabel(\"latitude / deg\", loc=\"right\", fontsize=12)\n", + "plt.xticks([-60,-30,0,30,60],[\"60S\", \"30S\",\"Eq\",\"30N\",\"60N\"], size=10, va=\"top\");\n", + "ax.text(0.03,0.96, \"c) native heating rates\", ha=\"left\", va=\"top\", transform=ax.transAxes, backgroundcolor=\"white\", \n", + " size=12, bbox=dict(facecolor=\"white\", edgecolor=\"k\", boxstyle=\"round,pad=0.3\")) \n", + "\n", + "# plot colorbar\n", + "# solution taken and adapted from https://stackoverflow.com/a/62436015\n", + "# axes position found manually, to do so use \"print(ax)\" for above subplots\n", + "ax = fig.add_axes([0.51,0.098,0.015, 0.252])\n", + "cb = mpl.colorbar.ColorbarBase(ax, orientation=\"vertical\", \n", + " cmap=\"RdBu_r\", extend=\"both\", ticks=[-2, -1.4, -0.8, 0.0, 0.8, 1.4, 2.0],\n", + " label=\"K/day\",\n", + " boundaries=clev, norm=mpl.colors.Normalize(clev[0], clev[-1])) \n", + "cb.ax.set_yticklabels([\"-2.0\", \"-1.4\", \"-0.8\", \"0\", \"0.8\", \"1.4\", \"2.0\"])\n", + "cb.ax.tick_params(labelsize=10)\n", + "cb.set_label(label=\"K/day\", size=12)\n", + "\n", + "ax=plt.subplot(3,2,2)\n", + "itime=0\n", + "ilat=20\n", + "ilon=60\n", + "print(\"Latitude:\", dTdtas_tntr.lat[ilat].values)\n", + "print(\"Longitude:\", dTdtas_tntr.lon[ilon].values)\n", + "# adjust spines\n", + "ax.spines[\"top\"].set_color(\"none\")\n", + "ax.spines[\"right\"].set_color(\"none\")\n", + "ax.xaxis.set_ticks_position(\"bottom\")\n", + "ax.spines[\"bottom\"].set_position((\"data\",1000))\n", + "ax.spines[\"left\"].set_position((\"data\",0))\n", + "ax.spines[\"left\"].set_color(\"k\")\n", + "plt.plot(dTdtas_tntr[\"dTdt-as-from-tntr\"].isel(time=itime,lat=ilat,lon=ilon), dTdtas_tntr.lev/100, color=\"firebrick\")\n", + "plt.plot(dTdtas_flx[\"dTdt-as-from-flx\"].isel(time=itime,lat=ilat,lon=ilon), dTdtas_flx.lev/100, color=\"royalblue\", zorder=-100)\n", + "plt.plot(dTdtas_int[\"dTdt\"].isel(time=itime,lat=ilat,lon=ilon), dTdtas_int.lev/100, color=\"gray\")\n", + "plt.ylim(1000,10)\n", + "plt.yticks([800,600,400,200],[\"800\", \"600\",\"400\",\"200\"], size=10);\n", + "plt.xlim(-1.5,0)\n", + "plt.xticks([-1.5,-1.0,-0.5,0],[\"-1.5\", \"-1.0\", \"-0.5\", \"0\"], size=10, va=\"top\");\n", + "ax.tick_params(direction=\"in\", length=6)\n", + "plt.ylabel(\"pressure / hPa\", loc=\"top\", fontsize=12)\n", + "plt.xlabel(\"K/day\", loc=\"right\", fontsize=12)\n", + "# legend\n", + "ax.text(0.03,0.96, \"interpolated fluxes\", ha=\"left\", va=\"top\", transform=ax.transAxes, color=\"gray\", backgroundcolor=\"none\", size=12) \n", + "ax.text(0.03,0.89, \"interpolated heating rates\", ha=\"left\", va=\"top\", transform=ax.transAxes, color=\"royalblue\", backgroundcolor=\"none\", size=12) \n", + "ax.text(0.03,0.82, \"native heating rates\", ha=\"left\", va=\"top\", transform=ax.transAxes, color=\"firebrick\", backgroundcolor=\"none\", size=12) \n", + "\n", + "hlp.spacing_subplots()\n", + "\n", + "plt.savefig(\"figures/illustrate_order_of_computation.pdf\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp2023.1 - 3.10.9", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/plots4paper/make_plot_crh_zonaltimemean_amip_median_std_obs.py b/plots4paper/make_plot_crh_zonaltimemean_amip_median_std_obs.py new file mode 100644 index 0000000000000000000000000000000000000000..bded97fc42bb93b38e3e3f633b632d3e21cce295 --- /dev/null +++ b/plots4paper/make_plot_crh_zonaltimemean_amip_median_std_obs.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Zonal-mean time-mean CRH for all available models: model median, model spread and comparison to observations including cloud cover + +# on srvx1 of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plot_crh_zonaltimemean_amip_median_std_obs.py + +# load libraries etc. +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import helpers as hlp +import sys +sys.path.append("../analysis/") +from cmip6radheating import define_targetlevels + +from cmcrameri import cm as cmc # nice colorbars for cloud fraction; adapted from Bertrand et al. 2024 colorbar for cloud fraction + # see https://github.com/bertrandclim/essd2023/blob/v1.0/9-9_ESSD-figs-export_R2R_oct26.ipynb + +# Loads observational estimates of CRH: FLXHR-LIDAR and CCCM; also cloud cover +cc_r05 = hlp.acre_obs_2bflxhrlidar_r05() # 2b-flxhr-lidar r05 +cc_r04 = hlp.acre_obs_2bflxhrlidar_r04() # 2b-flxhr-lidar r04 +cccm = hlp.acre_obs_cccm() # cccm +clobs = hlp.cc_obs_bertrand2024() # cloud cover from cloudsat/calipso by Bertrand et al. 2024 + +# Loads model data into a list of datasets. +crh = list() +ta = list() +tp = list() + +for mod in hlp.models_amip: + if mod in ["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"]: + _crh_int, lev = hlp.height2pressure_zg(hlp.load_crh_zontimmean(mod=mod, exp="amip"), mod=mod, exp="amip") + # _crh_int is a numpy array, need to transform to dataarray + _crh = xr.DataArray(_crh_int, name="crh", dims=("lev", "lat"), + coords={"lev": lev, "lat": hlp.load_crh_zontimmean(mod=mod, exp="amip").lat}) + crh.append(_crh) + else: + crh.append(hlp.load_crh_zontimmean(mod=mod, exp="amip")) + ta.append(hlp.ta_Amon_ymonmean(mod=mod, exp="amip")["ta"].mean(["month", "lon"]).squeeze()) + tp.append(hlp.tropo_Amon_zontimmean(mod=mod, exp="amip")["trop"].squeeze()) + +# Interpolates models to same latitude. +latint = np.linspace(-89,89,179) +crh_latint = list() +for ds in crh: + crh_latint.append(ds.interp(lat=latint).compute()) +ta_latint = list() +for ds in ta: + ta_latint.append(ds.interp(lat=latint).compute()) +tp_latint = list() +for ds in tp: + tp_latint.append(ds.interp(lat=latint).compute()) + +# Constructs numpy array of multi model ensemble, dimensions of model x lev x latint.m +crh_mm = np.array([crh_latint[i] for i in range(len(crh_latint))]) +ta_mm = np.array([ta_latint[i] for i in range(len(ta_latint)) ]) +tp_mm = np.array([tp_latint[i] for i in range(len(tp_latint)) ]) + +# Plotting. +# +# Colorbar handling made easy by using fig, axs = plt.subplots(2, 2, layout="constrained", figsize=(12,8)); see https://matplotlib.org/stable/gallery/subplots_axes_and_figures/colorbar_placement.html. +def niceaxes(ax): + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " ", " ", " "], size=10); + plt.xlim(-80,80) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=10, va="top"); + ax.tick_params(direction="in", length=4) + +lev = crh[0].lev/100 +clev=np.delete(1.0*np.linspace(-1,1,21),10) # contour levels for CRH, remove 0 +cl_clev=100*np.linspace(0,1,21)[1:] # [5,15,25,35,45,55,65,75,85,90] # contour levels for cloud cover + +fig, axs = plt.subplots(3, 2, layout="constrained", figsize=(12,12)) + +ax=plt.subplot(3,2,1) +cnt=plt.contourf(latint, lev, np.nanmedian(crh_mm, axis=0), levels=clev, cmap="RdBu_r") +plt.contour(latint, lev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +ax.text(0.03,0.96, "a) Model median", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +plt.ylabel(r"pressure / hPa", size=10, loc="top") +plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) +for c in cnt.collections: c.set_edgecolor("face") + +ax=plt.subplot(3,2,2) +cnt=plt.contourf(latint, lev, np.nanstd(crh_mm, axis=0), levels=np.linspace(0,0.5,6), cmap="gray_r", extend="max") +plt.contour(latint, lev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +cbar=plt.colorbar(cnt) +cbar.set_ticks([0,0.1,0.2,0.3,0.4,0.5]) +cbar.ax.tick_params(labelsize=10) +cbar.set_label(label="K/day", size=10) +niceaxes(ax) +ax.text(0.03,0.96, "b) Std. deviation\n across models", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +for c in cnt.collections: c.set_edgecolor("face") + +ax=plt.subplot(3,2,3) +cnt=plt.contourf(cc_r05.lat, cc_r05.lev/100, cc_r05, levels=clev, cmap="RdBu_r", extend="both") +plt.contour(latint, lev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +ax.text(0.03,0.96, "c) 2B-FLXHR-LIDAR R05", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +plt.ylabel(r"pressure / hPa", size=10, loc="top") +plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) +for c in cnt.collections: c.set_edgecolor("face") + +ax=plt.subplot(3,2,4) +cnt=plt.contourf(cc_r04.lat, cc_r04.lev/100, cc_r04, levels=clev, cmap="RdBu_r", extend="both") +plt.contour(latint, lev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +cbar=plt.colorbar(cnt) +cbar.set_ticks([-1, -0.7, -0.4, 0.0, 0.4, 0.7, 1.0]) +cbar.ax.tick_params(labelsize=10) +cbar.set_label(label="K/day", size=10) +ax.text(0.03,0.96, "d) 2B-FLXHR-LIDAR R04", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +for c in cnt.collections: c.set_edgecolor("face") + +ax=plt.subplot(3,2,5) +cnt=plt.contourf(cccm.lat, cccm.lev/100, cccm, levels=clev, cmap="RdBu_r", extend="both") +plt.contour(latint, lev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +ax.text(0.03,0.96, "e) CCCM", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +plt.xlabel("latitude / deg", size=10, loc="right") +plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=10, va="top"); +plt.ylabel(r"pressure / hPa", size=10, loc="top") +plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) +for c in cnt.collections: c.set_edgecolor("face") + +ax=plt.subplot(3,2,6) +cnt=plt.contourf(clobs.lat, clobs.lev/100, clobs, levels=np.arange(0.,0.7,0.05), cmap=cmc.batlow) +for c in cnt.collections: c.set_edgecolor("face") +plt.contour(latint, lev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="white", linewidth=1) +niceaxes(ax) +cbar=plt.colorbar(cnt) +cbar.set_ticks([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]) +cbar.ax.tick_params(labelsize=10) +cbar.set_label(label=" ", size=10) +ax.text(0.03,0.96, "f) Observed cloud fraction", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +plt.xlabel("latitude / deg", size=10, loc="right") +plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=10, va="top"); + +plt.savefig("figures/crh_zonaltimemean_amip_median_std_obs.pdf") + + + diff --git a/plots4paper/make_plot_radheating_amip_variance.py b/plots4paper/make_plot_radheating_amip_variance.py new file mode 100644 index 0000000000000000000000000000000000000000..4e6274daffb313558d77c726cee83820c250f54f --- /dev/null +++ b/plots4paper/make_plot_radheating_amip_variance.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plot intermodel variance of zonal-mean time-mean radiative heating in all-sky, clear-sky and cloud-radiative heating, +# as well as covariance between clear-sky and cloud radiative heating +# --> show that model spread in all-sky radiative heating is primarily caused by model spread in cloud-radiative heating + +# on masterhub of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plot_radheating_amip_variance.py + +# load libraries etc. +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp +import sys +sys.path.append("../analysis/") +from cmip6radheating import define_targetlevels + +import warnings +warnings.simplefilter("ignore") + +# Loads model data into a list of datasets. +csrh = list() +crh = list() +ta = list() +tp = list() + +modlist = hlp.models_amip.copy() + +# remove EC-EArth3 for which clear-sky radiative heating is much weaker compared to the other models +# this - in some sense artificially - increases the model spread in clear-sky radiative heating +modlist.remove("EC-Earth3") + +for mod in modlist: + if mod in ["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"]: + _csrh_int, lev = hlp.height2pressure_zg(hlp.load_csrh_zontimmean(mod=mod, exp="amip"), mod=mod, exp="amip") + _crh_int, lev = hlp.height2pressure_zg(hlp.load_crh_zontimmean(mod=mod, exp="amip"), mod=mod, exp="amip") + # transform from numpy array to transform to dataarray + _csrh = xr.DataArray(_csrh_int, name="csrh", dims=("lev", "lat"), + coords={"lev": lev, "lat": hlp.load_csrh_zontimmean(mod=mod, exp="amip").lat}) + _crh = xr.DataArray(_crh_int, name="crh", dims=("lev", "lat"), + coords={"lev": lev, "lat": hlp.load_crh_zontimmean(mod=mod, exp="amip").lat}) + csrh.append(_csrh) + crh.append(_crh) + else: + csrh.append(hlp.load_csrh_zontimmean(mod=mod, exp="amip")) + crh.append(hlp.load_crh_zontimmean(mod=mod, exp="amip")) + ta.append(hlp.ta_Amon_ymonmean(mod=mod, exp="amip")["ta"].mean(["month", "lon"]).squeeze()) + tp.append(hlp.tropo_Amon_zontimmean(mod=mod, exp="amip")["trop"].squeeze()) + +# Interpolate models to same latitude. +latint = np.linspace(-89,89,179) +csrh_latint = list() +for ds in csrh: + csrh_latint.append(ds.interp(lat=latint).compute()) +crh_latint = list() +for ds in crh: + crh_latint.append(ds.interp(lat=latint).compute()) +ta_latint = list() +for ds in ta: + ta_latint.append(ds.interp(lat=latint).compute()) +tp_latint = list() +for ds in tp: + tp_latint.append(ds.interp(lat=latint).compute()) + +# Constructs numpy array of multi model ensemble, dimensions of model x lev x latint +csrh_mm = np.array([csrh_latint[i] for i in range(len(csrh_latint))]) +crh_mm = np.array([crh_latint[i] for i in range(len(crh_latint))]) +ta_mm = np.array([ta_latint[i] for i in range(len(ta_latint)) ]) +tp_mm = np.array([tp_latint[i] for i in range(len(tp_latint)) ]) + +# all-sky radiative heating +asrh_mm = csrh_mm+crh_mm + +def covariance(data1, data2): + """ + Computes covariance assuming a numpy array of dimensions (models, lev, lat). + When data1 == data2, then this gives the variance. + """ + nmod = np.shape(data1)[0] + nlev = np.shape(data1)[1] + nlat = np.shape(data1)[2] + cov = np.nansum((data1 - np.nanmean(data1, axis=0)) * (data2 - np.nanmean(data2, axis=0)), axis=0) + # divide by number of available models, take into account that some models have nan in some parts + # of the atmosphere + nmod_latlev = np.nansum(0*data1 + 1.0, axis=0) + cov = cov /nmod_latlev + return cov + +def niceaxes(ax): + """ + Produces nice x and y axes for plots. + """ + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " ", " ", " "], size=10); + plt.xlim(-83,83) + plt.xticks([-60,-30,0,30,60],[" ", " "," "," "," "], size=10, va="top"); + ax.tick_params(direction="in", length=4) + +# pressure leves in hPa +plev=1e-2*define_targetlevels() + +# levels for contour plots +varlev=np.linspace(0,0.1,11) +covarlev=np.delete(np.linspace(-0.04,0.04,9), 4) + +# proceeed with plot +fig, axs = plt.subplots(2, 2, layout="constrained", figsize=(12,8)) + +ax=plt.subplot(2,2,1) +cnt=plt.contourf(latint, plev, covariance(asrh_mm,asrh_mm), levels=varlev, cmap="gray_r", extend="max") +for c in cnt.collections: c.set_edgecolor("face") +plt.contour(latint, plev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +plt.ylabel(r"pressure / hPa", size=10, loc="top") +plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) +ax.text(0.03,0.96, "a) All-sky heating", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + +ax=plt.subplot(2,2,2) +cnt=plt.contourf(latint, plev, covariance(crh_mm,crh_mm), levels=varlev, cmap="gray_r", extend="max") +for c in cnt.collections: c.set_edgecolor("face") +plt.contour(latint, plev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +ax.text(0.03,0.96, "b) Cloud-rad. heating", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +cbar=plt.colorbar(cnt) +cbar.set_ticks([0.0, 0.02, 0.04, 0.06, 0.08, 0.10]) +cbar.ax.tick_params(labelsize=10) +cbar.set_label(label=r"K$^2$/day$^2$", size=10) + + +ax=plt.subplot(2,2,3) +cnt=plt.contourf(latint, plev, covariance(csrh_mm,csrh_mm), levels=varlev, cmap="gray_r", extend="max") +for c in cnt.collections: c.set_edgecolor("face") +plt.contour(latint, plev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +plt.ylabel(r"pressure / hPa", size=10, loc="top") +plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) +plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=10, va="top"); +ax.text(0.03,0.96, "c) Clear-sky heating", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + +ax=plt.subplot(2,2,4) +cnt=plt.contourf(latint, plev, 2*covariance(csrh_mm,crh_mm), levels=covarlev, cmap="RdBu_r", extend="both") +for c in cnt.collections: c.set_edgecolor("face") +plt.contour(latint, plev, np.nanmedian(ta_mm, axis=0), levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) +plt.plot(latint, np.nanmedian(tp_mm, axis=0), color="seagreen", linewidth=1) +niceaxes(ax) +ax.text(0.03,0.96, "d) 2 x Covariance", ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=12, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) +niceaxes(ax) +plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=10, va="top"); +plt.xlabel("latitude / deg", loc="right", fontsize=10) +cbar=plt.colorbar(cnt) +cbar.set_ticks(covarlev) +cbar.ax.tick_params(labelsize=10) +cbar.set_label(label=r"K$^2$/day$^2$", size=10) + +hlp.spacing_subplots() + +plt.savefig("figures/radheating_zonaltimemean_amip_variance.pdf") \ No newline at end of file diff --git a/plots4paper/make_plots_cl.py b/plots4paper/make_plots_cl.py new file mode 100644 index 0000000000000000000000000000000000000000..d16620306e4afb7354df47e019d3455d14e333b9 --- /dev/null +++ b/plots4paper/make_plots_cl.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plots of cloud cover cl for all available models and the amip, amip-p4K and amip-future4K simulations +# Generates the following types of multi-panel plots of cl: +# * Plot 1: one panel per model +# * Plot 2: vertical profiles of cl averaged over 5 domains + +# on masterhub of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plots_cl.py + +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp + +from cmcrameri import cm as cmc # nice colorbars for cloud fraction; adapted from Bertrand et al. 2024 colorbar for cloud fraction + # see https://github.com/bertrandclim/essd2023/blob/v1.0/9-9_ESSD-figs-export_R2R_oct26.ipynb + +import warnings +warnings.simplefilter("ignore") + +#---------------------------------------------------------------------- +# Defines switches re which plots should be generated +#---------------------------------------------------------------------- +lplot1=True +lplot2=False + +#---------------------------------------------------------------------- +# Defines plotting functions +#---------------------------------------------------------------------- + +# Plot 1: +# zonal-mean time-mean CRH for all available models of a given simulation in a 4-column panel plot +# and with tropopause and T=0 and T=-38deg C as lines +def plot_cl_xypanelplot(exp, models): + + # contour levels and colorbar + cl_clev=np.arange(0.,0.7,0.05) + cmap=cmc.batlow + + nmod = len(models) # number of models + + ncol=4 + # number of panel rows as a function of number of models, we add one extra row to place colorbar there + nrow=int(np.floor(nmod/ncol)) + 1 + if np.mod(nmod,ncol) > 0: nrow+=1 + + def _plot_ta_tp(ta, tp, ax): + """ Plots temperature contours and tropopause, which are both on pressure levels.""" + plt.contour(ta.lat, ta.lev/100, ta, levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) + plt.plot(tp.lat, tp, color="white", linewidth=1) + return + + def _plot_cl_singledata(cl, ax): + """ Plots zonal-mean time-mean cloud cover. Works for both pressure-level and height-level data.""" + lat=cl.lat + if "lev" in cl.coords: # pressure levels (almost all models) + lev = cl.lev.values + elif "hgt" in cl.coords: # height levels (HadGEM and UKESM models) + cl, lev = hlp.height2pressure_zg(cl,mod,exp) + cnt=plt.contourf(lat, lev/100, 0.01*cl, cl_clev, cmap=cmap) + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " ", " ", " "], size=12); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=12, va="top"); + ax.tick_params(direction="in", length=6) + return + + # we use one extra row to place the colorbar there + fig=plt.figure(figsize=(6*4,nrow*4)) + + # loop over models + counter=0 + for mod in models: + counter+=1 + # air temperature and tropopause + ta = hlp.ta_Amon_ymonmean(mod, exp)["ta"].mean(["month", "lon"]).squeeze() + tp = hlp.tropo_Amon_zontimmean(mod, exp)["trop"].squeeze() + # cl + cl = hlp.load_cl_zontimmean(mod, exp) + if mod in ["CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2"]: + if cl is not None: cl = cl.where(cl.lev<500e2) + if ta is not None: ta = ta.where(ta.lev<500e2) + # leave this iteration and go to next model if there is no cloud cover data + if cl is None: continue + # also for CESM2, CESM2-WACCM + if mod in ["CESM2", "CESM2-WACCM"]: continue + ax=plt.subplot(nrow, ncol, counter) + _plot_cl_singledata(cl, ax) + _plot_ta_tp(ta, tp, ax) + if np.mod(counter, ncol) == 1: + plt.ylabel("pressure / hPa", loc="top", fontsize=15) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=12); + if counter>ncol*(nrow-2): + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + # for amip, need to add y-xis label for CNRM-CM6-1 by hand + if exp=="amip" and mod=="CNRM-CM6-1": + plt.ylabel("pressure / hPa", loc="top", fontsize=15) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=12); + # for rows that are not completely filled, we need to include + # xlabel in the panels of the row above + if counter+ncol>nmod: + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + ax.text(0.03,0.96, mod, ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=15, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position found manually, to do so use "print(ax)" for above subplots + if exp=="amip-p4K" or exp=="amip-future4K": + ax = fig.add_axes([0.714,0.381765,0.185, 0.04/nrow]) + if exp=="amip": + ax = fig.add_axes([0.714,0.20,0.185, 0.04/nrow]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap=cmap, extend="both", ticks=[0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6], + label="", + boundaries=cl_clev, norm=mpl.colors.Normalize(cl_clev[0], cl_clev[-1])) + cb.ax.set_xticklabels(["0", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6"]) + cb.ax.tick_params(labelsize=15) + cb.set_label(label="", size=15) + + hlp.spacing_subplots() + +# Plot 2: +# 5 panel plot for 5 domain averages ordered from South to North +def plot_cl_5domains(exp, models): + + nmod = len(models) # number of models + + def _make_niceaxes(ax, xlim, ticklength=0.08): + # adjust spines + ax.spines["top"].set_color("none") + ax.spines["right"].set_color("none") + ax.xaxis.set_ticks_position("bottom") + ax.spines["bottom"].set_position(("data",1000)) + ax.spines["left"].set_position(("data",-2)) + ax.spines["left"].set_color("none") + plt.ylim(1000,10) + plt.xlim(xlim[0], xlim[1]) + plt.yticks([ ], fontsize=10) + #for ypos in [1000,800,600,400,200,10]: + # plt.plot([-0.5*ticklength,0.5*ticklength], [ypos,ypos], linewidth=0.7, color="k", zorder=-10) + + def _plot_cl_singledata(_cl, mod): + """ Plots domain-mean time-mean CRH. Assumes pressure levels.""" + plt.plot(_cl, _cl.lev/100, color="gray", label=mod) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + return + + def _height2pressurelevels(_cl, mod, exp): + """ Interpolates from height to common pressure levels for HadGEM and UKESM models.""" + if mod in ["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"]: + _cl_int, lev = hlp.height2pressure_zg(_cl, mod, exp) + # _cl_int is a numpy array, need to transform to dataarray + _cl = xr.DataArray(_cl, name="cl", dims=("lev", "lat"), + coords={"lev": lev, "lat": _cl.lat}) + return _cl + + # 5 panel plot for 5 domain averages ordered from South to North + fig=plt.figure(figsize=(16,4)) + # we also collect the models' domain averages to plot the model median and std dev across models + shext = list() + shsub = list() + trops = list() + nhsub = list() + nhext = list() + for mod in models: + cl = hlp.load_cl_zontimmean(mod, exp) + if mod in ["CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2"]: + if cl is not None: cl = cl.where(cl.lev<500e2) + # leave this iteration and go to next model if there is no cloud cover data + if cl is None: continue + # also for CESM2, CESM2-WACCM + if mod in ["CESM2", "CESM2-WACCM"]: continue + cl = _height2pressurelevels(cl, mod, exp) + # 70S - 35S + ax=plt.subplot(1,5,1) + _plot_cl_singledata(hlp.compute_domainmean(cl, lats=-70, latn=-35), mod=mod) + # 35S - 15S + ax=plt.subplot(1,5,2) + _plot_cl_singledata(hlp.compute_domainmean(cl, lats=-35, latn=-15), mod=mod) + # 15S - 15N + ax=plt.subplot(1,5,3) + _plot_cl_singledata(hlp.compute_domainmean(cl, lats=-15, latn=+15), mod=mod) + # 15N - 35N + ax=plt.subplot(1,5,4) + _plot_cl_singledata(hlp.compute_domainmean(cl, lats=+15, latn=+35), mod=mod) + # 35N - 70N + ax=plt.subplot(1,5,5) + _plot_cl_singledata(hlp.compute_domainmean(cl, lats=+35, latn=+70), mod=mod) + # save domain averages + shext.append(hlp.compute_domainmean(cl, lats=-70, latn=-35).values) + shsub.append(hlp.compute_domainmean(cl, lats=-35, latn=-15).values) + trops.append(hlp.compute_domainmean(cl, lats=-15, latn=+15).values) + nhsub.append(hlp.compute_domainmean(cl, lats=+15, latn=+35).values) + nhext.append(hlp.compute_domainmean(cl, lats=+35, latn=+70).values) + + # include model median and std dev across models, make x-axis labels nice by hand + ax=plt.subplot(1,5,1); plt.plot(np.nanmedian(np.array(shext), axis=0), cl.lev/100, color="black", linewidth=2); + #plt.xlabel("model median", fontsize=10, fontweight="bold", color="black", loc="right") + plt.xticks(ticks=[0,10,20,30,40], labels=[0,10,20,30,40]) + ax=plt.subplot(1,5,2); plt.plot(np.nanmedian(np.array(shsub), axis=0), cl.lev/100, color="black", linewidth=2); + plt.xticks(ticks=[0,10,20], labels=[0,10,20]) + ax=plt.subplot(1,5,3); plt.plot(np.nanmedian(np.array(trops), axis=0), cl.lev/100, color="black", linewidth=2); + plt.xticks(ticks=[0,10,20,30], labels=[0,10,20,30]) + ax=plt.subplot(1,5,4); plt.plot(np.nanmedian(np.array(nhsub), axis=0), cl.lev/100, color="black", linewidth=2) + plt.xticks(ticks=[0,10,20], labels=[0,10,20]) + ax=plt.subplot(1,5,5); plt.plot(np.nanmedian(np.array(nhext), axis=0), cl.lev/100, color="black", linewidth=2) + plt.xticks(ticks=[0,10,20,30,40], labels=[0,10,20,30,40]) + + # make nice axes for subplots + ax=plt.subplot(1,5,1); _make_niceaxes(ax, xlim=[0,46]); plt.title("70S - 35S", fontweight="bold", fontsize=15) + plt.ylabel(r"pressure / hPa", size=12, loc="top") + plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) + ax=plt.subplot(1,5,2); _make_niceaxes(ax, xlim=[0,20]); plt.title("35S - 15S", fontweight="bold", fontsize=15) + ax=plt.subplot(1,5,3); _make_niceaxes(ax, xlim=[0,30]); plt.title("15S - 15N", fontweight="bold", fontsize=15); + ax=plt.subplot(1,5,4); _make_niceaxes(ax, xlim=[0,20]); plt.title("15N - 35N", fontweight="bold", fontsize=15) + ax=plt.subplot(1,5,5); _make_niceaxes(ax, xlim=[0,40]); plt.title("35N - 70N", fontweight="bold", fontsize=15) + plt.xlabel("cloud cover / %", size=12, loc="right") + + plt.subplots_adjust(left=0.1, bottom=0.15, right=0.9, top=0.9, + wspace=0.08, hspace=0.1) + +#---------------------------------------------------------------------- +# Generates plots by calling plotting functions. +#---------------------------------------------------------------------- + +# xypanel plots of zonal means +if lplot1: + # amip + plot_cl_xypanelplot(exp="amip", models=hlp.models_amip) + plt.savefig("./figures/cl_zonaltimemean_xypanelplot_amip.pdf") + # amip plus 4K SST + plot_cl_xypanelplot(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/cl_zonaltimemean_xypanelplot_amipp4K.pdf") + # amip with 4K-future SST increase + plot_cl_xypanelplot(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/cl_zonaltimemean_xypanelplot_amipfuture4K.pdf") + +# domain averages +if lplot2: + # amip + plot_cl_5domains(exp="amip", models=hlp.models_amip) + plt.savefig("figures/cl_5xdomaintimemean_amip.pdf") + # amip-p4K + plot_cl_5domains(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("figures/cl_5xdomaintimemean_amip-p4K.pdf") + # amip with 4K-future SST increase + plot_cl_5domains(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("figures/cl_5xdomaintimemean_amip-future4K.pdf") \ No newline at end of file diff --git a/plots4paper/make_plots_crh.py b/plots4paper/make_plots_crh.py new file mode 100644 index 0000000000000000000000000000000000000000..fce8551314913e30c052fd8ae92b537d92fd0918 --- /dev/null +++ b/plots4paper/make_plots_crh.py @@ -0,0 +1,375 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plots of CRH for all available models and the amip, amip-p4K and amip-future4K simulations +# Generates the following types of multi-panel plots of CRH: +# * Plot 1: one panel per model, using only one CRH approach per model; +# * Plot 2: one row per model and three columns: i) CRH from radiative fluxes provided by the CFmon table, ii) CRH from tntr provided by the CFmon, AERmon and Emon tables, and iii) CRH from tntr provided by the EmonZ table. +# * Plot 3: vertical profiles of CRH averaged over 5 domains + +# on master hub of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plots_crh.py + +import os +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp + +#---------------------------------------------------------------------- +# Defines switches re which plots should be generated +#---------------------------------------------------------------------- +lplot1=True +lplot2=False +lplot3=False + +#---------------------------------------------------------------------- +# Defines plotting functions +#---------------------------------------------------------------------- + +# Plot 1: +# zonal-mean time-mean CRH for all available models of a given simulation in a 4-column panel plot +# and with tropopause and T=0 and T=-38deg C as lines +def plot_crh_xypanelplot(exp, models): + + crh_clev=np.delete(1.0*np.linspace(-1,1,21),10) # contour levels for CRH, remove 0 + nmod = len(models) # number of models + + ncol=4 + # number of panel rows as a function of number of models, we add one extra row to place colorbar there + nrow=int(np.floor(nmod/ncol)) + 1 + if np.mod(nmod,ncol) > 0: nrow+=1 + + def _plot_crh_singledata(crh, ax): + """ Plots zonal-mean time-mean CRH. Works for both pressure-level and height-level data.""" + lat=crh.lat + if "lev" in crh.coords: # pressure levels (almost all models) + lev = crh.lev.values + elif "hgt" in crh.coords: # height levels (HadGEM and UKESM models) + crh, lev = hlp.height2pressure_zg(crh,mod,exp) + cnt=plt.contourf(lat, lev/100, crh, crh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " ", " ", " "], size=12); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=12, va="top"); + ax.tick_params(direction="in", length=6) + return + + def _plot_ta_tp(ta, tp, ax): + """ Plots temperature contours and tropopause, which are both on pressure levels.""" + cnt=plt.contour(ta.lat, ta.lev/100, ta, levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=1) + plt.plot(tp.lat, tp, color="seagreen", linewidth=1) + return + + # we use one extra row to place the colorbar there + fig=plt.figure(figsize=(6*4,nrow*4)) + #fig, axs = plt.subplots(ncol, nrow, layout="constrained", figsize=(6*ncol,4*nrow)) + + # loop over models, use crh in following order: 1) from CFmon flux, 2) from tntr of CFmon, AERmon, Emon, 3) from tntr of EmonZ + counter=0 + for mod in models: + counter+=1 + # air temperature and tropopause + ta = hlp.ta_Amon_ymonmean(mod, exp)["ta"].mean(["month", "lon"]).squeeze() + tp = hlp.tropo_Amon_zontimmean(mod, exp)["trop"].squeeze() + # crh + crh = hlp.load_crh_zontimmean(mod, exp) + # plot + ax=plt.subplot(nrow, ncol, counter) + _plot_crh_singledata(crh, ax) + _plot_ta_tp(ta, tp, ax) + if np.mod(counter, ncol) == 1: + plt.ylabel("pressure / hPa", loc="top", fontsize=15) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=12); + if counter>ncol*(nrow-2): + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + # for rows that are not completely filled, we need to include + # xlabel in the panels of the row above + if counter+ncol>nmod: + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + ax.text(0.03,0.96, mod, ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=15, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position found manually, to do so use "print(ax)" for above subplots + if exp=="amip-p4K" or exp=="amip-future4K": + ax = fig.add_axes([0.714,0.381765,0.185, 0.04/nrow]) + if exp=="amip": + ax = fig.add_axes([0.714,0.20,0.185, 0.04/nrow]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-1, -0.7, -0.4, 0.0, 0.4, 0.7, 1.0], + label="K/day", + boundaries=crh_clev, norm=mpl.colors.Normalize(crh_clev[0], crh_clev[-1])) + cb.ax.set_xticklabels(["-1.0", "-0.7", "-0.4", "0", "0.4", "0.7", "1.0"]) + cb.ax.tick_params(labelsize=15) + cb.set_label(label="K/day", size=15) + + hlp.spacing_subplots() + + +# Plot 2: +# zonal-mean time-mean CRH for all available models and all available approaches as a 3-column panel plot +# with one row per model +def plot_crh_3approaches(exp, models): + + crh_clev=np.delete(1.0*np.linspace(-1,1,21),10) # contour levels for CRH, remove 0 + nmod = len(models) # number of models + + def _plot_crh_singledata(crh, ax): + """ Plots zonal-mean time-mean CRH. Works for both pressure-level and height-level data.""" + # pressure levels (almost all models) + if "lev" in crh.coords: + cnt=plt.contourf(crh.lat, crh.lev/100, crh, crh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " "," "," "], size=6); + # height levels (HadGEM and UKESM models) + elif "hgt" in crh.coords: + cnt=plt.contourf(crh.lat, crh.hgt/1000, crh, crh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(0,20) + plt.yticks([4,8,12,16],[" ", " ", " ", " "], size=6); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=6, va="top"); + ax.tick_params(direction="in", length=6) + return + + fig=plt.figure(figsize=(10,nmod*1.5)) + + # three top subplots for title of columns + + ax=plt.subplot(nmod+1, 3, 1); ax.set_axis_off() + plt.text(0.5, 0.2, "From fluxes", fontsize=10, fontweight="bold", ha="center" , va="center", transform=ax.transAxes) + + ax=plt.subplot(nmod+1, 3, 2); ax.set_axis_off() + plt.text(0.5, 0.2, "From tntr of CFmon, AERmon, Emon", fontsize=10, fontweight="bold", ha="center" , va="center", transform=ax.transAxes) + + ax=plt.subplot(nmod+1, 3, 3); ax.set_axis_off() + plt.text(0.5, 0.2, "From tntr of EmonZ", fontsize=10, fontweight="bold", ha="center" , va="center", transform=ax.transAxes) + + counter=4 # counter for subplots + plot_modname=False # True if model name was already added + for mod in models: + # from fluxes + crh = hlp.crh_from_flx_ymonmean(mod, exp) + if crh is not None: + ax=plt.subplot(nmod+1, 3, counter); _plot_crh_singledata(crh.mean(["month", "lon"]), ax) + plt.text(-0.2, 0.5, mod, fontsize=8, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + # pressure levels (almost all models) + if "lev" in crh.coords: + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + plt.ylabel("pressure / hPa", loc="top", fontsize=6) + # height levels (HadGEM and UKESM models) + elif "hgt" in crh.coords: + plt.yticks([4,8,12,16],["4", "8", "12", "16"], size=6); + plt.ylabel("altitude / km", loc="top", fontsize=6) + plot_modname=True + # from tntr via CFmon, AERmon, Emon + crh = hlp.crh_from_tntr_ymonmean(mod, exp) + if crh is not None: + ax=plt.subplot(nmod+1, 3, counter+1); _plot_crh_singledata(crh.mean(["month", "lon"]), ax) + if plot_modname==False: + plt.text(-1.281, 0.5, mod, fontsize=8, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + # pressure levels (almost all models) + if "lev" in crh.coords: + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + plt.ylabel("pressure / hPa", loc="top", fontsize=6) + # height levels (HadGEM and UKESM models) + elif "hgt" in crh.coords: + plt.yticks([4,8,12,16],["4", "8", "12", "16"], size=6); + plt.ylabel("altitude / km", loc="top", fontsize=6) + plot_modname=True + # from tntr via EmonZ + crh = hlp.crh_from_tntr_EmonZ_ymonmean(mod, exp) + if crh is not None: + ax=plt.subplot(nmod+1, 3, counter+2); _plot_crh_singledata(crh.mean(["month"]), ax) + if plot_modname==False: + plt.text(-2.359, 0.5, mod, fontsize=8, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + # pressure levels (almost all models) + if "lev" in crh.coords: + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + plt.ylabel("pressure / hPa", loc="top", fontsize=6) + # height levels (HadGEM and UKESM models) + elif "hgt" in crh.coords: + plt.yticks([4,8,12,16],["4", "8", "12", "16"], size=6); + plt.ylabel("altitude / km", loc="top", fontsize=6) + # move on to next model --> increase subplot counter by 3 + counter=counter+3 + plot_modname=False + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position defined manually as a function of experiment + if exp=="amip-p4K" or exp=="amip-future4K": + ax = fig.add_axes([0.3, 0.05, 0.4, 0.06/nmod]) + if exp=="amip": + ax = fig.add_axes([0.3, 0.08, 0.4, 0.06/nmod]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-1, -0.7, -0.4, 0.0, 0.4, 0.7, 1.0], + label="K/day", + boundaries=crh_clev, norm=mpl.colors.Normalize(crh_clev[0], crh_clev[-1])) + cb.ax.set_xticklabels(["-1.0", "-0.7", "-0.4", "0", "0.4", "0.7", "1.0"]) + cb.ax.tick_params(labelsize=8) + cb.set_label(label="K/day", size=8) + + hlp.spacing_subplots_v2() + + +# Plot 3: +# 5 panel plot for 5 domain averages ordered from South to North +def plot_crh_5domains(exp, models): + + nmod = len(models) # number of models + + def _make_niceaxes(ax, ticklength=0.08): + # adjust spines + ax.spines["top"].set_color("none") + ax.spines["right"].set_color("none") + ax.xaxis.set_ticks_position("bottom") + ax.spines["bottom"].set_position(("data",1000)) + ax.spines["left"].set_position(("data",-1.5)) + ax.spines["left"].set_color("none") + plt.ylim(1000,10) + plt.yticks([ ], fontsize=10) + plt.plot([0,0], [1000,10], linewidth=0.7, color="k", zorder=-10) + for ypos in [1000,800,600,400,200,10]: + plt.plot([-0.5*ticklength,0.5*ticklength], [ypos,ypos], linewidth=0.7, color="k", zorder=-10) + + def _plot_crh_singledata(_crh, mod): + """ Plots domain-mean time-mean CRH. Assumes pressure levels.""" + plt.plot(_crh, _crh.lev/100, color="gray", label=mod) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + return + + def _height2pressurelevels(_crh, mod, exp): + """ Interpolates from height to common pressure levels for HadGEM and UKESM models.""" + if mod in ["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"]: + _crh_int, lev = hlp.height2pressure_zg(_crh, mod, exp) + # _crh_int is a numpy array, need to transform to dataarray + _crh = xr.DataArray(_crh_int, name="crh", dims=("lev", "lat"), + coords={"lev": lev, "lat": _crh.lat}) + return _crh + + def _plot_obs(lats, latn): + """ Plots domain-mean time-mean CRH from observations.""" + _obs = hlp.acre_obs_2bflxhrlidar_r05() + _obs2 = hlp.acre_obs_cccm() + plt.plot(hlp.compute_domainmean(_obs, lats=lats, latn=latn), _obs.lev/100, color="royalblue", linewidth=2) + plt.plot(hlp.compute_domainmean(_obs2, lats=lats, latn=latn), _obs2.lev/100, color="royalblue", linestyle="--", linewidth=2) + return + + # 5 panel plot for 5 domain averages ordered from South to North + fig=plt.figure(figsize=(16,4)) + # we also collect the models' domain averages to plot the model median and std dev across models + shext = list() + shsub = list() + trops = list() + nhsub = list() + nhext = list() + for mod in models: + crh = hlp.load_crh_zontimmean(mod, exp) + crh = _height2pressurelevels(crh, mod, exp) + # 70S - 35S + ax=plt.subplot(1,5,1) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=-70, latn=-35), mod=mod) + # 35S - 15S + ax=plt.subplot(1,5,2) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=-35, latn=-15), mod=mod) + # 15S - 15N + ax=plt.subplot(1,5,3) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=-15, latn=+15), mod=mod) + # 15N - 35N + ax=plt.subplot(1,5,4) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=+15, latn=+35), mod=mod) + # 35N - 70N + ax=plt.subplot(1,5,5) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=+35, latn=+70), mod=mod) + # save domain averages + shext.append(hlp.compute_domainmean(crh, lats=-70, latn=-35).values) + shsub.append(hlp.compute_domainmean(crh, lats=-35, latn=-15).values) + trops.append(hlp.compute_domainmean(crh, lats=-15, latn=+15).values) + nhsub.append(hlp.compute_domainmean(crh, lats=+15, latn=+35).values) + nhext.append(hlp.compute_domainmean(crh, lats=+35, latn=+70).values) + + # include model median and std dev across models for amip simulations + # make x-axis labels nice by hand for amip (but not the other simulations) + if exp=="amip": + ax=plt.subplot(1,5,1); plt.plot(np.nanmedian(np.array(shext), axis=0), crh.lev/100, color="black", linewidth=2); + plt.xlabel("model median", fontsize=10, fontweight="bold", color="black", loc="right") + plt.xticks(ticks=[-1,-0.5,0,0.5], labels=["-1.0","-0.5","0","0.5"]) + ax=plt.subplot(1,5,2); plt.plot(np.nanmedian(np.array(shsub), axis=0), crh.lev/100, color="black", linewidth=2); + plt.xlabel("solid: 2B-FLXHR-LIDAR", fontsize=10, fontweight="bold", color="royalblue", loc="center") + plt.xticks(ticks=[-1,-0.5,0,0.5], labels=["-1.0","-0.5","0","0.5"]) + ax=plt.subplot(1,5,3); plt.plot(np.nanmedian(np.array(trops), axis=0), crh.lev/100, color="black", linewidth=2); + plt.xlabel("dashed: CCCM", fontsize=10, fontweight="bold", color="royalblue", loc="left") + plt.xticks(ticks=[-0.5,0,0.5], labels=["-0.5","0","0.5"]) + ax=plt.subplot(1,5,4); plt.plot(np.nanmedian(np.array(nhsub), axis=0), crh.lev/100, color="black", linewidth=2) + plt.xticks(ticks=[-0.5,0,0.5], labels=["-0.5","0","0.5"]) + ax=plt.subplot(1,5,5); plt.plot(np.nanmedian(np.array(nhext), axis=0), crh.lev/100, color="black", linewidth=2) + plt.xticks(ticks=[-0.5,-0.25,0,0.25,0.5], labels=["-0.5","-0.25","0","0.25","0.5"]) + + # include observations for amip simulations + if exp=="amip": + ax=plt.subplot(1,5,1); _plot_obs(lats=-70, latn=-35) + ax=plt.subplot(1,5,2); _plot_obs(lats=-35, latn=-15) + ax=plt.subplot(1,5,3); _plot_obs(lats=-15, latn=+15) + ax=plt.subplot(1,5,4); _plot_obs(lats=+15, latn=+35) + ax=plt.subplot(1,5,5); _plot_obs(lats=+35, latn=+70) + + # make nice axes for subplots + ax=plt.subplot(1,5,1); _make_niceaxes(ax); plt.title("70S - 35S", fontweight="bold", fontsize=15) + plt.ylabel(r"pressure / hPa", size=12, loc="top") + plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) + ax=plt.subplot(1,5,2); _make_niceaxes(ax); plt.title("35S - 15S", fontweight="bold", fontsize=15) + ax=plt.subplot(1,5,3); _make_niceaxes(ax); plt.title("15S - 15N", fontweight="bold", fontsize=15); + ax=plt.subplot(1,5,4); _make_niceaxes(ax); plt.title("15N - 35N", fontweight="bold", fontsize=15) + ax=plt.subplot(1,5,5); _make_niceaxes(ax); plt.title("35N - 70N", fontweight="bold", fontsize=15) + plt.xlabel(r"cloud-radiative heating / K$\,$day$^{-1}$", size=12, loc="right") + + plt.subplots_adjust(left=0.1, bottom=0.15, right=0.9, top=0.9, + wspace=0.08, hspace=0.1) + +#---------------------------------------------------------------------- +# Generates plots by calling plotting functions. +#---------------------------------------------------------------------- + +# xypanel plots of zonal means +if lplot1: + # amip + plot_crh_xypanelplot(exp="amip", models=hlp.models_amip) + plt.savefig("./figures/crh_zonaltimemean_xypanelplot_amip.pdf") + # amip plus 4K SST + plot_crh_xypanelplot(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/crh_zonaltimemean_xypanelplot_amipp4K.pdf") + # amip with 4K-future SST increase + plot_crh_xypanelplot(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/crh_zonaltimemean_xypanelplot_amipfuture4K.pdf") + +# 3 approaches +if lplot2: + # amip + plot_crh_3approaches(exp="amip", models=hlp.models_amip) + plt.savefig("./figures/crh_zonaltimemean_3approaches_amip.pdf") + # amip plus 4K SST + plot_crh_3approaches(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/crh_zonaltimemean_3approaches_amip-p4K.pdf") + # amip with 4K-future SST increase + plot_crh_3approaches(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/crh_zonaltimemean_3approaches_amip-future4K.pdf") + +# domain averages +if lplot3: + # amip + plot_crh_5domains(exp="amip", models=hlp.models_amip) + plt.savefig("figures/crh_5xdomaintimemean_amip.pdf") + # amip-p4K + plot_crh_5domains(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("figures/crh_5xdomaintimemean_amip-p4K.pdf") + # amip with 4K-future SST increase + plot_crh_5domains(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("figures/crh_5xdomaintimemean_amip-future4K.pdf") \ No newline at end of file diff --git a/plots4paper/make_plots_crh_Tlev.py b/plots4paper/make_plots_crh_Tlev.py new file mode 100644 index 0000000000000000000000000000000000000000..cc9252a405598a2d3b720520b19281eb95683c3b --- /dev/null +++ b/plots4paper/make_plots_crh_Tlev.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plots of CRH sampled with T as vertical coordinate for all available models and the amip, amip-p4K and amip-future4K simulations +# Generates the following types of multi-panel plots of CRH: +# * Plot 1: one panel per model, using only one CRH approach per model; +# * Plot 2: vertical profiles of CRH averaged over 5 domains + +# on srvx1 of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plots_crh_Tlev.py + +import os +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp + +#---------------------------------------------------------------------- +# Defines switches re which plots should be generated +#---------------------------------------------------------------------- +lplot1=True +lplot2=True + +#---------------------------------------------------------------------- +# Defines plotting functions +#---------------------------------------------------------------------- + +# Plot 1: +# zonal-mean time-mean CRH for all available models of a given simulation in a 4-column panel plot +def plot_crh_Tlev_xypanelplot(exp, models): + + # temperature levels + Tint=np.linspace(100,320,221) + + crh_clev=np.delete(1.0*np.linspace(-1,1,21),10) # contour levels for CRH, remove 0 + nmod = len(models) # number of models + + ncol=4 + # number of panel rows as a function of number of models, we add one extra row to place colorbar there + nrow=int(np.floor(nmod/ncol)) + 1 + if np.mod(nmod,ncol) > 0: nrow+=1 + + def _plot_crh_singledata(crh, ax): + """ Plots zonal-mean time-mean CRH for T as vertical coordinate.""" + cnt=plt.contourf(crh.lat, crh.Tint, crh, crh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(300,180) + plt.yticks([300,270,240,210,180],[" ", " ", " ", " ", " "], size=12); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=12, va="top"); + ax.tick_params(direction="in", length=6) + return + + # we use one extra row to place the colorbar there + fig=plt.figure(figsize=(4*6,nrow*4)) + + # loop over models, use crh in following order: 1) from CFmon flux, 2) from tntr of CFmon, AERmon, Emon, 3) from tntr of EmonZ + counter=0 + for mod in models: + counter+=1 + crh = hlp.crh_zonaltimemean_Tlevels(mod, exp=exp, Tint=Tint) + ax=plt.subplot(nrow, ncol, counter) + _plot_crh_singledata(crh, ax) + if np.mod(counter, ncol) == 1: + plt.ylabel("temperature / K", loc="top", fontsize=15) + plt.yticks([300,270,240,210,180],["300","270","240","210","180"], size=12); + if counter>ncol*(nrow-2): + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + # for rows that are not completely filled, we need to include + # xlabel in the panels of the row above + if counter+ncol>nmod: + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + ax.text(0.03,0.96, mod, ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=15, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position found manually, to do so use "print(ax)" for above subplots + if exp=="amip-p4K" or exp=="amip-future4K": + ax = fig.add_axes([0.714,0.381765,0.185, 0.04/nrow]) + if exp=="amip": + ax = fig.add_axes([0.714,0.20,0.185, 0.04/nrow]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-1, -0.7, -0.4, 0.0, 0.4, 0.7, 1.0], + label="K/day", + boundaries=crh_clev, norm=mpl.colors.Normalize(crh_clev[0], crh_clev[-1])) + cb.ax.tick_params(labelsize=15) + cb.set_label(label="K/day", size=15) + + hlp.spacing_subplots() + + +# Plot 2: +# 5 panel plot for 5 domain averages ordered from South to North +def plot_crh_Tlev_5domains(exp, models): + + # temperature levels + Tint=np.linspace(100,320,221) + + nmod = len(models) # number of models + + def _make_niceaxes(ax, ticklength=0.08): + # adjust spines + ax.spines["top"].set_color("none") + ax.spines["right"].set_color("none") + ax.xaxis.set_ticks_position("bottom") + ax.spines["bottom"].set_position(("data",300)) + ax.spines["left"].set_position(("data",-0.6)) + ax.spines["left"].set_color("none") + plt.ylim(300,180) + plt.yticks([ ], fontsize=10) + plt.plot([0,0], [300,180], linewidth=0.7, color="k", zorder=-10) + for ypos in [300,270,240,210,180]: + plt.plot([-0.5*ticklength,0.5*ticklength], [ypos,ypos], linewidth=0.7, color="k", zorder=-10) + + def _plot_crh_singledata(_crh, mod): + plt.plot(_crh, _crh.Tint, color="gray", label=mod) + return + + # 5 panel plot for 5 domain averages ordered from South to North + fig=plt.figure(figsize=(16,4)) + for mod in models: + crh = hlp.crh_zonaltimemean_Tlevels(mod, exp=exp, Tint=Tint) + # 70S - 35S + ax=plt.subplot(1,5,1) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=-70, latn=-35), mod=mod) + # 35S - 15S + ax=plt.subplot(1,5,2) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=-35, latn=-15), mod=mod) + # 15S - 15N + ax=plt.subplot(1,5,3) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=-15, latn=+15), mod=mod) + # 15N - 35N + ax=plt.subplot(1,5,4) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=+15, latn=+35), mod=mod) + # 35N - 70N + ax=plt.subplot(1,5,5) + _plot_crh_singledata(hlp.compute_domainmean(crh, lats=+35, latn=+70), mod=mod) + + # make nice axes for subplots + ax=plt.subplot(1,5,1); _make_niceaxes(ax); plt.title("70S - 35S", fontsize=15, fontweight="bold") + plt.ylabel(r"temperature / K", size=12, loc="top") + plt.yticks([300,270,240,210,180], ["300","270","240","210","180"], fontsize=10) + ax=plt.subplot(1,5,2); _make_niceaxes(ax); plt.title("35S - 15S", fontsize=15, fontweight="bold") + ax=plt.subplot(1,5,3); _make_niceaxes(ax); plt.title("15S - 15N", fontsize=15, fontweight="bold"); + ax=plt.subplot(1,5,4); _make_niceaxes(ax); plt.title("15N - 35N", fontsize=15, fontweight="bold") + ax=plt.subplot(1,5,5); _make_niceaxes(ax); plt.title("35N - 70N", fontsize=15, fontweight="bold") + plt.xlabel(r"cloud-radiative heating / K$\,$day$^{-1}$", size=12, loc="right") + + plt.subplots_adjust(left=0.1, bottom=0.15, right=0.9, top=0.9, + wspace=0.08, hspace=0.1) + +#---------------------------------------------------------------------- +# Generates plots by calling plotting functions. +#---------------------------------------------------------------------- + +# xypanel plots of zonal means +if lplot1: + # amip + plot_crh_Tlev_xypanelplot(exp="amip", models=hlp.models_amip) + plt.savefig("./figures/crh_Tlev_zonaltimemean_xypanelplot_amip.pdf") + # amip plus 4K SST + plot_crh_Tlev_xypanelplot(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/crh_Tlev_zonaltimemean_xypanelplot_amipp4K.pdf") + # amip with 4K-future SST increase + plot_crh_Tlev_xypanelplot(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/crh_Tlev_zonaltimemean_xypanelplot_amipfuture4K.pdf") + +# domain averages +if lplot2: + # amip + plot_crh_Tlev_5domains(exp="amip", models=hlp.models_amip) + plt.savefig("figures/crh_Tlev_5xdomaintimemean_amip.pdf") + # amip-p4K + plot_crh_Tlev_5domains(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("figures/crh_Tlev_5xdomaintimemean_amip-p4K.pdf") + # amip with 4K-future SST increase + plot_crh_Tlev_5domains(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("figures/crh_Tlev_5xdomaintimemean_amip-future4K.pdf") \ No newline at end of file diff --git a/plots4paper/make_plots_crh_amipfuture4K-vs-amipp4K.py b/plots4paper/make_plots_crh_amipfuture4K-vs-amipp4K.py new file mode 100644 index 0000000000000000000000000000000000000000..87d8a375513760731b948c509b5203a120e15860 --- /dev/null +++ b/plots4paper/make_plots_crh_amipfuture4K-vs-amipp4K.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plots of CRH in amip-future4K versus amip-p4K with pressure as vertical coordinate for all available models. Purpose is to study to what extent CRH depends on pattern of surface warming. To this end, we plot amip-future4K - amip-p4K. +# Generates the following types of multi-panel plots of CRH: +# * Plot 1: one panel per model, using only one CRH approach per model; +# * Plot 2: vertical profiles of CRH averaged over 5 domains + +# on masterhub of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plots_crh_amipfuture4K-vs-amipp4K.py + +import os +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp + +#---------------------------------------------------------------------- +# Defines switches re which plots should be generated +#---------------------------------------------------------------------- +lplot1=True +lplot2=False + +#---------------------------------------------------------------------- +# Defines plotting functions +#---------------------------------------------------------------------- + +# Plot 1: +# zonal-mean time-mean CRH difference of amip-future4K minus amip-p4K for all available models of a given simulation in a 4-column panel plot +# and with tropopause and T=0 and T=-38deg C as lines +def plot_dcrh_xypanelplot(models): + + crh_clev=np.delete(0.5*np.linspace(-1,1,21),10) # contour levels for CRH, remove 0 + cl_clev=np.array([-5,-4,-3,-2,-1,1,2,3,4,5]) # contour levels for cloud cover + nmod = len(models) # number of models + + ncol=4 + # number of panel rows as a function of number of models, we add one extra row to place colorbar there + nrow=int(np.floor(nmod/ncol)) + 1 + if np.mod(nmod,ncol) > 0: nrow+=1 + + def _plot_crh_singledata(crh, ax): + """ Plots zonal-mean time-mean CRH. Works for both pressure-level data.""" + lev = crh.lev.values + cnt=plt.contourf(crh.lat, lev/100, crh, crh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " ", " ", " "], size=12); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=12, va="top"); + ax.tick_params(direction="in", length=6) + return + + def _plot_ta_tp(ta, tp, ax, linestyle="-"): + """ Plots temperature contours and tropopause, which are both on pressure levels.""" + plt.contour(ta.lat, ta.lev/100, ta, levels=[273.15-38, 273.15], colors="darkgray", linestyles=linestyle, linewidths=1) + plt.plot(tp.lat, tp, color="seagreen", linestyle=linestyle, linewidth=1) + return + + def _convert_hgt2lev(_ds, mod, exp, varname): + """ Converts crh from common height levels to common pressure levels. + Needed for HadGEM3-GC31-LL.""" + _ds_int, lev = hlp.height2pressure_zg(_ds, mod=mod, exp=exp) + # _data_int is a numpy array, need to transform to dataarray + _ds_int = xr.DataArray(_ds_int, name=varname, dims=("lev", "lat"), + coords={"lev": lev, "lat": _ds.lat}) + return _ds_int + + def _plot_cl_singledata(cl, ax): + """ Plots zonal-mean time-mean cloud cover. Works for both pressure-level data.""" + lat=cl.lat + lev = cl.lev.values + plt.contour(lat, lev/100, cl, cl_clev, colors="dimgray", linewidths=1) + plt.ylim(1000,10) + plt.xlim(-88,88) + return + + # we use one extra row to place the colorbar there + fig=plt.figure(figsize=(4*6,nrow*4)) + + # loop over models, use crh in following order: 1) from CFmon flux, 2) from tntr of CFmon, AERmon, Emon, 3) from tntr of EmonZ + counter=0 + for mod in models: + counter+=1 + lplot=False # plot already done for the model? + # air temperature and tropopause + ta_ami = hlp.ta_Amon_ymonmean(mod, exp="amip")["ta"].mean(["month", "lon"]).squeeze() + tp_ami = hlp.tropo_Amon_zontimmean(mod, exp="amip")["trop"].squeeze() + # crh + crh_p4K = hlp.load_crh_zontimmean(mod, exp="amip-p4K") + crh_f4K = hlp.load_crh_zontimmean(mod, exp="amip-future4K") + # cl + cl_p4K = hlp.load_cl_zontimmean(mod, exp="amip-p4K") + cl_f4K = hlp.load_cl_zontimmean(mod, exp="amip-future4K") + if mod=="HadGEM3-GC31-LL": + crh_p4K = _convert_hgt2lev(crh_p4K, mod, exp="amip-p4K", varname="crh") + crh_f4K = _convert_hgt2lev(crh_f4K, mod, exp="amip-future4K", varname="crh") + cl_p4K = _convert_hgt2lev(cl_p4K, mod, exp="amip-p4K", varname="cl") + cl_f4K = _convert_hgt2lev(cl_f4K, mod, exp="amip-future4K", varname="cl") + dcrh = crh_f4K - crh_p4K + # make sure that GFDL-CM4 is only plotted above 500hPa; note that cl is not available for GFDL-CM4 + if mod in ["GFDL-CM4"]: + dcrh = dcrh.where(dcrh.lev<500e2) + cl_f4K = None + cl_p4K = None + dcl = None + ta_ami = ta_ami.where(ta_ami.lev<500e2) + # plot + ax=plt.subplot(nrow, ncol, counter) + _plot_crh_singledata(dcrh, ax) + if (cl_p4K is not None) and (cl_f4K is not None): + dcl = cl_f4K - cl_p4K + _plot_cl_singledata(dcl, ax) + _plot_ta_tp(ta_ami, tp_ami, ax) + if np.mod(counter, ncol) == 1: + plt.ylabel("pressure / hPa", loc="top", fontsize=15) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=12); + if counter>ncol*(nrow-2): + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + # for rows that are not completely filled, we need to include + # xlabel in the panels of the row above + if counter+ncol>nmod: + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + ax.text(0.03,0.96, mod, ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=15, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position found manually, to do so use "print(ax)" for above subplots + ax = fig.add_axes([0.714,0.381765,0.185, 0.04/nrow]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-0.5, -0.25, 0.0, 0.25, 0.5], + label="K/day", + boundaries=crh_clev, norm=mpl.colors.Normalize(crh_clev[0], crh_clev[-1])) + cb.ax.set_xticklabels(["-0.5", "-0.25", "0", "0.25", "0.5"]) + cb.ax.tick_params(labelsize=15) + cb.set_label(label="K/day", size=15) + + hlp.spacing_subplots() + + +# Plot 2: +# 5 panel plot for 5 domain averages ordered from South to North +def plot_dcrh_5domains(models, beta=1.2): + """ Makes multipanel plots of domain averaged CRH difference of amip-future4K - amip-p4K. + First row is for all models. Rows below for individual models. """ + + nmod = len(models) # number of models + + def _make_niceaxes(ax, xlim=[-1,1]): + # adjust spines + ax.spines["top"].set_color("none") + ax.spines["right"].set_color("none") + ax.spines["left"].set_color("none") + ax.xaxis.set_ticks_position("bottom") + ax.spines["bottom"].set_position(("data",1000)) + ax.spines["right"].set_position(("data",xlim[1]+0.03)) + ax.yaxis.tick_right() + ax.yaxis.set_label_position("right") + plt.xticks([-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,0.3,0.4,0.5], ["","","","","","","","","","",""]) + plt.xlim(xlim[0], xlim[1]) + plt.ylim(1000,10) + plt.yticks([ ], fontsize=10) + plt.plot([0,0], [1000,10], linewidth=0.7, color="k", zorder=-10) + ticklength=0.04*np.abs(xlim[1]-xlim[0]) + for ypos in [1000,800,600,400,200,10]: + plt.plot([-0.5*ticklength,0.5*ticklength], [ypos,ypos], linewidth=0.7, color="k", zorder=-10) + + def _plot_crh_singledata(_crh, mod): + """ Plots domain-mean time-mean CRH. Works for both pressure-level and height-level data.""" + plt.plot(_crh, _crh.lev/100, color="gray", label=mod) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + return + + def _convert_crh_hgt2lev(_crh, mod, exp): + """ Converts crh from common height levels to common pressure levels. + Needed for HadGEM3-GC31-LL.""" + _crh_int, lev = hlp.height2pressure_zg(_crh, mod=mod, exp="amip") + # _data_int is a numpy array, need to transform to dataarray + _crh_int = xr.DataArray(_crh_int, name="crh", dims=("lev", "lat"), + coords={"lev": lev, "lat": _crh.lat}) + return _crh_int + + fig=plt.figure(figsize=(16,4+4*nmod)) + + # first row: 5 panel plot for 5 domain averages ordered from South to North + for mod in models: + crh_p4K = hlp.load_crh_zontimmean(mod, exp="amip-p4K") + crh_f4K = hlp.load_crh_zontimmean(mod, exp="amip-future4K") + if mod=="HadGEM3-GC31-LL": + crh_p4K = _convert_crh_hgt2lev(crh_p4K, mod, exp="amip-p4K") + crh_f4K = _convert_crh_hgt2lev(crh_f4K, mod, exp="amip-future4K") + dcrh = crh_f4K - crh_p4K + # make sure that GFDL-CM4 is only plotted above 500hPa + if mod in ["GFDL-CM4"]: dcrh = dcrh.where(dcrh.lev<500e2) + # 70S - 35S + ax=plt.subplot(nmod+1,5,1) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-70, latn=-35), mod=mod) + # 35S - 15S + ax=plt.subplot(nmod+1,5,2) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-35, latn=-15), mod=mod) + # 15S - 15N + ax=plt.subplot(nmod+1,5,3) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-15, latn=+15), mod=mod) + # 15N - 35N + ax=plt.subplot(nmod+1,5,4) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+15, latn=+35), mod=mod) + # 35N - 70N + ax=plt.subplot(nmod+1,5,5) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+35, latn=+70), mod=mod) + + # now 1 row for each model for the 5 domain averages + for imod in range(nmod): + crh_p4K = hlp.load_crh_zontimmean(models[imod], exp="amip-p4K") + crh_f4K = hlp.load_crh_zontimmean(models[imod], exp="amip-future4K") + if models[imod]=="HadGEM3-GC31-LL": + crh_p4K = _convert_crh_hgt2lev(crh_p4K, models[imod], exp="amip-p4K") + crh_f4K = _convert_crh_hgt2lev(crh_f4K, models[imod], exp="amip-future4K") + dcrh = crh_f4K - crh_p4K + # make sure that GFDL-CM4 is only plotted above 500hPa + if models[imod] in ["GFDL-CM4"]: dcrh = dcrh.where(dcrh.lev<500e2) + # 70S - 35S + ax=plt.subplot(nmod+1,5,(imod+1)*5+1) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-70, latn=-35), mod=mod) + # 35S - 15S + ax=plt.subplot(nmod+1,5,(imod+1)*5+2) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-35, latn=-15), mod=mod) + # 15S - 15N + ax=plt.subplot(nmod+1,5,(imod+1)*5+3) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-15, latn=+15), mod=mod) + # 15N - 35N + ax=plt.subplot(nmod+1,5,(imod+1)*5+4) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+15, latn=+35), mod=mod) + # 35N - 70N + ax=plt.subplot(nmod+1,5,(imod+1)*5+5) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+35, latn=+70), mod=mod) + # make nice axes for subplots + # 75S-35S + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+1); _make_niceaxes(ax, xlim=[-0.25,0.25]) + # 35S-15S + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+2); _make_niceaxes(ax, xlim=[-0.25,0.25]) + # 15S-15N + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+3); _make_niceaxes(ax, xlim=[-0.5,0.5]) + # 15NS-35N + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+4); _make_niceaxes(ax, xlim=[-0.25,0.25]) + # 35N-75N + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+5); _make_niceaxes(ax, xlim=[-0.25,0.25]) + + # add model names and y-axis labels and ticks + ax=plt.subplot(nmod+1,5,1) + plt.text(-0.1, 0.5, "All models", fontsize=15, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + for imod in range(nmod): + ax=plt.subplot(nmod+1,5,5*imod+6) + plt.text(-0.1, 0.5, models[imod], fontsize=15, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + + # add y-axis labels and ticks on right hand side of plot + ax=plt.subplot(nmod+1,5,5) + plt.ylabel(r"pressure / hPa", size=15, loc="top") + plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) + for imod in range(nmod): + ax=plt.subplot(nmod+1,5,5*imod+10) + plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) + + # add domains as titles + ax=plt.subplot(nmod+1,5,1); plt.text(0.5, 1.1, "70S - 35S", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,2); plt.text(0.5, 1.1, "35S - 15S", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,3); plt.text(0.5, 1.1, "15S - 15N", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,4); plt.text(0.5, 1.1, "15N - 35N", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,5); plt.text(0.5, 1.1, "35N - 70N", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + + # add x-labels in last row + ax=plt.subplot(nmod+1,5,5*nmod+1) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+2) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+3) + plt.xticks([-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,0.3,0.4,0.5], ["","-0.4","","-0.2","","0","","0.2","","0.4",""], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+4) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+5) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + plt.xlabel(r"cloud-radiative heating / K$\,$day$^{-1}$", size=15, loc="right") + + hlp.spacing_subplots() + + +#---------------------------------------------------------------------- +# Generates plots by calling plotting functions. +#---------------------------------------------------------------------- + +# xypanel plots of zonal means +if lplot1: + plot_dcrh_xypanelplot(models=hlp.models_amipp4K) + plt.savefig("./figures/crh_zonaltimemean_xypanelplot_amipfuture4K-amipp4K.pdf") + +# domain averages +if lplot2: + plot_dcrh_5domains(models=hlp.models_amipp4K) + plt.savefig("figures/crh_5xdomaintimemean_amipfuture4K-amipp4K.pdf") \ No newline at end of file diff --git a/plots4paper/make_plots_crh_changewithwarming.py b/plots4paper/make_plots_crh_changewithwarming.py new file mode 100644 index 0000000000000000000000000000000000000000..eda1de56fac2ba5be2c2c747af7b58ae8a94f786 --- /dev/null +++ b/plots4paper/make_plots_crh_changewithwarming.py @@ -0,0 +1,368 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plots of CRH change with surface warming sampled with pressure as vertical coordinate for all available models. +# Change is calculated as amip-p4K - amip and amip-future4K - amip. +# Generates the following types of multi-panel plots of CRH: +# * Plot 1: one panel per model, using only one CRH approach per model; +# * Plot 2: vertical profiles of CRH averaged over 5 domains + +# on srvx1 of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plots_crh_changewithwarming.py + +import os +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp + +#---------------------------------------------------------------------- +# Defines switches re which plots should be generated +#---------------------------------------------------------------------- +lplot1=True +lplot2=False + +#---------------------------------------------------------------------- +# Defines plotting functions +#---------------------------------------------------------------------- + +# Plot 1: +# zonal-mean time-mean CRH change for all available models of a given simulation in a 4-column panel plot +# and with tropopause and T=0 and T=-38deg C as lines +def plot_dcrh_xypanelplot(exp, models): + + crh_clev=np.delete(1*np.linspace(-1,1,21),10) #np.array([-2.0,-1.5,-1.0,-0.8,-0.6,-0.4,-0.2,0.2,0.4,0.6,0.8,1.0,1.5,2.0]) + #crh_clev=np.array([-4.0,-3.5,-3.0,-2.5,-2.0,-1.5,-1.0,-0.5,-0.4,-0.3,-0.2,-0.1,0.1,0.2,0.3,0.4,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0]) + dcrh_clev=np.delete(0.5*np.linspace(-1,1,21),10) # contour levels for dCRH, remove 0 + nmod = len(models) # number of models + + ncol=4 + # number of panel rows as a function of number of models, we add one extra row to place colorbar there + nrow=int(np.floor(nmod/ncol)) + 1 + if np.mod(nmod,ncol) > 0: nrow+=1 + + def _plot_crh_singledata(crh, ax, clev, plottype="contourf", labove700hPa=False): + """ Plots zonal-mean time-mean CRH. Works for both pressure-level and height-level data.""" + lat=crh.lat + if "lev" in crh.coords: # pressure levels (almost all models) + lev = crh.lev.values + elif "hgt" in crh.coords: # height levels (HadGEM and UKESM models) + aux, lev = hlp.height2pressure_zg(crh,mod,exp) + crh = xr.DataArray(aux, name="crh", dims=("lev", "lat"), + coords={"lev": lev, "lat": lat}) + if labove700hPa: + # only plot crh from amip above 600 hPa + crh = crh.where(crh.lev<700e2) + if plottype=="contourf": + cnt=plt.contourf(lat, lev/100, crh, clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + if plottype=="contour": + plt.contour(lat, lev/100, crh, clev, colors="dimgray", linewidths=0.5) + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " ", " ", " "], size=12); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=12, va="top"); + ax.tick_params(direction="in", length=6) + return + + def _plot_ta_tp(ta, tp, ax, linestyle="-"): + """ Plots temperature contours and tropopause, which are both on pressure levels.""" + plt.contour(ta.lat, ta.lev/100, ta, levels=[273.15-38, 273.15], colors="darkgray", linestyles=linestyle, linewidths=0.5) + plt.plot(tp.lat, tp, color="seagreen", linestyle=linestyle, linewidth=0.5) + return + + # we use one extra row to place the colorbar there + fig=plt.figure(figsize=(6*4,nrow*4)) + + # loop over models, use crh in following order: 1) from CFmon flux, 2) from tntr of CFmon, AERmon, Emon, 3) from tntr of EmonZ + counter=0 + for mod in models: + counter+=1 + lplot=False # plot already done for the model? + # air temperature and tropopause + ta_ami = hlp.ta_Amon_ymonmean(mod, exp="amip")["ta"].mean(["month", "lon"]).squeeze() + tp_ami = hlp.tropo_Amon_zontimmean(mod, exp="amip")["trop"].squeeze() + # crh + crh_exp = hlp.load_crh_zontimmean(mod, exp) + crh_ami = hlp.load_crh_zontimmean(mod, exp="amip") + dcrh = crh_exp - crh_ami + # plot + ax=plt.subplot(nrow, ncol, counter) + _plot_crh_singledata(dcrh, ax, clev=dcrh_clev, plottype="contourf") + #_plot_crh_singledata(crh_ami, ax, clev=crh_clev, plottype="contour",labove700hPa=True) + _plot_ta_tp(ta_ami, tp_ami, ax, linestyle="-") + if np.mod(counter, ncol) == 1: + plt.ylabel("pressure / hPa", loc="top", fontsize=15) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=12); + if counter>ncol*(nrow-2): + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + # for rows that are not completely filled, we need to include + # xlabel in the panels of the row above + if counter+ncol>nmod: + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + ax.text(0.03,0.96, mod, ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=15, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position found manually, to do so use "print(ax)" for above subplots + if exp=="amip-p4K" or exp=="amip-future4K": + ax = fig.add_axes([0.714,0.381765,0.185, 0.04/nrow]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-0.5, -0.25, 0, 0.25, 0.5], + label="K/day", + boundaries=dcrh_clev, norm=mpl.colors.Normalize(dcrh_clev[0], dcrh_clev[-1])) + cb.ax.set_xticklabels(["-0.5", "-0.25", "0", "0.25", "0.5"]) + cb.ax.tick_params(labelsize=15) + cb.set_label(label="K/day", size=15) + + hlp.spacing_subplots() + + +# Plot 2: +# 5 panel plot for 5 domain averages ordered from South to North +def plot_dcrh_5domains(exp, models, beta=1.2): + """ Makes multipanel plots of domain averaged CRH change in exp minus amip. Includes + prediction by upward shifted amip CRH, where beta defines the magnitude of the + upward shift. + + First row is for all models. Rows below for individual models. """ + + nmod = len(models) # number of models + + def _make_niceaxes(ax, xlim=[-1,1]): + # adjust spines + ax.spines["top"].set_color("none") + ax.spines["right"].set_color("none") + ax.spines["left"].set_color("none") + ax.xaxis.set_ticks_position("bottom") + ax.spines["bottom"].set_position(("data",1000)) + ax.spines["right"].set_position(("data",xlim[1]+0.03)) + ax.yaxis.tick_right() + ax.yaxis.set_label_position("right") + plt.xticks([-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,0.3,0.4,0.5], ["","","","","","","","","","",""]) + plt.xlim(xlim[0], xlim[1]) + plt.ylim(1000,10) + plt.yticks([ ], fontsize=10) + plt.plot([0,0], [1000,10], linewidth=0.7, color="k", zorder=-10) + ticklength=0.04*np.abs(xlim[1]-xlim[0]) + for ypos in [1000,800,600,400,200,10]: + plt.plot([-0.5*ticklength,0.5*ticklength], [ypos,ypos], linewidth=0.7, color="k", zorder=-10) + + def _plot_crh_singledata(_crh): + """ Plots domain-mean time-mean CRH. Works for both pressure-level and height-level data.""" + plt.plot(_crh, _crh.lev/100, color="gray", label=mod) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + return + + def _dcrh_upwardshift(_crh, _beta): + """ Predicts CRH change based on upward shift of reference crh. + Returns xarray datarray. + """ + _lev = _crh.lev + # do we need to reverse vertical axis so that pressure is increasing? + lreverse=False + if _lev[0]>_lev[1]: + lreverse=True + _lev = _lev[::-1] + _crh = _crh[::-1] + # interpolate shifted crh from levels lev/beta to input levels lev + _crh_shift = np.interp(_lev, _lev/_beta, _crh) + # reverse pressure back if reversed previously + if lreverse: + _crh = _crh[::-1] + _crh_shift = _crh_shift[::-1] + return _crh_shift - _crh + + def _plot_crh_upwardshift(_crh, beta): + """ Shift reference CRH upward from pressue lev to pressure lev/beta and plot.""" + _dcrh = _dcrh_upwardshift(_crh, beta) + # restrict plot to levels above 600 hPa + _dcrh = _dcrh.sel(lev=slice(600e2, 0)) + plt.plot(_dcrh, _dcrh.lev/100, color="royalblue") + return + + def _compute_correlation_upwardshift(_dcrh, _crh, beta): + """ Computes Pearson correlation between actual CRH change and prediction by + upward shift of reference crh according to beta.""" + # prediction by upward shift + _dcrh_shift = _dcrh_upwardshift(_crh, beta) + # restrict to levels between 500 and 100 600 hPa + _dcrh = _dcrh.sel(lev=slice(500e2, 100e2)) + _dcrh_shift = _dcrh_shift.sel(lev=slice(500e2, 100e2)) + # return correlation coefficient + return np.around(np.corrcoef(_dcrh, _dcrh_shift)[0,1], decimals=2) + + def _convert_crh_hgt2lev(_crh, mod, exp): + """ Converts crh from common height levels to common pressure levels. + Needed for HadGEM3-GC31-LL.""" + _crh_int, lev = hlp.height2pressure_zg(_crh, mod=mod, exp="amip") + # _data_int is a numpy array, need to transform to dataarray + _crh_int = xr.DataArray(_crh_int, name="crh", dims=("lev", "lat"), + coords={"lev": lev, "lat": _crh.lat}) + return _crh_int + + fig=plt.figure(figsize=(16,3+3*nmod)) + + # first row: 5 panel plot for 5 domain averages ordered from South to North + for mod in models: + crh_exp = hlp.load_crh_zontimmean(mod, exp) + crh_ami = hlp.load_crh_zontimmean(mod, exp="amip") + if mod=="HadGEM3-GC31-LL": + crh_exp = _convert_crh_hgt2lev(crh_exp, mod, exp) + crh_ami = _convert_crh_hgt2lev(crh_ami, mod, exp="amip") + dcrh = crh_exp - crh_ami + # 70S - 35S + ax=plt.subplot(nmod+1,5,1) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-70, latn=-35)) + # 35S - 15S + ax=plt.subplot(nmod+1,5,2) + if mod=="MRI-ESM2-0" and exp=="amip-p4K": + # for nicer plot + aux = hlp.compute_domainmean(dcrh, lats=-35, latn=-15); aux = xr.where(aux < 0.245, aux, 0.245) + _plot_crh_singledata(aux) + else: + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-35, latn=-15)) + # 15S - 15N + ax=plt.subplot(nmod+1,5,3) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-15, latn=+15)) + # 15N - 35N + ax=plt.subplot(nmod+1,5,4) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+15, latn=+35)) + # 35N - 70N + ax=plt.subplot(nmod+1,5,5) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+35, latn=+70)) + + # now 1 row for each model for the 5 domain averages and with the prediction by upward CRH shift + for imod in range(nmod): + crh_exp = hlp.load_crh_zontimmean(models[imod], exp) + crh_ami = hlp.load_crh_zontimmean(models[imod], exp="amip") + if models[imod]=="HadGEM3-GC31-LL": + crh_exp = _convert_crh_hgt2lev(crh_exp, models[imod], exp) + crh_ami = _convert_crh_hgt2lev(crh_ami, models[imod], exp="amip") + dcrh = crh_exp - crh_ami + # 70S - 35S + ax=plt.subplot(nmod+1,5,(imod+1)*5+1) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-70, latn=-35)) + _plot_crh_upwardshift(hlp.compute_domainmean(crh_ami, lats=-70, latn=-35), beta=beta) + corrcoeff=_compute_correlation_upwardshift(hlp.compute_domainmean(dcrh, lats=-70, latn=-35), + hlp.compute_domainmean(crh_ami, lats=-70, latn=-35), beta=beta) + plt.text(1, 0.03, "{0:.2f}".format(corrcoeff), + fontsize=12, fontweight="bold", ha="right", transform=ax.transAxes) + # 35S - 15S + ax=plt.subplot(nmod+1,5,(imod+1)*5+2) + if models[imod]=="MRI-ESM2-0" and exp=="amip-p4K": + # for nicer plot + aux = hlp.compute_domainmean(dcrh, lats=-35, latn=-15); aux = xr.where(aux < 0.245, aux, 0.245) + _plot_crh_singledata(aux) + else: + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-35, latn=-15)) + _plot_crh_upwardshift(hlp.compute_domainmean(crh_ami, lats=-35, latn=-15), beta=beta) + corrcoeff=_compute_correlation_upwardshift(hlp.compute_domainmean(dcrh, lats=-35, latn=-15), + hlp.compute_domainmean(crh_ami, lats=-35, latn=-15), beta=beta) + plt.text(1, 0.03, "{0:.2f}".format(corrcoeff), + fontsize=12, fontweight="bold", ha="right", transform=ax.transAxes) + # 15S - 15N + ax=plt.subplot(nmod+1,5,(imod+1)*5+3) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=-15, latn=+15)) + _plot_crh_upwardshift(hlp.compute_domainmean(crh_ami, lats=-15, latn=+15), beta=beta) + corrcoeff=_compute_correlation_upwardshift(hlp.compute_domainmean(dcrh, lats=-15, latn=+15), + hlp.compute_domainmean(crh_ami, lats=-15, latn=+15), beta=beta) + plt.text(1, 0.03, "{0:.2f}".format(corrcoeff), + fontsize=12, fontweight="bold", ha="right", transform=ax.transAxes) + # 15N - 35N + ax=plt.subplot(nmod+1,5,(imod+1)*5+4) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+15, latn=+35)) + _plot_crh_upwardshift(hlp.compute_domainmean(crh_ami, lats=+15, latn=+35), beta=beta) + corrcoeff=_compute_correlation_upwardshift(hlp.compute_domainmean(dcrh, lats=+15, latn=+35), + hlp.compute_domainmean(crh_ami, lats=+15, latn=+35), beta=beta) + plt.text(1, 0.03, "{0:.2f}".format(corrcoeff), + fontsize=12, fontweight="bold", ha="right", transform=ax.transAxes) + # 35N - 70N + ax=plt.subplot(nmod+1,5,(imod+1)*5+5) + _plot_crh_singledata(hlp.compute_domainmean(dcrh, lats=+35, latn=+70)) + _plot_crh_upwardshift(hlp.compute_domainmean(crh_ami, lats=+35, latn=+70), beta=beta) + corrcoeff=_compute_correlation_upwardshift(hlp.compute_domainmean(dcrh, lats=+35, latn=+70), + hlp.compute_domainmean(crh_ami, lats=+35, latn=+70), beta=beta) + plt.text(1, 0.03, "{0:.2f}".format(corrcoeff), + fontsize=12, fontweight="bold", ha="right", transform=ax.transAxes) + + # make nice axes for subplots + # 75S-35S + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+1); _make_niceaxes(ax, xlim=[-0.25,0.25]) + # 35S-15S + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+2); _make_niceaxes(ax, xlim=[-0.25,0.25]) + # 15S-15N + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+3); _make_niceaxes(ax, xlim=[-0.5,0.5]) + # 15NS-35N + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+4); _make_niceaxes(ax, xlim=[-0.25,0.25]) + # 35N-75N + for ipanel in range(nmod+1): ax=plt.subplot(nmod+1,5,5*ipanel+5); _make_niceaxes(ax, xlim=[-0.25,0.25]) + + # add model names and y-axis labels and ticks + ax=plt.subplot(nmod+1,5,1) + plt.text(-0.1, 0.5, "All models", fontsize=15, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + for imod in range(nmod): + ax=plt.subplot(nmod+1,5,5*imod+6) + plt.text(-0.1, 0.5, models[imod], fontsize=15, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + + # add y-axis labels and ticks on right hand side of plot + ax=plt.subplot(nmod+1,5,5) + plt.ylabel(r"pressure / hPa", size=15, loc="top") + plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) + for imod in range(nmod): + ax=plt.subplot(nmod+1,5,5*imod+10) + plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) + + # add domains as titles + ax=plt.subplot(nmod+1,5,1); plt.text(0.5, 1.1, "70S - 35S", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,2); plt.text(0.5, 1.1, "35S - 15S", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,3); plt.text(0.5, 1.1, "15S - 15N", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,4); plt.text(0.5, 1.1, "15N - 35N", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + ax=plt.subplot(nmod+1,5,5); plt.text(0.5, 1.1, "35N - 70N", fontsize=15, fontweight="bold", + ha="center" , va="center", transform=ax.transAxes) + + # add x-labels in last row + ax=plt.subplot(nmod+1,5,5*nmod+1) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+2) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+3) + plt.xticks([-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,0.3,0.4,0.5], ["","-0.4","","-0.2","","0","","0.2","","0.4",""], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+4) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + ax=plt.subplot(nmod+1,5,5*nmod+5) + plt.xticks([-0.2,-0.1,0,0.1,0.2], ["-0.2","","0","","0.2"], fontsize=10) + plt.xlabel(r"cloud-radiative heating / K$\,$day$^{-1}$", size=15, loc="right") + + hlp.spacing_subplots() + + +#---------------------------------------------------------------------- +# Generates plots by calling plotting functions. +#---------------------------------------------------------------------- + +# xypanel plots of zonal means +if lplot1: + # amip plus 4K SST + plot_dcrh_xypanelplot(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipp4K-amip.pdf") + # amip with 4K-future SST increase + plot_dcrh_xypanelplot(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/crh_changewithwarming_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf") + +# domain averages +if lplot2: + # amip-p4K + plot_dcrh_5domains(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("figures/crh_changewithwarming_5xdomaintimemean_amipp4K-amip.pdf") + # amip with 4K-future SST increase + plot_dcrh_5domains(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("figures/crh_changewithwarming_5xdomaintimemean_amipfuture4K-amip.pdf") \ No newline at end of file diff --git a/plots4paper/make_plots_crh_changewithwarming_Tlev.py b/plots4paper/make_plots_crh_changewithwarming_Tlev.py new file mode 100644 index 0000000000000000000000000000000000000000..037c85143d310040b87b53daaf1aa28ab0bbf4bb --- /dev/null +++ b/plots4paper/make_plots_crh_changewithwarming_Tlev.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plots of CRH change with surface warming sampled with T as vertical coordinate for all available models. +# Change is calculated as amip-p4K - amip and amip-future4K - amip. +# Generates the following types of multi-panel plots of CRH: +# * Plot 1: one panel per model, using only one CRH approach per model + +# on srvx1 of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plots_crh_changewithwarming_Tlev.py + +import os +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp + +#---------------------------------------------------------------------- +# Defines switches re which plots should be generated +#---------------------------------------------------------------------- +lplot1=True + +#---------------------------------------------------------------------- +# Defines plotting functions +#---------------------------------------------------------------------- + +# Plot 1: +# zonal-mean time-mean CRH for all available models of a given simulation in a 4-column panel plot +def plot_dcrh_Tlev_xypanelplot(exp, models): + + # temperature levels + Tint=np.linspace(100,320,221) + + crh_clev=0.5*np.delete(1.0*np.linspace(-1,1,21),10) # contour levels for CRH, remove 0 + nmod = len(models) # number of models + + ncol=4 + # number of panel rows as a function of number of models, we add one extra row to place colorbar there + nrow=int(np.floor(nmod/ncol)) + 1 + if np.mod(nmod,ncol) > 0: nrow+=1 + + def _plot_crh_singledata(crh, ax): + """ Plots zonal-mean time-mean CRH for T as vertical coordinate.""" + cnt=plt.contourf(crh.lat, crh.Tint, crh, crh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(300,180) + plt.yticks([300,270,240,210,180],[" ", " ", " ", " ", " "], size=10); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=10, va="top"); + ax.tick_params(direction="in", length=4) + return + + # we use one extra row to place the colorbar there + fig=plt.figure(figsize=(4*6,nrow*4)) + + # loop over models, use crh in following order: 1) from CFmon flux, 2) from tntr of CFmon, AERmon, Emon, 3) from tntr of EmonZ + counter=0 + for mod in models: + counter+=1 + crh_exp = hlp.crh_zonaltimemean_Tlevels(mod, exp=exp, Tint=Tint) + crh_ami = hlp.crh_zonaltimemean_Tlevels(mod, exp="amip", Tint=Tint) + crh_ami2= hlp.crh_zonaltimemean_Tlevels(mod, exp="amip", Tint=Tint, remove_pbl=True) + ax=plt.subplot(nrow, ncol, counter) + _plot_crh_singledata(crh_exp-crh_ami, ax) + # overlay with contour lines of crh in amip simulation with pbl removed + plt.contour(crh_ami2.lat, crh_ami2.Tint, crh_ami2, levels=2*crh_clev, colors="k") + if np.mod(counter, ncol) == 1: + plt.ylabel("temperature / K", loc="top", fontsize=15) + plt.yticks([300,270,240,210,180],["300","270","240","210","180"], size=12); + if counter>ncol*(nrow-2): + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + # for rows that are not completely filled, we need to include + # xlabel in the panels of the row above + if counter+ncol>nmod: + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + ax.text(0.03,0.96, mod, ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=15, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position found manually, to do so use "print(ax)" for above subplots + ax = fig.add_axes([0.714,0.381765,0.185, 0.04/nrow]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-1, -0.7, -0.4, 0.0, 0.4, 0.7, 1.0], + label="K/day", + boundaries=crh_clev, norm=mpl.colors.Normalize(crh_clev[0], crh_clev[-1])) + cb.ax.set_xticklabels(["-1.0", "-0.7", "-0.4", "0", "0.4", "0.7", "1.0"]) + cb.ax.tick_params(labelsize=15) + cb.set_label(label="K/day", size=15) + + hlp.spacing_subplots() + +#---------------------------------------------------------------------- +# Generates plots by calling plotting functions. +#---------------------------------------------------------------------- + +# xypanel plots of zonal means +if lplot1: + # amip plus 4K SST + plot_dcrh_Tlev_xypanelplot(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipp4K-amip.pdf") + # amip with 4K-future SST increase + plot_dcrh_Tlev_xypanelplot(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/crh_changewithwarming_Tlev_zonaltimemean_xypanelplot_amipfuture4K-amip.pdf") \ No newline at end of file diff --git a/plots4paper/make_plots_csrh.py b/plots4paper/make_plots_csrh.py new file mode 100644 index 0000000000000000000000000000000000000000..226fd81cb34aac87b9bcd37963cec1c96ef83029 --- /dev/null +++ b/plots4paper/make_plots_csrh.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Plots of clear-sky radiative heating (csrh) for all available models and the amip, amip-p4K and amip-future4K simulations +# Generates the following types of multi-panel plots of csrh: +# * Plot 1: one panel per model, using only one csrh approach per model; +# * Plot 2: one row per model and three columns: i) csrh from radiative fluxes provided by the CFmon table, ii) csrh from tntr provided by the CFmon, AERmon and Emon tables, and iii) csrh from tntr provided by the EmonZ table. +# * Plot 3: vertical profiles of csrh averaged over 5 domains + +# on srvx1 of img univie, call as follows: +# /home/swd/manual/nwp/2023.1/bin/python3.10 make_plots_csrh.py + +import os +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt +import matplotlib as mpl +import helpers as hlp + +import warnings +warnings.simplefilter("ignore") + +#---------------------------------------------------------------------- +# Defines switches re which plots should be generated +#---------------------------------------------------------------------- +lplot1=True +lplot2=True +lplot3=True + +#---------------------------------------------------------------------- +# Defines plotting functions +#---------------------------------------------------------------------- + +# Plot 1: +# zonal-mean time-mean csrh for all available models of a given simulation in a 4-column panel plot +# and with tropopause and T=0 and T=-38deg C as lines +def plot_csrh_xypanelplot(exp, models): + + csrh_clev=np.delete(2.0*np.linspace(-1,1,21),10) # contour levels for csrh, remove 0 + nmod = len(models) # number of models + + ncol=4 + # number of panel rows as a function of number of models, we add one extra row to place colorbar there + nrow=int(np.floor(nmod/ncol)) + 1 + if np.mod(nmod,ncol) > 0: nrow+=1 + + def _plot_csrh_singledata(csrh, ax): + """ Plots zonal-mean time-mean csrh. Works for both pressure-level and height-level data.""" + lat=csrh.lat + if "lev" in csrh.coords: # pressure levels (almost all models) + lev = csrh.lev.values + elif "hgt" in csrh.coords: # height levels (HadGEM and UKESM models) + csrh, lev = hlp.height2pressure_zg(csrh,mod,exp) + cnt=plt.contourf(lat, lev/100, csrh, csrh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " ", " ", " "], size=12); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],[" ", " ", " ", " ", " "], size=12, va="top"); + ax.tick_params(direction="in", length=6) + return + + def _plot_ta_tp(ta, tp, ax): + """ Plots temperature contours and tropopause, which are both on pressure levels.""" + plt.contour(ta.lat, ta.lev/100, ta, levels=[273.15-38, 273.15], colors="darkgray", linestyles="-", linewidths=0.5) + plt.plot(tp.lat, tp, color="seagreen", linewidth=0.5) + return + + # we use one extra row to place the colorbar there + fig=plt.figure(figsize=(6*4,nrow*4)) + #fig, axs = plt.subplots(ncol, nrow, layout="constrained", figsize=(6*ncol,4*nrow)) + + # loop over models, use csrh in following order: 1) from CFmon flux, 2) from tntr of CFmon, AERmon, Emon, 3) from tntr of EmonZ + counter=0 + for mod in models: + counter+=1 + # air temperature and tropopause + ta = hlp.ta_Amon_ymonmean(mod, exp)["ta"].mean(["month", "lon"]).squeeze() + tp = hlp.tropo_Amon_zontimmean(mod, exp)["trop"].squeeze() + # csrh + csrh = hlp.load_csrh_zontimmean(mod, exp) + if mod in ["CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2"]: + if ta is not None: ta = ta.where(ta.lev<500e2) + # plot + ax=plt.subplot(nrow, ncol, counter) + _plot_csrh_singledata(csrh, ax) + _plot_ta_tp(ta, tp, ax) + if np.mod(counter, ncol) == 1: + plt.ylabel("pressure / hPa", loc="top", fontsize=15) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=12); + if counter>ncol*(nrow-2): + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + # for rows that are not completely filled, we need to include + # xlabel in the panels of the row above + if counter+ncol>nmod: + plt.xlabel("latitude / deg", loc="right", fontsize=15) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=12, va="top"); + ax.text(0.03,0.96, mod, ha="left", va="top", transform=ax.transAxes, backgroundcolor="white", + size=15, bbox=dict(facecolor="white", edgecolor="k", boxstyle="round,pad=0.3")) + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position found manually, to do so use "print(ax)" for above subplots + if exp=="amip-p4K" or exp=="amip-future4K": + ax = fig.add_axes([0.714,0.381765,0.185, 0.04/nrow]) + if exp=="amip": + ax = fig.add_axes([0.714,0.20,0.185, 0.04/nrow]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-2, -1.4, -0.8, 0.0, 0.8, 1.4, 2.0], + label="K/day", + boundaries=csrh_clev, norm=mpl.colors.Normalize(csrh_clev[0], csrh_clev[-1])) + cb.ax.set_xticklabels(["-2.0", "-1.4", "-0.8", "0", "0.8", "1.4", "2.0"]) + cb.ax.tick_params(labelsize=15) + cb.set_label(label="K/day", size=15) + + hlp.spacing_subplots() + + +# Plot 2: +# zonal-mean time-mean csrh for all available models and all available approaches as a 3-column panel plot +# with one row per model +def plot_csrh_3approaches(exp, models): + + csrh_clev=np.delete(2.0*np.linspace(-1,1,21),10) # contour levels for csrh, remove 0 + nmod = len(models) # number of models + + def _plot_csrh_singledata(csrh, ax): + """ Plots zonal-mean time-mean csrh. Works for both pressure-level and height-level data.""" + # pressure levels (almost all models) + if "lev" in csrh.coords: + cnt=plt.contourf(csrh.lat, csrh.lev/100, csrh, csrh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(1000,10) + plt.yticks([800,600,400,200],[" ", " "," "," "], size=6); + # height levels (HadGEM and UKESM models) + elif "hgt" in csrh.coords: + cnt=plt.contourf(csrh.lat, csrh.hgt/1000, csrh, csrh_clev, cmap="RdBu_r", extend="both") + for c in cnt.collections: c.set_edgecolor("face") + plt.ylim(0,20) + plt.yticks([4,8,12,16],[" ", " ", " ", " "], size=6); + plt.xlim(-88,88) + plt.xticks([-60,-30,0,30,60],["60S", "30S","Eq","30N","60N"], size=6, va="top"); + ax.tick_params(direction="in", length=6) + return + + fig=plt.figure(figsize=(10,nmod*1.5)) + + # three top subplots for title of columns + + ax=plt.subplot(nmod+1, 3, 1); ax.set_axis_off() + plt.text(0.5, 0.2, "From fluxes", fontsize=10, fontweight="bold", ha="center" , va="center", transform=ax.transAxes) + + ax=plt.subplot(nmod+1, 3, 2); ax.set_axis_off() + plt.text(0.5, 0.2, "From tntr of CFmon, AERmon, Emon", fontsize=10, fontweight="bold", ha="center" , va="center", transform=ax.transAxes) + + ax=plt.subplot(nmod+1, 3, 3); ax.set_axis_off() + plt.text(0.5, 0.2, "From tntr of EmonZ", fontsize=10, fontweight="bold", ha="center" , va="center", transform=ax.transAxes) + + counter=4 # counter for subplots + plot_modname=False # True if model name was already added + for mod in models: + # from fluxes + csrh = hlp.csrh_from_flx_ymonmean(mod, exp) + if csrh is not None: + ax=plt.subplot(nmod+1, 3, counter); _plot_csrh_singledata(csrh.mean(["month", "lon"]), ax) + plt.text(-0.2, 0.5, mod, fontsize=8, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + # pressure levels (almost all models) + if "lev" in csrh.coords: + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + plt.ylabel("pressure / hPa", loc="top", fontsize=6) + # height levels (HadGEM and UKESM models) + elif "hgt" in csrh.coords: + plt.yticks([4,8,12,16],["4", "8", "12", "16"], size=6); + plt.ylabel("altitude / km", loc="top", fontsize=6) + plot_modname=True + # from tntr via CFmon, AERmon, Emon + csrh = hlp.csrh_from_tntr_ymonmean(mod, exp) + if csrh is not None: + ax=plt.subplot(nmod+1, 3, counter+1); _plot_csrh_singledata(csrh.mean(["month", "lon"]), ax) + if plot_modname==False: + plt.text(-1.281, 0.5, mod, fontsize=8, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + # pressure levels (almost all models) + if "lev" in csrh.coords: + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + plt.ylabel("pressure / hPa", loc="top", fontsize=6) + # height levels (HadGEM and UKESM models) + elif "hgt" in csrh.coords: + plt.yticks([4,8,12,16],["4", "8", "12", "16"], size=6); + plt.ylabel("altitude / km", loc="top", fontsize=6) + plot_modname=True + # from tntr via EmonZ + csrh = hlp.csrh_from_tntr_EmonZ_ymonmean(mod, exp) + if csrh is not None: + ax=plt.subplot(nmod+1, 3, counter+2); + # for CESM models, need to set spuriously large values for csrh to zero + if mod in ["CESM2", "CESM2-FV2", "CESM2-WACCM", "CESM2-WACCM-FV2"]: + aux=csrh.mean(["month"]) + aux = xr.where(aux>2.0,0,aux) + _plot_csrh_singledata(aux, ax) + else: + _plot_csrh_singledata(csrh.mean(["month"]), ax) + if plot_modname==False: + plt.text(-2.359, 0.5, mod, fontsize=8, fontweight="bold", ha="center" , va="center", rotation=90, transform=ax.transAxes) + # pressure levels (almost all models) + if "lev" in csrh.coords: + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + plt.ylabel("pressure / hPa", loc="top", fontsize=6) + # height levels (HadGEM and UKESM models) + elif "hgt" in csrh.coords: + plt.yticks([4,8,12,16],["4", "8", "12", "16"], size=6); + plt.ylabel("altitude / km", loc="top", fontsize=6) + # move on to next model --> increase subplot counter by 3 + counter=counter+3 + plot_modname=False + + # plot colorbar + # solution taken and adapted from https://stackoverflow.com/a/62436015 + # axes position defined manually as a function of experiment + if exp=="amip-p4K" or exp=="amip-future4K": + ax = fig.add_axes([0.3, 0.05, 0.4, 0.06/nmod]) + if exp=="amip": + ax = fig.add_axes([0.3, 0.08, 0.4, 0.06/nmod]) + cb = mpl.colorbar.ColorbarBase(ax, orientation="horizontal", + cmap="RdBu_r", extend="both", ticks=[-2, -1.4, -0.8, 0.0, 0.8, 1.4, 2.0], + label="K/day", + boundaries=csrh_clev, norm=mpl.colors.Normalize(csrh_clev[0], csrh_clev[-1])) + cb.ax.set_xticklabels(["-2.0", "-1.4", "-0.8", "0", "0.8", "1.4", "2.0"]) + cb.ax.tick_params(labelsize=8) + cb.set_label(label="K/day", size=8) + + hlp.spacing_subplots_v2() + + +# Plot 3: +# 5 panel plot for 5 domain averages ordered from South to North +def plot_csrh_5domains(exp, models): + + nmod = len(models) # number of models + + def _make_niceaxes(ax, ticklength=0.08): + # adjust spines + ax.spines["top"].set_color("none") + ax.spines["right"].set_color("none") + ax.xaxis.set_ticks_position("bottom") + ax.spines["bottom"].set_position(("data",1000)) + ax.spines["left"].set_position(("data",-1.5)) + ax.spines["left"].set_color("none") + plt.ylim(1000,10) + plt.yticks([ ], fontsize=10) + plt.plot([0,0], [1000,10], linewidth=0.7, color="k", zorder=-10) + for ypos in [1000,800,600,400,200,10]: + plt.plot([-0.5*ticklength,0.5*ticklength], [ypos,ypos], linewidth=0.7, color="k", zorder=-10) + + def _plot_csrh_singledata(_csrh, mod): + """ Plots domain-mean time-mean csrh. Assumes pressure levels.""" + plt.plot(_csrh, _csrh.lev/100, color="gray", label=mod) + plt.yticks([800,600,400,200],["800", "600","400","200"], size=6); + return + + def _height2pressurelevels(_csrh, mod, exp): + """ Interpolates from height to common pressure levels for HadGEM and UKESM models.""" + if mod in ["HadGEM3-GC31-LL", "HadGEM3-GC31-MM", "UKESM1-0-LL"]: + _csrh_int, lev = hlp.height2pressure_zg(_csrh, mod, exp) + # _csrh_int is a numpy array, need to transform to dataarray + _csrh = xr.DataArray(_csrh_int, name="csrh", dims=("lev", "lat"), + coords={"lev": lev, "lat": _csrh.lat}) + return _csrh + + # 5 panel plot for 5 domain averages ordered from South to North + fig=plt.figure(figsize=(16,4)) + # we also collect the models' domain averages to plot the model median and std dev across models + shext = list() + shsub = list() + trops = list() + nhsub = list() + nhext = list() + for mod in models: + csrh = hlp.load_csrh_zontimmean(mod, exp) + csrh = _height2pressurelevels(csrh, mod, exp) + # 70S - 35S + ax=plt.subplot(1,5,1) + _plot_csrh_singledata(hlp.compute_domainmean(csrh, lats=-70, latn=-35), mod=mod) + # 35S - 15S + ax=plt.subplot(1,5,2) + _plot_csrh_singledata(hlp.compute_domainmean(csrh, lats=-35, latn=-15), mod=mod) + # 15S - 15N + ax=plt.subplot(1,5,3) + _plot_csrh_singledata(hlp.compute_domainmean(csrh, lats=-15, latn=+15), mod=mod) + # 15N - 35N + ax=plt.subplot(1,5,4) + _plot_csrh_singledata(hlp.compute_domainmean(csrh, lats=+15, latn=+35), mod=mod) + # 35N - 70N + ax=plt.subplot(1,5,5) + _plot_csrh_singledata(hlp.compute_domainmean(csrh, lats=+35, latn=+70), mod=mod) + # save domain averages + shext.append(hlp.compute_domainmean(csrh, lats=-70, latn=-35).values) + shsub.append(hlp.compute_domainmean(csrh, lats=-35, latn=-15).values) + trops.append(hlp.compute_domainmean(csrh, lats=-15, latn=+15).values) + nhsub.append(hlp.compute_domainmean(csrh, lats=+15, latn=+35).values) + nhext.append(hlp.compute_domainmean(csrh, lats=+35, latn=+70).values) + + # include model median and std dev across models for amip simulations + # make x-axis labels nice by hand for amip (but not the other simulations) + if exp=="amip": + ax=plt.subplot(1,5,1); plt.plot(np.nanmedian(np.array(shext), axis=0), csrh.lev/100, color="black", linewidth=2); + plt.xlabel("model median", fontsize=10, fontweight="bold", color="black", loc="right") + plt.xticks(ticks=[-1,-0.5,0,0.5], labels=["-1.0","-0.5","0","0.5"]) + ax=plt.subplot(1,5,2); plt.plot(np.nanmedian(np.array(shsub), axis=0), csrh.lev/100, color="black", linewidth=2); + plt.xticks(ticks=[-1,-0.5,0,0.5], labels=["-1.0","-0.5","0","0.5"]) + ax=plt.subplot(1,5,3); plt.plot(np.nanmedian(np.array(trops), axis=0), csrh.lev/100, color="black", linewidth=2); + plt.xticks(ticks=[-0.5,0,0.5], labels=["-0.5","0","0.5"]) + ax=plt.subplot(1,5,4); plt.plot(np.nanmedian(np.array(nhsub), axis=0), csrh.lev/100, color="black", linewidth=2) + plt.xticks(ticks=[-0.5,0,0.5], labels=["-0.5","0","0.5"]) + ax=plt.subplot(1,5,5); plt.plot(np.nanmedian(np.array(nhext), axis=0), csrh.lev/100, color="black", linewidth=2) + plt.xticks(ticks=[-0.5,-0.25,0,0.25,0.5], labels=["-0.5","-0.25","0","0.25","0.5"]) + + # make nice axes for subplots + ax=plt.subplot(1,5,1); _make_niceaxes(ax); plt.title("70S - 35S", fontweight="bold", fontsize=15) + plt.ylabel(r"pressure / hPa", size=12, loc="top") + plt.yticks([1000,800,600,400,200,10], ["1000", "800", "600", "400", "200", "10"], fontsize=10) + ax=plt.subplot(1,5,2); _make_niceaxes(ax); plt.title("35S - 15S", fontweight="bold", fontsize=15) + ax=plt.subplot(1,5,3); _make_niceaxes(ax); plt.title("15S - 15N", fontweight="bold", fontsize=15); + ax=plt.subplot(1,5,4); _make_niceaxes(ax); plt.title("15N - 35N", fontweight="bold", fontsize=15) + ax=plt.subplot(1,5,5); _make_niceaxes(ax); plt.title("35N - 70N", fontweight="bold", fontsize=15) + plt.xlabel(r"clear-sky radiative heating / K$\,$day$^{-1}$", size=12, loc="right") + + plt.subplots_adjust(left=0.1, bottom=0.15, right=0.9, top=0.9, + wspace=0.08, hspace=0.1) + +#---------------------------------------------------------------------- +# Generates plots by calling plotting functions. +#---------------------------------------------------------------------- + +# xypanel plots of zonal means +if lplot1: + # amip + plot_csrh_xypanelplot(exp="amip", models=hlp.models_amip) + plt.savefig("./figures/csrh_zonaltimemean_xypanelplot_amip.pdf") + # amip plus 4K SST + plot_csrh_xypanelplot(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/csrh_zonaltimemean_xypanelplot_amipp4K.pdf") + # amip with 4K-future SST increase + plot_csrh_xypanelplot(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/csrh_zonaltimemean_xypanelplot_amipfuture4K.pdf") + +# 3 approaches +if lplot2: + # amip + plot_csrh_3approaches(exp="amip", models=hlp.models_amip) + plt.savefig("./figures/csrh_zonaltimemean_3approaches_amip.pdf") + # amip plus 4K SST + plot_csrh_3approaches(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("./figures/csrh_zonaltimemean_3approaches_amip-p4K.pdf") + # amip with 4K-future SST increase + plot_csrh_3approaches(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("./figures/csrh_zonaltimemean_3approaches_amip-future4K.pdf") + +# domain averages +if lplot3: + # amip + plot_csrh_5domains(exp="amip", models=hlp.models_amip) + plt.savefig("figures/csrh_5xdomaintimemean_amip.pdf") + # amip-p4K + plot_csrh_5domains(exp="amip-p4K", models=hlp.models_amipp4K) + plt.savefig("figures/csrh_5xdomaintimemean_amip-p4K.pdf") + # amip with 4K-future SST increase + plot_csrh_5domains(exp="amip-future4K", models=hlp.models_amipfuture4K) + plt.savefig("figures/csrh_5xdomaintimemean_amip-future4K.pdf") \ No newline at end of file diff --git a/plots4paper/obs_prediction.ipynb b/plots4paper/obs_prediction.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..541b9bbc1b15ffe0ea167d4eecad78f53d76ba4d --- /dev/null +++ b/plots4paper/obs_prediction.ipynb @@ -0,0 +1,260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aeb40072-b961-441e-a071-871b3b654a72", + "metadata": {}, + "source": [ + "# Make prediction based on satellite-based estimates of CRH and upward shift, using $\\beta=1.2$" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3a783296-8252-4157-a88d-71cbcab0d9f8", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import xarray as xr\n", + "import matplotlib.pyplot as plt \n", + "from matplotlib.gridspec import GridSpec\n", + "import matplotlib as mpl\n", + "\n", + "import helpers as hlp\n", + "\n", + "import sys\n", + "sys.path.append(\"../analysis/\")\n", + "from cmip6radheating import define_targetlevels" + ] + }, + { + "cell_type": "markdown", + "id": "177922a5-0723-4415-80d2-59965866f486", + "metadata": {}, + "source": [ + "Loads CRH obs data." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "51b009ff-90a7-4e0b-9051-1898cea6b0f4", + "metadata": {}, + "outputs": [], + "source": [ + "clca = hlp.acre_obs_2bflxhrlidar_r05() # 2b-lx-lidar r05\n", + "cccm = hlp.acre_obs_cccm() # cccm" + ] + }, + { + "cell_type": "markdown", + "id": "f0e95a12-ed38-46fb-b782-998c02a973e0", + "metadata": {}, + "source": [ + "Predicts CRH change from upward shift." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "6e60f111-5d1d-492f-a9a4-0ed44e28895e", + "metadata": {}, + "outputs": [], + "source": [ + "def dcrh_upwardshift(_crh, _beta):\n", + " \"\"\" Predicts CRH change based on upward shift of reference crh.\n", + " Returns xarray datarray.\n", + " \"\"\"\n", + " _lev = _crh.lev\n", + " _lat = _crh.lat\n", + " # do we need to reverse vertical axis so that pressure is increasing?\n", + " lreverse=False\n", + " if _lev[0]>_lev[1]:\n", + " lreverse=True\n", + " _lev = _lev[::-1]\n", + " _crh = _crh[::-1,:]\n", + " _crh_shift = _crh + np.nan\n", + " # interpolate shifted crh from levels lev/beta to input levels lev\n", + " for ilat in range(0, _lat.size):\n", + " _crh_shift[:, ilat] = np.interp(_lev, _lev/_beta, _crh[:, ilat]) \n", + " # reverse pressure back if reversed previously\n", + " if lreverse: \n", + " _crh = _crh[::-1,:]\n", + " _crh_shift = _crh_shift[::-1,:]\n", + " return _crh_shift - _crh" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2c5b6da3-39bc-4c92-8f8e-64312357373f", + "metadata": {}, + "outputs": [], + "source": [ + "dcrh_clca = dcrh_upwardshift(clca, _beta=1.2)\n", + "dcrh_cccm = dcrh_upwardshift(cccm, _beta=1.2)" + ] + }, + { + "cell_type": "markdown", + "id": "342d7597-5212-4b8c-acf7-4b15e3224d4e", + "metadata": {}, + "source": [ + "Makes plot." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "3008ad74-e895-4eed-9a6c-878051699492", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABBgAAAK0CAYAAACp747GAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy88F64QAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydeZwU1bn3f6eq19mBAQYQHBXclyga0bjgVVDjzjUaNWpcEnfFJRpjjBiNRhO3RGPc0bgmRlBjVNBEvbngvb6Y1SReFxBEhmFgmK17eqk67x811VT3VHfXvnQ/38+nlamurjpVdarOeX71LIxzzkEQBEEQBEEQBEEQBGEDwe8GEARBEARBEARBEAQRfkhgIAiCIAiCIAiCIAjCNiQwEARBEARBEARBEARhGxIYCIIgCIIgCIIgCIKwDQkMBEEQBEEQBEEQBEHYhgQGgiAIgiAIgiAIgiBsQwIDQRAEQRAEQRAEQRC2IYGBIAiCIAiCIAiCIAjbkMBAEARBEARBEARBEIRtSGAgCIIgCIIgCIIgCMI2gRcY3nnnHRxzzDGYPHkyGGNYvHhx0feccyxYsACTJ09GMpnE7Nmz8cEHH/jTWIIgCIIgCIIgCKLu+cUvfoFtttkGiUQCM2fOxH/913+VXfett94CY2zU59///reHLXaGwAsMQ0ND2GOPPXDvvffqfn/77bfjzjvvxL333ov33nsPHR0dmDNnDgYGBjxuKUEQBEEQBEEQBFHvPPfcc5g/fz6uu+46/PnPf8aBBx6II488EqtXr674uw8//BDr1q0rfGbMmOFRi52Dcc65340wCmMMixYtwvHHHw9A8V6YPHky5s+fj2uuuQYAkMlkMHHiRNx2220477zzfGwtQRAEQRAEQRAEUW/su+++2GuvvXD//fcXlu200044/vjjceutt45a/6233sIhhxyC3t5etLW1edhS54n43QA7rFy5El1dXZg7d25hWTwex8EHH4xly5bpCgyyLGPVqlWIRqNgjBV9F4/HEY/HXW83QRAEQVSDc46BgQFMnjwZguCMw6Esy/jiiy/Q3Nw8agwkCIIgiCDgxvgHAMPDw8hms5bbZNR2zGazWLFiBb773e8WLZ87dy6WLVtWcT977rknhoeHsfPOO+P73/8+DjnkEEvt9ZNQCwxdXV0AgIkTJxYtnzhxIj777DPd33zxxRfYbrvtXG8bQRAEQTjBmjVrsNVWWzmyrS+++AJTp051ZFsEQRAE4SZOjn/Dw8NoTzZhCJKl3zc1NWFwcLBo2Q033IAFCxaMWrenpweSJOnaqKr9WsqkSZPw4IMPYubMmchkMvjVr36FQw89FG+99RYOOuggS232i1ALDCqlapKewqTS3NwMAPjnP/9Z+LcKeTAQBEEQQaG/vx9Tp04dNVbZQd3WmjVrEItGHdsuQRAEQThBIpl0ZfzLZrMYgoSLotMQN5mGMAMZ9w2uxpo1a9DS0lJYXs1uNGOj7rDDDthhhx0Kf++3335Ys2YNfvrTn9aPwJBKpbB69epRbia777677UYZpaOjA4DiyTBp0qTC8u7u7lGKkYp6UadMmVLUQQiCIAgiiDgZyqBuq6WlhQQGgiAIInAkksnCv90I5YtDQJyZDLsYyVjY0tJiyH5sb2+HKIqjvBUq2ah6zJo1C08++aSppgYB00EtGzZswNFHH43m5mbssssu2HPPPYs+XrLNNtugo6MDS5cuLSzLZrN4++23sf/++3vaFoIgCIIgCIIgCKK+icVimDlzZpGNCgBLly41ZaP++c9/LnqJHhZMezDMnz8fvb29ePfdd3HIIYdg0aJFWL9+PW6++WbccccdjjdwcHAQH3/8ceHvlStX4i9/+QvGjh2LadOmYf78+bjlllswY8YMzJgxA7fccgsaGhpw6qmnGt4H5xyyLDvedoIgCIIwgyAIlHyRIAiCIELOFVdcgdNPPx1777039ttvPzz44INYvXo1zj//fADAtddei7Vr1+KJJ54AANx9993o7OzELrvsgmw2iyeffBK//e1v8dvf/tbPw7CEaYHhD3/4A1588UXss88+EAQBW2+9NebMmYOWlhbceuutOOqooxxt4P/7f/+vKHvmFVdcAQA488wzsXDhQlx99dVIp9O48MIL0dvbi3333RdLliwxFbOTz+UgSaMTfuTzebz77rv4fO1a5HM5+wdDEBZgjKGtrQ2zZs3CuHHj/G4OQRAuEo3FIIqi380AoIQf/u///i8GBgYQoorWnhONxbD11lvjyyPzIoIgCII4+eSTsXHjRvzwhz/EunXrsOuuu+L3v/89tt56awDAunXrsHr16sL62WwWV111FdauXYtkMolddtkFr7zyCr761a/6dQiWYdzkrKGlpQV/+9vf0NnZic7OTjz11FP4yle+gpUrV2KXXXZBKpVyq62O0N/fj9bWVvT19RViaLLZLGSNwCBJEn5www144okn0NPT41dTCaIIURTxH4ccgp///OeFhxNBELVFNBqFGFG0f73xyi7abZbLwfDBBx/g8iuuwJ/+9CcSFkwwqaMD5513Hq6++mryQiEIgrCImuTRrfHvimin6RwMGS7jztwqR9tTy5j2YNhhhx3w4YcforOzE1/60pfwwAMPoLOzE7/85S9DGSNSiizLOO/88/HMM8/g8ssvx9e//nXstNNOVF2C8A1JktDd3Y3f/e53+MlPfoK5hx+OJa+/TiIDQRCO889//hNHfvWrGD9+PB5++GEcccQRaG9vpzfzFRgeHsbf/vY3PPnkk1hw443Y1NuL2378Y7+bRRAEQRC+YCkHwxdffAFAqf15+OGH46mnnkIsFsPChQudbp/nLFu+HE899RQee+wxfPOb3/S7OQSBSCSCqVOn4oILLsDRRx+NL3/5y/jJT36Ce++91++mEQRRYyy48Ua0tbXhnXfeoZAsgzQ1NWH//ffH/vvvj2222QZXX301zjn7bGy//fZ+N40gCIIgPMf0K4nTTjsNZ511FgBgzz33xKpVq/Dee+9hzZo1OPnkkx1voNe88MILmDJlCs444wy/m0IQo5g6dSrOOOMMvPjSS8jn8343hyCIGmJgYABLlizBeeedR+KCRS6++GI0NTXhhRde8LspBEEQBOELhgWGVCqFiy66CFOmTMGECRNw6qmnoqenBw0NDdhrr73Q3t7uZjs94/3338d//Md/kDsoEVgOO+ww9PT0FCWGIQiCsMs///UvZDIZHHbYYX43JbQkk0kccMABWPH++343hSAIgiB8wbAVfcMNN2DhwoU46qij8PWvfx1Lly7FBRdc4GbbfGFwcBBtbW1+N4MgyqL2z/7+fn8bQhBETTE4MAAANAbapK2tDQMj55IgCIIg6g3DAsMLL7yARx55BA8++CB+9rOf4ZVXXsHixYt1yzuGHbvZn//v//4PsVgM7xt8g/GHP/wBZ599NnbccUc0NjZiypQpOO6447BixYpR686ePRuMscInGo2is7MT55xzDj777DND+3vrrbeKtqH9nHjiiUX72nXXXctuh3OOww47DOPGjUNXV9eo788//3zEYjH8+c9/BgCsWrUKjDH89Kc/1d3eT3/6UzDGsGrVqsKyb37zm0Xti8Vi2G677XDVVVcZNrAXLFgAxljFiiDqOXn++ecLyxYuXFi070QigY6ODhxyyCG49dZb0d3dXXG/e+21V8XjLd1+JBLBpEmT8PWvfx0fffRR2e2Sdw1BEG6iNwYaeY6qHHTQQZg/f76pffb39+NHP/oR9t57b7S0tCAej6OzsxNnn3227lj6t7/9DWeddRa22WYbJBIJNDU1Ya+99sLtt9+OTZs2Fa0ryzJ+9atf4bDDDkN7ezui0SgmTJiAo48+Gi+//DJkWQawZYxijGHBggW67Tz77LML65SDntEEQRBEPWN4FFyzZg0OPPDAwt9f/vKXEYlECgkfiS1sv/32OO2003D55ZcbWv/+++/HqlWrcNlll+H3v/897rnnHnR3d2PWrFn4wx/+MGr9bbfdFsuXL8fy5cvx5ptv4uqrr8bvfvc7HHjggabKhN5yyy2F7aifW2+91fDvGWN49NFHkc/n8a1vfavou9dffx0PPPAArrvuOuy5556Gt6lHMpkstO+ll17CIYccgjvuuKNIDHGTxx57DMuXL8fSpUtx33334Utf+hJuu+027LTTTnjjjTd0f/OXv/ylIKw88sgjhrb/xhtv4OKLL8ZLL72EAw44AL29vY4fC0EQhNvcdNNN+MUvfoEPP/zQ0PqffPIJ9txzT/z4xz/GIYccgmeeeQZLlizBjTfeiPXr12PmzJno6+srrP/QQw9h5syZeO+99/Cd73wHr732GhYtWoSvfe1r+OUvf4lzzjmnsO7w8DC++tWv4swzz8SECRNw//334w9/+AN++ctfYvLkyfja176Gl19+uag9zc3NWLhwYUF4UBkcHMRvfvMbKlFGEARBEBUwXEVCkiTEYrHiH0cilGiuDBdffDH23ntvLFu2DPvvv3/Fde+77z5MmDChaNkRRxyB6dOn45ZbbsF//Md/FH2XTCYxa9aswt8HHXQQEokEzjnnHPzpT3/C3LlzDbVxxowZRduxwrRp03DnnXfi3HPPxWOPPYazzjoLvb29OOecc7DXXnvhuuuus7V9QHkbpG3nEUccgU8//RRLly7FypUrsc0229jeRyV23XVX7L333oW///M//xOXX345DjjgAMybNw8fffQRJk6cWPSbhx9+GABw1FFH4ZVXXqnYD7Tbnz17NiRJwg033IDFixcXEqoSBEGEhYMPPhg77LAD7rjjDjz44IMV15UkCSeccAJ6enqwfPnyIq+5gw8+GGeeeSZeffVVRKNRAMDy5ctxwQUXYM6cOVi8eHFRCek5c+bgyiuvxGuvvVZYdsUVV+D111/H448/Pip587x58/Cd73wH6XS6aPnJJ5+Mhx9+GG+++SbmzJlTWP7cc89BkiQcf/zxePLJJ82fGIIgCIKoAwx7MHDO8c1vfhPz5s0rfIaHh3H++ecXLatlPv74Y5x11lmYMWMGGhoaMGXKFBxzzDH4+9//PmrdmTNnYqeddsIvf/nLqtstFRcApezVzjvvjDVr1hhqW2trKwAUJmFecs455+DII4/E5ZdfjjVr1uDiiy9GT08PnnjiCUQipiuhGkI1yNevX+/K9qsxbdo03HHHHRgYGMADDzxQ9N3w8DCefvppzJw5E3fddRcA4NFHHzW8bb+PjSAIohxr1qzBvHnz0NLSgtbWVnzjG9/Ahg0bRq13+umn4+mnn66ai2Dx4sX4+9//jmuvvbZsSN6RRx6JhoYGAIrnHWMMDz74YJG4oBKLxXDssccCALq6uvDwww/j8MMPL1sZasaMGdh9992Llu2www7Yf//9Rz23H330UcybN68w3hIEQRDhY3pTFNs3xUx9pjd5b1+FGcMCg+pe2NraWvh84xvfwOTJk4uW1TJffPEFxo0bhx//+Md47bXXcN999yESiWDffffVdQWdPXs2Xn31VXDOTe+rr68P77//PnbZZRfd7/P5PPL5PFKpFP73f/8XP/zhD7HttttW9ZbQIstyYTvqxyoPP/wwBEHAIYccgqeffho33nhj2bbr7Tefz49yR63EypUrEYlEsO2221pus12++tWvQhRFvPPOO0XLX3jhBfT29uLss8/GjBkzcMABB+C5557D4OCgoe2uXLkSAKiGOkEQgeOEE07A9OnT8fzzz2PBggVYvHgxDj/8cORyuaL1Zs+ejaGhIbz11lsVt7dkyRIAwPHHH19135Ik4Q9/+ANmzpyJqVOnVl3/j3/8I3K5nKFtl3LOOedg8eLFhVC1Dz/8EMuWLSsKvyAIgiAIYjSGXy8/9thjbrYjFBx00EE46KCDCn9LkoSjjjoKu+yyCx544AHceeedRevvtddeuP/++/Hhhx9ixx13NLWviy66CENDQ7ohBh988MEoT4Xtt98er7zyiu4bnXKcfPLJo5Z99NFHmD59uqm2AsDkyZPxne98B9/73vewxx574Kqrriq77jXXXINrrrnG1PZV8aOvrw+/+c1v8MILL+C73/2urveHVzQ2NqK9vX1UHpJHHnkEiUQCp556KgBlonrWWWfh17/+Nc4+++xR25EkCfl8HsPDw/jv//5v3HzzzTjooIMKb+EIgiCCwrx583D77bcDAObOnYuJEyfitNNOw69//WucdtpphfX23HNPMMbw3//93zjmmGPKbk8tt2sk1K2npwepVMpwWJyZbZdy0kkn4bLLLsPTTz+Niy66CI888gi22WYbzJ49G7/97W9Nb48gCIIg6gVKdWyCfD6PW265BTvvvDNisRgikQhisRg++ugj/Otf/xq1vmr8rl271tR+rr/+ejz11FO46667MHPmzFHfb7fddnjvvffw3nvvYfny5Xj66aeRTCZx6KGHFlUfKPUQKPWkuO222wrbUT9G3grpMTQ0VPBi+Oijj4oqQZRy2WWXjdrve++9h8suu6zstqPRKKLRKNrb23HBBRfg5JNPxo9+9KPCOpxzx7wxzFB6TleuXIk//vGPmDdvXqHU29e+9jU0NzeXDZOYNWsWotEompubccQRR2DMmDF48cUXXQsvIQiCsIpWRAAUQzwSieCPf/xj0fJoNIq2tjbT419QaGpqwte+9rVCIuMnnngCZ511lu0qUwRBEARR65i2YIaGhvDjH/8Yb775Jrq7u0e5tX/66aeONS5oXHHFFbjvvvtwzTXX4OCDD8aYMWMgCALOPffcUUmiACCRSACA7nfluPHGG3HzzTfjRz/6ES6++GLddRKJRFHSwVmzZmH27NmYMmUKfvCDH+CZZ57BqlWrRr21+eMf/4jZs2cX/t52222LtmOH73znO1i9ejVeeeUVnHHGGTj77LMLpR9L2WqrrXT3W86VNplMFsIQurq6cMcdd+CZZ57B7rvvju9+97sAgMcff3xUQkQroSlmGBoawsaNG7HbbrsVlj366KPgnOPEE0/E5s2bC8uPPfZYPPXUU/j3v/89ypvliSeewE477YSBgQE899xzeOCBB3DKKafg1VdfdbX9BEEQZuno6Cj6OxKJYNy4cdi4ceOodROJRNXxb9q0aQAUcbaap197ezsaGhoKYWTV0G7bCueccw4OOOAA/OhHP8KGDRvwzW9+09J2CIIgCKKeMC0wnHvuuXj77bdx+umnY9KkSXWl5j/55JM444wzcMsttxQt7+npKbyt1qLW4m5vbze0/RtvvBELFizAggUL8L3vfc9U2yZNmoT29nb89a9/BaCELLz33ntF6+ywww6mtmmUN998E7/85S9x/fXX44gjjsB9992Hk046CT//+c9x6aWX2t6+IAhFgsScOXMwc+ZM3HjjjTjttNMwdepUHHPMMaOO121eeeUVSJJUEG1kWcbChQsBoGzC00cffbTgXqyy0047FY7vkEMOgSRJePjhh/H88897VoqTIAjCCF1dXZgyZUrh73w+j40bN2LcuHGj1u3t7a06/h1++OF48MEHsXjx4oJgXA5RFHHooYfi1Vdfxeeff46tttqq4vqHHHIIotEoFi9ejPPPP7/iunp85StfwQ477IAf/vCHmDNnjmUPP4IgCIKoJ0wLDK+++ipeeeUVfOUrX3GjPYGGMTYqx8Err7yCtWvX6uYt+PTTTyEIgiHD/qabbsKCBQvw/e9/HzfccIPptn3++efo6enBzjvvDEDJpO2Ud0Il+vv7cfbZZ2OPPfbA97//fQBKSMCJJ56Ia6+9FkcddRS22247R/cZj8dx3333Yfbs2bj55pvxwAMPYNy4cboTXLdYvXo1rrrqKrS2tuK8884DALz++uv4/PPPcdFFF+kKAxdffDGeeOIJ3HLLLRXDH26//Xb89re/xQ9+8APMmzcPgkCRTARBBIOnnnqqKHTv17/+NfL5fJF3HKAkRR4eHi6MSeU47rjjsNtuu+HWW2/F0UcfrVtJ4vXXX8eBBx6IhoYGXHvttfj973+Pb33rW3jxxRdHlc/O5XJ47bXXcMwxx6CjowPnnnsu7r//fjzxxBO6lSQ++eQTDA0NjaokofL9738fzz//PC666KKKx0HUFtGejy39Ltc+3dDv1fUIgiBqEdMCw5gxYzB27Fg32hJ4jj76aCxcuBA77rgjdt99d6xYsQI/+clPyr5Feffdd/GlL30JY8aMqbjdO+64Az/4wQ9wxBFH4KijjsK7775b9P2sWbOK/k6n04V1JEnCypUrC2/F58+fb/Ho9Onv78fzzz8/avn48eNx8MEH4/LLL0dXVxdefvnlosSTv/jFL7DLLrtUDJWww8EHH4yvfvWreOyxx/Dd737XUBKvl19+Gc3NzaOWV/MS+Mc//lHI69Dd3Y3/+q//wmOPPQZRFLFo0SKMHz8egJLcMRKJ4Hvf+x4mT548ajvnnXceLr30Urzyyis47rjjyu5vzJgxuPbaa3H11Vfj6aefxje+8Y2qx0YQBOEFL7zwAiKRCObMmYMPPvgA119/PfbYYw+cdNJJReupY9QhhxxScXvqc3Tu3LnYb7/9cMEFF+CQQw5BY2MjPvvsMzz//PN4+eWXC9Uc9ttvP9x///248MILMXPmTFxwwQXYZZddkMvl8Oc//xkPPvggdt1110JiyTvvvBOffvopvvnNb+L111/HCSecgIkTJ6KnpwdLly7FY489hmeffbaswPCNb3yDnsF1glVRwco2tOtVEyVIjCAIImyYFhhuuukm/OAHP8Djjz9eqEtdL9xzzz2IRqO49dZbMTg4iL322gsvvPBC4c29lsHBQbz55pu46aabqm735ZdfBgC89tpreO2110Z9X5pL4NNPP8V+++0HQAkf6OjowB577IGf//znOPjgg60cWlnWrFmDr33ta6OWH3zwwbjmmmvw6KOP4kc/+tGoydn48eMdD5Uo5bbbbsNrr72Gm266qWwCRS16FRyA6rka1NwOsVgMbW1t2GmnnXDNNdfg3HPPLYgLPT09ePnll3H00UfriguAUhf+mmuuwSOPPFJRYACASy65BPfeey9++MMf4pRTToEoitUOjyAIwnVeeOEFLFiwAPfffz8YYzjmmGNw9913j/IkWLx4MXbbbbeiHDXl2G677fD+++/j5z//ORYtWoT7778fmUwGkyZNwkEHHYQ//elPRWWwv/Wtb+HLX/4y7rrrLtx2223o6upCNBrF9ttvj1NPPbUof1EikcArr7yCp556Co8//jjOO+889Pf3Y8yYMdh7773x6KOPVqxyQdQGTogHblGtbUbbTkIEQRBBgXEDmfDUclMqH3/8MTjn6OzsHFUu8f3333e+lQ7S39+P1tZW9PX1oaWlBQCQzWYhSxIAYO999sGhhx6Ke+65x9Z+HnnkEVx22WVYs2ZNVQ8GgjDDihUrsPfee2P5smX40pe+5HdzCIJwkGg0CnEkhEpvvLKLdpuxkvH7zTffxNHHHIPPPvuskCDR6j4mT56Mu+66C9/61rfsNjl0nHbaaVi7di1eo0S9tvBTFODdq13bNptg/d6yAgkPRNhIJJOujn+/GDMDSWbuxV2aS7iw9yNH21PLGPJgOP74411uRm2Rz+dx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9eOi5B3nS/P/Xb9+/UL7c3GOHDmCadOmYffu3UhOTobJZMKxY8fw4YcfOrYpOM5YsGABRo0ahe3bt0Ov1yMzMxPffPON01KWt/p8kZGRGD16dKk/H5WPihxjFKWy+nNBRa0kV1DBFSXmzZuH8+fP48KFC1iwYIHj/ry+WhT2Z6owlZYrQcWy2+2iadOmjvSk/fv3F7nt5s2bhVarLTT9KjIyUsTHxzu2/fzzzwvdruBt6dKl5f55ikoPy7up1Wqxfv16x/YFi+cUduvSpYvIyclxbP/EE08Uu71Op3NKGaPKUVxBOABi1qxZjm1v1UcCAwPFmTNnHNu7qi8L4Zw6WdQtb1oS+3LNcav/87xpBezLksKmSAghpa6HhYU5PZdTJCpPRfXjwlLK8zz44INOz62Ioni36steXl7i0KFDju0L9s/CbkOGDHEqqFtUUdK4uDjh5ubm9FymlFeOihxjuLo/59mzZ4/jfVq0aFHstgULv994GzdunNO27M9UmZjBUEWsX78eZ86cAQD07t0bHTt2LHLbO+64A3v37sVDDz3kWHYnIiICL730Ev777z8EBwc7tr3zzjuxcOFC3HPPPWjYsCG8vb2hUCgQGBiIwYMH49dff8XYsWPL/fP4+flh3LhxaN++PQICAqBUKuHm5oaoqCiMHj0aBw8exF133eXYvn///pgzZw569uyJsLAwqFQqeHh4oFOnTnj33XedUocBYPLkyZg5cyZ69eqFevXqwc3NDSqVCnXr1sXw4cOxd+9edOjQodw/FxXvhRdeQN++fREaGgq1Wg21Wo26deviwQcfxLp16/DWW285tg0JCcGHH36Iu+++G/Xr14dOp4NWq0VUVBQmTZqEY8eOISoqyrG9q/pyabEv1z7sy8XT6XSYPXt2JbSYyqK0/bg4eQXkKlLDhg0xatQotGrVCn5+flAoFPDw8ECrVq0wceJEHD16FO3atXNsP2zYMEybNg2dOnVCcHAwlEolvL290atXL3z++ef45Zdfii2KlyckJAQTJkyoyI9GRajIMUZxKqM/53n//fcdPxeVvZBn+fLl+Pzzz9GpUye4ubnBzc0NnTp1whdffFFsAd6C2J+pIsiEKEXODhERERERERFRIZjBQERERERERERlxgADEREREREREZUZAwxEREREREREVGYMMBARERERERFRmTHAQERERERE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ptSrV0+55pprlIyMjDzbXi4OCvqZKIqifPnll0r9+vWVxx57TOnTp88l2ygqvko5gkEIIYQQQoj8GI1Gnn/+eUaNGoVer6dTp06cOXOGHTt2MGLEiFzbBgcH88gjj/Dcc88RGRlJjRo1GDt2LNnZ2f5te/TowQ8//ED//v2JiIjg1VdfRaM5N0rMbDYzYsQInnvuOaKiooiLi+Pll1++bCG/i4mIiCAqKopvv/2WhIQEjh49ygsvvFCk411unzlq1arFmjVrOHz4MGaz+aJLON51113079+fHTt2MHToUP/jISEhPPvsszz11FN4vV46d+5MZmYmq1atwmw2+2tiFNbl9jts2LCAvr/LtWX48OH+mImNjWX06NGo1eqLTitISkpi3bp1/PnnnwU+TrVq1ViyZAndu3enT58+zJs3j7CwMP/zl4uDgv7Owff7fPbZZxk/fjyTJ08u+IchKiRJMAghhBBCCHGeV199Fa1Wy2uvvcbJkydJSEjg4Ycfznfb999/H6/Xy7Bhw7BYLLRp04Z58+YREREB+FakOHjwIDfeeCNhYWG89dZbHDp0KNc+PvjgA7KyshgwYAAhISE888wzZGTkXTa8INRqNVOnTuWJJ56gadOmNGzYkM8++yxX0b3CHq8g+wR49tlnGT58OE2aNMFms+V5nzl69OhBZGQke/bsYciQIbmee+utt4iNjeW9997j4MGDhIeH06pVK1566aUr+jwKst9Av7/L+eijj3j44Ye58cYbCQ0NZdSoURw7dgyjMf+psrNmzaJ9+/bExsYW6jhVq1Zl6dKldO/end69ezN//nzCw8P9z18qDgr6mQCEhoZyyy238PfffzNo0KBCtVFUPCpFKeqCiUIIIYQQQgghroTVaqVq1ar873//yzNKBnw1ODp37syoUaNKoXUF07t3bxo3bsxnn31W2k0RpUxGMAghhBBCCCFECdm0aRO7d++mXbt2ZGRk8OabbwIwcODAfLfv3Lkzd955Z0k2scBSU1OZP38+ixYt4osvvijt5ogyQBIMQgghhBBCCFGCPvzwQ/bs2YNer6d169YsX76c6OjofLctyyMXWrVqRVpaGmPGjLnsUpuicpApEkIIIYQQQgghhCiyKytPK4QQQgghhBBCCHEeSTAIIYQQQgghhBCiyCTBIIQQQgghhBBCiCKTBIMQQgghhBBCCCGKTBIMQgghhBBCCCGEKDJJMAghhBBCCCGEEKLIJMEghBBCCCGEEEKIIpMEgxBCCCGEEEIIIYpMEgxCCCGEEEIIIYQoMkkwCCGEEEIIIYQQosgkwSCEEEIIIYQQQogikwSDEEIIIYQQQgghikwSDEIIIYQQQgghhCiy/wdigaKxr81ysQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "<Figure size 1200x800 with 8 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "clev=0.5*np.delete(1.0*np.linspace(-1,1,21),10) # contour levels, remove 0\n", + "\n", + "# restrict plot to levels above 600 hPa\n", + "dcrh_clca = dcrh_clca.sel(lev=slice(600e2, 0))\n", + "dcrh_cccm = dcrh_cccm.sel(lev=slice(600e2, 0))\n", + "\n", + "def _make_niceaxes_contour(ax):\n", + " plt.ylim(600,10)\n", + " plt.yticks([600,400,200],[\" \", \" \", \" \"], size=10);\n", + " plt.xlim(-83,83)\n", + " plt.xticks([-60,-30,0,30,60],[\"60S\", \"30S\", \"Eq\", \"30N\", \"60N\"], size=10, va=\"top\");\n", + " ax.tick_params(direction=\"in\", length=4)\n", + " plt.xlabel(\"latitude / deg\", size=10, loc=\"right\")\n", + "\n", + "def _plot_crh_singledata(_crh, linestyle=\"-\"):\n", + " plt.plot(_crh, _crh.lev/100, color=\"royalblue\", linestyle=linestyle)\n", + " plt.yticks([800,600,400,200],[\"800\", \"600\",\"400\",\"200\"], size=6);\n", + " return\n", + "\n", + "def _make_niceaxes_profile(ax, xlim=[-0.2,0.2]):\n", + " # adjust spines\n", + " ax.spines[\"top\"].set_color(\"none\")\n", + " ax.spines[\"right\"].set_color(\"none\")\n", + " ax.spines[\"left\"].set_color(\"none\")\n", + " ax.xaxis.set_ticks_position(\"bottom\")\n", + " ax.spines[\"bottom\"].set_position((\"data\",620))\n", + " ax.spines[\"top\"].set_position((\"data\",-100))\n", + " ax.spines[\"right\"].set_position((\"data\",xlim[1]+0.03))\n", + " ax.yaxis.tick_left()\n", + " ax.yaxis.set_label_position(\"left\")\n", + " plt.xticks([-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,0.3,0.4,0.5], \n", + " [\"\",-0.4,\"\",-0.2,\"\",0,\"\",0.2,\"\",0.4,\"\"], fontsize=10)\n", + " plt.xlim(xlim[0], xlim[1])\n", + " plt.ylim(620,-100)\n", + " plt.yticks([ ], fontsize=10) \n", + " plt.plot([0,0], [600,10], linewidth=0.7, color=\"k\", zorder=-10)\n", + " ticklength=0.04*np.abs(xlim[1]-xlim[0])\n", + " for ypos in [600,400,200,10]:\n", + " plt.plot([-0.5*ticklength,0.5*ticklength], [ypos,ypos], linewidth=0.7, color=\"k\", zorder=-10) \n", + "\n", + " \n", + "fig = plt.figure(figsize=(12,8))\n", + "gs = GridSpec(2, 52, figure=fig)\n", + "\n", + "ax1 = fig.add_subplot(gs[0, 1:25])\n", + "cnt=plt.contourf(dcrh_clca.lat, dcrh_clca.lev/100, dcrh_clca, levels=clev, cmap=\"RdBu_r\")\n", + "for c in cnt.collections: c.set_edgecolor(\"face\")\n", + "_make_niceaxes_contour(ax1)\n", + "plt.ylabel(\"pressure / hPa\", loc=\"top\", fontsize=10)\n", + "plt.yticks([600,400,200,10], [\"600\", \"400\", \"200\", \"10\"], fontsize=10)\n", + "ax1.text(0.03,0.96, \"a) 2B-FLXHR-LIDAR\", ha=\"left\", va=\"top\", transform=ax1.transAxes, backgroundcolor=\"white\", \n", + " size=12, bbox=dict(facecolor=\"white\", edgecolor=\"k\", boxstyle=\"round,pad=0.3\"))\n", + "\n", + "ax2 = fig.add_subplot(gs[0, 26:50])\n", + "cnt=plt.contourf(dcrh_cccm.lat, dcrh_cccm.lev/100, dcrh_cccm, levels=clev, cmap=\"RdBu_r\")\n", + "for c in cnt.collections: c.set_edgecolor(\"face\")\n", + "_make_niceaxes_contour(ax2)\n", + "ax2.text(0.03,0.96, \"b) CCCM\", ha=\"left\", va=\"top\", transform=ax2.transAxes, backgroundcolor=\"white\", \n", + " size=12, bbox=dict(facecolor=\"white\", edgecolor=\"k\", boxstyle=\"round,pad=0.3\"))\n", + "\n", + "ax3 = fig.add_subplot(gs[1, 1:10])\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_clca, lats=-70, latn=-35))\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_cccm, lats=-70, latn=-35), linestyle=\"--\")\n", + "_make_niceaxes_profile(ax3, xlim=[-0.25,0.25])\n", + "plt.yticks([600,400,200,10], [600,400,200,10], fontsize=10)\n", + "plt.text(0.5, 0.92, \"70S - 35S\", fontsize=12, fontweight=\"bold\", \n", + " ha=\"center\" , va=\"center\", transform=ax3.transAxes)\n", + "plt.xlabel(\"solid: 2B-FLXHR-LIDAR\", fontsize=10, fontweight=\"bold\", color=\"royalblue\", loc=\"left\")\n", + "\n", + "ax4 = fig.add_subplot(gs[1, 11:20])\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_clca, lats=-35, latn=-15))\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_cccm, lats=-35, latn=-15), linestyle=\"--\")\n", + "_make_niceaxes_profile(ax4, xlim=[-0.25,0.25])\n", + "plt.text(0.5, 0.92, \"35S - 15S\", fontsize=12, fontweight=\"bold\", \n", + " ha=\"center\" , va=\"center\", transform=ax4.transAxes)\n", + "plt.xlabel(\"dashed: CCCM\", fontsize=10, fontweight=\"bold\", color=\"royalblue\", loc=\"right\")\n", + "\n", + "ax5 = fig.add_subplot(gs[1, 21:30])\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_clca, lats=-15, latn=+15))\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_cccm, lats=-15, latn=+15), linestyle=\"--\")\n", + "_make_niceaxes_profile(ax5, xlim=[-0.4,0.4])\n", + "plt.text(0.5, 0.92, \"15S - 15N\", fontsize=12, fontweight=\"bold\", \n", + " ha=\"center\" , va=\"center\", transform=ax5.transAxes)\n", + "\n", + "ax6 = fig.add_subplot(gs[1, 31:40])\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_clca, lats=+15, latn=+35))\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_cccm, lats=+15, latn=+35), linestyle=\"--\")\n", + "_make_niceaxes_profile(ax6, xlim=[-0.25,0.25])\n", + "plt.text(0.5, 0.92, \"15N - 35N\", fontsize=12, fontweight=\"bold\", \n", + " ha=\"center\" , va=\"center\", transform=ax6.transAxes)\n", + "\n", + "ax7 = fig.add_subplot(gs[1, 41:50])\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_clca, lats=+35, latn=+70))\n", + "_plot_crh_singledata(hlp.compute_domainmean(dcrh_cccm, lats=+35, latn=+70), linestyle=\"--\")\n", + "_make_niceaxes_profile(ax7, xlim=[-0.25,0.25])\n", + "plt.xlabel(r\"cloud-radiative heating / K$\\,$day$^{-1}$\", size=10, loc=\"right\");\n", + "plt.text(0.5, 0.92, \"35N - 70N\", fontsize=12, fontweight=\"bold\", \n", + " ha=\"center\" , va=\"center\", transform=ax7.transAxes)\n", + "\n", + "# plot colorbar\n", + "# solution taken and adapted from https://stackoverflow.com/a/62436015\n", + "ax8 = fig.add_subplot(gs[0, 51])\n", + "cb = mpl.colorbar.ColorbarBase(ax8, orientation=\"vertical\", \n", + " cmap=\"RdBu_r\", ticks=[-0.5, -0.25, 0.0, 0.25, 0.5],\n", + " label=\"K/day\",\n", + " boundaries=clev, norm=mpl.colors.Normalize(clev[0], clev[-1])) \n", + "cb.ax.set_yticklabels([\"-0.5\", \"-0.25\", \"0\", \"0.25\", \"0.5\"])\n", + "cb.ax.tick_params(labelsize=10)\n", + "cb.set_label(label=\"K/day\", size=10)\n", + "\n", + "plt.savefig(\"./figures/obs_prediction.pdf\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp2023.1 - 3.10.9", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/plots4paper/obtain_betavalue_for_obs_prediction.ipynb b/plots4paper/obtain_betavalue_for_obs_prediction.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..467e989f6e5b6a10078f4d7c4c7b6e4f84845226 --- /dev/null +++ b/plots4paper/obtain_betavalue_for_obs_prediction.ipynb @@ -0,0 +1,193 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aeb40072-b961-441e-a071-871b3b654a72", + "metadata": {}, + "source": [ + "# Obtain value of $\\beta$ for prediction based on satellite-based estimates of CRH and upward shift\n", + "\n", + "To this end, calculate global mean warming at PBL top. Used in obs_prediction.ipynb" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3a783296-8252-4157-a88d-71cbcab0d9f8", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import xarray as xr\n", + "import matplotlib.pyplot as plt \n", + "\n", + "import helpers as hlp" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "51b009ff-90a7-4e0b-9051-1898cea6b0f4", + "metadata": {}, + "outputs": [], + "source": [ + "# use models that have amip-p4k and amip-future4K temperature, these are the same models \n", + "models = hlp.models_amipp4K\n", + "\n", + "ta_amip = list();\n", + "ta_p4K = list();\n", + "ta_f4K = list();\n", + "[ta_amip.append(hlp.ta_Amon_ymonmean(mod=mod, exp=\"amip\")[\"ta\"].mean([\"month\", \"lon\"]).persist()) for mod in models];\n", + "[ta_p4K.append(hlp.ta_Amon_ymonmean(mod=mod, exp=\"amip-p4K\")[\"ta\"].mean([\"month\", \"lon\"]).persist()) for mod in models];\n", + "[ta_f4K.append(hlp.ta_Amon_ymonmean(mod=mod, exp=\"amip-future4K\")[\"ta\"].mean([\"month\", \"lon\"]).persist()) for mod in models];" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b8fce81c-ccf2-4d6d-ad4c-0fc9e34ce6c7", + "metadata": { + "jp-MarkdownHeadingCollapsed": true + }, + "outputs": [], + "source": [ + "def globalmean(data):\n", + " weights = np.cos(np.deg2rad(data.lat))\n", + " weights.name = \"weights\"\n", + " data_weighted = data.sel(lat=slice(-70,70)).weighted(weights)\n", + " return data_weighted.mean(\"lat\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "e8ea9e77-decd-4dce-b1ee-896b2e5c3615", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, 'pressure / hPa')" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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4J4cO66//nqmT5+e3IFatL/33nuPMWPG8KMf/YicnBxGjhzJc88919HdEvUklIgOU1lZSTweb3JjxNzcXEpLSzuoV8cmpRS33XYbkydPZsiQIR3dnWPCq6++yrJly6QieIRt2bKFp556ir59+/LJJ5/wf//3f9x0003861//6uiuCTrxXYLFsUPTtEbfK6WaHBPt64YbbuC7777j66+/7uiuHBN27tzJzTffzKefforNZuvo7hxTdF1nzJgxzJw5E4CRI0eyevVqnnrqKS699NIO7p2QSonoMFlZWRiNxiZVkfLy8ibVE9F+brzxRt577z2++OILunfv3tHdOSYsXbqU8vJyRo8ejclkwmQyMXfuXP7yl79gMpmIx+Md3cWjVn5+PoMGDWp0bODAgTK5vpOQUCI6jMViYfTo0cyaNavR8VmzZjFx4sQO6tWxQynFDTfcwFtvvcXnn39OcXFxR3fpmHHyySezcuVKVqxYkfwaM2YMP/3pT1mxYgVGo7Gju3jUmjRpUpOl7xs2bKCwsLCDeiT2JcM3okPddtttXHLJJYwZM4YJEybw7LPPsmPHDv7v//6vo7t21Lv++ut55ZVXePfdd3G5XMmKVWpqKna7vYN7d3RzuVxN5u44nU4yMzNlTk87u/XWW5k4cSIzZ87kggsuYPHixTz77LM8++yzHd01gSwJFp3Ak08+ycMPP0xJSQlDhgzhsccekyWpR8CB5u3885//5LLLLjuynRFMnTpVlgQfIR988AF33nknGzdupLi4mNtuu42rr766o7slkFAihBBCiE5C5pQIIYQQolOQUCKEEEKITkFCiRBCCCE6BQklQgghhOgUJJQIIYQQolOQUCKEEEKITkFCiRBCCCE6BQklQgghhOgUJJQIIcQ+5syZg6Zp1NbWdnRXhDjmSCgRohOYOnUqt9xyS0d344i47777GDFiREd346g3Z84c8vPzaW7T7uaC1549exgyZAiTJ0+WQCY6jIQSIUSbiEQiR/T1lFLEYrEj+ppdyXvvvcfZZ599wHsc7Wvz5s1MnjyZnj178umnn5KWltb+HRSiGRJKhOhgl112GXPnzuXPf/4zmqahaRrbtm0DYM2aNZx55pmkpKSQm5vLJZdcQmVlZfK5U6dO5cYbb+SWW24hPT2d3Nxcnn32Wfx+P5dffjkul4vevXvz0UcfJZ/T8K/kDz/8kOHDh2Oz2Rg3bhwrV65s1K/58+dzwgknYLfb6dGjBzfddBN+vz/5eFFREb/73e+47LLLSE1NTd7Q7I477qBfv344HA569erF3XffTTQaBeCFF17g/vvv59tvv01e6wsvvMC2bdvQNI0VK1Ykz19bW4umacyZM6dRvz/55BPGjBmD1Wrlq6++QinFww8/TK9evbDb7QwfPpw333zzoO95OBzmV7/6FT169MBqtdK3b1+ef/75Rm2WLl3KmDFjcDgcTJw4sdHt7jdv3sw555xDbm4uKSkpHHfcccyePbvR84uKipg5cyZXXHEFLpeLnj17NrkT7fz58xkxYgQ2m40xY8bwzjvvNHkfDvUzcCANoeRQvvvuOyZPnsy4ceN49913cTgch3yOEO1GCSE6VG1trZowYYK6+uqrVUlJiSopKVGxWEzt2bNHZWVlqTvvvFOtXbtWLVu2TJ166qnqxBNPTD53ypQpyuVyqQceeEBt2LBBPfDAA8pgMKgzzjhDPfvss2rDhg3q5z//ucrMzFR+v18ppdQXX3yhADVw4ED16aefqu+++07NmDFDFRUVqUgkopRS6rvvvlMpKSnqscceUxs2bFDz5s1TI0eOVJdddlnytQsLC5Xb7VZ//OMf1caNG9XGjRuVUko98MADat68eWrr1q3qvffeU7m5ueqhhx5SSikVCATUL37xCzV48ODktQYCAbV161YFqOXLlyfPX1NTowD1xRdfNOr3sGHD1Keffqo2bdqkKisr1a9//Ws1YMAA9fHHH6vNmzerf/7zn8pqtao5c+Yc8D2/4IILVI8ePdRbb72lNm/erGbPnq1effXVRq8zbtw4NWfOHLV69Wp1/PHHq4kTJyafv2LFCvX000+r7777Tm3YsEHdddddymazqe3btzd6fzIyMtTf/vY3tXHjRvXggw8qg8Gg1q5dq5RSyuPxqIyMDHXxxRer1atXq//973+qX79+jd6HlvwMNGfVqlXK6XSqYDDY7OMN1/jhhx+qtLQ0dd1116l4PH7QcwpxJEgoEaITmDJlirr55psbHbv77rvVtGnTGh3buXOnAtT69euTz5s8eXLy8VgsppxOp7rkkkuSx0pKShSgFixYoJTa+4HU8CGslFJVVVXKbrer1157TSml1CWXXKKuueaaRq/91VdfKYPBkPygKywsVOeee+4hr+3hhx9Wo0ePTn5/7733quHDhzdq05pQ8s477yTb+Hw+ZbPZ1Pz58xud78orr1QXXnhhs/1Zv369AtSsWbOafbzhdWbPnp089uGHHyrggB/ySik1aNAg9cQTTyS/LywsVBdffHHye13XVU5OjnrqqaeUUko99dRTKjMzs9E5n3vuuUbvQ0t+Bprz+9//Xv3gBz844OMN12ixWBr9rAjR0UxHuDAjhGihpUuX8sUXX5CSktLksc2bN9OvXz8Ahg0bljxuNBrJzMxk6NChyWO5ubkAlJeXNzrHhAkTkn/PyMigf//+rF27NvnamzZt4uWXX062UUqh6zpbt25l4MCBAIwZM6ZJ3958800ef/xxNm3ahM/nIxaL4Xa7W339B7Lva65Zs4ZQKMSpp57aqE0kEmHkyJHNPn/FihUYjUamTJly0NfZ933Nz88HEu9hz5498fv93H///XzwwQfs2bOHWCxGMBhkx44dBzyHpmnk5eUl/zusX7+eYcOGYbPZkm3Gjh3b6Pkt/RnY37vvvst111130OsDOOecc3j77bf56quvOP744w/ZXoj2JqFEiE5K13XOOussHnrooSaPNXxIApjN5kaPaZrW6FjDREdd1w/5mvu2vfbaa7npppuatOnZs2fy706ns9FjCxcu5Cc/+Qn3338/p512Gqmpqbz66qs88sgjB31dgyExvU3ts1KkYR7K/vZ9zYZr+vDDD+nWrVujdlartdnn2+32g/alwcHew1/+8pd88skn/OlPf6JPnz7Y7XbOP//8JpN9m/tv03AOpVSTSahqv5UyLf0Z2FdpaSnLli1j+vTph7zGZ555hjvuuIMzzjiDDz/88JBBTYj2JqFEiE7AYrEQj8cbHRs1ahT//e9/KSoqwmRq+/9VFy5cmAwYNTU1bNiwgQEDBiRfe/Xq1fTp06dV55w3bx6FhYXcddddyWPbt29v1Ka5a83OzgagpKQkWeHYd7LngQwaNAir1cqOHTta/IE6dOhQdF1n7ty5nHLKKS16zv6++uorLrvsMs477zwAfD5fcnJySw0YMICXX36ZcDicDFDffPNNozaH8zPw3nvvMWHCBLKysg7ZVtM0nnnmGYxGI2eeeSYffvghU6dObdV1CNGWZPWNEJ1AUVERixYtYtu2bVRWVqLrOtdffz3V1dVceOGFLF68mC1btvDpp59yxRVXNPlQPxy//e1v+eyzz1i1ahWXXXYZWVlZnHvuuUBiBc2CBQu4/vrrWbFiBRs3buS9997jxhtvPOg5+/Tpw44dO3j11VfZvHkzf/nLX3j77bebXOvWrVtZsWIFlZWVhMNh7HY748eP5w9/+ANr1qzhyy+/5De/+c0hr8HlcnH77bdz66238uKLL7J582aWL1/O3/72N1588cVmn1NUVMTPfvYzrrjiCt555x22bt3KnDlzeP3111v2xtVf51tvvcWKFSv49ttvueiii1pUidpXw3OuueYa1q5dm6y8wN7KzOH8DLz33nucc845Le6Hpmk8+eSTXH755UyfPp3PP/+8VdchRFuSUCJEJ3D77bdjNBoZNGgQ2dnZ7Nixg4KCAubNm0c8Hue0005jyJAh3HzzzaSmpiaHO76PP/zhD9x8882MHj2akpIS3nvvPSwWC5CYCzF37lw2btzI8ccfz8iRI7n77rsPOGTQ4JxzzuHWW2/lhhtuYMSIEcyfP5+77767UZsf/vCHnH766Zx44olkZ2fzn//8B4B//OMfRKNRxowZw80338zvfve7Fl3HAw88wD333MODDz7IwIEDOe2003j//fcpLi4+4HOeeuopzj//fK677joGDBjA1Vdf3Wi586E89thjpKenM3HiRM466yxOO+00Ro0a1eLnA7jdbt5//31WrFjBiBEjuOuuu7jnnnsAkvNMWvsz4Pf7+eyzz1q0FHhfmqbx17/+lauuuooZM2Y0Wd4sxJGiqf0HMYUQR7U5c+Zw4oknUlNTI5tkdTIvv/wyl19+OXV1dS2e+7Kvt956i9/85jesWbOmHXonRPuTOSVCCNFB/vWvf9GrVy+6devGt99+yx133MEFF1xwWIEEICUlpdlJsUJ0FRJKhBCig5SWlnLPPfdQWlpKfn4+P/rRj/j9739/2OebNm1aG/ZOiCNPhm+EEEII0SnIRFchhBBCdAoSSoQQQgjRKUgoEUIIIUSnIKFECCGEEJ2ChBIhhBBCdAoSSoQQQgjRKUgoEUIIIUSnIKFECCGEEJ2ChBIhhBBCdAoSSoQQQgjRKUgoEUIIIUSnIKFECCGEEJ2ChBIhhBBCdAoSSoQQQgjRKUgoEUIIIUSnIKFECCGEEJ2ChBIhhBBCdAoSSoQQQgjRKUgoEUIIIUSnIKFEiKNQUVERl112WZuf97XXXmPw4MHY7XY0TWPFihUtfm4gEOC+++5jzpw5bd6v72PNmjVYrVY0TeObb75p9Nh9992HpmlUVlY2Or5582Z69epFbm5uq96DzqLhuoTobEwd3QEhRNt7++23cbvdbXrOiooKLrnkEk4//XSefPJJrFYr/fr1a/HzA4EA999/PwBTp05t074drng8zhVXXEFWVhZ79uxp0XNWrlzJaaedhtls5uuvv6Zv377t3Mu2d9VVV3H66ad3dDeEaEIqJUIchUaOHEnv3r3b9JwbNmwgGo1y8cUXM2XKFMaPH4/D4WjT1zgcSimCweBhPfexxx5j165d3HHHHS1qv3DhQqZMmUJqairz5s3rkoEEoHv37owfP76juyFEExJKhDhCNm3axOWXX07fvn1xOBx069aNs846i5UrVzZqN2fOHDRN45VXXuGOO+4gPz+flJQUzjrrLMrKyvB6vVxzzTVkZWWRlZXF5Zdfjs/na3SO/YdvGs750ksvcdttt5GXl4fdbmfKlCksX778kH2/7LLLmDx5MgA//vGP0TQtWe2YOnVqs5WPyy67jKKiIgC2bdtGdnY2APfffz+apqFpWrKP+7bdV3PDDJqmccMNN/D0008zcOBArFYrL774IgAbN27koosuIicnB6vVysCBA/nb3/7W7DVt3LiRe+65hyeffLJFVaVZs2Zxyimn0Lt3b7766iu6d+9+yOe01v3338+4cePIyMjA7XYzatQonn/+eZRSjdoVFRUxY8YMPvjgA0aOHIndbmfgwIF88MEHALzwwgsMHDgQp9PJ2LFjDzgs1dw53377bYYNG4bNZqNXr1785S9/afPrFOJAZPhGiCNkz549ZGZm8oc//IHs7Gyqq6t58cUXGTduHMuXL6d///6N2v/617/mxBNP5IUXXmDbtm3cfvvtXHjhhZhMJoYPH85//vMfli9fzq9//WtcLleLPjx+/etfM2rUKP7+979TV1fHfffdx9SpU1m+fDm9evU64PPuvvtuxo4dy/XXX8/MmTM58cQTWzU8lJ+fz8cff8zpp5/OlVdeyVVXXQWQDCqt9c477/DVV19xzz33kJeXR05ODmvWrGHixIn07NmTRx55hLy8PD755BNuuukmKisruffee5PPV0px1VVXMWPGDM4++2xeeOGFg77ef//7X2666SYmTpzIe++9h8vlOqx+H8q2bdu49tpr6dmzJ5CozNx4443s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czRKURd2u1159tlnFbvd3tRdaXPkZ9905GfftOTn3/yoFOUM53OEEEIIIc6BZrunRAghhBBti4QSIYQQQjQLEkqEEEII0SxIKBFCCCFEsyChRDS59957jw4dOhAQEMCAAQP45ZdfmrpLbcLMmTMZNGgQwcHBxMTEMHnyZPbt29fU3WqTZs6ciUqlYvr06U3dlTbh2LFj3HjjjURGRmIymejbty8ZGRlN3S2BhBLRxObPn8/06dN58skn2bJlC6NGjeLiiy8mOzu7qbvW6q1atYp7772XdevWsWzZMtxuNxMmTMBisTR119qUjRs3MmvWLHr37t3UXWkTysrKGDFiBDqdjh9++IHdu3fz2muvScXuZkKOBIsmNWTIEPr378/777/vf6179+5MnjyZmTNnNmHP2p6ioiJiYmJYtWoVo0ePburutAlms5n+/fvz3nvv8eKLL9K3b1/efPPNpu5Wq/b444/z66+/yoxsMyUzJaLJOJ1OMjIymDBhQq3XJ0yYQHp6ehP1qu2qqKgAICIiool70nbce++9TJw40V+BWjS+RYsWMXDgQK655hpiYmLo168fH330UVN3S1STUCKaTHFxMR6P54SLEWNjY8nPz2+iXrVNiqLw0EMPMXLkSNLS0pq6O23CF198webNm2VG8Bw7fPgw77//Pqmpqfz444/86U9/4oEHHuCzzz5r6q4JmvEtwaLtUKlUtb5XFOWE10Tjuu+++9i+fTtr1qxp6q60CTk5OfzlL39h6dKlBAQENHV32hSv18vAgQOZMWMGAP369WPXrl28//773HzzzU3cOyEzJaLJREVFodFoTpgVKSwsPGH2RDSe+++/n0WLFvHzzz/Trl27pu5Om5CRkUFhYSEDBgxAq9Wi1WpZtWoVb7/9NlqtFo/H09RdbLXi4+Pp0aNHrde6d+8um+ubCQklosno9XoGDBjAsmXLar2+bNkyhg8f3kS9ajsUReG+++7j66+/ZsWKFXTo0KGpu9RmjBs3jh07drB161b/18CBA7nhhhvYunUrGo2mqbvYao0YMeKEo+/79+8nJSWliXokfkuWb0STeuihh7jpppsYOHAgw4YNY9asWWRnZ/OnP/2pqbvW6t17773MmzePb775huDgYP+MVWhoKEajsYl717oFBwefsHcnMDCQyMhI2dPTyB588EGGDx/OjBkzmDJlChs2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\n", + "text/plain": [ + "<Figure size 600x1200 with 2 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "lev = 1e-2*ta_amip[0].lev\n", + "\n", + "plt.figure(figsize=(6,12))\n", + "plt.subplot(2,1,1)\n", + "for imod in range(len(models)):\n", + " plt.plot(globalmean(ta_p4K[imod]-ta_amip[imod]), lev)\n", + "plt.ylim(1000,10)\n", + "plt.title(\"amip-p4K - amip\")\n", + "plt.xlabel(\"temperature change / K\")\n", + "plt.ylabel(\"pressure / hPa\")\n", + "\n", + "plt.subplot(2,1,2)\n", + "for imod in range(len(models)):\n", + " plt.plot(globalmean(ta_p4K[imod]-ta_amip[imod]), lev)\n", + "plt.ylim(1000,10)\n", + "plt.title(\"amip-future4K - amip\")\n", + "plt.xlabel(\"temperature change / K\")\n", + "plt.ylabel(\"pressure / hPa\")" + ] + }, + { + "cell_type": "markdown", + "id": "f1782704-cf45-48eb-9220-34abcd78572d", + "metadata": {}, + "source": [ + "Print temperature change at 800 hPa." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "80169e56-c28a-44cd-9c33-29e5cf4316b3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "amip-p4K - amip at 800 hPa: 4.910535836258547\n", + "amip-p4K - amip at 800 hPa: 4.880575414751951\n", + "amip-p4K - amip at 800 hPa: 4.917599325847588\n", + "amip-p4K - amip at 800 hPa: 4.992085567635118\n", + "amip-p4K - amip at 800 hPa: 4.537515753631762\n", + "amip-p4K - amip at 800 hPa: 4.910300527333427\n", + "amip-p4K - amip at 800 hPa: 4.7872367999810725\n", + "Model mean for amip-p4K: 4.847978460777066\n", + " \n", + "amip-future4K - amip at 800 hPa: 5.321209353243598\n", + "amip-future4K - amip at 800 hPa: 5.219394083266343\n", + "amip-future4K - amip at 800 hPa: 5.285933035994222\n", + "amip-future4K - amip at 800 hPa: 5.14766068767173\n", + "amip-future4K - amip at 800 hPa: 4.847990491095879\n", + "amip-future4K - amip at 800 hPa: 5.29699929573503\n", + "amip-future4K - amip at 800 hPa: 5.18934954162036\n", + "Model mean for amip-f4K: 5.186933784089595\n" + ] + } + ], + "source": [ + "aux_p4K = list()\n", + "for imod in range(len(models)):\n", + " aux_p4K.append(globalmean(ta_p4K[imod]-ta_amip[imod]).sel(lev=800e2).values)\n", + " print(\"amip-p4K - amip at 800 hPa:\", globalmean(ta_p4K[imod]-ta_amip[imod]).sel(lev=800e2).values)\n", + "print(\"Model mean for amip-p4K:\", np.mean(aux_p4K))\n", + "\n", + "print(\" \")\n", + "\n", + "aux_f4K = list()\n", + "for imod in range(len(models)):\n", + " aux_f4K.append(globalmean(ta_f4K[imod]-ta_amip[imod]).sel(lev=800e2).values)\n", + " print(\"amip-future4K - amip at 800 hPa:\", globalmean(ta_f4K[imod]-ta_amip[imod]).sel(lev=800e2).values)\n", + "print(\"Model mean for amip-f4K:\", np.mean(aux_f4K))" + ] + }, + { + "cell_type": "markdown", + "id": "faa91417-5df9-4589-af2e-e54a47314d15", + "metadata": {}, + "source": [ + "**Conclusion: a warming of 5K at 800 hPa is a good appproximation. 5K lead to a beta value of 1.2.**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nwp2023.1 - 3.10.9", + "language": "python", + "name": "nwp2023.1" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}