예제 #1
0
    def comparison_graph(self):
        
        fig = plt.figure(figsize=(12,8))
        print(self.og_water_level)
        ax = fig.add_subplot('311')
        ax.plot(self.time_data, self.og_water_level, alpha=.5)
        
        ax2 = fig.add_subplot('312')
        ax2.plot(self.time_data, self.pressure_ts, alpha=.5)
#        
        ax3 = fig.add_subplot('313')
        ax3.plot(self.time_data, p2d.hydrostatic_method(self.pressure_ts))
        
        plt.show()
예제 #2
0
 def convert_back_to_wl(self):
     '''This converts the pressure back to water level using the hydrostatic assumption'''
     print(p2d.hydrostatic_method(self.pressure_ts))
     self.hyrdo_water_level = p2d.hydrostatic_method(self.pressure_ts)
예제 #3
0
 def derive_filtered_water_level(self, pressure_data, pressure_mean, \
                              sensor_orifice_elevation, salinity):
     
     return sensor_orifice_elevation + p2d.hydrostatic_method(pressure_data + pressure_mean,
                                                              salinity)
예제 #4
0
    def derive_statistics(self, p_chunks, t_chunks, elev_chunks, orif_chunks, wchunks=None, 
                          meters=True, salinity = "salt"):
        
        if meters == True:
            units = 1
        else:
            units = uc.METER_TO_FEET
       
        func_dict = {
                    'T1/3': lambda spec, freq, time, depth: self.stats.significant_wave_period(spec, freq, depth, time[1]-time[0]),
#                      'H1/3 std': lambda spec, freq, time, depth: self.stats.significant_wave_height_standard(depth \
#                                                                                 * units),
                    'H1/3': lambda spec, freq, time, depth: self.stats.significant_wave_height(spec,freq, time, depth \
                                                                                * units),
                    'H10%': lambda spec, freq, time, depth: self.stats.ten_percent_wave_height(spec,freq, time, depth \
                                                                                * units),
                    'H1%': lambda spec, freq, time, depth: self.stats.one_percent_wave_height(spec,freq, time, depth \
                                                                                * units),
                    'RMS': lambda spec, freq, time, depth: self.stats.rms_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Median': lambda spec, freq, time, depth: self.stats.median_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Maximum': lambda spec, freq, time, depth: self.stats.maximum_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Average': lambda spec, freq, time, depth: self.stats.average_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Average Z Cross': lambda spec, freq, time, depth: self.stats.average_zero_crossing_period(spec, freq, time, depth),
                    'Mean Wave Period': lambda spec, freq, time, depth: self.stats.mean_wave_period(spec, freq, time, depth),
                    'Crest': lambda spec, freq,time, depth: self.stats.crest_wave_period(spec, freq, time, depth),
                    'Peak Wave': lambda spec, freq, time, depth: self.stats.peak_wave_period(spec, freq, time, depth)
                    }
        
        stat_dict, upper_stat_dict, lower_stat_dict = {}, {}, {}
        stat_dict['time'] = [np.average(t) * 1000 for t in t_chunks]
    
        stat_dict['Frequency'], stat_dict['Spectrum'] = [], []
        stat_dict['HighSpectrum'], stat_dict['LowSpectrum'] = [], []
        
        #to adjust the units of the wave height calculations
        wave_height_funcs = ['H1/3', 'H10%', 'H1%', 'Median', 'RMS', 'Maximum', 'Average']
        
        for x in range(0,len(t_chunks)):
            
            elevation = np.mean(elev_chunks[x])
            instrument_height = np.abs(elevation - \
                               np.mean(orif_chunks[x]))
            water_depth = np.mean(p2d.hydrostatic_method(p_chunks[x], salinity)) + instrument_height
            
            freq, amp, high, low = self.stats.power_spectrum(p_chunks[x], t_chunks[x][1]-t_chunks[x][0], \
                                                             instrument_height, water_depth)
            
            
            stat_dict['Frequency'].append(freq)
            stat_dict['Spectrum'].append(amp)
            stat_dict['HighSpectrum'].append(high)
            stat_dict['LowSpectrum'].append(low)
            
        for y in func_dict:
            stat_dict[y] = []
            upper_stat_dict[y] = []
            lower_stat_dict[y] = []
            
        for x in range(0,len(stat_dict['time'])):
            for y in func_dict:
             
                if y in wave_height_funcs:
                    stat_dict[y].append(\
                                        self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['Spectrum'][x],stat_dict['Frequency'][x]) * units)
                    upper_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['HighSpectrum'][x],stat_dict['Frequency'][x]) * units)
                    lower_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['LowSpectrum'][x],stat_dict['Frequency'][x]) * units)
                else:
                    stat_dict[y].append(\
                                        self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['Spectrum'][x],stat_dict['Frequency'][x]))
                    upper_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['HighSpectrum'][x],stat_dict['Frequency'][x]))
                    lower_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['LowSpectrum'][x],stat_dict['Frequency'][x]))
      
        return [stat_dict, upper_stat_dict, lower_stat_dict]
