def log(pro, logname, savepng=True): """ Log processed data (*.csv) and echograms (*.png) in rapidkrill/log/. Args: pro (dict): processed data output from "process" routine. logname (str ): directory name under which log results will be saved. savepng (bool): True to save echogram images, False to skip it. """ # Load processed data variables rawfiles = pro['rawfiles'] transect = pro['transect'] t120 = pro['t120'] r120 = pro['r120'] Sv120 = pro['Sv120'] Sv120sw = pro['Sv120sw'] t120r = pro['t120r'] nm120r = pro['nm120r'] lon120r = pro['lon120r'] lat120r = pro['lat120r'] sbline120r = pro['sbliner'][0, :] NASC120swr = pro['NASC120swr'][0, :] pc120swr = pro['pc120swr'][0, :] # Build summary results results = { 'Time': np.array(t120r[:-1], dtype=str), 'Longitude': np.round(lon120r[:-1], 5), 'Latitude': np.round(lat120r[:-1], 5), 'Transect': np.ones(len(t120r[:-1]), dtype=int) * transect, 'Miles': nm120r[:-1], 'Seabed': np.round(sbline120r[:-1], 1), 'NASC': np.round(NASC120swr[:-1], 2), '% samples': np.round(pc120swr[:-1], 1) } results = pd.DataFrame(results, columns=[ 'Time', 'Longitude', 'Latitude', 'Transect', 'Miles', 'Seabed', 'NASC', '% samples' ]) # Create new log subdirectory path = os.path.join(os.path.dirname(__file__), '..', 'log', logname, '') if not os.path.exists(path): os.makedirs(path) # Write results in CSV log file with open(path + logname + '.csv', 'a') as f: results.to_csv(path + logname + '.csv', index=False, mode='a', header=f.tell() == 0) # save png image if savepng: # set figure plt.close() plt.figure(figsize=(8, 8)) plt.subplots_adjust(left=0.066, right=1.055, bottom=0.065, top=0.985, wspace=0, hspace=0.05) plt.rcParams.update({'font.size': 9, 'lines.linewidth': 1}) # plot raw echogram plt.subplot(211).invert_yaxis() im = plt.pcolormesh(t120, r120, Sv120, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.colorbar(im).set_label('Sv raw (dB re 1m$^{-1}$)') plt.gca().set_ylim(270, 0) plt.gca().set_ylabel('Depth (m)') plt.gca().set_xlim(t120r[0], t120r[-1]) plt.gca().set_xticks(t120r[[0, -1]]) plt.tick_params(labelright=False, labelbottom=False) # plot processed echogram ax = plt.subplot(212) ax = [ax, ax.twinx()] im = ax[0].pcolormesh(t120, r120, Sv120sw, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.colorbar(im).set_label('Sv pro (dB re 1m$^{-1}$)') ax[0].invert_yaxis() ax[0].set_ylim(270, 0) ax[0].set_ylabel('Depth (m)') # overlay distance/NASC info for t, nm, NASC in zip(t120r[:-1], nm120r[:-1], NASC120swr[:-1]): ax[1].plot([t, t], [0, 1], color=[0, .8, 0], linewidth=2) ax[1].text(t, .95, ' ' + str(transect) + ': ' + str(round(nm, 2)), fontweight='bold', color=[0, .8, 0]) ax[1].text(t, .02, ' ' + str(round(NASC, 2)), fontweight='bold', color=[1, 0, 0]) ax[1].set_ylim(0, 1) ax[1].set_xlim(t120r[0], t120r[-1]) ax[1].set_xticks(t120r[[0, -1]]) ax[1].tick_params(labelright=False) ax[1].xaxis.set_major_formatter(mdates.DateFormatter('%d%b-%H:%M:%S')) # save figure pf = rawfiles[0].split('-')[0] fn = pd.to_datetime(str(t120[0])).strftime(pf + '-D%Y%m%d-T%H%M%S') plt.savefig(path + fn + '.png', figsize=(8, 8), dpi=100)
# ============================================================================= # Seabed masking # ============================================================================= print('Masking seabed...') r0, r1, roff, thr = 10, 1000, 10, (-40, -60) # (m, m, m, dB) mask38sb = maskSB.maxSv(Sv38smooth, r38, r0=r0, r1=r1, roff=roff, thr=thr) Sv38sboff = Sv38.copy() Sv38sboff[mask38sb] = np.nan # ============================================================================= # plot results # ============================================================================= print('Displaying results...') plt.figure(figsize=(8, 6)) c = cmaps() plt.subplot(211).invert_yaxis() plt.pcolormesh(t38, r38, Sv38, vmin=-80, vmax=-50, cmap=c.ek500) plt.colorbar().set_label('dB') plt.ylabel('Depth (m)') plt.tick_params(labelbottom=False) plt.title('Sv 38 kHz') plt.subplot(212).invert_yaxis() plt.pcolormesh(t38, r38, Sv38sboff, vmin=-80, vmax=-50, cmap=c.ek500) plt.colorbar().set_label('dB') plt.ylabel('Depth (m)') plt.xlabel('Time (dd HH:MM)') plt.title('Sv 38 kHz - seabed masked')
m120sn = mSN.derobertis(Sv120, bn120, thr=12) # In this case, Sv samples 12 dB above the background noise estimation, or # lower, will be masked. # ----------------------------------------------------------------------------- # use the mask to turn the Sv samples into "empty water" (-999) Sv120clean[m120sn] = -999 #------------------------------------------------------------------------------ # Figures plt.figure(figsize=(8, 7)) # Sv original plt.subplot(311).invert_yaxis() plt.pcolormesh(p120, r120, Sv120, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.tick_params(labelbottom=False) plt.colorbar() plt.title('Sv original') # Background noise estimation plt.subplot(312).invert_yaxis() plt.pcolormesh(p120, r120, bn120, cmap=cmaps().ek500) plt.tick_params(labelbottom=False) plt.ylabel('Depth (m)') plt.colorbar() plt.title('Background noise') # Sv after correcting for background noise plt.subplot(313).invert_yaxis() plt.pcolormesh(p120, r120, Sv120clean, vmin=-80, vmax=-50, cmap=cmaps().ek500)
Sv120cvv = tf.log(convolve2d(tf.lin(Sv120clean), k, 'same', boundary='symm')) #------------------------------------------------------------------------------ # Mask swarms using Weill's algorithm m120sh = mSH.weill(Sv120cvv, thr=-70, maxvgap=15, maxhgap=0, minhlen= 3, minvlen=15)[0] #------------------------------------------------------------------------------ # Figures plt.figure(figsize=(8,5)) plt.subplots_adjust(left=0.08, right=0.91, bottom=0.08, top=0.95, wspace=0.08) gs = gridspec.GridSpec(1, 3, width_ratios=[1, 1, .05]) # Sv original plt.subplot(gs[0]).invert_yaxis() im= plt.pcolormesh(t120, r120, Sv120, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.ylabel('Depth (m)') plt.xlabel('Time (dd HH:MM)') plt.title('Sv') # Swarms mask plt.subplot(gs[1]).invert_yaxis() plt.pcolormesh(t120, r120, m120sh*1, cmap='Greys') plt.tick_params(labelleft=False) plt.xlabel('Time (dd HH:MM)') plt.title('Swarms') # colorbar ax=plt.subplot(gs[2]) plt.colorbar(im, cax=ax).set_label('dB re m$^{-1}$')
def log(pro, outputdir, savepng=True): """ Log processed data (*.csv) and echograms (*.png) in rapidkrill/log/. Args: pro (dict): processed data output from "process" routine. outputdir (str ): directory name under which log results will be saved. savepng (bool): True to save echogram images, False to skip it. """ results_data = get_results(pro) results = pd.DataFrame(results_data, columns=[ 'Time', 'Longitude', 'Latitude', 'Transect', 'Miles', 'Seabed', 'NASC', '% samples' ]) # Create new log subdirectory if not os.path.exists(outputdir): os.makedirs(outputdir) csvfile = os.path.join(outputdir, 'output.csv') # Write results in CSV log file with open(csvfile, 'a') as f: results.to_csv(csvfile, index=False, mode='a', header=f.tell() == 0) # save png image if savepng: rawfiles = pro['rawfiles'] transect = pro['transect'] t120 = pro['t120'] t120r = pro['t120r'] t120intrvls = pro['t120intervals'] nm120r = pro['nm120r'] r120 = pro['r120'] Sv120 = pro['Sv120'] Sv120sw = pro['Sv120sw'] NASC120swr = pro['NASC120swr'][0, :] # set figure plt.close() plt.figure(figsize=(8, 8)) plt.subplots_adjust(left=0.066, right=1.055, bottom=0.065, top=0.985, wspace=0, hspace=0.05) plt.rcParams.update({'font.size': 9, 'lines.linewidth': 1}) # plot raw echogram plt.subplot(211).invert_yaxis() im = plt.pcolormesh(t120, r120, Sv120, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.colorbar(im).set_label('Sv raw (dB re 1m$^{-1}$)') plt.gca().set_ylim(270, 0) plt.gca().set_ylabel('Depth (m)') plt.gca().set_xlim(t120intrvls[0], t120intrvls[-1]) plt.gca().set_xticks(t120intrvls[[0, -1]]) plt.tick_params(labelright=False, labelbottom=False) # plot processed echogram ax = plt.subplot(212) ax = [ax, ax.twinx()] im = ax[0].pcolormesh(t120, r120, Sv120sw, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.colorbar(im, ax=ax).set_label('Sv pro (dB re 1m$^{-1}$)') ax[0].invert_yaxis() ax[0].set_ylim(270, 0) ax[0].set_ylabel('Depth (m)') # overlay distance/NASC info for t, nm, NASC in zip(t120r, nm120r, NASC120swr): ax[1].plot([t, t], [0, 1], color=[0, .8, 0], linewidth=2) ax[1].text(t, .95, ' ' + str(transect) + ': ' + str(round(nm, 2)), fontweight='bold', color=[0, .8, 0]) ax[1].text(t, .02, ' ' + str(round(NASC, 2)), fontweight='bold', color=[1, 0, 0]) ax[1].set_ylim(0, 1) ax[1].set_xlim(t120intrvls[0], t120intrvls[-1]) ax[1].set_xticks(t120intrvls[[0, -1]]) ax[1].tick_params(labelright=False) ax[1].xaxis.set_major_formatter(mdates.DateFormatter('%d%b-%H:%M:%S')) # save figure pf = rawfiles[0].split('-')[0] fn = pd.to_datetime(str(t120[0])).strftime(pf + '-D%Y%m%d-T%H%M%S') imagefile = os.path.join(outputdir, fn + '.png') fig, ax = plt.subplots() fig.set_size_inches(8, 8) plt.savefig(imagefile, dpi=100) plt.close()
#------------------------------------------------------------------------------ # integrate Nautical Area Scattering Coefficient (NASC), from 20 to 250 metres NASC, NASCper = tf.Sv2NASC(Sv38inoff, r38, 20, 250, method='sum') # note the sum method is used. # the second output is the percentange vertical samples integrated behind every # computation of NASC. #------------------------------------------------------------------------------ # Figures plt.figure(figsize=(8, 6)) # Sv with impulse noise removed plt.subplot(311).invert_yaxis() plt.pcolormesh(t38, r38, Sv38inoff, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.tick_params(labelbottom=False) plt.ylabel('Depth (m)') plt.title('Sv with impulse noise removed') # integrated sa ax = plt.subplot(312) ax = [ax, ax.twinx()] ax[0].plot(t38, sa, '-r') ax[0].set_xlim(t38[0], t38[-1]) ax[0].tick_params(axis='y', colors='r') ax[0].yaxis.tick_left() ax[0].yaxis.set_label_position("left") ax[0].set_ylabel('s$_a$ (m$^2$ m$^{-2}$)', color='r') ax[0].tick_params(labelbottom=False) ax[1].plot(t38, saper, '-b')
# This time we set "log=False" becaue theta is already at linear scale. # "log=False" is the default, so might skip this setting. #------------------------------------------------------------------------------ # Resample Sv and theta back to full resolution. Sv120rsf, m120rsf_ = rs.full(Sv120rs, r120rs, t120rs, r120, t120) theta120rsf, m120rsf_ = rs.full(theta120rs, r120rs, t120, r120, t120) #------------------------------------------------------------------------------ # Figures plt.figure(figsize=(8, 6)) # Sv original plt.subplot(221).invert_yaxis() plt.pcolormesh(t120, r120, Sv120, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.tick_params(labelbottom=False) plt.ylabel('Depth (m)') plt.title('Sv') # Theta original plt.subplot(222).invert_yaxis() plt.pcolormesh(t120, r120, theta120, cmap=cmaps().coolwarm) plt.tick_params(labelbottom=False) plt.tick_params(labelleft=False) plt.title('Theta') # Sv 2D-resampled plt.subplot(223).invert_yaxis() plt.pcolormesh(t120, r120, Sv120rsf, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.ylabel('Depth (m)')
#------------------------------------------------------------------------------ # Clean Sv from impulse noise with Wang's algorithm Sv120wang, m120wang_ = mIN.wang(Sv120) # Note that Wang's algorithm does not return a mask with impulse noise detected # but Sv without impulse noise and other Sv modifications. It also removes # Sv signal below and above the target of interest. In this case, krill swarms. #------------------------------------------------------------------------------ # Figures plt.figure(figsize=(8, 4)) # Sv original plt.subplot(131).invert_yaxis() plt.pcolormesh(p120, r120, Sv120, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.ylabel('Depth (m)') plt.title('IN on') # IN removed with Ryan's algorithm plt.subplot(132).invert_yaxis() plt.pcolormesh(p120, r120, Sv120ryan, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.tick_params(labelleft=False) plt.xlabel('Number of pings') plt.title('IN off (Ryan)') # IN removed (and further signal) with Wang's algorithm plt.subplot(133).invert_yaxis() plt.pcolormesh(p120, r120, Sv120wang, vmin=-80, vmax=-50, cmap=cmaps().ek500) plt.tick_params(labelleft=False) plt.title('IN off (Wang)')