@@ -905,10 +905,10 @@ def __init__(self, **kwargs):
905905
906906 @classmethod
907907 def load_ascii_catalogs (cls , filename , ** kwargs ):
908- """ Loads multiple CSEP catalogs in ASCII format.
908+ """ Loads multiple catalogs in csep-ascii format.
909909
910- This function can load multiple catalogs stored in a single file or directories . This typically called to
911- load a catalog-based forecast.
910+ This function can load multiple catalogs stored in a single file. This typically called to
911+ load a catalog-based forecast, but could also load a collection of catalogs stored in the same file
912912
913913 Args:
914914 filename (str): filepath or directory of catalog files
@@ -926,15 +926,46 @@ def parse_filename(filename):
926926 start_time = strptime_to_utc_datetime (split_fname [1 ], format = "%Y-%m-%dT%H-%M-%S-%f" )
927927 return (name , start_time )
928928
929+ def read_float (val ):
930+ """Returns val as float or None if unable"""
931+ try :
932+ val = float (val )
933+ except :
934+ val = None
935+ return val
936+
929937 def is_header_line (line ):
930- if line [0 ] == 'lon' :
938+ if line [0 ]. lower () == 'lon' :
931939 return True
932940 else :
933941 return False
934942
935- name_from_file , start_time = parse_filename (filename )
943+ def read_catalog_line (line ):
944+ # convert to correct types
945+ lon = read_float (line [0 ])
946+ lat = read_float (line [1 ])
947+ magnitude = read_float (line [2 ])
948+ # maybe fractional seconds are not included
949+ origin_time = line [3 ]
950+ if origin_time :
951+ try :
952+ origin_time = strptime_to_utc_epoch (line [3 ], format = '%Y-%m-%dT%H:%M:%S.%f' )
953+ except ValueError :
954+ origin_time = strptime_to_utc_epoch (line [3 ], format = '%Y-%m-%dT%H:%M:%S' )
955+ depth = read_float (line [4 ])
956+ catalog_id = int (line [5 ])
957+ event_id = line [6 ]
958+ # temporary event
959+ temp_event = (event_id , origin_time , lat , lon , depth , magnitude )
960+ return temp_event , catalog_id
961+
936962 # overwrite filename, if user specifies
937- kwargs .setdefault ('name' , name_from_file )
963+ try :
964+ name_from_file , start_time = parse_filename (filename )
965+ kwargs .setdefault ('name' , name_from_file )
966+ except :
967+ pass
968+
938969 # handle all catalogs in single file
939970 if os .path .isfile (filename ):
940971 with open (filename , 'r' , newline = '' ) as input_file :
@@ -948,52 +979,53 @@ def is_header_line(line):
948979 if prev_id is None :
949980 if is_header_line (line ):
950981 continue
951- # convert to correct types
952- lon = float (line [0 ])
953- lat = float (line [1 ])
954- magnitude = float (line [2 ])
955- # maybe fractional seconds are not included
956- try :
957- origin_time = strptime_to_utc_epoch (line [3 ], format = '%Y-%m-%dT%H:%M:%S.%f' )
958- except ValueError :
959- origin_time = strptime_to_utc_epoch (line [3 ], format = '%Y-%m-%dT%H:%M:%S' )
960- depth = float (line [4 ])
961- catalog_id = int (line [5 ])
962- event_id = line [6 ]
982+ # read line and return catalog id
983+ temp_event , catalog_id = read_catalog_line (line )
984+ empty = False
985+ # OK if event_id is empty
986+ if all ([val in (None , '' ) for val in temp_event [1 :]]):
987+ empty = True
963988 # first event is when prev_id is none, catalog_id should always start at zero
964989 if prev_id is None :
965990 prev_id = 0
966991 # if the first catalog doesn't start at zero
967992 if catalog_id != prev_id :
968- prev_id = catalog_id
969- # store this event for next time
970- events = [(event_id , origin_time , lat , lon , depth , magnitude )]
993+ if not empty :
994+ events = [temp_event ]
995+ else :
996+ events = []
971997 for id in range (catalog_id ):
972998 yield cls (data = [], catalog_id = id , ** kwargs )
973- # deal with cases of events
999+ prev_id = catalog_id
1000+ continue
1001+ # accumulate event if catalog_id is the same as previous event
9741002 if catalog_id == prev_id :
1003+ if not all ([val in (None , '' ) for val in temp_event ]):
1004+ events .append (temp_event )
9751005 prev_id = catalog_id
976- events .append ((event_id , origin_time , lat , lon , depth , magnitude ))
9771006 # create and yield class if the events are from different catalogs
9781007 elif catalog_id == prev_id + 1 :
979- catalog = cls (data = events , catalog_id = prev_id , ** kwargs )
1008+ yield cls (data = events , catalog_id = prev_id , ** kwargs )
1009+ # add event to new event list
1010+ if not empty :
1011+ events = [temp_event ]
1012+ else :
1013+ events = []
9801014 prev_id = catalog_id
981- # add first event to new event list
982- events = [(event_id , origin_time , lat , lon , depth , magnitude )]
983- yield catalog
9841015 # this implies there are empty catalogs, because they are not listed in the ascii file
9851016 elif catalog_id > prev_id + 1 :
986- catalog = cls (data = events , catalog_id = prev_id , ** kwargs )
987- # add event to new event list
988- events = [(event_id , origin_time , lat , lon , depth , magnitude )]
1017+ yield cls (data = events , catalog_id = prev_id , ** kwargs )
9891018 # if prev_id = 0 and catalog_id = 2, then we skipped one catalog. thus, we skip catalog_id - prev_id - 1 catalogs
9901019 num_empty_catalogs = catalog_id - prev_id - 1
991- # create empty catalog classes
1020+ # first yield empty catalog classes
9921021 for id in range (num_empty_catalogs ):
9931022 yield cls (data = [], catalog_id = catalog_id - num_empty_catalogs + id , ** kwargs )
994- # finally we want to yield the buffered catalog to preserve order
9951023 prev_id = catalog_id
996- yield catalog
1024+ # add event to new event list
1025+ if not empty :
1026+ events = [temp_event ]
1027+ else :
1028+ events = []
9971029 else :
9981030 raise ValueError (
9991031 "catalog_id should be monotonically increasing and events should be ordered by catalog_id" )
0 commit comments