Ariane is a particle tracking software that can be applied to NEMO and ROMS model NetCDF results files to trace the source of water masses (running backward in time) or to calculate where the water packet goes to (running forward in time).

Ariane can be run in two modes: quantitative and qualitative. In quantitative mode, you release particles and end up with a distribution function for each grid cell quantifying where your particles end up and the mass transfer, while in qualitative mode you specify each of the particles that you release and trace their exact track.


Getting Ariane

The MOAD group maintains our own Git repository on GitHub of the Ariane code base; this repository is accessible only by members of the MOAD group so as to respect the sign-up requirement of the upstream Ariane repository. The general Ariane code is available via the Ariane website . Modifications made by the MOAD group to the Ariane source code can be found on GitHub. To download the MOAD Ariane code base, clone the repository from GitHub to your $PROJECT space:

cd /ocean/$USER/$PROJECT/
git clone

Installing on salish

Configure the installation by going to the folder of your clone of the MOAD Ariane repo:

cd /ocean/$USER/$PROJECT/ariane-2.3.0_03
./configure --prefix=$PWD

The prefix argument overwrites the default install directory into a customized directory.

Make and install Ariane (you will need to do this every time you make changes to the code):

cd /ocean/$USER/$PROJECT/ariane-2.3.0_03
make check
make install

Add the path for the Ariane executable to your PATH environment variable:

export PATH=$PWD/bin:$PATH

Now you can run Ariane from any directory by typing ariane.

Testing Ariane installation

To test that you have everything set up correctly, run one of the Ariane examples. For instance, try:

cd /ocean/$USER/$PROJECT/ariane-2.3.0_03/examples/qualitative

You should notice several new files, such as results/ and validation/traj.txt. These files contain the trajectory information.

  • results/ contains the particle positions at each time step and the initial positions

  • validation/traj.txt gives a general idea of what the resulting trajectory coordinates look like or to check if the simulation ran properly

Qualitative Mode

This mode can be used to get the exact path of a set number of particles.


The initial_positions.txt file specifies the initial positions and release times of the particles that you are tracking. This file consists of 5 columns and a row for each particle that you are running.


Ariane uses FORTAN indexing, which counts starting at 1. If you used Python to look up initial positions, you should add 1 to your initial positions.

Within this file, the first three columns represent the initial X, Y, and Z coordinate point of your particle. A negative Z coordinate tells Ariane to confine the particle to its original depth throughout the trajectory. Note that these coordinate points should not be at the exact grid point coordinate, but rather offset by a little bit, otherwise Ariane may struggle at the boundaries between two grid boxes. The fourth column is the time index (use 0.5 if you want to start at NEMO time 00:00, if 0.0 it will interpolate between your data files), note that if you are running backwards, the time index here should be your end time step (so if you have a total of 330 time steps, you should release the particles at 329.5). The last column parameter is always set to 1.0. Here is an example initial_positions.txt file:

310.01 360.01 5.0  0.5 1.0
310.01 360.01 10.0 0.5 1.0
310.01 400.01 5.0  0.5 1.0
310.01 400.01 10.0 0.5 1.0
310.01 400.01 15.0 0.5 1.0


The namelist file specifies a variety of the run settings. The general Ariane parameters can be specified within ARIANE; the main ones that you are likely to change are:




Operate Ariane ‘forward’ or ‘backward’


Number of particles that you trace


Unit of time of your model files (sec)


Number of tunit in each time step (typically = 1)

The parameters of your model run are specified in OPAPARAM:



imt, jmt, kmt

x, y, and z dimensions of your model domain


Time dimension (total number of time steps)


Set to ‘TRUE’ if the model you are using does not have ‘w’ output

In qualitative mode, the frequency of calculation of the trajectory and of writing to the output file is set within QUALITATIVE:




Time step size (seconds)


Number of delta_t to calculate


Number of output time steps ( in units of delta_t x frequency)

The parameters for reading in the U, V, and W velocity files are indicated in ZONALCRT, MERIDCRT, and VERTICRT. The parameters are roughly the same, for example in the ZONALCRT section:




Directory where data is stored


NetCDF file name with velocity data


Variable name for velocity component


First number of file to read


Last number of file to read


Maximum number of integers in file name number

