From 6e46d5780823a96a8fe82a27b711b67d38cfe195 Mon Sep 17 00:00:00 2001
From: "Mads M. Pedersen" <mmpe@dtu.dk>
Date: Wed, 1 Nov 2017 11:06:06 +0100
Subject: [PATCH 1/3] stuff

---
 wetb/hawc2/htc_extensions.py            |  11 ++-
 wetb/hawc2/htc_file.py                  |   3 +
 wetb/hawc2/shear_file.py                |  17 +++-
 wetb/hawc2/tests/test_shear_file.py     |   2 +-
 wetb/utils/caching.py                   |  16 +++-
 wetb/utils/tests/test_caching.py        |  25 ++++-
 wetb/wind/__init__.py                   |   1 -
 wetb/wind/shear.py                      |  26 ++++--
 wetb/wind/stability.py                  |   1 -
 wetb/wind/turbulence/mann_parameters.py | 117 ++++++++++++++++--------
 wetb/wind/turbulence/spectra.py         |   2 +-
 11 files changed, 156 insertions(+), 65 deletions(-)

diff --git a/wetb/hawc2/htc_extensions.py b/wetb/hawc2/htc_extensions.py
index 67b9f7fe..72a59009 100644
--- a/wetb/hawc2/htc_extensions.py
+++ b/wetb/hawc2/htc_extensions.py
@@ -15,7 +15,8 @@ from builtins import int
 from builtins import str
 from future import standard_library
 import os
-from wetb.wind.shear import log_shear, power_shear
+
+
 standard_library.install_aliases()
 
 
@@ -82,10 +83,11 @@ class HTCDefaults(object):
         else:
             mann.add_line('create_turb_parameters', [L, ae23, Gamma, seed, int(high_frq_compensation)], "L, alfaeps, gamma, seed, highfrq compensation")
         if filenames is None:
-            fmt = "mann_l%.1f_ae%.2f_g%.1f_h%d_%dx%dx%d_%.3fx%.2fx%.2f_s%04d%c.turb"
+            
             import numpy as np
             dxyz = tuple(np.array(box_dimension) / no_grid_points)
-            filenames = ["./turb/" + fmt % ((L, ae23, Gamma, high_frq_compensation) + no_grid_points + dxyz + (seed, uvw)) for uvw in ['u', 'v', 'w']]
+            from wetb.wind.turbulence import mann_turbulence
+            filenames = ["./turb/" + mann_turbulence.name_format % ((L, ae23, Gamma, high_frq_compensation) + no_grid_points + dxyz + (seed, uvw)) for uvw in ['u', 'v', 'w']]
         if isinstance(filenames, str):
             filenames = ["./turb/%s_s%04d%s.bin" % (filenames, seed, c) for c in ['u', 'v', 'w']]
         for filename, c in zip(filenames, ['u', 'v', 'w']):
@@ -153,8 +155,9 @@ class HTCExtensions(object):
         z0 = -self.wind.center_pos0[2]
         wsp = self.wind.wsp[0]
         if shear_type==1: #constant
-            return lambda z : parameter
+            return lambda z : wsp
         elif shear_type==3:
+            from wetb.wind.shear import power_shear
             return power_shear(parameter, z0, wsp)
         else:
             raise NotImplementedError
\ No newline at end of file
diff --git a/wetb/hawc2/htc_file.py b/wetb/hawc2/htc_file.py
index f783408e..655b7406 100644
--- a/wetb/hawc2/htc_file.py
+++ b/wetb/hawc2/htc_file.py
@@ -66,6 +66,9 @@ class HTCFile(HTCContents, HTCDefaults, HTCExtensions):
     This is a comment
     >>> print (hydro_element.wave_breaking[0]) # first value
     2
+    
+    #Delete element
+    del htc.simulation.logfile #Delete logfile line. Raise keyerror if not exists
     """
 
     filename = None
diff --git a/wetb/hawc2/shear_file.py b/wetb/hawc2/shear_file.py
index 11d6d608..0b2560ff 100644
--- a/wetb/hawc2/shear_file.py
+++ b/wetb/hawc2/shear_file.py
@@ -31,7 +31,7 @@ class ShearFile(object):
     >>> sf.save('test.dat')
     """
     