예제 #5
0
 def derive_raw_water_level(self, sea_pressure_data, sensor_orifice_elevation, salinity):
     
     return sensor_orifice_elevation + p2d.hydrostatic_method(sea_pressure_data,
                                                              salinity)
예제 #6
0
    def derive_filtered_water_level(self, pressure_data, pressure_mean, \
                                 sensor_orifice_elevation, salinity):

        return sensor_orifice_elevation + p2d.hydrostatic_method(
            pressure_data + pressure_mean, salinity)
예제 #7
0
    def derive_raw_water_level(self, sea_pressure_data,
                               sensor_orifice_elevation, salinity):

        return sensor_orifice_elevation + p2d.hydrostatic_method(
            sea_pressure_data, salinity)
예제 #8
0
    def derive_statistics(self,
                          p_chunks,
                          t_chunks,
                          elev_chunks,
                          orif_chunks,
                          wchunks=None,
                          meters=True,
                          salinity="salt"):

        if meters == True:
            units = 1
        else:
            units = uc.METER_TO_FEET

        func_dict = {
                    'T1/3': lambda spec, freq, time, depth: self.stats.significant_wave_period(spec, freq, depth, time[1]-time[0]),
            #                      'H1/3 std': lambda spec, freq, time, depth: self.stats.significant_wave_height_standard(depth \
            #                                                                                 * units),
                    'H1/3': lambda spec, freq, time, depth: self.stats.significant_wave_height(spec,freq, time, depth \
                                                                                * units),
                    'H10%': lambda spec, freq, time, depth: self.stats.ten_percent_wave_height(spec,freq, time, depth \
                                                                                * units),
                    'H1%': lambda spec, freq, time, depth: self.stats.one_percent_wave_height(spec,freq, time, depth \
                                                                                * units),
                    'RMS': lambda spec, freq, time, depth: self.stats.rms_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Median': lambda spec, freq, time, depth: self.stats.median_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Maximum': lambda spec, freq, time, depth: self.stats.maximum_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Average': lambda spec, freq, time, depth: self.stats.average_wave_height(spec, freq, time, depth \
                                                                                * units),
                    'Average Z Cross': lambda spec, freq, time, depth: self.stats.average_zero_crossing_period(spec, freq, time, depth),
                    'Mean Wave Period': lambda spec, freq, time, depth: self.stats.mean_wave_period(spec, freq, time, depth),
                    'Crest': lambda spec, freq,time, depth: self.stats.crest_wave_period(spec, freq, time, depth),
                    'Peak Wave': lambda spec, freq, time, depth: self.stats.peak_wave_period(spec, freq, time, depth)
                    }

        stat_dict, upper_stat_dict, lower_stat_dict = {}, {}, {}
        stat_dict['time'] = [np.average(t) * 1000 for t in t_chunks]

        stat_dict['Frequency'], stat_dict['Spectrum'] = [], []
        stat_dict['HighSpectrum'], stat_dict['LowSpectrum'] = [], []

        #to adjust the units of the wave height calculations
        wave_height_funcs = [
            'H1/3', 'H10%', 'H1%', 'Median', 'RMS', 'Maximum', 'Average'
        ]

        for x in range(0, len(t_chunks)):

            elevation = np.mean(elev_chunks[x])
            instrument_height = np.abs(elevation - \
                               np.mean(orif_chunks[x]))
            water_depth = np.mean(p2d.hydrostatic_method(
                p_chunks[x], salinity)) + instrument_height

            freq, amp, high, low = self.stats.power_spectrum(p_chunks[x], t_chunks[x][1]-t_chunks[x][0], \
                                                             instrument_height, water_depth)

            stat_dict['Frequency'].append(freq)
            stat_dict['Spectrum'].append(amp)
            stat_dict['HighSpectrum'].append(high)
            stat_dict['LowSpectrum'].append(low)

        for y in func_dict:
            stat_dict[y] = []
            upper_stat_dict[y] = []
            lower_stat_dict[y] = []

        for x in range(0, len(stat_dict['time'])):
            for y in func_dict:

                if y in wave_height_funcs:
                    stat_dict[y].append(\
                                        self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['Spectrum'][x],stat_dict['Frequency'][x]) * units)
                    upper_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['HighSpectrum'][x],stat_dict['Frequency'][x]) * units)
                    lower_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['LowSpectrum'][x],stat_dict['Frequency'][x]) * units)
                else:
                    stat_dict[y].append(\
                                        self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['Spectrum'][x],stat_dict['Frequency'][x]))
                    upper_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['HighSpectrum'][x],stat_dict['Frequency'][x]))
                    lower_stat_dict[y].append(\
                                              self.process_chunk(func_dict[y],t_chunks[x],p_chunks[x],\
                                                           stat_dict['LowSpectrum'][x],stat_dict['Frequency'][x]))

        return [stat_dict, upper_stat_dict, lower_stat_dict]