Note that even in backwards mode, the first and last number of the files to read are in the forwards direction, i.e. from 1 to your last file number. Of course this is not a comprehensive list of all the parameters you can set in the namelist. More information can be found in the references listed at the start.

Analyzing qualitative output

The NetCDF file that contains the particle tracks is named The variables in this file include the initial and final x, y, z, and time for the particles. It is a good idea to double check that these agree with the locations you listed in initial_positions.txt. To plot and analyze the output, you read in traj_lon, traj_lat, traj_depth, and traj_time. These variables have the shape (number of particles, positions in time).

If you would like to see some examples of particle tracking, feel free to look at the following notebooks:

Quantitative Mode

This mode can be used to make estimates of transport through cross-sections by releasing a large number of particles and calculating how many particles pass through each section.


The namelist for quantitative mode is very similar to qualitative mode, note the frequency of calculation is now set in the QUANTITATIVE section. Here is an example of a quantitative namelist.

    key_alltracers =.FALSE.,
    key_sequential =.FALSE.,
    key_ascii_outputs =.TRUE.,
    mode ='quantitative',
    forback ='forward',
    bin ='nobin',
    init_final ='init',
    nmax =30000,
    tunit =3600.,
    ntfic =1,
    imt =398,
    jmt =898,
    kmt =40,
    lmt =24,
    key_periodic =.FALSE.,
    key_jfold =.FALSE.,
    key_computew =.FALSE.,
    key_partialsteps =.TRUE.,
    key_eco        = .TRUE.,
    key_reducmem   = .TRUE.,
    key_unitm3     = .TRUE.,
    key_nointerpolstats = .FALSE.,
    max_transport  = 1.e4,
    lmin = 1,
    lmax = 6,
    c_dir_zo ='/results/SalishSea/nowcast/01jan16/',
    c_prefix_zo ='',
    ind0_zo =-1,
    indn_zo =-1,
    maxsize_zo =-1,
    c_suffix_zo ='NONE',
    nc_var_zo ='vozocrtx',
    nc_var_eivu ='NONE',
    nc_att_mask_zo ='NONE',
    c_dir_me ='/results/SalishSea/nowcast/01jan16/',
    c_prefix_me ='',
    ind0_me =-1,
    indn_me =-1,
    maxsize_me =-1,
    c_suffix_me ='NONE',
    nc_var_me ='vomecrty',
    nc_var_eivv ='NONE',
    nc_att_mask_me ='NONE',
    c_dir_ve     = '/results/SalishSea/nowcast/01jan16/',
    c_prefix_ve  = '',
    ind0_ve      = -1,
    indn_ve      = -1,
    maxsize_ve   = -1,
    c_suffix_ve  = 'NONE',
    nc_var_ve    = 'vovecrtz',
    nc_var_eivw  = 'NONE',
    nc_att_mask_ve = 'NONE',
    c_dir_te     = 'NONE',
    c_prefix_te  = 'NONE',
    ind0_te      = -1,
    indn_te      = -1,
    maxsize_te   = -1,
    c_suffix_te  = 'NONE',
    nc_var_te    = 'NONE',
    nc_att_mask_te = 'NONE',
    c_dir_sa     = 'NONE',
    c_prefix_sa  = 'NONE',
    ind0_sa      = -1,
    indn_sa      = -1,
    maxsize_sa   = -1,
    c_suffix_sa  = 'NONE',
    nc_var_sa    = 'NONE',
    nc_att_mask_sa = 'NONE',
    dir_mesh ='/data/nsoontie/MEOPAR/NEMO-forcing/grid/',
    fn_mesh ='',
    nc_var_xx_tt ='glamt',
    nc_var_xx_uu ='glamu',
    nc_var_yy_tt ='gphit',
    nc_var_yy_vv ='gphiv',
    nc_var_zz_ww ='gdepw',
    nc_var_e2u ='e2u',
    nc_var_e1v ='e1v',
    nc_var_e1t ='e1t',
    nc_var_e2t ='e2t',
    nc_var_e3t ='e3t',
    nc_var_tmask ='tmask',
    nc_mask_val =0.,

Key differences in namelist from qualitative mode

