diff --git a/flux_calc_v3.py b/flux_calc_v3.py
index dcc963a6eb08aca3f58d760992ff1ac186534cbd..aff60cc450ca66131780da391160b16ab3956fa2 100755
--- a/flux_calc_v3.py
+++ b/flux_calc_v3.py
@@ -1,73 +1,133 @@
 import numpy as np
 import sys
 import logging
-from flux_subs import get_heights,cdn_calc, cd_calc, get_skin, psim_calc, \
-                      psit_calc, ctcq_calc,ctcqn_calc, get_gust, gc,q_calc,qsea_calc,qsat26sea, qsat26air, \
-                      visc_air, psit_26,psiu_26, psiu_40,cd_C35
+from flux_subs import (kappa, CtoK, get_heights, cdn_calc, cd_calc, get_skin,
+                       psim_calc, psit_calc, ctcq_calc, ctcqn_calc, get_gust,
+                       gc, q_calc, qsea_calc, qsat26sea, qsat26air,
+                       visc_air, psit_26, psiu_26, psiu_40, cd_C35,
+                       charnock_C35)
 
-def flux_calc_v3(spd, T, SST, lat, RH, P, hin, hout, wcp, sigH, zi = 600, \
-              Rl=None, Rs=None, jcool=1, method="Smith80",n=20):
-    """
-    inputs:
-        flux method ("Smith80","Smith88","LP82","HEXOS","HEXOSwave","YT96","COARE3.0","COARE3.5","LY04")
-        spd : relative wind speed in m/s (is assumed as magnitude difference between wind 
-              and surface current vectors)
-        T   : air temperature in K (will convert if < 200)
-        SST : sea surface temperature in K (will convert if < 200)
-        lat : latitude
-        rh  : relative humidity in %, default 80% for C35      
-        P   : air pressure, default 1013 for C35
-        hin : sensor heights in m (array of 1->3 values: 1 -> u=t=q; 2 -> u,t=q; 3 -> u,t,q ) default 10m
-        hout: default heights are 10m 
-        wcp  : phase speed of dominant waves (m/s) called in COARE3.5
-        sigH: significant wave height (m) called in COARE3.5
-        zi  : PBL height (m) called in COARE3.5
-        Rl  : downward longwave radiation (W/m^2)
-        Rs  : downward shortwave radiation (W/m^2)
-        jcool: 0 if sst is true ocean skin temperature called in COARE3.5
-        n   : number of iterations, for COARE3.5 set to 10
-    outputs:
-        res : which contains 1. tau 2. sensible heat 3. latent heat 4. Monin-Obhukov length (monob)
-              5. drag coefficient (cd) 6. neutral drag coefficient (cdn) 7. ct 8. ctn 9. cq 10. cqn
-              11.tsrv 12. tsr 13. qsr 14. usr 15. psim 16. psit 17. u10n 18. t10n 19. tv10n
-              20. q10n 21. zo 22. zot 23. zoq 24. urefs 25.trefs 26. qrefs 27. iterations
-        ind : the indices in the matrix for the points that did not converge after the maximum number of iterations 
-        based on bform.f and flux_calc.R modified and ported to python by S. Biri
+
+def flux_calc_v3_1(spd, T, SST, lat, RH, P, hin, hout, wcp, sigH, zi=600,
+                 Rl=None, Rs=None, jcool=1, meth="S88", n=10):
+    """ Calculates momentum and heat fluxes using different parameterizations
+
+    Parameters
+    ----------
+        meth : str
+            "S80","S88","LP82","YT96","UA","HEXOS","HEXOSwave",
+            "LY04","C30","C35","ERA5"
+        spd : float
+            relative wind speed in m/s (is assumed as magnitude difference
+            between wind and surface current vectors)
+        T : float
+            air temperature in K (will convert if < 200)
+        SST : float
+            sea surface temperature in K (will convert if < 200)
+        lat : float
+            latitude (deg)
+        RH : float
+            relative humidity in %
+        P : float
+            air pressure
+        hin : float
+            sensor heights in m (array of 1->3 values: 1 -> u=t=q; /
+            2 -> u,t=q; 3 -> u,t,q ) default 10m
+        hout : float
+            output height, default is 10m
+        wcp : float
+            phase speed of dominant waves (m/s) called in C35
+        sigH : float
+            significant wave height (m) called in C35
+        zi : int
+            PBL height (m) called in C35
+        Rl : float
+            downward longwave radiation (W/m^2)
+        Rs : float
+            downward shortwave radiation (W/m^2)
+        jcool : bool
+            0 if sst is true ocean skin temperature called in C35
+        n : int
+            number of iterations, for C35 set to 10
+        out : str
+            format in which to save output ('output.nc' or None)
+
+    Returns
+    -------
+        res : array that contains
+                       1. momentum flux (W/m^2)
+                       2. sensible heat (W/m^2)
+                       3. latent heat (W/m^2)
+                       4. Monin-Obhukov length (mb)
+                       5. drag coefficient (cd)
+                       6. neutral drag coefficient (cdn)
+                       7. heat exhange coefficient (ct)
+                       8. neutral heat exhange coefficient (ctn)
+                       9. moisture exhange coefficient (cq)
+                       10. neutral moisture exhange coefficient (cqn)
+                       11. star virtual temperature (tsrv)
+                       12. star temperature (tsr)
+                       13. star humidity (qsr)
+                       14. star velocity (usr)
+                       15. momentum stability function (psim)
+                       16. heat stability funciton (psit)
+                       17. 10m neutral velocity (u10n)
+                       18. 10m neutral temperature (t10n)
+                       19. 10m neutral virtual temperature (tv10n)
+                       20. 10m neutral specific humidity (q10n)
+                       21. surface roughness length (zo)
+                       22. heat roughness length (zot)
+                       23. moisture roughness length (zoq)
+                       24. velocity at reference height (urefs)
+                       25. temperature at reference height (trefs)
+                       26. specific humidity at reference height (qrefs)
+                       27. number of iterations until convergence
+        ind : int
+            the indices in the matrix for the points that did not converge
+            after the maximum number of iterations
+    The code is based on bform.f and flux_calc.R modified by S. Biri
     """
-    logging.basicConfig(filename='flux_calc.log', level=logging.INFO)
-    kappa,CtoK = 0.4, 273.16      # von Karman's constant; conversion factor from degC to K
+    logging.basicConfig(filename='flux_calc.log',
+                        format='%(asctime)s %(message)s',level=logging.INFO)
     ref_ht, tlapse = 10, 0.0098   # reference height, lapse rate
     hh_in = get_heights(hin)      # heights of input measurements/fields
-    hh_out = get_heights(hout)    # desired height of output variables,default is 10
-    g=gc(lat,None)                # acceleration due to gravity
-    ctn, ct, cqn, cq= np.zeros(spd.shape)*np.nan,np.zeros(spd.shape)*np.nan,np.zeros(spd.shape)*np.nan,np.zeros(spd.shape)*np.nan
+    hh_out = get_heights(hout)    # desired height of output variables
+    if np.all(np.isnan(lat)):     # set latitude to 45deg if empty
+        lat=45*np.ones(np.shape(spd))
+    g = gc(lat, None)             # acceleration due to gravity
+    ctn, ct, cqn, cq = (np.zeros(spd.shape)*np.nan, np.zeros(spd.shape)*np.nan,
+                        np.zeros(spd.shape)*np.nan, np.zeros(spd.shape)*np.nan)
     # if input values are nan break
     if (np.all(np.isnan(spd)) or np.all(np.isnan(T)) or np.all(np.isnan(SST))):
         sys.exit("input wind, T or SST is empty")
         logging.debug('all input is nan')
-    if (np.all(np.isnan(RH)) or np.all(np.isnan(P))):
-        if (method=="COARE3.5"):
-           RH=np.ones(np.shape(spd))*80
-           P=np.ones(np.shape(spd))*1013
-        else:
-           sys.exit("input RH or P is empty")
-    if (np.all(spd[~np.isnan(spd)]== 0) and method != "COARE3.0"):
-        sys.exit("wind cannot be zero when method other than COARE3.0")
-        logging.debug('all velocity input is zero')
-    if (np.all(np.isnan(Rl)) and method=="COARE3.5"):
-        Rl=np.ones(np.shape(spd))*370 # set to default
-    if (np.all(np.isnan(Rs)) and method=="COARE3.5"):
-        Rs=np.ones(np.shape(spd))*150  # set to default
-    if (np.all(np.isnan(zi)) and method=="COARE3.5"):
-        zi=600 # set to default
-    ### additional parameters for COARE3.5
-    waveage,seastate=1,1
+    if (np.all(np.isnan(RH)) and meth == "C35"):
+        RH = np.ones(np.shape(spd))*80  # if empty set to default for COARE3.5
+    else:
+        sys.exit("input RH is empty")
+        logging.debug('input RH is empty')
+    if (np.all(np.isnan(P)) and meth == "C35"):
+        P = np.ones(np.shape(spd))*1013  # if empty set to default for COARE3.5
+    else:
+        sys.exit("input P is empty")
+        logging.debug('input P is empty')
+    if (np.all(np.isnan(Rl)) and meth == "C35"):
+        Rl = np.ones(np.shape(spd))*370    # set to default for COARE3.5
+    if (np.all(np.isnan(Rs)) and meth == "C35"):
+        Rs = np.ones(np.shape(spd))*150  # set to default for COARE3.5
+    if (np.all(np.isnan(zi)) and meth == "C35"):
+        zi = 600  # set to default for COARE3.5
+    elif ((np.all(np.isnan(zi)) and meth == "ERA5") or
+          (np.all(np.isnan(zi)) and meth == "UA")):
+        zi = 1000
+    # additional parameters for C35
+    waveage, seastate = 1, 1
     if np.isnan(wcp[0]):
-        wcp=np.ones(np.shape(spd))*np.nan
-        waveage=0
+        wcp = np.ones(np.shape(spd))*np.nan
+        waveage = 0
     if np.isnan(sigH[0]):
-        sigH=np.ones(np.shape(spd))*np.nan
-        seastate=0
+        sigH = np.ones(np.shape(spd))*np.nan
+        seastate = 0
     if waveage and seastate:
         print('Using seastate dependent parameterization')
         logging.info('Using seastate dependent parameterization')
@@ -75,190 +135,298 @@ def flux_calc_v3(spd, T, SST, lat, RH, P, hin, hout, wcp, sigH, zi = 600, \
         print('Using waveage dependent parameterization')
         logging.info('Using waveage dependent parameterization')
     ####
-    Ta = np.where(np.nanmax(T)<200,np.copy(T)+CtoK+tlapse*hh_in[1],np.copy(T)+tlapse*hh_in[1]) # convert to Kelvin if needed
-    sst = np.where(np.nanmax(SST)<200,np.copy(SST)+CtoK,np.copy(SST))
-    if (method == "COARE3.5"):
-        qsea = qsat26sea(sst,P)/1000   # surface water specific humidity (g/kg)
-        Q,_  = qsat26air(T,P,RH)       # specific humidity of air (g/kg)
-        qair=Q/1000; del Q
-        logging.info('method %s | qsea:%s, qair:%s',method,np.ma.median(qsea),np.ma.median(qair))
+    Ta = np.where(np.nanmax(T) < 200, np.copy(T)+CtoK+tlapse*hh_in[1],
+                  np.copy(T)+tlapse*hh_in[1])  # convert to Kelvin if needed
+    sst = np.where(np.nanmax(SST) < 200, np.copy(SST)+CtoK, np.copy(SST))
+    if (meth == "C35"):
+        qsea = qsat26sea(sst, P)/1000  # surface water specific humidity (g/kg)
+        Q, _ = qsat26air(T, P, RH)     # specific humidity of air (g/kg)
+        qair = Q/1000
+        del Q
+        logging.info('method %s | qsea:%s, qair:%s', meth,
+                     np.ma.median(qsea[~np.isnan(qsea)]),
+                     np.ma.median(qair[~np.isnan(qair)]))
     else:
-        qsea = qsea_calc(sst,P) 
-        qair = q_calc(Ta,RH,P) 
-        logging.info('method %s | qsea:%s, qair:%s',method,np.ma.median(qsea),np.ma.median(qair))
+        qsea = qsea_calc(sst, P)
+        qair = q_calc(Ta, RH, P)
+        logging.info('method %s | qsea:%s, qair:%s', meth,
+                     np.ma.median(qsea[~np.isnan(qsea)]),
+                     np.ma.median(qair[~np.isnan(qair)]))
     if (np.all(np.isnan(qsea)) or np.all(np.isnan(qair))):
-       print("qsea and qair cannot be nan")
-       logging.debug('method %s qsea and qair cannot be nan | sst:%s, Ta:%s, P:%s, RH:%s',method,np.ma.median(sst),np.ma.median(Ta),np.ma.median(P),np.ma.median(RH))
-   
+        print("qsea and qair cannot be nan")
+        logging.debug('method %s qsea and qair cannot be nan | sst:%s, Ta:%s,'
+                      'P:%s, RH:%s', meth, np.ma.median(sst[~np.isnan(sst)]),
+                      np.ma.median(Ta[~np.isnan(Ta)]),
+                      np.ma.median(P[~np.isnan(P)]),
+                      np.ma.median(RH[~np.isnan(RH)]))
     # first guesses
-    inan=np.where(np.isnan(spd+T+SST+lat+RH+P))
+    inan = np.where(np.isnan(spd+T+SST+lat+RH+P))
     t10n, q10n = np.copy(Ta), np.copy(qair)
     tv10n = t10n*(1 + 0.61*q10n)
     rho = (0.34838*P)/(tv10n)
-    rhoa = P*100/(287.1*(T+CtoK)*(1+0.61*qair)) # difference with rho is that it uses T instead of Ta (which includes lapse rate)
-    lv = (2.501-0.00237*(SST))*1e6
-    dt=sst-Ta
-    dq=qsea-qair
-    if (method == "COARE3.5"):
-        cp=1004.67 #cpa  = 1004.67, cpv  = cpa*(1+0.84*Q)  
+    rhoa = P*100/(287.1*(T+CtoK)*(1+0.61*qair))
+    lv = (2.501-0.00237*SST)*1e6
+    dt = sst - Ta
+    dq = qsea - qair
+    if (meth == "C35"):
+        cp = 1004.67  # cpa  = 1004.67, cpv  = cpa*(1+0.84*Q)
         wetc = 0.622*lv*qsea/(287.1*sst**2)
-        ug=0.5*np.ones(np.shape(spd))
-        wind=np.sqrt(np.copy(spd)**2+ug**2) 
-        dter=0.3*np.ones(np.shape(spd)) #cool skin temperature depression
-        dqer=wetc*dter
-        Rnl=0.97*(5.67e-8*(SST-dter*jcool+CtoK)**4-Rl)
-        u10=wind*np.log(10/1e-4)/np.log(hh_in[0]/1e-4)
+        ug = 0.5*np.ones(np.shape(spd))
+        wind = np.sqrt(np.copy(spd)**2+ug**2)
+        dter = 0.3*np.ones(np.shape(spd))  # cool skin temperature depression
+        dqer = wetc*dter
+        Rnl = 0.97*(5.67e-8*(SST-dter*jcool+CtoK)**4-Rl)
+        u10 = wind*np.log(10/1e-4)/np.log(hh_in[0]/1e-4)
         usr = 0.035*u10
-        u10n=np.copy(u10)
-        zo  = 0.011*usr**2/g + 0.11*visc_air(T)/usr
-        cdn  = (kappa/np.log(10/zo))**2
-        cqn  = 0.00115*np.ones(np.shape(spd))
-        ctn  = cqn/np.sqrt(cdn)
-        cd    = (kappa/np.log(hh_in[0]/zo))**2
-        ct    = kappa/np.log(hh_in[1]/10/np.exp(kappa/ctn))
-        CC    = kappa*ct/cd
+        u10n = np.copy(u10)
+        zo = 0.011*usr**2/g + 0.11*visc_air(T)/usr
+        cdn = (kappa/np.log(10/zo))**2
+        cqn = 0.00115*np.ones(np.shape(spd))
+        ctn = cqn/np.sqrt(cdn)
+        cd = (kappa/np.log(hh_in[0]/zo))**2
+        ct = kappa/np.log(hh_in[1]/10/np.exp(kappa/ctn))
+        CC = kappa*ct/cd
         Ribcu = -hh_in[0]/zi/0.004/1.2**3
-        Ribu  = -g*hh_in[0]/(T+CtoK)*((dt-dter*jcool)+0.61*(T+CtoK)*(dq))/wind**2        
-        zetu=np.where(Ribu<0,CC*Ribu/(1+Ribu/Ribcu),CC*Ribu*(1+27/9*Ribu/CC))
-        k50=np.where(zetu>50) # stable with very thin M-O length relative to zu
+        Ribu = (-g*hh_in[0]/(T+CtoK)*((dt-dter*jcool)+0.61*(T+CtoK)*(dq)) /
+                wind**2)
+        zetu = np.where(Ribu < 0, CC*Ribu/(1+Ribu/Ribcu),
+                        CC*Ribu*(1+27/9*Ribu/CC))
+        k50 = np.where(zetu > 50)  # stable, very thin M-O relative to zu
         monob = hh_in[0]/zetu
-        gf=wind/spd
+        gf = wind/spd
         usr = wind*kappa/(np.log(hh_in[0]/zo)-psiu_40(hh_in[0]/monob))
-        tsr = -(dt-dter*jcool)*kappa/(np.log(hh_in[1]/10/np.exp(kappa/ctn))-psit_26(hh_in[1]/monob))
-        qsr = -(dq-wetc*dter*jcool)*kappa/(np.log(hh_in[2]/10/np.exp(kappa/ctn))-psit_26(hh_in[2]/monob))
-        tsrv=tsr+0.61*(T+CtoK)*qsr
-        ac = np.zeros((len(spd),3))
+        tsr = (-(dt-dter*jcool)*kappa/(np.log(hh_in[1]/10/np.exp(kappa/ctn)) -
+               psit_26(hh_in[1]/monob)))
+        qsr = (-(dq-wetc*dter*jcool)*kappa/(np.log(hh_in[2]/10 /
+               np.exp(kappa/ctn))-psit_26(hh_in[2]/monob)))
+        tsrv = tsr+0.61*(T+CtoK)*qsr
+        ac = np.zeros((len(spd), 3))
         charn = 0.011*np.ones(np.shape(spd))
-        charn =np.where(wind>10,0.011+(wind-10)/(18-10)*(0.018-0.011),np.where(wind>18,0.018,0.011))
-        ac[:,0]=charn
+        charn = np.where(wind > 10, 0.011+(wind-10)/(18-10)*(0.018-0.011),
+                         np.where(wind > 18, 0.018, 0.011))
+        ac[:, 0] = charn
     else:
-        cp = 1004.67 * (1 + 0.00084*qsea) 
-        wind,u10n=np.copy(spd),np.copy(spd)
-        cdn = cdn_calc(u10n,Ta,None,method)
-        psim, psit, psiq = np.zeros(u10n.shape), np.zeros(u10n.shape), np.zeros(u10n.shape)
-        psim[inan], psit[inan], psiq[inan] = np.nan,np.nan,np.nan 
-        cd = cd_calc(cdn,hh_in[0],ref_ht,psim)
-        zo = 0.0001*np.ones(u10n.shape)
-        zo[inan]=np.nan
-        monob = -100*np.ones(u10n.shape) # Monin-Obukhov length
+        cp = 1004.67*(1 + 0.00084*qsea)
+        u10n = np.copy(spd)
+        monob = -100*np.ones(u10n.shape)  # Monin-Obukhov length
         monob[inan] = np.nan
+        cdn = cdn_calc(u10n, Ta, None, meth)
+        psim, psit, psiq = (np.zeros(u10n.shape), np.zeros(u10n.shape),
+                            np.zeros(u10n.shape))
+        psim[inan], psit[inan], psiq[inan] = np.nan, np.nan, np.nan
+        cd = cd_calc(cdn, hh_in[0], ref_ht, psim)
+        tsr, tsrv = np.zeros(u10n.shape), np.zeros(u10n.shape)
+        qsr = np.zeros(u10n.shape)
+        tsr[inan], tsrv[inan], qsr[inan] = np.nan, np.nan, np.nan
+        if (meth == "UA"):
+            wind = np.sqrt(np.power(np.copy(spd),2)+np.power(0.5,2))
+            zo, zot = 0.0001*np.ones(u10n.shape), 0.0001*np.ones(u10n.shape)
+            zol = hh_in[0]/monob
+        elif (meth == "ERA5"):
+            wind = np.sqrt(np.power(np.copy(spd),2)+np.power(0.5,2))
+            usr = np.sqrt(cd*wind**2)
+            Ribu = ((g*hh_in[0]*((2*(Ta-sst))/(Ta+sst-g*hh_in[0]) +
+                    0.61*(qair-qsea)))/np.power(wind, 2))
+            zo = 0.11*visc_air(Ta)/usr+0.018*np.power(usr, 2)/g
+            zot = 0.40*visc_air(Ta)/usr
+            zol = (Ribu*((np.log((hh_in[0]+zo)/zo)-psim_calc((hh_in[0]+zo) /
+                   monob, meth)+psim_calc(zo/monob, meth)) /
+                   (np.log((hh_in[0]+zo)/zot) -
+                   psit_calc((hh_in[0]+zo)/monob, meth) +
+                   psit_calc(zot/monob, meth))))
+        else:
+            wind = np.copy(spd)
+            zo = 0.0001*np.ones(u10n.shape)
+            zo[inan] = np.nan
         usr = np.sqrt(cd * wind**2)
-        tsr, tsrv, qsr = np.zeros(u10n.shape), np.zeros(u10n.shape), np.zeros(u10n.shape)
-        tsr[inan], tsrv[inan], qsr[inan] = np.nan, np.nan, np.nan    
-    tol =np.array([0.01,0.01,5e-05,0.005,0.001,5e-07]) # tolerance u,t,q,usr,tsr,qsr
+    # tolerance for u,t,q,usr,tsr,qsr
+    tol = np.array([0.01, 0.01, 5e-05, 0.005, 0.001, 5e-07])
     it = 0
-    ind=np.where(spd>0)
-    ii =True
-    itera=np.zeros(spd.shape)*np.nan
+    ind = np.where(spd > 0)
+    ii = True
+    itera = np.zeros(spd.shape)*np.nan
     while np.any(ii):
         it += 1
 #        print('iter: '+str(it)+', p: '+str(np.shape(ind)[1]))
-        if it>n:
-            break          
-        if (method == "COARE3.5"): 
-            ### This allows all iterations regardless of convergence as in original
-            zet=kappa*g*hh_in[0]/(T+CtoK)*(tsr +0.61*(T+CtoK)*qsr)/(usr**2)
-            monob=hh_in[0]/zet
-            zo,cd,ct,cq=cd_C35(u10n,wind,usr,ac[:,0],monob,(T+CtoK),hh_in,lat)
-            usr=wind*cd
-            qsr=-(dq-wetc*dter*jcool)*cq
-            tsr=-(dt-dter*jcool)*ct
-            tsrv=tsr+0.61*(T+CtoK)*qsr
-            ug = get_gust((T+CtoK),usr,tsrv,zi,lat) # gustiness
-            wind = np.sqrt(np.copy(spd)**2 + ug**2) 
-            gf=wind/spd
-            dter, dqer=get_skin(sst,qsea,rhoa,jcool,Rl,Rs,Rnl,cp,lv,usr,tsr,qsr,lat)
-            Rnl=0.97*(5.67e-8*(SST-dter*jcool+CtoK)**4-Rl)
-            if it==1: # save first iteration solution for case of zetu>50
-                usr50,tsr50,qsr50,L50=usr[k50],tsr[k50],qsr[k50],monob[k50]
-                dter50, dqer50=dter[k50], dqer[k50]
-            u10n = usr/kappa/gf*np.log(10/zo)
-            ac=charnock_C35(wind,u10n,usr,seastate,waveage,wcp,sigH,lat)
-            new=np.array([np.copy(u10n),np.copy(usr),np.copy(tsr),np.copy(qsr)])  
-            ### otherwise iterations stop when u,usr,tsr,qsr converge but gives different results than above option
-#            old=np.array([np.copy(u10n[ind]),np.copy(usr[ind]),np.copy(tsr[ind]),np.copy(qsr[ind])])
-#            zet=kappa*g[ind]*hh_in[0]/(T[ind]+CtoK)*(tsr[ind] +0.61*(T[ind]+CtoK)*qsr[ind])/(usr[ind]**2)
-#            monob[ind]=hh_in[0]/zet
-#            zo[ind],cd[ind],ct[ind],cq[ind]=cd_C35(u10n[ind],wind[ind],usr[ind],ac[ind,0],monob[ind],(T[ind]+CtoK),hh_in,lat[ind])
-#            usr[ind]=wind[ind]*cd[ind]
-#            qsr[ind]=-(dq[ind]-wetc[ind]*dter[ind]*jcool)*cq[ind]
-#            tsr[ind]=-(dt[ind]-dter[ind]*jcool)*ct[ind]
-#            tsrv[ind]=tsr[ind]+0.61*(T[ind]+CtoK)*qsr[ind]
-#            ug[ind] = get_gust((T[ind]+CtoK),usr[ind],tsrv[ind],zi,lat[ind]) # gustiness
-#            wind[ind] = np.sqrt(np.copy(spd[ind])**2 + ug[ind]**2) 
-#            gf=wind/spd
-#            dter[ind], dqer[ind]=get_skin(sst[ind],qsea[ind],rhoa[ind],jcool,Rl[ind],Rs[ind],Rnl[ind],cp,lv[ind],usr[ind],tsr[ind],qsr[ind],lat[ind])
-#            Rnl=0.97*(5.67e-8*(SST-dter*jcool+CtoK)**4-Rl)
-#            if it==1: # save first iteration solution for case of zetu>50
-#                usr50,tsr50,qsr50,L50=usr[k50],tsr[k50],qsr[k50],monob[k50]
-#                dter50, dqer50=dter[k50], dqer[k50]
-#            u10n[ind] = usr[ind]/kappa/gf[ind]*np.log(10/zo[ind])
-#            ac[ind][:]=charnock_C35(wind[ind],u10n[ind],usr[ind],seastate,waveage,wcp[ind],sigH[ind],lat[ind])
-#            new=np.array([np.copy(u10n[ind]),np.copy(usr[ind]),np.copy(tsr[ind]),np.copy(qsr[ind])])  
-#            print(str(it)+'L= '+str(monob),file=open('/noc/mpoc/surface_data/sbiri/SAMOS/C35_int.txt','a'))
-#            print(str(it)+'dter= '+str(dter),file=open('/noc/mpoc/surface_data/sbiri/SAMOS/C35_int.txt','a'))
-#            print(str(it)+'ac= '+str(ac[:,0]),file=open('/noc/mpoc/surface_data/sbiri/SAMOS/C35_int.txt','a'))    
-#            d=np.abs(new-old)
-#            ind=np.where((d[0,:]>tol[0])+(d[1,:]>tol[3])+(d[2,:]>tol[4])+(d[3,:]>tol[5]))
-#            itera[ind]=np.ones(1)*it
-#            if np.shape(ind)[0]==0:
-#               break
-#            else:
-#               ii = (d[0,:]>tol[0])+(d[1,:]>tol[3])+(d[2,:]>tol[4])+(d[3,:]>tol[5])
+        if it > n:
+            break
+        if (meth == "C35"):
+            old = np.array([np.copy(u10n[ind]), np.copy(usr[ind]),
+                           np.copy(tsr[ind]), np.copy(qsr[ind])])
+            zet = (kappa*g[ind]*hh_in[0]/(T[ind]+CtoK)*(tsr[ind]+0.61 *
+                   (T[ind]+CtoK)*qsr[ind])/(usr[ind]**2))
+            monob[ind] = hh_in[0]/zet
+            zo[ind], cd[ind], ct[ind], cq[ind] = cd_C35(u10n[ind], wind[ind],
+                                                        usr[ind], ac[ind,0],
+                                                        monob[ind],
+                                                        (T[ind]+CtoK), hh_in,
+                                                        lat[ind])
+            usr[ind] = wind[ind]*cd[ind]
+            qsr[ind] = -(dq[ind]-wetc[ind]*dter[ind]*jcool)*cq[ind]
+            tsr[ind] = -(dt[ind]-dter[ind]*jcool)*ct[ind]
+            tsrv[ind] = tsr[ind]+0.61*(T[ind]+CtoK)*qsr[ind]
+            ug[ind] = get_gust(1.2, (T[ind]+CtoK), usr[ind], tsrv[ind],
+                               zi, lat[ind])  # gustiness
+            wind[ind] = np.sqrt(np.copy(spd[ind])**2 + ug[ind]**2)
+            gf = wind/spd
+            dter[ind], dqer[ind] = get_skin(sst[ind], qsea[ind], rhoa[ind],
+                                            Rl[ind], Rs[ind], Rnl[ind], cp,
+                                            lv[ind], usr[ind], tsr[ind],
+                                            qsr[ind], lat[ind])
+            Rnl = 0.97*(5.67e-8*(SST-dter*jcool+CtoK)**4-Rl)
+            if it == 1:  # save first iteration solution for case of zetu>50
+                usr50, tsr50, qsr50, L50 = (usr[k50], tsr[k50], qsr[k50],
+                                            monob[k50])
+                dter50, dqer50 = dter[k50], dqer[k50]
+            u10n[ind] = usr[ind]/kappa/gf[ind]*np.log(10/zo[ind])
+            ac[ind][:] = charnock_C35(wind[ind], u10n[ind], usr[ind], seastate,
+                                      waveage, wcp[ind], sigH[ind], lat[ind])
+            new = np.array([np.copy(u10n[ind]), np.copy(usr[ind]),
+                           np.copy(tsr[ind]), np.copy(qsr[ind])])
+            d = np.abs(new-old)
+            ind = np.where((d[0,:] > tol[0])+(d[1,:] > tol[3]) +
+                           (d[2,:] > tol[4])+(d[3,:] > tol[5]))
+            itera[ind] = np.ones(1)*it
+            if np.shape(ind)[0] == 0:
+               break
+            else:
+               ii = ((d[0,:] > tol[0])+(d[1,:] > tol[3])+(d[2,:] > tol[4]) +
+                     (d[3,:] > tol[5]))
         else:
-            old=np.array([np.copy(u10n[ind]),np.copy(t10n[ind]),np.copy(q10n[ind]),np.copy(usr[ind]),np.copy(tsr[ind]),np.copy(qsr[ind])])
-            cdn[ind] = cdn_calc(u10n[ind],Ta[ind],None,method)
+            old = np.array([np.copy(u10n[ind]), np.copy(t10n[ind]),
+                           np.copy(q10n[ind]), np.copy(usr[ind]),
+                           np.copy(tsr[ind]), np.copy(qsr[ind])])
+            cdn[ind] = cdn_calc(u10n[ind], Ta[ind], None, meth)
             if (np.all(np.isnan(cdn))):
-              break #sys.exit("cdn cannot be nan")  
-              logging.debug('%s at iteration %s cdn negative',method,it)
+                break  # sys.exit("cdn cannot be nan")
+                logging.debug('break %s at iteration %s cdn<0', meth, it)
             zo[ind] = ref_ht/np.exp(kappa/np.sqrt(cdn[ind]))
-            psim[ind] = psim_calc(hh_in[0]/monob[ind],method)
+            psim[ind] = psim_calc(hh_in[0]/monob[ind], meth)
             cd[ind] = cd_calc(cdn[ind], hh_in[0], ref_ht, psim[ind])
-            ctn[ind], cqn[ind] = ctcqn_calc(hh_in[1]/monob[ind],cdn[ind],u10n[ind],zo[ind],Ta[ind],method)
-            psit[ind] = psit_calc(hh_in[1]/monob[ind],method)
-            psiq[ind] = psit_calc(hh_in[2]/monob[ind],method)
-            ct[ind], cq[ind] = ctcq_calc(cdn[ind], cd[ind], ctn[ind], cqn[ind], hh_in[1], hh_in[2], ref_ht, psit[ind], psiq[ind])
-            usr[ind] = np.sqrt(cd[ind]*wind[ind]**2)        
+            ctn[ind], cqn[ind] = ctcqn_calc(hh_in[1]/monob[ind], cdn[ind],
+                                            u10n[ind], zo[ind], Ta[ind], meth)
+            psit[ind] = psit_calc(hh_in[1]/monob[ind], meth)
+            psiq[ind] = psit_calc(hh_in[2]/monob[ind], meth)
+            ct[ind], cq[ind] = ctcq_calc(cdn[ind], cd[ind], ctn[ind], cqn[ind],
+                                         hh_in[1], hh_in[2], ref_ht,
+                                         psit[ind], psiq[ind])
+            usr[ind] = np.sqrt(cd[ind]*wind[ind]**2)
             tsr[ind] = ct[ind]*wind[ind]*(-dt[ind])/usr[ind]
             qsr[ind] = cq[ind]*wind[ind]*(-dq[ind])/usr[ind]
-            fact = (np.log(hh_in[1]/ref_ht)-psit[ind])/kappa
-            t10n[ind] = Ta[ind] - (tsr[ind]*fact)
-            fact = (np.log(hh_in[2]/ref_ht)-psiq[ind])/kappa
-            q10n[ind] = qair[ind] - (qsr[ind]*fact)
+            if (meth == "UA"):
+                zot[ind] = 10/(np.exp(kappa**2/(ctn[ind]*np.log(10/zo[ind]))))
+                zol[ind] = hh_in[0]/monob[ind]
+                t10n[ind] = np.where(zol[ind]<-0.465,Ta[ind]-(tsr[ind]/kappa) *
+                                     (np.log((-0.465*monob[ind])/zot[ind]) -
+                                     psit_calc(-0.465,meth)+0.8 *
+                                     (np.power(0.465,-1/3) -
+                                     np.power(-zol[ind],-1/3))), \
+                                     np.where((zol[ind]>-0.465) & (zol[ind]<0),
+                                     Ta[ind]-(tsr[ind]/kappa) *
+                                     (np.log(hh_in[1]/zot[ind]) -
+                                     psit_calc(zol[ind],meth)), \
+                                     np.where((zol[ind]>0) & (zol[ind]<1),
+                                     Ta[ind]-(tsr[ind]/kappa) *
+                                     (np.log(hh_in[1]/zot[ind])+5*monob[ind]),
+                                     Ta[ind]-(tsr[ind]/kappa) *
+                                     (np.log(monob[ind]/zot[ind])+5 +
+                                     5*np.log(monob[ind])+monob[ind]-1))))
+                                     # Zeng et al. 1998 (11-14)
+                q10n[ind] = np.where(zol[ind]<-0.465,qair[ind] -
+                                     (qsr[ind]/kappa) *
+                                     (np.log((-0.465*monob[ind])/zot[ind]) -
+                                     psit_calc(-0.465,meth)+0.8 *
+                                     (np.power(0.465,-1/3) -
+                                     np.power(-zol[ind],-1/3))), \
+                                     np.where((zol[ind]>-0.465) & (zol[ind]<0),
+                                     qair[ind]-(qsr[ind]/kappa) *
+                                     (np.log(hh_in[1]/zot[ind]) -
+                                     psit_calc(zol[ind],meth)), \
+                                     np.where((zol[ind]>0) & (zol[ind]<1), \
+                                     qair[ind]-(qsr[ind]/kappa) *
+                                     (np.log(hh_in[1]/zot[ind])+5*monob[ind]),
+                                     qair[ind]-(qsr[ind]/kappa) *
+                                     (np.log(monob[ind]/zot[ind])+5 +
+                                     5*np.log(monob[ind])+monob[ind]-1))))
+            else:
+                fact = (np.log(hh_in[1]/ref_ht)-psit[ind])/kappa
+                t10n[ind] = Ta[ind] - (tsr[ind]*fact)
+                fact = (np.log(hh_in[2]/ref_ht)-psiq[ind])/kappa
+                q10n[ind] = qair[ind] - (qsr[ind]*fact)
             tv10n[ind] = t10n[ind]*(1+0.61*q10n[ind])
             tsrv[ind] = tsr[ind]+0.61*t10n[ind]*qsr[ind]
-            monob[ind] = (tv10n[ind]*usr[ind]**2)/(g[ind]*kappa*tsrv[ind])  
-            psim[ind] = psim_calc(hh_in[0]/monob[ind],method)
-            psit[ind] = psit_calc(hh_in[1]/monob[ind],method)
-            psiq[ind] = psit_calc(hh_in[2]/monob[ind],method)
-            u10n[ind] = wind[ind] -(usr[ind]/kappa)*(np.log(hh_in[0]/ref_ht)-psim[ind])
-            u10n[u10n<0]=np.nan # 0.5*old[0,np.where(u10n<0)]
-            new=np.array([np.copy(u10n[ind]),np.copy(t10n[ind]),np.copy(q10n[ind]),np.copy(usr[ind]),np.copy(tsr[ind]),np.copy(qsr[ind])])        
-            d=np.abs(new-old)
-            ind=np.where((d[0,:]>tol[0])+(d[1,:]>tol[1])+(d[2,:]>tol[2])+(d[3,:]>tol[3])+(d[4,:]>tol[4])+(d[5,:]>tol[5]))
-            itera[ind]=np.ones(1)*it
-            if np.shape(ind)[0]==0:
-               break
+            if (meth == "ERA5"):
+                zol[ind] = (kappa*g[ind]*hh_in[0]/Ta[ind]*(tsr[ind] +
+                        0.61*Ta[ind]*qsr[ind])/(usr[ind]**2))
+                monob[ind] = hh_in[0]/zol[ind]
+            else:
+                monob[ind] = (tv10n[ind]*usr[ind]**2)/(g[ind]*kappa*tsrv[ind])
+            psim[ind] = psim_calc(hh_in[0]/monob[ind], meth)
+            psit[ind] = psit_calc(hh_in[1]/monob[ind], meth)
+            psiq[ind] = psit_calc(hh_in[2]/monob[ind], meth)
+            if (meth == "UA"):
+                u10n[ind] = np.where(zol[ind]<-1.574,(usr[ind]/kappa) *
+                                     ((np.log(-1.574*monob[ind]/zo[ind]) -
+                                     psim_calc(-1.574,meth))+1.14 *
+                                     (np.power(-monob[ind],1/3) -
+                                     np.power(1.574,1/3))), \
+                                     np.where((zol[ind]>-1.574) & (zol[ind]<0),
+                                     (usr[ind]/kappa)*(np.log(ref_ht/zo[ind]) -
+                                     psim_calc(zol[ind])), \
+                                     np.where((zol[ind]>0) & (zol[ind]<1),
+                                     (usr[ind]/kappa)*(np.log(ref_ht/zo[ind]) +
+                                     5*zol[ind]),(usr[ind]/kappa) *
+                                     (np.log(monob[ind]/zo[ind])+5 +
+                                     5*np.log(zol[ind])+zol[ind]-1))))
+                                     # Zeng et al. 1998 (7-10)
+                u10n[u10n<0] = np.nan
+                wind[ind] = np.sqrt(np.power(np.copy(spd[ind]),2) +
+                                    np.power(get_gust(1,Ta[ind], usr[ind],
+                                    tsrv[ind],zi,lat[ind]),2))
+                                    # Zeng et al. 1998 (20)
+            elif (meth == "ERA5"):
+                wind[ind] = np.sqrt(np.copy(spd[ind])**2 +
+                                    (get_gust(1, Ta[ind], usr[ind], tsrv[ind],
+                                    zi, lat[ind]))**2)
+                u10n[ind] = (wind[ind]-(usr[ind]/kappa)*(np.log(hh_in[0] /
+                             ref_ht)-psim[ind]))
+                u10n[u10n < 0] = np.nan
             else:
-               ii = (d[0,ind]>tol[0])+(d[1,ind]>tol[1])+(d[2,ind]>tol[2])+(d[3,ind]>tol[3])+(d[4,ind]>tol[4])+(d[5,ind]>tol[5])
-   
+                u10n[ind] = (wind[ind]-(usr[ind]/kappa)*(np.log(hh_in[0] /
+                             ref_ht)-psim[ind]))
+                u10n[u10n < 0] = np.nan  # 0.5*old[0,np.where(u10n<0)]
+            new = np.array([np.copy(u10n[ind]), np.copy(t10n[ind]),
+                           np.copy(q10n[ind]), np.copy(usr[ind]),
+                           np.copy(tsr[ind]), np.copy(qsr[ind])])
+            d = np.abs(new-old)
+            ind = np.where((d[0, :] > tol[0])+(d[1, :] > tol[1]) +
+                           (d[2, :] > tol[2])+(d[3, :] > tol[3]) +
+                           (d[4, :] > tol[4])+(d[5, :] > tol[5]))
+            itera[ind] = np.ones(1)*it
+            if np.shape(ind)[0] == 0:
+                break
+            else:
+                ii = ((d[0, ind] > tol[0])+(d[1, ind] > tol[1]) +
+                      (d[2, ind] > tol[2])+(d[3, ind] > tol[3]) +
+                      (d[4, ind] > tol[4])+(d[5, ind] > tol[5]))
+
     # calculate output parameters
-    if (method == "COARE3.5"):
-        usr[k50],tsr[k50],qsr[k50],monob[k50]=usr50,tsr50,qsr50,L50
-        dter[k50], dqer[k50]=dter50, dqer50
+    if (meth == "C35"):
+        usr[k50], tsr[k50], qsr[k50], monob[k50] = usr50, tsr50, qsr50, L50
+        dter[k50], dqer[k50] = dter50, dqer50
         rhoa = P*100/(287.1*(T+CtoK)*(1+0.61*qair))
-        rr=zo*usr/visc_air(T+CtoK)
-        zoq=np.where(5.8e-5/rr**0.72>1.6e-4,1.6e-4,5.8e-5/rr**0.72)
-        zot=zoq 
-        psiT=psit_26(hh_in[1]/monob)
-        psi10T=psit_26(10/monob)
-        psi=psiu_26(hh_in[0]/monob)
-        psirf=psiu_26(hh_out[0]/monob)
+        rr = zo*usr/visc_air(T+CtoK)
+        zoq = np.where(5.8e-5/rr**0.72 > 1.6e-4, 1.6e-4, 5.8e-5/rr**0.72)
+        zot = zoq
+        psiT = psit_26(hh_in[1]/monob)
+        psi10T = psit_26(10/monob)
+        psi = psiu_26(hh_in[0]/monob)
+        psirf = psiu_26(hh_out[0]/monob)
         q10 = qair + qsr/kappa*(np.log(10/hh_in[2])-psi10T+psiT)
         tau = rhoa*usr*usr/gf
-        sensible=-rhoa*cp*usr*tsr
-        latent=-rhoa*lv*usr*qsr
-        cd = tau/rhoa/wind/np.where(spd<0.1,0.1,spd)
+        sensible = -rhoa*cp*usr*tsr
+        latent = -rhoa*lv*usr*qsr
+        cd = tau/rhoa/wind/np.where(spd < 0.1, 0.1, spd)
         cdn = 1000*kappa**2/np.log(10/zo)**2
         ct = -usr*tsr/wind/(dt-dter*jcool)
         ctn = 1000*kappa**2/np.log(10/zo)/np.log(10/zot)
@@ -267,12 +435,15 @@ def flux_calc_v3(spd, T, SST, lat, RH, P, hin, hout, wcp, sigH, zi = 600, \
         psim = psiu_26(hh_in[0]/monob)
         psit = psit_26(hh_in[1]/monob)
         u10n = u10+psiu_26(10/monob)*usr/kappa/gf
-        t10n = T + tsr/kappa*(np.log(10/hh_in[1])-psi10T+psiT) + tlapse*(hh_in[1]-10)+ psi10T*tsr/kappa
+        t10n = (T+tsr/kappa*(np.log(10/hh_in[1])-psi10T+psiT) +
+                tlapse*(hh_in[1]-10)+psi10T*tsr/kappa)
         q10n = q10 + psi10T*qsr/kappa
         tv10n = t10n*(1+0.61*q10n)
         urefs = spd + usr/kappa/gf*(np.log(hh_out[0]/hh_in[0])-psirf+psi)
-        trefs =T + tsr/kappa*(np.log(hh_out[1]/hh_in[1])-psit_26(hh_out[1]/monob)+psiT) + tlapse*(hh_in[1]-hh_out[1])
-        qrefs= qair + qsr/kappa*(np.log(hh_out[2]/hh_in[2])-psit_26(hh_out[2]/monob)+psiT)
+        trefs = (T+tsr/kappa*(np.log(hh_out[1]/hh_in[1]) -
+                 psit_26(hh_out[1]/monob)+psiT)+tlapse*(hh_in[1]-hh_out[1]))
+        qrefs = (qair+qsr/kappa*(np.log(hh_out[2]/hh_in[2]) -
+                 psit_26(hh_out[2]/monob)+psiT))
     else:
         rho = (0.34838*P)/(tv10n)
         t10n = t10n-(273.16+tlapse*ref_ht)
@@ -282,59 +453,39 @@ def flux_calc_v3(spd, T, SST, lat, RH, P, hin, hout, wcp, sigH, zi = 600, \
         zo = ref_ht/np.exp(kappa/cdn**0.5)
         zot = ref_ht/(np.exp(kappa**2/(ctn*np.log(ref_ht/zo))))
         zoq = ref_ht/(np.exp(kappa**2/(cqn*np.log(ref_ht/zo))))
-        urefs=spd-(usr/kappa)*(np.log(hh_in[0]/hh_out[0])-psim+psim_calc(hh_out[0]/monob,method))
-        trefs=Ta-(tsr/kappa)*(np.log(hh_in[1]/hh_out[1])-psit+psit_calc(hh_out[0]/monob,method))
+        urefs = (spd-(usr/kappa)*(np.log(hh_in[0]/hh_out[0])-psim +
+                 psim_calc(hh_out[0]/monob, meth)))
+        trefs = (Ta-(tsr/kappa)*(np.log(hh_in[1]/hh_out[1])-psit +
+                 psit_calc(hh_out[0]/monob, meth)))
         trefs = trefs-(273.16+tlapse*hh_out[1])
-        qrefs=qair-(qsr/kappa)*(np.log(hh_in[2]/hh_out[2])-psit+psit_calc(hh_out[2]/monob,method))        
-    res=np.zeros((27,len(spd)))
-    res[0][:]=tau
-    res[1][:]=sensible
-    res[2][:]=latent    
-    res[3][:]=monob
-    res[4][:]=cd
-    res[5][:]=cdn
-    res[6][:]=ct
-    res[7][:]=ctn
-    res[8][:]=cq
-    res[9][:]=cqn
-    res[10][:]=tsrv
-    res[11][:]=tsr
-    res[12][:]=qsr
-    res[13][:]=usr
-    res[14][:]=psim
-    res[15][:]=psit
-    res[16][:]=u10n
-    res[17][:]=t10n
-    res[18][:]=tv10n
-    res[19][:]=q10n
-    res[20][:]=zo
-    res[21][:]=zot
-    res[22][:]=zoq
-    res[23][:]=urefs
-    res[24][:]=trefs
-    res[25][:]=qrefs
-    res[26][:]=itera
+        qrefs = (qair-(qsr/kappa)*(np.log(hh_in[2]/hh_out[2]) -
+                 psit+psit_calc(hh_out[2]/monob, meth)))
+    res = np.zeros((27, len(spd)))
+    res[0][:] = tau
+    res[1][:] = sensible
+    res[2][:] = latent
+    res[3][:] = monob
+    res[4][:] = cd
+    res[5][:] = cdn
+    res[6][:] = ct
+    res[7][:] = ctn
+    res[8][:] = cq
+    res[9][:] = cqn
+    res[10][:] = tsrv
+    res[11][:] = tsr
+    res[12][:] = qsr
+    res[13][:] = usr
+    res[14][:] = psim
+    res[15][:] = psit
+    res[16][:] = u10n
+    res[17][:] = t10n
+    res[18][:] = tv10n
+    res[19][:] = q10n
+    res[20][:] = zo
+    res[21][:] = zot
+    res[22][:] = zoq
+    res[23][:] = urefs
+    res[24][:] = trefs
+    res[25][:] = qrefs
+    res[26][:] = itera
     return res, ind
-          
-def charnock_C35(wind,u10n,usr,seastate,waveage,wcp,sigH,lat):
-    g=gc(lat,None)
-    a1, a2=0.0017, -0.0050    
-    charnC=np.where(u10n>19,a1*19+a2,a1*u10n+a2)
-    A, B=0.114, 0.622  #wave-age dependent coefficients
-    Ad, Bd=0.091, 2.0  #Sea-state/wave-age dependent coefficients
-    charnW=A*(usr/wcp)**B
-    zoS=sigH*Ad*(usr/wcp)**Bd
-    charnS=(zoS*g)/usr**2    
-    charn=np.where(wind>10,0.011+(wind-10)/(18-10)*(0.018-0.011),np.where(wind>18,0.018,0.011*np.ones(np.shape(wind))))
-    if waveage:
-        if seastate:
-            charn=charnS
-        else:
-            charn=charnW
-    else:
-        charn=charnC
-    ac = np.zeros((len(wind),3))
-    ac[:,0] = charn
-    ac[:,1] = charnC
-    ac[:,2] = charnW
-    return ac
\ No newline at end of file
diff --git a/flux_subs.py b/flux_subs.py
index adc074d198d3b319ac484458aa737e628575e9e5..94dc9f543cd1f0c56d10b4d7b45b236a1898e2df 100755
--- a/flux_subs.py
+++ b/flux_subs.py
@@ -1,13 +1,41 @@
 import numpy as np
 
-""" Conversion factor for [:math:`^\\circ` C] to [:math:`^\\circ` K] """
 CtoK = 273.16  # 273.15
-""" von Karman's constant """
+""" Conversion factor for (^\circ\,C) to (^\\circ\\,K) """
+
 kappa = 0.4  # NOTE: 0.41
