def test_setitem(self): """ Tests __setitem__ method of AttribDict class. """ # 1 ad = AttribDict() ad['test'] = 'NEW' self.assertEqual(ad['test'], 'NEW') self.assertEqual(ad.test, 'NEW') self.assertEqual(ad.get('test'), 'NEW') self.assertEqual(ad.__getattr__('test'), 'NEW') self.assertEqual(ad.__getitem__('test'), 'NEW') self.assertEqual(ad.__dict__['test'], 'NEW') self.assertEqual(ad.__dict__.get('test'), 'NEW') self.assertIn('test', ad) self.assertIn('test', ad.__dict__) # 2 ad = AttribDict() ad.__setitem__('test', 'NEW') self.assertEqual(ad['test'], 'NEW') self.assertEqual(ad.test, 'NEW') self.assertEqual(ad.get('test'), 'NEW') self.assertEqual(ad.__getattr__('test'), 'NEW') self.assertEqual(ad.__getitem__('test'), 'NEW') self.assertEqual(ad.__dict__['test'], 'NEW') self.assertEqual(ad.__dict__.get('test'), 'NEW') self.assertIn('test', ad) self.assertIn('test', ad.__dict__)
def test_setitem(self): """ Tests __setitem__ method of AttribDict class. """ # 1 ad = AttribDict() ad['test'] = 'NEW' assert ad['test'] == 'NEW' assert ad.test == 'NEW' assert ad.get('test') == 'NEW' assert ad.__getattr__('test') == 'NEW' assert ad.__getitem__('test') == 'NEW' assert ad.__dict__['test'] == 'NEW' assert ad.__dict__.get('test') == 'NEW' assert 'test' in ad assert 'test' in ad.__dict__ # 2 ad = AttribDict() ad.__setitem__('test', 'NEW') assert ad['test'] == 'NEW' assert ad.test == 'NEW' assert ad.get('test') == 'NEW' assert ad.__getattr__('test') == 'NEW' assert ad.__getitem__('test') == 'NEW' assert ad.__dict__['test'] == 'NEW' assert ad.__dict__.get('test') == 'NEW' assert 'test' in ad assert 'test' in ad.__dict__
def __init__(self,phase_selected='P',length_before_phase=50,length_after_phase=150,length_before_origin=100, length_after_origin=2000, model1d='ak135'): self.phase_window= AttribDict({'phase_selected': phase_selected, 'length_before_phase': length_before_phase, 'length_after_phase': length_after_phase}) self.data_window=AttribDict({'length_before_origin':length_before_origin, 'length_after_origin': length_after_origin}) self.ref_model1d= model1d if self.phase_window['length_before_phase'] < 0: sys.exit('set window length_before_phase > 0') if phase_selected != 'P' and phase_selected != 'S': sys.exit('This is not a phase for receiver functions: '+phase_selected)
def __init__(self,stime=UTCDateTime('2002-12-22'),etime=UTCDateTime('2003-12-31'),min_mag=5.5,max_mag=9.0, search_center=(38.54,28.63), min_search_radius=30,max_search_radius=95, min_dep=0.,max_dep=800.): mag_type='Mw' self.magnitude_range= AttribDict({'mag_type': mag_type,'min_mag':min_mag,'max_mag':max_mag}) self.time_range= AttribDict({'stime':stime,'etime':etime}) self.distance_range= AttribDict({'center_lat': search_center[0],'center_lon':search_center[1], 'min_radius_in_deg':min_search_radius, 'max_radius_in_deg':max_search_radius}) self.depth_range= AttribDict({'min_depth':min_dep, 'max_depth':max_dep})
def export_sac(db, filename, pair, components, filterid, corr, ncorr=0, sac_format=None, maxlag=None, cc_sampling_rate=None): if sac_format is None: sac_format = get_config(db, "sac_format") if maxlag is None: maxlag = float(get_config(db, "maxlag")) if cc_sampling_rate is None: cc_sampling_rate = float(get_config(db, "cc_sampling_rate")) try: os.makedirs(os.path.split(filename)[0]) except: pass filename += ".SAC" mytrace = Trace(data=corr) mytrace.stats['station'] = pair mytrace.stats['sampling_rate'] = cc_sampling_rate mytrace.stats.sac = AttribDict() mytrace.stats.sac.b = -maxlag mytrace.stats.sac.depmin = np.min(corr) mytrace.stats.sac.depmax = np.max(corr) mytrace.stats.sac.depmen = np.mean(corr) mytrace.stats.sac.scale = 1 mytrace.stats.sac.npts = len(corr) st = Stream(traces=[mytrace, ]) st.write(filename, format='SAC') del st return
def sachdr2sitechan(header): """ Provide a sac header dictionary, get a sitechan table dictionary. """ sac_sitechan = [('kstnm', 'sta'), ('kcmpnm', 'chan'), ('cmpaz', 'hang'), ('cmpinc', 'vang'), ('stdp', 'edepth')] sitechandict = AttribDict() for hdr, col in sac_sitechan: val = header.get(hdr, None) sitechandict[col] = val if val != SACDEFAULT[hdr] else None try: sitechandict['edepth'] /= 1000.0 except (TypeError, KeyError): #edepth is None or missing pass sitechandict = _cast_float(sitechandict, ['hang', 'vang', 'edepth']) sitechandict = _clean_str(sitechandict, ['sta', 'chan']) sitechandict['sta'] = sitechandict['sta'].strip()[:6] return [sitechandict] or []
def insert_coordinates(stream, coordFile): """ Helper function to write coordinate details into an ObsPy Stream object headers from a text file for array analysis. :type stream: obspy stream object. :param stream: obspy stream object containing data for each array station. :type coordFile: string. :param coordFile: text file with headers trace.id, longitude, latitude and elevation. :return: Stream object, where each trace.stats contains an obspy.core.util.AttribDict with 'latitude', 'longitude' (in degrees) and 'elevation' (in km), or 'x', 'y', 'elevation' (in km) items/attributes. """ coordinates = open(coordFile, 'r') for line in coordinates: c = (line.strip('\n').split('\t')) for tr in stream: if tr.id == c[0]: tr.stats.coordinates = AttribDict({ 'latitude': c[2], 'elevation': c[3], 'longitude': c[1] }) return stream
def test_get_paz(self): t = UTCDateTime('20090808') c = self.client # test the deprecated call too for one/two releases data = c.station.get_paz('BW.MANZ..EHZ', t) self.assertEqual(data['zeros'], [0j, 0j]) self.assertEqual(data['sensitivity'], 2516800000.0) self.assertEqual(len(data['poles']), 5) self.assertEqual(data['poles'][0], (-0.037004 + 0.037016j)) self.assertEqual(data['poles'][1], (-0.037004 - 0.037016j)) self.assertEqual(data['poles'][2], (-251.33 + 0j)) self.assertEqual(data['poles'][3], (-131.03999999999999 - 467.29000000000002j)) self.assertEqual(data['poles'][4], (-131.03999999999999 + 467.29000000000002j)) self.assertEqual(data['gain'], 60077000.0) # test some not allowed wildcards t = UTCDateTime('20120501') self.assertRaises(ValueError, c.station.get_paz, "BW.RLAS..BJ*", t) self.assertRaises(ValueError, c.station.get_paz, "BW.RLAS..*", t) self.assertRaises(ValueError, c.station.get_paz, "BW.RLAS..BJ?", t) self.assertRaises(ValueError, c.station.get_paz, "BW.R*..BJZ", t) # test with a XSEED file with a referenced PAZ response info (see #364) t = UTCDateTime("2012-05-10") result = AttribDict( {'gain': 1.0, 'poles': [0j], 'sensitivity': 6319100000000.0, 'digitizer_gain': 1000000.0, 'seismometer_gain': 6319100.0, 'zeros': [0j]}) data = c.station.get_paz("BW.RLAS..BJZ", t) self.assertEqual(data, result)
def read(cls, filename): """ Read station file_ and return instance of Stations. Format has to be like in Stations.example. """ with open(filename, 'r') as file_: filedata = file_.read() # Create an iterator over matches in Stations file_ st_matches = re.finditer(cls.regex, filedata, re.VERBOSE + re.MULTILINE) # Create a list of dictionaries of PDE data st_list = [i.groupdict() for i in st_matches] st_dic = {} for i in st_list: st_dic[i['name']] = AttribDict({ 'latitude': float(i['latitude']), 'longitude': float(i['longitude']), 'info': i['info'] }) try: st_dic[i['name']]['elevation'] = float(i['elevation']) except TypeError: pass log.info('Read station information of stations %s from file_ %s' % (' '.join(sorted(st_dic.keys())), filename)) return cls(st_dic)
def write_sac(stream,sac_info,inv,suffix,debug): for tr in stream: chan_info=inv.get_channel_metadata(tr.id) tr.stats.sac=AttribDict() tr.stats.sac.stla=chan_info['latitude'] tr.stats.sac.stlo=chan_info['longitude'] tr.stats.sac.stel=chan_info['elevation'] tr.stats.sac.stdp=chan_info['local_depth'] tr.stats.sac.cmpaz=chan_info['azimuth'] tr.stats.sac.cmpinc=chan_info['dip'] khole=float(tr.stats.starttime-sac_info['otime']) tr.stats.sac.b=khole tr.stats.sac.o=0.0 #tr.stats.sac.o=float(tr.stats.starttime-sac_info['otime']) tr.stats.sac.evlo=sac_info['evlo'] tr.stats.sac.evla=sac_info['evla'] tr.stats.sac.evdp=sac_info['evdp'] tr.stats.sac.evel=sac_info['evel'] tr.stats.sac.khole=tr.stats.location t=tr.stats.starttime.strftime('%Y%j%H%M%S') #outfile=sac_info['outdir']+"/"+tr.id+"."+t+suffix #outfile=sac_info['outdir']+"/"+sac_info['evid']+"."+tr.id+suffix #outfile=sac_info['outdir']+"/"+sac_info['evid']+"."+tr.id+suffix outfile=f"{sac_info['outdir']}/{sac_info['evid']}.{tr.id}{suffix}" outfile=Path(outfile) if debug > 0: print("*** writing files: ",outfile) tr.write(filename=outfile.as_posix(),format='SAC')
def test_inside_geobounds(self): obj = AttribDict() obj.latitude = 48.8566 obj.longitude = 2.3522 ret = inside_geobounds(obj, minlatitude=48, maxlatitude=49, minlongitude=2, maxlongitude=3) self.assertTrue(ret) ret = inside_geobounds(obj, latitude=48, longitude=2, minradius=1, maxradius=2) self.assertFalse(ret) # Test for wrapping around longitude +/- 180° obj.latitude = -41.2865 obj.longitude = 174.7762 ret = inside_geobounds(obj, minlongitude=170, maxlongitude=-170) self.assertTrue(ret) obj.longitude = -175. ret = inside_geobounds(obj, minlongitude=170, maxlongitude=-170) self.assertTrue(ret) ret = inside_geobounds(obj, minlongitude=170, maxlongitude=190) self.assertTrue(ret)
def parseFreeForm(self, free_form_str, attrib_dict): """ Parse the free form section stored in free_form_str and save it in attrib_dict. """ # Separate the strings. strings = free_form_str.split(self.string_terminator) # This is not fully according to the SEG-2 format specification (or # rather the specification only speaks about on offset of 2 bytes # between strings and a string_terminator between two free form # strings. The file I have show the following separation between two # strings: 'random offset byte', 'string_terminator', # 'random offset byte' # Therefore every string has to be at least 3 bytes wide to be # acceptable after being split at the string terminator. strings = [_i for _i in strings if len(_i) >= 3] # Every string has the structure OPTION<SPACE>VALUE. Write to # stream.stats attribute. for string in strings: string = string.strip() string = string.split(' ') key = string[0].strip() value = ' '.join(string[1:]).strip() setattr(attrib_dict, key, value) # Parse the notes string again. if hasattr(attrib_dict, 'NOTE'): notes = attrib_dict.NOTE.split(self.line_terminator) attrib_dict.NOTE = AttribDict() for note in notes: note = note.strip() note = note.split(' ') key = note[0].strip() value = ' '.join(note[1:]).strip() setattr(attrib_dict.NOTE, key, value)
def setUp(self): self.event = read_events()[0] self.station = AttribDict({ 'latitude': 41.818 - 66.7, 'longitude': 79.689, 'elevation': 365.4 })
def info(self): try: return self.__cached_info except: pass self.__cached_info = AttribDict(self._get_info()) return self.__cached_info
def test_pretty_str(self): """ Test _pretty_str method of AttribDict. """ # 1 ad = AttribDict({'test1': 1, 'test2': 2}) out = ' test1: 1\n test2: 2' self.assertEqual(ad._pretty_str(), out) # 2 ad = AttribDict({'test1': 1, 'test2': 2}) out = ' test2: 2\n test1: 1' self.assertEqual(ad._pretty_str(priorized_keys=['test2']), out) # 3 ad = AttribDict({'test1': 1, 'test2': 2}) out = ' test1: 1\n test2: 2' self.assertEqual(ad._pretty_str(min_label_length=6), out)
def update_stats(tr, stla, stlo, stel, cha): """ Function to include SAC metadata to :class:`~obspy.core.Trace` objects Parameters ---------- tr : :class:`~obspy.core.Trace` object Trace object to update stla : float Latitude of station stlo : float Longitude of station cha : str Channel for component Returns ------- tr : :class:`~obspy.core.Trace` object Updated trace object """ tr.stats.sac = AttribDict() tr.stats.sac.stla = stla tr.stats.sac.stlo = stlo tr.stats.sac.stel = stel tr.stats.channel = cha return tr
def _convert_to_stream(receiver, components, data, dt_out, starttime, add_band_code=True): # Convert to an ObsPy Stream object. st = Stream() band_code = get_band_code(dt_out) instaseis_header = AttribDict(mu=data["mu"]) for comp in components: tr = Trace( data=data[comp], header={ "delta": dt_out, "starttime": starttime, "station": receiver.station, "network": receiver.network, "location": receiver.location, "channel": add_band_code * (band_code + "X") + comp, "instaseis": instaseis_header, }, ) st += tr return st
def get_model_info(self, model_name): """ Get some information about a particular model. .. rubric:: Example >>> from obspy.clients.syngine import Client >>> c = Client() >>> db_info = c.get_model_info(model_name="ak135f_5s") >>> print(db_info.period) 5.125 :param model_name: The name of the model. Case insensitive. :type model_name: str :returns: A dictionary with more information about any model. :rtype: :class:`obspy.core.util.attribdict.AttribDict` """ model_name = model_name.strip().lower() r = self._download(self._get_url("info"), params={"model": model_name}) info = AttribDict(compatibility.get_json_from_response(r)) # Convert slip and sliprate into numpy arrays for easier handling. info.slip = np.array(info.slip, dtype=np.float64) info.sliprate = np.array(info.sliprate, dtype=np.float64) return info
def test_pretty_str(self): """ Test _pretty_str method of AttribDict. """ # 1 ad = AttribDict({'test1': 1, 'test2': 2}) out = ' test1: 1\n test2: 2' assert ad._pretty_str() == out # 2 ad = AttribDict({'test1': 1, 'test2': 2}) out = ' test2: 2\n test1: 1' assert ad._pretty_str(priorized_keys=['test2']) == out # 3 ad = AttribDict({'test1': 1, 'test2': 2}) out = ' test1: 1\n test2: 2' assert ad._pretty_str(min_label_length=6) == out
def on_station_view_itemClicked(self, item, column): t = item.type() def get_station(item): station = item.parent().text(0) if "." not in station: station = item.parent().parent().text(0) + "." + station return station if t == STATION_VIEW_ITEM_TYPES["NETWORK"]: pass elif t == STATION_VIEW_ITEM_TYPES["STATION"]: pass elif t == STATION_VIEW_ITEM_TYPES["STATIONXML"]: station = get_station(item) for v in self._open_files.values(): if ( station in v["contents"] and v["contents"][station]["has_stationxml"] ): try: v["ds"].waveforms[station].StationXML.plot_response( 0.001 ) except Exception: continue break else: msg_box = QtGui.QMessageBox() msg_box.setText("Could not find StationXML document.") msg_box.exec_() return elif t == STATION_VIEW_ITEM_TYPES["WAVEFORM"]: station = get_station(item) tag = item.text(0) self._state["current_waveform_tag"] = tag self._state["current_station_objects"] = {} st = obspy.Stream() for filename, info in self._open_files.items(): if station not in info["ds"].waveforms: continue _station = info["ds"].waveforms[station] self._state["current_station_objects"][filename] = _station if tag not in _station: continue # Store the color for each trace. _st = _station[tag] for tr in _st: tr.stats.__color = info["color"] tr.stats.sextant = AttribDict() tr.stats.sextant.filename = filename st += _st self.st = st self.update_waveform_plot() else: pass
def attach_paz(tr, paz_file): ''' Attach tr.stats.paz AttribDict to trace from GSE2 paz_file This is experimental code, nevertheless it might be useful. It makes several assumption on the gse2 paz format which are valid for the geophysical observatory in Fuerstenfeldbruck but might be wrong in other cases. Attaches to a trace a paz AttribDict containing poles zeros and gain. The A0_normalization_factor is set to 1.0. :param tr: An ObsPy trace object containing the calib and gse2 calper attributes :param paz_file: path to pazfile or file pointer >>> from obspy.core import Trace >>> import io >>> tr = Trace(header={'calib': .094856, 'gse2': {'calper': 1}}) >>> f = io.StringIO( ... """CAL1 RJOB LE-3D Z M24 PAZ 010824 0001 ... 2 ... -4.39823 4.48709 ... -4.39823 -4.48709 ... 3 ... 0.0 0.0 ... 0.0 0.0 ... 0.0 0.0 ... 0.4""") >>> attach_paz(tr, f) >>> print(round(tr.stats.paz.sensitivity / 10E3) * 10E3) 671140000.0 ''' poles, zeros, seismometer_gain = read_paz(paz_file) # remove zero at 0,0j to undo integration in GSE PAZ for i, zero in enumerate(list(zeros)): if zero == complex(0, 0j): zeros.pop(i) break else: raise Exception("Could not remove (0,0j) zero to undo GSE integration") # ftp://www.orfeus-eu.org/pub/software/conversion/GSE_UTI/gse2001.pdf # page 3 calibration = tr.stats.calib * 2 * np.pi / tr.stats.gse2.calper # fill up ObsPy Poles and Zeros AttribDict tr.stats.paz = AttribDict() # convert seismometer gain from [muVolt/nm/s] to [Volt/m/s] tr.stats.paz.seismometer_gain = seismometer_gain * 1e3 # convert digitizer gain [count/muVolt] to [count/Volt] tr.stats.paz.digitizer_gain = 1e6 / calibration tr.stats.paz.poles = poles tr.stats.paz.zeros = zeros tr.stats.paz.sensitivity = tr.stats.paz.digitizer_gain * \ tr.stats.paz.seismometer_gain # A0_normalization_factor convention for gse2 paz in Observatory in FFB tr.stats.paz.gain = 1.0
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for key in self.extra_keys: if not hasattr(self, 'extra'): self.extra = AttribDict() self.extra[key] = {'value': 0, 'namespace': ns}
def test_in_place(self): self.sr = 10 # sampling rate st = AttribDict({'sampling_rate': self.sr}) testtro = Trace(np.ones(1000), header=st) testtr = testtro.copy() self.assertEqual(testtr, testtro) pu.cos_taper(testtr, 5, False) self.assertNotEqual(testtr, testtro)
def test_compare_with_dict(self): """ Checks if AttribDict is still comparable to a dict object. """ adict = {'test': 1} ad = AttribDict(adict) assert ad == adict assert adict == ad
def test_init_argument(self): """ Tests initialization of AttribDict with various arguments. """ # one dict works as expected ad = AttribDict({'test': 1}) assert ad.test == 1 # multiple dicts results into TypeError with pytest.raises(TypeError): AttribDict({}, {}) with pytest.raises(TypeError): AttribDict({}, {}, blah=1) # non-dicts results into TypeError with pytest.raises(TypeError): AttribDict(1) with pytest.raises(TypeError): AttribDict(object())
def test_compare_with_dict(self): """ Checks if AttribDict is still comparable to a dict object. """ adict = {'test': 1} ad = AttribDict(adict) self.assertEqual(ad, adict) self.assertEqual(adict, ad)
def sachdr2arrival(header, pickmap=None): """Similar to sachdr2assoc, but produces a list of up to 10 Arrival dictionaries. Same header->phase mapping applies, unless otherwise stated. """ # puts t[0-9] times into arrival.time if they're not null # puts corresponding kt[0-9] phase name into arrival.iphase # if a kt[0-9] phase name is null and its t[0-9] values isn't, # phase names are pulled from the pick2phase dictionary pick2phase = { 't0': 'P', 't1': 'Pn', 't2': 'Pg', 't3': 'S', 't4': 'Sn', 't5': 'Sg', 't6': 'Lg', 't7': 'LR', 't8': 'Rg', 't9': 'pP' } if pickmap: pick2phase.update(pickmap) # simple translations arrivaldict = AttribDict() if header.get('kstnm', None) not in (SACDEFAULT['kstnm'], None): arrivaldict['sta'] = header['kstnm'] if header.get('kcmpnm', None) not in (SACDEFAULT['kcmpnm'], None): arrivaldict['chan'] = header['kcmpnm'] # phases and arrival times t0 = get_sac_reftime(header) arrivals = [] for key in pick2phase: kkey = 'k' + key # if there's a value in t[0-9] if header.get('key', None) not in (SACDEFAULT[key], None): # TODO: This seems broken...t isn't defined yet itime = t + header[key] iarrival = { 'time': itime.timestamp, 'jdate': int(itime.strftime('%Y%j')) } # if the phase name kt[0-9] is null if header[kkey] == SACDEFAULT[kkey]: # take it from the pick2phase map iarrival['iphase'] = pick2phase[key] else: # take it directly iarrival['iphase'] = header[kkey] iarrival.update(arrivaldict) # TODO: wtf is iassoc?? arrivals.append(iassoc) return arrivals
def addDistanceAzimuth(self, mainshock): if self.events is None: return from obspy.core import AttribDict ns = "http://earthquake.usgs.gov/xmlns/1.0" origin = mainshock.preferred_origin() utmZone = int(math.floor((origin.longitude + 180) / 6) + 1) proj = pyproj.Proj(proj="utm", zone=utmZone, ellps='WGS84') x0, y0 = proj(origin.longitude, origin.latitude) for event in self.events: origin = event.preferred_origin() xE, yE = proj(origin.longitude, origin.latitude) dx = xE - x0 dy = yE - y0 dist = ((xE - x0)**2 + (yE - y0)**2)**0.5 distAttrib = AttribDict({ 'type': "attribute", 'namespace': ns, 'value': dist }) azimuth = 180.0 * math.atan2(dx, dy) / math.pi if azimuth < 0.0: azimuth += 360.0 azimuthAttrib = AttribDict({ 'type': "attribute", 'namespace': ns, 'value': azimuth }) if hasattr(event, 'extra'): extraAttrib = event.extra else: extraAttrib = AttribDict() event.extra = extraAttrib extraAttrib.mainshock_distance = distAttrib extraAttrib.mainshock_azimuth = azimuthAttrib return
def write(self, filename): """ writes to segy file :param filename: file name :note: the function uses the `obspy` module. """ if not OBSPY_AVAILABLE: raise RuntimeError("This feature (SimpleSEGYWriter.write())"+\ " depends on obspy, which is not installed, see "+\ "https://github.com/obspy/obspy for install guide") if getMPISizeWorld() > 1: raise RuntimeError("Writing segy files with multiple ranks is"+\ " not yet supported.") stream = Stream() for i in range(len(self.__receiver_group)): trace = Trace(data=np.array(self.__trace[i], dtype='float32')) # Attributes in trace.stats will overwrite everything in # trace.stats.segy.trace_header (in Hz) trace.stats.sampling_rate = 1. / self.getSamplingInterval() #trace.stats.starttime = UTCDateTime(2011,11,11,0,0,0) if not hasattr(trace.stats, 'segy.trace_header'): trace.stats.segy = {} trace.stats.segy.trace_header = SEGYTraceHeader() trace.stats.segy.trace_header.trace_identification_code = 1 trace.stats.segy.trace_header.trace_sequence_number_within_line = i + 1 trace.stats.segy.trace_header.scalar_to_be_applied_to_all_coordinates = -int( self.COORDINATE_SCALE) trace.stats.segy.trace_header.coordinate_units = 1 trace.stats.segy.trace_header.source_coordinate_x = int( self.__source[0] * self.COORDINATE_SCALE) trace.stats.segy.trace_header.source_coordinate_y = int( self.__source[1] * self.COORDINATE_SCALE) trace.stats.segy.trace_header.group_coordinate_x = int( self.__receiver_group[i][0] * self.COORDINATE_SCALE) trace.stats.segy.trace_header.group_coordinate_y = int( self.__receiver_group[i][1] * self.COORDINATE_SCALE) # Add trace to stream stream.append(trace) # A SEGY file has file wide headers. This can be attached to the stream # object. If these are not set, they will be autocreated with default # values. stream.stats = AttribDict() stream.stats.textual_file_header = 'C.. ' + self.__text + '\nC.. with esys.escript.downunder r%s\nC.. %s' % ( getVersion(), time.asctime()) stream.stats.binary_file_header = SEGYBinaryFileHeader() if getMPIRankWorld() < 1: stream.write(filename, format="SEGY", data_encoding=1, byteorder=sys.byteorder)
def _write_format_specific_header(self, format): st = self.stats format = format.lower() if format == 'q': format = 'sh' elif format == 'h5': return elif format == 'sac': # workaround for obspy issue 1285, fixed in obspy v1.0.1 # and obspy issue 1457, fixed in obspy v1.0.2 # https://github.com/obspy/obspy/pull/1285 # https://github.com/obspy/obspy/pull/1457 from obspy.io.sac.util import obspy_to_sac_header self.stats.pop('sac', None) self.stats.sac = obspy_to_sac_header(self.stats) # workaround for obspy issue 1507, introduced in obspy v1.0.2 # and fixed in obspy v1.0.3 self.stats.sac.lpspol = True self.stats.sac.lcalda = False try: header_map = zip(_HEADERS, _FORMATHEADERS[format]) except KeyError: if format != 'h5': msg = ("rf in-/output of file format '%s' is not supported" % format) warnings.warn(msg) return if format not in st: st[format] = AttribDict({}) if format == 'sh': comment = {} for head, head_format in header_map: if format == 'sh' and head_format == 'COMMENT': try: comment[head] = st[head] except KeyError: pass continue try: val = st[head] except KeyError: continue try: convert = _HEADER_CONVERSIONS[format][head][1] val = convert(st, head) except KeyError: pass st[format][head_format] = val if format == 'sh' and len(comment) > 0: # workaround for obspy issue #1456, fixed in obspy v1.0.2 # https://github.com/obspy/obspy/pull/1456 for k, v in comment.items(): try: comment[k] = np.asscalar(v) except AttributeError: pass st[format]['COMMENT'] = json.dumps(comment, separators=(',', ':'))