def mds_track_check(invoyage): ''' Perform one pass of the track check :param invoyage: A list of :class:`.Voyage` that you want track checked :type invoyage: :class:`.Voyage` :return: list of QC flags 0 for pass and 1 for fail :rtype: integer This is an implementation of the MDS track check code which was originally written in the 1990s. I don't know why this piece of historic trivia so exercises my mind, but it does: the 1990s! I wish my code would last so long. ''' km_to_nm = 0.539957 nobs = len(invoyage) #no obs in, no qc outcomes out if nobs == 0: return [] #Generic ids get a free pass on the track check if qc.id_is_generic(invoyage.getvar(0, 'ID'), invoyage.getvar(0, 'YR')): qcs = [] nobs = len(invoyage) for i in range(0, nobs): invoyage.set_qc(i, 'POS', 'bad_track', 0) qcs.append(0) return qcs #fewer than three obs - set the fewsome flag #deck 720 gets a pass prior to 1891 see Carella, Kent, Berry 2015 Appendix A3 if nobs < 3 and not(invoyage.getvar(0, 'DCK') == 720 and invoyage.getvar(0 ,'YR') < 1891): qcs = [] nobs = len(invoyage) for i in range(0, nobs): invoyage.set_qc(i, 'POS', 'fewsome_check', 1) qcs.append(0) return qcs #work out speeds and distances between alternating points invoyage.calc_alternate_speeds() #what are the mean and mode speeds? mean_speed = invoyage.meansp() modal_speed = modesp(invoyage.get_speed()) #set speed limits based on modal speed amax, amaxx, amin = set_speed_limits(modal_speed) #compare reported speeds and positions if we have them forward_diff_from_estimated = distr1(invoyage) reverse_diff_from_estimated = distr2(invoyage) midpoint_diff_from_estimated = midpt(invoyage) #do QC qcs = [0] all_alwdis = [0] invoyage.set_qc(0, 'POS', 'bad_track', 0) invoyage.set_qc(0, 'POS', 'fewsome_check', 0) for i in range(1, nobs-1): thisqc_a = 0 thisqc_b = 0 #together these cover the speeds calculate from point i if (invoyage.getvar(i, 'speed') > amax and invoyage.getvar(i-1 ,'alt_speed') > amax): thisqc_a += 1.00 elif (invoyage.getvar(i+1, 'speed') > amax and invoyage.getvar(i+1, 'alt_speed') > amax): thisqc_a += 2.00 elif (invoyage.getvar(i, 'speed') > amax and invoyage.getvar(i+1, 'speed') > amax): thisqc_a += 3.00 # Quality-control by examining the distance #between the calculated and reported second position. thisqc_b += check_distance_from_estimate(invoyage.getvar(i , 'vsi'), invoyage.getvar(i-1, 'vsi'), invoyage.getvar(i, 'time_diff'), forward_diff_from_estimated[i], reverse_diff_from_estimated[i]) #Check for continuity of direction thisqc_b += direction_continuity(invoyage.getvar(i, 'dsi'), invoyage.getvar(i-1, 'dsi'), invoyage.getvar(i, 'course')) #Check for continuity of speed. thisqc_b += speed_continuity(invoyage.getvar(i, 'vsi'), invoyage.getvar(i-1, 'vsi'), invoyage.getvar(i, 'speed')) #check for speeds in excess of 40.00 knots if invoyage.getvar(i, 'speed') > 40.00/km_to_nm: thisqc_b += 10.0 #make the final decision if (midpoint_diff_from_estimated[i] > 150.0/km_to_nm and thisqc_a > 0 and thisqc_b > 0): qcs.append(1) invoyage.set_qc(i, 'POS', 'bad_track', 1) invoyage.set_qc(i, 'POS', 'fewsome_check', 0) else: qcs.append(0) invoyage.set_qc(i, 'POS', 'bad_track', 0) invoyage.set_qc(i, 'POS', 'fewsome_check', 0) qcs.append(0) invoyage.set_qc(nobs-1, 'POS', 'bad_track', 0) invoyage.set_qc(nobs-1, 'POS', 'fewsome_check', 0) return qcs
def mds_track_check(invoyage): """ Perform one pass of the track check :param invoyage: A list of :class:`.Voyage` that you want track checked :type invoyage: :class:`.Voyage` :return: list of QC flags 0 for pass and 1 for fail :rtype: integer This is an implementation of the MDS track check code which was originally written in the 1990s. I don't know why this piece of historic trivia so exercises my mind, but it does: the 1990s! I wish my code would last so long. """ km_to_nm = 0.539957 nobs = len(invoyage) # no obs in, no qc outcomes out if nobs == 0: return [] # Generic ids get a free pass on the track check if qc.id_is_generic(invoyage.getvar(0, 'ID'), invoyage.getvar(0, 'YR')): qcs = [] nobs = len(invoyage) for i in range(0, nobs): invoyage.set_qc(i, 'POS', 'bad_track', 0) qcs.append(0) return qcs # fewer than three obs - set the fewsome flag # deck 720 gets a pass prior to 1891 see Carella, Kent, Berry 2015 Appendix A3 if nobs < 3 and not (invoyage.getvar(0, 'DCK') == 720 and invoyage.getvar(0, 'YR') < 1891): qcs = [] nobs = len(invoyage) for i in range(0, nobs): invoyage.set_qc(i, 'POS', 'fewsome_check', 1) qcs.append(0) return qcs # work out speeds and distances between alternating points invoyage.calc_alternate_speeds() # what are the mean and mode speeds? mean_speed = invoyage.meansp() modal_speed = modesp(invoyage.get_speed()) # set speed limits based on modal speed amax, amaxx, amin = set_speed_limits(modal_speed) # compare reported speeds and positions if we have them forward_diff_from_estimated = distr1(invoyage) reverse_diff_from_estimated = distr2(invoyage) midpoint_diff_from_estimated = midpt(invoyage) # do QC qcs = [0] all_alwdis = [0] invoyage.set_qc(0, 'POS', 'bad_track', 0) invoyage.set_qc(0, 'POS', 'fewsome_check', 0) for i in range(1, nobs - 1): thisqc_a = 0 thisqc_b = 0 # together these cover the speeds calculate from point i if (invoyage.getvar(i, 'speed') > amax and invoyage.getvar(i - 1, 'alt_speed') > amax): thisqc_a += 1.00 elif (invoyage.getvar(i + 1, 'speed') > amax and invoyage.getvar(i + 1, 'alt_speed') > amax): thisqc_a += 2.00 elif (invoyage.getvar(i, 'speed') > amax and invoyage.getvar(i + 1, 'speed') > amax): thisqc_a += 3.00 # Quality-control by examining the distance # between the calculated and reported second position. thisqc_b += check_distance_from_estimate( invoyage.getvar(i, 'vsi'), invoyage.getvar(i - 1, 'vsi'), invoyage.getvar(i, 'time_diff'), forward_diff_from_estimated[i], reverse_diff_from_estimated[i]) # Check for continuity of direction thisqc_b += direction_continuity(invoyage.getvar(i, 'dsi'), invoyage.getvar(i - 1, 'dsi'), invoyage.getvar(i, 'course')) # Check for continuity of speed. thisqc_b += speed_continuity(invoyage.getvar(i, 'vsi'), invoyage.getvar(i - 1, 'vsi'), invoyage.getvar(i, 'speed')) # check for speeds in excess of 40.00 knots if invoyage.getvar(i, 'speed') > 40.00 / km_to_nm: thisqc_b += 10.0 # make the final decision if (midpoint_diff_from_estimated[i] > 150.0 / km_to_nm and thisqc_a > 0 and thisqc_b > 0): qcs.append(1) invoyage.set_qc(i, 'POS', 'bad_track', 1) invoyage.set_qc(i, 'POS', 'fewsome_check', 0) else: qcs.append(0) invoyage.set_qc(i, 'POS', 'bad_track', 0) invoyage.set_qc(i, 'POS', 'fewsome_check', 0) qcs.append(0) invoyage.set_qc(nobs - 1, 'POS', 'bad_track', 0) invoyage.set_qc(nobs - 1, 'POS', 'fewsome_check', 0) return qcs
def mds_track_check(inreps): ''' Perform one pass of the track check :param inreps: A list of :class:`.MarineReport` that you want track checked :type inreps: :class:`.MarineReport` :return: list of QC flags 0 for pass and 1 for fail :rtype: integer This is an implementation of the MDS track check code which was originally written in the 1990s. I don't know why this piece of historic trivia so exercises my mind, but it does: the 1990s! I wish my code would last so long. ''' nobs = len(inreps) #no obs in, no qc outcomes out if nobs == 0: return [] #Generic ids get a free pass on the track check if qc.id_is_generic(inreps[0].id, inreps[0].year) or nobs < 3: qcs = [] nobs = len(inreps) for i in range(0, nobs): inreps[i].bad_track = 0 qcs.append(0) return qcs #work out speeds and distances between consecutive #points and alternating points time_diffs, speeds, distances, ship_directions = calc_1step_speeds(inreps) alt_time_diffs, alt_speeds, alt_distances, alt_ship_directions = \ calc_alternate_step_speeds(inreps) #what are the mean and mode speeds? mean_speed = meansp(speeds) modal_speed = modesp(speeds) #set speed limits based on modal speed amax, amaxx, amin = set_speed_limits(modal_speed) #compare reported speeds and positions if we have them forward_diff_from_estimated = distr1(inreps, time_diffs) reverse_diff_from_estimated = distr2(inreps, time_diffs) midpoint_diff_from_estimated = midpt(inreps, time_diffs) #do QC qcs = [0] all_alwdis = [0] for i in range(1, nobs-1): thisqc_a = 0 thisqc_b = 0 #together these cover the speeds calculate from point i if speeds[i] > amax and alt_speeds[i-1] > amax: thisqc_a += 1.00 elif speeds[i+1] > amax and alt_speeds[i+1] > amax: thisqc_a += 2.00 elif speeds[i] > amax and speeds[i+1] > amax: thisqc_a += 3.00 # Quality-control by examining the distance #between the calculated and reported second position. thisqc_b += check_distance_from_estimate(inreps[i].vsi, inreps[i-1].vsi, time_diffs[i], forward_diff_from_estimated[i], reverse_diff_from_estimated[i]) #Check for continuity of direction thisqc_b += direction_continuity(inreps[i].dsi, inreps[i-1].dsi, ship_directions[i]) #Check for continuity of speed. thisqc_b += speed_continuity(inreps[i].vsi, inreps[i-1].vsi, speeds[i]) #check for speeds in excess of 40.00 knots if speeds[i] > 40.00: thisqc_b += 10.0 #make the final decision if (midpoint_diff_from_estimated[i] > 150.0 and thisqc_a > 0 and thisqc_b > 0): qcs.append(1) inreps[i].bad_track = 1 else: qcs.append(0) inreps[i].bad_track = 0 qcs.append(0) return qcs