예제 #9
0
def make_depth_file(water_fname, air_fname, out_fname, method='combo', purpose='storm_surge', csv = False, step = 1, \
                    tz = None, dayLightSavings = None, graph = True):
    """Adds depth information to a water pressure file.
    """
    
    #These two declarations may not be used for the new linear wave theory calculations
#     device_depth = -1 * nc.get_device_depth(water_fname)
#     water_depth = nc.get_water_depth(water_fname)
     
    #Get the timestep, sea pressure, time and qc
    timestep = 1 / nc.get_frequency(water_fname)
    sea_pressure = nc.get_pressure(water_fname)
    sea_time = nc.get_time(water_fname)
#     sea_qc = nc.get_pressure_qc(water_fname)
    
    #This is going to be reflected by O(t)
    init_orifice_elevation, final_orifice_elvation = \
    nc.get_sensor_orifice_elevation(water_fname)
    O = np.linspace(init_orifice_elevation, final_orifice_elvation, len(sea_pressure))
    
    #This if going to be reflected by B(t)
    init_land_surface_elevation, final_land_surface_elevation = \
    nc.get_land_surface_elevation(water_fname)
    B = np.linspace(init_land_surface_elevation, final_land_surface_elevation, len(sea_pressure))
    
    #Sensor orifice Elevation Minus Land Surface Elevation
    X = O - B
    
    #Get air pressure, time, interpolation, subtract from sea_pressure, and get air qc data
    raw_air_pressure = nc.get_air_pressure(air_fname)
    instr_dict = nc.get_instrument_data(air_fname, 'air_pressure')
    air_time = nc.get_time(air_fname)
    air_pressure = np.interp(sea_time, air_time, raw_air_pressure,
                             left=np.NaN, right=np.NaN)
    sea_pressure = sea_pressure - air_pressure
    raw_pressure = sea_pressure
    sea_pressure[np.where(air_pressure == np.NaN)] = np.NaN
    
    #Get index of first and last point of overlap
    itemindex = np.where(~np.isnan(sea_pressure))
    begin = itemindex[0][0]
    end = itemindex[0][len(itemindex[0]) - 1]
    print('indexes',begin,end)
    
    #Cut off the portion of time series that does not overlap
    sea_time = sea_time[begin:end]
    sea_pressure = sea_pressure[begin:end]
    air_pressure = air_pressure[begin:end]
    raw_pressure = raw_pressure[begin:end]
    O = O[begin:end]
    X = X[begin:end]
    
    #get the mean of the sea pressure
    sea_pressure_mean = np.mean(sea_pressure)
    print(sea_pressure_mean)
    sea_pressure = sea_pressure - sea_pressure_mean
    
    #if for storm surge low pass the pressure time series
    if purpose == 'storm_surge':
        sea_pressure = p2d.lowpass_filter(sea_pressure)
        
        
        sea_pressure = sea_pressure + sea_pressure_mean
        print('sugre pressure max', np.max(sea_pressure), len(sea_pressure))
    elif purpose == 'surface_waves':
        filtered_pressure = p2d.lowpass_filter(sea_pressure)
        sea_pressure = sea_pressure - filtered_pressure
        
        plt.plot(sea_time,sea_pressure, alpha=0.5)
        plt.plot(sea_time,filtered_pressure, alpha=0.5)
        plt.savefig('test.jpg')
        
        sea_pressure = sea_pressure + sea_pressure_mean
    elif purpose == 'get_max':
        
        filtered_pressure = p2d.lowpass_filter(sea_pressure)
        wave_sea_pressure = sea_pressure - filtered_pressure
        filtered_pressure = filtered_pressure + sea_pressure_mean
        p = sea_pressure + sea_pressure_mean