-    def __init__(self,v_positions, w_positions, u=None, v=None, w=None, shear=None):
+    def __init__(self,v_positions, w_positions, u=None, v=None, w=None, u0=None, shear=None):
         """
         Parameters
         ----------
@@ -48,6 +48,10 @@ class ShearFile(object):
         w : array_like, optional
             shear_w component, normalized with U_mean\n
             shape must be (#w_positions, #v_positions) or (#w_positions,)
+        u0 : int or float
+            Mean wind speed
+        shear : function
+            Shear function: f(height)->wsp
         """
         self.v_positions = v_positions
         self.w_positions = w_positions
@@ -66,9 +70,10 @@ class ShearFile(object):
     
                 assert uvw[i].shape == shape, (i, uvw[i].shape, shape)
         self.u, self.v, self.w = uvw
+        self.u0 = u0
         self.shear = shear
     
-    def uvw(self, v,w,shear=None):
+    def uvw(self, v,w,u0=None,shear=None):
         """Calculate u,v,w wind speeds at position(s) (v,w)
         Parameters
         ----------
@@ -76,6 +81,8 @@ class ShearFile(object):
             v-coordinate(s)
         w : int, float or array_like
             w-coordinates(s)
+        u0 : int or float
+            mean wind speed
         shear : function or None
             if function: f(height)->wsp
             if None: self.shear is used, if not None. 
@@ -86,10 +93,11 @@ class ShearFile(object):
         u,v,w 
             wind speed(s) or wind speed factor(s) if shear not defined
         """
-        shear = shear or self.shear or (lambda z: 1)
+        u0 =u0 or self.u0 or 1
+        shear = shear or self.shear or (lambda z: 0)
         from scipy.interpolate import RegularGridInterpolator
         wv = np.array([w,v]).T
