MTgeophysics / mtpy

Python toolbox for standard Magnetotelluric (MT) data analysis
GNU General Public License v3.0
145 stars 66 forks source link

Bug during parsing of decimal:minutes:seconds lat lons in .edi file #98

Closed k-a-mendoza closed 4 years ago

k-a-mendoza commented 4 years ago

It looks like Mtpy expects all lat lons to come in decimal degrees, but some authors store their lat lons in the edi files as degrees:minutes:seconds. When the seconds value is 60.00, MtPy fails to convert the edi file to an MT Object.

as so:

from mtpy.core.mt import MT
mt_obj = MT(edi_file)

traceback:

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/core/mt.py in __init__(self, fn, **kwargs)
    156         self.original_file_type = None
    157         if fn is not None:
--> 158             self.read_mt_file(fn)
    159             self._fn = os.path.normpath(os.path.abspath(fn))  # store file reference
    160 

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/core/mt.py in read_mt_file(self, fn, file_type)
    364 
    365         if file_type.lower() == 'edi':
--> 366             self._read_edi_file(fn)
    367         elif file_type.lower() == 'j':
    368             self._read_j_file(fn)

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/core/mt.py in _read_edi_file(self, edi_fn)
    455         self.save_dir = os.path.dirname(edi_fn)
    456 
--> 457         edi_obj = MTedi.Edi(edi_fn=edi_fn)
    458 
    459         self._edi_get_site(edi_obj)

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/core/edi.py in __init__(self, edi_fn)
    137 
    138         if self.edi_fn is not None:
--> 139             self.read_edi_file()
    140 
    141     def read_edi_file(self, edi_fn=None):

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/core/edi.py in read_edi_file(self, edi_fn)
    183                 self._edi_lines = _validate_edi_lines(fid.readlines())
    184 
--> 185         self.Header = Header(edi_lines=self._edi_lines)
    186         self.Info = Information(edi_lines=self._edi_lines)
    187         self.Define_measurement = DefineMeasurement(edi_lines=self._edi_lines)

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/core/edi.py in __init__(self, edi_fn, **kwargs)
    943 
    944         if self.edi_fn is not None or self.edi_lines is not None:
--> 945             self.read_header()
    946 
    947     def get_header_list(self):

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/core/edi.py in read_header(self, header_list)
   1029             elif key in 'longitude':
   1030                 key = 'lon'
-> 1031                 value = gis_tools.assert_lon_value(value)
   1032 
   1033             elif key in 'elevation':

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/utils/gis_tools.py in assert_lon_value(longitude)
    120 
    121     except ValueError:
--> 122         lon_value = convert_position_str2float(longitude)
    123 
    124     if abs(lon_value) >= 180:

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/utils/gis_tools.py in convert_position_str2float(position_str)
     72     deg = float(p_list[0])
     73     minutes = _assert_minutes(float(p_list[1]))
---> 74     sec = _assert_seconds(float(p_list[2]))
     75 
     76     # get the sign of the position so that when all are added together the

~/miniconda3/envs/mtpy/lib/python3.6/site-packages/mtpy/utils/gis_tools.py in _assert_seconds(seconds)
     39 def _assert_seconds(seconds):
     40     assert 0 <= seconds < 60., \
---> 41         'seconds needs to be <60 and >0, currently {0:.3f}'.format(seconds)
     42     return seconds
     43 

AssertionError: seconds needs to be <60 and >0, currently 60.000

this is using the latest pip release of mtpy

alkirkby commented 4 years ago

Please update your edi files as 60 seconds is an invalid value (must be 0 <= seconds < 60)