From 3c1c46fd1a4e2e5c000f23a9c203312d17546a03 Mon Sep 17 00:00:00 2001
From: ronesy <rlt@nilu.no>
Date: Fri, 20 Dec 2024 12:05:17 +0100
Subject: [PATCH] Fix to average.f90 to include new retrieval OCO-2 and
 S5P-BLND and inclusion of routines and SETTINGS for S5P-BLND

---
 prep_satellite/README_satellites.txt |  50 +++
 prep_satellite/SETTINGS_bremen       |   2 +
 prep_satellite/SETTINGS_tropomi      |   2 +
 prep_satellite/SETTINGS_tropomi_blnd | 159 ++++++++
 prep_satellite/average.f90           |  63 ++--
 prep_satellite/get_bremen.f90        |  62 ++--
 prep_satellite/get_oco2.f90          |  37 +-
 prep_satellite/get_tropomi.f90       | 109 ++++--
 prep_satellite/get_tropomi_blnd.f90  | 518 +++++++++++++++++++++++++++
 prep_satellite/main.f90              |   3 +
 prep_satellite/makefile              |   1 +
 prep_satellite/mod_save.f90          |  57 +--
 prep_satellite/mod_settings.f90      |  14 +
 13 files changed, 942 insertions(+), 135 deletions(-)
 create mode 100644 prep_satellite/README_satellites.txt
 create mode 100644 prep_satellite/SETTINGS_tropomi_blnd
 create mode 100644 prep_satellite/get_tropomi_blnd.f90

diff --git a/prep_satellite/README_satellites.txt b/prep_satellite/README_satellites.txt
new file mode 100644
index 0000000..5441efc
--- /dev/null
+++ b/prep_satellite/README_satellites.txt
@@ -0,0 +1,50 @@
+================================================================
+
+ FLEXPART/FLEXINVERT Satellites Pre-processor
+
+================================================================
+
+Description:
+  prep_satellite is a pre-processor for satellite retrievals
+  to be run before running FLEXPART/FLEXINVERT. It contains
+  SETTINGS files and get_[satellite_id].f90 routines to read satellite
+  retrieval data from the original format and extract the
+  required variables needed for FLEXPART/FLEXINVERT, perform
+  any averaging to super-observations, and write the data into
+  two output files for each day: 
+      i)  releases_[satellite_id]_YYYYMMDD.nc
+      ii) retrieval_[satellite_id]_YYYYMMDD.nc
+  The first file is needed for FLEXPART to calculate total 
+  column SRRs, the second file contains the column average
+  mixing ratios and is needed for FLEXINVERT
+
+Currently available retrievals:
+  1) XCH4 TROPOMI Official product provided by SRON
+     routine: get_tropomi.f90 
+     satellite id in SETTINGS: tropomi
+  2) XCH4 TROPOMI WFMD retrieval product provided by University
+     of Bremen
+     routine: get_bremen.f90
+     satellite id in SETTINGS: bremen
+  3) XCH4 TROPOMI-GOSAT blended product provided by Harvard
+     University
+     routine: get_tropomi_blnd.f90
+     satellite id in SETTINGS: s5p_blnd
+  4) XCO2 OCO-2 Official "Lite" product provided by NASA
+     routine: get_oco2.f90
+     satellite id in SETTINGS: oco2
+
+To add new retrievals:
+  i)   create a new get_[satellite_id].f90 file
+  ii)  edit main.f90 and average.f90 to include this
+       new retrieval type
+  iii) add get_[satellite_id].f90 to the makefile
+
+Usage:
+  i)   Edit the SETTINGS file
+  ii)  Edit sbatch_satellite.sh 
+       and run this to prepare the output files
+  iii) Edit run_flexpart.sh
+       and run this to run FLEXPART
+
+
diff --git a/prep_satellite/SETTINGS_bremen b/prep_satellite/SETTINGS_bremen
index 4788ef4..fe3121b 100644
--- a/prep_satellite/SETTINGS_bremen
+++ b/prep_satellite/SETTINGS_bremen
@@ -69,6 +69,8 @@ pdel_name:      pressure_levels
 dryair_name:    pressure_weight
 # land fraction
 landfrac_name:  land_fraction
+# albedo SWIR
+albedo_name:    apparent_albedo
 
 # COMMAND
 
diff --git a/prep_satellite/SETTINGS_tropomi b/prep_satellite/SETTINGS_tropomi
index d1142ff..6cb97e6 100644
--- a/prep_satellite/SETTINGS_tropomi
+++ b/prep_satellite/SETTINGS_tropomi
@@ -74,6 +74,8 @@ psurf_name:     PRODUCT/SUPPORT_DATA/INPUT_DATA/surface_pressure
 pdel_name:      PRODUCT/SUPPORT_DATA/INPUT_DATA/pressure_interval
 # surface classification
 surfclass_name: PRODUCT/SUPPORT_DATA/INPUT_DATA/surface_classification
+# albedo SWIR
+albedo_name:    PRODUCT/SUPPORT_DATA/DETAILED_RESULTS/surface_albedo_SWIR
 
 # COMMAND
 
diff --git a/prep_satellite/SETTINGS_tropomi_blnd b/prep_satellite/SETTINGS_tropomi_blnd
new file mode 100644
index 0000000..57171f6
--- /dev/null
+++ b/prep_satellite/SETTINGS_tropomi_blnd
@@ -0,0 +1,159 @@
+# ==================================================
+#
+# SATELLITE DATA SETTINGS
+#
+# comment lines start with '#'
+# each parameter line starts with 'parameter name:'
+#
+# ==================================================
+
+# PATHS AND FILES 
+
+# use scratch (0: no, 1: yes)
+lscratch:      1
+# satellite instrument/retrieval (one of: tropomi, bremen, s5p_blnd, oco2)
+satellite:     s5p_blnd
+# name to include in output files
+satname:       s5pblnd_ch4
+# flexpart source path 
+path_flexpart: /mypath/FLEXPART_v104/
+# path where to write options folders (folders are created daily)
+path_options:  /mypath/flexpart_input/
+# path where to write flexpart output 
+path_output:   /mypath/flexpart_output/
+# path to OH fields (if use OH chemistry)
+path_ohfield:  /mypath/OH_fields/
+# path to satellite data
+path_obs:      /mypath/satellite_data/
+# suffix satellite files
+suffix:        ESACCI
+# path where to write observation output
+path_obsout:   /mypath/satellite_obs_out/
+# AVAILABLE files
+file_avail:     /mypath/AVAILABLE
+file_availnest: /mypath/AVAILABLE
+# windfields to use (determines lon of domain for flexpart run) (oper, era5)
+windfield:      era5
+
+# SATELLITE VARIABLES
+
+# select only retrievals only land (no sunglint)
+landonly:       .true.
+# number measurements dimension 
+nmeas_name:     nobs
+# number of lat/lon coordinates for each pixel
+ncoord_name:    corner
+# number of retrieval levels
+nlevel_name:    layer
+# time variable 
+time_name:      time_utc 
+# quality flag
+qa_name:        qa_value
+# quality cutoff value (0 = bad, 1 = good, values < qa_cutoff discarded) 
+qa_cutoff:      0.99
+# mixing ratio (ppbv)
+vmr_name:       methane_mixing_ratio_blended
+# mixing ratio precision (ppbv)
+verr_name:      methane_mixing_ratio_precision
+# latitude bounds
+lat_name:       latitude_bounds
+# longitude bounds
+lon_name:       longitude_bounds 
+# column averaging kernel
+ak_name:        column_averaging_kernel
+# mixing ratio apriori (mol/m2)
+apri_name:      methane_profile_apriori
+# pressure intervals (Pa)
+pdel_name:      pressure_interval 
+# surface pressure (Pa)
+psurf_name:     surface_pressure
+# dry air subcolumns (mol/m2)
+dryair_name:    dry_air_subcolumns
+# surface classification
+surfclass_name: surface_classification
+# albedo SWIR
+albedo_name:    surface_albedo_SWIR
+
+# COMMAND
+
+# start date of simulation (yyyymmdd)
+datei:   20200826
+# end date of simulation (yyyymmdd)
+datef:   20200831
+# output rate (secs)
+outrate: 86400
+# time average of output (secs)
+outaverage: 86400
+# sampling rate of output (secs)
+outsample: 1200
+# (mass unit = 1, mixing ratio unit = 2)
+ind_source: 1
+#  (mass unit = 1, mixing ratio unit = 2)
+ind_receptor: 2
+# use nested output (0 = no, 1 = yes)
+lnested: 1
+# output sensitivity to initial conditions (for backward runs, 0 = none, 1 = mass unit, 2 = mass mixing ratio)
+linit_cond: 2
+
+# OUTGRID
+
+# NOTE: domain specified will determine where retrievals are selected
+
+# longitude of lower left corner of output grid
+# for global use -180 (adjusts automatically for windfield)
+outlonleft: -180.00
+# latitude of lower left corner of output grid
+outlatlower: -90.00
+# number of longitudinal grid cells in output grid
+numxgrid: 180
+# number of latitudinal grid cells in output grid
+numygrid: 90
+# longitudinal resolution in output grid
+dxout: 2.0
+# latitudinal resolution in outout grid
+dyout: 2.0
+# longitude of lower left corner of nested grid (used if nested_output = 1)
+outlonnest: -15.0
+# latitude of lower left corner of nested grid (used if nested_output = 1)
+outlatnest: 33.0
+# number of longitudinal grid cells in nested grid (used if nested_output = 1)
+numxnest: 100
+# number of latitudinal grid cells in nested grid (used if nested_output = 1)
+numynest: 80
+# longitudinal resolution in nested grid (used if nested_output = 1)
+dxoutnest: 0.5
+# latitudinal resolution in nested grid (used if nested_output = 1)
+dyoutnest: 0.5
+# comma-separated list of vertical levels in output grid (meters)
+zlevel: 250, 750, 1500, 2500, 3500, 4500, 5500, 6500, 7500, 8500, 9500, 11000, 13000, 15000, 17000, 19000, 21250, 23750, 26250, 28750, 32500, 37500, 45000, 60000
+
+# RELEASES
+
+# species (see: /options/SPECIES/spec_overview)
+species: CH4
+# ageclass (sec)
+ageclass: 864000 
+# number of particles (no longer used in flexpart!)
+npart:    2000
+# mass of particles (no longer used in flexpart!)
+mass:     1000
+
+# AVERAGING 
+
+# average retrievals etc. (true/false)
+avg_pixels: .true.
+# If averaging need to set following (else ignored):
+# use predefined grid from file (true/false)
+usegridfile: .false.
+# if usegridfile is true specify file:
+filegrid: 
+# min grid resolution (degrees)
+dmin:     0.25
+# number of resolution steps
+nsteps:   2
+# cutoff standard deviation 
+cutoff:   10.
+# min number of retrievals in grid box in order to keep it
+nmin:     1 
+
+
diff --git a/prep_satellite/average.f90 b/prep_satellite/average.f90
index 335590a..166b173 100644
--- a/prep_satellite/average.f90
+++ b/prep_satellite/average.f90
@@ -39,8 +39,9 @@
 !!
 !---------------------------------------------------------------------------------------
 
-subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out,&
-                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, nretr, ncoord, nlayer)
+subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out, &
+                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, albedo_out, nretr, &
+                   ncoord, nlayer, numbox)
 
   use mod_settings
   use mod_var
@@ -53,21 +54,22 @@ subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, v
   real, dimension(maxretr,ncoord),  intent(in out)    :: xpoints, ypoints
   real, dimension(maxretr,nlayer),  intent(in out)    :: zpoint1, zpoint2
   real, dimension(maxretr,nlayer),  intent(in out)    :: vapri_out, vdryair_out, cak_out
-  real, dimension(maxretr),         intent(in out)    :: vmr_out, verr_out
+  real, dimension(maxretr),         intent(in out)    :: vmr_out, verr_out, albedo_out
   real, dimension(maxretr),         intent(in out)    :: cdryair, cpri, cakpri
-  integer,                          intent(in out)    :: nretr
+  integer,                          intent(in)        :: nretr
   integer,                          intent(in)        :: ncoord, nlayer
+  integer,                          intent(out)       :: numbox
   
   character(max_name_len)                             :: line
   real                                                :: llx, lly, urx, ury, xav, yav
   real, dimension(settings%nsteps)                    :: stepres
   real                                                :: res, box_mean, box_sd, box_err, rwork, area
-  integer                                             :: nbox, nbox_new, num, numbox, numx, numy
+  integer                                             :: nbox, nbox_new, num, numx, numy
   integer                                             :: ix, jy, ixy, n, nn, nr, ns, nb, nl, ierr
   integer                                             :: jjjjmmdd, hhmiss
   integer, dimension(:), allocatable                  :: retr_nbox, iretr, iretr_keep, mark_box, idate_mean, itime_mean 
   real, dimension(:), allocatable                     :: llx_box, lly_box, res_box, warea
-  real, dimension(:), allocatable                     :: vmr_mean, vmr_sd, cpri_mean, cdryair_mean, cakpri_mean
+  real, dimension(:), allocatable                     :: vmr_mean, vmr_sd, cpri_mean, cdryair_mean, cakpri_mean, albedo_mean
   real, dimension(:,:), allocatable                   :: cak_mean, vdryair_mean, xpts_box, ypts_box, zpt1_box, zpt2_box
   integer, dimension(4)                               :: num_subbox
   real(kind=8)                                        :: jdmean
@@ -106,9 +108,7 @@ subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, v
   allocate( iretr(nretr) )
   allocate( iretr_keep(nretr) )
   res = stepres(settings%nsteps)
-!  numx = (urx - llx)/res
-  numx = (urx - llx)/res + 1 ! to cover whole domain
-!  numy = (ury - lly)/res
+  numx = (urx - llx)/res + 1 ! +1 to cover whole domain
   numy = (ury - lly)/res + 1 
   nbox = numx*numy
   if ( nbox.gt.maxbox ) then
@@ -197,7 +197,6 @@ subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, v
                 num_subbox(n) = num_subbox(n) + 1
               endif
             end do ! n
-!          endif ! nb
         end do ! nn
         print*, 'num_subbox = ',num_subbox(:)
         if ( all(num_subbox.gt.0) ) then 
@@ -319,6 +318,7 @@ subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, v
   allocate( cpri_mean(nbox) )
   allocate( cdryair_mean(nbox) )
   allocate( cakpri_mean(nbox) )
+  allocate( albedo_mean(nbox) )
   allocate( cak_mean(nbox,nlayer) )
   allocate( vdryair_mean(nbox,nlayer) )
   allocate( xpts_box(nbox,ncoord) )
@@ -402,9 +402,13 @@ subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, v
     ! mean column prior convolved with averaging kernel
     rwork = 0.
     do n = 1, num
-      if ( settings%satellite.eq.'tropomi' ) then
+      if ( settings%satellite.eq.'tropomi'.or. &
+           settings%satellite.eq.'s5p_blnd' ) then
+        ! retrieval products with AK and prior profile in mol/m2
         rwork = rwork + warea(n)*dot_product(cak_out(iretr(n),:),vapri_out(iretr(n),:))
-      else if (settings%satellite.eq.'bremen' ) then
+      else if (settings%satellite.eq.'bremen'.or. &
+               settings%satellite.eq.'oco2' ) then
+        ! retrieval products with AK and prior profile in mole fraction
         do nl = 1, nlayer
           rwork = rwork + warea(n)*vdryair_out(iretr(n),nl)*vapri_out(iretr(n),nl)*cak_out(iretr(n),nl)
         end do
@@ -419,6 +423,8 @@ subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, v
     cdryair_mean(numbox) = dot_product(warea(1:num),cdryair(iretr(1:num)))
     ! mean dry air concentration
     vdryair_mean(numbox,:) = matmul(warea(1:num),vdryair_out(iretr(1:num),:))
+    ! mean albedo
+    albedo_mean(numbox) = dot_product(warea(1:num),albedo_out(iretr(1:num)))
     ! box coordinates
     xpts_box(numbox,(/1,4/)) = llx_box(nb)
     xpts_box(numbox,(/2,3/)) = llx_box(nb) + res_box(nb)
@@ -436,27 +442,26 @@ subroutine average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, v
     idate_mean(numbox) = jjjjmmdd
     itime_mean(numbox) = hhmiss
   end do
-  print*, 'zpt1_box(1:10,:) = ',zpt1_box(1:10,:)
-  nretr = numbox
-  write(logid,*) 'Number of averaged retrievals = ',nretr
-  print*, 'nretr = ',nretr
-  vmr_out(1:nretr) = vmr_mean(1:nretr)
-  verr_out(1:nretr) = vmr_sd(1:nretr)
-  cdryair(1:nretr) = cdryair_mean(1:nretr)
-  vdryair_out(1:nretr,:) = vdryair_mean(1:nretr,:)
-  cak_out(1:nretr,:) = cak_mean(1:nretr,:)
-  cpri(1:nretr) = cpri_mean(1:nretr)
-  cakpri(1:nretr) = cakpri_mean(1:nretr)
-  xpoints(1:nretr,:) = xpts_box(1:nretr,:)
-  ypoints(1:nretr,:) = ypts_box(1:nretr,:)
-  zpoint1(1:nretr,:) = zpt1_box(1:nretr,:)
-  zpoint2(1:nretr,:) = zpt2_box(1:nretr,:)
-  idate(1:nretr) = idate_mean(1:nretr)
-  itime(1:nretr) = itime_mean(1:nretr)
+  write(logid,*) 'Number of averaged retrievals = ',numbox
+  vmr_out(1:numbox) = vmr_mean(1:numbox)
+  verr_out(1:numbox) = vmr_sd(1:numbox)
+  cdryair(1:numbox) = cdryair_mean(1:numbox)
+  albedo_out(1:numbox) = albedo_mean(1:numbox)
+  vdryair_out(1:numbox,:) = vdryair_mean(1:numbox,:)
+  cak_out(1:numbox,:) = cak_mean(1:numbox,:)
+  cpri(1:numbox) = cpri_mean(1:numbox)
+  cakpri(1:numbox) = cakpri_mean(1:numbox)
+  xpoints(1:numbox,:) = xpts_box(1:numbox,:)
+  ypoints(1:numbox,:) = ypts_box(1:numbox,:)
+  zpoint1(1:numbox,:) = zpt1_box(1:numbox,:)
+  zpoint2(1:numbox,:) = zpt2_box(1:numbox,:)
+  idate(1:numbox) = idate_mean(1:numbox)
+  itime(1:numbox) = itime_mean(1:numbox)
   deallocate( vmr_mean )
   deallocate( vmr_sd )
   deallocate( cdryair_mean )
   deallocate( vdryair_mean )
+  deallocate( albedo_mean )
   deallocate( cak_mean )
   deallocate( cpri_mean )
   deallocate( cakpri_mean )
diff --git a/prep_satellite/get_bremen.f90 b/prep_satellite/get_bremen.f90
index 5592546..4328353 100644
--- a/prep_satellite/get_bremen.f90
+++ b/prep_satellite/get_bremen.f90
@@ -53,7 +53,7 @@ subroutine get_bremen(settings)
   character(len=3)                                      :: aspec
   character(len=6), dimension(4)                        :: units
   integer                                               :: i, ierr, n, nf, nl, nm, np, nt, nbits, iswater 
