Skip to content

Commit

Permalink
Merge 58e95ff into 9984bf7
Browse files Browse the repository at this point in the history
  • Loading branch information
jklenzing committed Jul 5, 2019
2 parents 9984bf7 + 58e95ff commit a56ecce
Show file tree
Hide file tree
Showing 37 changed files with 429,732 additions and 647,471 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ before_install:
install:
- source activate test-environment
- python setup.py install
- make -C sami2py/fortran compile
script:
- nosetests -vs --with-coverage --cover-package=sami2py

Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,12 @@ a local install use the "--user" flag after "install".
python setup.py install
```

Additionally, you must make and install the fortran executables.
If something has gone wrong, you may be prompted to manually install the fortran executables.

```
make -C sami2py/fortran compile
```

Now you can run the sami2 executable (sami2py.x) from anywhere.


# Example

Expand Down
4 changes: 1 addition & 3 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ a local install use the "--user" flag after "install".
cd sami2py/
python setup.py install

Additionally, you must make and install the fortran executables.
If something has gone wrong, you may be prompted to manually install the fortran executables.

::

make -C sami2py/fortran compile

Now you can run the sami2 executable (sami2py.x) from anywhere.
33 changes: 33 additions & 0 deletions docs/sample_workflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,37 @@ Now load the resultant data:
ModelRun = sami2py.Model(tag='run_name', lon=0, year=2012, day=210)
The data is stored as `ModelRun.data`, which is an `xarray.Dataset`. Information about the run is stored as 'ModelRun.MetaData', which is a human-readable dictionary of the namelist.

The MetaData can be accessed directly via the dictionary, or through the __repr__. Typing

.. code:: python
ModelRun
yields

.. code:: python
Model Run Name = test
Day 256, 1999
Longitude = 256 deg
2 time steps from 0.1 to 0.1 UT
Ions Used: H+, O+, NO+, O2+, He+, N2+
Solar Activity
--------------
F10.7: 120.0 sfu
F10.7A: 120.0 sfu
ap: 0
Component Models Used
---------------------
Neutral Atmosphere: NRLMSISe-2000
Winds: HWM-14
Photoproduction: EUVAC
ExB Drifts: Fejer-Scherliess
No modifications to empirical models
Full description coming soon
33 changes: 8 additions & 25 deletions sami2py/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,16 @@
# Full license can be found in License.md
# -----------------------------------------------------------------------------
"""
sami2py
-----------
sami2py - sami2py is another model of the ionosphere python style
=================================================================
Functions
---------------------------------------------------------------------------
run_model(year, day, lat=0, lon=0, alt=300,
f107=120, f107a=120, ap=0,
rmin=100, rmax=2000, gams=3, gamp=3, altmin=85.,
dthr=0.25, hrinit=0., hrpr=24., hrmax=48.,
dt0=30., maxstep=100000000, denmin=1.e-6,
nion1=1, nion2=7, mmass=48, h_scale=1, o_scale=1,
no_scale=1, o2_scale=1, he_scale=1, n2_scale=1, n_scale=1,
Tinf_scale=1, Tn_scale=1., euv_scale=1,
wind_scale=1, hwm_model=14,
fejer=True, ExB_drifts=np.zeros((10,2)), ve01=0., exb_scale=1,
alt_crit=150., cqe=7.e-14,
tag='test', clean=False, test=False)
Sami2py is a python module that runs the SAMI2 model, as well as archives,
loads and plots the resulting modeled values. SAMI2 is a model developed
by the Naval Research Laboratory to simulate the motions of plasma in a
2D ionospheric environment along a dipole magnetic field [Huba et al, 2000].
SAMI2 solves for the chemical and dynamical evolution of seven ion species
in this environment (H+, He+, N+, O+, N2+, NO+, and O2+).
Initializes a run of the SAMI2 model and archives the data.
---------------------------------------------------------------------------
Classes
---------------------------------------------------------------------------
model
Loads, reshapes, and holds SAMI2 output for a given model run
specified by the user.
---------------------------------------------------------------------------
"""
import logging
import sys
Expand Down
49 changes: 22 additions & 27 deletions sami2py/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import os
import subprocess
import numpy as np
from sami2py import fortran_dir
from sami2py import fortran_dir, __version__
from .utils import generate_path


Expand Down Expand Up @@ -252,8 +252,8 @@ def run_model(tag='model_run', lat=0, lon=0, alt=300, year=2018, day=1,
'wind_scale': wind_scale, 'hwm_model': hwm_model}

info['fejer'] = _generate_drift_info(fejer, ExB_drifts)
info['fmtout'] = _generate_format_info(fmtout)
info['outn'] = _generate_neutral_info(outn)
info['fmtout'] = _generate_fortran_bool(fmtout)
info['outn'] = _generate_fortran_bool(outn)
_generate_namelist(info)
archive_path = generate_path(tag, lon, year, day, test)
if not test:
Expand All @@ -268,36 +268,22 @@ def _generate_drift_info(fejer, ExB_drifts=None):
"""Generates the information regarding the ExB drifts used by the model.
This information is later stored in the namelist file for SAMI2
"""
if fejer:
drift_info = '.true.'
else:
drift_info = _generate_fortran_bool(fejer)
if not fejer:
if ExB_drifts.shape != (10, 2):
raise Exception('Invalid ExB drift shape! Must be 10x2 ndarray.')
drift_info = '.false.'
np.savetxt('exb.inp', ExB_drifts)
return drift_info


def _generate_format_info(fmtout):
"""Generates the namelist information needed to tell the SAMI2 model to
output the model results in formatted or unformatted data files
"""
if fmtout:
format_info = '.true.'
else:
format_info = '.false.'
return format_info


def _generate_neutral_info(outn):
"""Generates the namelist information needed to tell the SAMI2 model to
output the model results of neutral species and wind
def _generate_fortran_bool(pybool):
"""Generates a fortran bool as a string for the namelist generator
"""
if outn:
neutral_info = '.true.'
if pybool:
fbool = '.true.'
else:
neutral_info = '.false.'
return neutral_info
fbool = '.false.'
return fbool


def _generate_namelist(info):
Expand Down Expand Up @@ -380,6 +366,7 @@ def _archive_model(path, clean, fejer, fmtout, outn):
If False, then 'exb.inp' is also archived
"""
import shutil
import subprocess

if fmtout:
filelist = ['glonf.dat', 'glatf.dat', 'zaltf.dat',
Expand All @@ -392,19 +379,27 @@ def _archive_model(path, clean, fejer, fmtout, outn):
filelist = ['glonu.dat', 'glatu.dat', 'zaltu.dat',
'deniu.dat', 'vsiu.dat', 'tiu.dat', 'teu.dat',
'time.dat', 'sami2py-1.00.namelist']
if outn:
filelist.append('dennu.dat')
filelist.append('u4u.dat')

if os.path.isfile(filelist[0]):
try:
os.stat(path)
except FileNotFoundError:
os.makedirs(path)

hash = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'])
with open(os.path.join(path, 'version.txt'), 'w+') as f:
f.write('sami2py v' + __version__ + '\n')
f.write('short hash ' + hash.decode("utf-8"))

for list_file in filelist:
shutil.copyfile(list_file, path + list_file)
shutil.copyfile(list_file, os.path.join(path, list_file))
if clean:
for list_file in filelist[:-1]:
os.remove(list_file)
if not fejer:
shutil.copyfile('exb.inp', path + 'exb.inp')
shutil.copyfile('exb.inp', os.path.join(path, 'exb.inp'))
else:
print('No files to move!')
35 changes: 23 additions & 12 deletions sami2py/_core_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"""
from os import path
import numpy as np
import xarray as xr
from .utils import generate_path, get_unformatted_data


Expand Down Expand Up @@ -210,18 +211,27 @@ def _load_model(self):
te = get_unformatted_data(model_path, 'te',
dim0=dim0, dim1=dim1, reshape=True)

self.glat = np.reshape(glat, (nz, nf), order="F")
self.glon = np.reshape(glon, (nz, nf), order="F")
self.zalt = np.reshape(zalt, (nz, nf), order="F")
self.deni = np.reshape(deni, (nz, nf, ni, nt), order="F")
self.vsi = np.reshape(vsi, (nz, nf, ni, nt), order="F")
self.ti = np.reshape(ti, (nz, nf, ni, nt), order="F")
self.te = np.reshape(te, (nz, nf, nt), order="F")
glat = np.reshape(glat, (nz, nf), order="F")
glon = np.reshape(glon, (nz, nf), order="F")
zalt = np.reshape(zalt, (nz, nf), order="F")
deni = np.reshape(deni, (nz, nf, ni, nt), order="F")
vsi = np.reshape(vsi, (nz, nf, ni, nt), order="F")
ti = np.reshape(ti, (nz, nf, ni, nt), order="F")
te = np.reshape(te, (nz, nf, nt), order="F")
self.data = xr.Dataset({'deni': (['z', 'f', 'ion', 'ut'], deni),
'vsi': (['z', 'f', 'ion', 'ut'], vsi),
'ti': (['z', 'f', 'ion', 'ut'], ti),
'te': (['z', 'f', 'ut'], te),
'slt': (['ut'], self.slt)},
coords={'glat': (['z', 'f'], glat),
'glon': (['z', 'f'], glon),
'zalt': (['z', 'f'], zalt),
'ut': self.ut})
if self.outn:
self.denn = np.reshape(denn, (nz, nf, 7, nt), order="F")
self.u = np.reshape(u, (nz, nf, nt), order="F")
del denn, u
del glat, glon, zalt, deni, vsi, ti, te
denn = np.reshape(denn, (nz, nf, 7, nt), order="F")
self.data['denn'] = denn
u = np.reshape(u, (nz, nf, nt), order="F")
self.data['u'] = u

def _generate_metadata(self, namelist):
"""Reads the namelist and generates MetaData based on Parameters
Expand Down Expand Up @@ -345,7 +355,8 @@ def plot_lat_alt(self, time_step=0, species=1):
"""
import matplotlib.pyplot as plt

plt.pcolor(self.glat, self.zalt, self.deni[:, :, species, time_step])
plt.pcolor(self.data['glat'], self.data['zalt'],
self.data['deni'][:, :, species, time_step])
plt.xlabel('Geo Lat (deg)')
plt.ylabel('Altitude (km)')
plt.show()
20 changes: 10 additions & 10 deletions sami2py/fortran/exb.inp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
-2.256592115245508268e+01 -1.700658929016086063e+01
6.970157155494434598e+00 -1.785773092653965932e+01
7.715990594846469097e-01 -1.457794556537672204e+00
1.133009384321719537e+01 6.217447257350539047e+00
5.315180719049175551e+00 6.543500525980066485e+00
-4.754135936133724094e+00 7.493698025175492994e+00
-3.036451049580922046e+00 -1.789034697779917638e+00
-3.791099765373269648e+00 -8.665409647917849956e-01
2.083139968647748308e+00 -3.636326810220660732e+00
2.205828847907577828e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
0.000000000000000000e+00 0.000000000000000000e+00
10 changes: 8 additions & 2 deletions sami2py/fortran/sami2py-1.00.f
Original file line number Diff line number Diff line change
Expand Up @@ -2914,6 +2914,8 @@ subroutine sf1216 ( f,line,nfl )
subroutine open_u
include 'param-1.00.inc'
include 'com-1.00.inc'
! open output files (unformatted, except time.dat)
open ( unit=70, file='time.dat' ,form='formatted' )
Expand All @@ -2924,7 +2926,9 @@ subroutine open_u
! open ( unit=78, file='vnu.dat' ,form='unformatted' )
! open ( unit=90, file='vtu.dat' ,form='unformatted' )
! open ( unit=91, file='vru.dat' ,form='unformatted' )
! open ( unit=92, file='dennu.dat' ,form='unformatted' )
if (outn) then
open ( unit=92, file='dennu.dat' ,form='unformatted' )
endif
! open ( unit=93, file='vexbu.dat' ,form='unformatted' )
! diagnostic files (unformatted)
Expand All @@ -2935,7 +2939,9 @@ subroutine open_u
! open ( unit=84, file='u1u.dat' ,form='unformatted' )
! open ( unit=85, file='u2u.dat' ,form='unformatted' )
! open ( unit=86, file='u3u.dat' ,form='unformatted' )
! open ( unit=87, file='u4u.dat' ,form='unformatted' )
if (outn) then
open ( unit=87, file='u4u.dat' ,form='unformatted' )
endif
! open ( unit=88, file='u5u.dat' ,form='unformatted' )
return
Expand Down
12 changes: 6 additions & 6 deletions sami2py/fortran/sami2py-1.00.namelist
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
&go
fmtout = .true.,
maxstep = 100000000,
hrmax = 48.000000,
hrmax = 0.110000,
dt0 = 30.000000,
dthr = 0.250000,
hrpr = 24.000000,
dthr = 0.050000,
hrpr = 0.000000,
grad_in = 300.000000,
glat_in = 0.000000,
glon_in = 0.000000,
glon_in = 256.000000,
fejer = .true.,
rmin = 100.000000,
rmax = 2000.000000,
altmin = 85.000000,
fbar = 120.000000,
f10p7 = 120.000000,
ap = 0,
year = 2012,
day = 211,
year = 1958,
day = 30,
mmass = 48,
nion1 = 1,
nion2 = 7,
Expand Down
10 changes: 6 additions & 4 deletions sami2py/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def setup(self):
if not os.path.exists(self.model_path):
os.makedirs(self.model_path)
self.filelist = ['glonf.dat', 'glatf.dat', 'zaltf.dat', 'denif.dat',
'vsif.dat', 'tif.dat', 'tef.dat', 'time.dat']
'dennf.dat', 'u4f.dat', 'vsif.dat', 'tif.dat',
'tef.dat', 'time.dat']
for filename in self.filelist:
open(os.path.join(fortran_dir, filename), 'w').close()

Expand All @@ -42,7 +43,7 @@ def teardown(self):
def test_run_model_namelist(self):
"""The test to ensure that the namelist file is generated properly
"""
sami2py.run_model(tag='test', year=2012, day=211, test=True,
sami2py.run_model(tag='test', lon=0, year=2012, day=211, test=True,
fmtout=self.format)
namelist_file = self.model_path + 'sami2py-1.00.namelist'
ref_namelist = os.path.join(test_data_dir, self.ref_file)
Expand All @@ -61,7 +62,7 @@ def test_run_model_dat_files(self):
"""Test to ensure that the dat files are copied properly
"""
sami2py.run_model(tag='test', lon=0, year=2012, day=211, test=True,
fmtout=self.format)
fmtout=self.format, outn=True)
if self.format:
fname = 'glonf.dat'
else:
Expand Down Expand Up @@ -123,7 +124,8 @@ def setup(self):
if not os.path.exists(self.model_path):
os.makedirs(self.model_path)
self.filelist = ['glonu.dat', 'glatu.dat', 'zaltu.dat', 'deniu.dat',
'vsiu.dat', 'tiu.dat', 'teu.dat', 'time.dat']
'dennu.dat', 'u4u.dat', 'vsiu.dat', 'tiu.dat',
'teu.dat', 'time.dat']
for filename in self.filelist:
open(os.path.join(fortran_dir, filename), 'w').close()

Expand Down
Loading

0 comments on commit a56ecce

Please sign in to comment.