Index: preproc/python/FlexpartTools.py
===================================================================
--- preproc/python/FlexpartTools.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
+++ preproc/python/FlexpartTools.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
@@ -0,0 +1,431 @@
+#
+# (C) Copyright 2014 UIO.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# 
+# Creation: October 2014 - Anne Fouilloux - University of Oslo
+#
+#
+import subprocess
+import shutil
+import os, errno
+import datetime
+from dateutil.relativedelta import relativedelta
+import re
+
+from string import atoi
+from numpy  import *
+from ecmwfapi import ECMWFDataServer
+from gribapi import *
+from GribTools import GribTools
+
+def product(*args, **kwds):
+    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
+    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
+    pools = map(tuple, args) * kwds.get('repeat', 1)
+    result = [[]]
+    for pool in pools:
+        result = [x+[y] for x in result for y in pool]
+    for prod in result:
+        yield tuple(prod)
+
+###############################################################
+# utility to remove a file if it exists
+# it does not fail if the file does not exist
+###############################################################
+def silentremove(filename):
+    try:
+        os.remove(filename)
+    except OSError as e: # this would be "except OSError, e:" before Python 2.6
+        if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
+            raise # re-raise exception if a different error occured
+
+###############################################################
+# Utility to create directories
+###############################################################
+def mkdir_p(file):
+    path = os.path.dirname(file)
+    try:
+        os.stat(path)
+    except:
+        os.makedirs(path)
+
+##############################################################
+# function to iterate over dates
+##############################################################
+def daterange( start_date, end_date ):
+    if start_date <= end_date:
+        for n in range( ( end_date - start_date ).days + 1 ):
+            yield start_date + datetime.timedelta( n )
+    else:
+        for n in range( ( start_date - end_date ).days + 1 ):
+            yield start_date - datetime.timedelta( n )
+
+##############################################################
+# function to iterate over years
+##############################################################
+def years_between(start_date,end_date):
+    years = []
+    cursor = start_date
+
+    while cursor <= end_date:
+        if cursor.year not in years:
+            years.append(cursor.year)
+        cursor += relativedelta(years=1)
+
+    return years
+##############################################################
+# function to iterate over months
+##############################################################
+def months_between(start_date,end_date):
+    months = []
+    cursor = start_date
+
+    while cursor <= end_date:
+        if cursor.month not in months:
+            months.append(cursor.month)
+        cursor += datetime.timedelta(days=1)
+
+    return months
+
+##############################################################
+# MARSretrieval class
+##############################################################
+class MARSretrieval:
+    'class for MARS retrievals'
+
+    def __init__(self,server, dataset="interim",marsclass="ei",type="",levtype="",levelist="", 
+                 repres="", date="",resol="",stream="",area="",time="",step="",expver="1",
+                 number="",accuracy="", grid="", gaussian="", target="",param=""):
+        self.dataset=dataset
+        self.marsclass=marsclass
+        self.type=type
+        self.levtype=levtype
+        self.levelist=levelist
+        self.repres=repres
+        self.date=date
+        self.resol=resol
+        self.stream=stream
+        self.area=area
+        self.time=time
+        self.step=step
+        self.expver=expver
+        self.target=target
+        self.param=param
+        self.number=number
+        self.accuracy=accuracy
+        self.grid=grid
+        self.gaussian=gaussian
+        self.server=server
+
+    def displayInfo(self):
+        if self.dataset:
+            print "dataset: ", self.dataset
+        if self.marsclass:
+            print "class: ", self.marsclass
+        if self.type:
+             print "type: ", self.type
+        if self.levtype:
+            print "levtype: ", self.levtype
+        if self.levelist:
+            print "levelist: ", self.levelist
+        if self.repres:
+            print "repres: ", self.repres
+        if self.date:
+            print "date: ", self.date
+        if self.resol:
+            print "resol: ", self.resol
+        if self.stream:
+            print "stream: ", self.stream
+        if self.area:
+            print "area: ", self.area
+        if self.time:
+            print "time: ", self.time
+        if self.step:
+            print "step: ", self.step
+        if self.expver:
+            print "expver: ", self.expver
+        if self.target:
+            print "target: ", self.target
+        if self.param:
+            print "param: ", self.param
+        if self.number:
+            print "number: ", self.number
+        if self.accuracy:
+            print "accuracy: ", self.accuracy
+        if self.grid:
+            print "grid: ", self.grid
+        if self.gaussian:
+            print "gaussian: ", self.gaussian
+
+    def dataRetrieve(self):
+        dicolist = {}
+        if self.dataset:
+	        dicolist['dataset']="%s"%(self.dataset)
+        if self.marsclass:
+	        dicolist['class']="%s"%(self.marsclass)
+        if self.date:
+	        dicolist['date']="%s"%(self.date)
+        if self.time:
+	        dicolist['time']="%s"%(self.time)
+        if self.expver:
+	        dicolist['expver']="%s"%(self.expver)
+        if self.param:
+	        dicolist['param']="%s"%(self.param)
+        if self.type:
+	        dicolist['type']="%s"%(self.type)
+        if self.levtype:
+	        dicolist['levtype']="%s"%(self.levtype)
+        if self.levelist:
+	        dicolist['levelist']="%s"%(self.levelist)
+        if self.repres:
+	        dicolist['repres']="%s"%(self.repres)
+        if self.resol:
+	        dicolist['resol']="%s"%(self.resol)
+        if self.stream:
+	        dicolist['stream']="%s"%(self.stream)
+        if self.area:
+	        dicolist['area']="%s"%(self.area)
+        if self.step:
+	        dicolist['step']="%s"%(self.step)
+        if self.target:
+	        dicolist['target']="%s"%(self.target)
+        if self.number:
+	        dicolist['number']="%s"%(self.number)
+        if self.accuracy:
+	        dicolist['accuracy']="%s"%(self.accuracy)
+        if self.grid:
+	        dicolist['grid']="%s"%(self.grid)
+        if self.gaussian:
+	        dicolist['gaussian']="%s"%(self.gaussian)
+
+        self.server.retrieve(dicolist)
+
+
+##############################################################
+class EIFlexpart:
+    'class to retrieve Era Interim data for running FLEXPART'
+##############################################################
+
+    def __init__(self):
+# different mars types for retrieving reanalysis data for flexpart
+       self.types=["an","fc"]
+
+       self.mars={}
+# set type (an/fc) and times and steps for EI
+#         (real) time    [type     time  step ] as in mars  (step for forecast only)     
+       self.mars["00"] = ["an",    "00"]
+       self.mars["01"] = ["fc",    "00", "01"]
+       self.mars["02"] = ["fc",    "00", "02"]
+       self.mars["03"] = ["fc",    "00", "03"]
+       self.mars["04"] = ["fc",    "00", "04"]
+       self.mars["05"] = ["fc",    "00", "05"]
+       self.mars["06"] = ["an",    "06"]
+       self.mars["07"] = ["fc",    "00", "07"]
+       self.mars["08"] = ["fc",    "00", "08"]
+       self.mars["09"] = ["fc",    "00", "09"]
+       self.mars["10"] = ["fc",    "00", "10"]
+       self.mars["11"] = ["fc",    "00", "11"]
+       self.mars["12"] = ["an",    "12"]
+       self.mars["13"] = ["fc",    "12", "01"]
+       self.mars["14"] = ["fc",    "12", "02"]
+       self.mars["15"] = ["fc",    "12", "03"]
+       self.mars["16"] = ["fc",    "12", "04"]
+       self.mars["17"] = ["fc",    "12", "05"]
+       self.mars["18"] = ["an",    "18"]
+       self.mars["19"] = ["fc",    "12", "07"]
+       self.mars["20"] = ["fc",    "12", "08"]
+       self.mars["21"] = ["fc",    "12", "09"]
+       self.mars["22"] = ["fc",    "12", "10"]
+       self.mars["23"] = ["fc",    "12", "11"]
+       
+    def retrieve(self, server, dates,times, area, levels, outputdir):
+        self.dates=dates
+        self.times=times
+        self.server=server
+        self.area=area
+        self.levels=levels
+        if outputdir=="":
+	  self.outputdir='.'
+        else:
+          self.outputdir=outputdir
+        # surface data
+        dataset="interim"
+        marsclass="ei"
+        expver="0001"
+        levels="1/to/"+ self.levels
+# Retrieve Q not for using Q but as a template for a reduced gaussian grid one date and time is enough
+# Take analysis at 00
+        qdate=self.dates
+        idx=qdate.find("/")
+        if (idx >0):
+          qdate=self.dates[:idx]
+        
+        Q= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type="an", levtype="ML", levelist="1",
+                         gaussian="reduced",grid="80", resol="159",accuracy="24",target=self.outputdir+"/"+"Q.grb",
+                         date=qdate, time="00",expver=expver, param="133.128")
+        Q.displayInfo()
+        Q.dataRetrieve()
+
+        for type in self.types:
+            stime=set()
+            sstep=set()
+            for time in self.times.split('/'):
+# not so nice... to review later!
+                if self.mars[time][0] == type:
+                  stime.add(self.mars[time][1])
+                  if (len(self.mars[time]) > 2):
+                     sstep.add(self.mars[time][2])
+          
+            rtime="/".join(stime)
+            if len(sstep) > 0:
+              rstep="/".join(sstep)
+            else:
+              rstep=""
+            print type
+            print rtime
+            if rstep!="":
+               print rstep
+            print "MARS retrieve start... "
+            paramUVD="131.128/132.128/155.128"
+            paramT="130.128"
+            paramLNSP="152.128"
+            param2D2T="167.128/168.128"
+            if rstep!="":
+                UVD= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="ML", levelist=levels,
+                         resol="159", accuracy="24",grid="OFF",target=self.outputdir+"/"+type+"UVD.grb",
+                         area=self.area, date=self.dates, time=rtime,step=rstep, expver=expver, param=paramUVD)
+                T= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="ML", levelist=levels,
+                         resol="159", accuracy="24",grid="1.0/1.0",target=self.outputdir+"/"+type+"T.grb",
+                         area=self.area, date=self.dates, time=rtime,step=rstep, expver=expver, param=paramT)
+                LNSP= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="ML", levelist="1",
+                         accuracy="24",target=self.outputdir+"/"+type + "LNSP.grb",
+                         area=self.area, date=self.dates, time=rtime,step=rstep, expver=expver, param=paramLNSP)
+                DT= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="SFC", levelist="OFF",
+                         resol="159",accuracy="24",grid="1.0/1.0",target=self.outputdir+"/"+type + "2D2T.grb",
+                         area=self.area, date=self.dates, time=rtime,step=rstep, expver=expver, param=param2D2T)
+                print "do not retrieve Q for forecast"
+            else:
+                UVD= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="ML", levelist=levels,
+                         resol="159", accuracy="24",grid="OFF",target=self.outputdir+"/"+type + "UVD.grb",
+                         area=self.area, date=self.dates, time=rtime,expver=expver, param=paramUVD)
+                T= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="ML", levelist=levels,
+                         resol="159", accuracy="24",grid="1.0/1.0",target=self.outputdir+"/"+type + "T.grb",
+                         area=self.area, date=self.dates, time=rtime,expver=expver, param=paramT)
+                LNSP= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="ML", levelist="1",
+                         accuracy="24",target=self.outputdir+"/"+type + "LNSP.grb",
+                         area=self.area, date=self.dates, time=rtime,expver=expver, param=paramLNSP)
+                DT= MARSretrieval(self.server, dataset=dataset, marsclass=marsclass, stream="oper", type=type, levtype="SFC", levelist="OFF",
+                         resol="159",accuracy="24",grid="1.0/1.0",target=self.outputdir+"/"+type + "2D2T.grb",
+                         area=self.area, date=self.dates, time=rtime,expver=expver, param=param2D2T)
+
+            UVD.displayInfo()
+            UVD.dataRetrieve()
+            T.dataRetrieve()
+            LNSP.dataRetrieve()
+            DT.dataRetrieve()
+        print "MARS retrieve done... "
+        
+    def getFlexpartTime(self, type,step, time):
+        if int(step) < 10:
+            cstep = '0' +  str(step)
+        else:
+            cstep = str(step)
+        if int(time/100) < 10:
+            ctime = '0' +  str(int(time/100))
+        else:
+            ctime = str(int(time/100))
+
+        ctype = str(type)
+        if ctype == 'fc':
+            myinfo = [ctype,ctime, cstep]
+        else:
+            myinfo = [ctype,ctime]
+        cflextime = None
+        for t, marsinfo in self.mars.items():
+            if myinfo == marsinfo:
+                cflextime=t
+        return cflextime
+
+    def create(self, inputfiles, outputdir):
+        index_keys=["date","time","stepRange"]
+        indexfile="date_time_stepRange.idx"
+        grib=GribTools(inputfiles.files)
+        iid=grib.index(index_keys=index_keys, index_file = indexfile)
+
+        silentremove("fort.10")
+        silentremove("fort.11")
+        silentremove("fort.12")
+        silentremove("fort.13")
+        silentremove("fort.18")
+        index_vals = []
+        for key in index_keys:
+            key_vals = grib_index_get(iid,key)
+
+            index_vals.append(key_vals)
+
+
+        for prod in product(*index_vals):
+            for i in range(len(index_keys)):
+                grib_index_select(iid,index_keys[i],prod[i])
+
+            f10 = open('fort.10','w')
+            f11 = open('fort.11','w')
+            f12 = open('fort.12','w')
+            f13 = open('fort.13','w')
+            f16 = open('fort.16','w')
+            gid = grib_new_from_index(iid)
+            hid = gid
+            cflextime = None
+            if gid is not None: 
+                cdate = str(grib_get(gid, 'date'))
+                cyear = cdate[:4]
+                cmonth = cdate[4:6]
+                cday = cdate[6:8]
+                time = grib_get(gid, 'time')
+                type = grib_get(gid, 'type')
+                step = grib_get(gid, 'stepRange')
+                cflextime = self.getFlexpartTime(type,step, time)
+            while 1:  
+                if gid is None: break
+                paramId = grib_get(gid, 'paramId')
+                if paramId == 133:
+# Relative humidity (Q.grb) is used as a template only so we need the first we "meet"
+                    fout=open('fort.18','w')
+                    grib_write(gid,fout)
+                    fout.close()
+                if paramId == 131 or paramId == 132:
+                    grib_write(gid, f10)
+                if paramId == 130:
+                    grib_write(gid,f11)
+                if paramId == 152:
+                    grib_write(gid,f12)
+                if paramId == 155:
+                    grib_write(gid,f13)
+                if paramId == 167 or paramId == 168:
+                    grib_write(gid, f16)                    
+                grib_release(gid)
+                gid = grib_new_from_index(iid)
+# call for CONVERT2
+            
+            f10.close()
+            f11.close()
+            f12.close()
+            f13.close()
+            f16.close()
+            if hid is not None:
+                p=subprocess.check_call(['CONVERT2'])
+# create the corresponding output file  fort.15 (generated by CONVERT2) + fort.16 (paramId 167 and paramId 168)  
+                mkdir_p(outputdir+'/'+cyear+'/'+cmonth+'/')
+                fout = open(outputdir+'/'+cyear+'/'+cmonth+'/EI'+cyear[2:4]+cmonth+cday+cflextime,'wb')    
+                shutil.copyfileobj(open('fort.15','rb'), fout)     
+                shutil.copyfileobj(open('fort.16','rb'), fout)
+                fout.close()
+
+        grib_index_release(iid)
+
+    def clean(self):
+        print "clean"
+
Index: preproc/python/GribTools.py
===================================================================
--- preproc/python/GribTools.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
+++ preproc/python/GribTools.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
@@ -0,0 +1,140 @@
+#
+# (C) Copyright 2014 UIO.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+# 
+# 
+# Creation: July 2014 - Anne Fouilloux - University of Oslo
+#
+#
+
+from gribapi import *
+import traceback
+import sys,os
+
+
+##############################################################
+#  GRIB utilities
+##############################################################
+class GribTools:
+    'class for GRIB API with new methods'
+    def __init__(self,filename):
+        self.filename=filename
+    
+# get keyvalues for a given list of keynames
+# a where statment can be given (list of key and list of values)
+
+    def getkeys(self,keynames,wherekeynames=[],wherekeyvalues=[]):
+        fileid=open(self.filename,'r')
+
+        return_list=[]
+        
+        while 1:
+            gid_in = grib_new_from_file(fileid)  
+            if gid_in is None: break
+            select=True
+            i=0
+            if len(wherekeynames) != len(wherekeyvalues): raise Exception("Give a value for each keyname!")
+
+            for wherekey in wherekeynames:
+                if not grib_is_defined(gid_in, wherekey): raise Exception("where Key was not defined")
+                select=select and (str(wherekeyvalues[i])==str(grib_get(gid_in, wherekey)))
+                i=i+1
+            if select:
+                llist = []
+                for key in keynames:
+                    llist.extend([str(grib_get(gid_in, key))])
+                return_list.append(llist)
+            grib_release(gid_in)
+        fileid.close()
+        return return_list
+      
+# set keyvalues for a given list of keynames
+# a where statment can be given (list of key and list of values)
+# an input file must be given as an input for reading grib messages
+# note that by default all messages are written out
+# if you want to get only those meeting the where statement, use
+# strict=true
+    def setkeys(self,fromfile,keynames,keyvalues, wherekeynames=[],wherekeyvalues=[], strict=False, filemode='w'):
+        fout=open(self.filename,filemode)
+        fin=open(fromfile)
+        
+        while 1:
+            gid_in = grib_new_from_file(fin)  
+            if gid_in is None: break
+            
+            select=True
+            i=0
+            if len(wherekeynames) != len(wherekeyvalues): raise Exception("Give a value for each keyname!")
+
+            for wherekey in wherekeynames:
+                if not grib_is_defined(gid_in, wherekey): raise Exception("where Key was not defined")
+                select=select and (str(wherekeyvalues[i])==str(grib_get(gid_in, wherekey)))
+                i=i+1
+            if select:
+                i=0
+                for key in keynames:
+                    grib_set(gid_in, key, keyvalues[i])
+                    i=i+1
+            if strict:
+                if select:
+                    grib_write(gid_in,fout)
+            else:
+                grib_write(gid_in,fout)
+            grib_release(gid_in)
+        fin.close()
+        fout.close()
+
+# Add the content of a grib file but only messages
+# corresponding to keys/values        
+# if selectWhere is False select fields that are different from keynames/keyvalues
+    def copy(self,filename_in, selectWhere=True, keynames=[], keyvalues=[],filemode='w'):
+        fin=open(filename_in)
+        fout=open(self.filename,filemode)
+        
+        while 1:
+            gid_in = grib_new_from_file(fin)  
+            if gid_in is None: break
+            
+            select=True
+            i=0
+            if len(keynames) != len(keyvalues): raise Exception("Give a value for each keyname!")
+
+            for key in keynames:
+                if not grib_is_defined(gid_in, key): raise Exception("Key was not defined")
+                
+                if selectWhere:
+                    select=select and (str(keyvalues[i])==str(grib_get(gid_in, key)))
+                else:
+                    select=select and (str(keyvalues[i])!=str(grib_get(gid_in, key)))
+                i=i+1
+            if select:
+                grib_write(gid_in,fout)
+            grib_release(gid_in)
+        fin.close()
+        fout.close()
+
+# Create index from a list of files if it does not exist or read it
+    def index(self,index_keys=["mars"], index_file = "my.idx"):
+        self.iid = None
+ 
+        if (os.path.exists(index_file)):
+            self.iid = grib_index_read(index_file)
+            print "Use existing index file: %s "%(index_file)
+        else:
+            for file in self.filename:
+                print "Inputfile: %s "%(file)
+                if self.iid == None:
+                    self.iid = grib_index_new_from_file(file,index_keys)
+                else:
+                     grib_index_add_file(self.iid,file)
+
+            if self.iid != None:
+              grib_index_write(self.iid,index_file)
+        return self.iid 
+
+
+       
+
+        
Index: preproc/python/README.md
===================================================================
--- preproc/python/README.md	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
+++ preproc/python/README.md	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
@@ -0,0 +1,151 @@
+# README #
+
+This documentation shows how to use these python scripts to extract ECMWF ERA-Interim data and generate WINDFIELDS for running FLEXPART. 
+
+### Overview ###
+
+To run FLEXPART with ECMWF ERA-Interim data, you first need to retrieve ECMWF ERA-Interim GRIB fields and generate FLEXPART WINDFIELDS to run FLEXPART.
+
+The two main programs are called respectively `getEIdata.py` and `prepareFLEXPART.py`. 
+
+To get the usage of these programs, use `-h` option:
+
+`getEIdata.py `-h`
+
+Optional arguments are mentionned in squared brackets. 
+
+* `getEIdata.py`
+
+This program allows you to download ECMWF ERA-Interim data from ECMWF using [ecmwfapi](https://software.ecmwf.int/wiki/display/WEBAPI/ECMWF+Web+API+Home). 
+It requires `ecmwfapi` python library (see Requirements below). Check with your local IT group as it may be already available.
+
+`
+Usage: getEIdata.py --start_date=YYYYMMDD [--end_date=YYYYMMDD] [--times=tt1/tt2/tt3] [--levels=nlevels]
+                                                  [--area=north/west/south/east]  [--outputdir=output_directory]
+
+Options:
+  -h, --help            show this help message and exit
+  --start_date=start_date
+                        start date YYYYMMDD
+  --end_date=end_date   end_date YYYYMMDD
+  --times=times         times such as 00/12
+  --levels=levels       number of vertical levels
+  --area=area           area defined as north/west/south/east with default
+                        90.0/-179.0/-90.0/180.0
+  --outputdir=outputdir
+                        root directory for storing output files
+`
+
+* `prepareFLEXPART.py`
+
+This program allow you to generate FLEXPART WINDFIELDS (inputs for FLEXPART). It requires python interface to grib_api and `CONVERT2` program (located in `src` directory with instruction on how to compile it). You also need to provide a namelist for CONVERT2 (see test_1).
+
+`
+Usage: prepareFLEXPART.py --start_date=YYYYMMDD [--end_date=YYYYMMDD] [--namelist=namelist_for_convert] [--inputdir=input_root_directory] [--outputdir=output_directory]
+
+Options:
+  -h, --help            show this help message and exit
+  --start_date=start_date
+                        start date YYYYMMDD
+  --end_date=end_date   end_date YYYYMMDD
+  --namelist=namelist   namelist used for converting
+  --inputdir=inputdir   root directory for reading input files
+  --outputdir=outputdir
+                        root directory for storing output files
+
+`
+### Requirements ###
+
+| Python Support        |
+|----------------------:| 
+| python                | [http://www.python.org](http://www.python.org)  | We have use [python Anaconda](https://store.continuum.io/cshop/anaconda/) for our testings
+| python-numpy          | [http://www.numpy.org/](http://www.numpy.org/)  | Not necessary if you have installed python Anaconda
+| ecmwfapi              | [https://software.ecmwf.int/wiki/display/WEBAPI/ECMWF+Web+API+Home](https://software.ecmwf.int/wiki/display/WEBAPI/ECMWF+Web+API+Home) | You also need to install your API key (as explained in the documentation)
+| Utilities             |
+|----------------------:| 
+|  grib-api             | [https://software.ecmwf.int/wiki/display/GRIB/Home](https://software.ecmwf.int/wiki/display/GRIB/Home) | Make sure you install GRIB-API with JPEG support and python GRIB-API.
+|----------------------:| 
+| FLEXPART programs     | to run these programs (prepareFLEXPART.py), you need to compile CONVERT2 program (located in preproc/src). See separate README file to get instructions on how to compile this code.
+|----------------------:| 
+
+
+### Installation ###
+
+*  Environment
+
+At UIO, Red Hat 6 Linux systems (64 bits) were used for testing. We use the [Module package](http://modules.sourceforge.net/) to set-up user environment.
+
+* Getting the source code
+In the directory of your choice:
+
+`
+git clone git@bitbucket.org:flexpart/flexpart.git
+`
+This command will create a subdirectory called flexpart: it contains the latest FLEXPART version.
+
+Set then environment variable `FLEXPART_HOME`:
+
+** Korn-shell or Bash users:
+`
+cd flexpart
+export FLEXPART_HOME=$PWD
+`
+
+** C-shell users:
+
+`
+cd flexpart
+setenv FLEXPART_HOME=$PWD
+`
+
+* Installation
+
+Make sure your first generate `CONVERT2` program (see separate instructions in `preproc/src`).
+
+Users need to be able to execute prepareFLEXPART.py and getEIdata.py so make sure they have the correct unix permissions:
+
+`
+cd preproc/python
+chmod uog+rx getEIdata.py prepareFLEXPART.py
+`
+
+These two programs must be in the user PATH. At UIO this is done automatically when loading flexpart. If not, you would need to do the following:
+
+** Korn-shell or Bash users:
+`
+export PATH=$FLEXPART_HOME/preproc/python:$PATH
+`
+
+** C-shell users:
+
+`
+setenv PATH $FLEXPART_HOME/preproc/python:$PATH
+`
+
+Where `$FLEXPART_HOME` is the directory where FLEXPART 
+
+* Testing your installation
+
+First check that grib-api python interface is correctly installed on your platform:
+`
+python
+>>> from gribapi import *
+>>>
+`
+Use `CTRL-D` to quit python.
+
+Then check that `ecmwfapi` is properly installed:
+`
+python
+>>> from ecmwfapi import *
+>>>
+`
+
+If the two previous tests were successful, you can run `tests/preproc` (See separate instructions in `tests/preproc`). 
+
+If any of these two tests fail, this probably means that either `ecmwfapi` or `grib-api` have not been installed properly. 
+
+Please report any problems.
+
+###  Installation FAQ ###
+
Index: preproc/python/UIOTools.py
===================================================================
--- preproc/python/UIOTools.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
+++ preproc/python/UIOTools.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
@@ -0,0 +1,45 @@
+#!/usr/bin/env python                                                                                                                                                                      
+#                                                                                                                                                                                          
+# (C) Copyright 2014 UIO.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# Creation: October 2014 - Anne Fouilloux - University of Oslo
+#
+
+import os
+
+class UIOFiles:
+    'class to manipulate files'
+    def __init__(self,suffix):
+# type of files to manipulate such as ['.grib', 'grb', 'grib1', 'grib2', 'grb1','grb2']
+        self.suffix=suffix
+
+    def listFiles(self,pathname):
+        ''' list files (suffix previously given) within this directory. '''
+    # Get the absolute path of the pathname parameter
+        pathname = os.path.abspath(pathname)
+ 
+    # Get a list of files in pathname
+        filesInCurDir = os.listdir(pathname)
+        self.counter = 0
+        self.files = []
+    # Traverse through all files
+        for file in filesInCurDir:
+            curFile = os.path.join(pathname, file)
+ 
+        # Check if it's a normal file or directory
+            if os.path.isfile(curFile):
+                # Get the file extension
+                fileNoExt,curFileExtension = os.path.splitext(curFile)
+                # Check if the file has an extension of typical video files
+                if curFileExtension in self.suffix:
+                    # We have got a file file! Increment the counter
+                    self.counter += 1
+                    # add this filename in the list
+                    self.files.append(curFile)
+                    
+            else:
+                # We got a directory, enter into it for further processing
+                self.listFiles(curFile)
Index: preproc/python/getEIdata.py
===================================================================
--- preproc/python/getEIdata.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
+++ preproc/python/getEIdata.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+#
+# (C) Copyright 2014 UIO.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+# 
+# Creation: July 2014 - Anne Fouilloux - University of Oslo
+#
+# Get ERA-Interim GRIB fields from ECMWF to prepare WINDFIELDS for running
+# FLEXPART examples.
+# 
+# To run this example, you need to self-register at ECMWF data server and
+# get an API key available from https://api.ecmwf.int/v1/key/
+#
+# Inputs parameters:
+#  start_date: starting date for retrieving ECMWF data
+#  end_date  : end date for retrieving ECMWF data; set to start_date if not specified
+#  times     : forecast or analysis time for MARS retrievals
+#  levels    : number of levels; set to 60 by default (for ERA-interim)
+#  area      : you can define your area with --area=north/west/south/east (values are in degrees)
+#  outputdir : location where you want to store ERA-Interim outputs
+# 
+from ecmwfapi import ECMWFDataServer
+import calendar
+import shutil
+import datetime
+import time
+import os
+from string import strip
+from optparse import OptionParser
+from FlexpartTools import MARSretrieval, EIFlexpart, daterange, mkdir_p, silentremove, months_between
+
+
+def main():
+    usage = """usage: %prog --start_date=YYYYMMDD [--end_date=YYYYMMDD] [--times=tt1/tt2/tt3] [--levels=nlevels]
+                                                  [--area=north/west/south/east]  [--outputdir=output_directory] """
+    parser = OptionParser(usage=usage)
+    parser.add_option("--start_date", dest="start_date",
+                      help="start date YYYYMMDD", metavar="start_date" )
+    parser.add_option( "--end_date", dest="end_date",
+                      help="end_date YYYYMMDD", metavar="end_date")
+    parser.add_option("--times", dest="times",
+                      default="00/03/06/09/12/15/18/21", help="times such as 00/12", metavar="times")
+    parser.add_option("--levels", dest="levels",
+                      default="60",help="number of vertical levels", metavar="levels")
+    parser.add_option("--area", dest="area",
+                      default="90.0/-179.0/-90.0/180.0",help="area defined as north/west/south/east with default 90.0/-179.0/-90.0/180.0", metavar="area")
+    parser.add_option("--outputdir", dest="outputdir",
+                      help="root directory for storing output files", metavar="outputdir")
+    (options, args) = parser.parse_args()
+
+    if not options.start_date:
+        parser.error("start date must be specified!")
+    else:
+        start_date=options.start_date
+
+    if not options.end_date:
+        end_date=start_date
+    else:
+        end_date=options.end_date
+
+    if not options.outputdir:
+# if WORKDIR is defined, we will use it otherwise files 
+# will be stored in the current directory
+        outputdir=os.environ.get("WORKDIR",".")
+    else:
+        outputdir=options.outputdir
+
+
+    print "start date %s "%(start_date)
+    print "end date %s "%(end_date)
+
+       
+    server = ECMWFDataServer()
+
+# Retrieve ERA interim data for running flexpart
+
+    syear=int(start_date[:4])
+    smonth=int(start_date[4:6])
+    sday=int(start_date[6:])
+    start = datetime.date( year = syear, month = smonth, day = sday )
+    eyear=int(end_date[:4])
+    emonth=int(end_date[4:6])
+    eday=int(end_date[6:])
+
+    end = datetime.date( year = eyear, month = emonth, day = eday )
+
+    current_ym = ""
+    ir_date = start
+    retrieve="no"
+    for date in daterange( start, end ):
+# if new year & month then we create a new directory to store output files
+        er_date = date
+        if date.strftime("%Y%m") != current_ym:
+            current_outputdir =  outputdir + "/"  + date.strftime("%Y") + '/' + date.strftime("%m") + '/' 
+            mkdir_p(current_outputdir)
+            if current_ym != "":
+               retrieve="yes"
+
+        if date == end:
+            retrieve="yes"
+
+        if retrieve == "yes":
+                # we need to retrieve MARS data for this period (maximum one month)
+                flexpart = EIFlexpart()
+                dates= ir_date.strftime("%Y%m%d") + "/to/" + er_date.strftime("%Y%m%d") 
+                flexpart.retrieve(server, dates, options.times, options.area, options.levels, current_outputdir)
+                ir_date = er_date
+
+        current_ym =  date.strftime("%Y%m")
+
+
+
+if __name__ == "__main__":
+    main()
Index: preproc/python/prepareFLEXPART.py
===================================================================
--- preproc/python/prepareFLEXPART.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
+++ preproc/python/prepareFLEXPART.py	(revision 57637935b8c736ecb0a376df5e8f6a044bbd05af)
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# (C) Copyright 2014 UIO.
+#
+# This software is licensed under the terms of the Apache Licence Version 2.0
+# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
+# 
+# Creation: October 2014 - Anne Fouilloux - University of Oslo
+#
+# Compute WINDFILEDS from ECMWF GRIB data
+# 
+import calendar
+import shutil
+import datetime
+import time
+import os
+from UIOTools import UIOFiles
+from string import strip
+from optparse import OptionParser
+from GribTools import GribTools
+from FlexpartTools import EIFlexpart, daterange
+
+
+def main():
+    usage = """usage: %prog --start_date=YYYYMMDD [--end_date=YYYYMMDD] [--namelist=namelist_for_convert] [--inputdir=input_root_directory] [--outputdir=output_directory] """
+    parser = OptionParser(usage=usage)
+    parser.add_option("--start_date", dest="start_date",
+                      help="start date YYYYMMDD", metavar="start_date" )
+    parser.add_option( "--end_date", dest="end_date",
+                      help="end_date YYYYMMDD", metavar="end_date")
+    parser.add_option("--namelist", dest="namelist",
+                      help="namelist used for converting", metavar="namelist")
+    parser.add_option("--inputdir", dest="inputdir",
+                      help="root directory for reading input files", metavar="inputdir")
+    parser.add_option("--outputdir", dest="outputdir",
+                      help="root directory for storing output files", metavar="outputdir")
+    (options, args) = parser.parse_args()
+
+    if not options.start_date:
+        parser.error("start date must be specified!")
+    else:
+        start_date=options.start_date
+
+    if not options.end_date:
+        end_date=start_date
+    else:
+        end_date=options.end_date
+
+    if not options.namelist:
+        namelist='fort.4'
+    else:
+        namelist=options.namelist
+
+    if not options.inputdir:
+# if WORKDIR is defined, we will use it otherwise files 
+# will be stored in the current directory
+        inputdir=os.environ.get("WORKDIR",".")
+    else:
+        inputdir=options.inputdir
+
+    if not options.outputdir:
+# if FLEXPART_WINDS is defined, we will use it otherwise files 
+# will be stored in the current directory
+        outputdur=os.environ.get("FLEXPART_WINDS",".")
+    else:
+        outputdir=options.outputdir
+
+
+
+    syear=int(start_date[:4])
+    smonth=int(start_date[4:6])
+    sday=int(start_date[6:])
+    start = datetime.date( year = syear, month = smonth, day = sday )
+    eyear=int(end_date[:4])
+    emonth=int(end_date[4:6])
+    eday=int(end_date[6:])
+
+    end = datetime.date( year = eyear, month = emonth, day = eday )
+
+
+
+    cyear = -1
+    cmont = -1
+    inputfiles=UIOFiles(['.grib', '.grb', '.grib1', '.grib2', '.grb1','.grb2'])
+    if (not os.path.exists('fort.4')):
+        fnamelist=open('fort.4','w')
+        shutil.copyfileobj(open(namelist,'r'), fnamelist)
+        fnamelist.close()
+    for date in daterange( start, end ):
+# data retrieved by year/month
+           if cyear != date.year or cmonth != date.month:
+             print 'year : ' + str(date.year) + ' month : ', date.month
+             cyear = date.year
+             cmonth = date.month
+
+             # we will make the list of files from the root inputdir
+             if cmonth < 10:
+                 inputfiles.listFiles(inputdir + '/'+str(cyear)+'/0'+str(date.month))
+             else:
+                 inputfiles.listFiles(inputdir + '/'+str(cyear)+'/'+str(date.month))
+                 
+             flexpart = EIFlexpart()
+             flexpart.create(inputfiles, outputdir)
+
+if __name__ == "__main__":
+    main()
