예제 #1
0
def setup_acquisition_sources(args):

    sources = []
    iarg = 0
    while iarg < len(args):
        arg = args[iarg]

        msl = re.match(r'seedlink://([a-zA-Z0-9.-]+)(:(\d+))?(/(.*))?', arg)
        mca = re.match(r'cam://([^:]+)', arg)
        mus = re.match(r'hb628://([^:?]+)(\?([^?]+))?', arg)
        msc = re.match(r'school://([^:]+)', arg)
        med = re.match(r'edl://([^:]+)', arg)
        if msl:
            host = msl.group(1)
            port = msl.group(3)
            if not port:
                port = '18000'

            sl = SlinkAcquisition(host=host, port=port)
            if msl.group(5):
                stream_patterns = msl.group(5).split(',')

                if '_' not in msl.group(5):
                    try:
                        streams = sl.query_streams()
                    except slink.SlowSlinkError as e:
                        logger.fatal(str(e))
                        sys.exit(1)

                    streams = list(
                        set(util.match_nslcs(stream_patterns, streams)))

                    for stream in streams:
                        sl.add_stream(*stream)
                else:
                    for stream in stream_patterns:
                        sl.add_raw_stream_selector(stream)

            sources.append(sl)
        elif mca:
            port = mca.group(1)
            cam = CamAcquisition(port=port, deltat=0.0314504)
            sources.append(cam)
        elif mus:
            port = mus.group(1)
            try:
                d = {}
                if mus.group(3):
                    d = dict(urlparse.parse_qsl(mus.group(3)))  # noqa

                deltat = 1.0 / float(d.get('rate', '50'))
                channels = [(int(c), c) for c in d.get('channels', '01234567')]
                hb628 = USBHB628Acquisition(port=port,
                                            deltat=deltat,
                                            channels=channels,
                                            buffersize=16,
                                            lookback=50)

                sources.append(hb628)
            except Exception:
                raise
                sys.exit('invalid acquisition source: %s' % arg)

        elif msc:
            port = msc.group(1)
            sco = SchoolSeismometerAcquisition(port=port)
            sources.append(sco)
        elif med:
            port = med.group(1)
            edl = EDLAcquisition(port=port)
            sources.append(edl)

        if msl or mca or mus or msc or med:
            args.pop(iarg)
        else:
            iarg += 1

    return sources
def setup_acquisition_sources(args):

    sources = []
    iarg = 0
    while iarg < len(args):
        arg = args[iarg]

        msl = re.match(r'seedlink://([a-zA-Z0-9.-]+)(:(\d+))?(/(.*))?', arg)
        mca = re.match(r'cam://([^:]+)', arg)
        mus = re.match(r'hb628://([^:?]+)(\?([^?]+))?', arg)
        msc = re.match(r'school://([^:]+)', arg)
        med = re.match(r'edl://([^:]+)', arg)
        if msl:
            host = msl.group(1)
            port = msl.group(3)
            if not port:
                port = '18000'

            sl = SlinkAcquisition(host=host, port=port)
            if msl.group(5):
                stream_patterns = msl.group(5).split(',')

                if '_' not in msl.group(5):
                    try:
                        streams = sl.query_streams()
                    except slink.SlowSlinkError as e:
                        logger.fatal(str(e))
                        sys.exit(1)

                    streams = list(set(
                        util.match_nslcs(stream_patterns, streams)))

                    for stream in streams:
                        sl.add_stream(*stream)
                else:
                    for stream in stream_patterns:
                        sl.add_raw_stream_selector(stream)

            sources.append(sl)
        elif mca:
            port = mca.group(1)
            cam = CamAcquisition(port=port, deltat=0.0314504)
            sources.append(cam)
        elif mus:
            port = mus.group(1)
            try:
                d = {}
                if mus.group(3):
                    d = dict(urlparse.parse_qsl(mus.group(3)))  # noqa

                deltat = 1.0/float(d.get('rate', '50'))
                channels = [(int(c), c) for c in d.get('channels', '01234567')]
                hb628 = USBHB628Acquisition(
                    port=port,
                    deltat=deltat,
                    channels=channels,
                    buffersize=16,
                    lookback=50)

                sources.append(hb628)
            except Exception:
                raise
                sys.exit('invalid acquisition source: %s' % arg)

        elif msc:
            port = msc.group(1)
            sco = SchoolSeismometerAcquisition(port=port)
            sources.append(sco)
        elif med:
            port = med.group(1)
            edl = EDLAcquisition(port=port)
            sources.append(edl)

        if msl or mca or mus or msc or med:
            args.pop(iarg)
        else:
            iarg += 1

    return sources