#         sea_pressure = sea_pressure + sea_pressure_mean
        surge_depth = p2d.hydrostatic_method(filtered_pressure)
        wave_depth = p2d.hydrostatic_method(wave_sea_pressure)
        combined_depth = p2d.hydrostatic_method(p)
        final_depth = np.array(O+surge_depth+wave_depth)
       
        index = final_depth.argmax()
        print(O[0], O[-1])
        print(final_depth[index] * unit_conversion.METER_TO_FEET, \
              unit_conversion.convert_ms_to_datestring(sea_time[index], pytz.UTC))
        return (final_depth[index], sea_time[index])
        
        
#     air_qc, bad_data = DataTests.run_tests(air_pressure,1,1)
        
    #"combo" refers to linear wave theory, "naive" refers to hydrostatic 
    if method == 'combo':
        pass
#         depth = p2d.combo_method(sea_time, sea_pressure,
#                                  device_depth, water_depth, timestep)
    elif method == 'naive':
        #return sensor orifice elevation plus the hydrostatic calculation of sea pressure
        depth = O + p2d.hydrostatic_method(sea_pressure)
        print('max depth', np.max(depth))
        raw_depth = O + p2d.hydrostatic_method(raw_pressure)
         
    if len(depth) == len(sea_pressure) - 1: # this is questionable
        depth = np.append(depth, np.NaN)
      
    if purpose == 'storm_surge':
        nc.custom_copy(water_fname, out_fname, begin, end, mode = 'storm_surge', step=step)
        nc.set_global_attribute(out_fname, 'time_coverage_resolution','P1.00S')
    else:  
        #copy all attributes from sea_pressure file
        nc.custom_copy(water_fname, out_fname, begin, end, mode = 'storm_surge', step=step)
