''' Created on 24/04/2014 @author: MMPE ''' from __future__ import print_function from __future__ import unicode_literals from __future__ import division from __future__ import absolute_import from io import open from builtins import range from future import standard_library standard_library.install_aliases() import numpy as np class AtTimeFile(object): """Loads an at time file generated by HAWC2 Functions are generated for each sensor in the file from the template: xxx(l=None, curved_length=False) E.g. twist(36, curved_length=True) # Twist 36m from the root along the (curved) center line twist(36) # Twist at radius 36m (Straight line radius, nondim. with bladetip_radius which must be specified in constructor) twist() # Twist at all aerodynamic calculation points >>> at = AtTimeFile("at.dat", 86.3655) # load file >>> at.attribute_names # Attribute names ['radius_s', 'twist', 'chord'] >>> at[:3,1]) # first 3 twist rows [-14.5 -14.5002 -14.5007] >>> at.twist()[:3]) # Twist first 3 twist rows [-14.5 -14.5002 -14.5007] >>> at.twist(36, curved_length=True) # Twist at curved_length = 36 (interpolated) -5.172195702789108 >>> at.twist(36) # Twist at radius = 36 (interpolated) -5.162084567646019 """ def __init__(self, filename, bladetip_radius=None): """ Parameters ---------- filename : string Filename bladetip_radius : int, float or None, optional Radius of blade tip. Used to convert from curved length to radius """ self.blade_radius = bladetip_radius with open(filename, encoding='utf-8') as fid: lines = fid.readlines() atttribute_name_line = [l.strip().startswith("# Radius_s") for l in lines].index(True) #self.attribute_names = lines[atttribute_name_line].lower().replace("#", "").split() self.attribute_names = [n.strip() for n in lines[atttribute_name_line].lower().split("#")[1:]] data = np.array([[float(l) for l in lines[i].split() ] for i in range(atttribute_name_line+1, len(lines))]) self.data = data def func_factory(column): def values(l=None, curved_length=False): assert curved_length==True or curved_length==False, "Curved length must be boolean, but is %s"%curved_length if l is None: return self.data[:, column] else: if curved_length: return np.interp(l, self.data[:, 0], self.data[:, column]) else: assert self.blade_radius is not None, "bladetip_radius must be specified in __init__ when requesting value of radius (alternatively you can request for curved_length)" return np.interp(l/self.blade_radius, self.data[:, 0]/self.data[-1, 0], self.data[:, column]) return values for column, att_name in enumerate(self.attribute_names): setattr(self, att_name, func_factory(column)) def radius_curved_ac(self, radius=None): """Radius (curved distance) of aerodynamic calculation point(s) Parameters ---------- radius : int or float, optional - if None (default): Radius of calculation points\n - if int or float: Radius of calculation point nearest radius Returns ------- radius : float or array_like Radius of calculation points or radius of calculation point nearest radius """ if radius is None: return self.radius_s() else: return self.radius_s()[np.argmin(np.abs(self.radius_s() - radius))] def value(self, radius, column): return np.interp(radius, self.data[:, 0], self.data[:, column]) def __getitem__(self, subset): return self.data[subset] if __name__ == "__main__": at = AtTimeFile(r"tests/test_files/at.dat", 86.3655) # load file at = AtTimeFile(r'U:\hama\HAWC2-AVATAR\res/avatar-7ntm-scaled-rad.dat') at.attribute_names # Attribute names at[:3,1] # first 3 twist rows print (len(at.attribute_names)) print ("\n".join(at.attribute_names)) print (at.data.shape) #at.twist()[:3] # Twist first 3 twist rows #print (at.twist(36, curved_length=True)) # Twist at curved_length = 36 (interpolated) #print (at.twist(36)) # Twist at 36 (interpolated)