xdenisx

Ice targets Stat

Oct 18th, 2014
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.80 KB | None | 0 0
  1. import xlrd
  2. import datetime
  3. import sys
  4. import shapefile as sf
  5. import numpy as np
  6. from math import pi, cos, sin, radians, degrees, atan2
  7. import math
  8. from pylab import *
  9.  
  10. def nautical(kilometers=0, meters=0, miles=0, feet=0):
  11.     nm = 0.
  12.     if feet:
  13.         miles += feet / ft(1.)
  14.     if miles:
  15.         kilometers += km(miles=miles)
  16.     if meters:
  17.         kilometers += meters / 1000.
  18.     nm += kilometers / 1.852
  19.     return nm
  20.  
  21. ''' Distance and azimuth '''
  22. def dist(llat1,llong1,llat2,llong2):
  23.     rad = 6372795
  24.    
  25.     lat1 = llat1*math.pi/180.
  26.     lat2 = llat2*math.pi/180.
  27.     long1 = llong1*math.pi/180.
  28.     long2 = llong2*math.pi/180.
  29.  
  30.     cl1 = math.cos(lat1)
  31.     cl2 = math.cos(lat2)
  32.     sl1 = math.sin(lat1)
  33.     sl2 = math.sin(lat2)
  34.     delta = long2 - long1
  35.     cdelta = math.cos(delta)
  36.     sdelta = math.sin(delta)
  37.  
  38.     y = math.sqrt(math.pow(cl2*sdelta,2)+math.pow(cl1*sl2-sl1*cl2*cdelta,2))
  39.     x = sl1*sl2+cl1*cl2*cdelta
  40.     ad = math.atan2(y,x)
  41.     dist = ad*rad
  42.  
  43.     x = (cl1*sl2) - (sl1*cl2*cdelta)
  44.     y = sdelta*cl2
  45.     z = math.degrees(math.atan(-y/x))
  46.  
  47.     if (x < 0):
  48.         z = z+180.
  49.  
  50.     z2 = (z+180.) % 360. - 180.
  51.     z2 = - math.radians(z2)
  52.     anglerad2 = z2 - ((2*math.pi)*math.floor((z2/(2*math.pi))) )
  53.     angledeg = (anglerad2*180.)/math.pi
  54.  
  55.     #print 'Distance >> %.0f %s' % (dist/1000., ' [km]')
  56.     #print 'Initial bearing >> ', angledeg, '[degrees]'
  57.     return dist, angledeg
  58.  
  59. ''' Create prj file '''
  60. def create_prj(shp_filename):
  61.     # create the PRJ file
  62.     prjfn = shp_filename
  63.     prj = open("%s.prj" % prjfn, "w")
  64.     epsg = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]]'
  65.     prj.write(epsg)
  66.     prj.close()  
  67.     w.save(shp_filename)
  68.  
  69. ''' Redefine type of an ice object based on length '''
  70. def define_type(ll):
  71.     if ll<5.:
  72.         return 'Growler'
  73.     if ll>=5. and ll<=15:
  74.         return 'Bergy Bit'
  75.     if ll>15. and ll<=60:
  76.         return 'Small'
  77.     if ll>60. and ll<=120:
  78.         return 'Medium'
  79.     if ll>120. and ll<=200:
  80.         return 'Large'
  81.     if ll>200. and ll<=300:
  82.         return 'Very Large'
  83.     if ll>300.:
  84.         return 'Ice Island'
  85.  
  86. '''Statistics'''
  87.  
  88. def av_azimuth(direction):
  89.     # Averaging azimuth
  90.     try:
  91.         d = np.array(direction)
  92.         rads = [radians(i) for i in d]
  93.         ave = lambda x: sum(x)/len(x)
  94.         rotate = lambda x: x+2*(pi) if x<0 else x
  95.         # Calculate the averages
  96.         sa = ave([sin(i) for i in rads]) # Average of the sines
  97.         ca = ave([cos(i) for i in rads]) # Average of the cosines
  98.         # Take the arctan of the averages, rotate to positive values, and then
  99.         # convert back to degrees.
  100.         d_mean = degrees(rotate(atan2(sa,ca)))
  101.         return d_mean
  102.     except:
  103.         print 'cannot calculate azimuth'
  104.         return 9999.
  105.  
  106. def statistics(width, length, height, speed, direction):
  107.     print '\nTotal: %s' % total_number
  108.  
  109.     w = np.array(width)
  110.     l = np.array(length)
  111.     h = np.array(height)
  112.     s = np.array(speed)
  113.     d = np.array(direction)
  114.  
  115.     # width/length/heigth mean values
  116.     w_mean = w.mean()
  117.     l_mean = l.mean()
  118.     h_mean = h.mean()
  119.     s_mean = s.mean()
  120.  
  121.     # Averaging azimuth
  122.     try:
  123.         rads = [radians(i) for i in d]
  124.         ave = lambda x: sum(x)/len(x)
  125.         rotate = lambda x: x+2*(pi) if x<0 else x
  126.         # Calculate the averages
  127.         sa = ave([sin(i) for i in rads]) # Average of the sines
  128.         ca = ave([cos(i) for i in rads]) # Average of the cosines
  129.         # Take the arctan of the averages, rotate to positive values, and then
  130.         # convert back to degrees.
  131.         d_mean = degrees(rotate(atan2(sa,ca)))
  132.     except:
  133.         print 'cannot calculate azimuth'
  134.  
  135.     try:
  136.         print '\nMean values\n Width: %5.2f m \n Length: %5.2f m \n Higth: %5.2f m\
  137. \n Speed: %5.2f kt\n Direction: %5.0f degrees\n' % \
  138.       (w_mean, l_mean, h_mean, s_mean, d_mean)
  139.     except:
  140.         pass
  141.  
  142.     u_type = set(type)
  143.     #print u_type
  144.     # all targets number
  145.     all_targets_ch = 0
  146.     for itype in u_type:
  147.         i = 0
  148.         for iitype in type:
  149.             if iitype == itype:
  150.                 i = i + 1
  151.         print '%s = %d' % (itype, i)
  152.         all_targets_ch = all_targets_ch + i
  153.  
  154.     # checking total targets
  155.     print '\nTotal\All types: %s\%d\n' % (total_number, all_targets_ch)
  156.  
  157.     # Statistics on ships
  158.     u_ship = set(ship)
  159.     print '*****************************'
  160.     print '*** Statistics on vessels ***'
  161.     print '*****************************'
  162.     for iship in u_ship:
  163.         i = 0
  164.         for iiship in ship:
  165.             if iiship == iship:
  166.                 i = i + 1          
  167.         print '%s = %d' % (iship, i)
  168.  
  169. def make_pie_plot(par, ititle, ilabels, ifracs, iexplode):
  170.     plt.clf()
  171.     # make a square figure and axes
  172.     figure(1, figsize=(6,6))
  173.     ax = axes([0.1, 0.1, 0.8, 0.8])
  174.  
  175.     # The slices will be ordered and plotted counter-clockwise.
  176.     labels = ilabels
  177.     fracs = ifracs
  178.     explode = iexplode
  179.  
  180.     pie(fracs, explode=explode, labels=labels,
  181.                 autopct='%1.1f%%', shadow=True)
  182.                 # The default startangle is 0, which would start
  183.                 # the Frogs slice on the x-axis.  With startangle=90,
  184.                 # everything is rotated counter-clockwise by 90 degrees,
  185.                 # so the plotting starts on the positive y-axis.
  186.  
  187.     title(ititle, bbox={'facecolor':'0.8', 'pad':5})
  188.  
  189.     savefig('pics\\%s.png' % par)
  190.            
  191. ############################
  192. ### Main Program
  193. ############################
  194. source = 'vessel_targets'
  195. ff = sys.argv[1]
  196. width = []
  197. length = []
  198. height = []
  199. speed = []
  200. direction = []
  201. type = []
  202. ship = []
  203. temp_width = []
  204. temp_length = []
  205. temp_hight = []
  206. temp_speed = []
  207. temp_direction = []
  208. temp_type = []
  209. all_target_statistics = []
  210.  
  211. ###########################
  212. #### Shapefile creation
  213. ###########################
  214. shp_filename = 'shp\\%s' % source # ff.split('.')[0] #'updated_targets.shp'
  215. # create the shapefile
  216. w = sf.Writer(sf.POLYLINE)
  217.  
  218. w.field('name','C','90')
  219. w.field('type','C','90')
  220. w.field('start','C','90')
  221. w.field('end','C','90')
  222. w.field('number_obs','C','90')
  223. w.field('av_width','C','90')
  224. w.field('av_length','C','90')
  225. w.field('av_height','C','90')
  226. w.field('av_speed','C','90')
  227. w.field('azimuth','C','90')
  228. ############################
  229.  
  230. iid = 0
  231.  
  232. rb = xlrd.open_workbook(ff,formatting_info=True)
  233. sheet = rb.sheet_by_index(0)
  234.  
  235. names = []
  236.  
  237. for rownum in range(sheet.nrows):
  238.     row = sheet.row_values(rownum)
  239.     try:
  240.         names.append(row[0])
  241.     except:
  242.         pass
  243.  
  244. unique_names = set(names)
  245.  
  246. ilist = []
  247. # lat/lons lists
  248. llat = []
  249. llon = []
  250. names = []
  251.  
  252. lll = []
  253.  
  254. # Total number of tracks
  255. total_number = 0
  256.  
  257. # Drift rose file
  258. ff_rose = open('txt\\speed_dir.txt','w')
  259. # File within numbers of observations
  260. num_obs_ll = []
  261. ff_obs = open('txt\\numbers_obs.csv','w')
  262. ff_obs.write('ID,Observations,\n')
  263. # Size statistics
  264. ff_sizes = open('txt\\vessel_target_av_size.csv','w')
  265. ff_sizes.write('ID,Type,Start Date,End Date,Num of obs,Width,Length,Height,Speed,Direction,\n')
  266.  
  267. for iname in unique_names:
  268.     for rownum in range(sheet.nrows):
  269.         row = sheet.row_values(rownum)
  270.         if row[0]==iname and row[13]=="Vessel":
  271.             # List withing all data for a current target
  272.             if (float(row[6])>50. and float(row[6])<90. and float(row[5])>69. and float(row[5])<78.):
  273.                 ilist.append({'name':row[0], 'type':row[2], 'date':row[4], \
  274.                       'lat':row[5], 'lon':row[6], 'direction':row[7], \
  275.                       'speed':row[8], 'hight':row[9], 'width':row[10], \
  276.                       'length':row[11], 'mass':row[12], 'sources':row[13], \
  277.                       'note':row[14], 'entered':row[15]})
  278.     try:
  279.         if len(ilist)>0:
  280.             #print '%s %s' % (iname, len(ilist))
  281.             # List within number of observations    
  282.             num_obs_ll.append([iname, len(ilist)])
  283.             # Total number of tracks
  284.             total_number = total_number + 1
  285.             #print iname
  286.             sorted_list = sorted(ilist, key=lambda x: datetime.datetime.strptime(x['date'],\
  287.                                                                     '%m/%d/%Y %I:%M:%S %p'))
  288.  
  289.             # Start and End date of measaurments
  290.             start_date = sorted_list[0]['date']
  291.             end_date = sorted_list[-1]['date']
  292.             #print start_date, end_date
  293.      
  294.             # Looking through elements of a list and retrieve parameters
  295.             for key in sorted_list:
  296.                 # lat lon              
  297.                 lll.append([float(key['lon']),float(key['lat'])])                
  298.                 # Sizes and types
  299.                 try:
  300.                     # Lists for overall and current statistics
  301.                     if key['width']<>'':
  302.                         width.append(float(key['width']))
  303.                         temp_width.append(float(key['width']))                        
  304.                     if key['length']<>'':
  305.                         length.append(float(key['length']))
  306.                         temp_length.append(float(key['length']))
  307.                     if key['hight']<>'':
  308.                         height.append(float(key['hight']))
  309.                         temp_hight.append(float(key['hight']))
  310.                     if key['speed']<>'':
  311.                         if float(key['speed'])<3.:
  312.                             speed.append(float(key['speed']))
  313.                             temp_speed.append(float(key['speed']))
  314.                             # Speed and direction to a file
  315.                             ff_rose.write('%s %s\n' % (float(key['speed']),float(key['direction'])))
  316.                     if key['direction']<>'':
  317.                         direction.append(float(key['direction']))
  318.                         temp_direction.append(float(key['direction']))  
  319.  
  320.                     if key['entered']<>'':
  321.                         ship.append(key['entered'])
  322.  
  323.                      # Redefine type
  324.                     if key['length']<>'':
  325.                         ll = float(key['length'])
  326.                         new_type = define_type(ll)
  327.                         type.append(new_type)
  328.                         temp_type.append(new_type)
  329.                     else:
  330.                         type.append(key['type'])
  331.                         temp_type.append(key['type'])
  332.                 except:
  333.                     pass
  334.  
  335.                  
  336.             # Filtering wrong coordinates by distance
  337.             # Firs values
  338.             lon_prev = float(lll[0][0])
  339.             lat_prev = float(lll[0][1])
  340.             #print "%s lon: %s lat: %s" % (iname, lon_prev, lat_prev)
  341.             ch = 0
  342.             for ii in lll:
  343.                 # Check the distance between coordinates
  344.                 #print ii
  345.                 llat2  = float(ii[1])
  346.                 llong2 = float(ii[0])
  347.                 try:
  348.                     d, a = dist(lat_prev, lon_prev, llat2,llong2)
  349.                     dist_nm = nautical(meters = d)
  350.                     # If distance > 30 then delete an element
  351.                     if dist_nm>30:
  352.                         #print "%.2f [nm]" % dist_nm
  353.                         del lll[ch]
  354.                 except:
  355.                    
  356.                     dist_nm = 0.
  357.                 ch = ch + 1
  358.  
  359.             # Current statistics on each track
  360.             w_mean = np.array(temp_width).mean()
  361.             l_mean = np.array(temp_length).mean()
  362.             h_mean = np.array(temp_hight).mean()
  363.             s_mean = np.array(temp_speed).mean()
  364.             d_mean = av_azimuth(temp_direction)
  365.  
  366.             if len(temp_type)==0:
  367.                 temp_type='Unknown'
  368.             else:
  369.                 temp_type = temp_type[0]
  370.            
  371.             if np.isnan(w_mean)==True:
  372.                 w_mean = 9999.
  373.             if np.isnan(l_mean)==True:
  374.                 l_mean = 9999.
  375.             if np.isnan(h_mean)==True:
  376.                 h_mean = 9999.
  377.             if np.isnan(s_mean)==True:
  378.                 s_mean = 9999.
  379.             if np.isnan(d_mean)==True:
  380.                 d_mean = 9999.
  381.  
  382.             # Add al data to a dictonary
  383.             all_target_statistics.append({'name':iname, 'type':temp_type, 'date1':start_date, \
  384.                                     'date2':end_date, 'num_obs': len(sorted_list), \
  385.                                     'width':w_mean, 'length':l_mean, 'height':h_mean, \
  386.                                     'speed':s_mean, 'direction':d_mean})
  387.            
  388.             temp_width = []
  389.             temp_length = []
  390.             temp_hight = []
  391.             temp_speed = []
  392.             temp_direction = []
  393.            
  394.                
  395.     except:
  396.         print 'Error! iname: %s' % iname  
  397.     try:
  398.         ilast = sorted_list[-1]
  399.     except:
  400.         pass
  401.  
  402.     #############################
  403.     ### Shapefile creation
  404.     #############################
  405.     try:
  406.         if len(lll)>0:
  407.             w.line(parts=[lll])
  408.             w.record('%s' % iname,'%s' % temp_type,'%s' % start_date, '%s' % end_date, str(len(sorted_list)),\
  409.                      str('%5.1f' % w_mean),str('%5.1f' % l_mean), str('%5.1f' % h_mean), str('%5.1f' % s_mean), str('%5.1f' % d_mean))
  410.                                                                          
  411.     except:
  412.         pass
  413.     temp_type = []
  414.     lll = []
  415.     # make an empty list
  416.     ilist = []
  417.  
  418. try:              
  419.     all_targets_sorted_list = sorted(all_target_statistics, key=lambda x: (x['name']))
  420.     for i in range(0,len(all_targets_sorted_list)):
  421.         ff_sizes.write('%s,%s,%s,%s,%d,%5.1f,%5.1f,%5.1f,%5.1f,%5.0f\n' % (all_targets_sorted_list[i]['name'],all_targets_sorted_list[i]['type'],all_targets_sorted_list[i]['date1'],all_targets_sorted_list[i]['date2'],\
  422.                                                                                        all_targets_sorted_list[i]['num_obs'],all_targets_sorted_list[i]['width'],all_targets_sorted_list[i]['length'],\
  423.                                                                                        all_targets_sorted_list[i]['height'],all_targets_sorted_list[i]['speed'],all_targets_sorted_list[i]['direction']))
  424. except:
  425.     pass
  426.  
  427.  
  428. # Get statistics
  429. try:
  430.     statistics(width, length, height, speed, direction)
  431. except:
  432.     "Statistics error"
  433.  
  434. create_prj(shp_filename)
  435.  
  436. # Plots
  437. # Size Distribution
  438. ilabels = 'Growler', 'Bergy Bit', 'Small'
  439. ifracs = [27, 49, 91]
  440. iexplode=(0, 0.05, 0)
  441. par = 'Types'
  442. ititle = 'Size Distribution of Ice Targets'
  443. make_pie_plot(par, ititle, ilabels, ifracs, iexplode)
  444.  
  445. # Close txt files
  446. ff_rose.close()
  447. sorted_num_obs_ll = sorted(num_obs_ll, key=lambda x: x[1], reverse=True)
  448. for iid,inum in sorted_num_obs_ll:
  449.     ff_obs.write('%s,%s\n' % (iid,inum))
  450.  
  451. ff_obs.close()
  452. ff_sizes.close()
Advertisement
Add Comment
Please, Sign In to add comment