There are some key differences between the namelists in quantitative and qualitative mode. Pay special attention to the following options:


  • nmax: The maximum number of particles. This parameter is typically much higher in quantitative mode. Tip: set it really high, the actual amount of particles seeded will be based on what you set for max_transport and its no fun to have your run crash because the nmax has been met.


  • key_eco: Setting to .TRUE. reduces CPU time.

  • key_reducmem: Setting to .TRUE. reduces memory by only reading model data over selected region.

  • key_unitm3: Setting to .TRUE. prints transport calculation in m^3/s instead of Sverdrups.

  • max_transport: Maximum transport (in m^3/s) that should not be exceeded by the transport associated with each initial particle. A lower values means more initial particles and higher accuracy. Example values are 1e9 for one particle in one model cell and 1e4 for typical experiments.

  • lmin: First time step to generate particles, usually=1.

  • lmax: Last time step to generate particles (will keep running until lmt is reached just with no new particles seeded), less than or equal to lmt.

Running Backwards

If you’re hoping to do source water analysis the ability to run backwards in Ariane is a great tool! You’ll have to make a few small edits to your namelist to do so:


  • forback: set to backward now.

QUANTITATIVE: The run now starts at time = lmt, so lmin and lmax need to be adjsuted accordingly.

  • lmin: Last time step to generate particles (will keep running until timestep 1 is reached just with no new particles seeded), greater than or equal to 1.

  • lmax: First time step to generate particles, usually=:kbd:lmt.

Defining Sections

You must define a closed region in your domain for transport calculations. Ariane calculates the mass transport between an initial section in your region and the other sections. Ariane provides a couple of useful tools for defining the sections.

  • mkseg0: This program reads your land-ocean mask and writes it as a text file. Run this program in the same directory as your namelist. You may need to add the ariane executables to your path.

  • segrid: After you run mkseg0, you should see a new file called segrid. Edit this file with

nedit segrid
  • If you turn off text wrapping, you might see something like this:


Land points are # and ocean points are -.

  • Add numbered cross-sections to this file. Be sure your sections are over ocean points and not land points. Ariane will initialize particles along the section labelled as 1 and will calculate transport through all other sections. Your sections must make up a closed volume. Place the @ symbol somewhere within your closed subdomain.

  • Run mkseg

  • This will print out whether you succeeded or not and let you know the extent of the sections you defined. If something went wrong in editing segrid the message will let you know how, this usually entails accidentally deleting a land point, not closing your boundaries, or forgetting to place the @ symbol somewhere!

  • Once you have that without errors, section definitions will be copied automatically into a file called sections.txt. The section definitions should look something like this:

    1   250   313  -409  -409     1    40 "1section"
    2   264   312   386   386     1    40 "2section"
    3     1   398     1   898     0     0 "Surface"

You can rename "1section" and "2section" to something more intuitive if you desire. The "Surface" section won’t be added automatically, you should as it as above, with 398 replaced by the x-index extent of your model and 898 by the y-index extent.

Analyzing quantitative output

A new file called stats.txt contains statistics about the initial and final particles through each section and the transport calculations. It might look something like this:

total transport (in m3/s):    230033.88767527405       ( x lmt =   5520813.3042065771      )
    max_transport (in m3/s)  :    1000000000.0000000
    # particles              :        20380

    initial state                #  20380
     stats. for:          x         y         z         a
            min:   -123.457    48.946     0.500     0.000
            max:   -123.134    49.063   226.275     0.000
           mean:   -123.347    48.986    74.893     0.000
      std. dev.:      0.062     0.022    61.722     0.000

    meanders        166079.1572 0
    1section        .0000 1
    2section        63952.7799 2
    Surface         .0000 3
              total 230033.8877
        except mnds 63954.7305
               lost 1.9506

    final state        meanders #  11094
    stats. ini:          x         y         z         a
           min:   -123.457    48.946     0.500     0.006
           max:   -123.134    49.063   226.275    16.858
          mean:   -123.343    48.987    91.665     0.606
     std. dev.:      0.055     0.020    61.438     1.010
    stats. fin:          x         y         z         a
           min:   -123.458    48.945     0.019     0.006
           max:   -123.132    49.064   238.621    16.858
          mean:   -123.329    48.992    91.483     0.606
     std. dev.:      0.052     0.019    62.670     1.010

    final state        2section #   9285
    stats. ini:          x         y         z         a
           min:   -123.457    48.946     0.500     0.191
           max:   -123.134    49.063   226.275    16.074
          mean:   -123.357    48.982    31.337     1.715
     std. dev.:      0.075     0.028    35.675     1.639
    stats. fin:          x         y         z         a
           min:   -123.317    48.883     0.058     0.191
           max:   -123.079    48.970   151.722    16.074
          mean:   -123.192    48.929    25.504     1.715
     std. dev.:      0.068     0.025    25.477     1.639
  • lost are the particles not intercepted by any section.

  • meanders are the particles that go back out the source section (section 1). Note that this is actually a bad translation from the original french Ariane was writen in. It would be more accurate to think of these particles as loop.

