From 15f86f38bff70081d6c79a6d4f83308898fbc4b4 Mon Sep 17 00:00:00 2001
From: ronesy <rlt@nilu.no>
Date: Thu, 24 Oct 2024 15:46:36 +0200
Subject: [PATCH] changes for FPv11 with backwards compatibility with FPv10.4
 and name change for aerosol species

---
 grid_to_ncdf/grid_convert.f90         |  12 +-
 grid_to_ncdf/init_convert.f90         |   6 +-
 grid_to_ncdf/initialize.f90           |  19 +-
 grid_to_ncdf/makefile                 |  61 ++--
 grid_to_ncdf/mod_flexpart.f90         |  16 +-
 grid_to_ncdf/run_grid2ncdf.sh         |  16 +
 prep_flexpart/SETTINGS                |  22 +-
 prep_flexpart/list_obsfiles.f90       |  28 +-
 prep_flexpart/main.f90                |  56 +--
 prep_flexpart/makefile                |   8 +-
 prep_flexpart/mod_prep_ageclass.f90   | 147 ++++++++
 prep_flexpart/mod_prep_command.f90    | 359 ++++++++++++++++++++
 prep_flexpart/mod_settings.f90        |  81 ++++-
 prep_flexpart/mod_var.f90             |   1 +
 prep_flexpart/prep_ageclass.f90       |  99 ------
 prep_flexpart/prep_command.f90        | 241 -------------
 prep_flexpart/prep_outgrid.f90        |   2 +-
 prep_flexpart/prep_pathnames.f90      |  15 +-
 prep_flexpart/prep_reagents.f90       |  73 ++++
 prep_flexpart/prep_releases.f90       |  85 ++++-
 prep_flexpart/prep_releases_reg.f90   |  80 ++++-
 prep_flexpart/read_basic.f90          |  24 +-
 prep_flexpart/read_icos.f90           |  26 +-
 prep_flexpart/read_noaa.f90           |  24 +-
 prep_flexpart/read_obspack.f90        |  23 +-
 prep_flexpart/read_wdcgg.f90          |  25 +-
 prep_flexpart/sbatch_prep_flexpart.sh |   2 +-
 prep_fluxes/makefile                  |  62 ++--
 prep_regions/get_surfinf.f90          |   6 +-
 prep_regions/initialize.f90           |  35 +-
 prep_regions/mod_flexpart.f90         |  16 +-
 prep_regions/mod_settings.f90         |   2 +-
 prep_regions/prep_regions.f90         |   9 -
 prep_regions/run_prepregions.sh       |  27 ++
 prep_satellite/makefile               |  70 ++--
 prep_syndata/get_error_cov.f90        |  10 +-
 prep_syndata/get_flux.f90             |   4 +-
 prep_syndata/get_obs.f90              |   6 +-
 prep_syndata/initialize.f90           |  40 ++-
 prep_syndata/makefile                 |  72 ++--
 prep_syndata/mod_flexpart.f90         |  16 +-
 prep_syndata/mod_perturb.f90          |   6 +-
 prep_syndata/mod_save.f90             |  48 +--
 prep_syndata/mod_var.f90              |   2 +-
 prep_syndata/prep_syndata.f90         |   3 -
 prep_syndata/run_prepsyndata.sh       |  24 ++
 settings/SETTINGS_aero_config         | 151 ++++++++
 settings/SETTINGS_aero_files          |  89 +++++
 settings/SETTINGS_co2_config          |   3 +
 settings/SETTINGS_ghg_config          |   3 +
 source/average_fp.f90                 |   6 +-
 source/calc_conc.f90                  |  15 +-
 source/init_aero.f90                  | 472 ++++++++++++++++++++++++++
 source/init_cini.f90                  |   6 +-
 source/init_cini_month.f90            |   6 +-
 source/init_ghg.f90                   |   2 +-
 source/initialize.f90                 |  19 +-
 source/job_flexinvert.sh              |   4 +-
 source/main.f90                       |   6 +-
 source/makefile                       |   1 +
 source/mod_flexpart.f90               |  20 +-
 source/mod_perturb.f90                |   3 +-
 source/mod_save.f90                   |  35 +-
 source/mod_settings.f90               |  15 +-
 source/read_obs.f90                   |  76 ++---
 source/sbatch_flexinvert.sh           |   4 +-
 source/simulate.f90                   |  23 +-
 67 files changed, 2221 insertions(+), 747 deletions(-)
 create mode 100755 grid_to_ncdf/run_grid2ncdf.sh
 create mode 100644 prep_flexpart/mod_prep_ageclass.f90
 create mode 100644 prep_flexpart/mod_prep_command.f90
 delete mode 100644 prep_flexpart/prep_ageclass.f90
 delete mode 100644 prep_flexpart/prep_command.f90
 create mode 100644 prep_flexpart/prep_reagents.f90
 create mode 100755 prep_regions/run_prepregions.sh
 create mode 100755 prep_syndata/run_prepsyndata.sh
 create mode 100644 settings/SETTINGS_aero_config
 create mode 100644 settings/SETTINGS_aero_files
 create mode 100644 source/init_aero.f90

diff --git a/grid_to_ncdf/grid_convert.f90 b/grid_to_ncdf/grid_convert.f90
index 4c3adfd..6fb61a5 100644
--- a/grid_to_ncdf/grid_convert.f90
+++ b/grid_to_ncdf/grid_convert.f90
@@ -51,7 +51,7 @@ subroutine grid_convert(files, config, nr, timestamp)
   integer                                                :: ibdate, ibtime
   integer, dimension(maxpoint)                           :: releases
   real                                                   :: bndx, bndy, delx, dely
-  integer                                                :: numx, numy
+  integer                                                :: numx, numy, numz
 
   ! list all grid files in directory
   if ( trim(config%filefreq).eq.'month' ) then
@@ -90,17 +90,23 @@ subroutine grid_convert(files, config, nr, timestamp)
   ! read header for this month to get ngrid
   if ( config%lnested ) then
     filename = trim(path_flexpart)//'header_nest'
+    inquire(file=trim(filename),exist=lexist)
+    if ( .not.lexist ) then
+      ! test if is FPv11 file
+      filename = trim(path_flexpart)//'header_nest_grid_time'
+      inquire(file=trim(filename),exist=lexist)
+    endif
   else
     filename = trim(path_flexpart)//'header'
+    inquire(file=trim(filename),exist=lexist)
   endif
-  inquire(file=trim(filename),exist=lexist)
   if ( .not.lexist ) then
     print*, 'ERROR: cannot find flexpart header'
     stop
   endif
   print*, 'Reading flexpart header: '//trim(filename)
   call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                   numx, numy, bndx, bndy, delx, dely)
+                   numx, numy, numz, bndx, bndy, delx, dely)
   if ( config%linversionout ) then
     ngrid = trajdays*ndgrid+2
   else
diff --git a/grid_to_ncdf/init_convert.f90 b/grid_to_ncdf/init_convert.f90
index a57bfeb..1fb8f0f 100644
--- a/grid_to_ncdf/init_convert.f90
+++ b/grid_to_ncdf/init_convert.f90
@@ -52,7 +52,7 @@ subroutine init_convert(files, config, nr, timestamp)
   integer                                                :: ibdate, ibtime
   integer, dimension(maxpoint)                           :: releases
   real                                                   :: bndx, bndy, delx, dely
-  integer                                                :: numx, numy
+  integer                                                :: numx, numy, numz
 
   ! list all grid files in directory
   if ( trim(config%filefreq).eq.'month' ) then
@@ -92,8 +92,8 @@ subroutine init_convert(files, config, nr, timestamp)
   endif
   print*, 'Reading flexpart header: '//trim(filename)
   call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                   numx, numy, bndx, bndy, delx, dely)
-  print*, 'numx, numy, bndx, bndy, delx, dely = ',numx,numy,bndx,bndy,delx,dely
+                   numx, numy, numz, bndx, bndy, delx, dely)
+  print*, 'numx, numy, numz, bndx, bndy, delx, dely = ',numx,numy,numz,bndx,bndy,delx,dely
   allocate( grid(nxgrid,nygrid,nzgrid) )
   allocate( levels(nzgrid) )
   ! trick to use write_ncdf also for grid_initial
diff --git a/grid_to_ncdf/initialize.f90 b/grid_to_ncdf/initialize.f90
index ab0df23..451750a 100644
--- a/grid_to_ncdf/initialize.f90
+++ b/grid_to_ncdf/initialize.f90
@@ -43,7 +43,7 @@ subroutine initialize(files, config)
   integer                                :: ibdate, ibtime
   integer, dimension(maxpoint)           :: releases
   real                                   :: bndx, bndy, delx, dely
-  integer                                :: numx, numy
+  integer                                :: numx, numy, numz
   integer                                :: i, ierr
 
   ! read list of receptors
@@ -74,15 +74,27 @@ subroutine initialize(files, config)
       else
         filename = trim(files%path_flexpart)//trim(areldate)//'/header'
       endif
+      inquire(file=trim(filename),exist=lexist)
     else if ( config%lnested ) then
       if ( trim(config%filefreq).eq.'month' ) then
         filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest'
+        inquire(file=trim(filename),exist=lexist)
+        if ( .not.lexist ) then
+          ! test if is FPv11 file 
+          filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest_grid_time'
+          inquire(file=trim(filename),exist=lexist)
+        endif
       else
         filename = trim(files%path_flexpart)//trim(areldate)//'/header_nest'
+        inquire(file=trim(filename),exist=lexist)
+        if ( .not.lexist ) then
+          ! test if is FPv11 file
+          filename = trim(files%path_flexpart)//trim(areldate)//'/header_nest_grid_time'
+          inquire(file=trim(filename),exist=lexist)
+        endif
       endif
     endif
     print*, filename
-    inquire(file=trim(filename),exist=lexist)
     i = i + 1
   end do
   if ( .not.lexist ) then
@@ -91,9 +103,10 @@ subroutine initialize(files, config)
   endif
   write(*,*) 'Reading flexpart header: '//trim(filename)
   call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                   numx, numy, bndx, bndy, delx, dely)
+                   numx, numy, numz, bndx, bndy, delx, dely)
   nxgrid = numx
   nygrid = numy
+  nzgrid = numz
   llx = bndx
   lly = bndy
   dx = delx
diff --git a/grid_to_ncdf/makefile b/grid_to_ncdf/makefile
index 75feccc..55f38ba 100644
--- a/grid_to_ncdf/makefile
+++ b/grid_to_ncdf/makefile
@@ -1,34 +1,41 @@
-F90     = gfortran
-LIBPATH = /usr/lib/
-INCPATH = /usr/include/
-LNK = -o
-CMPL = -c
-LIBS = -lnetcdf -lnetcdff -llapack
-#FFLAGS   = -O2 -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form
-FFLAGS = -O0 -g -m64 -fbounds-check -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form \
-         -fbacktrace
-LDFLAGS  = $(FFLAGS)  -L$(LIBPATH) -I$(INCPATH) $(LIBS)
+F90      = /apps/sw/ubuntu22.04/gcc-11.4.0/gcc-13.2.0-tkesyophy2o6rjlzknndu3b4oyasvuqm/bin/gfortran
+LIBPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib/
+INCPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/include/
+
+# OPTIMIZATION LEVEL
+O_LEV = 0 # [0,1,2,3,g,s,fast]
+
+LIBS = -lm -DUSE_NCF -lnetcdff
+
+FFLAGS   = -I$(INCPATH1) -O$(O_LEV) -g -cpp -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -fmessage-length=0 -flto=jobserver -O$(O_LEV) -DUSE_NCF -lnetcdff -fbacktrace -Warray-bounds -fcheck=all # -march=native
+
+LDFLAGS  = $(FFLAGS) -L$(LIBPATH1) -Wl,-rpath,$(LIBPATH1) $(LIBS)
 
 MAIN = grid_to_ncdf
 
-SRCS =   mod_var.f90 \
-         mod_settings.f90 \
-         mod_dates.f90 \
-         mod_flexpart.f90 \
-         initialize.f90 \
-         grid_convert.f90 \
-         init_convert.f90 \
-         factor_convert.f90 \
-         write_ncdf.f90 \
-	 read_reclist.f90 \
-         grid_to_ncdf.f90
-
-OBJECTS = $(SRCS:.f90=.o)
-$(MAIN): $(OBJECTS) $(MODULES)
-	$(F90) $(LNK) $(MAIN) $(OBJECTS) $(LIBS)
+MODULES = mod_var.o \
+         mod_settings.o \
+         mod_dates.o \
+         mod_flexpart.o
+
+OBJECTS = initialize.o \
+         grid_convert.o \
+         init_convert.o \
+         factor_convert.o \
+         write_ncdf.o \
+	 read_reclist.o \
+         grid_to_ncdf.o
+
+%.o: %.mod
+
+$(MAIN): $(MODULES) $(OBJECTS)
+	+$(F90) -o $@ $(MODULES) $(OBJECTS) $(LDFLAGS)
+
 %.o : %.f90
-	$(F90) $(LDFLAGS) $(CMPL) $<  -o $@
+	+$(F90) -c $(FFLAGS) $< 
 
 clean:
-	rm -f $(OBJECTS) $(MODULES)
+	rm -f *.o *.mod
+
+.SUFFIXES = $(SUFFIXES) .f90
 
diff --git a/grid_to_ncdf/mod_flexpart.f90 b/grid_to_ncdf/mod_flexpart.f90
index 0480e61..82810c3 100644
--- a/grid_to_ncdf/mod_flexpart.f90
+++ b/grid_to_ncdf/mod_flexpart.f90
@@ -49,7 +49,7 @@ module mod_flexpart
   ! --------------------------------------------------
 
   subroutine read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely)
+                           numx, numy, numz, bndx, bndy, delx, dely)
 
     use mod_var
 
@@ -59,7 +59,7 @@ module mod_flexpart
     integer,                      intent(in out) :: numpoint
     integer,                      intent(in out) :: ibdate, ibtime   
     integer, dimension(maxpoint), intent(in out) :: releases           
-    integer,                      intent(in out) :: numx, numy
+    integer,                      intent(in out) :: numx, numy, numz
     real,                         intent(in out) :: bndx, bndy, delx, dely
 
     character(len=29)                            :: flexversion
@@ -75,7 +75,7 @@ module mod_flexpart
     real, dimension(:), allocatable              :: xpoint, ypoint, zpoint1, zpoint2
     real, dimension(:,:), allocatable            :: xmass
     integer, dimension(10)                       :: lage
-    integer                                      :: n, i, j, ierr
+    integer                                      :: n, i, j, ierr, dummy
  
     inquire ( file=trim(filename),exist=lexist )
     if ( .not.lexist ) then
@@ -91,14 +91,14 @@ module mod_flexpart
     read(100) ibdate, ibtime, flexversion
     read(100) loutstep, loutaver, loutsample
     read(100) bndx, bndy, numx, numy, delx, dely
-    read(100) nzgrid, (outheight(i), i = 1, nzgrid)
+    read(100) numz, (outheight(i), i = 1, numz)
     read(100) jjjjmmdd, ihmmss
-    read(100) nspec, nzgrid
+    read(100) nspec, numz
     nspec=nspec/3
     do n=1,nspec
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
+      read(100) dummy, species(n)
+      read(100) dummy, species(n)
+      read(100) numz, species(n)
     end do
     read(100) numpoint
 
diff --git a/grid_to_ncdf/run_grid2ncdf.sh b/grid_to_ncdf/run_grid2ncdf.sh
new file mode 100755
index 0000000..3d5a737
--- /dev/null
+++ b/grid_to_ncdf/run_grid2ncdf.sh
@@ -0,0 +1,16 @@
+#!/bin/bash 
+#SBATCH -J grid2ncdf
+#SBATCH -p main
+#SBATCH -o grid2ncdf.out
+#SBATCH --time=2:00:00
+#SBATCH --mem=8000
+
+module purge
+module load gcc/13.2.0-tkesy
+module load openmpi/5.0.3-l3mqa
+module load eccodes/2.34.0-wrusa
+
+export LIBRARY_PATH=$LIBRARY_PATH:/apps/sw/ubuntu22.04/gcc-13.2.0/eccodes-2.34.0-wrusaoev7mlquymqrelfbxrhvnagtz6d/lib:/apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/apps/sw/ubuntu22.04/gcc-13.2.0/eccodes-2.34.0-wrusaoev7mlquymqrelfbxrhvnagtz6d/lib:/apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib
+
+srun ./grid_to_ncdf SETTINGS
diff --git a/prep_flexpart/SETTINGS b/prep_flexpart/SETTINGS
index ad393e6..c6634ba 100644
--- a/prep_flexpart/SETTINGS
+++ b/prep_flexpart/SETTINGS
@@ -8,16 +8,20 @@
 # ==================================================
 
 # Path and file settings
+# use scratch drive, if yes writes relative paths for options and output (1 = yes, 0 = no)
+lscratch :    1
 # flexpart source path 
 path_flexpart: /mypath/flexpart/
+# flexpart version (either 10 or 11)
+FPversion:    10
 # path where to write options folder (root only, recname and month are appended)
 path_options: /mypath/flexpart_options/
 # path where to write flexpart output (root only, recname and month are appended)
 path_output: /mypath/flexpart_output/
-# path to OH fields (if use OH chemistry)
-path_ohfield: /mypath/ohfields/
 # path to observations 
 path_obs: /mypath/obs/
+# path to OH fields (FPv10 only)
+path_ohfield: /mypath/oh_fields/
 # path where to write observation output
 path_obsout: /mypath/obs_out/
 # observation file format (one of obspack, wdcgg, noaa, basic, icos)
@@ -29,6 +33,18 @@ file_recept: /mypath/input/reclist.txt
 # AVAILABLE files
 file_avail: /mypath/available_files/AVAILABLE
 file_availnest: /mypath/available_files/AVAILABLE
+# windfields to use (determines lon of domain for flexpart run) (oper, era5)
+windfield:  era5
+
+# If species has chemical reactions (for FPv11 only)
+# number of reactions
+nreagent: 1
+# comma-separated list of paths to reagents files (length of nreagent)
+path_reagents: /mypath/oh_fields/
+# comma-separated list of units in reagents files ("molecule/cm3" or "mol/mol") (length of nreagent)
+reagent_units: molecule/cm3
+# comma-sepated list indicating if reagent fields are to be interpolated to hourly based on SZA (0 = no, 1 = yes)
+reagent_interp: 1
 
 # General settings
 # make flexpart releases only when there are observations (1) or at regular intervals (0)
@@ -44,6 +60,8 @@ laverage: 0
 intaverage: 0
 # flexpart file format (namelist = 1, ascii = 0)
 lnamelist: 1
+# if observation output already exists - append (1) or make new files (0)
+lappendfile: 0
 
 # COMMAND settings
 # start date of simulation (yyyymmdd)
diff --git a/prep_flexpart/list_obsfiles.f90 b/prep_flexpart/list_obsfiles.f90
index ce62464..fea8dc5 100644
--- a/prep_flexpart/list_obsfiles.f90
+++ b/prep_flexpart/list_obsfiles.f90
@@ -27,22 +27,40 @@ subroutine list_obsfiles(settings)
 
   use mod_var
   use mod_settings
+  use mod_dates
 
   implicit none
 
   type (settings_t), intent(in)    :: settings
   integer                          :: nf, ierr
+  character(len=6)                 :: adate
+  integer                          :: jjjjmmdd, hhmiss
 
   ! list observation files
   ! ----------------------
 
