diff --git a/dartwrf/exp_config.py b/dartwrf/exp_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..c7fa14ecd284602a8205baa083f7147d2a28af02
--- /dev/null
+++ b/dartwrf/exp_config.py
@@ -0,0 +1,117 @@
+from dartwrf import utils
+
+exp = utils.Experiment()
+exp.expname = "exp_v1.22_P2_rr_VIS_obs20_loc10_oe3"
+exp.model_dx = 2000
+exp.n_ens = 40
+exp.superob_km = False  # False or int (spatial averaging of observations)
+
+exp.use_existing_obsseq = False  # False or pathname (use precomputed obs_seq.out files)
+#exp.use_existing_obsseq = '/users/students/lehre/advDA_s2023/dartwrf_tutorial/very_cold_observation.out'
+
+# path to the nature run, where we take observations from
+exp.nature_wrfout = '/jetfs/scratch/lkugler/data/sim_archive/exp_v1.18_P1_nature/2008-07-30_06:00/1/wrfout_d01_%Y-%m-%d_%H:%M:%S'
+
+exp.input_profile = '/mnt/jetfs/home/lkugler/data/initial_profiles/wrf/ens/2022-03-31/raso.fc.<iens>.wrfprof'
+
+
+exp.dart_nml = {'&assim_tools_nml':
+                    dict(filter_kind='1',
+                        sampling_error_correction='.false.',
+                        # obs_impact_filename='/jetfs/home/lkugler/DART-WRF/templates/impactfactor_T.txt',
+                        ),
+                '&filter_nml':
+                    dict(ens_size=exp.n_ens,
+                            num_output_state_members=exp.n_ens,
+                            num_output_obs_members=exp.n_ens,
+                            inf_flavor=['0', '0'],
+                            output_members='.true.',
+                            output_mean='.true.',
+                            output_sd='.true.',
+                            stages_to_write='output',
+                        ),
+                '&location_nml':
+                    dict(horiz_dist_only='.true.',
+                        ),
+                '&model_nml':
+                    dict(wrf_state_variables = 
+                        [['U',     'QTY_U_WIND_COMPONENT',     'TYPE_U',    'UPDATE','999',],
+                         ['V',     'QTY_V_WIND_COMPONENT',     'TYPE_V',    'UPDATE','999',],
+                         ['W',     'QTY_VERTICAL_VELOCITY',    'TYPE_W',    'UPDATE','999',],
+                         ['PH',    'QTY_GEOPOTENTIAL_HEIGHT',  'TYPE_GZ',   'UPDATE','999',],
+                         ['THM',   'QTY_POTENTIAL_TEMPERATURE','TYPE_T',    'UPDATE','999',],
+                         ['MU',    'QTY_PRESSURE',             'TYPE_MU',   'UPDATE','999',],
+                         ['QVAPOR','QTY_VAPOR_MIXING_RATIO',   'TYPE_QV',   'UPDATE','999',],
+                         ['QICE',  'QTY_ICE_MIXING_RATIO',     'TYPE_QI',   'UPDATE','999',],
+                         ['QCLOUD','QTY_CLOUDWATER_MIXING_RATIO','TYPE_QC', 'UPDATE','999',],
+                         ['CLDFRA','QTY_CLOUD_FRACTION',       'TYPE_CFRAC','UPDATE','999',],
+                         ['PSFC',  'QTY_SURFACE_PRESSURE',     'TYPE_PSFC', 'UPDATE','999',],
+                         ['T2',    'QTY_2M_TEMPERATURE',       'TYPE_T',    'UPDATE','999',],
+                         ['TSK',   'QTY_SKIN_TEMPERATURE',     'TYPE_T',    'UPDATE','999',],
+                         ['REFL_10CM','QTY_RADAR_REFLECTIVITY','TYPE_REFL', 'UPDATE','999',]]),
+                }
+
+
+# n_obs can be 22500: 2km, 5776: 4km, 121: 30km, 256:16x16 (20km); 961: 10km resoltn 
+# if radar: then n_obs is for each observation height level
+
+vis = dict(var_name='VIS 0.6µm', unit='[1]',
+           kind='MSG_4_SEVIRI_BDRF', sat_channel=1, 
+           n_obs=256, obs_locations='square_array_evenly_on_grid',
+           # n_obs=1, obs_locations=[(44.141, -0.99)],
+           error_generate=0.03, error_assimilate=0.03,
+           loc_horiz_km=10)
+
+wv62 = dict(var_name='Brightness temperature WV 6.2µm', unit='[K]',
+            kind='MSG_4_SEVIRI_TB', sat_channel=5, 
+            n_obs=961,  obs_locations='square_array_evenly_on_grid',
+            error_generate=1., error_assimilate=2., 
+            loc_horiz_km=20)
+
+wv73 = dict(var_name='Brightness temperature WV 7.3µm', unit='[K]',
+            kind='MSG_4_SEVIRI_TB', sat_channel=6, 
+            n_obs=961, obs_locations='square_array_evenly_on_grid',
+            error_generate=1., error_assimilate=3., 
+            loc_horiz_km=20)
+
+ir108 = dict(var_name='Brightness temperature IR 10.8µm', unit='[K]',
+             kind='MSG_4_SEVIRI_TB', sat_channel=9, 
+             n_obs=1, obs_locations='square_array_evenly_on_grid',
+             error_generate=5., error_assimilate=10.,
+             loc_horiz_km=32)
+
+radar = dict(var_name='Radar reflectivity', unit='[dBz]',
+             kind='RADAR_REFLECTIVITY', 
+             n_obs=5776, obs_locations='square_array_evenly_on_grid',
+             error_generate=2.5, error_assimilate=2.5,
+             heights=range(2000, 14001, 2000),
+             loc_horiz_km=20, loc_vert_km=2.5)
+
+t = dict(var_name='Temperature', unit='[K]',
+         kind='RADIOSONDE_TEMPERATURE', 
+         #n_obs=22500, obs_locations='square_array_evenly_on_grid',
+         n_obs=1, obs_locations=[(45., 0.)],
+         error_generate=0.2, error_assimilate=0.2,
+         heights=[1000,], #range(1000, 17001, 2000),
+         loc_horiz_km=50, loc_vert_km=2.5)
+
+q = dict(var_name='Specific humidity', unit='[kg/kg]',
+         kind='RADIOSONDE_SPECIFIC_HUMIDITY', n_obs=1,
+         error_generate=0., error_assimilate=5*1e-5,
+         heights=[1000], #range(1000, 17001, 2000),
+         loc_horiz_km=0.1, loc_vert_km=2.5)
+
+t2m = dict(var_name='SYNOP Temperature', unit='[K]',
+           kind='SYNOP_TEMPERATURE', n_obs=1, 
+           error_generate=0.1, error_assimilate=0.1,
+           loc_horiz_km=40, loc_vert_km=2.5)
+
+psfc = dict(var_name='SYNOP Pressure', unit='[Pa]',
+            kind='SYNOP_SURFACE_PRESSURE', n_obs=1, 
+            error_generate=50., error_assimilate=100.,
+            loc_horiz_km=32, loc_vert_km=5)
+
+exp.observations = [vis]
+exp.update_vars = ['U', 'V', 'W', 'THM', 'PH', 'MU', 'QVAPOR', 'QCLOUD', 'QICE', 'PSFC']
+
+
diff --git a/dartwrf/server_config.py b/dartwrf/server_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..a978a51bccf07dad53090810183254aafc89ec7b
--- /dev/null
+++ b/dartwrf/server_config.py
@@ -0,0 +1,82 @@
+import os, sys
+import datetime as dt
+from dartwrf import utils
+from cfg import exp
+
+"""Configuration name docs
+
+When coding, use attributes of a dictionary like this: 
+$ from cfg import exp, cluster
+$ path = cluster.archivedir
+
+
+attribute name    |     description
+------------------------------------------------------
+name                    any string (currently unused)
+
+python                  path of python version to use
+python_enstools         path of python version to use for verification script (not provided)
+ncks                    path to 'ncks' program; type 'which ncks' to find the path,
+                            if it doesn't exist, try to load the module first ('module load nco')
+ideal                   path to WRF's ideal.exe
+wrfexe                  path to WRF's wrf.exe
+
+wrf_rundir_base         path for temporary files for WRF
+dart_rundir_base        path for temporary files for DART
+archive_base            path for long-time output storage
+
+srcdir                  path to where WRF has been compiled, including the 'run' folder of WRF, e.g. /home/WRF-4.3/run
+dart_srcdir             path to DART compile directory, e.g. /home/DART-9.11.9/models/wrf/work
+rttov_srcdir            path to RTTOV compile directory, e.g. /home/RTTOV13/rtcoef_rttov13/
+scriptsdir              path where DART-WRF scripts reside, e.g. /home/DART-WRF/scripts
+
+namelist                path to a namelist template; strings like <hist_interval>, will be overwritten in scripts/prepare_namelist.py
+run_WRF                 path to script which runs WRF on a node of the cluster
+obs_impact_filename     path to obs_impact_filename (see DART guide; module assim_tools_mod and program obs_impact_tool)
+geo_em                  path to NetCDF file of WRF domain (see WRF guide)
+
+slurm_cfg               python dictionary, containing options of SLURM
+                            defined in SLURM docs (https://slurm.schedmd.com/sbatch.html)
+                            this configuration can be overwritten later on, for example:
+                            'dict(cluster.slurm_cfg, **cfg_update)' where
+                            'cfg_update = {"nodes": "2"}'
+"""
+
+
+cluster = utils.ClusterConfig(exp)
+cluster.name = 'jet'
+cluster.max_nproc = 12
+cluster.use_slurm = True
+cluster.size_jobarray = 40
+
+# binaries
+cluster.python = '/jetfs/home/lkugler/miniconda3/envs/DART/bin/python'
+cluster.python_verif = '/jetfs/home/lkugler/miniconda3/envs/enstools/bin/python'
+cluster.ncks = '/jetfs/spack/opt/spack/linux-rhel8-skylake_avx512/intel-2021.7.1/nco-5.1.0-izrhxv24jqco5epjhf5ledsqwanojc5m/bin/ncks'
+cluster.ideal = '/jetfs/home/lkugler/bin/ideal-v4.3_v1.22.exe'
+cluster.wrfexe = '/jetfs/home/lkugler/bin/wrf-v4.3_v1.22_ifort_20230413.exe'
+cluster.dart_modules = 'module purge; module load netcdf-fortran/4.5.3-gcc-8.5.0-qsqbozc;'
+cluster.wrf_modules = """module purge; module load intel-oneapi-compilers/2022.2.1-zkofgc5 hdf5/1.12.2-intel-2021.7.1-w5sw2dq netcdf-fortran/4.5.3-intel-2021.7.1-27ldrnt netcdf-c/4.7.4-intel-2021.7.1-lnfs5zz intel-oneapi-mpi/2021.7.1-intel-2021.7.1-pt3unoz
+export HDF5=/jetfs/spack/opt/spack/linux-rhel8-skylake_avx512/intel-2021.7.1/hdf5-1.12.2-w5sw2dqpcq2orlmeowleamoxr65dhhdc
+"""
+
+# paths for data output
+cluster.wrf_rundir_base = '/jetfs/home/lkugler/data/run_WRF/'  # path for temporary files
+cluster.dart_rundir_base = '/jetfs/home/lkugler/data/run_DART/'  # path for temporary files
+cluster.archive_base = '/jetfs/home/lkugler/data/sim_archive/'
+
+# paths used as input
+cluster.srcdir = '/jetfs/home/lkugler/data/compile/WRF-4.3/run'
+cluster.dart_srcdir = '/jetfs/home/lkugler/data/compile/DART/DART-10.5.3/models/wrf/work'
+cluster.rttov_srcdir = '/jetfs/home/lkugler/data/compile/RTTOV13/rtcoef_rttov13/'
+cluster.dartwrf_dir = '/jetfs/home/lkugler/DART-WRF/'
+
+# other inputs
+cluster.geo_em_for_WRF_ideal = '/jetfs/home/lkugler/data/geo_em.d01.nc'
+cluster.obs_impact_filename = cluster.dartwrf_dir+'/templates/impactfactor_T.txt'
+cluster.namelist = cluster.dartwrf_dir+'/templates/namelist.input'
+cluster.run_WRF = '/jetfs/home/lkugler/DART-WRF/dartwrf/run_ens.jet.sh'
+
+cluster.slurm_cfg = {"account": "lkugler", "partition": "compute", #"nodelist": "jet07",
+                 "ntasks": "1", "ntasks-per-core": "1", "mem": "50G",
+                 "mail-type": "FAIL", "mail-user": "lukas.kugler@univie.ac.at"}