예제 #3
0
    def call(self):
        self.cleanup()
        viewer = self.get_viewer()
        events = [m.get_event() for m in self.get_selected_event_markers()]
        for iev, ev in enumerate(events):
            ev.name = '%05i' % iev


        show_arrivals = False

        filters = []
        for ident in ['high', 'low']:
            val = getattr(self, ident)
            if val != None:
                filters.append(trace.ButterworthResponse(corner=float(val),
                                                         order=4,
                                                         type=ident))

        stations = self.get_stations()
        traces = list(self.chopper_selected_traces(fallback=True, trace_selector=
                                                   viewer.trace_selector,
                                                   load_data=False))
        traces = [tr for trs in traces for tr in trs ]
        visible_nslcs = [tr.nslc_id for tr in traces]
        stations = filter(lambda s: util.match_nslcs("%s.%s.%s.*" % s.nsl(), visible_nslcs), stations)

        # TODO option to choose other models
        mod = cake.load_model()
        nevents = len(events)
        pile = self.get_pile()
        targets = make_targets(pile, stations)
        if len(targets)==0:
            self.fail("No station available")
        ntargets = len(targets)
        self.cc = num.zeros((ntargets, nevents, nevents), dtype=num.float)
        self.similarity_matrix = SimilarityMatrix(targets=targets,
                                                  events=events,
                                                  filters=filters,
                                                  padding=float(self.tpad),
                                                  windowing_method=self.time_window_choice,
                                                  vmax=float(self.vmax),
                                                  vmin=float(self.vmin))
        similarities = []
        trs2add = []
        if self.save_traces :
            figure_dir = self.input_directory(caption='Select directory to store images')
        for itarget, target in enumerate(targets):
            print (itarget+1.)/float(ntargets)
            ok_filtered = []
            markers = []
            for iev, ev in enumerate(events):
                dist = target.distance_to(ev)
                if self.time_window_choice=='vmin/vmax':
                    tmin = ev.time + dist / self.vmax - self.tpad
                    tmax = ev.time + dist / self.vmin + self.tpad
                elif self.time_window_choice=='P-phase':
                    d = dist*cake.m2d
                    z = ev.depth
                    t = self.phase_cache.get((mod, d, z), False)
                    if not t:
                        rays = mod.arrivals(
                            phases=[cake.PhaseDef(x) for x in 'p P'.split()],
                            distances=[d],
                            zstart=z)
                        t = rays[0].t
                        self.phase_cache[(mod, d, z)] = t
                    tmin = ev.time + t - self.tpad * 0.1
                    tmax = ev.time + t + self.tpad * 0.9
                trs = pile.chopper(tmin=tmin,
                                   tmax=tmax,
                                   trace_selector=viewer.trace_selector,
                                   want_incomplete=False)
                tr = [t for trss  in trs for t in trss if t.nslc_id==target.codes]
                if len(tr)==0:
                    continue
                elif len(tr)==1:
                    tr = tr[0]
                else:
                    self.fail('Something went wrong')
                if self.dt_wanted:
                    tr.downsample_to(self.dt_wanted)

                tr2 = tr.copy()
                for f in filters:
                    tr2 = tr2.transfer(transfer_function=f)
                tr2.chop(tmin, tmax)
                tr2.set_codes(location=ev.name+'f')

                tr.chop(tmin, tmax)
                tr.set_codes(location=ev.name+'r')

                ok_filtered.append((iev, ev, tr2))

            ok = ok_filtered
            while ok:
                (ia, a_ev, a_tr) = ok.pop()
                for (ib, b_ev, b_tr) in ok:
                    relamp = 0.0
                    if a_tr is not None and b_tr is not None:
                        c_tr = trace.correlate(a_tr, b_tr, mode='full', normalization='normal')
                        t_center = c_tr.tmin+(c_tr.tmax-c_tr.tmin)/2.
                        c_tr_chopped = c_tr.chop(t_center-self.tdist, t_center+self.tdist, inplace=False)
                        t_mini, v_mini = c_tr_chopped.min()
                        t_maxi, v_maxi = c_tr_chopped.max()
                        b_tr_shifted = b_tr.copy()
                        a_tr_shifted = a_tr.copy()

                        if abs(v_mini) > abs(v_maxi):
                            v_cc = v_mini
                            time_lag = -t_mini
                        else:
                            time_lag = -t_maxi
                            v_cc = v_maxi

                        self.cc[itarget, ia, ib] = v_cc
                        b_tr_shifted.shift(time_lag)

                        if self.cc[itarget, ia, ib] != 0.0:
                            tmin = max(a_tr.tmin, b_tr_shifted.tmin)
                            tmax = min(a_tr.tmax, b_tr_shifted.tmax)
                            try:
                                a_tr_chopped = a_tr.chop(tmin, tmax, inplace=False)
                                b_tr_chopped = b_tr_shifted.chop(tmin, tmax)
                            except trace.NoData:
                                logger.warn('NoData %s'%a_tr_chopped)
                                continue

                            ya = a_tr_chopped.ydata
                            yb = b_tr_chopped.ydata
                            relamp = num.sum(ya*yb) / num.sum(ya**2)

                        if self.save_traces:
                            fig, axes = plt.subplots(3,1)
                            fig.suptitle('.'.join(target.codes))
                            axes[0].plot(a_tr_chopped.get_xdata(), a_tr_chopped.get_ydata())
                            axes[0].text(0, 1, "id: %s, time: %s" %(a_ev.name, util.time_to_str(a_ev.time)),
                                         transform=axes[0].transAxes,
                                         verticalalignment='top', horizontalalignment='left')
                            axes[1].plot(b_tr_chopped.get_xdata(), b_tr_chopped.get_ydata())
                            axes[1].text(0, 1, "id: %s, time: %s" %(b_ev.name, util.time_to_str(b_ev.time)),
                                         transform=axes[1].transAxes,
                                         verticalalignment='top', horizontalalignment='left')
                            axes[2].plot(c_tr.get_xdata(), c_tr.get_ydata())
                            axes[2].text(0, 1, 'cc_max: %1.4f' % v_cc,
                                         transform=axes[2].transAxes,
                                         verticalalignment='top', horizontalalignment='left')
                            fn = op.join(figure_dir, 'cc_T%s.E%s.E%s.png' % (itarget, ia, ib))
                            fig.savefig(fn, pad_inches=0.1, bbox_inches='tight', tight_layout=True)

                        sim = Similarity(
                            ievent=ia,
                            jevent=ib,
                            itarget=itarget,
                            cross_correlation=float(self.cc[itarget, ia, ib]),
                            relative_amplitude=float(relamp),
                            time_lag=float(-time_lag))

                        similarities.append(sim)

        if self.show_results:
            for itarget, target in enumerate(targets):
                if not num.any(self.cc[itarget]):
                    continue
                fig = self.pylab(get='figure')
                fig.suptitle('.'.join(target.codes))
                axes = fig.add_subplot(111)
                axes.set_xlabel('Event number')
                axes.set_ylabel('Event number')
                mesh = axes.pcolormesh(self.cc[itarget,:,:], cmap='RdBu', vmin=-1.0, vmax=1.0)
                cb = fig.colorbar(mesh, ax=axes)
                cb.set_label('Max correlation coefficient')
                fig.canvas.draw()

        self.similarity_matrix.similarities = similarities
        self.similarity_matrix.validate()
