Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup codespaces #225

Merged
merged 6 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .devcontainer/Dockerfile.codespace
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM fedora:37

RUN dnf -y update \
&& dnf -y install \
git \
gcc \
gcc-c++ \
gnuplot \
netcdf-devel \
python3 \
python3-pip \
python-devel \
tree \
&& dnf clean all

# COPY . /workspaces/music-box
# WORKDIR /workspaces/music-box
# RUN pip3 install -e '.[dev]'
10 changes: 10 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "MusicBox",
"dockerFile": "Dockerfile.codespace",
"extensions": [
"ms-python.python",
],
"settings": {
},
"postCreateCommand": "cd /workspaces/music-box && pip3 install -e '.[dev]'"
}
57 changes: 23 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,64 +11,53 @@ MusicBox: A MUSICA model for boxes and columns.
Copyright (C) 2020 National Center for Atmospheric Research

# Installation
```
pip install acom_music_box
```

The project is configured to be installed using `pip` by the `pyproject.toml` file.
# Command line tool
MusicBox provides a command line tool that can run configurations as well as some pre-configured examples. Basic plotting can be done if gnuplot is installed.

To install the `music-box` package into a Python environment, run the following command from the root directory:
Checkout the command line options

```
pip install .
music_box -h
```

The package is also available on PyPi and can be installed in any Python environment through:
Run an example. Notice that the output, in csv format, is printed to the terminal.

```
pip install acom_music_box
music_box -e Chapman
```

# Developing

Install music box as an editable installation.
You can also run your own configuration

```
pip install -e '.[dev]'
music_box -c my_config.json
```

After installing music box for local development
Output can be saved to a file

```
pytest
music_box -e Chapman -o output.csv
```

# Command line tool
MusicBox provides a command line tool that can run configurations as well as some pre-configured examples. Basic plotting can be done if gnuplot is installed.
And, if you have gnuplot installed, some basic plots can be made to show some resulting concentrations

```
music_box -h
usage: music_box [-h] [-c CONFIG] [-e {CB5,Chapman,FlowTube,Analytical}] [-o OUTPUT] [-v] [--color-output] [--plot PLOT]
music_box -e Chapman -o output.csv --color-output --plot CONC.O1D
```

MusicBox simulation runner.
# Development and Contributing

optional arguments:
-h, --help show this help message and exit
-c CONFIG, --config CONFIG
Path to the configuration file. If --example is provided, this argument is ignored.
-e {CB5,Chapman,FlowTube,Analytical}, --example {CB5,Chapman,FlowTube,Analytical}
Name of the example to use. Overrides --config.
Available examples:
CB5: Carbon bond 5
Chapman: The Chapman cycle with conditions over Boulder, Colorado
FlowTube: A fictitious flow tube experiment
Analytical: An example of an analytical solution to a simple chemical system
-o OUTPUT, --output OUTPUT
Path to save the output file, including the file name. If not provided, result will be printed to the console.
-v, --verbose Increase logging verbosity. Use -v for info, -vv for debug.
--color-output Enable color output for logs.
--plot PLOT Plot a comma-separated list of species if gnuplot is available (e.g., CONC.A,CONC.B).
For local development, install `music-box` as an editable installation:

```
pip install -e '.[dev]'
```

To run one of the examples and plot something you would run
## Tests

```
music_box -e Chapman -o output.csv -vv --color-output --plot CONC.O1D
pytest
```
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ dependencies = [
"xarray",
"colorlog",
"pandas",
"tqdm"
"tqdm",
"netcdf4"
]

[project.urls]
Expand Down
29 changes: 29 additions & 0 deletions sample_waccm_data/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# WACCM

