@@ -16,20 +16,42 @@ def get_distance_matrix(detections: pd.DataFrame):
1616 Returns:
1717 pd.DataFrame: A Pandas DataFrame matrix of station to station distances
1818 """
19- stn_grouped = detections .groupby ('station' , dropna = False )
20- stn_locs = stn_grouped [['longitude' , 'latitude' ]].mean ()
19+ # what we expect the input data format to be
20+ data_format_guess = 'otn_old'
21+
22+ if 'catalogNumber' in detections .columns : # the new version of otn det extracts uses camel case
23+ data_format_guess = 'otn_2025'
24+
25+
26+ # set the stations locations to their deployments' mean lat and lon
27+
28+ if data_format_guess == 'otn_old' :
29+ stn_grouped = detections .groupby ('station' , dropna = False )
30+ stn_locs = stn_grouped [['longitude' , 'latitude' ]].mean ()
31+ elif : data_format_guess == 'otn_2025' :
32+ stn_grouped = detections .groupby ('station' , dropna = False )
33+ stn_locs = stn_grouped [['decimalLongitude' , 'decimalLatitude' ]].mean ()
2134
2235 dist_mtx = pd .DataFrame (
2336 np .zeros (len (stn_locs ) ** 2 ).reshape (len (stn_locs ), len (stn_locs )),
2437 index = stn_locs .index , columns = stn_locs .index )
2538
26- for cstation in dist_mtx .columns :
27- for rstation in dist_mtx .index :
28- cpoint = (stn_locs .loc [cstation , 'latitude' ],
29- stn_locs .loc [cstation , 'longitude' ])
30- rpoint = (stn_locs .loc [rstation , 'latitude' ],
31- stn_locs .loc [rstation , 'longitude' ])
32- dist_mtx .loc [rstation , cstation ] = geodesic (cpoint , rpoint ).m
39+ if data_format_guess == 'otn_old' :
40+ for cstation in dist_mtx .columns :
41+ for rstation in dist_mtx .index :
42+ cpoint = (stn_locs .loc [cstation , 'latitude' ],
43+ stn_locs .loc [cstation , 'longitude' ])
44+ rpoint = (stn_locs .loc [rstation , 'latitude' ],
45+ stn_locs .loc [rstation , 'longitude' ])
46+ dist_mtx .loc [rstation , cstation ] = geodesic (cpoint , rpoint ).m
47+ elif data_format_guess == 'otn_2025' :
48+ for cstation in dist_mtx .columns :
49+ for rstation in dist_mtx .index :
50+ cpoint = (stn_locs .loc [cstation , 'decimalLatitude' ],
51+ stn_locs .loc [cstation , 'decimalLongitude' ])
52+ rpoint = (stn_locs .loc [rstation , 'decimalLatitude' ],
53+ stn_locs .loc [rstation , 'decimalLongitude' ])
54+ dist_mtx .loc [rstation , cstation ] = geodesic (cpoint , rpoint ).m
3355 dist_mtx .index .name = None
3456 return dist_mtx
3557
@@ -66,7 +88,18 @@ def filter_detections(detections: pd.DataFrame, suspect_file=None,
6688 detections.
6789 """
6890
91+ # what we expect the input data format to be
92+ data_format_guess = 'otn_old'
6993 # Set of mandatory column names for detection_file
94+
95+ if 'catalogNumber' in detections .columns : # the new version of otn det extracts uses camel case
96+ data_format_guess = 'otn_2025'
97+ mandatory_columns = set (['station' ,
98+ 'unqDetecID' ,
99+ 'dateCollectedUTC' ,
100+ 'catalogNumber' ])
101+
102+ else : # the original OTN detections did not use camel case.
70103 mandatory_columns = set (['station' ,
71104 'unqdetecid' ,
72105 'datecollected' ,
@@ -88,28 +121,47 @@ def filter_detections(detections: pd.DataFrame, suspect_file=None,
88121 # If the space before + after > min_time_buffer
89122 # Remove that detection row from the detections and add it to suspect detections.
90123 # SQL that does this is in load_to_postgresql under createSuspect
124+
91125 detections = detections .copy (deep = True )
92- ind = detections ['catalognumber' ].unique ()
93- detections .loc [:, 'datecollected' ] = pd .to_datetime (
94- detections ['datecollected' ])
95- user_int = timedelta (seconds = min_time_buffer )
96- good_dets = pd .DataFrame ()
97- susp_dets = pd .DataFrame ()
98- grouped = detections .groupby ('catalognumber' , dropna = False )
99- for anm in ind :
100- anm_dets = grouped .get_group (anm ).sort_values (
101- 'datecollected' , ascending = True )
102- intervals = anm_dets ['datecollected' ] - \
103- anm_dets ['datecollected' ].shift (1 )
104- post_intervals = anm_dets ['datecollected' ].shift (
105- - 1 ) - anm_dets ['datecollected' ]
106-
107- good_dets = pd .concat ([
108- good_dets ,
109- anm_dets [
110- (intervals <= user_int ) | (post_intervals <= user_int )
111- ]
112- ])
126+
127+ if data_format_guess == 'otn_old' :
128+ ind = detections ['catalognumber' ].unique ()
129+ detections .loc [:, 'datecollected' ] = pd .to_datetime (
130+ detections ['datecollected' ])
131+ user_int = timedelta (seconds = min_time_buffer )
132+ good_dets = pd .DataFrame ()
133+ susp_dets = pd .DataFrame ()
134+ grouped = detections .groupby ('catalognumber' , dropna = False )
135+ for anm in ind :
136+ anm_dets = grouped .get_group (anm ).sort_values (
137+ 'datecollected' , ascending = True )
138+ intervals = anm_dets ['datecollected' ] - \
139+ anm_dets ['datecollected' ].shift (1 )
140+ post_intervals = anm_dets ['datecollected' ].shift (
141+ - 1 ) - anm_dets ['datecollected' ]
142+
143+ elif data_format_guess == 'otn_2025' :
144+ ind = detections ['catalogNumber' ].unique ()
145+ detections .loc [:, 'dateCollectedUTC' ] = pd .to_datetime (
146+ detections ['dateCollectedUTC' ])
147+ user_int = timedelta (seconds = min_time_buffer )
148+ good_dets = pd .DataFrame ()
149+ susp_dets = pd .DataFrame ()
150+ grouped = detections .groupby ('catalogNumber' , dropna = False )
151+ for anm in ind :
152+ anm_dets = grouped .get_group (anm ).sort_values (
153+ 'dateCollectedUTC' , ascending = True )
154+ intervals = anm_dets ['dateCollectedUTC' ] - \
155+ anm_dets ['dateCollectedUTC' ].shift (1 )
156+ post_intervals = anm_dets ['dateCollectedUTC' ].shift (
157+ - 1 ) - anm_dets ['dateCollectedUTC' ]
158+
159+ good_dets = pd .concat ([
160+ good_dets ,
161+ anm_dets [
162+ (intervals <= user_int ) | (post_intervals <= user_int )
163+ ]
164+ ])
113165
114166 # If they aren't a good det, they're suspect!
115167 # TODO: Reporting: Decide if we want to report the big 'before/after'
@@ -118,8 +170,12 @@ def filter_detections(detections: pd.DataFrame, suspect_file=None,
118170 # append.
119171 # For now, just a matter of putting the complement of the good dets in
120172 # the susp_dets
121- susp_dets = detections .loc [~ detections ['unqdetecid' ].isin (
122- good_dets ['unqdetecid' ])].copy (deep = True )
173+ if data_format_guess == 'otn_old' :
174+ susp_dets = detections .loc [~ detections ['unqdetecid' ].isin (
175+ good_dets ['unqdetecid' ])].copy (deep = True )
176+ elif data_format_guess == 'otn_2025' :
177+ susp_dets = detections .loc [~ detections ['unqDetecID' ].isin (
178+ good_dets ['unqDetecID' ])].copy (deep = True )
123179
124180 else :
125181 raise GenericException ("Missing required input columns: {}" .format (
@@ -132,9 +188,12 @@ def filter_detections(detections: pd.DataFrame, suspect_file=None,
132188 output_dict = {"filtered" : good_dets , "suspect" : susp_dets }
133189
134190 if distance_matrix :
135-
136191 # Must now have lat and long columns as well.
137- dm_mandatory_columns = set (['latitude' , 'longitude' ])
192+ if data_format_guess == 'otn_old' :
193+ dm_mandatory_columns = set (['latitude' , 'longitude' ])
194+ elif : data_format_guess == 'otn_2025' :
195+ dm_mandatory_columns = set (['decimalLatitude' , 'decimalLongitude' ])
196+
138197 if dm_mandatory_columns .issubset (detections .columns ):
139198 output_dict ['dist_mtrx' ] = get_distance_matrix (detections )
140199 print ("There are {0} station locations in the distance \
@@ -175,20 +234,40 @@ def distance_filter(detections: pd.DataFrame, maximum_distance=100000, add_colum
175234 """
176235 pd .options .mode .chained_assignment = None
177236
178- mandatory_columns = set (['station' ,
237+ # what we expect the input data format to be
238+ data_format_guess = 'otn_old'
239+ # Set of mandatory column names for detection_file
240+
241+ if 'catalogNumber' in detections .columns : # the new version of otn det extracts uses camel case
242+ data_format_guess = 'otn_2025'
243+
244+ if data_format_guess == 'otn_old' :
245+ mandatory_columns = set (['station' ,
179246 'unqdetecid' ,
180247 'datecollected' ,
181248 'catalognumber' ])
249+ elif data_format_guess == 'otn_2025' :
250+ mandatory_columns = set (['station' ,
251+ 'unqDetecID' ,
252+ 'dateCollectedUTC' ,
253+ 'catalogNumber' ])
182254
183255 if mandatory_columns .issubset (detections .columns ):
184256 dm = get_distance_matrix (detections )
185257
186258 lead_lag_stn_df = pd .DataFrame ()
187- for _ , group in detections .sort_values (['datecollected' ]).groupby (['catalognumber' ], dropna = False ):
188- group ['lag_station' ] = group .station .shift (1 ).fillna (group .station )
189- group ['lead_station' ] = group .station .shift (
190- - 1 ).fillna (group .station )
191- lead_lag_stn_df = pd .concat ([lead_lag_stn_df , group ])
259+ if data_format_guess == 'otn_old' :
260+ for _ , group in detections .sort_values (['datecollected' ]).groupby (['catalognumber' ], dropna = False ):
261+ group ['lag_station' ] = group .station .shift (1 ).fillna (group .station )
262+ group ['lead_station' ] = group .station .shift (
263+ - 1 ).fillna (group .station )
264+ lead_lag_stn_df = pd .concat ([lead_lag_stn_df , group ])
265+ elif data_format_guess == 'otn_2025' :
266+ for _ , group in detections .sort_values (['dateCollected' ]).groupby (['catalogNumber' ], dropna = False ):
267+ group ['lag_station' ] = group .station .shift (1 ).fillna (group .station )
268+ group ['lead_station' ] = group .station .shift (
269+ - 1 ).fillna (group .station )
270+ lead_lag_stn_df = pd .concat ([lead_lag_stn_df , group ])
192271 del detections
193272
194273 distance_df = pd .DataFrame ()
@@ -235,28 +314,53 @@ def velocity_filter(detections: pd.DataFrame, maximum_velocity=10, add_column:b
235314 detections.
236315 """
237316 pd .options .mode .chained_assignment = None
317+ # what we expect the input data format to be
318+ data_format_guess = 'otn_old'
319+ # Set of mandatory column names for detection_file
238320
239- mandatory_columns = set (['station' ,
321+ if 'catalogNumber' in detections .columns : # the new version of otn det extracts uses camel case
322+ data_format_guess = 'otn_2025'
323+
324+ if data_format_guess == 'otn_old' :
325+ mandatory_columns = set (['station' ,
240326 'unqdetecid' ,
241327 'datecollected' ,
242328 'catalognumber' ])
243-
329+ elif data_format_guess == 'otn_2025' :
330+ mandatory_columns = set (['station' ,
331+ 'unqDetecID' ,
332+ 'dateCollected' ,
333+ 'catalogNumber' ])
334+
244335 if mandatory_columns .issubset (detections .columns ):
245336
246337 dm = get_distance_matrix (detections )
247338
248339 lead_lag_df = pd .DataFrame ()
249- for _ , group in detections .sort_values (['datecollected' ]).groupby (['catalognumber' ], dropna = False ):
250- group ['lag_station' ] = group .station .shift (1 ).fillna (group .station )
251- group ['lead_station' ] = group .station .shift (
252- - 1 ).fillna (group .station )
253-
254- group .datecollected = pd .to_datetime (group .datecollected )
255- group ['lag_time_diff' ] = group .datecollected .diff ().fillna (
256- timedelta (seconds = 1 ))
257- group ['lead_time_diff' ] = group .lag_time_diff .shift (
258- - 1 ).fillna (timedelta (seconds = 1 ))
259- lead_lag_df = pd .concat ([lead_lag_df , group ])
340+ if data_format_guess == 'otn_old' :
341+ for _ , group in detections .sort_values (['datecollected' ]).groupby (['catalognumber' ], dropna = False ):
342+ group ['lag_station' ] = group .station .shift (1 ).fillna (group .station )
343+ group ['lead_station' ] = group .station .shift (
344+ - 1 ).fillna (group .station )
345+
346+ group .datecollected = pd .to_datetime (group .datecollected )
347+ group ['lag_time_diff' ] = group .datecollected .diff ().fillna (
348+ timedelta (seconds = 1 ))
349+ group ['lead_time_diff' ] = group .lag_time_diff .shift (
350+ - 1 ).fillna (timedelta (seconds = 1 ))
351+ lead_lag_df = pd .concat ([lead_lag_df , group ])
352+ elif data_format_guess == 'otn_2025' :
353+ for _ , group in detections .sort_values (['dateCollectedUTC' ]).groupby (['catalogNumber' ], dropna = False ):
354+ group ['lag_station' ] = group .station .shift (1 ).fillna (group .station )
355+ group ['lead_station' ] = group .station .shift (
356+ - 1 ).fillna (group .station )
357+
358+ group .datecollected = pd .to_datetime (group .datecollected )
359+ group ['lag_time_diff' ] = group .datecollected .diff ().fillna (
360+ timedelta (seconds = 1 ))
361+ group ['lead_time_diff' ] = group .lag_time_diff .shift (
362+ - 1 ).fillna (timedelta (seconds = 1 ))
363+ lead_lag_df = pd .concat ([lead_lag_df , group ])
260364 del detections
261365
262366 vel_df = pd .DataFrame ()
0 commit comments