예제 #4
0
    def call(self):
        self.cleanup()
        viewer = self.get_viewer()
        events = [m.get_event() for m in self.get_selected_event_markers()]
        for iev, ev in enumerate(events):
            ev.name = '%05i' % iev


        show_arrivals = False

        filters = []
        for ident in ['high', 'low']:
            val = getattr(self, ident)
            if val != None:
                filters.append(trace.ButterworthResponse(corner=float(val),
                                                         order=4,
                                                         type=ident))

        stations = self.get_stations()
        traces = list(self.chopper_selected_traces(fallback=True, trace_selector=
                                                   viewer.trace_selector,
                                                   load_data=False))
        traces = [tr for trs in traces for tr in trs ]
        visible_nslcs = [tr.nslc_id for tr in traces]
        stations = [x for x in stations if util.match_nslcs(
            "%s.%s.%s.*" % x.nsl(), visible_nslcs)]

        # TODO option to choose other models
        mod = cake.load_model()
        nevents = len(events)
        pile = self.get_pile()
        targets = make_targets(pile, stations)
        if len(targets)==0:
            self.fail("No station available")
        ntargets = len(targets)
        self.cc = num.zeros((ntargets, nevents, nevents), dtype=num.float)
        self.similarity_matrix = SimilarityMatrix(targets=targets,
                                                  events=events,
                                                  filters=filters,
                                                  padding=float(self.tpad),
                                                  windowing_method=self.time_window_choice,
                                                  vmax=float(self.vmax),
                                                  vmin=float(self.vmin))
        similarities = []
        if self.save_traces :
            figure_dir = self.input_directory(caption='Select directory to store images')
        for itarget, target in enumerate(targets):
            print((itarget+1.)/float(ntargets))
            ok_filtered = []
            markers = []
            for iev, ev in enumerate(events):
                dist = target.distance_to(ev)
                if self.time_window_choice=='vmin/vmax':
                    tmin = ev.time + dist / self.vmax - self.tpad
                    tmax = ev.time + dist / self.vmin + self.tpad
                elif self.time_window_choice=='P-phase':
                    d = dist*cake.m2d
                    z = ev.depth
                    t = self.phase_cache.get((mod, d, z), False)
                    if not t:
                        rays = mod.arrivals(
                            phases=[cake.PhaseDef(x) for x in 'p P'.split()],
                            distances=[d],
                            zstart=z)
                        t = rays[0].t
                        self.phase_cache[(mod, d, z)] = t
                    tmin = ev.time + t - self.tpad * 0.1
                    tmax = ev.time + t + self.tpad * 0.9
                trs = pile.chopper(tmin=tmin,
                                   tmax=tmax,
                                   trace_selector=viewer.trace_selector,
                                   want_incomplete=False)
                tr = [t for trss  in trs for t in trss if t.nslc_id==target.codes]
                if len(tr)==0:
                    continue
                elif len(tr)==1:
                    tr = tr[0]
                else:
                    self.fail('Something went wrong')
                if self.dt_wanted:
                    tr.downsample_to(self.dt_wanted)

                tr2 = tr.copy()
                for f in filters:
                    tr2 = tr2.transfer(transfer_function=f)
                tr2.chop(tmin, tmax)
                tr2.set_codes(location=ev.name+'f')

                tr.chop(tmin, tmax)
                tr.set_codes(location=ev.name+'r')

                ok_filtered.append((iev, ev, tr2))

            ok = ok_filtered
            while ok:
                (ia, a_ev, a_tr) = ok.pop()
                for (ib, b_ev, b_tr) in ok:
                    relamp = 0.0
                    if a_tr is not None and b_tr is not None:
                        c_tr = trace.correlate(a_tr, b_tr, mode='full', normalization='normal')
                        t_center = c_tr.tmin+(c_tr.tmax-c_tr.tmin)/2.
                        c_tr_chopped = c_tr.chop(t_center-self.tdist, t_center+self.tdist, inplace=False)
                        t_mini, v_mini = c_tr_chopped.min()
                        t_maxi, v_maxi = c_tr_chopped.max()
                        b_tr_shifted = b_tr.copy()

                        if abs(v_mini) > abs(v_maxi):
                            v_cc = v_mini
                            time_lag = -t_mini
                        else:
                            time_lag = -t_maxi
                            v_cc = v_maxi

                        self.cc[itarget, ia, ib] = v_cc
                        b_tr_shifted.shift(time_lag)

                        if self.cc[itarget, ia, ib] != 0.0:
                            tmin = max(a_tr.tmin, b_tr_shifted.tmin)
                            tmax = min(a_tr.tmax, b_tr_shifted.tmax)
                            try:
                                a_tr_chopped = a_tr.chop(tmin, tmax, inplace=False)
                                b_tr_chopped = b_tr_shifted.chop(tmin, tmax)
                            except trace.NoData:
                                logger.warn('NoData %s'%a_tr_chopped)
                                continue

                            ya = a_tr_chopped.ydata
                            yb = b_tr_chopped.ydata
                            relamp = num.sum(ya*yb) / num.sum(ya**2)

                        if self.save_traces:
                            fig, axes = plt.subplots(3,1)
                            fig.suptitle('.'.join(target.codes))
                            axes[0].plot(a_tr_chopped.get_xdata(), a_tr_chopped.get_ydata())
                            axes[0].text(0, 1, "id: %s, time: %s" %(a_ev.name, util.time_to_str(a_ev.time)),
                                         transform=axes[0].transAxes,
                                         verticalalignment='top', horizontalalignment='left')
                            axes[1].plot(b_tr_chopped.get_xdata(), b_tr_chopped.get_ydata())
                            axes[1].text(0, 1, "id: %s, time: %s" %(b_ev.name, util.time_to_str(b_ev.time)),
                                         transform=axes[1].transAxes,
                                         verticalalignment='top', horizontalalignment='left')
                            axes[2].plot(c_tr.get_xdata(), c_tr.get_ydata())
                            axes[2].text(0, 1, 'cc_max: %1.4f' % v_cc,
                                         transform=axes[2].transAxes,
                                         verticalalignment='top', horizontalalignment='left')
                            fn = op.join(figure_dir, 'cc_T%s.E%s.E%s.png' % (itarget, ia, ib))
                            fig.savefig(fn, pad_inches=0.1, bbox_inches='tight', tight_layout=True)

                        sim = Similarity(
                            ievent=ia,
                            jevent=ib,
                            itarget=itarget,
                            cross_correlation=float(self.cc[itarget, ia, ib]),
                            relative_amplitude=float(relamp),
                            time_lag=float(-time_lag))

                        similarities.append(sim)

        if self.show_results:
            for itarget, target in enumerate(targets):
                if not num.any(self.cc[itarget]):
                    continue
                fig = self.pylab(get='figure')
                fig.suptitle('.'.join(target.codes))
                axes = fig.add_subplot(111)
                axes.set_xlabel('Event number')
                axes.set_ylabel('Event number')
                mesh = axes.pcolormesh(self.cc[itarget,:,:], cmap='RdBu', vmin=-1.0, vmax=1.0)
                cb = fig.colorbar(mesh, ax=axes)
                cb.set_label('Max correlation coefficient')
                fig.canvas.draw()

        self.similarity_matrix.similarities = similarities
        self.similarity_matrix.validate()