+""" von Karman's constant """
 # ---------------------------------------------------------------------
 
 
 def charnock_C35(wind, u10n, usr, seastate, waveage, wcp, sigH, lat):
+    """ Calculates Charnock number following Edson et al. 2013 based on 
+    C35 matlab code (coare35vn.m)
+    
+    Parameters
+    ----------
+    wind : float
+        wind speed (m/s)
+    u10n : float
+        neutral 10m wind speed (m/s)
+    usr  : float
+        friction velocity (m/s)
+    seastate : bool
+        0 or 1
+    waveage  : bool
+        0 or 1
+    wcp      : float
+        phase speed of dominant waves (m/s)
+    sigH     : float
+        significant wave height (m)
+    lat      : float
+        latitude (deg)
+    
+    Returns
+    -------
+    ac : float
+        Charnock number
+    """
     g = gc(lat, None)
     a1, a2 = 0.0017, -0.0050
     charnC = np.where(u10n > 19, a1*19+a2, a1*u10n+a2)
@@ -34,6 +62,37 @@ def charnock_C35(wind, u10n, usr, seastate, waveage, wcp, sigH, lat):
 
 
 def cd_C35(u10n, wind, usr, charn, monob, Ta, hh_in, lat):
+    """ Calculates exchange coefficients following Edson et al. 2013 based on 
+    C35 matlab code (coare35vn.m)
+    
+    Parameters
+    ----------
+    u10n : float
+        neutral 10m wind speed (m/s)
+    wind : float
+        wind speed (m/s)    
+    charn : float
+        Charnock number
+    monob : float
+        Monin-Obukhov stability length
+    Ta    : float
+        air temperature (K)
+    hh_in : float
+        input sensor's height (m)
+    lat      : float
+        latitude (deg)
+    
+    Returns
+    -------
+    zo : float
+        surface roughness (m)
+    cdhf : float
+        drag coefficient
+    cthf : float
+        heat exchange coefficient
+    cqhf : float
+        moisture exchange coefficient
+    """
     g = gc(lat, None)
     zo = charn*usr**2/g+0.11*visc_air(Ta)/usr  # surface roughness
     rr = zo*usr/visc_air(Ta)
