Seisplotjs Tutorial

Helicorder

See it live in tutorial6.html.

Now for something completely different. A helicorder style plot is a nice way to quickly look at a large amount of data from a single station, usually a entire day, by breaking it into multiple lines. A common style is 12 lines each covering 2 hours. First we need to get the data, but to illustrate another technique for finding services, we will use the FDSN Datacenter Registry to find the IRIS dataselect web service. As before, we need to create a div to put it in, and we add some headers with spans to label it.


            <h3>A Helicorder for <span id="channel"></span>!</h3>
            <h5>From </span> to <span id="endtime"></span></h5>
            <div id="helicorder">
            </div>
          

We also need a little styling to size the div.


              div#helicorder {
                height: 600px;
              }
          

A little trickery finds the end time that is an even hour boundary, so that if the current time is 10:45, we will make the plot go to 12:00 instead of just 11:00, keeping each line's hour to an even value. You can create a custom query to the FDSN Datacenters Registry, but there is a convenience method to just get standard FDSN web services. So, we will just get the first fdsn-dataselect web service that we find in the IRISDMC datacenter. Being a remote operation, this also returns a Promise.


            const plotEnd = seisplotjs.moment.utc().endOf('hour').add(1, 'millisecond');
            if (plotEnd.hour() % 2 === 1) {plotEnd.add(1, 'hour');}
            const timeWindow = new seisplotjs.util.StartEndDuration(null, plotEnd, seisplotjs.moment.duration(1, 'day'));
            new seisplotjs.fdsndatacenters.DataCentersQuery().findFdsnDataSelect("IRISDMC")
          

In the then method of the Promise from findFdsnDataSelect, we construct our dataselect query. Because the helicorder will need 24 hours of data, it is probably best not to try this on a 100 samples per second HHZ channel, but a 1 sample per second LHZ channel should be fine. The querySeismograms() method of course returns a Promise.


            .then(dataSelectArray => {
              return dataSelectArray[0].networkCode('CO')
                .stationCode('JSC')
                .locationCode('00')
                .channelCode('LHZ')
                .timeWindow(timeWindow)
                .querySeismograms();
          

In the following then method, we populate out text spans using d3 and then configure our helicorder. One extra bit we add is a marker for the current time. Since each line is 2 hours, without this marker it is hard to know if the station is way behind or if we are just in the middle of a two hour section, so adding a marker helps. Lastly, we draw the helicorder. If any errors occur, the catch is invoked that should output an error message to the page.


          }).then(seisArray => {
            seisplotjs.d3.select("span#channel").text(seisArray[0].codes());
            seisplotjs.d3.select("span#starttime").text(timeWindow.start.format('YYYY-MM-DD HH:mm')+"Z");
            seisplotjs.d3.select("span#endtime").text(timeWindow.end.format('YYYY-MM-DD HH:mm')+"Z");
            let heliConfig = new seisplotjs.helicorder.HelicorderConfig(timeWindow);
            heliConfig.title = `Helicorder for ${seisArray[0].codes()}`;
            let seisData = seisplotjs.seismogram.SeismogramDisplayData.fromSeismogram(seisArray[0]);
            seisData.addMarkers([ { markertype: 'predicted', name: "now", time: seisplotjs.moment.utc() } ]);
            let helicorder = new seisplotjs.helicorder.Helicorder("div#helicorder",
                                          heliConfig,
                                          seisData);
            helicorder.draw();
          }).catch( function(error) {
            seisplotjs.d3.select("div#helicorder").append('p').html("Error loading data." +error);
            console.assert(false, error);
          });
          

See it live in tutorial6.html.

Previous: Deconvolution and Filtering

Next: Realtime Data