@@ -165,6 +165,8 @@ def __init__(self, file_path, veg_codes):
165
165
self .reqd_columns = REQD_COLUMNS
166
166
self .sourceLatCol = sourceLatCol
167
167
self .sourceLonCol = sourceLonCol
168
+ self .sourceTimeCol = sourceTimeCol
169
+ self .sourceDateCol = sourceDateCol
168
170
self .veg_codes = veg_codes
169
171
170
172
@property
@@ -174,9 +176,10 @@ def valid(self):
174
176
No missing base columns
175
177
At least one vegetation column
176
178
No malformed latitude or longitude values
179
+ No malformed date or time values
177
180
"""
178
181
if self .file_exists and len (self .missing_columns ) == 0 and len (self .veg_columns ) > 0 and \
179
- len (self .lat_errors ) == 0 and len (self .lon_errors ) == 0 :
182
+ len (self .lat_errors ) == 0 and len (self .lon_errors ) == 0 and len ( self . time_errors ) == 0 and len ( self . date_errors ) == 0 :
180
183
return True
181
184
else :
182
185
return False
@@ -233,7 +236,6 @@ def veg_columns(self):
233
236
_veg_columns = set (self .veg_codes ).intersection (set (self .all_columns ))
234
237
return list (_veg_columns )
235
238
236
-
237
239
@property
238
240
def columns (self ):
239
241
"""combined list of base and vegetation columns in source csv file"""
@@ -258,13 +260,31 @@ def lon_errors(self):
258
260
except :
259
261
return None
260
262
263
+ @property
264
+ def time_errors (self ):
265
+ """list of rows in source csv file with erroneous time values"""
266
+ try :
267
+ _time_errors = self ._validate_time (self .sourceTimeCol )
268
+ return _time_errors
269
+ except :
270
+ return None
271
+
272
+ @property
273
+ def date_errors (self ):
274
+ """list of rows in source csv file with erroneous date values"""
275
+ try :
276
+ _date_errors = self ._validate_date (self .sourceDateCol )
277
+ return _date_errors
278
+ except :
279
+ return None
280
+
261
281
def _validate_latlon (self , col ):
262
282
"""Function to validate lat or lon values based on expected pattern"""
263
283
# Assumes input in format ##d##.####' Dir or ##d##' Dir
264
284
# latlon_pattern = "[0-9]+[d][0-9]+[.][0-9]+\' [nsewNSEW]"
265
285
latlon_pattern = "[0-9]+[d][0-9]+[.]?[0-9]+\' [nsewNSEW]"
266
- error_rows = []
267
- #
286
+ error_rows = [] # initialize list of rows with errors
287
+ # Loop through data and validate lat/long value
268
288
for i , row in enumerate (self .rows ):
269
289
csv_row = i + 1
270
290
coord = row [col ]
@@ -282,6 +302,48 @@ def _validate_latlon(self, col):
282
302
283
303
return error_rows
284
304
305
+ def _validate_time (self , col ):
306
+ """
307
+ Function to validate time values based on expected patter
308
+ Input can be in 12-hour (AM/PM) or 24-hour format
309
+ :param col:
310
+ :return:
311
+ """
312
+ error_rows = [] # initialize list of rows with errors
313
+ # Loop through data and validate time values
314
+ for i , row in enumerate (self .rows ):
315
+ csv_row = i + 1
316
+ time_of_survey = row [col ]
317
+ time24hr_pattern = "^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$"
318
+ time12hr_pattern = "^(1[0-2]|0?[1-9]):([0-5]?[0-9]):([0-5]?[0-9])( ?[AP]M)?$"
319
+
320
+ if "M" in time_of_survey :
321
+ if not re .search (time12hr_pattern , time_of_survey ):
322
+ error_rows .append (csv_row )
323
+ else :
324
+ if not re .search (time24hr_pattern , time_of_survey ):
325
+ error_rows .append (csv_row )
326
+ return error_rows
327
+
328
+ def _validate_date (self , col ):
329
+ """
330
+ Function to validate date values based on expected pattern
331
+ Input expected to be in this format: m/d/yyyy or mm/dd/yyyy
332
+ :param col:
333
+ :return:
334
+ """
335
+ error_rows = [] # initialize list of rows with errors
336
+ # Loop through data and validate time values
337
+ for i , row in enumerate (self .rows ):
338
+ csv_row = i + 1
339
+ date_of_survey = row [col ]
340
+ try :
341
+ [m , d , y ] = date_of_survey .split ('/' )
342
+ testdate = datetime .date (int (y ), int (m ), int (d ))
343
+ except :
344
+ error_rows .append (csv_row )
345
+ return error_rows
346
+
285
347
@property
286
348
def dataframe (self ):
287
349
if self .valid :
@@ -483,7 +545,6 @@ def transect_video0(self):
483
545
# print df_max.loc[tranCol > 1]
484
546
return df_max
485
547
486
-
487
548
def _validate_data (self ):
488
549
# Check validation properties
489
550
if self .video_zero or self .null_video or self .null_veg or self .video_gt1 \
@@ -663,6 +724,14 @@ def write_csverr(self, csvsource):
663
724
err_type = "Bad Longitude Values"
664
725
details = 'Rows: ' + ';' .join (str (r ) for r in csvsource .lon_errors )
665
726
self .fh .write ("," .join ((csv_dir , csv_file , err_type , details )) + "\n " )
727
+ if csvsource .time_errors :
728
+ err_type = "Bad Time Values"
729
+ details = 'Rows: ' + ';' .join (str (r ) for r in csvsource .time_errors )
730
+ self .fh .write ("," .join ((csv_dir , csv_file , err_type , details )) + "\n " )
731
+ if csvsource .date_errors :
732
+ err_type = "Bad Date Values"
733
+ details = 'Rows: ' + ';' .join (str (r ) for r in csvsource .date_errors )
734
+ self .fh .write ("," .join ((csv_dir , csv_file , err_type , details )) + "\n " )
666
735
667
736
def write_direrr (self , csv_dir ):
668
737
@@ -693,7 +762,7 @@ def write_datawarn(self, csvdata):
693
762
self .fh .write ("," .join ((csv_dir , csv_file , err_type , details )) + "\n " )
694
763
if csvdata .null_video :
695
764
err_type = "Null Video Values"
696
- # print ', '.join(str(x) for x in list_of_ints)
765
+ # print( ', '.join(str(x) for x in list_of_ints) )
697
766
details = 'Rows: ' + ';' .join (str (i ) for i in csvdata .null_video )
698
767
self .fh .write ("," .join ((csv_dir , csv_file , err_type , details )) + "\n " )
699
768
if csvdata .null_veg :
@@ -773,7 +842,7 @@ def main(in_dir, sites_file, vegcode_table, out_gdb, err_dir):
773
842
if transectData .warnings :
774
843
msg ("Data Validation Warnings.\n Writing to log file: {1}" .format (csvSource .file_path , warning_log .log_file ))
775
844
warning_log .write_datawarn (transectData )
776
- print "Creating Point feature class {0}" .format (fc_path )
845
+ msg ( "Creating Point feature class {0}" .format (fc_path ) )
777
846
ptFC = PointFC (transectData .nparray , fc_path )
778
847
ptFC .create_fc ()
779
848
else :
@@ -804,21 +873,26 @@ def main(in_dir, sites_file, vegcode_table, out_gdb, err_dir):
804
873
# Input parameter 1: Parent directory for site data folders and input csv files
805
874
# in_dir = "Y:/projects/dnr_svmp2016/data/2014_test/site_folders"
806
875
in_dir = "Y:/projects/dnr_svmp2016/data/examples"
876
+ # in_dir = "Y:/projects/dnr_svmp2016/data/IslandCoMRC"
807
877
808
878
# Input parameter 2: Text file with list of sites to process
809
879
sites_file = os .path .join ("Y:/projects/dnr_svmp2016/data/examples" , "sites2process_examples.txt" )
880
+ # sites_file = os.path.join("Y:/projects/dnr_svmp2016/data/IslandCoMRC", "sites2process_IslandCoMRC.txt")
810
881
811
882
# Input parameter 3: Table with vegetation codes
812
883
vegcode_table = "Y:/projects/dnr_svmp2016/db/SVMP_2000_2015_DB.v4_20170109/SVMP_DB_v4_20170109.mdb/veg_codes"
884
+ # vegcode_table = "Y:/projects/dnr_svmp2016/db/SVMP_DB_v5.2_20170815.mdb/veg_codes"
813
885
814
886
# Input parameter 4: Output Geodatabase to store point feature classes
815
887
out_gdb = "Y:/projects/dnr_svmp2016/data/examples/examples_pgdb.mdb"
888
+ # out_gdb = "Y:/projects/dnr_svmp2016/data/IslandCoMRC/IslandCoMRC_transects.mdb"
816
889
817
890
# Input parameter 5: Error Log directory
818
891
err_dir = in_dir
892
+ # err_dir = "Y:/projects/dnr_svmp2016/data/IslandCoMRC/err_logs"
819
893
820
894
main (in_dir , sites_file , vegcode_table , out_gdb , err_dir )
821
895
822
896
t1 = time .time ()
823
897
824
- print ("Total time elapsed is: %s seconds" % str (t1 - t0 ))
898
+ print ("Total time elapsed is: %s seconds" % str (t1 - t0 ))
0 commit comments