예제 #5
0
    def call(self):
        self.cleanup()
        c_station_id = ('_', 'STK')
        if self.unit == 's/deg':
            slow_factor = 1. / onedeg
        elif self.unit == 's/km':
            slow_factor = 1. / 1000.

        slow = self.slow * slow_factor
        if self.stacked_traces is not None:
            self.add_traces(self.stacked_traces)
        viewer = self.get_viewer()
        if self.station_c:
            viewer.stations.pop(c_station_id)

        stations = self.get_stations()
        if len(stations) == 0:
            self.fail('No station meta information found')

        traces = list(self.chopper_selected_traces(fallback=True))
        traces = [tr for trs in traces for tr in trs]
        visible_nslcs = [tr.nslc_id for tr in traces]
        stations = [
            x for x in stations
            if util.match_nslcs("%s.%s.%s.*" % x.nsl(), visible_nslcs)
        ]
        if not self.lat_c or not self.lon_c or not self.z_c:
            self.lat_c, self.lon_c, self.z_c = self.center_lat_lon(stations)
            self.set_parameter('lat_c', self.lat_c)
            self.set_parameter('lon_c', self.lon_c)

        self.station_c = Station(lat=float(self.lat_c),
                                 lon=float(self.lon_c),
                                 elevation=float(self.z_c),
                                 depth=0.,
                                 name='Array Center',
                                 network=c_station_id[0],
                                 station=c_station_id[1])

        viewer.add_stations([self.station_c])
        lat0 = num.array([self.lat_c] * len(stations))
        lon0 = num.array([self.lon_c] * len(stations))
        lats = num.array([s.lat for s in stations])
        lons = num.array([s.lon for s in stations])
        ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
        theta = num.float(self.bazi * num.pi / 180.)
        R = num.array([[num.cos(theta), -num.sin(theta)],
                       [num.sin(theta), num.cos(theta)]])
        distances = R.dot(num.vstack((es, ns)))[1]
        channels = set()
        self.stacked = {}
        num_stacked = {}
        self.t_shifts = {}
        shifted_traces = []
        taperer = trace.CosFader(xfrac=0.05)
        if self.diff_dt_treat == 'downsample':
            traces.sort(key=lambda x: x.deltat)
        elif self.diff_dt_treat == 'oversample':
            dts = [t.deltat for t in traces]
            for tr in traces:
                tr.resample(min(dts))

        for tr in traces:
            if tr.nslc_id[:2] == c_station_id:
                continue
            tr = tr.copy(data=True)
            tr.ydata = tr.ydata.astype(num.float64)
            tr.ydata -= tr.ydata.mean(dtype=num.float64)
            tr.taper(taperer)
            try:
                stack_trace = self.stacked[tr.channel]
                num_stacked[tr.channel] += 1
            except KeyError:
                stack_trace = tr.copy(data=True)
                stack_trace.set_ydata(num.zeros(len(stack_trace.get_ydata())))

                stack_trace.set_codes(network=c_station_id[0],
                                      station=c_station_id[1],
                                      location='',
                                      channel=tr.channel)

                self.stacked[tr.channel] = stack_trace
                channels.add(tr.channel)
                num_stacked[tr.channel] = 1

            nslc_id = tr.nslc_id

            try:
                stats = [
                    x for x in stations
                    if util.match_nslc('%s.%s.%s.*' % x.nsl(), nslc_id)
                ]

                stat = stats[0]
            except IndexError:
                break

            i = stations.index(stat)
            d = distances[i]
            t_shift = d * slow
            tr.shift(t_shift)
            stat = viewer.get_station(tr.nslc_id[:2])
            self.t_shifts[stat] = t_shift
            if self.normalize_std:
                tr.ydata = tr.ydata / tr.ydata.std()

            if num.abs(tr.deltat - stack_trace.deltat) > 0.000001:
                if self.diff_dt_treat == 'downsample':
                    stack_trace.downsample_to(tr.deltat)
                elif self.diff_dt_treat == 'upsample':
                    print(
                        'something went wrong with the upsampling, previously')
            stack_trace.add(tr)

            if self.add_shifted:
                tr.set_station('%s_s' % tr.station)
                shifted_traces.append(tr)

        if self.post_normalize:
            for ch, tr in self.stacked.items():
                tr.set_ydata(tr.get_ydata() / num_stacked[ch])

        self.cleanup()

        for ch, tr in self.stacked.items():
            if num_stacked[ch] > 1:
                self.add_trace(tr)

        if self.add_shifted:
            self.add_traces(shifted_traces)