This is data downloaded from [ACOM's data repository](https://www.acom.ucar.edu/waccm/DATA/). Each file has been reduced to have only ground level data and only chemical species needed for the IGAC demo.
This brings the file size from 8GB per file to 93MB per file, small enough that it can fit in github and be easily used for the demo. This data is temporary and will be removed after the demo.


The script to reduce the data is this:


```
import xarray as xr
import os

keep = ['ALKNIT', 'AODVISdn', 'BCARY', 'BENZENE', 'BIGALD', 'BIGALD1', 'BIGALD2', 'BIGALD3', 'BIGALD4', 'BIGALK', 'BIGENE', 'C2H2', 'C2H4', 'C2H5OH', 'C2H6', 'C3H6', 'C3H8', 'CH2O', 'CH3CHO', 'CH3CN', 'CH3COCH3', 'CH3COCHO', 'CH3COOH', 'CH3OH', 'CH3OOH', 'CH4', 'CHBR3', 'CO', 'CO01', 'CO02', 'CO03', 'CO04', 'CO05', 'CO06', 'CO07', 'CO08', 'CO09', 'CRESOL', 'DMS', 'GLYOXAL', 'H2O', 'H2O2', 'HCN', 'HCOOH', 'HNO3', 'HO2', 'HO2NO2', 'HONITR', 'HYAC', 'ISOP', 'ISOPNITA', 'ISOPNITB', 'MACR', 'MEK', 'MPAN', 'MTERP', 'MVK', 'M_dens', 'N2O', 'N2O5', 'NH3', 'NH4', 'NO', 'NO2', 'NO3', 'NOA', 'O3', 'O3S', 'OH', 'ONITR', 'P0', 'PAN', 'PBZNIT', 'PHENOL', 'PS', 'Q', 'SO2', 'T', 'TERPNIT', 'TOLUENE', 'XYLENES', 'Z3', 'ap', 'bc_a1', 'bc_a4', 'ch4vmr', 'co2vmr', 'date', 'dst_a1', 'dst_a2', 'dst_a3', 'f107', 'f107a', 'f107p', 'f11vmr', 'f12vmr', 'kp', 'mdt', 'n2ovmr', 'ncl_a1', 'ncl_a2', 'ncl_a3', 'num_a1', 'num_a2', 'num_a3', 'pom_a1', 'pom_a4', 'so4_a1', 'so4_a2', 'so4_a3', 'soa1_a1', 'soa1_a2', 'soa2_a1', 'soa2_a2', 'soa3_a1', 'soa3_a2', 'soa4_a1', 'soa4_a2', 'soa5_a1', 'soa5_a2', 'soa_a1', 'soa_a2', 'sol_tsi',]

for root, _, files in os.walk('data'):
for file in files:
file_path = os.path.join(root, file)
ds = xr.open_dataset(file_path)
# Select the second time index and nearest lev, expand both dimensions
ds_sel = ds[keep].isel(time=1).sel(lev=1000.0, method="nearest").expand_dims(['lev', 'time'])
ds_sel.to_netcdf(f'sample_waccm_data/{file}')
```

You can extract a coniguraiton file with

```
waccmToMusicBox waccmDir="./sample_waccm_data" musicaDir="src/acom_music_box/examples/configs/ts1" date="20240904" time="07:00" latitude=3.1 longitude=101.7 template=src/acom_music_box/examples/configs/ts1/
```
Binary file not shown.
49 changes: 21 additions & 28 deletions src/acom_music_box/main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import os
import argparse
from acom_music_box import MusicBox, Examples, __version__
import colorlog
import datetime
import sys
import logging
import colorlog
import os
import subprocess
import sys
import tempfile
from acom_music_box import MusicBox, Examples, __version__


def format_examples_help(examples):
Expand Down Expand Up @@ -59,35 +59,22 @@ def parse_arguments():


def setup_logging(verbosity, color_output):
if verbosity >= 2:
log_level = logging.DEBUG
elif verbosity == 1:
log_level = logging.INFO
else:
log_level = logging.CRITICAL
log_level = logging.DEBUG if verbosity >= 2 else logging.INFO if verbosity == 1 else logging.CRITICAL
datefmt = '%Y-%m-%d %H:%M:%S'
format_string = '%(asctime)s - %(levelname)s - %(module)s.%(funcName)s - %(message)s'
formatter = logging.Formatter(format_string, datefmt=datefmt)
console_handler = logging.StreamHandler()

formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(module)s.%(funcName)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
if color_output:
color_formatter = colorlog.ColoredFormatter(
'%(log_color)s%(asctime)s - %(levelname)s - %(module)s.%(funcName)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
log_colors={
'DEBUG': 'green',
'INFO': 'cyan',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'bold_red'})
console_handler = logging.StreamHandler()
console_handler.setLevel(log_level)
color_formatter = colorlog.ColoredFormatter( f'%(log_color)s{format_string}', datefmt=datefmt,
log_colors={'DEBUG': 'green', 'INFO': 'cyan', 'WARNING': 'yellow', 'ERROR': 'red', 'CRITICAL': 'bold_red'}
)
console_handler.setFormatter(color_formatter)
logging.basicConfig(level=log_level, handlers=[console_handler])
else:
console_handler = logging.StreamHandler()
console_handler.setLevel(log_level)
console_handler.setFormatter(formatter)
logging.basicConfig(level=log_level, handlers=[console_handler])

console_handler.setLevel(log_level)
logging.basicConfig(level=log_level, handlers=[console_handler])


def plot_with_gnuplot(data, species_list):
Expand Down Expand Up @@ -149,6 +136,12 @@ def main():
musicBoxOutputPath = args.output
plot_species_list = args.plot.split(',') if args.plot else None

if not musicBoxConfigFile:
error = "Configuration file is required."
print(error)
logger.error(error)
sys.exit(1)

# Create and load a MusicBox object
myBox = MusicBox()
logger.debug(f"Configuration file = {musicBoxConfigFile}")
Expand Down