#         shutil.copy(water_fname, out_fname)
#         sea_uuid = nc.get_global_attribute(water_fname, 'uuid')
#         nc.set_var_attribute(water_fname, 'sea_pressure', 'sea_uuid', sea_uuid)
#         nc.set_global_attribute(out_fname, 'uuid', uuid.uuid4())
    
    # append air pressure
    nc.append_air_pressure(out_fname, air_pressure[::step], air_fname)
    nc.set_instrument_data(out_fname, 'air_pressure', instr_dict)
    air_uuid = nc.get_global_attribute(air_fname, 'uuid')
    nc.set_var_attribute(out_fname, 'air_pressure', 'air_uuid', air_uuid)
    
    #update the lat and lon comments
    lat_comment = nc.get_variable_attr(out_fname, 'latitude', 'comment')
    nc.set_var_attribute(out_fname, 'latitude', 'comment',  \
                         ''.join([lat_comment, ' Latitude of sea pressure sensor used to derive ' \
                                  'sea surface elevation.']))
    lon_comment = nc.get_variable_attr(out_fname, 'longitude', 'comment')
    nc.set_var_attribute(out_fname, 'longitude', 'comment',  \
                         ''.join([lon_comment, ' Longitude of sea pressure sensor used to derive ' \
                                  'sea surface elevation.']))
    
    #set sea_pressure instrument data to global variables in water_level netCDF
    sea_instr_data = nc.get_instrument_data(water_fname,'sea_pressure')
    for x in sea_instr_data:
        attrname = ''.join(['sea_pressure_',x])
        nc.set_global_attribute(out_fname,attrname,sea_instr_data[x])
        
    nc.set_global_attribute(out_fname,'summary','This file contains two time series: 1)' 
                            'air pressure 2) sea surface elevation.  The latter was derived'
                            ' from a time series of high frequency sea pressure measurements '
                            ' adjusted using the former and then lowpass filtered to remove '
                            ' waves of period 1 second or less.')
    
    lat = nc.get_variable_data(out_fname, 'latitude')
    lon = nc.get_variable_data(out_fname, 'longitude')
    stn_station = nc.get_global_attribute(out_fname, 'stn_station_number')
#     stn_id = nc.get_global_attribute(out_fname, 'stn_instrument_id')
    first_stamp = nc.get_global_attribute(out_fname, 'time_coverage_start')
    last_stamp = nc.get_global_attribute(out_fname, 'time_coverage_end')
    
    nc.set_global_attribute(out_fname,'title','Calculation of water level at %.4f latitude,'
                            ' %.4f degrees longitude from the date range of %s to %s.'
                            % (lat,lon,first_stamp,last_stamp))
    
#     nc.append_depth_qc(out_fname, sea_qc[begin:end], air_qc, purpose)
    nc.append_depth(out_fname, depth[::step])
    nc.append_variable(out_fname, 'raw_depth', raw_depth[::step], 'raw_depth', 'raw_depth')
    nc.set_var_attribute(out_fname, 'water_surface_height_above_reference_datum', \
                         'air_uuid', air_uuid)
    
    if csv == True:
        
        #adjust date times to appropriate time zone
        format_time = [unit_conversion.convert_ms_to_date(x, pytz.utc) for x in sea_time[::step]]
        format_time = unit_conversion.adjust_from_gmt(format_time, tz, dayLightSavings)
        format_time = [x.strftime('%m/%d/%y %H:%M:%S') for x in format_time]
        
        #convert decibars to inches of mercury
        format_air_pressure = air_pressure * unit_conversion.DBAR_TO_INCHES_OF_MERCURY
    
        #convert meters to feet
        format_depth = depth * unit_conversion.METER_TO_FEET
        
        if dayLightSavings != None and dayLightSavings == True: 
            column1 = '%s Daylight Savings Time' % tz 
        else:
            column1 = '%s Time' % tz 
            
        excelFile = pd.DataFrame({column1: format_time, 
                                  'Air Pressure in Inches of Hg': format_air_pressure[::step],
                                  'Storm Tide Water Level in Feet': format_depth[::step]})
        
        #append file name to new excel file
        last_index = out_fname.find('.')
        out_fname = out_fname[0:last_index]
        
        last_index = out_fname.find('.')
        #save with csv extension if not already done so
        if out_fname[last_index:] != '.csv':
            
            if last_index < 0:
                out_file_name = ''.join([out_fname,'.csv'])
            else:
                out_file_name = ''.join([out_fname[0:last_index],'.csv'])
        else:
            out_file_name = out_fname
            
        with open(out_file_name, 'w') as csvfile:
            writer = csv_package.writer(csvfile, delimiter=',')
            
            
            csv_header = ["","Latitude: %.4f" % lat, 'Longitude: %.4f' % lon, \
                'STN_Station_Number: %s' % stn_station]
            writer.writerow(csv_header)
           
        
        excelFile.to_csv(path_or_buf=out_file_name, mode='a', columns=[column1,
                                                             'Water Level in Feet',
                                                             'Air Pressure in Inches of Hg'])