Ariane will also produce netCDF files and that can be used to plot the particle trajectories and statistics.

Time Considerations

Particles initialized later in the simulation do not have as much time to cross one of the sections, you can check if this is a problem by keeping an eye on how many of your water parcels are “lost” during the simmulation. Cutting down on these lost water parcels is part of why we typically do runs with days at the end of the simmulation without particles being seeded. Alternatively, (if you don’t want to have a super long run-time) it could be beneficial to impose a maximum age of each particle. This can be achieved by modifying mod_criter1.f90 in src/ariane as follows:

!- ADD AT THE END OF EACH LINE "!!ctr1" -!
!criter1=.FALSE.                 !! ctr1
!- Examples -!
     criter1=(abs(hl-fl).ge. lmt-lmax)   !! ctr1
  • lmt and lmax should be substituted by the values you set in the namelist.

  • NOTE: You must remake and install ariane when making a change to any of the fortran files.

Defining and tracking water masses

You can also impose a density and/or salinity and/or temperature criteria on the initial particles in order to solely track specific water masses. You can achieve this by editing mod_criter0.f90.

!criter0=.TRUE.        !!ctr0
!- Examples -!
     criter0=(zinter(ss,hi,hj,hk,hl).le.29_rprec)     !!crt0
  • Once again, you must remake and install ariane.

  • You’ll also need to make sure that key_alltracers and key_computesigma are .TRUE. and zsigma are defined in your namelist.

  • Now particles will only be initialized if they have a salinity less than 29.

  • There are other examples of useful criteria in mod_criter0.f90.

  • NOTE: This same water mass tracking can also be done easily in your analysis of the output by filtering for parcticles that started with a salinity (data.init_salt) less than 29.

Using tracers in Ariane

Ariane can help us analyze tracers along the particle’s trajectory (qualitative mode) or when the particle is entering leaving the analysis domain (quantitative mode).

The following items must be changed or added to the namelist file:

  • key_alltracers: .TRUE. to print tracer information in diagnostics.

  • key_computesigma: .TRUE. to compute density from temperature and salinity (set to .FALSE. if the tracers you have input into the temperature and salinity fields are not actually temperature and salinity).

  • zsigma: Reference depth for calculation of density.

  • TEMPERAT and SALINITY setions of the namelist file must be included as shown below, in order to tell Ariane where to look for the temperature and salinity model output


        c_dir_te ='/ocean/nsoontie/MEOPAR/SalishSea/results/storm-surges/final/dec2006/all_forcing/30min/',
        c_prefix_te ='',
        ind0_te =-1,
        indn_te =-1,
        maxsize_te =-1,
        c_suffix_te ='NONE',
        nc_var_te ='votemper',
        nc_att_mask_te ='NONE',


        c_dir_sa ='/ocean/nsoontie/MEOPAR/SalishSea/results/storm-surges/final/dec2006/all_forcing/30min/',
        c_prefix_sa ='',
        ind0_sa =-1,
        indn_sa =-1,
        maxsize_sa =-1,
        c_suffix_sa ='NONE',
        nc_var_sa ='vosaline',
        nc_att_mask_sa ='NONE',

votemper and vosaline are the variable names for temperature and salinity in our input file.