@@ -47,15 +106,31 @@ def cd_C35(u10n, wind, usr, charn, monob, Ta, hh_in, lat):
 # ---------------------------------------------------------------------
 
 
-def cdn_calc(u10n, Ta, Tp, method="Smith80"):
-    if (method == "Smith80"):
+def cdn_calc(u10n, Ta, Tp, method="S80"):
+    """ Calculates neutral drag coefficient
+    
+    Parameters
+    ----------
+    u10n : float
+        neutral 10m wind speed (m/s)
+    Ta   : float
+        air temperature (K)
+    Tp   : float
+        wave period
+    method : str
+    
+    Returns
+    -------
+    cdn : float
+    """
+    if (method == "S80"):
         cdn = np.where(u10n <= 3, (0.61+0.567/u10n)*0.001,
                        (0.61+0.063*u10n)*0.001)
     elif (method == "LP82"):
         cdn = np.where((u10n < 11) & (u10n >= 4), 1.2*0.001,
                        np.where((u10n <= 25) & (u10n >= 11),
                        (0.49+0.065*u10n)*0.001, 1.14*0.001))
-    elif (method == "Smith88" or method == "COARE3.0" or
+    elif (method == "S88" or method == "C30" or
           method == "COARE4.0" or method == "UA" or method == "ERA5"):
         cdn = cdn_from_roughness(u10n, Ta, None, method)
     elif (method == "HEXOS"):
@@ -64,7 +139,7 @@ def cdn_calc(u10n, Ta, Tp, method="Smith80"):
     elif (method == "HEXOSwave"):
         cdn = cdn_from_roughness(u10n, Ta, Tp, method)
     elif (method == "YT96"):
-        # for u<3 same as Smith80
+        # for u<3 same as S80
         cdn = np.where((u10n < 6) & (u10n >= 3),
                        (0.29+3.1/u10n+7.7/u10n**2)*0.001,
                        np.where((u10n <= 26) & (u10n >= 6),
@@ -78,7 +153,23 @@ def cdn_calc(u10n, Ta, Tp, method="Smith80"):
 # ---------------------------------------------------------------------
 
 
-def cdn_from_roughness(u10n, Ta, Tp, method="Smith88"):
+def cdn_from_roughness(u10n, Ta, Tp, method="S88"):
+    """ Calculates neutral drag coefficient from roughness length
+    
+    Parameters
+    ----------
+    u10n : float
+        neutral 10m wind speed (m/s)
+    Ta   : float
+        air temperature (K)
+    Tp   : float
+        wave period
+    method : str
+    
+    Returns
+    -------
+    cdn : float
+    """
     g, tol = 9.812, 0.000001
     cdn, usr = np.zeros(Ta.shape), np.zeros(Ta.shape)
     cdnn = (0.61+0.063*u10n)*0.001
@@ -86,13 +177,13 @@ def cdn_from_roughness(u10n, Ta, Tp, method="Smith88"):
     for it in range(5):
         cdn = np.copy(cdnn)
         usr = np.sqrt(cdn*u10n**2)
-        if (method == "Smith88"):
+        if (method == "S88"):
             # .....Charnock roughness length (equn 4 in Smith 88)
             zc = 0.011*np.power(usr, 2)/g
             # .....smooth surface roughness length (equn 6 in Smith 88)
             zs = 0.11*visc_air(Ta)/usr
             zo = zc + zs  # .....equns 7 & 8 in Smith 88 to calculate new CDN
-        elif (method == "COARE3.0"):
+        elif (method == "C30"):
             zc = 0.011 + (u10n-10)/(18-10)*(0.018-0.011)
             zc = np.where(u10n < 10, 0.011, np.where(u10n > 18, 0.018, zc))
             zs = 0.11*visc_air(Ta)/usr
@@ -116,9 +207,32 @@ def cdn_from_roughness(u10n, Ta, Tp, method="Smith88"):
 # ---------------------------------------------------------------------
 
 
-def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="Smith80"):
-    if (method == "Smith80" or method == "Smith88" or method == "YT96"):
-        cqn = np.ones(Ta.shape)*1.20*0.001  # from Smith88
+def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="S80"):
+    """ Calculates neutral heat and moisture exchange coefficients
+    
+    Parameters
+    ----------
+    zol  : float
+        height over MO length
+    cdn  : float
+        neatral drag coefficient
+    u10n : float
+        neutral 10m wind speed (m/s)
+    zo   : float
+        surface roughness (m)
+    Ta   : float
+        air temperature (K)
+    method : str
+    
+    Returns
+    -------
+    ctn : float
+        neutral heat exchange coefficient
+    cqn : float
+        neutral moisture exchange coefficient
+    """
+    if (method == "S80" or method == "S88" or method == "YT96"):
+        cqn = np.ones(Ta.shape)*1.20*0.001  # from S88
         ctn = np.ones(Ta.shape)*1.00*0.001
     elif (method == "LP82"):
         cqn = np.where((zol <= 0) & (u10n > 4) & (u10n < 14), 1.15*0.001,
@@ -128,7 +242,7 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="Smith80"):
     elif (method == "HEXOS" or method == "HEXOSwave"):
         cqn = np.where((u10n <= 23) & (u10n >= 3), 1.1*0.001, np.nan)
         ctn = np.where((u10n <= 18) & (u10n >= 3), 1.1*0.001, np.nan)
-    elif (method == "COARE3.0" or method == "COARE4.0"):
+    elif (method == "C30" or method == "COARE4.0"):
         usr = (cdn*u10n**2)**0.5
         rr = zo*usr/visc_air(Ta)
         zoq = 5.5e-5/rr**0.6
@@ -162,6 +276,23 @@ def ctcqn_calc(zol, cdn, u10n, zo, Ta, method="Smith80"):
 
 
 def cd_calc(cdn, height, ref_ht, psim):
+    """ Calculates drag coefficient at reference height
+    
+    Parameters
+    ----------
+    cdn : float
+        neutral drag coefficient
+    height : float
+        original sensor height (m)
+    ref_ht : float
+        reference height (m)
+    psim : float
+        momentum stability function
+    
+    Returns
+    -------
+    cd : float
+    """
     cd = (cdn*np.power(1+np.sqrt(cdn)*np.power(kappa, -1) *
           (np.log(height/ref_ht)-psim), -2))
     return cd
@@ -169,16 +300,56 @@ def cd_calc(cdn, height, ref_ht, psim):
 
 
 def ctcq_calc(cdn, cd, ctn, cqn, h_t, h_q, ref_ht, psit, psiq):
+    """ Calculates heat and moisture exchange coefficients at reference height
+    
+    Parameters
+    ----------
+    cdn : float
+        neutral drag coefficient
+    cd  : float
+        drag coefficient at reference height
+    ctn : float
+        neutral heat exchange coefficient
+    cqn : float
+        neutral moisture exchange coefficient
+    h_t : float
+        original temperature sensor height (m)
+    h_q : float
+        original moisture sensor height (m)
+    ref_ht : float
+        reference height (m)
+    psit : float
+        heat stability function
+    psiq : float
+        moisture stability function
+    
+    Returns
+    -------
+    ct : float
+    cq : float
+    """
     ct = ctn*(cd/cdn)**0.5/(1+ctn*((np.log(h_t/ref_ht)-psit)/(kappa*cdn**0.5)))
     cq = cqn*(cd/cdn)**0.5/(1+cqn*((np.log(h_q/ref_ht)-psiq)/(kappa*cdn**0.5)))
     return ct, cq
 # ---------------------------------------------------------------------
 
 
-def psim_calc(zol, method="Smith80"):
+def psim_calc(zol, method="S80"):
+    """ Calculates momentum stability function
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    method : str
+    
+    Returns
+    -------
+    psim : float
+    """
     coeffs = get_stabco(method)
     alpha, beta, gamma = coeffs[0], coeffs[1], coeffs[2]
-    if (method == "COARE3.0" or method == "COARE4.0"):
+    if (method == "C30" or method == "COARE4.0"):
         psim = np.where(zol < 0, psim_conv_coare3(zol, alpha, beta, gamma),
                         psim_stab_coare3(zol, alpha, beta, gamma))
     elif (method == "ERA5"):
@@ -191,10 +362,22 @@ def psim_calc(zol, method="Smith80"):
 # ---------------------------------------------------------------------
 
 
-def psit_calc(zol, method="Smith80"):
+def psit_calc(zol, method="S80"):
+    """ Calculates heat stability function
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    method : str
+    
+    Returns
+    -------
+    psit : float
+    """
     coeffs = get_stabco(method)
     alpha, beta, gamma = coeffs[0], coeffs[1], coeffs[2]
-    if (method == "COARE3.0" or method == "COARE4.0"):
+    if (method == "C30" or method == "COARE4.0"):
         psit = np.where(zol < 0, psi_conv_coare3(zol, alpha, beta, gamma),
                         psi_stab_coare3(zol, alpha, beta, gamma))
     elif (method == "ERA5"):
@@ -207,8 +390,18 @@ def psit_calc(zol, method="Smith80"):
 # ---------------------------------------------------------------------
 
 
-def get_stabco(method="Smith80"):
-    if (method == "Smith80" or method == "Smith88" or method == "LY04" or
+def get_stabco(method="S80"):
+    """ Gives the coefficients \\alpha, \\beta, \\gamma for stability functions
+    
+    Parameters
+    ----------
+    method : str
+    
+    Returns
+    -------
+    coeffs : float
+    """
+    if (method == "S80" or method == "S88" or method == "LY04" or
             method == "UA" or method == "ERA5"):
         alpha, beta, gamma = 16, 0.25, 5  # Smith 1980, from Dyer (1974)
     elif (method == "LP82"):
@@ -217,7 +410,7 @@ def get_stabco(method="Smith80"):
         alpha, beta, gamma = 16, 0.25, 8
     elif (method == "YT96"):
         alpha, beta, gamma = 20, 0.25, 5
-    elif (method == "COARE3.0" or method == "COARE4.0"):
+    elif (method == "C30" or method == "COARE4.0"):
         # use separate subroutine
         alpha, beta, gamma = 15, 1/3, 5   # not sure about gamma=34.15
     else:
@@ -231,6 +424,22 @@ def get_stabco(method="Smith80"):
 
 
 def psi_conv_coare3(zol, alpha, beta, gamma):
+    """ Calculates heat stability function for unstable conditions 
+        for method C30
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha : float
+    beta : float
+    gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psit : float
+    """
     x = (1-alpha*zol)**0.5  # Kansas unstable
     psik = 2*np.log((1+x)/2.)
     y = (1-34.15*zol)**beta
@@ -242,7 +451,21 @@ def psi_conv_coare3(zol, alpha, beta, gamma):
 # ---------------------------------------------------------------------
 
 
-def psi_stab_coare3(zol, alpha, beta, gamma):  # Stable
+def psi_stab_coare3(zol, alpha, beta, gamma):
+    """ Calculates heat stability function for stable conditions 
+        for method C30
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psi : float
+    """
     c = np.where(0.35*zol > 50, 50, 0.35*zol)  # Stable
     psit = -((1+2*zol/3)**1.5+0.6667*(zol-14.28)/np.exp(c)+8.525)
     return psit
@@ -250,6 +473,20 @@ def psi_stab_coare3(zol, alpha, beta, gamma):  # Stable
 
 
 def psi_stab_era5(zol, alpha, beta, gamma):
+    """ Calculates heat stability function for stable conditions 
+        for method ERA5
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psit : float
+    """
     # eq (3.22) p. 39 IFS Documentation cy46r1
     a, b, c, d = 1, 2/3, 5, 0.35
     psit = -b*(zol-c/d)*np.exp(-d*zol)-np.power(1+(2/3)*a*zol, 1.5)-(b*c)/d+1
@@ -257,6 +494,19 @@ def psi_stab_era5(zol, alpha, beta, gamma):
 # ---------------------------------------------------------------------
 
 def psi_conv(zol, alpha, beta, gamma):
+    """ Calculates heat stability function for unstable conditions
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psit : float
+    """
     xtmp = (1-alpha*zol)**beta
     psit = 2*np.log((1+xtmp**2)*0.5)
     return psit
@@ -264,30 +514,65 @@ def psi_conv(zol, alpha, beta, gamma):
 
 
 def psi_stab(zol, alpha, beta, gamma):
+    """ Calculates heat stability function for stable conditions
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psit : float
+    """
     psit = -gamma*zol
     return psit
 # ---------------------------------------------------------------------
 
 
-def psit_26(zet):
-    """
-    computes temperature structure function as in COARE3.5
+def psit_26(zol):
+    """ Computes temperature structure function as in C35
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+        
+    Returns
+    -------
+    psi : float
     """
-    dzet = np.where(0.35*zet > 50, 50, 0.35*zet)  # stable
-    psi = -((1+0.6667*zet)**1.5+0.6667*(zet-14.28)*np.exp(-dzet)+8.525)
-    k = np.where(zet < 0)  # unstable
-    x = (1-15*zet[k])**0.5
+    dzol = np.where(0.35*zol > 50, 50, 0.35*zol)  # stable
+    psi = -((1+0.6667*zol)**1.5+0.6667*(zol-14.28)*np.exp(-dzol)+8.525)
+    k = np.where(zol < 0)  # unstable
+    x = (1-15*zol[k])**0.5
     psik = 2*np.log((1+x)/2)
-    x = (1-34.15*zet[k])**0.3333
+    x = (1-34.15*zol[k])**0.3333
     psic = (1.5*np.log((1+x+x**2)/3)-np.sqrt(3)*np.arctan((1+2*x) /
             np.sqrt(3))+4*np.arctan(1)/np.sqrt(3))
-    f = zet[k]**2/(1+zet[k]**2)
+    f = zol[k]**2/(1+zol[k]**2)
     psi[k] = (1-f)*psik+f*psic
     return psi
 # ---------------------------------------------------------------------
 
 
 def psim_conv_coare3(zol, alpha, beta, gamma):
+    """ Calculates momentum stability function for unstable conditions 
+        for method C30
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psim : float
+    """
     x = (1-15*zol)**0.25  # Kansas unstable
     psik = 2*np.log((1+x)/2)+np.log((1+x*x)/2)-2*np.arctan(x)+2*np.arctan(1)
     y = (1-10.15*zol)**0.3333  # Convective
@@ -300,6 +585,20 @@ def psim_conv_coare3(zol, alpha, beta, gamma):
 
 
 def psim_stab_coare3(zol, alpha, beta, gamma):
+    """ Calculates momentum stability function for stable conditions 
+        for method C30
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psim : float
+    """
     c = np.where(0.35*zol > 50, 50, 0.35*zol)  # Stable
     psim = -((1+1*zol)**1.0+0.6667*(zol-14.28)/np.exp(-c)+8.525)
     return psim
@@ -307,6 +606,20 @@ def psim_stab_coare3(zol, alpha, beta, gamma):
 
 
 def psim_stab_era5(zol, alpha, beta, gamma):
+    """ Calculates momentum stability function for stable conditions 
+        for method ERA5
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psim : float
+    """
     # eq (3.22) p. 39 IFS Documentation cy46r1
     a, b, c, d = 1, 2/3, 5, 0.35
     psim = -b*(zol-c/d)*np.exp(-d*zol)-a*zol-(b*c)/d
@@ -315,6 +628,19 @@ def psim_stab_era5(zol, alpha, beta, gamma):
 
 
 def psim_conv(zol, alpha, beta, gamma):
+    """ Calculates momentum stability function for unstable conditions
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psim : float
+    """
     xtmp = (1-alpha*zol)**beta
     psim = (2*np.log((1+xtmp)*0.5)+np.log((1+xtmp**2)*0.5) -
             2*np.arctan(xtmp)+np.pi/2)
@@ -323,50 +649,112 @@ def psim_conv(zol, alpha, beta, gamma):
 
 
 def psim_stab(zol, alpha, beta, gamma):
+    """ Calculates momentum stability function for stable conditions
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+    alpha, beta, gamma : float
+        constants given by get_stabco
+    
+    Returns
+    -------
+    psim : float
+    """
     psim = -gamma*zol
     return psim
 # ---------------------------------------------------------------------
 
 
-def psiu_26(zet):
+def psiu_26(zol):
+    """ Computes velocity structure function C35
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+   
+    Returns
+    -------
+    psi : float
     """
-    computes velocity structure function COARE3.5
-    """
-    dzet = np.where(0.35*zet > 50, 50, 0.35*zet)  # stable
+    dzol = np.where(0.35*zol > 50, 50, 0.35*zol)  # stable
     a, b, c, d = 0.7, 3/4, 5, 0.35
-    psi = -(a*zet+b*(zet-c/d)*np.exp(-dzet)+b*c/d)
-    k = np.where(zet < 0)  # unstable
-    x = (1-15*zet[k])**0.25
+    psi = -(a*zol+b*(zol-c/d)*np.exp(-dzol)+b*c/d)
+    k = np.where(zol < 0)  # unstable
+    x = (1-15*zol[k])**0.25
     psik = 2*np.log((1+x)/2)+np.log((1+x**2)/2)-2*np.arctan(x)+2*np.arctan(1)
-    x = (1-10.15*zet[k])**0.3333
+    x = (1-10.15*zol[k])**0.3333
     psic = (1.5*np.log((1+x+x**2)/3)-np.sqrt(3)*np.arctan((1+2*x)/np.sqrt(3)) +
             4*np.arctan(1)/np.sqrt(3))
-    f = zet[k]**2/(1+zet[k]**2)
+    f = zol[k]**2/(1+zol[k]**2)
     psi[k] = (1-f)*psik+f*psic
     return psi
 # ------------------------------------------------------------------------------
 
 
-def psiu_40(zet):
-    """
-    computes velocity structure function COARE3.5
+def psiu_40(zol):
+    """ Computes velocity structure function C35
+    
+    Parameters
+    ----------
+    zol : float
+        height over MO length
+   
+    Returns
+    -------
+    psi : float
     """
-    dzet = np.where(0.35*zet > 50, 50, 0.35*zet)  # stable
+    dzol = np.where(0.35*zol > 50, 50, 0.35*zol)  # stable
     a, b, c, d = 1, 3/4, 5, 0.35
-    psi = -(a*zet+b*(zet-c/d)*np.exp(-dzet)+b*c/d)
-    k = np.where(zet < 0)  # unstable
-    x = (1-18*zet[k])**0.25
+    psi = -(a*zol+b*(zol-c/d)*np.exp(-dzol)+b*c/d)
+    k = np.where(zol < 0)  # unstable
+    x = (1-18*zol[k])**0.25
     psik = 2*np.log((1+x)/2)+np.log((1+x**2)/2)-2*np.arctan(x)+2*np.arctan(1)
-    x = (1-10*zet[k])**0.3333
+    x = (1-10*zol[k])**0.3333
     psic = (1.5*np.log((1+x+x**2)/3)-np.sqrt(3)*np.arctan((1+2*x)/np.sqrt(3)) +
             4*np.arctan(1)/np.sqrt(3))
-    f = zet[k]**2/(1+zet[k]**2)
+    f = zol[k]**2/(1+zol[k]**2)
     psi[k] = (1-f)*psik+f*psic
     return psi
 # ---------------------------------------------------------------------
 
 
-def get_skin(sst, qsea, rho, jcool, Rl, Rs, Rnl, cp, lv, usr, tsr, qsr, lat):
+def get_skin(sst, qsea, rho, Rl, Rs, Rnl, cp, lv, usr, tsr, qsr, lat):
+    """ Computes cool skin
+    
+    Parameters
+    ----------
+    sst : float
+        sea surface temperature ($^\circ$\,C)
+    qsea : float
+        specific humidity over sea (g/kg)
+    rho : float
+        density of air (kg/m^3)
+    Rl : float
+        downward longwave radiation (W/m^2)
+    Rs : float
+        downward shortwave radiation (W/m^2)
+    cp : float
+       specific heat of air at constant pressure
+    lv : float
+       latent heat of vaporization
+    usr : float
+       friction velocity
+    tsr : float
+       star temperature
+    qsr : float
+       star humidity
+    lat : float
+       latitude
+    
+    Returns
+    -------
+    dter : float
+    dqer : float      
+    
+    """
     # coded following Saunders (1967) with lambda = 6
     g = gc(lat, None)
     if (np.nanmin(sst) > 200):  # if Ta in Kelvin convert to Celsius
@@ -397,6 +785,27 @@ def get_skin(sst, qsea, rho, jcool, Rl, Rs, Rnl, cp, lv, usr, tsr, qsr, lat):
 
 
 def get_gust(beta, Ta, usr, tsrv, zi, lat):
+    """ Computes gustiness
+    
+    Parameters
+    ----------
+    beta : float
+        constant
+    Ta : float
+        air temperature (K)
+    usr : float
+        friction velocity (m/s)
+    tsrv : float
+        star virtual temperature of air (K)
+    zi : int
+        scale height of the boundary layer depth (m)
+    lat : float
+        latitude
+    
+    Returns
+    -------
+    ug : float
+    """
     if (np.max(Ta) < 200):  # convert to K if in Celsius
         Ta = Ta+273.16
     if np.isnan(zi):
@@ -410,6 +819,17 @@ def get_gust(beta, Ta, usr, tsrv, zi, lat):
 
 
 def get_heights(h):
+    """ Reads input heights for velocity, temperature and humidity
+    
+    Parameters
+    ----------
+    h : float
+        input heights (m)
+        
+    Returns
+    -------
+    hh : array
+    """
     hh = np.zeros(3)
     if (type(h) == float or type(h) == int):
         hh[0], hh[1], hh[2] = h, h, h
@@ -422,10 +842,17 @@ def get_heights(h):
 
 
 def svp_calc(T):
-    """
-    calculates saturation vapour pressure
-    T is in Kelvin
-    svp in mb, pure water
+    """ Calculates saturation vapour pressure
+    
+    Parameters
+    ----------
+    T : float
+        temperature (K)
+    
+    Returns
+    -------
+    svp : float
+        in mb, pure water
     """
     if (np.nanmin(T) < 200):  # if T in Celsius convert to Kelvin
         T = T+273.16
@@ -435,10 +862,19 @@ def svp_calc(T):
 
 
 def qsea_calc(sst, pres):
-    """
-    sst in Kelvin
-    pres in mb
-    qsea in kg/kg
+    """ Computes specific humidity of the  sea surface air
+    
+    Parameters
+    ----------
+    sst : float
+        sea surface temperature (K)
+    pres : float
+        pressure (mb)
+    
+    Returns
+    -------
+    qsea : float 
+        (kg/kg)
     """
     if (np.nanmin(sst) < 200):  # if sst in Celsius convert to Kelvin
         sst = sst+273.16
@@ -451,11 +887,20 @@ def qsea_calc(sst, pres):
 
 
 def q_calc(Ta, rh, pres):
-    """
-    rh in %
-    air in K, if not it will be converted to K
-    pres in mb
-    qair in kg/kg, as in Haltiner and Martin p.24
+    """ Computes specific humidity following Haltiner and Martin p.24
+    
+    Parameters
+    ----------
+    Ta : float
+        air temperature (K)
+    rh : float
+        relative humidity (%)
+    pres : float
+        air pressure (mb)
+        
+    Returns
+    -------
+    qair : float, (kg/kg)
     """
     if (np.nanmin(Ta) < 200):  # if sst in Celsius convert to Kelvin
         Ta = Ta+273.15
@@ -466,9 +911,18 @@ def q_calc(Ta, rh, pres):
 
 
 def bucksat(T, P):
-    """
-    computes saturation vapor pressure [mb] as in COARE3.5
-    given T [degC] and P [mb]
+    """ Computes saturation vapor pressure (mb) as in C35
+    
+    Parameters
+    ----------
+    T : float
+        temperature ($^\\circ$\\,C)
+    P : float
+        pressure (mb)
+    
+    Returns
+    -------
+    exx : float
     """
     T = np.asarray(T)
     if (np.nanmin(T) > 200):  # if Ta in Kelvin convert to Celsius
@@ -479,9 +933,18 @@ def bucksat(T, P):
 
 
 def qsat26sea(T, P):
-    """
-    computes surface saturation specific humidity [g/kg] as in COARE3.5
-    given T [degC] and P [mb]
+    """ Computes surface saturation specific humidity (g/kg) as in C35
+    
+    Parameters
+    ----------
+    T : float
+        temperature ($^\\circ$\\,C)
+    P : float
+        pressure (mb)
+        
+    Returns
+    -------
+    qs : float
     """
     T = np.asarray(T)
     if (np.nanmin(T) > 200):  # if Ta in Kelvin convert to Celsius
@@ -494,9 +957,19 @@ def qsat26sea(T, P):
 
 
 def qsat26air(T, P, rh):
-    """
-    computes saturation specific humidity [g/kg] as in COARE3.5
-    given T [degC] and P [mb]
+    """ Computes saturation specific humidity (g/kg) as in C35
+    
+    Parameters
+    ----------
+    T : float
+        temperature ($^\circ$\,C)
+    P : float
+        pressure (mb)
+        
+    Returns
+    -------
+    q : float
+    em : float
     """
     T = np.asarray(T)
     if (np.nanmin(T) > 200):  # if Ta in Kelvin convert to Celsius
@@ -509,13 +982,19 @@ def qsat26air(T, P, rh):
 
 
 def gc(lat, lon=None):
-    """
-    computes gravity relative to latitude
-    inputs:
-        lat : latitudes in deg
-        lon : longitudes (optional)
-    output:
-        gc: gravity constant
+    """ Computes gravity relative to latitude
+    
+    Parameters
+    ----------
+    lat : float
+        latitude ($^\circ$)
+    lon : float
+        longitude ($^\circ$, optional)
+    
+    Returns
+    -------
+    gc : float
+        gravity constant (m/s^2)
     """
     gamma = 9.7803267715
     c1 = 0.0052790414
@@ -535,13 +1014,18 @@ def gc(lat, lon=None):
 
 
 def visc_air(Ta):
-    """
-    Computes the kinematic viscosity of dry air as a function of air temp.
+    """ Computes the kinematic viscosity of dry air as a function of air temp.
     following Andreas (1989), CRREL Report 89-11.
-    input:
-        Ta : air temperature [Celsius]
-    output
-    visa : kinematic viscosity [m^2/s]
+    
+    Parameters
+    ----------
+    Ta : float
+        air temperature ($^\circ$\,C)
+    
+    Returns
+    -------
+    visa : float
+        kinematic viscosity (m^2/s)
     """
     Ta = np.asarray(Ta)
     if (np.nanmin(Ta) > 200):  # if Ta in Kelvin convert to Celsius