-        return [RegularGridInterpolator((self.w_positions, self.v_positions), uvw)(wv)*shear(w) 
+        return [(RegularGridInterpolator((self.w_positions, self.v_positions), uvw)(wv))*u0+shear(w) 
                             for uvw in [self.u, self.v, self.w] if uvw is not None]
         
 
@@ -156,6 +164,7 @@ class ShearFile(object):
         user_defined_shear_filename = os.path.join(htc_file.modelpath, htc_file.wind.user_defined_shear[0])
         shear_file = ShearFile.load(user_defined_shear_filename)
         shear_file.shear = htc_file.get_shear()
+        shear_file.u0 = htc_file.wind.wsp[0]
         return shear_file
 
 def save(filename, v_coordinates, w_coordinates, u=None, v=None, w=None):
diff --git a/wetb/hawc2/tests/test_shear_file.py b/wetb/hawc2/tests/test_shear_file.py
index 302cae18..f724ca3b 100644
--- a/wetb/hawc2/tests/test_shear_file.py
+++ b/wetb/hawc2/tests/test_shear_file.py
@@ -93,7 +93,7 @@ class TestShearFile(unittest.TestCase):
         
         shear_file = ShearFile.load_from_htc(tfp+"htcfiles/test.htc")
         np.testing.assert_array_equal(shear_file.w_positions, [30,100,160])
-        np.testing.assert_array_almost_equal(shear_file.uvw([0,-55],[65,65])[0],np.array([.85,.9])*8.860807038)
+        np.testing.assert_array_almost_equal(shear_file.uvw([0,-55],[65,65])[0],np.array([.85,.9])*10+8.860807038)
 if __name__ == "__main__":
     #import sys;sys.argv = ['', 'Test.test_shearfile']
     unittest.main()
diff --git a/wetb/utils/caching.py b/wetb/utils/caching.py
index a4333a2b..d8cd22e1 100644
--- a/wetb/utils/caching.py
+++ b/wetb/utils/caching.py
@@ -10,9 +10,10 @@ from __future__ import absolute_import
 from future import standard_library
 import sys
 from collections import OrderedDict
+import os
 standard_library.install_aliases()
 import inspect
-
+import numpy as np
 def set_cache_property(obj, name, get_func, set_func=None):
     """Create a cached property
 
@@ -106,4 +107,15 @@ class cache_method():
                 if len(self.cache_dict)>self.N:
                     self.cache_dict.popitem(last=False)
             return self.cache_dict[arg_id]
-        return wrapped
\ No newline at end of file
+        return wrapped
+    
+def cache_binary(f):
+    def wrap(filename,*args,**kwargs):
+        np_filename = os.path.splitext(filename)[0] + ".npy"
+        if os.path.isfile(np_filename) and (not os.path.isfile(filename) or os.path.getmtime(np_filename) > os.path.getmtime(filename)):
+            return np.load(np_filename)
+        else:
+            res = f(filename,*args,**kwargs)
+            np.save(np_filename,res)
+            return res
+    return wrap
\ No newline at end of file
diff --git a/wetb/utils/tests/test_caching.py b/wetb/utils/tests/test_caching.py
index 94530e7c..23655a0d 100644
--- a/wetb/utils/tests/test_caching.py
+++ b/wetb/utils/tests/test_caching.py
@@ -9,16 +9,18 @@ from __future__ import division
 from __future__ import absolute_import
 from future import standard_library
 from collections import OrderedDict
+import os
 standard_library.install_aliases()
 import multiprocessing
 import time
 import unittest
-
+import numpy as np
 
 from wetb.utils.timing import get_time
-from wetb.utils.caching import cache_function, set_cache_property, cache_method
-
+from wetb.utils.caching import cache_function, set_cache_property, cache_method,\
+    cache_binary
 
+tfp = os.path.dirname(__file__) + "/test_files/"
 class Example(object):
     def __init__(self, *args, **kwargs):
         object.__init__(self, *args, **kwargs)
@@ -54,7 +56,9 @@ class Example(object):
         time.sleep(1)
         return x*2
 
-
+@cache_binary
+def open_csv(filename):
+    return np.loadtxt(filename)
 
 def f(x):
     return x ** 2
@@ -110,6 +114,19 @@ class TestCacheProperty(unittest.TestCase):
         t = time.time()
         e.test_cache_property
         self.assertAlmostEqual(time.time()-t, 0, places=1)
+        
+    def test_cache_binary(self):
+        if os.path.isfile(tfp+"test.npy"):
+            os.remove(tfp+'test.npy')
+        A = open_csv(tfp + "test.csv")
+        self.assertTrue(os.path.isfile(tfp+"test.npy"))
+        np.testing.assert_array_equal(A,np.loadtxt(tfp + "test.csv"))
+        A[0]=-1
+        np.save(tfp+"test.npy",A)
+        B = open_csv(tfp + "test.csv")
+        np.testing.assert_array_equal(A,B)
+        os.remove(tfp+'test.npy')
+        
 if __name__ == "__main__":
     #import sys;sys.argv = ['', 'Test.testName']
     unittest.main()
diff --git a/wetb/wind/__init__.py b/wetb/wind/__init__.py
index 36e41c9b..e69de29b 100644
--- a/wetb/wind/__init__.py
+++ b/wetb/wind/__init__.py
@@ -1 +0,0 @@
-from .turbulence import *
diff --git a/wetb/wind/shear.py b/wetb/wind/shear.py
index dd3281b0..de1acbb5 100644
--- a/wetb/wind/shear.py
+++ b/wetb/wind/shear.py
@@ -114,7 +114,7 @@ def fit_power_shear_ref(z_u_lst, z_ref, plt=None):
 
 
 
-def log_shear(u_star, z0, z, Obukhov_length=None):
+def log_shear(u_star, z0):
     """logarithmic shear
 
     Parameters
@@ -123,24 +123,28 @@ def log_shear(u_star, z0, z, Obukhov_length=None):
         Friction velocity
     z0 : int or float
         Surface roughness [m]
-    z : int, float or array_like
-        The heights of interest
 
     Returns
     -------
-    log_shear : array-like
-        Wind speeds at height z
+    log_shear : function f(z,L=None) -> wsp
+        z : int, float or array_like
+            The heights of interest
+        L : int, float or array_like, optional
+            The corresponding Monin-Obukhov length
 
     Example
     --------
-    >>> log_shear(1, 10, [20, 50, 70])
+    >>> shear = log_shear(1, 10)
+    >>> shear([20, 50, 70])
     [ 1.73286795  4.02359478  4.86477537]
     """
     K = 0.4  # von Karmans constant
-    if Obukhov_length is None:
-        return u_star / K * (np.log(np.array(z) / z0))
-    else:
-        return u_star / K * (np.log(z / z0) - stability_term(z, z0, Obukhov_length))
+    def log_shear(z,Obukhov_length=None):
+        if Obukhov_length is None:
+            return u_star / K * (np.log(np.array(z) / z0))
+        else:
+            return u_star / K * (np.log(z / z0) - stability_term(z, z0, Obukhov_length))
+    return log_shear
 
 def stability_term(z, z0, L):
     """Calculate the stability term for the log shear
@@ -169,6 +173,8 @@ def fit_log_shear(z_u_lst, include_R=False):
         - u_z1: Wind speeds or mean wind speed at z1
         - z2: another height
         - u_z2: Wind speeds or mean wind speeds at z2
+    include_R : boolean, optional
+        If True, the R^2 error is returned
 
     Returns
     -------
diff --git a/wetb/wind/stability.py b/wetb/wind/stability.py
index 6826d581..b60a8d30 100644
--- a/wetb/wind/stability.py
+++ b/wetb/wind/stability.py
@@ -32,7 +32,6 @@ def MoninObukhov_length(u,v,w, T):
     v = v-np.mean(v)
     w = w-np.mean(w)
     u_star = (np.mean(u*w)**2+np.mean(v*w)**2)**(1/4)
-    t = T-T.mean()
     wT = np.mean(w*T)
     return -u_star ** 3 * (T.mean() + 273.15) / (K * g * wT)
 
diff --git a/wetb/wind/turbulence/mann_parameters.py b/wetb/wind/turbulence/mann_parameters.py
index 0dd3c3f4..9799b49f 100644
--- a/wetb/wind/turbulence/mann_parameters.py
+++ b/wetb/wind/turbulence/mann_parameters.py
@@ -10,9 +10,9 @@ import os
 from scipy.interpolate import RectBivariateSpline
 
 import numpy as np
-from wetb.wind.turbulence.spectra import spectra, logbin_spectra, \
-    plot_spectrum, plot_spectra
-from wetb.utils.test_files import move2test_files
+from wetb.wind.turbulence.spectra import spectra, logbin_spectra, plot_spectra,\
+    detrend_wsp
+
 
 
 
@@ -198,13 +198,19 @@ def residual(ae, L, G, k1, uu, vv=None, ww=None, uw=None, log10_bin_size=.2):
     return np.sqrt(((bk1 * (sp_meas - sp_fit)) ** 2).mean(1))
 
 
-def fit_ae2var(variance, L, G):
+def var2ae(variance, spatial_resolution, N, L, G):
     """Fit alpha-epsilon to match variance of time series
 
     Parameters
     ----------
     variance : array-like
         variance of u vind component
+    spatial_resolution : int, float or array_like
+        Distance between samples in meters
+        - For turbulence boxes: 1/dx = Nx/Lx where dx is distance between points, 
+        Nx is number of points and Lx is box length in meters
+        - For time series: Sample frequency / U
+    N : int
     L : int or float
         Length scale of Mann model
     G : int or float
@@ -226,13 +232,17 @@ def fit_ae2var(variance, L, G):
     return ae
 
 
-def fit_ae(sf, u, L, G, min_bin_count=None, plt=False):
+
+def fit_ae(spatial_resolution, u, L, G, plt=False):
     """Fit alpha-epsilon to match variance of time series
 
     Parameters
     ----------
-    sf : int or float
-        Sample frequency
+    spatial_resolution : int, float or array_like
+        Distance between samples in meters
+        - For turbulence boxes: 1/dx = Nx/Lx where dx is distance between points, 
+        Nx is number of points and Lx is box length in meters
+        - For time series: Sample frequency / U
     u : array-like
         u vind component
     L : int or float
@@ -245,33 +255,37 @@ def fit_ae(sf, u, L, G, min_bin_count=None, plt=False):
     ae : float
         Alpha epsilon^(2/3) of Mann model that makes the energy of the model equal to the varians of u
     """
-#    def get_var(k1, ae):
-#        uu = get_mann_model_spectra(ae, L, G, k1)[0]
-#        return np.trapz(2 * uu, k1)
-#        return (np.sum(uu) * 2 * (k1[1] - k1[0]))
-    if len(u.shape) == 1:
-        u = u.reshape(len(u), 1)
-    if min_bin_count is None:
-        min_bin_count = max(2, 6 - u.shape[1] / 2)
-
+    #if len(u.shape) == 1:
+    #    u = u.reshape(len(u), 1)
+#     if min_bin_count is None:
+#         min_bin_count = max(2, 6 - u.shape[0] / 2)
+#     min_bin_count = 1
     def get_var(k1, uu):
         l = 0  #128 // np.sqrt(u.shape[1])
         return np.trapz(2 * uu[l:], k1[l:])
 
-    k1 = spectra(sf, u)[0]
-    v1 = get_var(*logbin_spectra(k1, get_mann_model_spectra(0.1, L, G, k1)[0], min_bin_count=min_bin_count)[:2])
-    v2 = get_var(*logbin_spectra(k1, get_mann_model_spectra(0.2, L, G, k1)[0], min_bin_count=min_bin_count)[:2])
-    k1, uu = logbin_spectra(*spectra(sf, u), min_bin_count=2)[:2]
-    #variance = np.mean([detrend_wsp(u_)[0].var() for u_ in u.T])
-    v = get_var(k1, uu)
+    k1, uu = spectra(spatial_resolution, u)[:2]
+    v = get_var(k1,uu)
+    v1 = get_var(k1, get_mann_model_spectra(0.1, L, G, k1)[0])
+    v2 = get_var(k1, get_mann_model_spectra(0.2, L, G, k1)[0])
     ae = (v - v1) / (v2 - v1) * .1 + .1
+#     print (ae)
+#     
+#     k1 = spectra(sf, u)[0]
+#     v1 = get_var(*logbin_spectra(k1, get_mann_model_spectra(0.1, L, G, k1)[0], min_bin_count=min_bin_count)[:2])
+#     v2 = get_var(*logbin_spectra(k1, get_mann_model_spectra(0.2, L, G, k1)[0], min_bin_count=min_bin_count)[:2])
+#     k1, uu = logbin_spectra(*spectra(sf, u), min_bin_count=2)[:2]
+#     #variance = np.mean([detrend_wsp(u_)[0].var() for u_ in u.T])
+#     v = get_var(k1, uu)
+#     ae = (v - v1) / (v2 - v1) * .1 + .1
+#     print (ae)
     if plt is not False:
         if not hasattr(plt, 'plot'):
             import matplotlib.pyplot as plt
         plt.semilogx(k1, k1 * uu, 'b-', label='uu')
-        k1, uu = logbin_spectra(*spectra(sf, u), min_bin_count=1)[:2]
+        k1_lb, uu_lb = logbin_spectra(*spectra(sf, u), min_bin_count=1)[:2]
 
-        plt.semilogx(k1, k1 * uu, 'r--', label='uu_logbin')
+        plt.semilogx(k1_lb, k1_lb * uu_lb, 'r--', label='uu_logbin')
         muu = get_mann_model_spectra(ae, L, G, k1)[0]
         plt.semilogx(k1, k1 * muu, 'g', label='ae:%.3f, L:%.1f, G:%.2f' % (ae, L, G))
         plt.legend()
@@ -312,22 +326,51 @@ if __name__ == "__main__":
     ds = gtsdf.Dataset(os.path.dirname(wind.__file__)+"/tests/test_files/WspDataset.hdf5")#'unit_test/test_files/wspdataset.hdf5')
     f = 35
     u, v = wsp_dir2uv(ds.Vhub_85m, ds.Dir_hub_)
-
+ 
     u_ref = np.mean(u)
     u -= u_ref
-
+ 
     sf = f / u_ref
-    ae, L, G = fit_mann_model_spectra(*spectra(sf, u, v), plt = plt)
+    ae, L, G = fit_mann_model_spectra(*spectra(sf, u, v), plt = None)
     print (ae, L, G)
+    print (u.shape)
+    print (ds.Time[-1])
+    plt.plot(u)
+    plt.plot(detrend_wsp(u)[0])
+    plt.show()
+    print (fit_ae(sf, detrend_wsp(u)[0], L,  G, plt))
+    print (var2ae(detrend_wsp(u)[0].var(), L,  G,))
+    print ()
+    print (fit_ae(sf, u[:21000], L,  G))
+    print (var2ae(u[:21000].var(), L,  G,))
+    
+
 
  
-    """Example of fitting Mann parameters to a "series" of a turbulence box"""
-    l = 16384
-    nx = 8192
-    ny, nz = 8, 8
-    sf = (nx / l)
-    #fn = os.path.dirname(wind.__file__)+"/tests/test_files/turb/h2a8192_8_8_16384_32_32_0.15_10_3.3%s.dat"
-    #fn = os.path.dirname(wind.__file__)+"/tests/test_files/turb/h2a8192_8_8_16384_32_32_0.15_10_3.3%s.dat"
-    u, v, w = [np.fromfile(fn % uvw, np.dtype('<f'), -1).reshape(nx , ny * nz) for uvw in ['u', 'v', 'w']]
-    ae, L, G = fit_mann_model_spectra(*spectra(sf, u, v, w), plt=plt)
-    print (ae, L, G)
+#     """Example of fitting Mann parameters to a "series" of a turbulence box"""
+#     l = 16384
+#     nx = 8192
+#     ny, nz = 8, 8
+#     sf = (nx / l)
+#     #fn = os.path.dirname(wind.__file__)+"/tests/test_files/turb/h2a8192_8_8_16384_32_32_0.15_10_3.3%s.dat"
+#     #fn = os.path.dirname(wind.__file__)+"/tests/test_files/turb/h2a8192_8_8_16384_32_32_0.15_10_3.3%s.dat"
+#     u, v, w = [np.fromfile(fn % uvw, np.dtype('<f'), -1).reshape(nx , ny * nz) for uvw in ['u', 'v', 'w']]
+#     ae, L, G = fit_mann_model_spectra(*spectra(sf, u, v, w), plt=plt)
+#     print (ae, L, G)
+
+
+
+#     """Example of fitting Mann parameters to a "series" of a turbulence box"""
+#     l = 4778.3936
+#     nx = 8192
+#     ny, nz = 32,32
+#     sf = (nx / l)
+#     #fn = os.path.dirname(wind.__file__)+"/tests/test_files/turb/h2a8192_8_8_16384_32_32_0.15_10_3.3%s.dat"
+#     for s in [1,2,3,4,5,6]:
+#         fn = r'C:\mmpe\HAWC2\models\SWT3.6-107\turb/mann_l73.1_ae0.00_g2.0_h1_8192x32x32_0.583x3.44x3.44_s160%d%%s.turb'%s
+#         u, v, w = [np.fromfile(fn % uvw, np.dtype('<f'), -1).reshape(nx , ny * nz) for uvw in ['u', 'v', 'w']]
+#         u = np.fromfile(fn % 'u', np.dtype('<f'), -1).reshape(nx , ny * nz)
+#         #ae, L, G = fit_mann_model_spectra(*spectra(sf, u, v, w), plt=plt)
+#         #print (fit_ae(sf, u, 73.0730383576,  2.01636095317))
+#         print (u.std())
+#     #print (ae, L, G)
\ No newline at end of file
diff --git a/wetb/wind/turbulence/spectra.py b/wetb/wind/turbulence/spectra.py
index f6aa6010..1a226c53 100644
--- a/wetb/wind/turbulence/spectra.py
+++ b/wetb/wind/turbulence/spectra.py
@@ -49,7 +49,7 @@ def spectra(spatial_resolution, u, v=None, w=None, detrend=True):
     ----------
     spatial_resolution : int, float or array_like
         Distance between samples in meters
-        - For turbulence boxes: 1/dx = Lx/Nx where dx is distance between points, 
+        - For turbulence boxes: 1/dx = Nx/Lx where dx is distance between points, 
         Nx is number of points and Lx is box length in meters
         - For time series: Sample frequency / U
     u : array_like
-- 
GitLab


From db3db3eb1338f1a3d04ace254ff8599946b2d188 Mon Sep 17 00:00:00 2001
From: "Mads M. Pedersen" <mmpe@dtu.dk>
Date: Wed, 1 Nov 2017 11:13:06 +0100
Subject: [PATCH 2/3] test fixes

---
 wetb/hawc2/pc_file.py                   |   7 +-
 wetb/hawc2/tests/test_htc_file.py       |   6 +-
 wetb/utils/tests/test_files/test.csv    |   5 ++
 wetb/wind/tests/test_Shear.py           |   9 +-
 wetb/wind/turbulence/mann_turbulence.py | 108 ++++++++++++++++++++++++
 5 files changed, 124 insertions(+), 11 deletions(-)
 create mode 100644 wetb/utils/tests/test_files/test.csv
 create mode 100644 wetb/wind/turbulence/mann_turbulence.py

diff --git a/wetb/hawc2/pc_file.py b/wetb/hawc2/pc_file.py
index 301a5b81..78dafdc5 100644
--- a/wetb/hawc2/pc_file.py
+++ b/wetb/hawc2/pc_file.py
@@ -16,7 +16,8 @@ standard_library.install_aliases()
 from wetb.hawc2.ae_file import AEFile
 import numpy as np
 
-class PCFile(AEFile):
+
+class PCFile(object):
     """Read HAWC2 PC (profile coefficients) file
 
     examples
@@ -37,9 +38,7 @@ class PCFile(AEFile):
     >>> pcfile.CM(36,10) # CM at radius=36m and AOA=10deg
     -0.1103
     """
-    def __init__(self, filename, ae_filename):
-        AEFile.__init__(self, ae_filename)
-
+    def __init__(self, filename):
         with open (filename) as fid:
             lines = fid.readlines()
         nsets = int(lines[0].split()[0])
diff --git a/wetb/hawc2/tests/test_htc_file.py b/wetb/hawc2/tests/test_htc_file.py
index 79b08927..ade4e173 100644
--- a/wetb/hawc2/tests/test_htc_file.py
+++ b/wetb/hawc2/tests/test_htc_file.py
@@ -151,9 +151,9 @@ class TestHtcFile(unittest.TestCase):
         htcfile.add_mann_turbulence(30.1, 1.1, 3.3, 102, False)
         s = """begin mann;
     create_turb_parameters\t30.1 1.1 3.3 102 0;\tL, alfaeps, gamma, seed, highfrq compensation
-    filename_u\t./turb/mann_l30.1_ae1.10_g3.3_h0_16384x32x32_0.366x3.12x3.12_s0102u.turb;
-    filename_v\t./turb/mann_l30.1_ae1.10_g3.3_h0_16384x32x32_0.366x3.12x3.12_s0102v.turb;
-    filename_w\t./turb/mann_l30.1_ae1.10_g3.3_h0_16384x32x32_0.366x3.12x3.12_s0102w.turb;
+    filename_u\t./turb/mann_l30.1_ae1.1000_g3.3_h0_16384x32x32_0.366x3.12x3.12_s0102u.turb;
+    filename_v\t./turb/mann_l30.1_ae1.1000_g3.3_h0_16384x32x32_0.366x3.12x3.12_s0102v.turb;
+    filename_w\t./turb/mann_l30.1_ae1.1000_g3.3_h0_16384x32x32_0.366x3.12x3.12_s0102w.turb;
     box_dim_u\t16384 0.3662;
     box_dim_v\t32 3.2258;
     box_dim_w\t32 3.2258;"""
diff --git a/wetb/utils/tests/test_files/test.csv b/wetb/utils/tests/test_files/test.csv
new file mode 100644
index 00000000..158e1a69
--- /dev/null
+++ b/wetb/utils/tests/test_files/test.csv
@@ -0,0 +1,5 @@
+0.000000000000000000e+00 5.000000000000000000e+00
+1.000000000000000000e+00 6.000000000000000000e+00
+2.000000000000000000e+00 7.000000000000000000e+00
+3.000000000000000000e+00 8.000000000000000000e+00
+4.000000000000000000e+00 9.000000000000000000e+00
diff --git a/wetb/wind/tests/test_Shear.py b/wetb/wind/tests/test_Shear.py
index 2de47b7b..3cefb0fc 100644
--- a/wetb/wind/tests/test_Shear.py
+++ b/wetb/wind/tests/test_Shear.py
@@ -158,8 +158,8 @@ class TestShear(unittest.TestCase):
 
 
     def test_log_shear(self):
-        u = log_shear(2, 3, 9)
-        self.assertAlmostEqual(u, 5.49306144)
+        shear = log_shear(2, 3)
+        self.assertAlmostEqual(shear(9), 5.49306144)
 
     def test_fit_log_shear(self):
         zu = [(85, 8.88131), (21, 4.41832)]
@@ -171,8 +171,9 @@ class TestShear(unittest.TestCase):
             plt.plot(log_shear(u_star, z0, z), z)
             plt.show()
 
-        for _zu, b in zip(zu, log_shear(u_star, z0, [85, 21])):
-            self.assertAlmostEqual(_zu[1], b, 4)
+        shear = log_shear(u_star, z0)
+        for z,u in zu:
+            self.assertAlmostEqual(u, shear(z), 4)
 
 
     def test_show_log_shear(self):
diff --git a/wetb/wind/turbulence/mann_turbulence.py b/wetb/wind/turbulence/mann_turbulence.py
new file mode 100644
index 00000000..efe42360
--- /dev/null
+++ b/wetb/wind/turbulence/mann_turbulence.py
@@ -0,0 +1,108 @@
+'''
+Created on 20. jul. 2017
+
+@author: mmpe
+'''
+import numpy as np
+
+from wetb.wind.turbulence.spectra import spectra, spectra_from_time_series
+name_format = "mann_l%.1f_ae%.4f_g%.1f_h%d_%dx%dx%d_%.3fx%.2fx%.2f_s%04d%c.turb"
+
+def load(filename, N=(32,32)):
+    """Load mann turbulence box
+    
+    Parameters
+    ----------
+    filename : str
+        Filename of turbulence box
+    N : tuple, (ny,nz) or (nx,ny,nz)
+        Number of grid points
+        
+    Returns
+    -------
+    turbulence_box : nd_array
+    
+    Examples
+    --------
+    >>> u = load('turb_u.dat') 
+    """
+    data = np.fromfile(filename, np.dtype('<f'), -1)
+    if len(N)==2:
+        ny,nz = N
+        nx = len(data)/(ny*nz)
+        assert nx==int(nx), "Size of turbulence box (%d) does not match ny x nz (%d), nx=%.2f" % (len(data),ny*nz, nx)
+        nx=int(nx)
+    else:
+        nx,ny,nz = N
+        assert len(data) == nx*ny*nz, "Size of turbulence box (%d) does not match nx x ny x nz (%d)" % (len(data),nx*ny*nz)
+    return data.reshape(nx , ny * nz)
+
+def load_uvw(filenames, N=(1024,32,32)):
+    """Load u, v and w turbulence boxes
+    
+    Parameters
+    ----------
+    filenames : list or str
+        if list: list of u,v,w filenames
+        if str: filename pattern where u,v,w are replaced with '%s'
+    N : tuple
+        Number of grid point in the x, y and z direction
+    
+    Returns
+    -------
+    u,v,w : list of np_array
+    
+    Examples
+    --------
+    >>> u,v,w =load_uvw('turb_%s.dat') 
+    """
+    if isinstance(filenames,str):
+        return [load(filenames%uvw, N) for uvw in 'uvw']
+    else:
+        return [load(f, N) for f in filenames]
+    
+def parameters2name(no_grid_points,box_dimension,ae23,L, Gamma,high_frq_compensation, seed, folder="./turb/"):
+    
+    dxyz = tuple(np.array(box_dimension) / no_grid_points)
+    return ["./turb/" + name_format % ((L, ae23, Gamma, high_frq_compensation) + no_grid_points + dxyz + (seed, uvw)) for uvw in ['u', 'v', 'w']]    
+
+    
+def fit_mann_parameters(spatial_resolution, u, v, w=None, plt=None):
+    """Fit mann parameters, ae, L, G
+    
+    Parameters
+    ----------
+    spatial_resolution : inf, float or array_like
+        Distance between samples in meters
+        - For turbulence boxes: 1/dx = Lx/Nx where dx is distance between points, 
+        Nx is number of points and Lx is box length in meters
+        - For time series: Sample frequency / U
+    u : array_like
+        The u-wind component\n
+        - if shape is (r,): One time series with *r* observations\n
+        - if shape is (r,c): *c* different time series with *r* observations\n
+    v : array_like, optional
+        The v-wind component
+        - if shape is (r,): One time series with *r* observations\n
+        - if shape is (r,c): *c* different time series with *r* observations\n
+    w : array_like, optional
+        The w-wind component
+        - if shape is (r,): One time series with *r* observations\n
+        - if shape is (r,c): *c* different time series with *r* observations\n
+    
+    Returns
+    -------
+    ae : int or float
+        Alpha epsilon^(2/3) of Mann model
+    L : int or float
+        Length scale of Mann model
+    G : int or float
+        Gamma of Mann model
+    """
+    from wetb.wind.turbulence.mann_parameters import fit_mann_model_spectra
+    return fit_mann_model_spectra(*spectra(spatial_resolution, u, v, w), plt=plt)
+
+
+def fit_mann_parameters_from_time_series(sample_frq, Uvw_lst, plt=None):
+    from wetb.wind.turbulence.mann_parameters import fit_mann_model_spectra
+    return fit_mann_model_spectra(*spectra_from_time_series(sample_frq, Uvw_lst), plt=plt)
\ No newline at end of file
-- 
GitLab


From 07d0c264bfb9b330cfbeab6ae9486fcf97d76369 Mon Sep 17 00:00:00 2001
From: "Mads M. Pedersen" <mmpe@dtu.dk>
Date: Wed, 1 Nov 2017 11:15:56 +0100
Subject: [PATCH 3/3] fix tests

---
 wetb/hawc2/pc_file.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/wetb/hawc2/pc_file.py b/wetb/hawc2/pc_file.py
index 78dafdc5..301a5b81 100644
--- a/wetb/hawc2/pc_file.py
+++ b/wetb/hawc2/pc_file.py
@@ -16,8 +16,7 @@ standard_library.install_aliases()
 from wetb.hawc2.ae_file import AEFile
 import numpy as np
 
-
-class PCFile(object):
+class PCFile(AEFile):
     """Read HAWC2 PC (profile coefficients) file
 
     examples
@@ -38,7 +37,9 @@ class PCFile(object):
     >>> pcfile.CM(36,10) # CM at radius=36m and AOA=10deg
     -0.1103
     """
-    def __init__(self, filename):
+    def __init__(self, filename, ae_filename):
+        AEFile.__init__(self, ae_filename)
+
         with open (filename) as fid:
             lines = fid.readlines()
         nsets = int(lines[0].split()[0])
-- 
GitLab