In qualitative results ( the variable names for the tracers are:

  • traj_temp

  • traj_salt

  • traj_dens

In quantitative results ( the variable names for the tracers are:

  • init_salt

  • init_temp

  • init_dens

  • final_salt

  • final_temp

  • final dens

A sample of Ariane qualitative tracer results:

Multi-day runs

Until now, we have entered only one input file into Ariane. Use Ariane’s sequential mode to enter multiple files.

Input Files

The NetCDF files used as input must have the following format: prefix_number_suffix

If the file names do not follow this format, create symbolic links that do. Create this link by using the command ln -s [target file directory] [symbolic link name]

For example, you may consider:

  • prefix = SalishSea_

  • number = 01, 02, etc

  • suffix =,,

Note: number must contain a constant digit number and its value must increase by one in chronological order. For example, file contains tracers for November 1st and contains tracers for November 2nd.

Namelist Modifications


  • change key_sequential to TRUE.

Add a SEQUENTIAL section:

  • one parameter, maxcycles. We recommend the value of this parameter to be 1 since this tells Ariane to stop generating trajectory points once it has run out of input data.

maxcycles =1,

ZONALCRT, MERIDCRT, TEMPERAT, and SALINITY: The parameters that must be changed for these sections are the same; c_dir_X, c_prefix_X, ind0_X, indn_X, maxsize_X, and c_suffix_X where X is zo, me, te, sa for the ZONALCRT, MERIDCRT, TEMPERAT, and SALINITY sections, respectively.

  • c_dir_X is the directory with the symbolic links for the input files, the namelist, and the initial positions text file.

  • Now that we have formatted the filenames as prefix_number_suffix, c_prefix_me takes on the value of the prefix and c_suffix_me takes the value of suffix.Previously, we have been entering the full filename,, into c_prefix_X.

  • ind0_X is the number for the earliest input file and indn_X is the latest.

  • maxsize_X is the number of digits in number.

For example, the ZONALCRT section would look like the following for input files and :

        c_dir_zo ='/ocean/imachuca/MEOPAR/Ariane/results/drifter_compare/sequential/',
        c_prefix_zo ='SalishSea_',
        ind0_zo =01,
        indn_zo =02,
        maxsize_zo =2,
        c_suffix_zo ='',
        nc_var_zo ='vozocrtx',
        nc_var_eivu ='NONE',
        nc_att_mask_zo ='NONE',

Running Ariane for Multiple Days

If you want to run Ariane for A LOT of days you’re not going to want to have to write out where Ariane should look for the input, lucky for you a python script has already been wirtten to make the Links to the correct files, tell Ariane how to find them, run Ariane, and save the ouput in an organized fashion:

Loop over dates, setting up a series of forcing links, running Ariane starting particles over multiple days
and saving the statistic results"""

import argparse
import arrow
import os
import subprocess

TARGET_TMPL = 'SalishSea_1h_{:06d}_grid_{:s}.nc'
FILENAME_TMPL = 'SalishSea_1h_{:%Y%m%d}_{:%Y%m%d}_grid_{:s}.nc'
SUBDIR_TMPL = '{:%d%b%y}'

def make_links(rundate, runlength):
    dir = '/results2/SalishSea/nowcast-green.201905/'
    tardir = 'Links'
    for grid in ['T', 'U', 'V', 'W']:
        for fileno in range(runlength):
            target = TARGET_TMPL.format(fileno+1, grid)
            date = rundate.shift(days=+fileno).datetime
            print (date, dir)
            link = FILENAME_TMPL.format(date, date, grid)
            subdir = SUBDIR_TMPL.format(date).lower()
                os.unlink(os.path.join(tardir, target))
            except FileNotFoundError:
            os.symlink(os.path.join(dir, subdir, link),
                       os.path.join(tardir, target))

def run_ariane():
    with open('babypoo', 'wt') as stdout:
        with open('errpoo', 'wt') as stderr:
                stdout=stdout, stderr=stderr,

def rename_results(rundate=arrow.utcnow(), subdir='',
                   nday=1, labeltype='date'):
    finaldir = '/ocean/rbeutel/MOAD/analysis-becca/Ariane/'
    filelist = ['ariane_memory.log', '',
                'final_pos.txt', 'init_pos.txt', 'output',
                '', 'final.sav',
                'init.sav', 'stats.txt']
    for filename in filelist:
        if labeltype == 'date':
            newdir = SUBDIR_TMPL.format(rundate.datetime).lower()
            newdir = ''
        print(os.path.join(finaldir, subdir, newdir, filename))
        if not os.path.exists(os.path.join(finaldir, subdir, newdir)):
                os.makedirs(os.path.join(finaldir, subdir, newdir))
        os.rename(filename, os.path.join(finaldir, subdir, newdir, filename))

def main(args):
    initialrundate = arrow.get(args.initialrundate, 'YYYY-MM-DD')
    for nday in range(args.numberofdays):
        rundate = initialrundate.shift(days=+nday)
        print ('Start', rundate)
        if args.forback == 'forward':
            startfile = rundate
        elif args.forback == 'backward':
            startfile = rundate.shift(days=-(args.runlength-1))
        make_links(startfile, args.runlength+args.releaseparticledays)
        print ('Startfile', startfile)
        rename_results(rundate=rundate, subdir=args.runtype)
        print ('End', rundate)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
        'initialrundate', help='Date to start from as YYYY-MM-DD', type=str)
        'numberofdays', help='Number of different dates to do', type=int)
        'runlength', help='Number of days to track particles', type=int)
        'releaseparticledays', help='Number of days over which to release particles for one run', type=int)
    parser.add_argument('forback', help='Run forward or backward', type=str)
                        help='FluxesSouth FluxesNorth BackSouth BackNorth',
    args = parser.parse_args()
  • TARGET_TMPL is the template for naming the links, in a format the Ariane can read (ie. prefix_number_suffix)

  • FILENAME_TMPL is the template for the actual filenames so that the links to them can be made

  • SUBDIR_TMPL is the template for the subdirectory where you want your output to be named. NOTE: right now it is set for the startdate of your run, so if you do multiple runs on the same date don’t want previous runs overwritten then you need to rename this.

Function Description

def make_links(rundate, runlength) This function makes the Links for you for your U, V, W, and T (for salinity and temperature) files between your rundates. You need to have the target directory (set in tardir) already made. This function is specific to running Ariane with the 201905 SalishSeaCast runs (see the dir its looking in) and using temperature and salinity as your tracers, but it can be odified easily if you’re running with different tracers (the file would no longer end with “”) and/or different model output (directory its looking in and/or filename template would have to change)

def run_ariane() This function is what actually runs ariane for you and calls on the function def main(args). The only thing that needs to be changed is the filepath to your ariane repository (instead of rbeutel’s). This function also saves all of what Ariane prints into two files: errpoo and babypoo. errpoo holds all the error messages from ariane so should be the first place you look if ariane crashes. babypoo holds everything else, if errpoo doesn’t answer your questions then babypoo can help you figure out where exactly your run failed.

def rename_results() This function organises your output into “stuff that stays in the current directory you’re working in” and “stuff that goes to target subdirectory”. Everything in the filelist list will be moved to the results directory. Note that this filelist is specific for quantitative run output and will need to be edited for qualitative runs to the following: [‘ariane_memory.log’, ‘’, ‘init.sav’, ‘final.sav’, ‘output’].

Calling the Run Ariane Script

Calling this script takes a bit more information than most, in your command line type the following:

python3 startday number_of_loops days_with_particles_seeding total_days_in_run forward_or_backward target_subdirectory_name

for example, the following was typed into the command line for 30 days of seeding, 30 days of run after seeding is completed, foward run, starting January 1st 2018:

python3 ./ 2018-01-01 1 30 30 forward 201905_1hr

Frequency Sensitivity Sample

The model produces datasets containing information about the velocity field for a region. Ariane uses this information to produce particle trajectories. We wanted to know at what frequency would the model output need to be to produce the most reliable particle trajectories.

For the frequency sensitivity studies, we used model outputs with 30 minute, 1 hour, and 4 hour frequencies. This data was used in Ariane’s qualitative mode to generate particle trajectories with points at 30 minute intervals. We did this for particles starting their trajectories at the Fraser River and at various points along the thalweg. The results are summarized below.

On the Surface

At the Fraser River, we found that the particle trajectory generated using data at a 4 hour frequency does not capture subtleties in particle motion as do the trajectories derived from data at 30 minute and 1 hour frequencies. The trajectory that used 1 hour frequency data very closely resembles the trajectory that used 30 minute data.

Conclusion: We can use 1 hour or 30 minute NEMO output data when particle trajectories start at the Fraser River.

At Depth

Conclusion: In regions of moderate mixing, 30 minute data would be preferable; we can use 1 hour data with some caution. In regions of heavy mixing, we should exercise caution in analyzing trajectories and depths since results vary greatly depending on frequencies.