-  integer                                               :: nfiles, nread, nretr, npx_in_scan
+  integer                                               :: nfiles, nread, nretr, npx_in_scan, numbox
   real(kind=8)                                          :: jdatei, jdatef, jd, days_since_ref, jdateref, jdmeas
   real                                                  :: sec_since_midnight
   integer                                               :: jjjjmmdd, hhmiss, hh, mi, ss
@@ -61,12 +61,12 @@ subroutine get_bremen(settings)
   integer, parameter                                    :: lsynctime = 600
   integer                                               :: ntime, nmeas, npixel, nlevel, ncoord, nlayer
   real, dimension(:,:), allocatable                     :: lat_bnds, lon_bnds
-  real, dimension(:), allocatable                       :: vmr, verr, time, landfrac, qa
+  real, dimension(:), allocatable                       :: vmr, verr, time, landfrac, qa, albedo
   real, dimension(:,:), allocatable                     :: pres, vapri, vdryair, cak
   real, dimension(:,:), allocatable                     :: xpoints, ypoints
   real, dimension(:,:), allocatable                     :: zpoint1, zpoint2
   real, dimension(:,:), allocatable                     :: cak_out, vapri_out, vdryair_out
-  real, dimension(:), allocatable                       :: vmr_out, verr_out
+  real, dimension(:), allocatable                       :: vmr_out, verr_out, albedo_out
   real, dimension(:), allocatable                       :: cpri, cakpri, cdryair
   integer, dimension(:), allocatable                    :: idate, itime 
   integer                                               :: specnum, nchar
@@ -159,8 +159,8 @@ subroutine get_bremen(settings)
       cycle read_loop     
     endif
 
-    ! loop over files
-    ! ---------------
+    ! loop over files for current day
+    ! -------------------------------
 
     do n = 1, nread
 
@@ -228,8 +228,13 @@ subroutine get_bremen(settings)
       call check( nf90_inq_varid(ncid,trim(settings%dryair_name),varid) )
       call check( nf90_get_var(ncid,varid,vdryair) )
       allocate( landfrac(nmeas), stat=ierr ) 
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate landfrac'
       call check( nf90_inq_varid(ncid,trim(settings%landfrac_name),varid) )
       call check( nf90_get_var(ncid,varid,landfrac) )