예제 #6
0
    def call(self):
        self.cleanup()
        c_station_id = ('_', 'STK')
        if self.unit == 's/deg':
            slow_factor = 1./onedeg
        elif self.unit == 's/km':
            slow_factor = 1./1000.

        slow = self.slow*slow_factor
        if self.stacked_traces is not None:
            self.add_traces(self.stacked_traces)
        viewer = self.get_viewer()
        if self.station_c:
            viewer.stations.pop(c_station_id)

        stations = self.get_stations()
        if len(stations) == 0:
            self.fail('No station meta information found')

        traces = list(self.chopper_selected_traces(fallback=True))
        traces = [tr for trs in traces for tr in trs ]
        visible_nslcs = [tr.nslc_id for tr in traces]
        stations = filter(lambda s: util.match_nslcs("%s.%s.%s.*" % s.nsl(), visible_nslcs), stations)
        if not self.lat_c or not self.lon_c or not self.z_c:
            self.lat_c, self.lon_c, self.z_c = self.center_lat_lon(stations)
            self.set_parameter('lat_c', self.lat_c)
            self.set_parameter('lon_c', self.lon_c)

        self.station_c = Station(lat=float(self.lat_c),
                                 lon=float(self.lon_c),
                                 elevation=float(self.z_c),
                                 depth=0.,
                                 name='Array Center',
                                 network=c_station_id[0],
                                 station=c_station_id[1])

        viewer.add_stations([self.station_c])
        lat0 = num.array([self.lat_c]*len(stations))
        lon0 = num.array([self.lon_c]*len(stations))
        lats = num.array([s.lat for s in stations])
        lons = num.array([s.lon for s in stations])
        ns, es = ortho.latlon_to_ne_numpy(lat0, lon0, lats, lons)
        theta = num.float(self.bazi*num.pi/180.)
        R = num.array([[num.cos(theta), -num.sin(theta)],
                        [num.sin(theta), num.cos(theta)]])
        distances = R.dot(num.vstack((es, ns)))[1]
        channels = set()
        self.stacked = {}
        num_stacked = {}
        self.t_shifts = {}
        shifted_traces = []
        taperer = trace.CosFader(xfrac=0.05)
        if self.diff_dt_treat=='downsample':
            traces.sort(key=lambda x: x.deltat)
        elif self.diff_dt_treat=='oversample':
            dts = [t.deltat for t in traces]
            for tr in traces:
                tr.resample(min(dts))

        for tr in traces:
            if tr.nslc_id[:2] == c_station_id:
                continue
            tr = tr.copy(data=True)
            tr.ydata = tr.ydata.astype(num.float64)
            tr.ydata -= tr.ydata.mean(dtype=num.float64)
            tr.taper(taperer)
            try:
                stack_trace = self.stacked[tr.channel]
                num_stacked[tr.channel] += 1
            except KeyError:
                stack_trace = tr.copy(data=True)
                stack_trace.set_ydata(num.zeros(
                    len(stack_trace.get_ydata())))

                stack_trace.set_codes(network=c_station_id[0],
                                      station=c_station_id[1],
                                      location='',
                                      channel=tr.channel)

                self.stacked[tr.channel] = stack_trace
                channels.add(tr.channel)
                num_stacked[tr.channel] = 1

            nslc_id = tr.nslc_id

            try:
                stats = filter(lambda x: util.match_nslc(
                    '%s.%s.%s.*' % x.nsl(), nslc_id), stations)

                stat = stats[0]
            except IndexError:
                break

            i = stations.index(stat)
            d = distances[i]
            t_shift = d*slow
            tr.shift(t_shift)
            stat = viewer.get_station(tr.nslc_id[:2])
            self.t_shifts[stat] = t_shift
            if self.normalize_std:
                tr.ydata = tr.ydata/tr.ydata.std()

            if num.abs(tr.deltat-stack_trace.deltat)>0.000001:
                if self.diff_dt_treat=='downsample':
                    stack_trace.downsample_to(tr.deltat)
                elif self.diff_dt_treat=='upsample':
                    print 'something went wrong with the upsampling, previously'
            stack_trace.add(tr)

            if self.add_shifted:
                tr.set_station('%s_s' % tr.station)
                shifted_traces.append(tr)

        if self.post_normalize:
            for ch, tr in self.stacked.items():
                tr.set_ydata(tr.get_ydata()/num_stacked[ch])
        
        self.cleanup()

        for ch, tr in self.stacked.items():
            if num_stacked[ch]>1:
                self.add_trace(tr)

        if self.add_shifted:
            self.add_traces(shifted_traces)