-  call system('rm -f '//trim(settings%path_obsout)//'obsfiles.txt')
-  call system('ls '//trim(settings%path_obs)//'*'//trim(settings%suffix)//' | wc -l > '//trim(settings%path_obsout)//'obsfiles.txt')
-  call system('ls '//trim(settings%path_obs)//' | grep '//trim(settings%suffix)//' >> '//trim(settings%path_obsout)//'obsfiles.txt')
+  if ( settings%lappendfile.eq.1 ) then
+    call system('rm -f '//trim(settings%path_obsout)//'obsfiles.dat')
+    call system('ls '//trim(settings%path_obs)//'*'//trim(settings%suffix)//&
+                ' | wc -l > '//trim(settings%path_obsout)//'obsfiles.dat')
+    call system('ls '//trim(settings%path_obs)//' | grep '//trim(settings%suffix)//&
+                ' >> '//trim(settings%path_obsout)//'obsfiles.dat')
+  else
+    call caldate(jdatei, jjjjmmdd, hhmiss)
+    write(adate,'(I6)') jjjjmmdd/100
+    call system('ls '//trim(settings%path_obs)//'*'//trim(settings%suffix)//&
+                ' | wc -l > '//trim(settings%path_obsout)//adate//'/'//'obsfiles.dat')
+    call system('ls '//trim(settings%path_obs)//' | grep '//trim(settings%suffix)//&
+                ' >> '//trim(settings%path_obsout)//adate//'/'//'obsfiles.dat')
+  endif    
 
-  open(100,file=trim(settings%path_obsout)//'obsfiles.txt',action='read',status='old',iostat=ierr)
+  if ( settings%lappendfile.eq.1 ) then
+    open(100,file=trim(settings%path_obsout)//'obsfiles.dat',action='read',status='old',iostat=ierr)
+  else
+    open(100,file=trim(settings%path_obsout)//adate//'/'//'obsfiles.dat',action='read',status='old',iostat=ierr)
+  endif
   if ( ierr.ne. 0 ) then
-    write(*,*) 'ERROR: cannot open obsfiles.txt'
+    write(*,*) 'ERROR: cannot open obsfiles.dat'
     stop
   endif
   read(100,*,iostat=ierr) nfiles
diff --git a/prep_flexpart/main.f90 b/prep_flexpart/main.f90
index f48a0c2..114e804 100644
--- a/prep_flexpart/main.f90
+++ b/prep_flexpart/main.f90
@@ -41,6 +41,8 @@ program main
   use mod_dates
   use mod_settings
   use mod_obs
+  use mod_prep_ageclass
+  use mod_prep_command
 
   implicit none
 
@@ -50,6 +52,7 @@ program main
   
   character(max_path_len)  :: settings_file
   real(kind=8)             :: jd
+  character(len=6)         :: adate
   logical                  :: lexist
   integer                  :: nobs, nr
   integer                  :: jjjjmmdd, hhmiss, eomday
@@ -70,37 +73,47 @@ program main
   jreldatei = juldate(settings%reldatei, 0)
   jreldatef = juldate(settings%reldatef, 0)
 
-  print*, 'datei: ', settings%datei, jdatei
-  print*, 'datef: ', settings%datef, jdatef
-  print*, 'reldatei: ', settings%reldatei, jreldatei
-  print*, 'reldatef: ', settings%reldatef, jreldatef
+  write(*,*) 'datei: ', settings%datei, jdatei
+  write(*,*) 'datef: ', settings%datef, jdatef
+  write(*,*) 'reldatei: ', settings%reldatei, jreldatei
+  write(*,*) 'reldatef: ', settings%reldatef, jreldatef
   
   ! checks
   if( jdatei.ne.jreldatei.or.jdatef.ne.jreldatef ) then 
-    print*, 'WARNING: different run and release times' 
+    write(*,*) 'WARNING: different run and release times' 
   endif
   if( (jreldatei.lt.jdatei).or.(jreldatei.gt.jdatef) ) then
-    print*, 'ERROR: release date outside run time'
+    write(*,*) 'ERROR: release date outside run time'
     stop
   endif
   if( (jreldatef.lt.jdatei).or.(jreldatef.gt.jdatef) ) then
-    print*, 'ERROR: release date outside run time'
+    write(*,*) 'ERROR: release date outside run time'
     stop
   endif
   inquire(file=settings%file_avail,exist=lexist)
   if( .not.lexist ) then
-    print*, 'ERROR: AVAILABLE file not found'
+    write(*,*) 'ERROR: AVAILABLE file not found'
     stop
   endif
   if( settings%laverage.eq.0 ) then
     settings%intaverage = 0.
-    print*, 'WARNING: laverage is 0 but intaverage > 0'
-    print*, 'setting intaverage to 0'
+    write(*,*) 'WARNING: laverage is 0 but intaverage > 0'
+    write(*,*) 'setting intaverage to 0'
   endif
   if( settings%lrelease.eq.0 ) then
-    print*, 'FLEXPART releases at regular intervals'
+    write(*,*) 'FLEXPART releases at regular intervals'
   else
-    print*, 'FLEXPART releases at observation timestamps'
+    write(*,*) 'FLEXPART releases at observation timestamps'
+  endif
+
+  ! clean-up previous run
+  if ( settings%lappendfile.eq.0 ) then
+    write(*,*) 'WARNING: cleaning-up existing directory'
+    call caldate(jdatei, jjjjmmdd, hhmiss)
+    write(adate,'(I6)') jjjjmmdd/100
+    print*, trim(settings%path_obsout)//adate//'/'
+    call system('rm -rf '//trim(settings%path_obsout)//adate//'/')
+    call system('mkdir -p '//trim(settings%path_obsout)//adate//'/')
   endif
 
   ! read receptor list
@@ -121,18 +134,20 @@ program main
       call prep_pathnames(settings, jd, nr)
 
       ! write COMMAND
-      call prep_command(settings, jd, nr)
+      if ( settings%FPversion.eq.10 ) then
+        call prep_command_FP10(settings, jd, nr)
+      else if ( settings%FPversion.eq.11 ) then
+        call prep_command(settings, jd, nr)
+      endif
  
       ! write OUTGRID
       call prep_outgrid(settings, jd, nr)
 
       ! write AGECLASS
-      if ( settings%lFPversion.eq.0 ) then
-         write(*,*) 'Preparing ageclass for FP10', settings%lFPversion
-         call prep_ageclass_FP10(settings, jd, nr)
-      else
-         write(*,*) 'Preparing ageclass for FP11', settings%lFPversion
-         call prep_ageclass(settings, jd, nr)
+      if ( settings%FPversion.eq.10 ) then
+        call prep_ageclass_FP10(settings, jd, nr)
+      else if ( settings%FPversion.eq.11 ) then
+        call prep_ageclass(settings, jd, nr)
       endif
 
       ! read and process observations
@@ -147,7 +162,8 @@ program main
       else if ( settings%obsformat.eq.'basic' ) then
         call read_basic(settings, jd, nr, nobs, obs)
       else  
-        print*, 'ERROR: unknown observation file format'
+        write(*,*) 'ERROR: unknown observation file format'
+        stop
       endif
 
       ! write RELEASES
diff --git a/prep_flexpart/makefile b/prep_flexpart/makefile
index a3a0e4b..67c16ed 100644
--- a/prep_flexpart/makefile
+++ b/prep_flexpart/makefile
@@ -18,15 +18,15 @@ MODULES  =   mod_var.o \
          mod_dates.o \
          mod_tools.o \
          mod_obs.o \
-         mod_strings.o
+         mod_strings.o \
+         mod_prep_ageclass.o \
+         mod_prep_command.o
 
 OBJECTS =   read_reclist.o \
          list_obsfiles.o \
          prep_pathnames.o \
-         prep_command.o \
          prep_outgrid.o \
-         prep_ageclass.o \
-         prep_ageclass_FP10.o \
+         prep_reagents.o \
          prep_releases.o \
          prep_releases_reg.o \
          process_obs.o \
diff --git a/prep_flexpart/mod_prep_ageclass.f90 b/prep_flexpart/mod_prep_ageclass.f90
new file mode 100644
index 0000000..d93df8a
--- /dev/null
+++ b/prep_flexpart/mod_prep_ageclass.f90
@@ -0,0 +1,147 @@
+!---------------------------------------------------------------------------------------
+! PREP_FLEXPART: mod_prep_ageclass
+!---------------------------------------------------------------------------------------
+!  FLEXINVERT is free software: you can redistribute it and/or modify
+!  it under the terms of the GNU General Public License as published by
+!  the Free Software Foundation, either version 3 of the License, or
+!  (at your option) any later version.
+!
+!  FLEXINVERT is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU General Public License for more details.
+!
+!  You should have received a copy of the GNU General Public License
+!  along with FLEXINVERT.  If not, see <http://www.gnu.org/licenses/>.
+!
+!  Copyright 2017, Rona Thompson
+!---------------------------------------------------------------------------------------
+!
+!> mod_prep_ageclass
+!!
+!! Purpose:    Prepares the options file AGECLASS.
+!!
+!! Interface:
+!!
+!!    Inputs
+!!             settings  -  settings data structure
+!!             jd        -  julian day of start of month
+!!             nr        -  index to receptor list
+!!
+!!    Externals
+!!             caldate
+!!
+!---------------------------------------------------------------------------------------
+
+module mod_prep_ageclass
+
+  use mod_var
+  use mod_settings
+  use mod_dates
+
+  implicit none
+  private
+
+  public :: prep_ageclass_FP10, prep_ageclass
+
+  character(len=max_path_len)   :: filename
+  character(len=6)              :: adate
+  integer                       :: jjjjmm, jjjjmmdd, hhmiss
+  integer                       :: datei, datef, eomday
+  integer                       :: ierr
+  integer                       :: nageclass, lage
+
+  contains
+
+    ! --------------------------------------------------
+    ! prep_ageclass
+    ! --------------------------------------------------
+    !
+    ! Prepares the AGECLASS file for FLEXPART v11
+    ! --------------------------------------------------
+
+    subroutine prep_ageclass(settings, jd, nr)
+
+      implicit none
+
+      type (settings_t), intent(in) :: settings
+      real(kind=8),      intent(in) :: jd
+      integer,           intent(in) :: nr
+
+      namelist /nage/ &
+        nageclass
+      namelist /ageclass/ &
+        lage
+
+      ! preset namelist variables
+      nageclass = 1
+      lage = settings%ageclass
+
+      call caldate(jd, jjjjmmdd, hhmiss)
+      write(adate,fmt='(I6.6)') jjjjmmdd/100
+      filename = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/AGECLASSES'
+
+      open(100,file=trim(filename),status='replace',action='write',iostat=ierr)
+      write(100,nml=nage)
+      write(100,nml=ageclass)
+      close(100)
+
+    end subroutine prep_ageclass
+
+    ! --------------------------------------------------
+    ! prep_ageclass_FP10
+    ! --------------------------------------------------
+    !
+    ! Prepares the AGECLASS file for FLEXPART v10.4
+    ! --------------------------------------------------
+
+    subroutine prep_ageclass_FP10(settings, jd, nr)
+
+      implicit none
+
+      type (settings_t), intent(in) :: settings
+      real(kind=8),      intent(in) :: jd
+      integer,           intent(in) :: nr
+
+      namelist /ageclass/ &
+        nageclass, &
+        lage
+
+      ! preset namelist variables
+      nageclass = 1
+      lage = settings%ageclass
+
+      call caldate(jd, jjjjmmdd, hhmiss)
+      write(adate,fmt='(I6.6)') jjjjmmdd/100
+      filename = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/AGECLASSES'
+
+      open(100,file=trim(filename),status='replace',action='write',iostat=ierr)
+
+      if( settings%lnamelist.eq.1 ) then
+        ! use namelist file format
+        write(100,nml=ageclass)
+      else
+        ! use old file format
+        write(100,fmt='(A48)') '************************************************'
+        write(100,fmt='(A48)') '*                                              *'
+        write(100,fmt='(A48)') '*Lagrangian particle dispersion model FLEXPART *'
+        write(100,fmt='(A48)') '*         Please select your options           *'
+        write(100,fmt='(A48)') '*                                              *'
+        write(100,fmt='(A48)') '*This file determines the ageclasses to be used*'
+        write(100,fmt='(A48)') '*                                              *'
+        write(100,fmt='(A48)') '*Ages are given in seconds. The first class    *'
+        write(100,fmt='(A48)') '*starts at age zero and goes up to the first   *'
+        write(100,fmt='(A48)') '*age specified. The last age gives the maximum *'
+        write(100,fmt='(A48)') '*time a particle is carried in the simulation. *'
+        write(100,fmt='(A48)') '*                                              *'
+        write(100,fmt='(A48)') '************************************************'
+        write(100,fmt='(A48)') '1          Integer        Number of age classes '
+        write(100,fmt=*) settings%ageclass
+      endif
+
+      close(100)
+
+    end subroutine prep_ageclass_FP10
+
+end module mod_prep_ageclass
+
diff --git a/prep_flexpart/mod_prep_command.f90 b/prep_flexpart/mod_prep_command.f90
new file mode 100644
index 0000000..7020fc5
--- /dev/null
+++ b/prep_flexpart/mod_prep_command.f90
@@ -0,0 +1,359 @@
+!---------------------------------------------------------------------------------------
+! PREP_FLEXPART: mod_prep_command
+!---------------------------------------------------------------------------------------
+!  FLEXINVERT is free software: you can redistribute it and/or modify
+!  it under the terms of the GNU General Public License as published by
+!  the Free Software Foundation, either version 3 of the License, or
+!  (at your option) any later version.
+!
+!  FLEXINVERT is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU General Public License for more details.
+!
+!  You should have received a copy of the GNU General Public License
+!  along with FLEXINVERT.  If not, see <http://www.gnu.org/licenses/>.
+!
+!  Copyright 2017, Rona Thompson
+!---------------------------------------------------------------------------------------
+!
+!> mod_prep_command
+!!
+!! Purpose:    Prepares the options file COMMAND.
+!!
+!! Interface:
+!!
+!!    Inputs
+!!             settings  -  settings data structure
+!!             jd        -  julian day for start of month
+!!             nr        -  index to the receptors list
+!!
+!!    Externals
+!!             caldate
+!!             juldate
+!!
+!---------------------------------------------------------------------------------------
+
+module mod_prep_command
+
+  use mod_var
+  use mod_settings
+  use mod_dates
+  use mod_tools
+
+  implicit none
+  private
+
+  public :: prep_command, prep_command_FP10
+
+  character(len=max_path_len)   :: filename
+  character(len=6)              :: adate
+  real(kind=8)                  :: jdf
+  integer                       :: jjjjmm, jjjjmmdd, hhmiss
+  integer                       :: datei, datef, eomday
+  integer                       :: ierr
+  integer                       :: ldirect                ! runtime mode (currently only backwards: ldirect = -1)
+  integer                       :: ibdate, ibtime
+  integer                       :: iedate, ietime
+  integer                       :: loutstep
+  integer                       :: loutaver
+  integer                       :: loutsample
+  integer                       :: loutrestart
+  integer                       :: itsplit                ! time constant for particle splitting (secs)
+  integer                       :: lsynctime              ! synchronisation interval of flexpart (secs)
+  real                          :: ctl                    ! factor by which time step must be smaller than tl
+  integer                       :: ifine                  ! factor by which to decrease time step for vertical motion
+  integer                       :: iout                   ! output type (1 = concentration/residence time, 2 = mixing ratio, 3 = both, 4 = plume trajectory)
+  integer                       :: ipout                  ! particle dump (0 = never, 1 = every output interval, 2 = only at end)
+  integer                       :: lsubgrid               ! use subgrid terrain effect parameterization (0 = no, 1 = yes)
+  integer                       :: lconvection            ! use convection (0 = no, 1 = yes)
+  integer                       :: lturbulence            ! FP11
+  integer                       :: lturbulence_meso       ! FP11
+  integer                       :: nxshift                ! FP11
+  integer                       :: maxthreadgrid          ! FP11
+  integer                       :: maxfilesize            ! FP11
+  integer                       :: logvertinterp          ! FP11
+  integer                       :: lagespectra            ! calculate age spectra (0 = no, 1 = yes)
+  integer                       :: ipin                   ! continue simulation with dumped particle data (0 = no, 1 = yes)
+  integer                       :: ioutputforeachrelease  ! create output file for each release location (0 = no, 1 = yes)
+  integer                       :: mdomainfill            ! domain filling option (0 = no, 1 = yes)
+  integer                       :: mquasilag              ! quasilagrangian mode to track particles (0 = no, 1 = yes)
+  integer                       :: sfc_only               ! FP11 save only surface layer in grid_time files = 1, full resolution = 0
+  integer                       :: surf_only              ! save only surface layer in grid_time files = 1, full resolution = 0
+  integer                       :: lnetcdfout             ! netcdf output (0 = no, 1 = yes)
+  integer                       :: cblflag                ! 
+  integer                       :: linversionout          ! one grid_time file per release = 1, or per timestep (original format) = 0
+  integer                       :: iflux                  ! calculate fluxes (0 = no, 1 = yes)
+  integer                       :: ind_source
+  integer                       :: ind_receptor
+  integer                       :: nested_output
+  integer                       :: linit_cond
+  character(len=max_path_len)   :: ohfields_path
+
+  contains
+
+    ! --------------------------------------------------
+    ! prep_command
+    ! --------------------------------------------------
+    !
+    ! Prepares COMMAND for FLEXPARTv11
+    ! --------------------------------------------------
+
+    subroutine prep_command(settings, jd, nr)
+  
+      implicit none
+
+      type (settings_t), intent(in) :: settings
+      real(kind=8),      intent(in) :: jd
+      integer,           intent(in) :: nr
+ 
+      namelist /command/ &
+        ldirect, &
+        ibdate,ibtime, &
+        iedate,ietime, &
+        loutstep, &
+        loutaver, &
+        loutsample, &
+        lsynctime, &
+        ctl, &
+        ifine, &
+        iout, &
+        ipout, &
+        lsubgrid, &
+        lconvection, &
+        lturbulence, &
+        lturbulence_meso, &
+        nxshift, &
+        maxthreadgrid, &
+        maxfilesize, &
+        logvertinterp, &
+        loutrestart, &
+        lagespectra, &
+        ipin, &
+        ioutputforeachrelease, &
+        iflux, &
+        mdomainfill, &
+        ind_source, &
+        ind_receptor, &
+        mquasilag, &
+        nested_output, &
+        linit_cond, &
+        lnetcdfout, &
+        sfc_only, &
+        cblflag, &
+        linversionout, &
+        ohfields_path
+
+      ! end of month day
+      call caldate(jd, jjjjmmdd, hhmiss)
+      eomday = calceomday(jjjjmmdd/100)
+
+      ! initialize command file path and name
+      write(adate,fmt='(I6.6)') jjjjmmdd/100
+      filename = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/COMMAND'
+
+      call system('mkdir -p '//trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/')
+
+      ! get dates
+      ! correct start date for length of back trajectory
+      call caldate((jd-settings%ageclass/3600d0/24d0), jjjjmmdd, hhmiss)
+      datei = jjjjmmdd
+      call caldate(jd, jjjjmmdd, hhmiss)
+      jdf = juldate(jjjjmmdd+eomday,0)
+      call caldate(min(jdf,jdatef),jjjjmmdd,hhmiss)
+      datef = jjjjmmdd
+  
+      ! preset namelist variables
+      ldirect = -1
+      ibdate = datei
+      ibtime = 0
+      iedate = datef
+      ietime = 0
+      loutstep = settings%outrate
+      loutaver = settings%outaverage
+      loutsample = settings%outsample
+      itsplit = 999999999
+      lsynctime = lsync
+      ctl = -5
+      ifine = 4
+      iout = 1
+      ipout = 0
+      lsubgrid = 1
+      lconvection = 1
+      lturbulence = 1
+      lturbulence_meso = 0
+      lnetcdfout = 0
+      nxshift = 1
+      maxthreadgrid = 1
+      maxfilesize = 10000
+      logvertinterp = 0
+      loutrestart = -1
+      lagespectra = 1
+      ipin = 0
+      ioutputforeachrelease = 1
+      iflux = 0
+      mdomainfill = 0
+      ind_source = settings%ind_source
+      ind_receptor = settings%ind_receptor
+      mquasilag = 0
+      nested_output = settings%lnested
+      linit_cond = settings%linit_cond
+      sfc_only = 1
+      cblflag = 0
+      linversionout = 1
+      ohfields_path = trim(settings%path_ohfield)
+ 
+      open(100,file=trim(filename),status='replace',action='write',iostat=ierr)    
+      write(100,nml=command)
+      close(100)
+
+    end subroutine prep_command
+ 
+    ! --------------------------------------------------
+    ! prep_command_FP10
+    ! --------------------------------------------------
+    !
+    ! Prepares COMMAND for FLEXPARTv10
+    ! --------------------------------------------------
+
+    subroutine prep_command_FP10(settings, jd, nr)
+
+      implicit none
+
+      type (settings_t), intent(in) :: settings
+      real(kind=8),      intent(in) :: jd
+      integer,           intent(in) :: nr
+
+      namelist /command/ &
+        ldirect, &
+        ibdate,ibtime, &
+        iedate,ietime, &
+        loutstep, &
+        loutaver, &
+        loutsample, &
+        itsplit, &
+        lsynctime, &
+        ctl, &
+        ifine, &
+        iout, &
+        ipout, &
+        lsubgrid, &
+        lconvection, &
+        lagespectra, &
+        ipin, &
+        ioutputforeachrelease, &
+        iflux, &
+        mdomainfill, &
+        ind_source, &
+        ind_receptor, &
+        mquasilag, &
+        nested_output, &
+        linit_cond, &
+        lnetcdfout, &
+        surf_only, &
+        cblflag, &
+        linversionout, &
+        ohfields_path
+
+      ! end of month day
+      call caldate(jd, jjjjmmdd, hhmiss)
+      eomday = calceomday(jjjjmmdd/100)
+
+      ! initialize command file path and name
+      write(adate,fmt='(I6.6)') jjjjmmdd/100
+      filename = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/COMMAND'
+
+      call system('mkdir -p '//trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/')
+
+      ! get dates
+      ! correct start date for length of back trajectory
+      call caldate((jd-settings%ageclass/3600d0/24d0), jjjjmmdd, hhmiss)
+      datei = jjjjmmdd
+      call caldate(jd, jjjjmmdd, hhmiss)
+      jdf = juldate(jjjjmmdd+eomday,0)
+      call caldate(min(jdf,jdatef),jjjjmmdd,hhmiss)
+      datef = jjjjmmdd
+
+      ! preset namelist variables
+      ldirect = -1
+      ibdate = datei
+      ibtime = 0
+      iedate = datef
+      ietime = 0
+      loutstep = settings%outrate
+      loutaver = settings%outaverage
+      loutsample = settings%outsample
+      itsplit = 999999999
+      lsynctime = lsync
+      ctl = -5
+      ifine = 4
+      iout = 1
+      ipout = 2
+      lsubgrid = 1
+      lconvection = 1
+      lagespectra = 1
+      ipin = 0
+      ioutputforeachrelease = 1
+      iflux = 0
+      mdomainfill = 0
+      ind_source = settings%ind_source
+      ind_receptor = settings%ind_receptor
+      mquasilag = 0
+      nested_output = settings%lnested
+      linit_cond = settings%linit_cond
+      lnetcdfout = 0
+      surf_only = 1
+      cblflag = 0
+      linversionout = 1
+      ohfields_path = trim(settings%path_ohfield)
+
+      ! open command file
+      open(100,file=trim(filename),status='replace',action='write',iostat=ierr)
+
+      if( settings%lnamelist.eq.1 ) then
+        ! use namelist file format
+        write(100,nml=command)
+      else
+        ! use old file format
+        write(100,fmt='(A)') '********************************************************************************'
+        write(100,fmt='(A)') '*                                                                              *'
+        write(100,fmt='(A)') '*      Input file for the Lagrangian particle dispersion model FLEXPART        *'
+        write(100,fmt='(A)') '*                           Please select your options                         *'
+        write(100,fmt='(A)') '*                                                                              *'
+        write(100,fmt='(A)') '*                                                                              *'
+        write(100,fmt='(A)') '********************************************************************************'
+        write(100,fmt='(I2)')          ldirect
+        write(100,fmt='(I8,1X,I6.6)')  datei,0
+        write(100,fmt='(I8,1X,I6.6)')  datef,0
+        write(100,fmt='(I5)')          settings%outrate
+        write(100,fmt='(I5)')          settings%outaverage
+        write(100,fmt='(I5)')          settings%outsample
+        write(100,fmt='(I9)')          itsplit
+        write(100,fmt='(I3,3X,A14)')   lsynctime,'SYNC'
+        write(100,fmt='(F5.2,1X,A10)') ctl,'CTL'
+        write(100,fmt='(I3,3X,A14)')   ifine,'IFINE'
+        write(100,fmt='(I1,5X,A14)')   iout,'IOUT'
+        write(100,fmt='(I1,5X,A14)')   ipout,'IPOUT'
+        write(100,fmt='(I1,5X,A14)')   lsubgrid,'LSUBGRID'
+        write(100,fmt='(I1,5X,A14)')   lconvection,'LCONVECTION'
+        write(100,fmt='(I1,5X,A14)')   lagespectra,'LAGESPECTRA'
+        write(100,fmt='(I1,5X,A14)')   ipin,'IPIN'
+        write(100,fmt='(I1,5X,A14)')   ioutputforeachrelease,'IOUTPUTFOREACHRELEASE'
+        write(100,fmt='(I1,5X,A14)')   iflux,'IFLUX'
+        write(100,fmt='(I1,5X,A14)')   mdomainfill,'MDOMAINFILL'
+        write(100,fmt='(I1,5X,A14)')   settings%ind_source,'IND_SOURCE'
+        write(100,fmt='(I1,5X,A14)')   settings%ind_receptor,'IND_RECEPTOR'
+        write(100,fmt='(I1,5X,A14)')   mquasilag,'MQUASILAG'
+        write(100,fmt='(I1,5X,A14)')   settings%lnested,'NESTED_OUTPUT'
+        write(100,fmt='(I1,5X,A14)')   settings%linit_cond,'LINIT_COND'
+        write(100,fmt='(I1,5X,A14)')   sfc_only,'SURF_ONLY'
+        write(100,fmt='(I1,5X,A14)')   linversionout,'LINVERSIONOUT'
+      endif
+
+      close(100)
+
+    end subroutine prep_command_FP10
+
+end module mod_prep_command
+
+
diff --git a/prep_flexpart/mod_settings.f90 b/prep_flexpart/mod_settings.f90
index beb460e..abc5061 100644
--- a/prep_flexpart/mod_settings.f90
+++ b/prep_flexpart/mod_settings.f90
@@ -48,10 +48,17 @@ module mod_settings
     character(len=max_name_len)     :: windfield
     character(len=max_name_len)     :: obsformat
     character(len=max_name_len)     :: suffix
+    integer                         :: lscratch
+    integer                         :: FPversion
+
+    integer                         :: nreagent
+    character(len=max_path_len), dimension(:), allocatable :: path_reagents
+    character(len=max_name_len), dimension(:), allocatable :: reagent_units
+    integer, dimension(:), allocatable :: reagent_interp
 
-    integer                         :: lFPversion
     integer                         :: lselect
     integer                         :: lrelease
+    integer                         :: lappendfile
     real                            :: relfreq
     integer                         :: laverage
     real                            :: intaverage
@@ -296,6 +303,9 @@ module mod_settings
         stop
       endif
 
+      ! default settings
+      settings%lscratch = 1  ! use scratch drive
+
       ! loop over lines
       read_loop: do
         read (100, fmt='(A)', iostat=ierr) line
@@ -313,6 +323,9 @@ module mod_settings
           if ( len   (trim (line))      .eq. 0 ) cycle read_loop
 
           ! Path and file settings
+          identifier = "lscratch:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) settings%lscratch = int(cn)
           identifier = "path_flexpart:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%path_flexpart = cc
@@ -349,17 +362,64 @@ module mod_settings
           identifier = "windfield:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%windfield = cc
+          identifier = "FPversion:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) settings%FPversion = int(cn)
 
-          ! General settings
-          identifier = "lFPversion:"
+          ! Species settings
+          identifier = "nreagent:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) settings%nreagent = int(cn)
+          identifier = "path_reagents:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) then
+            call parse_string(cc, ',', temp, n)
+            if ( n.ne.settings%nreagent ) then
+              write(*,*) 'ERROR reading SETTINGS: number of reagent paths not equal to nreagent'
+              stop
+            endif
+            allocate( settings%path_reagents(settings%nreagent) )
+            do i=1,settings%nreagent
+              settings%path_reagents(i) = trim(temp(i))
+            end do
+          endif
+          identifier = "reagent_units:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) then
+            call parse_string(cc, ',', temp, n)
+            if ( n.ne.settings%nreagent ) then
+              write(*,*) 'ERROR reading SETTINGS: number of reagent units not equal to nreagent'
+              stop
+            endif
+            allocate( settings%reagent_units(settings%nreagent) )
+            do i=1,settings%nreagent
+              settings%reagent_units(i) = trim(temp(i))
+            end do
+          endif
+          identifier = "reagent_interp:"
           call read_content (line, identifier, cc, cn, cl, match)
-          if ( match ) settings%lFPversion = int(cn)
+          if ( match ) then
+            call parse_string(cc, ',', temp, n)
+            if ( n.ne.settings%nreagent ) then
+              write(*,*) 'ERROR reading SETTINGS: number of flags for interpolation not equal to nreagent'
+              stop
+            endif
+            allocate( settings%reagent_interp(settings%nreagent) )
+            do i=1,settings%nreagent
+              read(temp(i),*) settings%reagent_interp(i) 
+            end do
+          endif
+
+          ! General settings
           identifier = "lselect:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%lselect = int(cn)
           identifier = "lrelease:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%lrelease = int(cn)
+          identifier = "lappendfile:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) settings%lappendfile = int(cn)
           identifier = "relfreq:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%relfreq = real(cn)
@@ -374,7 +434,7 @@ module mod_settings
           if ( match ) settings%lnamelist = int(cn)
           identifier = "measerr:"
           call read_content (line, identifier, cc, cn, cl, match)
-          if ( match ) settings%measerr = int(cn)
+          if ( match ) settings%measerr = real(cn)
 
           ! COMMAND settings
           identifier = "datei:"
@@ -485,6 +545,17 @@ module mod_settings
       print*, 'path_flexpart: ',trim(settings%path_flexpart)
       print*, 'path_options: ',trim(settings%path_options)
 
+      ! Some checks
+      if ( settings%FPversion.lt.10.or.settings%FPversion.gt.11 ) then
+        write(*,*) 'ERROR: FPversion must be either 10 or 11'
+        stop
+      endif
+      if ( settings%lnamelist.ne.1.and.settings%FPversion.eq.11 ) then
+        write(*,*) 'WARNING: only namelist file format available for FPversion 11'
+        settings%lnamelist = 1
+      endif
+      
+      nreagent = settings%nreagent
 
     end subroutine read_settings
 
diff --git a/prep_flexpart/mod_var.f90 b/prep_flexpart/mod_var.f90
index 05fbe5d..606809e 100644
--- a/prep_flexpart/mod_var.f90
+++ b/prep_flexpart/mod_var.f90
@@ -36,6 +36,7 @@ module mod_var
   real(kind=8)                                  :: jreldatei, jreldatef
   integer                                       :: nrec
   integer                                       :: nfiles
+  integer                                       :: nreagent
   character(len=recname_len), dimension(:), allocatable   :: recname
   character(len=256), dimension(:), allocatable :: filelist
   real, dimension(:), allocatable               :: reclon, reclat, recalt
diff --git a/prep_flexpart/prep_ageclass.f90 b/prep_flexpart/prep_ageclass.f90
deleted file mode 100644
index fbeac57..0000000
--- a/prep_flexpart/prep_ageclass.f90
+++ /dev/null
@@ -1,99 +0,0 @@
-!---------------------------------------------------------------------------------------
-! PREP_FLEXPART: prep_ageclass
-!---------------------------------------------------------------------------------------
-!  FLEXINVERT is free software: you can redistribute it and/or modify
-!  it under the terms of the GNU General Public License as published by
-!  the Free Software Foundation, either version 3 of the License, or
-!  (at your option) any later version.
-!
-!  FLEXINVERT is distributed in the hope that it will be useful,
-!  but WITHOUT ANY WARRANTY; without even the implied warranty of
-!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-!  GNU General Public License for more details.
-!
-!  You should have received a copy of the GNU General Public License
-!  along with FLEXINVERT.  If not, see <http://www.gnu.org/licenses/>.
-!
-!  Copyright 2017, Rona Thompson
-!---------------------------------------------------------------------------------------
-!
-!> prep_ageclass
-!!
-!! Purpose:    Prepares the options file AGECLASS.
-!!
-!! Interface:
-!!
-!!    Inputs
-!!             settings  -  settings data structure
-!!             jd        -  julian day of start of month
-!!             nr        -  index to receptor list
-!!
-!!    Externals
-!!             caldate
-!!
-!---------------------------------------------------------------------------------------
-
-subroutine prep_ageclass(settings, jd, nr)
-
-  use mod_var
-  use mod_settings
-  use mod_dates
-
-  implicit none
-
-  type (settings_t), intent(in) :: settings
-  real(kind=8),      intent(in) :: jd
-  integer,           intent(in) :: nr
-
-  character(len=max_path_len)   :: filename
-  character(len=6)              :: adate
-  integer                       :: jjjjmm, jjjjmmdd, hhmiss
-  integer                       :: datei, datef, eomday
-  integer                       :: ierr
-  integer                       :: nageclass, lage
-
-
-  ! FP 11
-  namelist /nage/ &
-      nageclass
-  namelist /ageclass/ &
-      lage
-
- 
-
-  ! preset namelist variables
-  nageclass = 1
-  lage = settings%ageclass
-
-  call caldate(jd, jjjjmmdd, hhmiss)
-  write(adate,fmt='(I6.6)') jjjjmmdd/100
-  filename = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/AGECLASSES'
-
-  open(100,file=trim(filename),status='replace',action='write',iostat=ierr)
-
-  if( settings%lnamelist.eq.1 ) then
-    ! use namelist file format, FP11
-    write(100,nml=nage)
-    write(100,nml=ageclass)
-  else
-    ! use old file format
-    write(100,fmt='(A48)') '************************************************'
-    write(100,fmt='(A48)') '*                                              *'
-    write(100,fmt='(A48)') '*Lagrangian particle dispersion model FLEXPART *'
-    write(100,fmt='(A48)') '*         Please select your options           *'
-    write(100,fmt='(A48)') '*                                              *'
-    write(100,fmt='(A48)') '*This file determines the ageclasses to be used*'
-    write(100,fmt='(A48)') '*                                              *'
-    write(100,fmt='(A48)') '*Ages are given in seconds. The first class    *'
-    write(100,fmt='(A48)') '*starts at age zero and goes up to the first   *'
-    write(100,fmt='(A48)') '*age specified. The last age gives the maximum *'
-    write(100,fmt='(A48)') '*time a particle is carried in the simulation. *'
-    write(100,fmt='(A48)') '*                                              *'
-    write(100,fmt='(A48)') '************************************************'
-    write(100,fmt='(A48)') '1          Integer        Number of age classes '
-    write(100,fmt=*) settings%ageclass
-  endif
-
-  close(100)
-
-end subroutine prep_ageclass
diff --git a/prep_flexpart/prep_command.f90 b/prep_flexpart/prep_command.f90
deleted file mode 100644
index 9a310e9..0000000
--- a/prep_flexpart/prep_command.f90
+++ /dev/null
@@ -1,241 +0,0 @@
-!---------------------------------------------------------------------------------------
-! PREP_FLEXPART: prep_command
-!---------------------------------------------------------------------------------------
-!  FLEXINVERT is free software: you can redistribute it and/or modify
-!  it under the terms of the GNU General Public License as published by
-!  the Free Software Foundation, either version 3 of the License, or
-!  (at your option) any later version.
-!
-!  FLEXINVERT is distributed in the hope that it will be useful,
-!  but WITHOUT ANY WARRANTY; without even the implied warranty of
-!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-!  GNU General Public License for more details.
-!
-!  You should have received a copy of the GNU General Public License
-!  along with FLEXINVERT.  If not, see <http://www.gnu.org/licenses/>.
-!
-!  Copyright 2017, Rona Thompson
-!---------------------------------------------------------------------------------------
-!
-!> prep_command
-!!
-!! Purpose:    Prepares the options file COMMAND.
-!!
-!! Interface:
-!!
-!!    Inputs
-!!             settings  -  settings data structure
-!!             jd        -  julian day for start of month
-!!             nr        -  index to the receptors list
-!!
-!!    Externals
-!!             caldate
-!!             juldate
-!!
-!---------------------------------------------------------------------------------------
-
-subroutine prep_command(settings, jd, nr)
-
-  use mod_var
-  use mod_settings
-  use mod_dates
-  use mod_tools
-
-  implicit none
-
-  type (settings_t), intent(in) :: settings
-  real(kind=8),      intent(in) :: jd
-  integer,           intent(in) :: nr
-
-  character(len=max_path_len)   :: filename
-  character(len=6)              :: adate
-  real(kind=8)                  :: jdf
-  integer                       :: jjjjmm, jjjjmmdd, hhmiss
-  integer                       :: datei, datef, eomday
-  integer                       :: ierr
-
-  integer                       :: ldirect                ! runtime mode (currently only backwards: ldirect = -1)
-  integer                       :: ibdate, ibtime
-  integer                       :: iedate, ietime
-!  integer                       :: partsplit
-  integer                       :: loutstep
-  integer                       :: loutaver
-  integer                       :: loutsample
-  integer                       :: loutrestart
-!  integer                       :: itsplit                ! time constant for particle splitting (secs)
-  integer                       :: lsynctime              ! synchronisation interval of flexpart (secs)
-  real                          :: ctl                    ! factor by which time step must be smaller than tl
-  integer                       :: ifine                  ! factor by which to decrease time step for vertical motion
-  integer                       :: iout                   ! output type (1 = concentration/residence time, 2 = mixing ratio, 3 = both, 4 = plume trajectory)
-  integer                       :: ipout                  ! particle dump (0 = never, 1 = every output interval, 2 = only at end)
-  integer                       :: lsubgrid               ! use subgrid terrain effect parameterization (0 = no, 1 = yes)
-  integer                       :: lconvection            ! use convection (0 = no, 1 = yes)
-  integer                       :: lturbulence            ! FP11
-  integer                       :: lturbulence_meso       ! FP11
-  integer                       :: nxshift                ! FP11
-  integer                       :: maxthreadgrid          ! FP11
-  integer                       :: maxfilesize            ! FP11
-  integer                       :: logvertinterp          ! FP11
-  integer                       :: bcscheme               ! FP11
-  integer                       :: lagespectra            ! calculate age spectra (0 = no, 1 = yes)
-  integer                       :: ipin                   ! continue simulation with dumped particle data (0 = no, 1 = yes)
-  integer                       :: ioutputforeachrelease  ! create output file for each release location (0 = no, 1 = yes)
-  integer                       :: mdomainfill            ! domain filling option (0 = no, 1 = yes)
-  integer                       :: mquasilag              ! quasilagrangian mode to track particles (0 = no, 1 = yes)
-  integer                       :: sfc_only              ! save only surface layer in grid_time files = 1, full resolution = 0
-  integer                       :: lnetcdfout             ! netcdf output (0 = no, 1 = yes)
-  integer                       :: cblflag                ! 
-  integer                       :: linversionout          ! one grid_time file per release = 1, or per timestep (original format) = 0
-  integer                       :: iflux                  ! calculate fluxes (0 = no, 1 = yes)
-  integer                       :: ind_source
-  integer                       :: ind_receptor
-  integer                       :: nested_output
-  integer                       :: linit_cond
-  character(len=max_path_len)   :: ohfields_path
-
-  namelist /command/ &
-    ldirect, &
-    ibdate,ibtime, &
-    iedate,ietime, &
-    loutstep, &
-    loutaver, &
-    loutsample, &
-!    itsplit, &
-    lsynctime, &
-    ctl, &
-    ifine, &
-    iout, &
-    ipout, &
-    lsubgrid, &
-    lconvection, &
-    lturbulence, &
-    lturbulence_meso, &
-    nxshift, &
-    maxthreadgrid, &
-    maxfilesize, &
-    logvertinterp, &
-    bcscheme, &
-    loutrestart, &
-    lagespectra, &
-    ipin, &
-    ioutputforeachrelease, &
-    iflux, &
-    mdomainfill, &
-    ind_source, &
-    ind_receptor, &
-    mquasilag, &
-    nested_output, &
-    linit_cond, &
-    lnetcdfout, &
-    sfc_only, &
-    cblflag, &
-    linversionout, &
-    ohfields_path
-
-  ! end of month day
-  call caldate(jd, jjjjmmdd, hhmiss)
-  eomday = calceomday(jjjjmmdd/100)
-
-  ! initialize command file path and name
-  write(adate,fmt='(I6.6)') jjjjmmdd/100
-  filename = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/COMMAND'
-
-  call system('mkdir -p '//trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/')
-
-  ! get dates
-  ! correct start date for length of back trajectory
-  call caldate((jd-settings%ageclass/3600d0/24d0), jjjjmmdd, hhmiss)
-  datei = jjjjmmdd
-  call caldate(jd, jjjjmmdd, hhmiss)
-  jdf = juldate(jjjjmmdd+eomday,0)
-  call caldate(min(jdf,jdatef),jjjjmmdd,hhmiss)
-  datef = jjjjmmdd
-
-  ! preset namelist variables
-  ldirect = -1
-  ibdate = datei
-  ibtime = 0
-  iedate = datef
-  ietime = 0
-  loutstep = settings%outrate
-  loutaver = settings%outaverage
-  loutsample = settings%outsample
-!  itsplit = 999999999
-  lsynctime = lsync
-  ctl = -5
-  ifine = 4
-  iout = 1
-  ipout = 0
-  lsubgrid = 1
-  lconvection = 1
-  lturbulence = 1
-  lturbulence_meso = 0
-  lnetcdfout = 0
-  nxshift = 1
-  maxthreadgrid = 1
-  maxfilesize = 10000
-  logvertinterp = 0
-  bcscheme = 1
-  loutrestart = -1
-  lagespectra = 1
-  ipin = 0
-  ioutputforeachrelease = 1
-  iflux = 0
-  mdomainfill = 0
-  ind_source = settings%ind_source
-  ind_receptor = settings%ind_receptor
-  mquasilag = 0
-  nested_output = settings%lnested
-  linit_cond = settings%linit_cond
-  sfc_only = 1
-  cblflag = 0
-  linversionout = 1
-  ohfields_path = trim(settings%path_ohfield)
-
-  ! open command file
-  open(100,file=trim(filename),status='replace',action='write',iostat=ierr)    
-
-  if( settings%lnamelist.eq.1 ) then
-    ! use namelist file format
-    write(100,nml=command)
-  else
-    ! use old file format
-    write(100,fmt='(A)') '********************************************************************************'
-    write(100,fmt='(A)') '*                                                                              *'
-    write(100,fmt='(A)') '*      Input file for the Lagrangian particle dispersion model FLEXPART        *'
-    write(100,fmt='(A)') '*                           Please select your options                         *'
-    write(100,fmt='(A)') '*                                                                              *'
-    write(100,fmt='(A)') '*                                                                              *'
-    write(100,fmt='(A)') '********************************************************************************'
-    write(100,fmt='(I2)')          ldirect
-    write(100,fmt='(I8,1X,I6.6)')  datei,0
-    write(100,fmt='(I8,1X,I6.6)')  datef,0
-    write(100,fmt='(I5)')          settings%outrate
-    write(100,fmt='(I5)')          settings%outaverage
-    write(100,fmt='(I5)')          settings%outsample
-!    write(100,fmt='(I9)')          itsplit
-    write(100,fmt='(I3,3X,A14)')   lsynctime,'SYNC'
-    write(100,fmt='(F5.2,1X,A10)') ctl,'CTL'
-    write(100,fmt='(I3,3X,A14)')   ifine,'IFINE'
-    write(100,fmt='(I1,5X,A14)')   iout,'IOUT'
-    write(100,fmt='(I1,5X,A14)')   ipout,'IPOUT'
-    write(100,fmt='(I1,5X,A14)')   lsubgrid,'LSUBGRID'
-    write(100,fmt='(I1,5X,A14)')   lconvection,'LCONVECTION'
-    write(100,fmt='(I1,5X,A14)')   lagespectra,'LAGESPECTRA'
-    write(100,fmt='(I1,5X,A14)')   ipin,'IPIN'
-    write(100,fmt='(I1,5X,A14)')   ioutputforeachrelease,'IOUTPUTFOREACHRELEASE'
-    write(100,fmt='(I1,5X,A14)')   iflux,'IFLUX'
-    write(100,fmt='(I1,5X,A14)')   mdomainfill,'MDOMAINFILL'
-    write(100,fmt='(I1,5X,A14)')   settings%ind_source,'IND_SOURCE'
-    write(100,fmt='(I1,5X,A14)')   settings%ind_receptor,'IND_RECEPTOR'
-    write(100,fmt='(I1,5X,A14)')   mquasilag,'MQUASILAG'
-    write(100,fmt='(I1,5X,A14)')   settings%lnested,'NESTED_OUTPUT'
-    write(100,fmt='(I1,5X,A14)')   settings%linit_cond,'LINIT_COND'
-    write(100,fmt='(I1,5X,A14)')   sfc_only,'SURF_ONLY'
-    write(100,fmt='(I1,5X,A14)')   linversionout,'LINVERSIONOUT'
-  endif
-
-  close(100)
-
-end subroutine prep_command
-
diff --git a/prep_flexpart/prep_outgrid.f90 b/prep_flexpart/prep_outgrid.f90
index 4be6291..8d55f9f 100644
--- a/prep_flexpart/prep_outgrid.f90
+++ b/prep_flexpart/prep_outgrid.f90
@@ -84,7 +84,7 @@ subroutine prep_outgrid(settings, jd, nr)
     if ( settings%windfield.eq.'oper' ) then
       outlon0 = -179.
     else if ( settings%windfield.eq.'era5' ) then
-      outlon0 = -179.5
+      outlon0 = -179.
     else
       write(*,*) 'ERROR: prep_outgrid: unknown windfield type'
       stop
diff --git a/prep_flexpart/prep_pathnames.f90 b/prep_flexpart/prep_pathnames.f90
index 7e16d98..28fa2a1 100644
--- a/prep_flexpart/prep_pathnames.f90
+++ b/prep_flexpart/prep_pathnames.f90
@@ -59,16 +59,21 @@ subroutine prep_pathnames(settings, jd, nr)
 
   open(100,file=trim(filename),status='replace',action='write',iostat=ierr)
 
-  write(100,fmt='(A)') trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/'
-  write(100,fmt='(A)') trim(settings%path_output)//trim(recname(nr))//'/'//adate//'/'
+  if ( settings%lscratch.eq.0 ) then
+    ! not using scratch
+    write(100,fmt='(A)') trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/'
+    write(100,fmt='(A)') trim(settings%path_output)//trim(recname(nr))//'/'//adate//'/'
+  else
+    ! using scratch
+    write(100,fmt='(A)') './options/'
+    write(100,fmt='(A)') './output/'
+  endif
   write(100,fmt='(A1)') '/'
   write(100,fmt='(A)') trim(settings%file_avail)
 
-  if( settings%lnested.eq.1 ) then
+  if( settings%file_availnest.ne.'' ) then
     write(100,fmt='(A1)') '/'
     write(100,fmt='(A)') trim(settings%file_availnest)
-    write(100,fmt='(A)') '============================================'
-    write(100,fmt='(A1)') ' '
   endif
 
   close(100)
diff --git a/prep_flexpart/prep_reagents.f90 b/prep_flexpart/prep_reagents.f90
new file mode 100644
index 0000000..9673f7d
--- /dev/null
+++ b/prep_flexpart/prep_reagents.f90
@@ -0,0 +1,73 @@
+!---------------------------------------------------------------------------------------
+! PREP_FLEXPART: prep_reagents
+!---------------------------------------------------------------------------------------
+!  FLEXINVERT is free software: you can redistribute it and/or modify
+!  it under the terms of the GNU General Public License as published by
+!  the Free Software Foundation, either version 3 of the License, or
+!  (at your option) any later version.
+!
+!  FLEXINVERT is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU General Public License for more details.
+!
+!  You should have received a copy of the GNU General Public License
+!  along with FLEXINVERT.  If not, see <http://www.gnu.org/licenses/>.
+!
+!  Copyright 2017, Rona Thompson
+!---------------------------------------------------------------------------------------
+!
+!> prep_reagents
+!!
+!! Purpose:    Prepares the options file REAGENTS
+!!
+!! Interface:
+!!
+!!    Inputs
+!!             settings  -  settings data structure
+!!             reagent   -  character string of reagent name (see SPECIES files)
+!!
+!---------------------------------------------------------------------------------------
+
+subroutine prep_reagents(settings,reagents,nr,jd)
+
+  use mod_var
+  use mod_dates
+  use mod_settings
+
+  implicit none
+
+  type (settings_t), intent(in)      :: settings
+  character(len=6), dimension(nreagent), intent(in) :: reagents
+  integer, intent(in)                :: nr
+  real(kind=8), intent(in)           :: jd
+
+  character(len=max_path_len)        :: filename, preag_path
+  character(len=max_name_len)        :: preagent, punit
+  character(len=6)                   :: adate
+  integer                            :: phourly
+  integer                            :: jjjjmmdd, hhmiss, ierr, n
+
+  namelist /reagent_params/ &
+    preagent, &
+    preag_path, &
+    phourly, &
+    punit
+
+  call caldate(jd, jjjjmmdd, hhmiss)
+  write(adate,fmt='(I6.6)') jjjjmmdd/100
+  filename = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/REAGENTS'
+  open(100,file=trim(filename),status='replace',action='write',iostat=ierr)
+  do n = 1, nreagent
+    if (reagents(n).ne."") then
+      preagent = trim(reagents(n))
+      preag_path = trim(settings%path_reagents(n))
+      phourly = settings%reagent_interp(n)
+      punit = trim(settings%reagent_units(n))
+      write(100,nml=reagent_params)
+    endif
+  end do
+  close(100)
+  
+end subroutine prep_reagents
+
diff --git a/prep_flexpart/prep_releases.f90 b/prep_flexpart/prep_releases.f90
index a015180..2dd83d1 100644
--- a/prep_flexpart/prep_releases.f90
+++ b/prep_flexpart/prep_releases.f90
@@ -43,6 +43,7 @@ subroutine prep_releases(settings, jd, nr, nobs, obs)
   use mod_dates
   use mod_obs
   use mod_tools
+  use mod_strings
 
   implicit none
 
@@ -70,6 +71,23 @@ subroutine prep_releases(settings, jd, nr, nobs, obs)
   integer                       :: zkind, parts
   real                          :: mass
   character(len=40)             :: comment
+  logical                       :: lexist
+
+  character(len=16)  :: pspecies, pemis_name
+  character(len=256) :: pemis_path, pemis_file
+  integer :: pemis_unit
+  real :: pemis_coeff
+  real :: pdecay, pweta_gas, pwetb_gas, preldiff, phenry, pf0, pdensity, pdquer
+  real :: pdsigma, pdryvel, pweightmolar, pdia
+  character(len=10), allocatable, dimension(:) :: preactions
+  real, allocatable, dimension(:) :: pcconst, pdconst, pnconst 
+  real, allocatable, dimension(:) :: pohnconst, pohcconst, pohdconst
+  real :: pcrain_aero, pcsnow_aero, pccn_aero, pin_aero
+  real :: parea_dow(7), parea_hour(24), ppoint_dow(7), ppoint_hour(24)
+  integer :: ios
+  integer :: pshape,porient
+  real ::pla,pia,psa,f,e,paspectratio
+
 
   namelist /releases_ctrl/ &
     nspec, &
@@ -86,20 +104,65 @@ subroutine prep_releases(settings, jd, nr, nobs, obs)
     parts, &
     comment
 
+  namelist /species_params/ &
+       pspecies, pdecay, pweta_gas, pwetb_gas, &
+       pcrain_aero, pcsnow_aero, pccn_aero, pin_aero, &
+       preldiff, phenry, pf0, pdensity, pdquer, pdia, &
+       pdsigma, pdryvel, pweightmolar, pohnconst, &
+       preactions, pcconst, pdconst, pnconst, pohcconst, pohdconst, &
+       pemis_path, pemis_file, pemis_name, pemis_unit, pemis_coeff, &
+       parea_dow, parea_hour, ppoint_dow, ppoint_hour, &
+       pshape, paspectratio, pla, pia, psa, porient
+
   call caldate(jd, jjjjmmdd, hhmiss)
   write(adate,fmt='(I6.6)') jjjjmmdd/100
 
   ! read species file
-  open(100,file=trim(settings%path_flexpart)//'options/SPECIES/spec_overview',status='old',action='read',iostat=ierr)
-  nchar = len_trim(settings%species)
-  do while ( ierr.eq.0 )
-    read (100, fmt='(A)', iostat=ierr) line
-! sec - reads the last char   if ( line(len_trim(line)-nchar+1:len_trim(line)) == trim(settings%species) ) ierr = 1
-    if ( line(5:5+nchar-1) == trim(settings%species) ) ierr = 1
-  end do
-! sec - read(line(9:11),*) spec
-  read(line(1:3),*) spec
-  write(aspec,fmt='(I3.3)') spec
+  if ( settings%FPversion.eq.10 ) then
+    inquire(file=trim(settings%path_flexpart)//'options/SPECIES/spec_overview',exist=lexist)
+    if ( .not.lexist ) then
+      write(*,*) 'ERROR: cannot find file /options/SPECIES/spec_overview'
+      stop
+    endif
+    open(100,file=trim(settings%path_flexpart)//'options/SPECIES/spec_overview',status='old',action='read',iostat=ierr)
+    nchar = len_trim(settings%species)
+    do while ( ierr.eq.0 )
+      read (100, fmt='(A)', iostat=ierr) line
+      if ( line(len_trim(line)-nchar+1:len_trim(line)) == trim(settings%species) ) ierr = 1
+    end do
+    read(line(9:11),*) spec
+    write(aspec,fmt='(I3.3)') spec
+  else if ( settings%FPversion.eq.11 ) then
+    ! FPv11 new version SPECIES files contain species name not number
+    spec = 1
+    inquire(file=trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//to_upper(trim(settings%species)),&
+            exist=lexist)
+    if ( .not.lexist ) then
+      write(*,*) 'ERROR: cannot find file /options/SPECIES/SPECIES_'//to_upper(trim(settings%species))
+      stop
+    endif
+    write(aspec,fmt='(I3.3)') spec    
+    call system('cp '//trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//to_upper(trim(settings%species))//&
+                ' '//trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//aspec)
+    write(aspec,fmt='(I3.3)') spec    
+    ! read SPECIES file for reagents info
+    allocate(preactions(nreagent))
+    allocate(pcconst(nreagent))
+    allocate(pdconst(nreagent))
+    allocate(pnconst(nreagent))
+    open(100,file=trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//to_upper(trim(settings%species)),&
+          action='read',iostat=ierr)
+    read(100,species_params,iostat=ierr)
+    if ( ierr.ne.0 ) then
+      write(*,*) 'ERROR: reading SPECIES_'//to_upper(trim(settings%species))
+      stop
+    endif
+    write(*,*) 'Chemical reactions: ',preactions
+    if (any(preactions.ne."")) then
+      ! write reagents file
+      call prep_reagents(settings,preactions,nr,jd)
+    endif
+  endif
 
   ! preset namelist variables releases_ctrl
   nspec = 1
@@ -108,7 +171,7 @@ subroutine prep_releases(settings, jd, nr, nobs, obs)
   ! copy standard input files to options folder
   pathname = trim(settings%path_options)//trim(recname(nr))//'/'//adate//'/options/'
   call system('mkdir -p '//trim(pathname)//'SPECIES/')
-  filename = trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//aspec
+  filename = trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//trim(aspec)
   call system('cp '//trim(filename)//' '//trim(pathname)//'SPECIES/')
   call system('cp '//trim(settings%path_flexpart)//'options/*.dat'//' '//trim(pathname))
   call system('cp '//trim(settings%path_flexpart)//'options/*.t'//' '//trim(pathname))
diff --git a/prep_flexpart/prep_releases_reg.f90 b/prep_flexpart/prep_releases_reg.f90
index 9cc5ff3..1b2f182 100644
--- a/prep_flexpart/prep_releases_reg.f90
+++ b/prep_flexpart/prep_releases_reg.f90
@@ -45,6 +45,7 @@ subroutine prep_releases_reg(settings, jd, nr)
   use mod_settings
   use mod_dates
   use mod_tools
+  use mod_strings
 
   implicit none
 
@@ -72,6 +73,22 @@ subroutine prep_releases_reg(settings, jd, nr)
   integer                       :: zkind, parts
   real                          :: mass
   character(len=40)             :: comment
+  logical                       :: lexist
+
+  character(len=16)  :: pspecies, pemis_name
+  character(len=256) :: pemis_path, pemis_file
+  integer :: pemis_unit
+  real :: pemis_coeff
+  real :: pdecay, pweta_gas, pwetb_gas, preldiff, phenry, pf0, pdensity, pdquer
+  real :: pdsigma, pdryvel, pweightmolar, pdia
+  character(len=10), allocatable, dimension(:) :: preactions
+  real, allocatable, dimension(:) :: pcconst, pdconst, pnconst
+  real, allocatable, dimension(:) :: pohnconst, pohcconst, pohdconst
+  real :: pcrain_aero, pcsnow_aero, pccn_aero, pin_aero
+  real :: parea_dow(7), parea_hour(24), ppoint_dow(7), ppoint_hour(24)
+  integer :: ios
+  integer :: pshape,porient
+  real ::pla,pia,psa,f,e,paspectratio
 
   namelist /releases_ctrl/ &
     nspec, &
@@ -88,6 +105,16 @@ subroutine prep_releases_reg(settings, jd, nr)
     parts, &
     comment
 
+  namelist /species_params/ &
+       pspecies, pdecay, pweta_gas, pwetb_gas, &
+       pcrain_aero, pcsnow_aero, pccn_aero, pin_aero, &
+       preldiff, phenry, pf0, pdensity, pdquer, pdia, &
+       pdsigma, pdryvel, pweightmolar, pohnconst, &
+       preactions, pcconst, pdconst, pnconst, pohcconst, pohdconst, &
+       pemis_path, pemis_file, pemis_name, pemis_unit, pemis_coeff, &
+       parea_dow, parea_hour, ppoint_dow, ppoint_hour, &
+       pshape, paspectratio, pla, pia, psa, porient
+
   ! initialize date/time variables
   call caldate(jd, jjjjmmdd, hhmiss)
   write(adate,fmt='(I6.6)') jjjjmmdd/100
@@ -100,14 +127,51 @@ subroutine prep_releases_reg(settings, jd, nr)
   print*, 'prep_releases_reg: jdf = ',jdf
 
   ! read species file
-  open(100,file=trim(settings%path_flexpart)//'options/SPECIES/spec_overview',status='old',action='read',iostat=ierr)
-  nchar = len_trim(settings%species)
-  do while ( ierr.eq.0 )
-    read (100, fmt='(A)', iostat=ierr) line
-    if ( line(len_trim(line)-nchar+1:len_trim(line)) == trim(settings%species) ) ierr = 1
-  end do
-  read(line(9:11),*) spec
-  write(aspec,fmt='(I3.3)') spec
+  if ( settings%FPversion.eq.10 ) then
+    inquire(file=trim(settings%path_flexpart)//'options/SPECIES/spec_overview',exist=lexist)
+    if ( .not.lexist ) then
+      write(*,*) 'ERROR: cannot fine file /options/SPECIES/spec_overview'
+      stop
+    endif
+    open(100,file=trim(settings%path_flexpart)//'options/SPECIES/spec_overview',status='old',action='read',iostat=ierr)
+    nchar = len_trim(settings%species)
+    do while ( ierr.eq.0 )
+      read (100, fmt='(A)', iostat=ierr) line
+      if ( line(len_trim(line)-nchar+1:len_trim(line)) == trim(settings%species) ) ierr = 1
+    end do
+    read(line(9:11),*) spec
+    write(aspec,fmt='(I3.3)') spec
+  else if ( settings%FPversion.eq.11 ) then
+    ! FPv11 new version SPECIES files contain species name not number
+    spec = 1
+    inquire(file=trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//to_upper(trim(settings%species)),&
+            exist=lexist)
+    if ( .not.lexist ) then
+      write(*,*) 'ERROR: cannot find file /options/SPECIES/SPECIES_'//to_upper(trim(settings%species))
+      stop
+    endif
+    write(aspec,fmt='(I3.3)') spec
+    call system('cp '//trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//to_upper(trim(settings%species))//&
+                ' '//trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//aspec)
+    write(aspec,fmt='(I3.3)') spec
+    ! read SPECIES file for reagents info
+    allocate(preactions(nreagent))
+    allocate(pcconst(nreagent))
+    allocate(pdconst(nreagent))
+    allocate(pnconst(nreagent))
+    open(100,file=trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//to_upper(trim(settings%species)),&
+          action='read',iostat=ierr)
+    read(100,species_params,iostat=ierr)
+    if ( ierr.ne.0 ) then
+      write(*,*) 'ERROR: reading SPECIES_'//to_upper(trim(settings%species))
+      stop
+    endif
+    write(*,*) 'Chemical reactions: ',preactions
+    if (any(preactions.ne."")) then
+      ! write reagents file
+      call prep_reagents(settings,preactions,nr,jd)
+    endif
+  endif
 
   ! preset namelist variables releases_ctrl
   nspec = 1
diff --git a/prep_flexpart/read_basic.f90 b/prep_flexpart/read_basic.f90
index 9f29efa..52f25ae 100644
--- a/prep_flexpart/read_basic.f90
+++ b/prep_flexpart/read_basic.f90
@@ -63,6 +63,7 @@ subroutine read_basic(settings, jd, nr, nobs, obs)
   character(len=max_path_len)                           :: rowfmt
   character(len=200)                                    :: line
   character(len=200), dimension(50)                     :: args
+  character(len=6)                                      :: adate
   character(len=3)                                      :: flag
   real, dimension(12)                                   :: temp
   logical                                               :: lexist
@@ -166,7 +167,7 @@ subroutine read_basic(settings, jd, nr, nobs, obs)
 
   ! no observations go to end
   if ( nobs.eq.0 ) then
-    call caldate(jdate, jjjjmmdd, hhmiss)
+    call caldate(jd, jjjjmmdd, hhmiss)
     print*, 'WARNING: no data for ',trim(recname(nr)),' in year/month ',jjjjmmdd/100
     go to 20
   endif
@@ -181,7 +182,17 @@ subroutine read_basic(settings, jd, nr, nobs, obs)
   if ( nobs.eq.0 ) go to 20
 
   ! write formatted obs to file
-  file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.gob'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    ! generic output directory
+    file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  else
+    ! do not append to file when this is a new run
+    ! create subdirectory for ouput based on start year, month
+    call caldate(jdatei, jjjjmmdd, hhmiss)
+    write(adate,'(I6)') jjjjmmdd/100
+    file_out = trim(settings%path_obsout)//adate//'/'//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   if( lexist ) then
     ! append to existing
@@ -212,8 +223,13 @@ subroutine read_basic(settings, jd, nr, nobs, obs)
   close(100)
 
   ! write detailed station list file
-  print*, 'lat, lon , alt: ',obs%lat(1), obs%lon(1), obs%alt(1)
-  file_out = trim(settings%path_obsout)//'stnlist_detail.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    file_out = trim(settings%path_obsout)//'stnlist_detail.dat'
+  else
+    ! do not append
+    file_out = trim(settings%path_obsout)//adate//'/'//'stnlist_detail.dat'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   write(rowfmt,fmt='(A,I1,A)') '(A',recname_len,',1X,F7.2,1X,F7.2,1X,F7.1)'
   if( lexist ) then
diff --git a/prep_flexpart/read_icos.f90 b/prep_flexpart/read_icos.f90
index 1368edd..ded6283 100644
--- a/prep_flexpart/read_icos.f90
+++ b/prep_flexpart/read_icos.f90
@@ -64,6 +64,7 @@ subroutine read_icos(settings, jd, nr, nobs, obs)
   character(len=200)                                    :: line
   character(len=200), dimension(20)                     :: args
   character(len=1)                                      :: flag
+  character(len=6)                                      :: adate
   real, dimension(16)                                   :: temp
   logical                                               :: lexist
   integer                                               :: ierr
@@ -153,7 +154,6 @@ subroutine read_icos(settings, jd, nr, nobs, obs)
     do n = 2, 11
       read(args(n),*) temp(n)
     end do
-    print*, temp
     yyyy = int(temp(3))
     mm = int(temp(4))
     dd = int(temp(5))
@@ -162,7 +162,6 @@ subroutine read_icos(settings, jd, nr, nobs, obs)
     conc = temp(9)
     err = temp(10)
     flag = args(12)
-    print*, flag
     ! calculate julian date 
     jjjjmmdd = yyyy*10000+mm*100+dd
     hhmiss = hh*10000+mi*100
@@ -190,12 +189,11 @@ subroutine read_icos(settings, jd, nr, nobs, obs)
 
   ! no observations go to end
   if ( nobs.eq.0 ) then
-    call caldate(jdate, jjjjmmdd, hhmiss)
+    call caldate(jd, jjjjmmdd, hhmiss)
     print*, 'WARNING: no data for ',trim(recname(nr)),' in year/month ',jjjjmmdd/100
     go to 20
   endif
 
-
   ! allocate obs
   call alloc_obs(nobs, obs)
 
@@ -206,7 +204,17 @@ subroutine read_icos(settings, jd, nr, nobs, obs)
   if ( nobs.eq.0 ) go to 20
 
   ! write formatted obs to file
-  file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    ! generic output directory
+    file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  else
+    ! do not append to file when this is a new run
+    ! create subdirectory for ouput based on start year, month
+    call caldate(jdatei, jjjjmmdd, hhmiss)
+    write(adate,'(I6)') jjjjmmdd/100
+    file_out = trim(settings%path_obsout)//adate//'/'//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   if( lexist ) then
     ! append to existing
@@ -237,7 +245,13 @@ subroutine read_icos(settings, jd, nr, nobs, obs)
   close(100)
 
   ! write detailed station list file
-  file_out = trim(settings%path_obsout)//'stnlist_detail.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    file_out = trim(settings%path_obsout)//'stnlist_detail.dat'
+  else
+    ! do not append
+    file_out = trim(settings%path_obsout)//adate//'/'//'stnlist_detail.dat'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   write(rowfmt,fmt='(A,I1,A)') '(A',recname_len,',1X,F7.2,1X,F7.2,1X,F7.1)'
   if( lexist ) then
diff --git a/prep_flexpart/read_noaa.f90 b/prep_flexpart/read_noaa.f90
index 06f5943..e11007e 100644
--- a/prep_flexpart/read_noaa.f90
+++ b/prep_flexpart/read_noaa.f90
@@ -64,6 +64,7 @@ subroutine read_noaa(settings, jd, nr, nobs, obs)
   character(len=200)                                    :: line
   character(len=200), dimension(50)                     :: args
   character(len=3)                                      :: flag
+  character(len=6)                                      :: adate
   real, dimension(13)                                   :: temp
   logical                                               :: lexist
   integer                                               :: ierr
@@ -180,7 +181,7 @@ subroutine read_noaa(settings, jd, nr, nobs, obs)
 
   ! no observations go to end
   if ( nobs.eq.0 ) then
-    call caldate(jdate, jjjjmmdd, hhmiss)
+    call caldate(jd, jjjjmmdd, hhmiss)
     print*, 'WARNING: no data for ',trim(recname(nr)),' in year/month ',jjjjmmdd/100 
     go to 20
   endif
@@ -243,7 +244,17 @@ subroutine read_noaa(settings, jd, nr, nobs, obs)
   if ( nobs.eq.0 ) go to 20
 
   ! write formatted obs to file
-  file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    ! generic output directory
+    file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  else
+    ! do not append to file when this is a new run
+    ! create subdirectory for ouput based on start year, month
+    call caldate(jdatei, jjjjmmdd, hhmiss)
+    write(adate,'(I6)') jjjjmmdd/100
+    file_out = trim(settings%path_obsout)//adate//'/'//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   if( lexist ) then
     ! append to existing
@@ -274,8 +285,13 @@ subroutine read_noaa(settings, jd, nr, nobs, obs)
   close(100)
 
   ! write detailed station list file
-  print*, 'lat, lon , alt: ',obs%lat(1), obs%lon(1), obs%alt(1)
-  file_out = trim(settings%path_obsout)//'stnlist_detail.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    file_out = trim(settings%path_obsout)//'stnlist_detail.dat'
+  else
+    ! do not append
+    file_out = trim(settings%path_obsout)//adate//'/'//'stnlist_detail.dat'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   write(rowfmt,fmt='(A,I1,A)') '(A',recname_len,',1X,F7.2,1X,F7.2,1X,F7.1)'
   if( lexist ) then
diff --git a/prep_flexpart/read_obspack.f90 b/prep_flexpart/read_obspack.f90
index dc11b94..3dbb911 100644
--- a/prep_flexpart/read_obspack.f90
+++ b/prep_flexpart/read_obspack.f90
@@ -63,6 +63,7 @@ subroutine read_obspack(settings, jd, nr, nobs, obs)
   character(len=max_path_len)                           :: rowfmt
   character(len=200)                                    :: line
   character(len=200), dimension(20)                     :: args
+  character(len=6)                                      :: adate
   character(len=4)                                      :: version
   real, dimension(16)                                   :: temp
   logical                                               :: lexist
@@ -193,7 +194,7 @@ subroutine read_obspack(settings, jd, nr, nobs, obs)
 
   ! no observations go to end
   if ( nobs.eq.0 ) then
-    call caldate(jdate, jjjjmmdd, hhmiss)
+    call caldate(jd, jjjjmmdd, hhmiss)
     print*, 'WARNING: no data for ',trim(recname(nr)),' in year/month ',jjjjmmdd/100
     go to 20
   endif
@@ -208,7 +209,17 @@ subroutine read_obspack(settings, jd, nr, nobs, obs)
   if ( nobs.eq.0 ) go to 20
 
   ! write formatted obs to file
-  file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    ! generic output directory
+    file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  else
+    ! do not append to file when this is a new run
+    ! create subdirectory for ouput based on start year, month
+    call caldate(jdatei, jjjjmmdd, hhmiss)
+    write(adate,'(I6)') jjjjmmdd/100
+    file_out = trim(settings%path_obsout)//adate//'/'//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   if( lexist ) then
     ! append to existing
@@ -239,7 +250,13 @@ subroutine read_obspack(settings, jd, nr, nobs, obs)
   close(100)
 
   ! write detailed station list file
-  file_out = trim(settings%path_obsout)//'stnlist_detail.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    file_out = trim(settings%path_obsout)//'stnlist_detail.dat'
+  else
+    ! do not append
+    file_out = trim(settings%path_obsout)//adate//'/'//'stnlist_detail.dat'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   write(rowfmt,fmt='(A,I1,A)') '(A',recname_len,',1X,F7.2,1X,F7.2,1X,F7.1)'
   if( lexist ) then
diff --git a/prep_flexpart/read_wdcgg.f90 b/prep_flexpart/read_wdcgg.f90
index 48499d1..0783191 100644
--- a/prep_flexpart/read_wdcgg.f90
+++ b/prep_flexpart/read_wdcgg.f90
@@ -63,8 +63,7 @@ subroutine read_wdcgg(settings, jd, nr, nobs, obs)
   character(len=max_path_len)                           :: rowfmt
   character(len=200)                                    :: line
   character(len=200), dimension(30)                     :: args
-  character(len=10)                                     :: adate
-  character(len=5)                                      :: atime
+  character(len=6)                                      :: adate
   character(len=6)                                      :: utcstr
   real, dimension(22)                                   :: temp
   logical                                               :: lexist
@@ -176,7 +175,7 @@ subroutine read_wdcgg(settings, jd, nr, nobs, obs)
 
   ! no observations go to end
   if ( nobs.eq.0 ) then
-    call caldate(jdate, jjjjmmdd, hhmiss)
+    call caldate(jd, jjjjmmdd, hhmiss)
     print*, 'WARNING: no data for ',trim(recname(nr)),' in year/month ',jjjjmmdd/100
     go to 20
   endif
@@ -193,7 +192,17 @@ subroutine read_wdcgg(settings, jd, nr, nobs, obs)
   if ( nobs.eq.0 ) go to 20
 
   ! write formatted obs to file
-  file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    ! generic output directory
+    file_out = trim(settings%path_obsout)//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  else
+    ! do not append to file when this is a new run
+    ! create subdirectory for ouput based on start year, month
+    call caldate(jdatei, jjjjmmdd, hhmiss)
+    write(adate,'(I6)') jjjjmmdd/100
+    file_out = trim(settings%path_obsout)//adate//'/'//trim(recname(nr))//'_'//trim(settings%species)//'.txt'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   if( lexist ) then
     ! append to existing
@@ -224,7 +233,13 @@ subroutine read_wdcgg(settings, jd, nr, nobs, obs)
   close(100)
 
   ! write detailed station list file
-  file_out = trim(settings%path_obsout)//'stnlist_detail.txt'
+  if ( settings%lappendfile.eq.1 ) then
+    ! append file
+    file_out = trim(settings%path_obsout)//'stnlist_detail.dat'
+  else
+    ! do not append
+    file_out = trim(settings%path_obsout)//adate//'/'//'stnlist_detail.dat'
+  endif
   inquire(file=trim(file_out),exist=lexist)
   write(rowfmt,fmt='(A,I1,A)') '(A',recname_len,',1X,F7.2,1X,F7.2,1X,F7.1)'
   if( lexist ) then
diff --git a/prep_flexpart/sbatch_prep_flexpart.sh b/prep_flexpart/sbatch_prep_flexpart.sh
index 6fc859b..919cc6d 100755
--- a/prep_flexpart/sbatch_prep_flexpart.sh
+++ b/prep_flexpart/sbatch_prep_flexpart.sh
@@ -1,6 +1,6 @@
 #!/bin/bash 
 #---------------------------------------------------
-partition=nilu
+partition=main
 settings_files='./SETTINGS'
 #---------------------------------------------------
 
diff --git a/prep_fluxes/makefile b/prep_fluxes/makefile
index 97883d0..e09dae2 100644
--- a/prep_fluxes/makefile
+++ b/prep_fluxes/makefile
@@ -1,34 +1,42 @@
-F90     = gfortran
-LIBPATH = /usr/lib/
-INCPATH = /usr/include/
-LNK = -o
-CMPL = -c
-LIBS = -lnetcdf -lnetcdff -llapack
-#FFLAGS   = -O2 -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form
-FFLAGS = -O0 -g -m64 -fbounds-check -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form \
-         -fbacktrace
-LDFLAGS  = $(FFLAGS)  -L$(LIBPATH) -I$(INCPATH) $(LIBS)
+F90      = /apps/sw/ubuntu22.04/gcc-11.4.0/gcc-13.2.0-tkesyophy2o6rjlzknndu3b4oyasvuqm/bin/gfortran
+LIBPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib/
+INCPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/include/
+
+# OPTIMIZATION LEVEL
+O_LEV = 0 # [0,1,2,3,g,s,fast]
+
+LIBS = -lm -DUSE_NCF -lnetcdff
+
+FFLAGS   = -I$(INCPATH1) -O$(O_LEV) -g -cpp -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -fmessage-length=0 -flto=jobserver -O$(O_LEV) -DUSE_NCF -lnetcdff -fbacktrace -Warray-bounds -fcheck=all # -march=native
+
+LDFLAGS  = $(FFLAGS) -L$(LIBPATH1) -Wl,-rpath,$(LIBPATH1) $(LIBS)
 
 MAIN = prep_flux
 
-SRCS =   mod_var.f90 \
-         mod_settings.f90 \
-         mod_dates.f90 \
-         sort.f90 \
-         read_ncdf.f90 \
-         write_ncdf.f90 \
-         gridarea.f90 \
-         convertgrid.f90 \
-         calc_monthly.f90 \
-         adjust_time.f90 \
-         prep_flux.f90  
-
-OBJECTS = $(SRCS:.f90=.o)
-$(MAIN): $(OBJECTS) $(MODULES)
-	$(F90) $(LNK) $(MAIN) $(OBJECTS) $(LIBS)
+MODULES = mod_var.o \
+         mod_settings.o \
+         mod_dates.o
+
+OBJECTS = sort.o \
+         read_ncdf.o \
+         write_ncdf.o \
+         gridarea.o \
+         convertgrid.o \
+         calc_monthly.o \
+         adjust_time.o \
+         prep_flux.o  
+
+%.o: %.mod
+
+$(MAIN): $(MODULES) $(OBJECTS)
+	+$(F90) -o $@ $(MODULES) $(OBJECTS) $(LDFLAGS)
+
 %.o : %.f90
-	$(F90) $(LDFLAGS) $(CMPL) $<  -o $@
+	+$(F90) -c $(FFLAGS) $< 
 
 clean:
-	rm -f $(OBJECTS) $(MODULES)
+	rm -f *.o *.mod
+
+.SUFFIXES = $(SUFFIXES) .f90
+
 
diff --git a/prep_regions/get_surfinf.f90 b/prep_regions/get_surfinf.f90
index bd81909..7ad8cd7 100644
--- a/prep_regions/get_surfinf.f90
+++ b/prep_regions/get_surfinf.f90
@@ -70,7 +70,7 @@ subroutine get_surfinf(files, config, recs, cdryair, obstimes, avetimes, surfinf
   real(kind=8), dimension(maxngrid)                   :: gtime_tmp  ! flux sensitivity time stamp (julian days) of first footprint per observation
 
   real                                                :: bndx, bndy, delx, dely
-  integer                                             :: numx, numy, xshift, new_grid_time, standard_grid_time
+  integer                                             :: numx, numy, numz, xshift, new_grid_time, standard_grid_time
   integer                                             :: numpoint, release_nr, nr_footprints, ngrid, nretr
   integer                                             :: ibdate, ibtime
   real(kind=8), dimension(maxpoint,2)                 :: releases
@@ -129,7 +129,7 @@ subroutine get_surfinf(files, config, recs, cdryair, obstimes, avetimes, surfinf
       if ( lexist ) then
         print*, 'Get header:', i, ' '//trim(path_flexrec)//'header'
         call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely, xshift)
+                           numx, numy, numz, bndx, bndy, delx, dely, xshift)
       else
         print*, 'WARNING: cannot find ',filename
         go to 10
@@ -140,7 +140,7 @@ subroutine get_surfinf(files, config, recs, cdryair, obstimes, avetimes, surfinf
         if ( lexist ) then
           print*, 'Get header:', i, ' '//trim(path_flexrec)//'header'
           call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                             numx, numy, bndx, bndy, delx, dely, xshift)
+                             numx, numy, numz, bndx, bndy, delx, dely, xshift)
         else
           print*, 'WARNING: cannot find ',filename
           go to 10
diff --git a/prep_regions/initialize.f90 b/prep_regions/initialize.f90
index 1f11671..fcbafce 100644
--- a/prep_regions/initialize.f90
+++ b/prep_regions/initialize.f90
@@ -56,7 +56,7 @@ subroutine initialize(files, config)
   integer                                :: ibdate, ibtime
   real(kind=8), dimension(maxpoint,2)    :: releases
   real                                   :: bndx, bndy, delx, dely
-  integer                                :: numx, numy, xshift, ngrid
+  integer                                :: numx, numy, numz, xshift, ngrid
   integer                                :: i, ierr
 
   ! read receptor list file
@@ -79,9 +79,18 @@ subroutine initialize(files, config)
   if ( config%satellite.and.nrec.eq.0 ) then
     ! satellite only
     write(areldate,'(I8)') config%datei
-    if ( .not.config%nested ) filename = trim(files%path_flexsat)//areldate//'/header'
-    if ( config%nested ) filename = trim(files%path_flexsat)//areldate//'/header_nest'
-    inquire(file=trim(filename),exist=lexist)
+    if ( .not.config%nested ) then
+      filename = trim(files%path_flexsat)//areldate//'/header'
+      inquire(file=trim(filename),exist=lexist)
+    else
+      filename = trim(files%path_flexsat)//areldate//'/header_nest'
+      inquire(file=trim(filename),exist=lexist)
+      if ( .not.lexist ) then
+        ! test if is FPv11 file
+        filename = trim(files%path_flexsat)//areldate//'/header_nest_grid_time'
+        inquire(file=trim(filename),exist=lexist)
+      endif
+    endif
   else
     ! ground-based output
     yyyymm=config%datei/100
@@ -89,10 +98,18 @@ subroutine initialize(files, config)
     lexist = .false.
     i = 1
     do while ( (.not.lexist).and.(i.le.nrec) )
-      if ( .not.config%nested ) filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header'
-      if ( config%nested )      filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest'
-      print*, filename
-      inquire(file=trim(filename),exist=lexist)
+      if ( .not.config%nested ) then
+        filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header'
+        inquire(file=trim(filename),exist=lexist)
+      else
+        filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest'
+        inquire(file=trim(filename),exist=lexist)
+        if ( .not.lexist ) then
+          ! test if is FPv11 file
+          filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest_grid_time'
+          inquire(file=trim(filename),exist=lexist)
+        endif
+      endif
       i = i + 1
     end do
   endif
@@ -103,7 +120,7 @@ subroutine initialize(files, config)
 
   print*, 'Reading flexpart header: '//trim(filename)
   call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                   numx, numy, bndx, bndy, delx, dely, xshift)
+                   numx, numy, numz, bndx, bndy, delx, dely, xshift)
   nxgrid = numx
   nygrid = numy
   nxshift = xshift
diff --git a/prep_regions/mod_flexpart.f90 b/prep_regions/mod_flexpart.f90
index 3316434..5c10a04 100644
--- a/prep_regions/mod_flexpart.f90
+++ b/prep_regions/mod_flexpart.f90
@@ -49,7 +49,7 @@ module mod_flexpart
   ! --------------------------------------------------
 
   subroutine read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely, xshift)
+                           numx, numy, numz, bndx, bndy, delx, dely, xshift)
 
     use mod_var
 
@@ -59,7 +59,7 @@ module mod_flexpart
     integer,                        intent(in out) :: numpoint
     integer,                        intent(in out) :: ibdate, ibtime   
     real(kind=8), dimension(maxpoint,2), intent(in out) :: releases           
-    integer,                        intent(in out) :: numx, numy, xshift
+    integer,                        intent(in out) :: numx, numy, numz, xshift
     real,                           intent(in out) :: bndx, bndy, delx, dely
 
     character(len=29)                              :: flexversion
@@ -75,7 +75,7 @@ module mod_flexpart
     real, dimension(:), allocatable                :: xpoint, ypoint, zpoint1, zpoint2
     real, dimension(:,:), allocatable              :: xmass
     integer, dimension(10)                         :: lage
-    integer                                        :: n, i, j, ierr 
+    integer                                        :: n, i, j, ierr, dummy
  
     inquire ( file=trim(filename),exist=lexist )
     if ( .not.lexist ) then
@@ -91,14 +91,14 @@ module mod_flexpart
     read(100) ibdate, ibtime, flexversion
     read(100) loutstep, loutaver, loutsample
     read(100) bndx, bndy, numx, numy, delx, dely
-    read(100) nzgrid, (outheight(i), i = 1, nzgrid)
+    read(100) numz, (outheight(i), i = 1, numz)
     read(100) jjjjmmdd, ihmmss
-    read(100) nspec, nzgrid
+    read(100) nspec, numz
     nspec=nspec/3
     do n=1,nspec
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
+      read(100) dummy, species(n)
+      read(100) dummy, species(n)
+      read(100) numz, species(n)
     end do
     read(100) numpoint
 
diff --git a/prep_regions/mod_settings.f90 b/prep_regions/mod_settings.f90
index ddbdb4a..6025ddd 100644
--- a/prep_regions/mod_settings.f90
+++ b/prep_regions/mod_settings.f90
@@ -82,7 +82,7 @@ module mod_settings
 
   type :: config_t
  
-    character(len=3)            :: spec            ! species ('co2' or 'ghg')
+    character(len=3)            :: spec            ! species ('co2' or 'ghg' or 'aero')
     integer                     :: datei           ! start date (yyyymmdd)
     integer                     :: datef           ! end date (yyyymmdd)
     logical                     :: nested          ! use nested flexpart output (true or false)
diff --git a/prep_regions/prep_regions.f90 b/prep_regions/prep_regions.f90
index 1aa8d19..ad66a6d 100644
--- a/prep_regions/prep_regions.f90
+++ b/prep_regions/prep_regions.f90
@@ -130,15 +130,6 @@ program prep_regions
   varname = 'regions'
   call write_ncdf(files, filename, varname, nbox_xy)
 
-  ! write the average fooptrint for all receptors
-  open(50,file=trim(files%path_output)//'all_footprint_average.txt')
-  do ix=1,nxregrid
-      do jy=1,nyregrid
-          write(50,*)  reg_lon(ix), reg_lat(jy), surfinf(ix,jy)
-       end do
-  end do
-  close(50)
-
   ! write lsm 
   allocate( mask(nxregrid,nyregrid), stat=ierr)
   mask=lsm
diff --git a/prep_regions/run_prepregions.sh b/prep_regions/run_prepregions.sh
new file mode 100755
index 0000000..53c0e5f
--- /dev/null
+++ b/prep_regions/run_prepregions.sh
@@ -0,0 +1,27 @@
+#!/bin/bash 
+#SBATCH -J prep_region
+#SBATCH -p debug
+#SBATCH -q debug
+#SBATCH -o prep_regions.out
+#SBATCH --time=4:00:00
+#SBATCH --mem=10000
+
+#---------------------------------------------------
+
+settings_file='/mypath/settings/SETTINGS_files'
+settings_config='/mypath/settings/SETTINGS_config'
+settings_region='/mypath/prep_regions/SETTINGS_regions'
+
+#---------------------------------------------------
+
+module purge
+module load gcc/13.2.0-tkesy
+module load openmpi/5.0.3-l3mqa
+module load eccodes/2.34.0-wrusa
+
+export LIBRARY_PATH=$LIBRARY_PATH:/apps/sw/ubuntu22.04/gcc-13.2.0/eccodes-2.34.0-wrusaoev7mlquymqrelfbxrhvnagtz6d/lib:/apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/apps/sw/ubuntu22.04/gcc-13.2.0/eccodes-2.34.0-wrusaoev7mlquymqrelfbxrhvnagtz6d/lib:/apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib
+
+srun ./prep_regions ${settings_file} ${settings_config} ${settings_region}
+
+
diff --git a/prep_satellite/makefile b/prep_satellite/makefile
index 9b0516c..e54f331 100644
--- a/prep_satellite/makefile
+++ b/prep_satellite/makefile
@@ -1,40 +1,44 @@
-F90     = gfortran
-LIBPATH = /usr/lib/
-INCPATH = /usr/include/
-LNK = -o
-CMPL = -c
-LIBS = -lnetcdf -lnetcdff 
-#FFLAGS   = -O2 -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form
-FFLAGS = -O0 -g -m64 -fbounds-check -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form \
-         -fbacktrace
-LDFLAGS  = $(FFLAGS)  -L$(LIBPATH) -I$(INCPATH) $(LIBS)
+F90      = /apps/sw/ubuntu22.04/gcc-11.4.0/gcc-13.2.0-tkesyophy2o6rjlzknndu3b4oyasvuqm/bin/gfortran
+LIBPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib/
+INCPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/include/
+
+# OPTIMIZATION LEVEL
+O_LEV = 0 # [0,1,2,3,g,s,fast]
+
+LIBS = -lm -DUSE_NCF -lnetcdff 
+
+FFLAGS   = -I$(INCPATH1) -O$(O_LEV) -g -cpp -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -fmessage-length=0 -flto=jobserver -O$(O_LEV) -DUSE_NCF -lnetcdff -fbacktrace -Warray-bounds -fcheck=all # -march=native
+
+LDFLAGS  = $(FFLAGS) -L$(LIBPATH1) -Wl,-rpath,$(LIBPATH1) $(LIBS)
 
 MAIN = prep_satellite
 
-SRCS =  mod_var.f90 \
-	mod_dates.f90 \
-	mod_settings.f90 \
-	mod_save.f90 \
-	gridarea.f90 \
-	geodarea.f90 \
-        prep_command.f90 \
-	prep_outgrid.f90 \
-	prep_ageclass.f90 \
-	prep_pathnames.f90 \
-	average.f90 \
-	get_tropomi.f90 \
-	get_bremen.f90 \
-	get_oco2.f90 \
-	main.f90
-
-
-OBJECTS = $(SRCS:.f90=.o)
-$(MAIN): $(OBJECTS) $(MODULES)
-	$(F90) $(LNK) $(MAIN) $(OBJECTS) $(LIBS)
+MODULES = mod_var.o \
+	mod_dates.o \
+	mod_settings.o \
+	mod_save.o 
+
+OBJECTS = gridarea.o \
+	geodarea.o \
+        prep_command.o \
+	prep_outgrid.o \
+	prep_ageclass.o \
+	prep_pathnames.o \
+	average.o \
+	get_tropomi.o \
+	get_bremen.o \
+	get_oco2.o \
+	main.o
+
+%.o: %.mod
+
+$(MAIN): $(MODULES) $(OBJECTS)
+	+$(F90) -o $@ $(MODULES) $(OBJECTS) $(LDFLAGS)
+
 %.o : %.f90
-	$(F90) $(LDFLAGS) $(CMPL) $<  -o $@
+	+$(F90) -c $(FFLAGS) $< 
 
 clean:
-	rm -f $(OBJECTS) $(MODULES)
-
+	rm -f *.o *.mod
 
+.SUFFIXES = $(SUFFIXES) .f90
diff --git a/prep_syndata/get_error_cov.f90 b/prep_syndata/get_error_cov.f90
index 9c05c9a..4a45ca3 100644
--- a/prep_syndata/get_error_cov.f90
+++ b/prep_syndata/get_error_cov.f90
@@ -46,7 +46,7 @@ subroutine get_error_cov(files, config)
   filename = trim(files%path_output)//'evals.txt'
   inquire(file=trim(filename),exist=lexist)
   if (.not.lexist) then
-    write(logid,*) 'ERROR: cannot find '//trim(filename)
+    write(logid,*) 'ERROR get_error_cov: cannot find '//trim(filename)
     stop
   endif
 
@@ -59,7 +59,7 @@ subroutine get_error_cov(files, config)
   end do
   close(100)
   neig = neig - 1
-  print*, 'neig = ',neig
+  write(logid,*) 'get_error_cov: neig = ',neig
 
   allocate ( evals(neig) )
   allocate ( evecs(ndvar,neig) )
@@ -79,7 +79,7 @@ subroutine get_error_cov(files, config)
   filename = trim(files%path_output)//'evecs.txt'
   inquire(file=trim(filename),exist=lexist)
   if (.not.lexist) then
-    write(logid,*) 'ERROR: cannot find '//trim(filename)
+    write(logid,*) 'ERROR get_error_cov: cannot find '//trim(filename)
     stop
   endif
 
@@ -99,13 +99,13 @@ subroutine get_error_cov(files, config)
     stat_time(i) = juldatei + (i-1)*statres
   end do
 
-  print*, 'stat_time = ',stat_time
+  write(logid,*) 'get_error_cov: stat_time = ',stat_time
 
   allocate ( cort(ntstate,ntstate) )
   filename = trim(files%path_output)//'cort.txt'
   inquire(file=trim(filename),exist=lexist)
   if (.not.lexist) then
-    write(logid,*) 'ERROR: cannot find '//trim(filename)
+    write(logid,*) 'ERROR get_error_cov: cannot find '//trim(filename)
     stop
   endif
 
diff --git a/prep_syndata/get_flux.f90 b/prep_syndata/get_flux.f90
index 8554d8a..78f25c9 100644
--- a/prep_syndata/get_flux.f90
+++ b/prep_syndata/get_flux.f90
@@ -153,7 +153,7 @@ subroutine get_flux(config, files, flx, state)
       else
         filename = str_replace(files%filename_nee, 'YYYY', adate)
       endif
-      print*, 'get_flux: filename = ',filename
+      write(logid,*) 'get_flux: filename = ',filename
       filename = trim(files%path_prior)//trim(filename)
       inquire(file=trim(filename),exist=lexist)
       if (.not.lexist) then
@@ -208,7 +208,7 @@ subroutine get_flux(config, files, flx, state)
     state(:) = 0.
 !  endif
   
-  print*, 'flx_time = ',flx_time
+  write(logid,*) 'get_flux: flx_time = ',flx_time
 
 end subroutine get_flux 
 
diff --git a/prep_syndata/get_obs.f90 b/prep_syndata/get_obs.f90
index 03c82d4..63daf7f 100644
--- a/prep_syndata/get_obs.f90
+++ b/prep_syndata/get_obs.f90
@@ -66,7 +66,7 @@ subroutine get_obs(config, files, obs, obserr)
   filename = trim(files%path_output)//'monitor.txt'
   inquire(file=trim(filename), exist=lexist)
   if ( .not.lexist ) then
-    write(logid,*) 'ERROR: cannot find '//trim(filename)
+    write(logid,*) 'ERROR get_obs: cannot find '//trim(filename)
     stop
   endif
 
@@ -85,12 +85,14 @@ subroutine get_obs(config, files, obs, obserr)
     do i = 1, maxobs
       read(100,fmt=rowfmt,iostat=ierr) recs, jjjjmmdd, hhmiss, jdate, conc, cini(i), cinipos, bkg(i), &
                 ghg(i), prior(i), post, cpri(i), cakpri(i), delta, obserr(i)
+      print*, recs, jjjjmmdd, hhmiss, jdate, conc, cini(i), cinipos, bkg(i), &
+              ghg(i), prior(i), post, cpri(i), cakpri(i), delta, obserr(i)
       if ( ierr.ne.0 ) exit
     end do
   endif
   close(100)
   nobs = i - 1
-  print*, 'nobs: ',nobs
+  write(logid,*) 'get_obs: nobs = ',nobs
 
   ! check obserr
   do i = 1, nobs
diff --git a/prep_syndata/initialize.f90 b/prep_syndata/initialize.f90
index a2dbb47..1b06a9e 100644
--- a/prep_syndata/initialize.f90
+++ b/prep_syndata/initialize.f90
@@ -49,7 +49,7 @@ subroutine initialize(files, config)
   real                                   :: area
   integer                                :: i, ix, jy
   real                                   :: bndx, bndy, delx, dely
-  integer                                :: numx, numy, xshift
+  integer                                :: numx, numy, numz, xshift
   integer                                :: ierr
 
   ! open log file
@@ -84,9 +84,18 @@ subroutine initialize(files, config)
     lexist = .false.
     i = 1
     do while ( (.not.lexist).and.(i.le.nrec) )
-      if ( .not.config%nested ) filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header'
-      if ( config%nested ) filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest'
-      inquire(file=trim(filename),exist=lexist)
+      if ( .not.config%nested ) then
+        filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header'
+        inquire(file=trim(filename),exist=lexist)
+      else
+        filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest'
+        inquire(file=trim(filename),exist=lexist)
+        if ( .not.lexist ) then
+          ! try if is FPv11 file
+          filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest_grid_time'
+          inquire(file=trim(filename),exist=lexist)
+        endif
+      endif
       i = i + 1
     end do
   endif ! satellite
@@ -96,7 +105,7 @@ subroutine initialize(files, config)
   endif
   write(logid,*) 'Reading flexpart header: '//trim(filename)
   call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                     numx, numy, bndx, bndy, delx, dely, xshift)
+                     numx, numy, numz, bndx, bndy, delx, dely, xshift)
   ! global domain variables
   nxgrid = numx
   nygrid = numy
@@ -179,15 +188,15 @@ subroutine initialize(files, config)
     stop
   endif
 
-  print*, 'statres: ',statres
-  print*, 'flxtres: ',flxtres
-  print*, 'ntstate: ',ntstate
-  print*, 'nt_flx: ',nt_flx
-  print*, 'nflx: ',nflx
-  print*, 'nt_nee: ',nt_nee
-  print*, 'nd_nee: ',nd_nee
-  print*, 'nday: ',nday
-  print*, 'nyr: ',nyr
+  write(logid,*) 'statres: ',statres
+  write(logid,*) 'flxtres: ',flxtres
+  write(logid,*) 'ntstate: ',ntstate
+  write(logid,*) 'nt_flx: ',nt_flx
+  write(logid,*) 'nflx: ', nflx
+  write(logid,*) 'nt_nee: ',nt_nee
+  write(logid,*) 'nd_nee: ',nd_nee
+  write(logid,*) 'nday: ',nday
+  write(logid,*) 'nyr: ',nyr
 
   ! initialize grid variables
   ! -------------------------
@@ -267,6 +276,9 @@ subroutine initialize(files, config)
     ndvar = nbox
   endif
 
+  write(logid,*) 'nvar = ',nvar
+  write(logid,*) 'ndvar = ',ndvar
+
 end subroutine initialize
 
 
diff --git a/prep_syndata/makefile b/prep_syndata/makefile
index 1fb0149..15bddca 100644
--- a/prep_syndata/makefile
+++ b/prep_syndata/makefile
@@ -1,39 +1,47 @@
-F90     = gfortran
-LIBPATH = /usr/lib/
-INCPATH = /usr/include/
-LNK = -o
-CMPL = -c
-LIBS = -lnetcdf -lnetcdff -llapack
-#FFLAGS   = -O2 -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form
-FFLAGS = -O0 -g -m64 -fbounds-check -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -ffree-form \
-         -fbacktrace -ffree-line-length-0 -fcheck=all -Wall
-LDFLAGS  = $(FFLAGS)  -L$(LIBPATH) -I$(INCPATH) $(LIBS)
+F90      = /apps/sw/ubuntu22.04/gcc-11.4.0/gcc-13.2.0-tkesyophy2o6rjlzknndu3b4oyasvuqm/bin/gfortran
+LIBPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib/
+INCPATH1 = /apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/include/
+
+# OPTIMIZATION LEVEL
+O_LEV = 0 # [0,1,2,3,g,s,fast]
+
+LIBS  = -llapack -lm -DUSE_NCF -lnetcdff
+
+FFLAGS  = -I$(INCPATH1) -O$(O_LEV) -g -cpp -m64 -mcmodel=medium -fconvert=little-endian -frecord-marker=4 -fmessage-length=0 -flto=jobserver -O$(O_LEV) -DUSE_NCF -lnetcdff -fbacktrace -Warray-bounds -fcheck=all -ffree-form -ffree-line-length-0 # -march=native
+
+LDFLAGS = $(FFLAGS) -L$(LIBPATH1) -Wl,-rpath,$(LIBPATH1) $(LIBS)
 
 MAIN = prep_syndata
 
-SRCS =   mod_var.f90 \
-         mod_settings.f90 \
-         mod_strings.f90 \
-         mod_dates.f90 \
-         mod_tools.f90 \
-         mod_flexpart.f90 \
-         mod_perturb.f90 \
-         mod_save.f90 \
-         read_reclist.f90 \
-         read_ncdf.f90 \
-         initialize.f90 \
-	 get_flux.f90 \
-         get_error_cov.f90 \
-         get_obs.f90 \
-         calc_error_cov.f90 \
-         prep_syndata.f90
-
-OBJECTS = $(SRCS:.f90=.o)
-$(MAIN): $(OBJECTS) $(MODULES)
-	$(F90) $(LNK) $(MAIN) $(OBJECTS) $(LIBS)
+MODULES = mod_var.o \
+         mod_settings.o \
+         mod_strings.o \
+         mod_dates.o \
+         mod_tools.o \
+         mod_flexpart.o \
+         mod_perturb.o \
+         mod_save.o
+
+OBJECTS = read_reclist.o \
+         read_ncdf.o \
+         initialize.o \
+	 get_flux.o \
+         get_error_cov.o \
+         get_obs.o \
+         calc_error_cov.o \
+         prep_syndata.o
+
+%.o: %.mod
+
+$(MAIN): $(MODULES) $(OBJECTS)
+	+$(F90) -o $@ $(MODULES) $(OBJECTS) $(LDFLAGS)
+
 %.o : %.f90
-	$(F90) $(LDFLAGS) $(CMPL) $<  -o $@
+	+$(F90) -c $(FFLAGS) $< 
 
 clean:
-	rm -f $(OBJECTS) $(MODULES)
+	rm -f *.o *.mod
+
+.SUFFIXES = $(SUFFIXES) .f90
+
 
diff --git a/prep_syndata/mod_flexpart.f90 b/prep_syndata/mod_flexpart.f90
index 97abe47..40c99e0 100644
--- a/prep_syndata/mod_flexpart.f90
+++ b/prep_syndata/mod_flexpart.f90
@@ -47,7 +47,7 @@ module mod_flexpart
   ! --------------------------------------------------
 
   subroutine read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely, xshift)
+                           numx, numy, numz, bndx, bndy, delx, dely, xshift)
 
     use mod_var
 
@@ -57,7 +57,7 @@ module mod_flexpart
     integer,                      intent(in out) :: numpoint
     integer,                      intent(in out) :: ibdate, ibtime   
     integer, dimension(maxpoint), intent(in out) :: releases           
-    integer,                      intent(in out) :: numx, numy, xshift
+    integer,                      intent(in out) :: numx, numy, numz, xshift
     real,                         intent(in out) :: bndx, bndy, delx, dely
 
     character(len=29)                            :: flexversion
@@ -73,7 +73,7 @@ module mod_flexpart
     real, dimension(:), allocatable              :: xpoint, ypoint, zpoint1, zpoint2
     real, dimension(:,:), allocatable            :: xmass
     integer, dimension(10)                       :: lage
-    integer                                      :: n, i, j, ierr 
+    integer                                      :: n, i, j, ierr, dummy 
  
     inquire ( file=trim(filename),exist=lexist )
     if ( .not.lexist ) then
@@ -89,14 +89,14 @@ module mod_flexpart
     read(100) ibdate, ibtime, flexversion
     read(100) loutstep, loutaver, loutsample
     read(100) bndx, bndy, numx, numy, delx, dely
-    read(100) nzgrid, (outheight(i), i = 1, nzgrid)
+    read(100) numz, (outheight(i), i = 1, numz)
     read(100) jjjjmmdd, ihmmss
-    read(100) nspec, nzgrid
+    read(100) nspec, numz
     nspec=nspec/3
     do n=1,nspec
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
+      read(100) dummy, species(n)
+      read(100) dummy, species(n)
+      read(100) numz, species(n)
     end do
     read(100) numpoint
 
diff --git a/prep_syndata/mod_perturb.f90 b/prep_syndata/mod_perturb.f90
index 2bdd1b7..309456b 100644
--- a/prep_syndata/mod_perturb.f90
+++ b/prep_syndata/mod_perturb.f90
@@ -70,12 +70,12 @@ module mod_perturb
     work = cort
     call dpotrf('L',ntstate,work,ntstate,info)
     if ( info.gt.0 ) then
-      write(logid,*) 'ERROR: lower Cholesky triangle'
+      write(logid,*) 'ERROR perturb_flux: lower Cholesky triangle'
       stop
     endif
     call dpotri('L',ntstate,work,ntstate,info)
     if ( info.gt.0 ) then
-      write(logid,*) 'ERROR: Cholesky inverse'
+      write(logid,*) 'ERROR perturb_flux: Cholesky inverse'
       stop
     endif
     ! returns lower ('L') triangle of inverse of work
@@ -106,7 +106,7 @@ module mod_perturb
         end do
       end do
     end do
-    print*, 'min/max perturbation = ',minval(perturb), maxval(perturb)
+    write(logid,*) 'perturb_flux: min/max perturbation = ',minval(perturb), maxval(perturb)
 
     ! add perturbation to state vector 
     state(:) = state(:) + real(perturb(:),kind=4)
diff --git a/prep_syndata/mod_save.f90 b/prep_syndata/mod_save.f90
index 9ad81e3..4e56592 100644
--- a/prep_syndata/mod_save.f90
+++ b/prep_syndata/mod_save.f90
@@ -89,9 +89,9 @@ module mod_save
     jy1 = minloc(gbl_lat,dim=1,mask=abs(gbl_lat-rlly).eq.minval(abs(gbl_lat-rlly)))
     jy2 = minloc(gbl_lat,dim=1,mask=abs(gbl_lat-(rury-rdy)).eq.minval(abs(gbl_lat-(rury-rdy))))
 
-    print*, 'save_flux: gbl_lon = ',gbl_lon
-    print*, 'save_flux: gbl_lat = ',gbl_lat
-    print*, 'save_flux: ix1,ix2,jy1,jy2 = ',ix1,ix2,jy1,jy2
+    write(logid,*) 'save_flux: gbl_lon = ',gbl_lon
+    write(logid,*) 'save_flux: gbl_lat = ',gbl_lat
+    write(logid,*) 'save_flux: ix1,ix2,jy1,jy2 = ',ix1,ix2,jy1,jy2
 
     ! space and time conversions
     ! --------------------------
@@ -155,7 +155,7 @@ module mod_save
       do n = 1, nflx
         nt = minloc(stat_time,dim=1,mask=abs(stat_time-flx_time(n)).eq.minval(abs(stat_time-flx_time(n))))
         nt = min(nt,ntstate)
-        print*, 'stat_time(nt), flx_time(n) = ',stat_time(nt), flx_time(n)
+        write(logid,*) 'save_flux: stat_time(nt), flx_time(n) = ',stat_time(nt), flx_time(n)
         do jy = 1, nyregrid
           do ix = 1, nxregrid
             ! if inc_ocean is true state vector includes all fluxes, if false need to add ocean fluxes
@@ -213,7 +213,7 @@ module mod_save
     ! convert to kg/m2/h
     flx = flx*3600.
 
-    print*, 'mod_save: min/max flx = ',minval(flx), maxval(flx)
+    write(logid,*) 'save_flux: min/max flx = ',minval(flx), maxval(flx)
 
     ! adjust time to days since 1-Jan-1900
     flx_time = flx_time - juldate(19000101, 0) !+ 1d0
@@ -333,7 +333,7 @@ module mod_save
     filename = trim(files%path_output)//'monitor.txt'
     inquire(file=trim(filename), exist=lexist)
     if ( .not.lexist ) then
-      write(logid,*) 'ERROR: cannot find '//trim(filename)
+      write(logid,*) 'ERROR save_obs: cannot find '//trim(filename)
       stop
     endif
 
@@ -402,7 +402,7 @@ module mod_save
           ! third instance of delim
           call split(string,"_",species,sep)
           satname = trim(prefix)//'_'//trim(species)
-          write(logid,*) 'prefix satellite file = ',satname
+          write(logid,*) 'save_obs: prefix satellite file = ',satname
           exit
         endif
       end do
@@ -432,23 +432,25 @@ module mod_save
           vmr(cnt) = obs(i)
         endif
       end do ! nobs
-      ! copy original ncdf file and replace vmr with obs
-      call caldate(jd, currentdate, currenttime)
-      write(adate,fmt='(I8.8)') currentdate
-      filename = 'retrieval_'//trim(satname)//'_'//adate//'.nc'
-      print*, 'mod_save: filename = ',filename
-      call system('cp '//trim(files%path_satobs)//trim(filename)//' '//trim(files%path_output)//trim(filename)) 
-      call check( nf90_open(trim(files%path_output)//trim(filename),nf90_WRITE,ncid) ) 
-      call check( nf90_inq_dimid(ncid,'retrieval',dimid) )
-      call check( nf90_inquire_dimension(ncid,dimid,len=numretr) )
-      ! check consistent number of retrievals
-      if ( cnt.ne.numretr ) then
-        write(logid,*) 'ERROR: inconsistent number of retrievals for day ',currentdate,': numretr, cnt = ',numretr,cnt
-        stop
+      if ( cnt>0 ) then
+        ! copy original ncdf file and replace vmr with obs
+        call caldate(jd, currentdate, currenttime)
+        write(adate,fmt='(I8.8)') currentdate
+        filename = 'retrieval_'//trim(satname)//'_'//adate//'.nc'
+        write(logid,*) 'save_obs: filename = ',filename
+        call system('cp '//trim(files%path_satobs)//trim(filename)//' '//trim(files%path_output)//trim(filename)) 
+        call check( nf90_open(trim(files%path_output)//trim(filename),nf90_WRITE,ncid) ) 
+        call check( nf90_inq_dimid(ncid,'retrieval',dimid) )
+        call check( nf90_inquire_dimension(ncid,dimid,len=numretr) )
+        ! check consistent number of retrievals
+        if ( cnt.ne.numretr ) then
+          write(logid,*) 'ERROR save_obs: inconsistent number of retrievals for day ',currentdate,': numretr, cnt = ',numretr,cnt
+          stop
+        endif
+        call check( nf90_inq_varid(ncid,'vmr',varid) )
+        call check( nf90_put_var(ncid, varid, vmr(1:numretr)) )
+        call check( nf90_close(ncid) )
       endif
-      call check( nf90_inq_varid(ncid,'vmr',varid) )
-      call check( nf90_put_var(ncid, varid, vmr(1:numretr)) )
-      call check( nf90_close(ncid) )
       ! next day
       jd = jd + 1d0
       vmr(:) = 0.
diff --git a/prep_syndata/mod_var.f90 b/prep_syndata/mod_var.f90
index 5d6e10b..4a9b190 100644
--- a/prep_syndata/mod_var.f90
+++ b/prep_syndata/mod_var.f90
@@ -30,7 +30,7 @@ module mod_var
 
   integer, parameter :: max_path_len=200          ! max character length of paths and files
   integer, parameter :: max_name_len=50           ! max character length of variable names
-  integer, parameter :: recname_len=3             ! length of receptor names
+  integer, parameter :: recname_len=7             ! length of receptor names
   real, parameter    :: numscale=1.e12            ! numeric scaling factor
   integer, parameter :: maxpoint=1000             ! max number of releases per receptor per month
   integer, parameter :: maxspec=10                ! max number of species in a flexpart run
diff --git a/prep_syndata/prep_syndata.f90 b/prep_syndata/prep_syndata.f90
index 673a13d..43835e6 100644
--- a/prep_syndata/prep_syndata.f90
+++ b/prep_syndata/prep_syndata.f90
@@ -60,9 +60,6 @@ program prep_syndata
     stop 'ERROR: need to specify SETTINGS_config file'
   endif
 
-  write(*,*) 'Using: '//trim(settings_files)
-  write(*,*) 'Using: '//trim(settings_config)
-
   ! initialization
   ! --------------
 
diff --git a/prep_syndata/run_prepsyndata.sh b/prep_syndata/run_prepsyndata.sh
new file mode 100755
index 0000000..c9075af
--- /dev/null
+++ b/prep_syndata/run_prepsyndata.sh
@@ -0,0 +1,24 @@
+#!/bin/bash 
+#SBATCH -J prep_syndata
+#SBATCH -p main
+#SBATCH -o prep_syndata.out
+#SBATCH --time=4:00:00
+#SBATCH --mem=8000
+
+#---------------------------------------------------
+
+settings_file='/mypath/settings/SETTINGS_files'
+settings_config='/mypath/settings/SETTINGS_config'
+
+#---------------------------------------------------
+
+module purge
+module load gcc/13.2.0-tkesy
+module load openmpi/5.0.3-l3mqa
+module load eccodes/2.34.0-wrusa
+
+export LIBRARY_PATH=$LIBRARY_PATH:/apps/sw/ubuntu22.04/gcc-13.2.0/eccodes-2.34.0-wrusaoev7mlquymqrelfbxrhvnagtz6d/lib:/apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/apps/sw/ubuntu22.04/gcc-13.2.0/eccodes-2.34.0-wrusaoev7mlquymqrelfbxrhvnagtz6d/lib:/apps/sw/ubuntu22.04/gcc-13.2.0/netcdf-fortran-4.6.1-ubcs4l6pjwpgoeyvz32wpzyzykib6bwm/lib
+
+srun ./prep_syndata ${settings_file} ${settings_config}
+
diff --git a/settings/SETTINGS_aero_config b/settings/SETTINGS_aero_config
new file mode 100644
index 0000000..511cd86
--- /dev/null
+++ b/settings/SETTINGS_aero_config
@@ -0,0 +1,151 @@
+# ==================================================
+#
+# FLEXINVERT CONFIGURATION SETTINGS
+#
+# comment lines start with '#'
+# each parameter line starts with 'parameter name:'
+#
+# ==================================================
+
+# Run mode:
+#  0 = run forward model
+#  1 = run optimization
+#  2 = randomly perturb for MC 
+run_mode:    1
+
+# Random number seed
+# (only used if run_mode = 2)
+seed:        100
+
+# Run dates: format yyyymmdd
+# datei = start date 
+# datef = end date
+datei:      20120101
+datef:      20120131
+
+# Use lognormal distribution (true or false) (only for non-CO2 species)
+# if true need to use m1qn3 method
+lognormal: .false.
+
+# Truncation of eigenvalues of B (cut at trunc x largest eigenvalue)
+trunc:      1.e-4
+
+# Inversion method ('analytic', 'congrad' or 'm1qn3')
+method:     congrad 
+
+# Average/select flexpart releases (true or false)
+average_fp: .true.
+
+# Number of iterations
+# only used if method is 'congrad' or 'm1qn3'
+maxiter:    10
+
+# Optimize ocean boxes (true or false)
+inc_ocean:  .false.
+
+# Optimize initial mixing ratios (true or false)
+# (not relevant for aerosols)
+opt_cini:    .false.
+
+# Use spatial correlation in error covariance matrix (true or false)
+# if use regions based ecosystems then should be false
+spa_corr:   .true.
+
+# Use best guess estimate from previous inversion (congrad only)
+# 0 = no prior best guess
+# 1 = use prior best guess (file must be specified in SETTINGS_files)
+prior_bg:    0
+
+# Restart a crashed run
+# for congrad/m1qn3 will pick-up from last iteration
+# for analytic will only use pre-calculated covariance matrix and boundary conditions
+# 0 = new run
+# 1 = restart crashed run
+restart:     0
+
+# Verbose output
+# only use for debugging small runs
+verbose:    .true.
+
+# Use satellite observations (true or false)
+satellite:   .false.
+
+# Use ground-based observations (true or false)
+ground:      .true.
+
+# Species ("co2" or "ghg" or "aero")
+spec:        aero
+
+# Coefficient to convert from grid units of ppt to ppb
+coeff:       1.0
+
+# Use nested flexpart output (true or false)
+nested:     .false.
+
+# Inversion domain:
+# if using nested output it must match the inversion domain
+# w_edge_lon = lon of western edge of inversion grid
+# s_edge_lat = lat of southern edge inversion grid
+# e_edge_lon = lon of eastern edge of inversion grid
+# n_edge_lat = lat of northern inversion grid
+# xres  = longitudinal grid resolution 
+# yres  = latitudinal grid resolution 
+w_edge_lon:  -15
+s_edge_lat:   30
+e_edge_lon:   35
+n_edge_lat:   75  
+xres:         1.0
+yres:         1.0
+
+# Spatial aggregation of grid (true or false)
+regions:    .true.
+
+# Select ground observations for day/night for low altitude/mountain sites
+selectobs:  .true.
+
+# State vector (days):
+# temporal resolution at which NEE fluxes are optimized
+# must be an integer multiple of 1 day
+statres:     10.
+
+# prior fluxes:
+# nstep_flx = time step of other fluxes (integer hours, for monthly data use 720)
+nstep_flx:   720
+
+# Measurement error: unit same as obs 
+measerr:     100.0
+
+# Initial mixing ratio error: fraction
+# (not relevant for aerosols)
+cinierr:     0.005
+
+# Prior flux error: fraction
+flxerr:      0.5
+
+# Lower limit flux error: unit (kg/m2/h)
+flxerr_ll:   1.e-8
+
+# Spatial correlation length for land: unit (km)
+sigma_land:  250.
+
+# Spatial correlation length for ocean: unit (km)
+sigma_ocean: 1000.
+
+# Temporal correlation length: unit (days)
+sigmatime:   30.
+
+# Total error for inversion domain (Tg/y)
+# globerr <= 0: prior error covariance matrix not scaled
+globerr:     -1.
+
+# Settings for optimization of initial mixing ratios
+# (not relevant for aerosols)
+# comma separated list of northern edges of latitude bands
+cini_lat:    -30.,0.,30.,90.
+# comma separated list of upper level of vertical bands (upper most level > outheight(nzgrid))
+#cini_alt:    2000., 10000., 55000.
+cini_alt:    55000.
+# time resolution for initial mixing ratio scalars (days) 
+cinires:     30.
+
+
diff --git a/settings/SETTINGS_aero_files b/settings/SETTINGS_aero_files
new file mode 100644
index 0000000..3274512
--- /dev/null
+++ b/settings/SETTINGS_aero_files
@@ -0,0 +1,89 @@
+# ==================================================
+#
+# FLEXINVERT FILE SETTINGS
+#
+# comment lines start with '#'
+# each parameter line starts with 'parameter name:'
+#
+# Prior fluxes file dimensions: 
+#  time      : days since 1900
+#  latitude  : latitude degrees north midpoints
+#  longitude : longitude degrees east midpoints
+#
+# Regional mask file dimensions:
+#  latitude  : latitude degrees north midpoints
+#  longitude : longitude degrees east midpoints
+#
+# Land-sea mask file dimensions:
+#  latitude  : latitude degrees north midpoints
+#  longitude : longitude degrees east midpoints
+#
+# Initial concentrations file dimensions:
+#  latitude  : latitude degrees north south boundary
+#  longitude : longitude degrees east west boundary 
+#
+# Receptor list file: 
+#  ascii file containing one column list of 
+#  receptor names
+#
+# ==================================================
+
+# Paths:
+path_obs:      /mypath/obs/
+path_prior:    /mypath/flux/
+path_output:   /mypath/output/
+path_flexpart: /mypath/flexpart_output/
+path_flexncdf: /mypath/flexpart_ncdf_out/
+
+# Prior best guess file (if prior_bg = 1 in SETTINGS_config)
+file_bg:       
+
+# Suffix by which to identify observation files
+suffix:       .txt
+
+# Log file:
+file_log:     flexinvert.log
+
+# Regions mask file:
+# needs to correspond to flexpart domain and resolution (if using nested output needs to correspond to nest)
+file_regions: /mypath/output/regions_aero.nc
+varname_regs: regions
+lonname_regs: longitude
+latname_regs: latitude
+
+# Orography file:
+# needs to correspond to global flexpart domain and resolution
+file_orog:    /mypath/input/elev.1-deg.nc
+varname_orog: data
+lonname_orog: lon
+latname_orog: lat
+
+# Land-sea mask file:
+# needs to correspond to flexpart domain and resolution (if using nested output needs to correspond to nest)
+file_lsm:     /mypath/input/lsm_1x1.nc
+varname_lsm:  lsm
+lonname_lsm:  lon
+latname_lsm:  lat
+
+# Global prior flux file: flux kg/m2/h
+# needs to correspond to flexpart domain and resolution
+# generic name with year YYYY
+filename_flx: AERO_TOTAL_YYYY_10x10.nc
+varname_flx:  emis
+lonname_flx:  longitude
+latname_flx:  latitude
+timename_flx: time
+
+# Regional prior flux file: flux kg/m2/h
+# only needed if using nested output (needs to correspond to nest)
+# generic name with year YYYY
+filenest_flx: 
+varnest_flx:  
+lonnest_flx: 
+latnest_flx:  
+timenest_flx:
+
+# Receptor list file:
+file_recept:   /mypath/input/reclist_aero.txt
+
+
diff --git a/settings/SETTINGS_co2_config b/settings/SETTINGS_co2_config
index c35647a..a80f8fd 100644
--- a/settings/SETTINGS_co2_config
+++ b/settings/SETTINGS_co2_config
@@ -103,6 +103,9 @@ yres:        1.0
 # Spatial aggregation of grid (true or false)
 regions:    .false.
 
+# Select ground observations for day/night for low altitude/mountain sites
+selectobs:  .true.
+
 # State vector time resolution:
 # time resolution at which NEE fluxes are optimized
 # statres = averaging interval over 1 or more days (given in days)
diff --git a/settings/SETTINGS_ghg_config b/settings/SETTINGS_ghg_config
index 225cc30..901327c 100644
--- a/settings/SETTINGS_ghg_config
+++ b/settings/SETTINGS_ghg_config
@@ -102,6 +102,9 @@ yres:         1.0
 # Spatial aggregation of grid (true or false)
 regions:    .true.
 
+# Select ground observations for day/night for low altitude/mountain sites
+selectobs:  .true.
+
 # State vector (days):
 # temporal resolution at which NEE fluxes are optimized
 # must be an integer multiple of 1 day
diff --git a/source/average_fp.f90 b/source/average_fp.f90
index 4600328..1a52cc6 100755
--- a/source/average_fp.f90
+++ b/source/average_fp.f90
@@ -79,7 +79,7 @@ subroutine average_fp(files, config, obs)
   integer                                  :: ngrid, nretr, ierr
 
   real                                     :: bndx, bndy, delx, dely
-  integer                                  :: numx, numy, xshift, new_grid_time, standard_grid_time
+  integer                                  :: numx, numy, numz, xshift, new_grid_time, standard_grid_time
   integer                                  :: numpoint, release_nr, nr_footprints
   integer                                  :: ibdate, ibtime
   real(kind=8), dimension(maxpoint,2)      :: releases
@@ -127,12 +127,12 @@ subroutine average_fp(files, config, obs)
     if ( i.eq.1 .or. month.ne.prevmonth ) then
       write(logid,*) 'Get header:', i, ' '//trim(path_flexrec)//'header'
       call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                         numx, numy, bndx, bndy, delx, dely, xshift)
+                         numx, numy, numz, bndx, bndy, delx, dely, xshift)
     else
       if(trim(obs%recs(i)).ne.trim(obs%recs(i-1)))then
         write(logid,*) 'Get header:', i, ' '//trim(path_flexrec)//'header'
         call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely, xshift)
+                           numx, numy, numz, bndx, bndy, delx, dely, xshift)
       endif
     endif
   
diff --git a/source/calc_conc.f90 b/source/calc_conc.f90
index c3e1a0f..b70c602 100644
--- a/source/calc_conc.f90
+++ b/source/calc_conc.f90
@@ -76,8 +76,8 @@ subroutine calc_conc(config, fluxes, obs, ngrid, gtime, hnest, hbkg, iobs, ix1,
     flxbg = fluxes%flxnee(:,:,ind) + &
                     fluxes%flxff(:,:,ind) + &
                     fluxes%flxocn(:,:,ind) 
-  else if (( trim(config%spec).eq.'ghg' ) .or. ( trim(config%spec).eq.'bca' )) then
-    ! GHG or BC aerosol species
+  else if (( trim(config%spec).eq.'ghg' ) .or. ( trim(config%spec).eq.'aero' )) then
+    ! GHG or aerosol species
     flxbg = fluxes%flx(:,:,ind)
   endif
 
@@ -129,7 +129,7 @@ subroutine calc_conc(config, fluxes, obs, ngrid, gtime, hnest, hbkg, iobs, ix1,
         obs%ocn(iobs) = obs%ocn(iobs) + sum(hnest(:,:,n) * fluxes%flxocn(ix1:ix2,jy1:jy2,ilo))
       endif
     else
-      ! GHG species
+      ! GHG and aerosol species
       if ( config%nested ) then
         ! nested domain
         obs%ghg(iobs) = obs%ghg(iobs) + sum(hnest(:,:,n) * fluxes%flx_nest(:,:,ilo))
@@ -138,7 +138,7 @@ subroutine calc_conc(config, fluxes, obs, ngrid, gtime, hnest, hbkg, iobs, ix1,
         obs%ghg(iobs) = obs%ghg(iobs) + sum(hnest(:,:,n) * fluxes%flx(ix1:ix2,jy1:jy2,ilo))
       endif
       if ( config%lognormal.and..not.config%inc_ocean ) then
-        ! since for lognormal fluxes are optimized (not offsets) if ocean fluxes are not optimized need
+        ! since for lognormal scalars of fluxes are optimized, if ocean fluxes are not optimized need
         ! to still account for influence on mixing ratios
         obs%ocn(iobs) = obs%ocn(iobs) + sum(hnest(:,:,n) * fluxes%flxocn(:,:,ilo))
       endif
@@ -151,9 +151,12 @@ subroutine calc_conc(config, fluxes, obs, ngrid, gtime, hnest, hbkg, iobs, ix1,
   if ( trim(config%spec).eq.'co2' ) then
     ! CO2
     obs%err(iobs) = sqrt(obs%measerr(iobs)**2 + (sum(obs%cini(iobs,:))*config%cinierr)**2 + bkgerr + ffferr)
-  else
-    ! GHG
+  else if ( trim(config%spec).eq.'ghg' ) then
+    ! GHG 
     obs%err(iobs) = sqrt(obs%measerr(iobs)**2 + (sum(obs%cini(iobs,:))*config%cinierr)**2 + bkgerr)
+  else if ( trim(config%spec).eq.'aero' ) then
+    ! aerosols
+    obs%err(iobs) = sqrt(obs%measerr(iobs)**2 +  bkgerr)
   endif
 
 end subroutine calc_conc
diff --git a/source/init_aero.f90 b/source/init_aero.f90
new file mode 100644
index 0000000..7563d20
--- /dev/null
+++ b/source/init_aero.f90
@@ -0,0 +1,472 @@
+!---------------------------------------------------------------------------------------
+! FLEXINVERT: init_aero
+!---------------------------------------------------------------------------------------
+!  FLEXINVERT is free software: you can redistribute it and/or modify
+!  it under the terms of the GNU General Public License as published by
+!  the Free Software Foundation, either version 3 of the License, or
+!  (at your option) any later version.
+!
+!  FLEXINVERT is distributed in the hope that it will be useful,
+!  but WITHOUT ANY WARRANTY; without even the implied warranty of
+!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+!  GNU General Public License for more details.
+!
+!  You should have received a copy of the GNU General Public License
+!  along with FLEXINVERT.  If not, see <http://www.gnu.org/licenses/>.
+!
+!  Copyright 2017, Rona Thompson
+!---------------------------------------------------------------------------------------
+!
+!> init_aero
+!! Initialize aerosol variables
+!!
+!! Purpose:    Reads prior fluxes and observations of an aerosol and calculates the 
+!!             state and observation vectors as well as their uncertainties.
+!!
+!! Interface:
+!!
+!!    Inputs
+!!             files   -  file data structure
+!!             config  -  configuration settings data structure
+!!             fluxes  -  flux data structure
+!!             obs     -  observation data structure
+!!             covar   -  error covariance data structure
+!!
+!!    Externals
+!!             alloc_fluxes
+!!             alloc_states
+!!             caldate     
+!!             read_ncdf        
+!!             read_bg       
+!!             correl
+!!             error_cov        
+!!             read_obs
+!!             assign_obs
+!!             perturb_state
+!!             perturb_obs
+!!
+!---------------------------------------------------------------------------------------
+
+subroutine init_aero(files, config, fluxes, obs, states, covar)
+
+  use mod_var
+  use mod_settings
+  use mod_dates
+  use mod_tools
+  use mod_strings
+  use mod_fluxes
+  use mod_obs
+  use mod_states
+  use mod_covar
+  use mod_perturb
+  use mod_save, only : save_for_restart 
+
+  implicit none
+
+  type (files_t),        intent (in)         :: files
+  type (config_t),       intent (in)         :: config
+  type (fluxes_t),       intent (in out)     :: fluxes
+  type (obs_t),          intent (in out)     :: obs
+  type (states_t),       intent (in out)     :: states
+  type (covar_t),        intent (in out)     :: covar
+
+  character(max_path_len)                    :: filename
+  character(max_path_len)                    :: rowfmt
+  character(len=4)                           :: adate
+  character(len=2)                           :: amonth
+  logical                                    :: lexist
+  real, dimension(:,:,:), allocatable        :: flx, flxghg
+  real, dimension(:,:), allocatable          :: datain, dataout
+  real, dimension(nbox,ntstate)              :: flx_box
+  real, dimension(nbox,ntstate)              :: err_box
+  real, dimension(nbox)                      :: xerr
+  real, dimension(nbox,nbox)                 :: corr
+  integer                                    :: yyyymmdd, hhmiss
+  real                                       :: area
+  real(kind=8)                               :: jd
+  integer                                    :: ix, jy, ix0, jy0, ix1, ix2, jy1, jy2
+  integer                                    :: i, n, nb, nread, num, eomday
+  integer                                    :: ierr
+  real(kind=8), dimension(:), allocatable    :: jdate, timeghg
+  character(len=recname_len), dimension(:), allocatable:: recs
+  real                                       :: conc
+  character(len=20)                          :: dump
+  real, parameter                            :: smallnum=1.e-15
+
+  ! global prior fluxes
+  ! -------------------
+
+  ! if nested run global fluxes are only used to calculate the contribution to  mixing ratios 
+  ! from fluxes outside the inversion domain, otherwise, global fluxes are used to
+  ! calculate the contribution to mixing ratios and as prior fluxes inside the domain.
+
+  call alloc_fluxes(config, fluxes)
+  fluxes%flx(:,:,:) = 0.
+  fluxes%flxocn(:,:,:) = 0.
+
+  ! loop over prior flux files
+
+  allocate( flxghg(nxgrid,nygrid,max(1,(nday*24/nt_flx))), stat = ierr )
+  if ( ierr.ne.0 ) stop 'ERROR init_aero: not enough memory'
+  allocate( timeghg(max(1,nday*24/nt_flx)) )
+
+  n = 0
+  jd = juldatei
+  do while ( jd.le.juldatef )
+    call caldate(jd, yyyymmdd, hhmiss)
+    write(adate,'(I4.4)') yyyymmdd/10000
+    write(amonth,'(I2.2)') (yyyymmdd-(yyyymmdd/10000)*10000)/100
+    eomday = calceomday(yyyymmdd/100)    
+    nread = eomday*24/nt_flx
+    if ( nread.eq.0 ) nread = 1
+    print*, 'init_aero: nread = ',nread
+    allocate( flx(nxgrid,nygrid,nread), stat = ierr )
+    if ( ierr.ne.0 ) stop 'ERROR init_aero: not enough memory'
+    filename = str_replace(files%filename_flx, 'YYYY', adate)
+    if ( index(filename, 'MM').ne.0 ) then
+      filename = str_replace(filename, 'MM', amonth)
+    endif
+    filename = trim(files%path_prior)//trim(filename)
+    write(logid,*) 'Reading prior fluxes :'//trim(filename)
+    inquire(file=trim(filename),exist=lexist)
+    if (.not.lexist) then
+      write(logid,*) 'ERROR: cannot find '//trim(filename)
+      stop
+    endif
+    call read_ncdf(filename, &
+                   files%varname_flx, &
+                   files%lonname_flx, &
+                   files%latname_flx, &
+                   files%timename_flx,&
+                   llx, lly, &
+                   nxgrid, nygrid, &
+                   jd, nread, num, &
+                   flx)
+    do i = 1, nread
+      if ( ((n+i).gt.(nday*24/nt_flx)).and.(nday*24/nt_flx.ne.0) ) exit
+      flxghg(:,:,n+i) = flx(:,:,i)
+      timeghg(n+i) = jd + dble((i-1)*nt_flx)/24d0
+    end do
+    deallocate( flx )
+    n = n + nread
+    jd = jd + dble(eomday)
+  end do
+  n = min(n, nday*24/nt_flx)
+  n = max(n, 1)
+  print*, 'init_aero: n = ',n
+  print*, 'init_aero: timeghg = ',timeghg
+
+  ! convert to kg/m2/s
+  flxghg = flxghg/3600.
+  ! apply numerical scaling
+  flxghg = flxghg*numscale
+
+  ! average/interpolate to state vector timestamp
+  allocate( datain(nxgrid,n) )
+  allocate( dataout(nxgrid,ntstate) )
+  do i = 1, ntstate
+    fluxes%time(i) = juldatei + dble(i-1)*dble(statres)
+  enddo
+  if ( statres.gt.real(nt_flx/24) ) then
+    ! average flux
+    do jy = 1, nygrid
+      datain = flxghg(:,jy,:)
+      call average(nxgrid, n, timeghg, datain, ntstate, fluxes%time, dataout)
+      fluxes%flx(:,jy,:) = dataout(:,:)
+    end do
+  else if ( statres.lt.real(nt_flx/24) ) then
+    ! interpolate flux
+    do jy = 1, nygrid
+      datain = flxghg(:,jy,:)
+      call interp(nxgrid, n, timeghg, datain, ntstate, fluxes%time, dataout)
+      fluxes%flx(:,jy,:) = dataout(:,:)
+    end do
+  else if ( statres.eq.real(nt_flx/24) ) then
+    fluxes%flx(:,:,:) = flxghg
+  endif
+  deallocate( datain )
+  deallocate( dataout )
+  deallocate( flxghg )
+  deallocate( timeghg )
+
+  ! ocean fluxes for lognormal case when inc_ocean is false
+  ! cover only inversion domain
+  if ( config%lognormal.and..not.config%inc_ocean.and..not.config%nested ) then
+    ! use land-sea mask to set all land fluxes to zero
+    ix1 = int((rllx - llx + dx)/dx)
+    ix2 = int((rurx - llx)/dx)
+    jy1 = int((rlly - lly + dy)/dy)
+    jy2 = int((rury - lly)/dy)
+    do n = 1, ntstate
+      fluxes%flxocn(:,:,n) = abs(lsm(:,:) - 1.)*fluxes%flx(ix1:ix2,jy1:jy2,n)
+    end do
+  endif
+
+  ! regional prior fluxes
+  ! ---------------------
+
+  if ( config%nested ) then
+
+    allocate( flxghg(nxregrid,nyregrid,(max(1,nday*24/nt_flx))), stat = ierr )
+    if ( ierr.ne.0 ) stop 'ERROR init_aero: not enough memory'
+    allocate( timeghg(max(1,nday*24/nt_flx)) )
+
+    n = 0
+    jd = juldatei
+    do while ( jd.le.juldatef )
+      call caldate(jd, yyyymmdd, hhmiss)
+      write(adate,'(I4.4)') yyyymmdd/10000
+      write(amonth,'(I2.2)') (yyyymmdd-(yyyymmdd/10000)*10000)/100
+      eomday = calceomday(yyyymmdd/100)
+      nread = eomday*24/nt_flx
+      if ( nread.eq.0 ) nread = 1
+      print*, 'init_aero: reg nread = ',nread
+      allocate( flx(nxregrid,nyregrid,nread), stat = ierr )
+      if ( ierr.ne.0 ) stop 'ERROR init_aero: not enough memory'
+      filename = str_replace(files%filenest_flx, 'YYYY', adate)
+      if ( index(filename, 'MM').ne.0 ) then
+        filename = str_replace(filename, 'MM', amonth)
+      endif
+      filename = trim(files%path_prior)//trim(filename)
+      write(logid,*) 'Reading prior fluxes :'//trim(filename)
+      inquire(file=trim(filename),exist=lexist)
+      if (.not.lexist) then
+        write(logid,*) 'ERROR: cannot find '//trim(filename)
+        stop
+      endif
+      call read_ncdf(filename, &
+                     files%varnest_flx, &
+                     files%lonnest_flx, &
+                     files%latnest_flx, &
+                     files%timenest_flx,&
+                     rllx, rlly, &
+                     nxregrid, nyregrid, &
+                     jd, nread, num, &
+                     flx)
+      do i = 1, nread
+        if ( ((n+i).gt.(nday*24)/nt_flx).and.((nday*24)/nt_flx.ne.0) ) exit
+        timeghg(n+i) = jd + dble((i-1)*nt_flx)/24d0
+        flxghg(:,:,n+i) = flx(:,:,i)
+      end do
+      deallocate( flx )
+      n = n + nread
+      jd = jd + dble(eomday)
+    end do
+    n = min(n, (nday*24)/nt_flx)
+    n = max(n, 1)
+    print*, 'init_aero: reg n = ',n
+    print*, 'init_aero: reg timeghg = ',timeghg
+
+    ! convert to kg/m2/s
+    flxghg = flxghg/3600.
+    ! apply numerical scaling
+    flxghg = flxghg*numscale
+
+    ! average/interpolate to state vector timestamp
+    allocate( datain(nxregrid,n) )
+    allocate( dataout(nxregrid,ntstate) )
+    if ( statres.gt.real(nt_flx/24) ) then
+      ! average flux
+      do jy = 1, nyregrid
+        datain = flxghg(:,jy,:)
+        call average(nxregrid, n, timeghg, datain, ntstate, fluxes%time, dataout)
+        fluxes%flx_nest(:,jy,:) = dataout(:,:)
+      end do
+    else if ( statres.lt.real(nt_flx/24) ) then
+      ! interpolate flux
+      do jy = 1, nyregrid
+        datain = flxghg(:,jy,:)
+        call interp(nxregrid, n, timeghg, datain, ntstate, fluxes%time, dataout)
+        fluxes%flx_nest(:,jy,:) = dataout(:,:)
+      end do
+    else if ( statres.eq.real(nt_flx/24) ) then
+      fluxes%flx_nest(:,:,:) = flxghg
+    endif
+    deallocate( datain )
+    deallocate( dataout )
+    deallocate( flxghg )
+    deallocate( timeghg )
+
+    ! ocean fluxes for lognormal case when inc_ocean is false
+    if ( config%lognormal.and..not.config%inc_ocean ) then
+      ! use land-sea mask to set all land fluxes to zero
+      do n = 1, ntstate
+        fluxes%flxocn(:,:,n) = abs(lsm(:,:) - 1.)*fluxes%flx_nest(:,:,n)
+      end do
+    endif
+
+    ! nest -> use nested fluxes for state vector
+    allocate( flx(nxregrid,nyregrid,ntstate) )
+    flx(:,:,:) = fluxes%flx_nest
+
+  else
+
+    ! no nest -> use global fluxes for state vector 
+    allocate( flx(nxgrid,nygrid,ntstate) )
+    flx(:,:,:) = fluxes%flx
+
+  endif
+
+  ! prior state vector
+  ! ------------------
+
+  ! calculate area-weighted mean flux and uncertainty for each box
+
+  if ( config%nested ) then
+    ix0 = 1
+    jy0 = 1
+  else
+    ix0 = minloc(gbl_lon,dim=1,mask=abs(gbl_lon-rllx).eq.minval(abs(gbl_lon-rllx)))
+    jy0 = minloc(gbl_lat,dim=1,mask=abs(gbl_lat-rlly).eq.minval(abs(gbl_lat-rlly)))
+  endif
+  write(logid,*) 'init_aero: ix0, jy0 = ',ix0,jy0
+
+  flx_box(:,:) = 0.
+  err_box(:,:) = 0.
+  do n = 1, ntstate
+    do ix = 1, nxregrid
+      do jy = 1, nyregrid
+        area = grid_area(reg_lat(jy)+0.5*rdy, rdy, rdx)
+        ! if inc_ocean flx_box contains all fluxes, if false only land fluxes
+        if ( nbox_xy(ix,jy).gt.0 ) then
+          flx_box(nbox_xy(ix,jy),n) = flx_box(nbox_xy(ix,jy),n) + &
+                                        flx(ix0+ix-1,jy0+jy-1,n) * area
+          err_box(nbox_xy(ix,jy),n) = err_box(nbox_xy(ix,jy),n) + &
+                                        flx(ix0+ix-1,jy0+jy-1,n) * config%flxerr * area
+        endif
+      end do
+    end do
+    flx_box(:,n) = flx_box(:,n)/area_box
+    err_box(:,n) = err_box(:,n)/area_box
+  end do
+  fluxes%flx_box(:,:,1) = flx_box(:,:)
+
+  ! set minimum error
+  do n = 1, ntstate
+    do nb = 1, nbox
+      err_box(nb,n) = max(config%flxerr_ll*numscale/3600.,err_box(nb,n))
+    end do
+  end do
+
+  ! verbose output
+  ! --------------
+
+  if ( config%verbose ) then
+    ! check prior fluxes read correctly (1-time dimension only)
+    write(rowfmt,'(A,I6,A)') '(',nxregrid,'(E11.4,1X))'
+    open(100,file=trim(files%path_output)//'flx_prior.txt',status='replace',action='write',iostat=ierr)
+    do n = 1, nyregrid
+      write(100,fmt=rowfmt) flx(ix0:(ix0+nxregrid-1),jy0+n-1,1)
+    end do
+    close(100)
+    ! check regridding to variable resolution 
+    write(rowfmt,'(A,I6,A)') '(',nbox,'(E11.4,1X))'
+    open(100,file=trim(files%path_output)//'flx_box.txt',status='replace',action='write',iostat=ierr)
+    do n = 1, ntstate
+      write(100,fmt=rowfmt) flx_box(:,n)
+    end do
+    close(100)
+  endif
+
+  ! prior state vector
+  ! ------------------
+
+  ! number of state variables
+  npvar = ntstate*nbox
+  ndvar = nbox
+  nvar = npvar
+  write(logid,*) 'Number of flux state variables: ',npvar
+  write(logid,*) 'Number of state variables per flux time step: ',ndvar
+  write(logid,*) 'Total number of state variables: ',nvar
+
+  ! allocate state and error vectors
+  call alloc_states(states)
+
+  if ( config%lognormal ) then
+    ! lognormal distribution 
+    ! optimize scalar z = ln(x/xb) 
+    ! prior state vector z is zero
+    states%px0(1:npvar) = 0.
+  else
+    ! normal distribution
+    ! prior state vector zero since optimize offsets
+     states%px0(1:npvar) = 0.
+  endif
+
+  ! time stamp of flux variables
+  states%xtime(:) = fluxes%time
+
+  if ( config%lognormal ) then
+    ! lognormal 
+    ! uncertainty of a scalar of fluxes -> use constant uncertainty
+    ! transform to error of z
+    xerr(:) = log(1.+config%flxerr)
+  else
+    ! normal
+    ! average error over time steps
+    xerr = abs(sum(err_box(:,:),dim=2)/real(ntstate) )
+  endif
+
+  ! assign best guess of state vector
+  if ( (config%prior_bg.eq.1).and.((config%method.eq.'congrad').or.(config%method.eq.'m1qn3')) ) then
+    ! from previous inversion
+    call read_bg(files, config, states)
+  else
+    ! from prior
+    states%px(:) = states%px0(:)
+  endif
+
+  ! testing
+  open(100,file=trim(files%path_output)//'prior.txt',status='replace',action='write',iostat=ierr)
+  do n = 1, nvar
+    write(100,fmt='(E14.8)') states%px(n)
+  end do
+  close(100)  
+
+  ! correlation and error covariance matrices
+  ! -----------------------------------------
+
+  corr(:,:) = 0.
+  if ( config%spa_corr ) then
+    write(logid,*) 'Using spatial correlation in B'
+    ! check if file already exists (in case of rerun)
+    inquire(file=trim(files%path_output)//'correl.txt',exist=lexist) 
+    if ( lexist ) then
+      write(logid,*) 'Reading spatial correlation from correl.txt'
+      open(100,file=trim(files%path_output)//'correl.txt',action='read',status='old',iostat=ierr)
+      write(rowfmt,'(A,I6,A)') '(',nbox,'(E11.4,1X))'
+      print*, rowfmt
+      do nb = 1, nbox
+        read(100,fmt=rowfmt) corr(nb,:)
+      end do
+      close(100)
+    else
+      call correl(files, config, corr)
+    endif
+  else
+    do n = 1, nbox
+      corr(n,n) = 1.
+    end do
+  endif
+  call error_cov(config, files, states, covar, corr, xerr)
+
+  ! observations
+  ! ------------
+
+  call read_obs(config, files)
+  call assign_obs(config, files, obs)
+
+  ! add random perturbation for MC
+  ! ------------------------------
+
+  if ( config%run_mode.eq.2 ) then
+    write(logid,*) 'Adding random perturbation to state vector and observations...'
+    ! perturb state vector
+    call perturb_state(config, states, covar)
+    ! perturb observations 
+    call perturb_obs(config, obs)
+  endif
+
+end subroutine init_aero
+
+
diff --git a/source/init_cini.f90 b/source/init_cini.f90
index 9577c63..0447d07 100644
--- a/source/init_cini.f90
+++ b/source/init_cini.f90
@@ -72,7 +72,7 @@ subroutine init_cini(files, config, obs)
   real, dimension(:,:,:,:), allocatable  :: concini
 
   real                                   :: bndx, bndy, delx, dely
-  integer                                :: numx, numy, xshift
+  integer                                :: numx, numy, numz, xshift
   integer                                :: numpoint, release_nr, nr_init
   integer                                :: ibdate, ibtime
   real(kind=8), dimension(maxpoint,2)    :: releases
@@ -146,12 +146,12 @@ subroutine init_cini(files, config, obs)
       if ( i.eq.1 .or. month.ne.prevmonth ) then
         write(logid,*) 'Get header:', i, ' '//trim(path_flexrec)//'header'
         call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely, xshift)
+                           numx, numy, numz, bndx, bndy, delx, dely, xshift)
       else
         if(trim(obs%recs(ind(i))).ne.trim(obs%recs(ind(i-1))))then
           write(logid,*) 'Get header:', i, ' '//trim(path_flexrec)//'header'
           call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                             numx, numy, bndx, bndy, delx, dely, xshift)
+                             numx, numy, numz, bndx, bndy, delx, dely, xshift)
         endif
       endif
       ! find the first release number corresponding to the current observation
diff --git a/source/init_cini_month.f90 b/source/init_cini_month.f90
index f2f56d9..ee6856b 100644
--- a/source/init_cini_month.f90
+++ b/source/init_cini_month.f90
@@ -70,7 +70,7 @@ subroutine init_cini_month(files, config, obs)
   real, dimension(nxgrid,nygrid,nzgrid,1):: concini, preconcini, proconcini
 
   real                                   :: bndx, bndy, delx, dely
-  integer                                :: numx, numy, xshift
+  integer                                :: numx, numy, numz, xshift
   integer                                :: numpoint, release_nr, nr_init
   integer                                :: ibdate, ibtime
   real(kind=8), dimension(maxpoint,2)    :: releases
@@ -131,12 +131,12 @@ subroutine init_cini_month(files, config, obs)
       if ( i.eq.1 .or. month.ne.prevmonth ) then
         write(logid,*) 'Get header:', i, ' '//trim(path_flexrec)//'header'
         call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely, xshift)
+                           numx, numy, numz, bndx, bndy, delx, dely, xshift)
       else
         if(trim(obs%recs(ind(i))).ne.trim(obs%recs(ind(i-1))))then
           write(logid,*) 'Get header:', i, ' '//trim(path_flexrec)//'header'
           call read_header(filename, numpoint, ibdate, ibtime, releases, &
-                             numx, numy, bndx, bndy, delx, dely, xshift)
+                             numx, numy, numz, bndx, bndy, delx, dely, xshift)
         endif
       endif
       ! find the first release number corresponding to the current observation
diff --git a/source/init_ghg.f90 b/source/init_ghg.f90
index 15ab159..63cb925 100644
--- a/source/init_ghg.f90
+++ b/source/init_ghg.f90
@@ -481,7 +481,7 @@ subroutine init_ghg(files, config, fluxes, obs, states, covar)
 
   ! initial concentrations from termination of trajectories
   ! only do for a fresh run
-  if ( ( config%restart.eq.0 ).and.( config%spec.ne.'bca') ) then  
+  if ( config%restart.eq.0 ) then
     if ( files%init_type.lt.5 ) then
       ! daily or higher frequency
       call init_cini(files, config, obs)
diff --git a/source/initialize.f90 b/source/initialize.f90
index adbb03d..f0b7b1a 100644
--- a/source/initialize.f90
+++ b/source/initialize.f90
@@ -55,7 +55,7 @@ subroutine initialize(files, config)
   integer                                :: ibdate, ibtime, jjjjmmdd, hhmiss
   real(kind=8), dimension(maxpoint,2)    :: releases
   real                                   :: bndx, bndy, delx, dely
-  integer                                :: numx, numy, xshift
+  integer                                :: numx, numy, numz, xshift
   integer                                :: i, ierr
 
   ! initialize log file
@@ -146,11 +146,14 @@ subroutine initialize(files, config)
   endif
   write(logid,*) 'Reading flexpart header: '//trim(filename)
   call read_header(filename, numpoint, ibdate, ibtime, releases, & 
-                     numx, numy, bndx, bndy, delx, dely, xshift)
+                     numx, numy, numz, bndx, bndy, delx, dely, xshift)
 
   ! global domain variables
   nxgrid = numx
   nygrid = numy
+  ! nzgrid is the number full vertical layers in grid_initial 
+  ! read only from header for global grid_time files 
+  nzgrid = numz
   llx = bndx
   lly = bndy
   dx = delx
@@ -172,6 +175,11 @@ subroutine initialize(files, config)
       write(areldate,'(I8)') config%datei
       filename = trim(files%path_flexsat)//areldate//'/header_nest'
       inquire(file=trim(filename),exist=lexist)
+      if ( .not.lexist ) then
+        ! test if is FPv11 file
+        filename = trim(files%path_flexsat)//areldate//'/header_nest_grid_time'
+        inquire(file=trim(filename),exist=lexist)
+      endif
     else
       ! read from ground-based output
       lexist = .false.
@@ -179,6 +187,11 @@ subroutine initialize(files, config)
       do while ( (.not.lexist).and.(i.le.nrec) )
         filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest'
         inquire(file=trim(filename),exist=lexist)
+        if ( .not.lexist) then
+          ! test if is FPv11 file
+          filename = trim(files%path_flexpart)//trim(recname(i))//'/'//adate//'/header_nest_grid_time'
+          inquire(file=trim(filename),exist=lexist)
+        endif
         i = i + 1
       end do
     endif ! satellite
@@ -188,7 +201,7 @@ subroutine initialize(files, config)
     endif
     write(logid,*) 'Reading flexpart header_nest: '//trim(filename)
     call read_header(filename, numpoint, ibdate, ibtime, releases, & 
-                       numx, numy, bndx, bndy, delx, dely, xshift)
+                       numx, numy, numz, bndx, bndy, delx, dely, xshift)
 
     ! nested domain variables
     nnxgrid = numx
diff --git a/source/job_flexinvert.sh b/source/job_flexinvert.sh
index 479ee24..0f92bf6 100755
--- a/source/job_flexinvert.sh
+++ b/source/job_flexinvert.sh
@@ -1,7 +1,7 @@
 #!/bin/bash 
 #---------------------------------------------------
 
-settings_files='/mypath/settings/SETTINGS_ghg_files'
-settings_config='/mypath/settings/SETTINGS_ghg_config'
+settings_files='../settings/SETTINGS_ghg_files'
+settings_config='../settings/SETTINGS_ghg_config'
 
 ./main ${settings_files} ${settings_config} 
diff --git a/source/main.f90 b/source/main.f90
index d5e9971..f5ee070 100644
--- a/source/main.f90
+++ b/source/main.f90
@@ -89,10 +89,12 @@ program main
 
   if ( config%spec.eq.'co2' ) then
     call init_co2(files, config, fluxes, obs, states, covar)
-  else if ((config%spec.eq.'ghg').or.(config%spec.eq.'bca')) then
+  else if ( config%spec.eq.'ghg' ) then
     call init_ghg(files, config, fluxes, obs, states, covar)
+  else if ( config%spec.eq.'aero' ) then
+    call init_aero(files, config, fluxes, obs, states, covar)
   else
-    write(logid,*) 'ERROR: spec must be one of co2 or ghg'
+    write(logid,*) 'ERROR: spec must be one of co2, ghg, aero'
     stop
   endif
 
diff --git a/source/makefile b/source/makefile
index 4f2c631..38974c9 100644
--- a/source/makefile
+++ b/source/makefile
@@ -46,6 +46,7 @@ OBJECTS = read_reclist.o \
           init_cini_month.o \
           init_co2.o \
           init_ghg.o \
+          init_aero.o \
           calc_conc.o \
           simulate.o \
           average_fp.o \
diff --git a/source/mod_flexpart.f90 b/source/mod_flexpart.f90
index 08780c0..f4f54fe 100755
--- a/source/mod_flexpart.f90
+++ b/source/mod_flexpart.f90
@@ -49,7 +49,7 @@ module mod_flexpart
   ! --------------------------------------------------
 
   subroutine read_header(filename, numpoint, ibdate, ibtime, releases, &
-                           numx, numy, bndx, bndy, delx, dely, xshift)
+                           numx, numy, numz, bndx, bndy, delx, dely, xshift)
 
     use mod_var
 
@@ -59,7 +59,7 @@ module mod_flexpart
     integer,                        intent(in out) :: numpoint
     integer,                        intent(in out) :: ibdate, ibtime   
     real(kind=8), dimension(maxpoint,2), intent(in out) :: releases           
-    integer,                        intent(in out) :: numx, numy, xshift
+    integer,                        intent(in out) :: numx, numy, numz, xshift
     real,                           intent(in out) :: bndx, bndy, delx, dely
 
     character(len=29)                              :: flexversion
@@ -75,7 +75,7 @@ module mod_flexpart
     real, dimension(:), allocatable                :: xpoint, ypoint, zpoint1, zpoint2
     real, dimension(:,:), allocatable              :: xmass
     integer, dimension(10)                         :: lage
-    integer                                        :: n, i, j, ierr 
+    integer                                        :: n, i, j, ierr, dummy
  
     inquire ( file=trim(filename),exist=lexist )
     if ( .not.lexist ) then
@@ -91,14 +91,14 @@ module mod_flexpart
     read(100) ibdate, ibtime, flexversion
     read(100) loutstep, loutaver, loutsample
     read(100) bndx, bndy, numx, numy, delx, dely
-    read(100) nzgrid, (outheight(i), i = 1, nzgrid)
+    read(100) numz, (outheight(i), i = 1, numz)
     read(100) jjjjmmdd, ihmmss
-    read(100) nspec, nzgrid
+    read(100) nspec, numz
     nspec=nspec/3
     do n=1,nspec
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
-      read(100) nzgrid, species(n)
+      read(100) dummy, species(n)
+      read(100) dummy, species(n)
+      read(100) numz, species(n)
     end do
     read(100) numpoint
 
@@ -382,6 +382,8 @@ module mod_flexpart
     integer, dimension(nxgrid*nygrid*nzgrid)              :: sparse_dump_i
     real, dimension(nxgrid*nygrid*nzgrid)                 :: sparse_dump_r
     
+    print*, 'read_init: filename = ',filename
+
     gridinit(:,:,:)=0.
 
     inquire ( file=trim(filename),exist=lexist )
@@ -398,6 +400,8 @@ module mod_flexpart
     read(100) jjjjmmdd
     read(100) hhmiss
 
+    print*, 'read_init: jjjjmmdd, hhmiss = ',jjjjmmdd, hhmiss
+
     fact = 1.
     read(100) sp_count_i
     read(100) (sparse_dump_i(ix), ix=1, sp_count_i)
diff --git a/source/mod_perturb.f90 b/source/mod_perturb.f90
index d443d49..61e8834 100644
--- a/source/mod_perturb.f90
+++ b/source/mod_perturb.f90
@@ -98,7 +98,8 @@ module mod_perturb
     ! add perturbation to state vector 
     if ( config%lognormal ) then
       ! lognormal
-      states%px(:) = real(perturb(:),kind=4)
+      states%px0(:) = real(perturb(:),kind=4)
+      states%px(:) = states%px0(:) 
     else
       ! normal
       states%px0(:) = states%px0(:) + real(perturb(:),kind=4)
diff --git a/source/mod_save.f90 b/source/mod_save.f90
index aed5666..ec3c977 100644
--- a/source/mod_save.f90
+++ b/source/mod_save.f90
@@ -88,7 +88,7 @@ module mod_save
                 obs%model(i), obs%cpri(i), obs%cakpri(i), obs%delta(i), obs%err(i)
       end do
     else
-      ! GHG species
+      ! GHG and aerosol species
       write(100,*) 'rec yyyymmdd hhmmss juldate conc cini cinipos bkg ghg prior post cpri cakpri diff error'
       write(rowfmt,'(A,I1,A,I6,A)') '(A',recname_len,',1X,I8,1X,I6,1X,F14.6,1X,',11,'(F10.4,1X))'
       do i = 1, nobs
@@ -412,7 +412,7 @@ module mod_save
   ! --------------------------------------------------
   !> save_ghg
   !!
-  !! Purpose:  Saves the GHG fluxes to the file
+  !! Purpose:  Saves the GHG and aerosol fluxes to 
   !!           analysis.nc
   !!
   ! --------------------------------------------------
@@ -448,9 +448,10 @@ module mod_save
     integer, dimension(3)                      :: dimids
     integer                                    :: lon_varid, lat_varid, time_varid
     integer                                    :: pri_varid, pos_varid, epri_varid, epos_varid, xpos_varid
+    integer                                    :: mcpri_varid, mcpos_varid
     integer                                    :: ix, jy, n, ix0, jy0, nb
     real(kind=8), dimension(ntstate)           :: timeout
-    real, dimension(nxregrid,nyregrid,ntstate) :: fpri, fpos, epri, epos, xpos, focn_reg
+    real, dimension(nxregrid,nyregrid,ntstate) :: fpri, fpos, epri, epos, xpos, focn_reg, mcpri, mcpos
     real                                       :: area, totpos
 
     ! regrid fluxes and errors
@@ -528,6 +529,24 @@ module mod_save
               epos(ix,jy,n) = states%pxerr((n-1)*nbox+nbox_xy(ix,jy))/numscale
               xpos(ix,jy,n) = states%px((n-1)*nbox+nbox_xy(ix,jy))/numscale
             endif
+            if ( config%run_mode.eq.2 ) then
+              ! monte carlo ensemble run for posterior uncertainty
+              ! save posterior and perturbed prior state vectors with no redistribution
+              if ( config%lognormal ) then
+                ! lognormal distribution
+                if ( config%nested ) then
+                  mcpri(ix,jy,n) = exp(states%px0((n-1)*nbox+nbox_xy(ix,jy))) * fluxes%flx_nest(ix,jy,n)/numscale
+                  mcpos(ix,jy,n) = exp(states%px((n-1)*nbox+nbox_xy(ix,jy))) * fluxes%flx_nest(ix,jy,n)/numscale
+                else
+                  mcpri(ix,jy,n) = exp(states%px0((n-1)*nbox+nbox_xy(ix,jy))) * fluxes%flx(ix0+ix-1,jy0+jy-1,n)/numscale
+                  mcpos(ix,jy,n) = exp(states%px((n-1)*nbox+nbox_xy(ix,jy))) * fluxes%flx(ix0+ix-1,jy0+jy-1,n)/numscale
+                endif
+              else
+                ! normal distribution
+                mcpri(ix,jy,n) = states%px0((n-1)*nbox+nbox_xy(ix,jy))/numscale + fpri(ix,jy,n)
+                mcpos(ix,jy,n) = states%px((n-1)*nbox+nbox_xy(ix,jy))/numscale + fpri(ix,jy,n)
+              endif
+            endif
           else
             ! include ocean fluxes if not optimized
             if ( config%nested ) then
@@ -596,6 +615,12 @@ module mod_save
     call check( nf90_put_att(ncid, epos_varid, units, flxunit) )
     call check( nf90_def_var(ncid, xpos_name, nf90_real, dimids, xpos_varid) )
     call check( nf90_put_att(ncid, xpos_varid, units, flxunit) )
+    if ( config%run_mode.eq.2 ) then
+      call check( nf90_def_var(ncid, 'mcpri', nf90_real, dimids, mcpri_varid) )
+      call check( nf90_put_att(ncid, mcpri_varid, units, flxunit) )
+      call check( nf90_def_var(ncid, 'mcpos', nf90_real, dimids, mcpos_varid) )
+      call check( nf90_put_att(ncid, mcpos_varid, units, flxunit) )
+    endif
 
     call check( nf90_enddef(ncid) )
 
@@ -608,6 +633,10 @@ module mod_save
     call check( nf90_put_var(ncid, pos_varid, fpos) )
     call check( nf90_put_var(ncid, epos_varid, epos) )
     call check( nf90_put_var(ncid, xpos_varid, xpos) )
+    if ( config%run_mode.eq.2 ) then
+      call check( nf90_put_var(ncid, mcpri_varid, mcpri) )
+      call check( nf90_put_var(ncid, mcpos_varid, mcpos) )
+    endif
 
     call check( nf90_close(ncid) )
 
diff --git a/source/mod_settings.f90 b/source/mod_settings.f90
index 4b54e1c..2320915 100644
--- a/source/mod_settings.f90
+++ b/source/mod_settings.f90
@@ -117,7 +117,7 @@ module mod_settings
     integer                     :: datei           ! start date (yyyymmdd)
     integer                     :: datef           ! end date (yyyymmdd)
     logical                     :: average_fp      ! average footprints to match observation (true or false)
-    character(len=3)            :: spec            ! species ('co2', 'bca' or 'ghg')
+    character(len=3)            :: spec            ! species ('co2' or 'ghg' or 'aero')
     character(len=max_name_len) :: method          ! inversion method ('analytic' or 'congrad' or 'm1qn3')
     logical                     :: lognormal       ! use log-normal distribution in state space
     real                        :: trunc           ! truncation factor for eigenvalues of B
@@ -130,8 +130,11 @@ module mod_settings
     integer                     :: restart         ! restart a run that crashed (0=false, 1=true)
     real                        :: molarmass       ! molar mass of species (corresponds to flux files, e.g. C=12, CH4=16)
     real                        :: coeff           ! conversion coefficient from ppt to ppm or ppbv
+    real                        :: saterrfactor    ! factor by which to scale satellite observation error
+    real                        :: satlowlim       ! exclude satellite observations below this value
     logical                     :: satellite       ! use satellite observations (true or false)
     logical                     :: ground          ! use ground-based observations (true or false)
+    logical                     :: selectobs       ! select ground-based observations for day/night
     real                        :: coeffsat        ! conversion coefficient for satellite data to ppm or ppbv
     logical                     :: nested          ! use nested flexpart output (true or false)
     real                        :: w_edge_lon      ! lon of western edge of inversion grid 
@@ -642,6 +645,7 @@ module mod_settings
       config%lognormal = .false.
       config%satellite = .false.
       config%ground = .false.
+      config%selectobs = .false.
       config%trunc = 1.e-3
 
      ! open file
@@ -741,9 +745,18 @@ module mod_settings
           identifier = "satellite:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) config%satellite = cl
+          identifier = "saterrfactor:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) config%saterrfactor = real(cn,kind=4)
+          identifier = "satlowlim:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) config%satlowlim = real(cn,kind=4)
           identifier = "ground:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) config%ground = cl
+          identifier = "selectobs:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) config%selectobs = cl
           identifier = "coeffsat:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) config%coeffsat = real(cn,kind=4)
diff --git a/source/read_obs.f90 b/source/read_obs.f90
index d987322..7110f02 100755
--- a/source/read_obs.f90
+++ b/source/read_obs.f90
@@ -52,13 +52,15 @@ subroutine read_obs(config, files)
   integer                                                :: ncid, varid, dimid
   integer, dimension(:), allocatable                     :: idate, itime
   real, dimension(:), allocatable                        :: cpri, cakpri, cdryair, vmr, vmr_err
-!  real, dimension(:,:), allocatable                      :: cak
   real                                                   :: xcpri, xcakpri, scl_cpri, scl_cakpri, scl_cdryair !, cak_av 
   logical                                                :: lexist
 
   ! list observation files
   ! ----------------------
 
+  print*, 'readobs: files%path_output = ',trim(files%path_output)
+  print*, 'readobs: files%path_satobs = ',trim(files%path_satobs)
+
   if ( config%ground.and.config%satellite ) then
     call system('ls '//trim(files%path_obs)//'*'//trim(files%suffix)//&
                 ' '//trim(files%path_satobs)//'*.nc'//' | wc -l > '//trim(files%path_output)//'obsfiles.txt')
@@ -94,7 +96,6 @@ subroutine read_obs(config, files)
     write(logid,*) 'ERROR: cannot open obsread.txt'
     stop
   endif
-!  write(200,*) 'rec yyyymmdd hhmmss juldate avetime conc error cpri cakpri cdryair cakav'
   write(200,*) 'rec yyyymmdd hhmmss juldate avetime conc error cpri cakpri cdryair'
 
   cnt = 0
@@ -102,7 +103,9 @@ subroutine read_obs(config, files)
 
     ! check if ground-based or satellite observation
     string = filelist(nf)
+    print*, 'readobs: string = ',string
     call split(string,".",before,sep)
+    print*, 'readobs: before, string = ',before, string
 
     if ( string.eq.'nc' ) then
 
@@ -111,7 +114,6 @@ subroutine read_obs(config, files)
 
       ! check if data is in inversion time interval
       read(before(19:26),*) yyyymmdd
-      print*, 'readobs: string before = ',before(19:26)
       jdate = juldate(yyyymmdd, 0)
       if ( jdate.lt.juldatei.or.jdate.gt.juldatef ) cycle
 
@@ -142,52 +144,34 @@ subroutine read_obs(config, files)
       call check( nf90_get_var(ncid,varid,vmr_err) )
       call check( nf90_close(ncid) )
 
-      ! read ncdf file of releases (for AK info)
-      ! this is not needed 
-!      write(adate,'(I8)') yyyymmdd
-!      print*, trim(filelist(nf))
-!      filerelease=str_replace(trim(filelist(nf)),'retrieval','releases')
-!      inquire(file=trim(files%path_satrel)//adate//'/options/'//trim(filerelease),exist=lexist)
-!      if (.not.lexist) then
-!        write(logid,*) 'ERROR: file not found ',trim(files%path_satrel)//adate//'/options/'//trim(filerelease)
-!        stop
-!      endif
-!      call check( nf90_open(trim(files%path_satrel)//adate//'/options/'//trim(filerelease),nf90_NOWRITE,ncid) )
-!      call check( nf90_inq_dimid(ncid,'retrieval',dimid) )
-!      call check( nf90_inquire_dimension(ncid,dimid,len=nrelease) )
-!      call check( nf90_inq_dimid(ncid,'nlayer',dimid) )
-!      call check( nf90_inquire_dimension(ncid,dimid,len=nlayer) )
-!      if (nrelease.ne.nretr) then
-!        write(logid,*) 'ERROR: number of releases does not much number of retrievals'
-!        stop
-!      endif
-!      allocate( cak(nretr,nlayer), stat=ierr )
-!      call check( nf90_inq_varid(ncid,'cak',varid) )
-!      call check( nf90_get_var(ncid,varid,cak) )
-!      call check( nf90_close(ncid) )      
-
       ! loop over retrievals
       avetime = 0d0
       write(numfmt,fmt='(A,I1,A,I1,A)') '(I',recname_len,'.',recname_len,')'
-!      write(rowfmt,fmt='(A,I1,A)') '(A',recname_len,',1X,I8,1X,I6,1X,F14.6,1X,F10.6,1X,F10.4,1X,F10.4,1X,F10.5,1X,F10.5,1X,F10.2,1X,F6.4)'
       write(rowfmt,fmt='(A,I1,A)') '(A',recname_len,',1X,I8,1X,I6,1X,F14.6,1X,F10.6,1X,F10.4,1X,F10.4,1X,F10.5,1X,F10.5,1X,F10.2)'
       do nr = 1, nretr
-        cnt = cnt + 1
         write(recs,fmt=numfmt) nr
+        ! exclude vmr values that are anomolously low
+        if ((vmr(nr).lt.config%satlowlim).and.(config%satlowlim.gt.0)) then
+          write(logid,*) 'WARNING: excluding low satellite value for = ',yyyymmdd, nr 
+          cycle
+        endif
+        cnt = cnt + 1
         ! convert from input unit (e.g. mol/m2) to mole fraction 
         xcpri = cpri(nr)*config%coeffsat/cdryair(nr)
         xcakpri = cakpri(nr)*config%coeffsat/cdryair(nr)
-!        cak_av = sum(cak(nr,:))/real(nlayer)
         print*, 'read_obs: xcpri, xcakpri = ',xcpri, xcakpri
         print*, 'read_obs: cpri, cdryair = ',cpri(nr), cdryair(nr)
         print*, 'read_obs: coeffsat = ',config%coeffsat
         ! julian time
         jdate = juldate(idate(nr), itime(nr))
+        ! scale retrieval error by factor 
+        if (config%saterrfactor.gt.0) then
+          vmr_err(nr) = vmr_err(nr)*config%saterrfactor
+        endif
         write(200,fmt=rowfmt) recs, idate(nr), itime(nr), jdate, avetime, vmr(nr), vmr_err(nr), &
                               xcpri, xcakpri, cdryair(nr) !, cak_av
       end do
 
-!      deallocate( idate, itime, cpri, cakpri, cdryair, vmr, vmr_err, cak )
       deallocate( idate, itime, cpri, cakpri, cdryair, vmr, vmr_err )
 
     else 
@@ -249,30 +233,30 @@ subroutine read_obs(config, files)
         if ( ierr.ne.0 ) exit read_loop
         if ( jdate.ge.(juldatef+1d0) ) exit read_loop
         if ( jdate.lt.juldatei ) cycle read_loop
-        ! select day/night for low/high alt sites
-        hh = hhmiss/10000
-        hl = hh + int(lon*24./360.)
-        if ( hl.lt.0 ) then
-          hl = hl + 24
-        else if ( hl.ge.24 ) then
-          hl = hl - 24
-        endif
-        if ( alt.le.1000. ) then
-!         if ( (hl.lt.11).or.(hl.gt.15) ) cycle read_loop
-        else
-!         if ( (hl.gt.3).and.(hl.lt.23) ) cycle read_loop
+        if ( config%selectobs ) then
+          ! select day/night for low/high alt sites
+          hh = hhmiss/10000
+          hl = hh + int(lon*24./360.)
+          if ( hl.lt.0 ) then
+            hl = hl + 24
+          else if ( hl.ge.24 ) then
+            hl = hl - 24
+          endif
+          if ( alt.le.1000. ) then
+            if ( (hl.lt.11).or.(hl.gt.15) ) cycle read_loop
+          else
+            if ( (hl.gt.3).and.(hl.lt.23) ) cycle read_loop
+          endif
         endif
         if ( conc.le.-999. ) cycle read_loop
         measerr = max(config%measerr, err)
         scl_cpri = 0.
         scl_cakpri = 0.
         scl_cdryair = 0.
-!        cak_av = 1.
         cnt = cnt + 1
         ! write to output file
-!        write(rowfmt,'(A,I1,A)') '(A',recname_len,',1X,I8,1X,I6,1X,F14.6,1X,F10.6,1X,F10.4,1X,F10.4,F10.5,1X,F10.5,1X,F10.2,1X,F6.4)'
         write(rowfmt,'(A,I1,A)') '(A',recname_len,',1X,I8,1X,I6,1X,F14.6,1X,F10.6,1X,F10.4,1X,F10.4,F10.5,1X,F10.5,1X,F10.2)'
-        write(200,fmt=rowfmt) recs, yyyymmdd, hhmiss, jdate, avetime, conc, measerr, scl_cpri, scl_cakpri, scl_cdryair !, cak_av
+        write(200,fmt=rowfmt) recs, yyyymmdd, hhmiss, jdate, avetime, conc, measerr, scl_cpri, scl_cakpri, scl_cdryair 
       end do read_loop
 
       ! close input file
diff --git a/source/sbatch_flexinvert.sh b/source/sbatch_flexinvert.sh
index b82c3b9..ce2779f 100755
--- a/source/sbatch_flexinvert.sh
+++ b/source/sbatch_flexinvert.sh
@@ -2,8 +2,8 @@
 #---------------------------------------------------
 partition=nilu
 jobname=ghg
-settings_files='/mypath/settings/SETTINGS_ghg_files'
-settings_config='/mypath/settings/SETTINGS_ghg_config'
+settings_files='../settings/SETTINGS_ghg_files'
+settings_config='../settings/SETTINGS_ghg_config'
 #---------------------------------------------------
 
 cat <<EOF > run_job.sh
diff --git a/source/simulate.f90 b/source/simulate.f90
index 999c532..23bebb8 100644
--- a/source/simulate.f90
+++ b/source/simulate.f90
@@ -173,7 +173,7 @@ subroutine simulate(iter, files, config, fluxes, obs, states, grad_o, cost_o)
         ftime(n) = juldate(int(dates(n)/1d6),int(dates(n)-floor(dates(n)/1d6)*1d6)) 
       end do
       factor(:,:,:) = 1. 
-      if ( config%spec.ne.'bca' ) then
+      if ( config%spec.ne.'aero' ) then
          filefactor = trim(path_flexrec)//'factor_drygrid'
          inquire ( file=trim(filefactor),exist=lexist )
          if ( lexist ) then
@@ -239,11 +239,11 @@ subroutine simulate(iter, files, config, fluxes, obs, states, grad_o, cost_o)
     end do
     ! convert s.m3/kg to s.m2/kg
     grid = grid/outheight(1)
-    ! convert from equivalent ppt to observation units (e.g. ppmv)
-    ! sec not do it for bca
-    if ( config%spec.eq.'bca' ) then
+    if ( config%spec.eq.'aero' ) then
+       ! convert to match concentration units 
        grid = grid*config%coeff
     else
+       ! convert from equivalent ppt to observation units (e.g. ppmv)
        grid = grid*config%coeff*mmair/config%molarmass
     endif
 
@@ -262,7 +262,7 @@ subroutine simulate(iter, files, config, fluxes, obs, states, grad_o, cost_o)
         if ( allocated(factor_nest) ) deallocate(factor_nest)
         allocate ( factor_nest(nnxgrid,nnygrid,nread) )
         factor(:,:,:) = 1.
-        if ( config%spec.ne.'bca' ) then
+        if ( config%spec.ne.'aero' ) then
            filefactor = trim(path_flexrec)//'factor_drygrid_nest'
            inquire ( file=trim(filefactor),exist=lexist )
            if ( lexist ) then
@@ -316,8 +316,7 @@ subroutine simulate(iter, files, config, fluxes, obs, states, grad_o, cost_o)
       ! convert s.m3/kg to s.m2/kg
       gridnest = gridnest/outheight(1)
       ! convert from equivalent ppt to observation units (e.g. ppmv) 
-      ! sec not do it for bca
-      if ( config%spec.eq.'bca' ) then
+      if ( config%spec.eq.'aero' ) then
         gridnest = gridnest*config%coeff
       else
         gridnest = gridnest*config%coeff*mmair/config%molarmass
@@ -592,11 +591,11 @@ subroutine simulate(iter, files, config, fluxes, obs, states, grad_o, cost_o)
       endif
     endif
 
-    ! if background missing then observation should have no influence! 
-!    if ( sum(obs%cini(i,:)).eq.0. ) then
-!      write(logid,*) 'WARNING: background zero for observation ',i
-!      obs%delta(i) = 0.
-!    endif
+    ! check if background missing (not for aerosols)
+    if ( config%spec.ne.'aero'.and.sum(obs%cini(i,:)).eq.0. ) then
+      write(logid,*) 'ERROR: background zero for observation ',i
+      stop
+    endif
 
     ! calculate gradient in observation space
     ! ---------------------------------------
-- 
GitLab