+      allocate( albedo(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate albedo'
+      call check( nf90_inq_varid(ncid,trim(settings%albedo_name),varid) )
+      call check( nf90_get_var(ncid,varid,albedo) )
 
       call check( nf90_close(ncid)) 
 
@@ -257,6 +262,8 @@ subroutine get_bremen(settings)
         if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vmr_out'
         allocate( verr_out(maxretr), stat=ierr )
         if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate verr_out'
+        allocate( albedo_out(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate albedo_out'
         nretr = 0
       endif
       do nm = 1, nmeas
@@ -306,6 +313,7 @@ subroutine get_bremen(settings)
         vmr_out(nretr) = vmr(nm)
         ! unlike official retrieval no factor of 2 necessary for error
         verr_out(nretr) = verr(nm)
+        albedo_out(nretr) = albedo(nm)
       end do
       print*, 'range(pres) = ',minval(pres),maxval(pres)
       print*, 'range(zpoint1) = ',minval(zpoint1),maxval(zpoint1)
@@ -323,22 +331,20 @@ subroutine get_bremen(settings)
       if ( allocated(vmr) )           deallocate(vmr)
       if ( allocated(verr) )          deallocate(verr)
       if ( allocated(landfrac) )      deallocate(landfrac)
+      if ( allocated(albedo) )        deallocate(albedo)
 
     end do  ! nread
 
     if ( nretr.eq.0 ) go to 10
 
     ! calculate column prior (units ppbv)
-    allocate( cpri(nretr), stat=ierr )
+    allocate( cpri(maxretr), stat=ierr )
     do nm = 1, nretr
       cpri(nm) = dot_product(vapri_out(nm,:), vdryair_out(nm,:))
     end do
 
-    !! test
-    print*, 'vdryair_out(1:10,:) = ',vdryair_out(1:10,:)
-
     ! calculate column prior convolved with averaging kernel (units ppbv)
-    allocate( cakpri(nretr), stat=ierr )
+    allocate( cakpri(maxretr), stat=ierr )
     do nm = 1, nretr
       do nl = 1, nlayer
         cakpri(nm) = cakpri(nm) + vdryair_out(nm,nl)*vapri_out(nm,nl)*cak_out(nm,nl)
@@ -346,38 +352,29 @@ subroutine get_bremen(settings)
     end do
  
     ! column dry-air not needed but only as dummy variable
-    allocate( cdryair(nretr) )
+    allocate( cdryair(maxretr) )
     cdryair(:) = 1.
 
     ! average pixels
     ! --------------
 
     if ( settings%avg_pixels ) then
-      call average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out,&
-                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, nretr, ncoord, nlayer)
+      ! nretr is number of individual observations
+      ! after averaging numbox is number of super observations
+      call average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out, &
+                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, albedo_out, nretr, &
+                   ncoord, nlayer, numbox)
+    else
+      ! no averaging
+      numbox = nretr
     endif 
 
-    !! testing
-!    open(500,file='bremen_cak.txt',action='write',status='replace')
-!    do nm = 1, nretr
-!      write(500,fmt='(20(F7.5,1X))') cak_out(nm,:)
-!    end do
-!    close(500)
-!    open(500,file='bremen_cpri.txt',action='write',status='replace')
-!    do nm = 1, nretr
-!      write(500,fmt='(20(F7.2,1X))') vapri_out(nm,:)
-!    end do
-!    close(500)
-!    stop
-    !! 
-
-
     ! write output data
     ! -----------------
 
     ! adjust itime 
     ! needed so that with flexpart rounding to lsynctime all retrievals are still for current day
-    do nm = 1, nretr
+    do nm = 1, numbox
       if ( itime(nm).gt.(235959-lsynctime*100/60) ) then
         itime(nm) = 235950-lsynctime*100/60
       endif
@@ -402,12 +399,12 @@ subroutine get_bremen(settings)
     units(4) = 'ppbv'
 
     ! write releases data for flexpart
-    call write_releases(settings,nretr,nlayer,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
+    call write_releases(settings,numbox,nlayer,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
                         idate,itime,cak_out,vdryair_out,specnum,units)
 
     ! write retrieval data for flexinvert
-    call write_retrieval(settings,nretr,ncoord,xpoints,ypoints,idate,itime,&
-                         cpri,cakpri,vmr_out,verr_out,cdryair,units)
+    call write_retrieval(settings,numbox,ncoord,xpoints,ypoints,idate,itime,&
+                         cpri,cakpri,vmr_out,verr_out,cdryair,albedo_out,units)
 
     ! copy standard input files to options folder
     write(aspec,fmt='(I3.3)') specnum
@@ -437,6 +434,7 @@ subroutine get_bremen(settings)
     if ( allocated(cpri) )        deallocate(cpri)
     if ( allocated(cakpri) )      deallocate(cakpri)
     if ( allocated(cdryair) )     deallocate(cdryair)
+    if ( allocated(albedo_out) )  deallocate(albedo_out)
 
     ! iterate over days
     jd = jd + 1d0
diff --git a/prep_satellite/get_oco2.f90 b/prep_satellite/get_oco2.f90
index 9f3c00c..8ea646a 100644
--- a/prep_satellite/get_oco2.f90
+++ b/prep_satellite/get_oco2.f90
@@ -56,7 +56,7 @@ subroutine get_oco2(settings)
   character(len=3)                                      :: aspec
   character(len=6), dimension(4)                        :: units
   integer                                               :: i, ierr, n, nf, nl, ln, nm, np, nt  
-  integer                                               :: nfiles, nread, nretr 
+  integer                                               :: nfiles, nread, nretr, numbox 
   real(kind=8)                                          :: jdatei, jdatef, jd, jdateref, jdmeas
   integer                                               :: jjjjmmdd, jjmmdd, hhmiss
   integer                                               :: hh, mi, ss
@@ -65,12 +65,12 @@ subroutine get_oco2(settings)
   integer                                               :: ntime, nmeas, nlevel, ncoord
   real(kind=8), dimension(:), allocatable               :: time
   real, dimension(:,:), allocatable                     :: lat_bnds, lon_bnds
-  real, dimension(:), allocatable                       :: vmr, verr, landfrac, qa
+  real, dimension(:), allocatable                       :: vmr, verr, landfrac, qa 
   real, dimension(:,:), allocatable                     :: pres, vapri, vdryair, cak
   real, dimension(:,:), allocatable                     :: xpoints, ypoints
   real, dimension(:,:), allocatable                     :: zpoint1, zpoint2
   real, dimension(:,:), allocatable                     :: cak_out, vapri_out, vdryair_out
-  real, dimension(:), allocatable                       :: vmr_out, verr_out
+  real, dimension(:), allocatable                       :: vmr_out, verr_out, albedo_out ! albedo is a dummy variable  
   real, dimension(:), allocatable                       :: cpri, cakpri, cdryair
   integer, dimension(:), allocatable                    :: idate, itime, oper_mode
   integer                                               :: specnum, nchar
@@ -284,6 +284,9 @@ subroutine get_oco2(settings)
         if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vmr_out'
         allocate( verr_out(maxretr), stat=ierr )
         if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate verr_out'
+        allocate( albedo_out(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate albedo_out'
+        albedo_out(:) = 0. ! dummy variable
         nretr = 0
 
         ! checking
@@ -358,16 +361,13 @@ subroutine get_oco2(settings)
     if ( nretr.eq.0 ) go to 10
 
     ! calculate column prior (units ppbv)
-    allocate( cpri(nretr), stat=ierr )
+    allocate( cpri(maxretr), stat=ierr )
     do nm = 1, nretr
       cpri(nm) = dot_product(vapri_out(nm,:), vdryair_out(nm,:))
     end do
 
-    !! test
-    print*, 'vdryair_out(1:10,:) = ',vdryair_out(1:10,:)
-
     ! calculate column prior convolved with averaging kernel (units ppbv)
-    allocate( cakpri(nretr), stat=ierr )
+    allocate( cakpri(maxretr), stat=ierr )
     do nm = 1, nretr
       do nl = 1, nlevel
         cakpri(nm) = cakpri(nm) + vdryair_out(nm,nl)*vapri_out(nm,nl)*cak_out(nm,nl)
@@ -375,15 +375,21 @@ subroutine get_oco2(settings)
     end do
  
     ! column dry-air not needed but only as dummy variable
-    allocate( cdryair(nretr) )
+    allocate( cdryair(maxretr) )
     cdryair(:) = 1.
 
     ! average pixels
     ! --------------
 
     if ( settings%avg_pixels ) then
-      call average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out,&
-                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, nretr, ncoord, nlevel)
+      ! nretr is number of individual observations
+      ! after averaging numbox is number of super observations
+      call average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out, &
+                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, albedo_out, nretr, &
+                   ncoord, nlevel, numbox)
+    else
+      ! no averaging
+      numbox = nretr  
     endif 
 
     ! write output data
@@ -391,7 +397,7 @@ subroutine get_oco2(settings)
 
     ! adjust itime 
     ! needed so that with flexpart rounding to lsynctime all retrievals are still for current day
-    do nm = 1, nretr
+    do nm = 1, numbox
       if ( itime(nm).gt.(235959-lsynctime*100/60) ) then
         itime(nm) = 235950-lsynctime*100/60
       endif
@@ -416,12 +422,12 @@ subroutine get_oco2(settings)
     units(4) = 'ppmv'
 
     ! write releases data for flexpart
-    call write_releases(settings,nretr,nlevel,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
+    call write_releases(settings,numbox,nlevel,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
                         idate,itime,cak_out,vdryair_out,specnum,units)
 
     ! write retrieval data for flexinvert
-    call write_retrieval(settings,nretr,ncoord,xpoints,ypoints,idate,itime,&
-                         cpri,cakpri,vmr_out,verr_out,cdryair,units)
+    call write_retrieval(settings,numbox,ncoord,xpoints,ypoints,idate,itime,&
+                         cpri,cakpri,vmr_out,verr_out,cdryair,albedo_out,units)
 
     ! copy standard input files to options folder
     write(aspec,fmt='(I3.3)') specnum
@@ -451,6 +457,7 @@ subroutine get_oco2(settings)
     if ( allocated(cpri) )        deallocate(cpri)
     if ( allocated(cakpri) )      deallocate(cakpri)
     if ( allocated(cdryair) )     deallocate(cdryair)
+    if ( allocated(albedo_out) )  deallocate(albedo_out)
 
     ! iterate over days
     jd = jd + 1d0
diff --git a/prep_satellite/get_tropomi.f90 b/prep_satellite/get_tropomi.f90
index 850d7c6..d20aefa 100644
--- a/prep_satellite/get_tropomi.f90
+++ b/prep_satellite/get_tropomi.f90
@@ -56,7 +56,7 @@ subroutine get_tropomi(settings)
   character(len=2)                                      :: amon, aday
   character(len=6), dimension(4)                        :: units
   integer                                               :: i, ierr, n, nf, nl, nm, np, nt, nbits, iswater 
-  integer                                               :: nfiles, nread, nretr 
+  integer                                               :: nfiles, nread, nretr, numbox 
   real(kind=8)                                          :: jdatei, jdatef, jd, ndays, jref, jdmeas
   integer                                               :: jjjjmmdd, hhmiss, mm, dd, hh, mi, ss
   integer, parameter                                    :: refdate = 20100101
@@ -64,13 +64,13 @@ subroutine get_tropomi(settings)
   integer, parameter                                    :: lsynctime = 600
   integer                                               :: ntime, nmeas, npixel, nlevel, ncoord, nlayer
   real, dimension(:,:,:,:), allocatable                 :: lat_bnds, lon_bnds
-  real, dimension(:,:,:), allocatable                   :: psurf, pdel, vmr, verr, qa
+  real, dimension(:,:,:), allocatable                   :: psurf, pdel, vmr, verr, qa, albedo
   real, dimension(:,:,:,:), allocatable                 :: vapri, vdryair, cak
   real, dimension(:,:), allocatable                     :: xpoints, ypoints
   real, dimension(:,:), allocatable                     :: zpoint1, zpoint2
   real, dimension(:,:), allocatable                     :: cak_out, vapri_out, vdryair_out
   real, dimension(:,:), allocatable                     :: cak_tmp, vapri_tmp, vdryair_tmp
-  real, dimension(:), allocatable                       :: vmr_out, verr_out
+  real, dimension(:), allocatable                       :: vmr_out, verr_out, albedo_out
   real, dimension(:), allocatable                       :: cpri, cakpri, cdryair
   integer, dimension(:), allocatable                    :: idate, itime, time
   integer, dimension(:,:), allocatable                  :: timedel
@@ -80,8 +80,10 @@ subroutine get_tropomi(settings)
   integer                                               :: dimid, varid 
   real                                                  :: nest_llx, nest_lly, nest_urx, nest_ury
   real                                                  :: llx, lly, urx, ury
-  real                                                  :: sclfact, offset
+  real                                                  :: sclfact, offset 
   real, parameter                                       :: bignum=huge(0.)
+  real                                                  :: const, alb, factor_corr
+  real, dimension(11)                                   :: poly
 
   write(logid,*) 'largest number that can be handled (used to define NA) = ',bignum
 
@@ -162,6 +164,12 @@ subroutine get_tropomi(settings)
     write(aday,fmt='(I2.2)') dd
     nread = 0
     do n = 1, nfiles
+      ! corrupted files have "xxx" at start of name
+      i=len_trim(settings%path_obs)
+      if ( filelist(n)((i+1):(i+3)).eq.'xxx' ) then 
+        print*, 'skipping file: ',filelist(n)
+        cycle
+      endif
       do i = 1, len_trim(filelist(n))-18
         if ( filelist(n)(i:(i+7)).eq.adate ) then
           nread = nread + 1
@@ -176,8 +184,8 @@ subroutine get_tropomi(settings)
       cycle read_loop
     endif
 
-    ! loop over files
-    ! ---------------
+    ! loop over files for current day
+    ! --------------------------------
 
     do n = 1, nread
 
@@ -302,6 +310,16 @@ subroutine get_tropomi(settings)
       call check( nf90_inq_varid(det_grpid,trim(string),varid) )
       call check( nf90_get_var(det_grpid,varid,cak) )
       write(logid,*) 'read column averaging kernel'
+      allocate( albedo(npixel,nmeas,ntime), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate albedo'
+      string = settings%albedo_name
+      call split(string,'/',grpname)
+      call split(string,'/',suppdata_grpname)
+      call split(string,'/',details_grpname)
+      call check( nf90_inq_ncid(supp_grpid,trim(details_grpname),det_grpid) )
+      call check( nf90_inq_varid(det_grpid,trim(string),varid) )
+      call check( nf90_get_var(det_grpid,varid,albedo) )
+      write(logid,*) 'read surface albedo SWIR'
 
       ! product variables
       allocate( qa(npixel,nmeas,ntime), stat=ierr )
@@ -373,10 +391,13 @@ subroutine get_tropomi(settings)
         if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vmr_out'
         allocate( verr_out(maxretr), stat=ierr )
         if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate verr_out'
+        allocate( albedo_out(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate albedo_out'
         cak_out(:,:)=0.
         vapri_out(:,:)=0.
         vmr_out(:)=0.
         verr_out(:)=0.
+        albedo_out(:)=0.
         nretr = 0
       endif
       do nt = 1, ntime
@@ -431,6 +452,7 @@ subroutine get_tropomi(settings)
               zpoint2(nretr,nl) = zpoint2(nretr,nl-1) - pdel(np,nm,nt)
             end do
             cak_out(nretr,:) = cak(:,np,nm,nt)
+            albedo_out(nretr) = albedo(np,nm,nt)
             vapri_out(nretr,:) = vapri(:,np,nm,nt)
             vdryair_out(nretr,:) = vdryair(:,np,nm,nt)
             vmr_out(nretr) = vmr(np,nm,nt)
@@ -450,6 +472,7 @@ subroutine get_tropomi(settings)
       if ( allocated(vapri) )         deallocate(vapri)
       if ( allocated(vdryair) )       deallocate(vdryair)
       if ( allocated(cak) )           deallocate(cak)
+      if ( allocated(albedo) )        deallocate(albedo)
       if ( allocated(timedel) )       deallocate(timedel)
       if ( allocated(time) )          deallocate(time)
       if ( allocated(qa) )            deallocate(qa)
@@ -479,49 +502,70 @@ subroutine get_tropomi(settings)
     vdryair_out = vdryair_tmp
     deallocate( cak_tmp, vapri_tmp, vdryair_tmp)
 
-    print*, 'itime(1), itime(nretr) = ',itime(1),itime(nretr)
-
     ! calculate column prior (units mol/m2)
-    allocate( cpri(nretr), stat=ierr )
-    cpri = sum(vapri_out(1:nretr,:), dim=2)
+    allocate( cpri(maxretr), stat=ierr )
+    cpri(1:nretr) = sum(vapri_out(1:nretr,:), dim=2)
 
     ! calculate column prior convolved with averaging kernel (units mol/m2) 
-    allocate( cakpri(nretr), stat=ierr )
+    allocate( cakpri(maxretr), stat=ierr )
     do nm = 1, nretr
       cakpri(nm) = dot_product(vapri_out(nm,:), cak_out(nm,:))
     end do
 
+    ! apply albedo correction used in Official retrievals to cak, cpri and cakpri 
+    ! this is polynomial function order of 11 (Soumyajit Mandal, SRON)
+!    const =  1.0282413517102085
+!    poly(1) = -0.4717177565799524
+!    poly(2) = 2.1491179428159324
+!    poly(3) = 16.952582059603163
+!    poly(4) = -250.66075995913351
+!    poly(5) = 1307.5191440027886
+!    poly(6) =-3791.6452849323673
+!    poly(7) =6783.218182991253
+!    poly(8) =-7689.387517819326
+!    poly(9) = 5404.118866385074
+!    poly(10) =-2154.928509865762
+!    poly(11) =373.4579485937264
+!    if ( settings%albedo_corr ) then
+!      open(100,file=trim(settings%path_obsout)//'aldbedo_corr_'//adate//'.txt', &
+!            status='replace',action='write')
+!      do nm = 1, nretr
+!        alb = albedo_out(nm)
+!        factor_corr = const + poly(1)*alb + poly(2)*alb**2 + poly(3)*alb**3 + poly(4)*alb**4 + &
+!                       poly(5)*alb**5 + poly(6)*alb**6 + poly(7)*alb**7 + poly(8)*alb**8 + &
+!                       poly(9)*alb**9 + poly(10)*alb**10 + poly(11)*alb**11
+!        cakpri(nm) = factor_corr*cakpri(nm)
+!        cpri(nm) = factor_corr*cpri(nm)
+!        cak_out(nm,:) = factor_corr*cak_out(nm,:)
+!        write(100,'(F6.4,1X,F6.4)') factor_corr, alb
+!      end do
+!      close(100)
+!    endif
+    
     ! calculate column dry air (units mol/m2)
-    allocate( cdryair(nretr), stat=ierr )
-    cdryair = sum(vdryair_out(1:nretr,:), dim=2)
+    allocate( cdryair(maxretr), stat=ierr )
+    cdryair(1:nretr) = sum(vdryair_out(1:nretr,:), dim=2)
 
     ! average pixels
     ! --------------
 
     if ( settings%avg_pixels ) then
-      call average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out,&
-                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, nretr, ncoord, nlayer)
+      ! nretr is number of individual observations
+      ! after averaging numbox is number of super observations
+      call average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out, &
+                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, albedo_out, nretr, &
+                   ncoord, nlayer, numbox)
+    else
+      ! no averaging
+      numbox = nretr
     endif
 
-    !! testing
-!    open(500,file='tropomi_cak.txt',action='write',status='replace')
-!    do nm = 1, nretr
-!      write(500,fmt='(12(F7.5,1X))') cak_out(nm,:)
-!    end do
-!    close(500)
-!    open(500,file='tropomi_cpri.txt',action='write',status='replace')
-!    do nm = 1, nretr
-!      write(500,fmt='(12(F7.2,1X))') vapri_out(nm,:)*1.e9/vdryair_out(nm,:)
-!    end do
-!    close(500)
-!    !!  
-
     ! write output data
     ! -----------------
 
     ! adjust itime 
     ! needed so that with flexpart rounding to lsynctime all retrievals are still for current day
-    do nm = 1, nretr
+    do nm = 1, numbox
       if ( itime(nm).gt.(235959-lsynctime*100/60) ) then
         itime(nm) = 235950-lsynctime*100/60
       endif
@@ -546,12 +590,12 @@ subroutine get_tropomi(settings)
     units(4) = 'ppbv'
 
     ! write releases data for flexpart
-    call write_releases(settings,nretr,nlayer,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
+    call write_releases(settings,numbox,nlayer,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
                         idate,itime,cak_out,vdryair_out,specnum,units)
 
     ! write retrieval data for flexinvert
-    call write_retrieval(settings,nretr,ncoord,xpoints,ypoints,idate,itime,&
-                         cpri,cakpri,vmr_out,verr_out,cdryair,units)
+    call write_retrieval(settings,numbox,ncoord,xpoints,ypoints,idate,itime,&
+                         cpri,cakpri,vmr_out,verr_out,cdryair,albedo_out,units)
 
     ! copy standard input files to options folder
     write(aspec,fmt='(I3.3)') specnum
@@ -574,6 +618,7 @@ subroutine get_tropomi(settings)
     if ( allocated(vapri_out) )   deallocate(vapri_out)
     if ( allocated(vdryair_out) ) deallocate(vdryair_out)
     if ( allocated(vmr_out) )     deallocate(vmr_out)
+    if ( allocated(albedo_out) )  deallocate(albedo_out)
     if ( allocated(verr_out) )    deallocate(verr_out)
     if ( allocated(cpri) )        deallocate(cpri)
     if ( allocated(cakpri) )      deallocate(cakpri)
diff --git a/prep_satellite/get_tropomi_blnd.f90 b/prep_satellite/get_tropomi_blnd.f90
new file mode 100644
index 0000000..d935e02
--- /dev/null
+++ b/prep_satellite/get_tropomi_blnd.f90
@@ -0,0 +1,518 @@
+!---------------------------------------------------------------------------------------
+! PREP_SATELLITE: get_tropomi_blnd
+!---------------------------------------------------------------------------------------
+!  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 2022, Rona Thompson
+!---------------------------------------------------------------------------------------
+!
+!> get_tropomi_blnd
+!!
+!! Purpose:    Reads observations and auxilliary data from the specified satellite and
+!!             and writes the output into files that can be directly used by FLEXPART
+!!             and, for inversions, by FLEXINVERT
+!!
+!! Interface:
+!!
+!!    Inputs
+!!             settings  -  settings data structure
+!!
+!!    Outputs
+!!
+!!    Externals
+!!
+!---------------------------------------------------------------------------------------
+
+subroutine get_tropomi_blnd(settings)
+
+  use mod_settings
+  use mod_var
+  use mod_dates
+  use mod_save
+  use netcdf
+
+  implicit none
+
+  type (settings_t), intent(in)                         :: settings
+
+  character(max_name_len), dimension(:), allocatable    :: filelist, filereadlist
+  character(max_name_len)                               :: line, filename
+  character(len=27), dimension(:), allocatable          :: timestr
+  character(len=8)                                      :: adate
+  character(len=6)                                      :: atime
+  character(len=3)                                      :: aspec
+  character(len=6), dimension(4)                        :: units
+  integer                                               :: i, ierr, n, nf, nl, nm, np, nt, nbits, iswater 
+  integer                                               :: nfiles, nread, nretr, npx_in_scan, numbox
+  real(kind=8)                                          :: jdatei, jdatef, jd, days_since_ref, jdateref, jdmeas
+  real                                                  :: sec_since_midnight
+  integer                                               :: jjjjmmdd, hhmiss, jjjj, mm, dd, hh, mi, ss
+  integer, parameter                                    :: refdate = 19700101
+  integer, parameter                                    :: lsynctime = 600
+  integer                                               :: ntime, nmeas, ncoord, nlayer
+  real, dimension(:,:), allocatable                     :: lat_bnds, lon_bnds
+  real, dimension(:), allocatable                       :: vmr, verr, time, qa, albedo
+  real, dimension(:,:), allocatable                     :: vapri, vdryair, cak
+  real, dimension(:), allocatable                       :: psurf, pdel
+  real, dimension(:,:), allocatable                     :: xpoints, ypoints
+  real, dimension(:,:), allocatable                     :: zpoint1, zpoint2
+  real, dimension(:,:), allocatable                     :: cak_out, vapri_out, vdryair_out
+  real, dimension(:,:), allocatable                     :: cak_tmp, vapri_tmp, vdryair_tmp
+  real, dimension(:), allocatable                       :: vmr_out, verr_out, albedo_out
+  real, dimension(:), allocatable                       :: cpri, cakpri, cdryair
+  integer, dimension(:), allocatable                    :: idate, itime, surfclass
+  character(len=8)                                      :: surfclass_bin, qa_bin 
+  integer                                               :: specnum, nchar
+  integer                                               :: ncid, dimid, varid
+  real                                                  :: nest_llx, nest_lly, nest_urx, nest_ury
+  real                                                  :: llx, lly, urx, ury
+  integer                                               :: nargs, cnt
+  character(max_name_len), dimension(2)                 :: args
+  character(len=28)                                     :: str
+  real                                                  :: sclfact, offset
+  character(len=2)                                      :: anread
+
+  ! get species number
+  ! ------------------
+
+  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),*) specnum
+  write(logid,*) 'species: ',settings%species
+  write(logid,*) 'specnum: ',specnum
+  write(logid,*) 'qa cutoff: ',settings%qa_cutoff
+  close(100)
+
+  ! define domains
+  ! --------------------
+
+  llx = settings%outlonleft
+  lly = settings%outlatlower
+  urx = llx + settings%numxgrid*settings%dxout
+  ury = lly + settings%numygrid*settings%dyout
+
+  if ( settings%lnested.eq.1 ) then
+    nest_llx = settings%outlonnest
+    nest_lly = settings%outlatnest
+    nest_urx = nest_llx + settings%numxnest*settings%dxoutnest
+    nest_ury = nest_lly + settings%numynest*settings%dyoutnest
+  endif
+  print*, 'llx,lly,urx,ury = ',llx,lly,urx,ury
+  if (settings%lnested.eq.1) print*, 'nest_llx,nest_lly,nest_urx,nest_ury = ',nest_llx,nest_lly,nest_urx,nest_ury
+
+  ! list satellite files
+  ! ----------------------
+
+  call system('find '//trim(settings%path_obs)//' -type f | grep '//trim(settings%suffix)//&
+              ' | wc -l > '//trim(settings%path_obsout)//'obsfiles.txt')
+  call system('find '//trim(settings%path_obs)//' -type f | grep '//trim(settings%suffix)//&
+              ' >> '//trim(settings%path_obsout)//'obsfiles.txt')
+
+  open(100,file=trim(settings%path_obsout)//'obsfiles.txt',action='read',status='old',iostat=ierr)
+  if ( ierr.ne. 0 ) then
+    write(logid,*) 'ERROR: cannot open obsfiles.txt'
+    stop
+  endif
+  read(100,*,iostat=ierr) nfiles
+  allocate ( filelist(nfiles), stat = ierr )
+  allocate ( filereadlist(nfiles), stat = ierr )
+  do nf = 1, nfiles
+    read(100,fmt='(A)',iostat=ierr) filelist(nf)
+    if (ierr.ne.0) exit
+  end do
+  close(100)
+
+  ! loop over days 
+  ! --------------
+
+  jdatei = juldate(settings%datei, 0)
+  jdatef = juldate(settings%datef, 0)
+  jd = jdatei
+
+  read_loop: do
+
+    if ( jd.gt.jdatef ) exit read_loop
+
+    ! search files for current date
+    call caldate(jd, jjjjmmdd, hhmiss)
+    write(adate,fmt='(I8.8)') jjjjmmdd
+    write(logid,*) 'current day: ',adate
+    nread = 0
+    do n = 1, nfiles
+      do i = 1, len_trim(filelist(n))-18
+        if ( filelist(n)(i:(i+7)).eq.adate ) then
+          nread = nread + 1
+          filereadlist(nread) = filelist(n)
+          exit
+        endif
+      end do
+    end do
+    write(logid,*) 'number of files for current day: ',nread
+    if ( nread.eq.0 ) then 
+      jd = jd + 1d0
+      cycle read_loop     
+    endif
+
+    ! loop over files for current day
+    ! -------------------------------
+
+    do n = 1, nread
+
+      ! open file
+      write(logid,*) 'reading file: ',filereadlist(n)
+      call check( nf90_open(trim(filereadlist(n)),nf90_NOWRITE,ncid) )
+
+      ! dimension variables
+      call check( nf90_inq_dimid(ncid,trim(settings%nmeas_name),dimid) )
+      call check( nf90_inquire_dimension(ncid,dimid,len=nmeas) )
+      write(logid,*) 'number of retrievals: ',nmeas
+      if ( nmeas.eq.0 ) then
+        write(logid,*) 'file contains no retrievals moving to next file'
+        cycle
+      endif
+      call check( nf90_inq_dimid(ncid,trim(settings%ncoord_name),dimid) )
+      call check( nf90_inquire_dimension(ncid,dimid,len=ncoord) )
+      write(logid,*) 'number of geocoordinates: ',ncoord
+      call check( nf90_inq_dimid(ncid,trim(settings%nlevel_name),dimid) )
+      call check( nf90_inquire_dimension(ncid,dimid,len=nlayer) )
+      write(logid,*) 'number of vertical layers: ',nlayer
+
+      ! geolocation variables
+      allocate( lat_bnds(ncoord,nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate lat_bnds'
+      call check( nf90_inq_varid(ncid,trim(settings%lat_name),varid) )
+      call check( nf90_get_var(ncid,varid,lat_bnds) )
+      allocate( lon_bnds(ncoord,nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate lon_bnds'
+      call check( nf90_inq_varid(ncid,trim(settings%lon_name),varid) )
+      call check( nf90_get_var(ncid,varid,lon_bnds) )
+      
+      ! product variables
+      allocate( timestr(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate timestr'
+      ! cannot read variable type string in fortran
+!      call check( nf90_inq_varid(ncid,trim(settings%time_name),varid) )
+!      call check( nf90_get_var(ncid,varid,timestr) )
+      ! work around -> extract time variable to ascii
+      call system("ncdump -v "//trim(settings%time_name)//" "//trim(filereadlist(n))//&
+                  " | sed -e '1,/data:/d' -e '$d' | tail -n +2 > "//trim(settings%path_obsout)//"time.txt")
+      open(100,file=trim(settings%path_obsout)//"time.txt",action='read',status='old',iostat=ierr)
+      if (ierr.ne.0) then
+        write(logid,*) 'ERROR: cannot open time.txt'
+        stop
+      endif
+      cnt=0
+      do while (ierr.eq.0)
+        read (100, fmt='(A)', iostat=ierr) line
+        if (ierr.ne.0) exit
+        ! remove pesky characters in first line
+        if (cnt==0) then
+          line = line(12:len(line))
+        endif
+        call parse_string(line, ',', args, nargs)
+        do i = 1, nargs
+          cnt=cnt+1
+          str=trim(args(i))  
+          timestr(cnt)=str(2:28)
+        end do
+      end do
+      close(100)
+      call system("rm -f "//trim(settings%path_obsout)//"time.txt")
+      allocate( psurf(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate psurf'
+      call check( nf90_inq_varid(ncid,trim(settings%psurf_name),varid) )
+      call check( nf90_get_var(ncid,varid,psurf) )
+      allocate( pdel(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate pdel'
+      call check( nf90_inq_varid(ncid,trim(settings%pdel_name),varid) )
+      call check( nf90_get_var(ncid,varid,pdel) )
+      allocate( qa(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate qa'
+      call check( nf90_inq_varid(ncid,trim(settings%qa_name),varid) )
+      call check( nf90_get_var(ncid,varid,qa) )
+      call check( nf90_get_att(ncid,varid,'scale_factor',sclfact) )
+      call check( nf90_get_att(ncid,varid,'add_offset',offset) )
+      qa = qa*sclfact + offset
+      print*, 'qa = ',qa(1:20)
+      allocate( vmr(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vmr'
+      call check( nf90_inq_varid(ncid,trim(settings%vmr_name),varid) )
+      call check( nf90_get_var(ncid,varid,vmr) )
+      allocate( verr(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate verr'
+      call check( nf90_inq_varid(ncid,trim(settings%verr_name),varid) )
+      call check( nf90_get_var(ncid,varid,verr) )
+
+      ! detailed results variables
+      allocate( cak(nlayer,nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate cak'
+      call check( nf90_inq_varid(ncid,trim(settings%ak_name),varid) )
+      call check( nf90_get_var(ncid,varid,cak) )
+      allocate( vapri(nlayer,nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vapri'
+      call check( nf90_inq_varid(ncid,trim(settings%apri_name),varid) )
+      call check( nf90_get_var(ncid,varid,vapri) )
+      allocate( vdryair(nlayer,nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vdryair'
+      call check( nf90_inq_varid(ncid,trim(settings%dryair_name),varid) )
+      call check( nf90_get_var(ncid,varid,vdryair) )
+      allocate( surfclass(nmeas), stat=ierr ) 
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate surfclass'
+      call check( nf90_inq_varid(ncid,trim(settings%surfclass_name),varid) )
+      call check( nf90_get_var(ncid,varid,surfclass) )
+      allocate( albedo(nmeas), stat=ierr )
+      if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate albedo'
+      call check( nf90_inq_varid(ncid,trim(settings%albedo_name),varid) )
+      call check( nf90_get_var(ncid,varid,albedo) )
+
+      call check( nf90_close(ncid)) 
+
+      ! select retrievals and extract needed info
+      if( n.eq.1 ) then
+        allocate( xpoints(maxretr,ncoord), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate xpoints'
+        allocate( ypoints(maxretr,ncoord), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate ypoints'
+        allocate( zpoint1(maxretr,nlayer), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate zpoint1'
+        allocate( zpoint2(maxretr,nlayer), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate zpoint2'
+        allocate( idate(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate idate'
+        allocate( itime(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate itime'
+        allocate( cak_out(maxretr,nlayer), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate cak_out'
+        allocate( vapri_out(maxretr,nlayer), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vapri_out'
+        allocate( vdryair_out(maxretr,nlayer), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vdryair_out'
+        allocate( vmr_out(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vmr_out'
+        allocate( verr_out(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate verr_out'
+        allocate( albedo_out(maxretr), stat=ierr )
+        if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate albedo_out'
+        nretr = 0
+      endif
+      print*, 'nmeas = ',nmeas
+      do nm = 1, nmeas
+        ! exclude retrievals above quality cutoff
+        if ( qa(nm).lt.settings%qa_cutoff ) cycle
+        write(surfclass_bin, fmt='(B0)') surfclass(nm)
+        nbits = len_trim(surfclass_bin)
+        read(surfclass_bin(nbits:nbits),*) iswater
+        if(nm.lt.10) print*, 'surfclass_bin, nbits, iswater = ',surfclass_bin, nbits, iswater
+        ! if landonly exclude pixels over water
+        if ( settings%landonly.and.iswater.eq.1 ) cycle
+        if ( settings%lnested.eq.1 ) then
+          ! if nested domain exclude pixels outside
+          if ( any(lon_bnds(:,nm).lt.nest_llx).or. &
+               any(lon_bnds(:,nm).gt.nest_urx).or. &
+               any(lat_bnds(:,nm).lt.nest_lly).or. &
+               any(lat_bnds(:,nm).gt.nest_ury) ) cycle
+        else
+          ! if not nested exclude pixels outside global domain
+          if ( any(lon_bnds(:,nm).lt.llx).or. &
+               any(lon_bnds(:,nm).gt.urx).or. &
+               any(lat_bnds(:,nm).lt.lly).or. &
+               any(lat_bnds(:,nm).gt.ury) ) cycle
+        endif
+        read(timestr(nm)(1:4),'(I4)') jjjj
+        read(timestr(nm)(6:7),'(I2)') mm
+        read(timestr(nm)(9:10),'(I2)') dd
+        read(timestr(nm)(12:13),'(I2)') hh
+        read(timestr(nm)(15:16),'(I2)') mi
+        read(timestr(nm)(18:19),'(I2)') ss
+        hhmiss=hh*10000+mi*100+ss
+        jjjjmmdd=jjjj*10000+mm*100+dd
+        jdmeas=juldate(jjjjmmdd,hhmiss)
+        ! exclude retrievals if not for current day
+        if ( floor(jdmeas).ne.jd ) cycle
+        ! check date and time
+        if (isnan(real(hhmiss)).or.(jjjjmmdd.lt.0)) then
+          write(logid,*) 'WARNING: problem with itime, idate for file, nmeas, jdmeas = ',trim(filereadlist(n)), nm, jdmeas
+          cycle
+        endif
+        nretr = nretr + 1
+        if (nretr.lt.10) print*, 'jjjjmmdd, hhmiss = ',jjjjmmdd, hhmiss
+        idate(nretr) = jjjjmmdd
+        itime(nretr) = hhmiss
+        ! corners ordered anticlockwise from lower left
+        xpoints(nretr,:) = lon_bnds(:,nm)
+        ypoints(nretr,:) = lat_bnds(:,nm)
+        ! pressure levels are equipressure apart
+        zpoint1(nretr,1) = psurf(nm)
+        zpoint2(nretr,1) = psurf(nm) - pdel(nm)
+        do nl = 2, nlayer
+          zpoint1(nretr,nl) = zpoint1(nretr,nl-1) - pdel(nm)
+          zpoint2(nretr,nl) = zpoint2(nretr,nl-1) - pdel(nm)
+        end do
+        cak_out(nretr,:) = cak(:,nm)
+        vapri_out(nretr,:) = vapri(:,nm)
+        vdryair_out(nretr,:) = vdryair(:,nm)
+        vmr_out(nretr) = vmr(nm)
+        verr_out(nretr) = verr(nm)
+        albedo_out(nretr) = albedo(nm)
+      end do
+
+      write(logid,*) 'number of retrievals: ',nretr
+
+      if ( allocated(lat_bnds) )      deallocate(lat_bnds)
+      if ( allocated(lon_bnds) )      deallocate(lon_bnds)
+      if ( allocated(vapri) )         deallocate(vapri)
+      if ( allocated(vdryair) )       deallocate(vdryair)
+      if ( allocated(cak) )           deallocate(cak)
+      if ( allocated(timestr) )       deallocate(timestr)
+      if ( allocated(psurf) )         deallocate(psurf)
+      if ( allocated(pdel) )          deallocate(pdel)
+      if ( allocated(qa) )            deallocate(qa)
+      if ( allocated(vmr) )           deallocate(vmr)
+      if ( allocated(verr) )          deallocate(verr)
+      if ( allocated(surfclass) )     deallocate(surfclass)
+      if ( allocated(albedo) )        deallocate(albedo)
+
+    end do  ! nread
+
+    if ( nretr.eq.0 ) go to 10
+
+    ! reverse direction of vertical coordinate
+    ! raw data ordered from top of atmosphere to surface
+    ! which is opposite to the pressure levels calculated (zpoint)
+    allocate( cak_tmp(maxretr,nlayer), stat=ierr )
+    if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate cak_tmp'
+    allocate( vapri_tmp(maxretr,nlayer), stat=ierr )
+    if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vapri_tmp'
+    allocate( vdryair_tmp(maxretr,nlayer), stat=ierr )
+    if ( ierr.ne.0 ) write(logid,*) 'ERROR: cannot allocate vdryair_tmp'
+    do nl = 1, nlayer
+      cak_tmp(:,nl) = cak_out(:,(nlayer-nl+1))
+      vapri_tmp(:,nl) = vapri_out(:,(nlayer-nl+1))
+      vdryair_tmp(:,nl) = vdryair_out(:,(nlayer-nl+1))
+    end do
+    cak_out = cak_tmp
+    vapri_out = vapri_tmp
+    vdryair_out = vdryair_tmp
+    deallocate( cak_tmp, vapri_tmp, vdryair_tmp)
+
+    ! calculate column prior (units mol/m2)
+    allocate( cpri(maxretr), stat=ierr )
+    cpri(1:nretr) = sum(vapri_out(1:nretr,:), dim=2)
+
+    ! calculate column prior convolved with averaging kernel (units mol/m2) 
+    allocate( cakpri(maxretr), stat=ierr )
+    do nm = 1, nretr
+      cakpri(nm) = dot_product(vapri_out(nm,:), cak_out(nm,:))
+    end do
+
+    ! calculate column dry air (units mol/m2)
+    allocate( cdryair(maxretr), stat=ierr )
+    cdryair(1:nretr) = sum(vdryair_out(1:nretr,:), dim=2)
+
+    ! average pixels
+    ! --------------
+
+    if ( settings%avg_pixels ) then
+      ! nretr is number of individual observations
+      ! after averaging numbox is number of super observations
+      call average(settings, idate, itime, xpoints, ypoints, zpoint1, zpoint2, vmr_out, verr_out, &
+                   vapri_out, cpri, cakpri, cak_out, cdryair, vdryair_out, albedo_out, nretr, &
+                   ncoord, nlayer, numbox)
+    else
+      ! no averaging
+      numbox = nretr
+    endif 
+
+    ! write output data
+    ! -----------------
+
+    ! adjust itime 
+    ! needed so that with flexpart rounding to lsynctime all retrievals are still for current day
+    do nm = 1, numbox
+      if ( itime(nm).gt.(235959-lsynctime*100/60) ) then
+        itime(nm) = 235950-lsynctime*100/60
+      endif
+    end do
+
+    ! write command file
+    call prep_command(settings,jd)
+
+    ! write outgrid file
+    call prep_outgrid(settings,jd)
+
+    ! write ageclasses file
+    call prep_ageclass(settings,jd)
+
+    ! write pathnames file
+    call prep_pathnames(settings,jd)
+
+    ! units of output data: dryair, cdryair, cpri, vmr
+    units(1) = 'mol/m2'
+    units(2) = 'mol/m2'
+    units(3) = 'mol/m2'
+    units(4) = 'ppbv'
+
+    ! write releases data for flexpart
+    call write_releases(settings,numbox,nlayer,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
+                        idate,itime,cak_out,vdryair_out,specnum,units)
+
+    ! write retrieval data for flexinvert
+    call write_retrieval(settings,numbox,ncoord,xpoints,ypoints,idate,itime,&
+                         cpri,cakpri,vmr_out,verr_out,cdryair,albedo_out,units)
+
+    ! copy standard input files to options folder
+    write(aspec,fmt='(I3.3)') specnum
+    call system('mkdir -p '//trim(settings%path_options)//adate//'/options/SPECIES/')
+    filename = trim(settings%path_flexpart)//'options/SPECIES/SPECIES_'//aspec
+    call system('cp '//trim(filename)//' '//trim(settings%path_options)//adate//'/options/SPECIES/')
+    call system('cp '//trim(settings%path_flexpart)//'options/*.dat'//' '//trim(settings%path_options)//adate//'/options/')
+    call system('cp '//trim(settings%path_flexpart)//'options/*.t'//' '//trim(settings%path_options)//adate//'/options/')
+
+    ! no retrievals on this day
+10 continue
+
+    ! prepare for next day
+    ! -------------------- 
+
+    if ( allocated(xpoints) )     deallocate(xpoints)
+    if ( allocated(ypoints) )     deallocate(ypoints)
+    if ( allocated(zpoint1) )     deallocate(zpoint1)
+    if ( allocated(zpoint2) )     deallocate(zpoint2)
+    if ( allocated(idate) )       deallocate(idate)
+    if ( allocated(itime) )       deallocate(itime)
+    if ( allocated(cak_out) )     deallocate(cak_out)
+    if ( allocated(vapri_out) )   deallocate(vapri_out)
+    if ( allocated(vdryair_out) ) deallocate(vdryair_out)
+    if ( allocated(vmr_out) )     deallocate(vmr_out)
+    if ( allocated(verr_out) )    deallocate(verr_out)
+    if ( allocated(cpri) )        deallocate(cpri)
+    if ( allocated(cakpri) )      deallocate(cakpri)
+    if ( allocated(cdryair) )     deallocate(cdryair)
+    if ( allocated(albedo_out) )  deallocate(albedo_out)
+
+    ! iterate over days
+    jd = jd + 1d0
+
+  end do read_loop
+
+  if ( allocated(filelist) )     deallocate(filelist)
+  if ( allocated(filereadlist) ) deallocate(filereadlist)
+
+
+end subroutine get_tropomi_blnd
+
diff --git a/prep_satellite/main.f90 b/prep_satellite/main.f90
index 60685ff..72c1c63 100644
--- a/prep_satellite/main.f90
+++ b/prep_satellite/main.f90
@@ -73,6 +73,9 @@ program main
   else if ( settings%satellite.eq.'bremen' ) then
     ! bremen retrieval for tropomi
     call get_bremen(settings)
+  else if ( settings%satellite.eq.'s5p_blnd' ) then
+    ! tropomi-gosat blended product
+    call get_tropomi_blnd(settings)
   else if ( settings%satellite.eq.'oco2' ) then
     call get_oco2(settings)
   else
diff --git a/prep_satellite/makefile b/prep_satellite/makefile
index e54f331..7e2d44e 100644
--- a/prep_satellite/makefile
+++ b/prep_satellite/makefile
@@ -28,6 +28,7 @@ OBJECTS = gridarea.o \
 	get_tropomi.o \
 	get_bremen.o \
 	get_oco2.o \
+	get_tropomi_blnd.o \
 	main.o
 
 %.o: %.mod
diff --git a/prep_satellite/mod_save.f90 b/prep_satellite/mod_save.f90
index f3cfaf5..6e9e2ac 100644
--- a/prep_satellite/mod_save.f90
+++ b/prep_satellite/mod_save.f90
@@ -67,11 +67,11 @@ module mod_save
   !
   ! --------------------------------------------------
 
-  subroutine write_releases(settings,nretr,nlayer,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
+  subroutine write_releases(settings,numbox,nlayer,ncoord,xpoints,ypoints,zpoint1,zpoint2,&
                              idate,itime,cak_out,vdryair_out,specnum,units)
 
     type (settings_t),               intent(in) :: settings
-    integer,                         intent(in) :: nretr, nlayer, ncoord
+    integer,                         intent(in) :: numbox, nlayer, ncoord
     real, dimension(maxretr,ncoord), intent(in) :: xpoints, ypoints
     real, dimension(maxretr,nlayer), intent(in) :: zpoint1, zpoint2
     integer, dimension(maxretr),     intent(in) :: idate, itime
@@ -95,7 +95,7 @@ module mod_save
     call check( nf90_create(trim(pathout)//trim(filename), nf90_clobber, ncid) )
 
     ! define dimensions and variables
-    call check( nf90_def_dim(ncid, 'retrieval', nretr, nrid) )
+    call check( nf90_def_dim(ncid, 'retrieval', numbox, nrid) )
     call check( nf90_def_dim(ncid, 'nlayer', nlayer, nlid) )
     call check( nf90_def_dim(ncid, 'ncoord', ncoord, ncoid) )
     call check( nf90_def_var(ncid, 'xpoints', nf90_real, (/nrid, ncoid/), xptid) )
@@ -122,14 +122,14 @@ module mod_save
     call check( nf90_enddef(ncid) )
 
     ! insert variables
-    call check( nf90_put_var(ncid, xptid, xpoints(1:nretr,:)) )
-    call check( nf90_put_var(ncid, yptid, ypoints(1:nretr,:)) )
-    call check( nf90_put_var(ncid, zpt1id, zpoint1(1:nretr,:)) )
-    call check( nf90_put_var(ncid, zpt2id, zpoint2(1:nretr,:)) )
-    call check( nf90_put_var(ncid, dateid, idate(1:nretr)) )
-    call check( nf90_put_var(ncid, timeid, itime(1:nretr)) )
-    call check( nf90_put_var(ncid, cakid, cak_out(1:nretr,:)) )
-    call check( nf90_put_var(ncid, dairid, vdryair_out(1:nretr,:)) )
+    call check( nf90_put_var(ncid, xptid, xpoints(1:numbox,:)) )
+    call check( nf90_put_var(ncid, yptid, ypoints(1:numbox,:)) )
+    call check( nf90_put_var(ncid, zpt1id, zpoint1(1:numbox,:)) )
+    call check( nf90_put_var(ncid, zpt2id, zpoint2(1:numbox,:)) )
+    call check( nf90_put_var(ncid, dateid, idate(1:numbox)) )
+    call check( nf90_put_var(ncid, timeid, itime(1:numbox)) )
+    call check( nf90_put_var(ncid, cakid, cak_out(1:numbox,:)) )
+    call check( nf90_put_var(ncid, dairid, vdryair_out(1:numbox,:)) )
   
     ! close file
     call check( nf90_close(ncid) )
@@ -154,22 +154,22 @@ module mod_save
   !
   ! --------------------------------------------------
 
-  subroutine write_retrieval(settings,nretr,ncoord,xpoints,ypoints,idate,itime,&
-                             cpri,cakpri,vmr_out,verr_out,cdryair,units)
+  subroutine write_retrieval(settings,numbox,ncoord,xpoints,ypoints,idate,itime,&
+                             cpri,cakpri,vmr_out,verr_out,cdryair,albedo_out,units)
 
     type (settings_t),               intent(in) :: settings 
-    integer,                         intent(in) :: nretr, ncoord
+    integer,                         intent(in) :: numbox, ncoord
     real, dimension(maxretr,ncoord), intent(in) :: xpoints, ypoints
     integer, dimension(maxretr),     intent(in) :: idate, itime
-    real, dimension(maxretr),        intent(in) :: vmr_out, verr_out
-    real, dimension(nretr),          intent(in) :: cpri, cakpri, cdryair
+    real, dimension(maxretr),        intent(in) :: vmr_out, verr_out, albedo_out
+    real, dimension(maxretr),        intent(in) :: cpri, cakpri, cdryair
     character(len=6), dimension(4),  intent(in) :: units
 
     character(max_name_len)                     :: filename
     character(len=8)                            :: adate
     integer                                     :: ncid, nrid, nlid, ncoid
     integer                                     :: xptid, yptid, dateid, timeid
-    integer                                     :: cprid, cakprid, vmrid, verrid, cdairid    
+    integer                                     :: cprid, cakprid, vmrid, verrid, albid, cdairid    
 
     write(adate,fmt='(I8.8)') idate(1)
     filename = 'retrieval_'//trim(settings%satname)//'_'//adate//'.nc'
@@ -179,7 +179,7 @@ module mod_save
     call check( nf90_create(trim(settings%path_obsout)//trim(filename), nf90_clobber, ncid) )
 
     ! define dimensions and variables
-    call check( nf90_def_dim(ncid, 'retrieval', nretr, nrid) )
+    call check( nf90_def_dim(ncid, 'retrieval', numbox, nrid) )
     call check( nf90_def_dim(ncid, 'ncoord', ncoord, ncoid) )
     call check( nf90_def_var(ncid, 'xpoints', nf90_real, (/nrid, ncoid/), xptid) )
     call check( nf90_put_att(ncid, xptid, 'units', 'degrees_east') )
@@ -197,6 +197,8 @@ module mod_save
     call check( nf90_put_att(ncid, vmrid, 'units', trim(units(4))) )
     call check( nf90_def_var(ncid, 'vmr_err', nf90_real, nrid, verrid) )
     call check( nf90_put_att(ncid, verrid, 'units', trim(units(4))) )
+    call check( nf90_def_var(ncid, 'albedo_swir', nf90_real, nrid, albid) )
+    call check( nf90_put_att(ncid, albid, 'units', 'none') )
     call check( nf90_def_var(ncid, 'cdryair', nf90_real, nrid, cdairid) )
     call check( nf90_put_att(ncid, cdairid, 'units', trim(units(2))) )
 
@@ -204,15 +206,16 @@ module mod_save
     call check( nf90_enddef(ncid) )
 
     ! insert variables
-    call check( nf90_put_var(ncid, xptid, xpoints(1:nretr,:)) )
-    call check( nf90_put_var(ncid, yptid, ypoints(1:nretr,:)) )
-    call check( nf90_put_var(ncid, dateid, idate(1:nretr)) )
-    call check( nf90_put_var(ncid, timeid, itime(1:nretr)) )
-    call check( nf90_put_var(ncid, cprid, cpri) )
-    call check( nf90_put_var(ncid, cakprid, cakpri) )
-    call check( nf90_put_var(ncid, vmrid, vmr_out(1:nretr)) )
-    call check( nf90_put_var(ncid, verrid, verr_out(1:nretr)) )
-    call check( nf90_put_var(ncid, cdairid, cdryair) )
+    call check( nf90_put_var(ncid, xptid, xpoints(1:numbox,:)) )
+    call check( nf90_put_var(ncid, yptid, ypoints(1:numbox,:)) )
+    call check( nf90_put_var(ncid, dateid, idate(1:numbox)) )
+    call check( nf90_put_var(ncid, timeid, itime(1:numbox)) )
+    call check( nf90_put_var(ncid, cprid, cpri(1:numbox)) )
+    call check( nf90_put_var(ncid, cakprid, cakpri(1:numbox)) )
+    call check( nf90_put_var(ncid, vmrid, vmr_out(1:numbox)) )
+    call check( nf90_put_var(ncid, verrid, verr_out(1:numbox)) )
+    call check( nf90_put_var(ncid, albid, albedo_out(1:numbox)) )
+    call check( nf90_put_var(ncid, cdairid, cdryair(1:numbox)) )
   
     ! close file
     call check( nf90_close(ncid) )
diff --git a/prep_satellite/mod_settings.f90 b/prep_satellite/mod_settings.f90
index e03234e..96ed844 100644
--- a/prep_satellite/mod_settings.f90
+++ b/prep_satellite/mod_settings.f90
@@ -36,6 +36,7 @@ module mod_settings
 
   type :: settings_t
 
+    integer                         :: lscratch
     character(len=max_name_len)     :: satellite
     character(len=max_name_len)     :: satname
     character(len=max_path_len)     :: path_flexpart
@@ -49,6 +50,7 @@ module mod_settings
     character(len=max_path_len)     :: file_availnest
     character(len=max_name_len)     :: windfield
 
+    logical                         :: albedo_corr
     logical                         :: landonly
     integer                         :: opmode_sel
     character(len=max_name_len)     :: nmeas_name
@@ -71,6 +73,7 @@ module mod_settings
     character(len=max_name_len)     :: pdel_name
     character(len=max_name_len)     :: surfclass_name
     character(len=max_name_len)     :: landfrac_name
+    character(len=max_name_len)     :: albedo_name
 
     integer                         :: datei
     integer                         :: datef
@@ -310,7 +313,9 @@ module mod_settings
      settings%avg_pixels = .false.
      settings%usegridfile = .false.
      settings%landonly = .false.
+     settings%albedo_corr = .false.
      settings%opmode_sel = -1
+     settings%lscratch = 1  ! use scratch drive
 
      ! open file
       open (100, file = trim (filename), status = 'old', iostat=ierr)
@@ -336,6 +341,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 = "satellite:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%satellite = cc
@@ -374,6 +382,9 @@ module mod_settings
           if ( match ) settings%windfield = cc
 
           ! satellite variables
+          identifier = "albedo_corr:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) settings%albedo_corr = cl
           identifier = "landonly:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%landonly = cl
@@ -440,6 +451,9 @@ module mod_settings
           identifier = "landfrac_name:"
           call read_content (line, identifier, cc, cn, cl, match)
           if ( match ) settings%landfrac_name = cc
+          identifier = "albedo_name:"
+          call read_content (line, identifier, cc, cn, cl, match)
+          if ( match ) settings%albedo_name = cc
 
           ! COMMAND settings
           identifier = "datei:"
-- 
GitLab