gov.usgs.anss.query.filefactory.SacFileFactory.java Source code

Java tutorial

Introduction

Here is the source code for gov.usgs.anss.query.filefactory.SacFileFactory.java

Source

/*
 * Copyright 2010, Institute of Geological & Nuclear Sciences Ltd or
 * third-party contributors as indicated by the @author tags.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package gov.usgs.anss.query.filefactory;

import edu.sc.seis.TauP.SacTimeSeries;
import gov.usgs.anss.query.CustomEvent;
import gov.usgs.anss.query.NSCL;
import gov.usgs.anss.query.ZeroFilledSpan;
import gov.usgs.anss.query.cwb.data.CWBDataServer;
import gov.usgs.anss.query.metadata.ChannelMetaData;
import gov.usgs.anss.query.metadata.MetaDataQuery;
import gov.usgs.anss.query.metadata.MetaDataServer;
import gov.usgs.anss.query.outputter.Filename;
import gov.usgs.anss.seed.MiniSeed;
import nz.org.geonet.simplequakeml.domain.Event;
import org.joda.time.DateTime;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author geoffc
 */
public class SacFileFactory {

    private static final Logger logger = Logger.getLogger(SacFileFactory.class.getName());
    private CWBDataServer cwbServer = null;
    private MetaDataServer metaDataServer = null;
    private Event event = null;
    private String synthetic = null;
    private CustomEvent customEvent = null;
    private String pzunit = null;
    private boolean picks = true;
    private boolean extendedPhases = false;
    private boolean gaps = true;
    private boolean trim = false;
    private Integer fill = SacTimeSeries.INT_UNDEF;

    static {
        logger.fine("$Id$");
    }

    public void setCWBDataServer(CWBDataServer cwbServer) {
        this.cwbServer = cwbServer;
    }

    public void setMetaDataServer(MetaDataServer metaDataServer) {
        this.metaDataServer = metaDataServer;
    }

    public void setEvent(Event event) {
        this.event = event;
    }

    public void setSynthetic(String synthetic) {
        this.synthetic = synthetic;
    }

    public void setCustomEvent(CustomEvent customEvent) {
        this.customEvent = customEvent;
    }

    public void setExtendedPhases(boolean extendedPhases) {
        this.extendedPhases = extendedPhases;
    }

    public void setFill(Integer fill) {
        this.fill = fill;
    }

    public void setGaps(boolean gaps) {
        this.gaps = gaps;
    }

    public void setPicks(boolean picks) {
        this.picks = picks;
    }

    public void setPzunit(String pzunit) {
        this.pzunit = pzunit;
    }

    public void setTrim(boolean trim) {
        this.trim = trim;
    }

    public void makeFiles(DateTime begin, double duration, String nsclSelectString, String mask) {
        cwbServer.query(begin, duration, nsclSelectString);
        if (cwbServer.hasNext()) {
            do {
                SacTimeSeries sac = makeTimeSeries(cwbServer.getNext(), begin, duration, this.fill, this.gaps,
                        this.trim);
                if (sac != null) {
                    if (this.event != null) {
                        SacHeaders.setEventHeader(sac, this.event);
                        if (this.picks) {
                            if (this.synthetic == null) {
                                SacHeaders.setPhasePicks(sac, this.event);
                            } else {
                                SacHeaders.setPhasePicks(sac, this.event, this.extendedPhases, this.synthetic);
                            }
                        } else {
                            if (this.synthetic != null) {
                                SacHeaders.setPhasePicks(sac, this.extendedPhases, this.synthetic);
                            }
                        }
                    } else {
                        if (this.customEvent != null) {
                            SacHeaders.setEventHeader(sac, this.customEvent.getEventTime(),
                                    this.customEvent.getEventLat(), this.customEvent.getEventLon(),
                                    this.customEvent.getEventDepth(), this.customEvent.getEventMag(),
                                    this.customEvent.getEventMagType().magNum(),
                                    this.customEvent.getEventType().eventTypeNum());
                        }
                        if (this.synthetic != null) {
                            SacHeaders.setPhasePicks(sac, this.extendedPhases, this.synthetic);
                        }
                    }

                    outputFile(sac, begin, mask, this.pzunit);
                } else {
                    // TODO logger message about null data
                }
            } while (cwbServer.hasNext());
        } else {
            logger.info(String.format("No matching data for \"%s\", at begin time %s, duration %.2fs, on %s:%d",
                    nsclSelectString, begin.toString("YYYY/MM/dd HH:mm:ss"), duration, cwbServer.getHost(),
                    cwbServer.getPort()));
        }
    }

    public SacTimeSeries makeTimeSeries(TreeSet<MiniSeed> miniSeed, DateTime begin, double duration, Integer fill,
            boolean gaps, boolean trim) {
        // This logic isn't strictly the same as SacOutputter.
        if (!gaps && fill == null) {
            fill = 2147000000;
        }

        // Use the span to populate a sac file

        TimeZone tz = TimeZone.getTimeZone("GMT+0");
        TimeZone.setDefault(tz);
        GregorianCalendar start = new GregorianCalendar();
        start.setTimeInMillis(begin.getMillis());

        // build the zero filled area (either with exact limits or with all blocks)
        ZeroFilledSpan span = new ZeroFilledSpan(new ArrayList(miniSeed), start, duration, fill);
        if (span.getRate() <= 0.00) {
            return null; // There is no real data to put in SAC
        }

        NSCL nscl = NSCL.stringToNSCL(miniSeed.first().getSeedName());

        logger.fine("ZeroSpan=" + span.toString());

        int noval = span.getNMissingData();

        if (!gaps && span.hasGapsBeforeEnd()) {
            logger.warning("  ** " + nscl.toString() + " has gaps - discarded # missing =" + noval);
            return null;
        }

        //ZeroFilledSpan span = new ZeroFilledSpan(blks);

        SacTimeSeries sac = new SacTimeSeries();
        sac.npts = span.getNsamp();

        // Set the byteOrder based on native architecture and sac statics
        sac.nvhdr = 6; // Only format supported
        sac.b = 0.; // beginning time offsed
        sac.e = ((span.getNsamp() - 1) / span.getRate());
        sac.iftype = SacTimeSeries.ITIME;
        sac.leven = SacTimeSeries.TRUE;
        sac.delta = (1. / span.getRate());
        sac.depmin = span.getMin();
        sac.depmax = span.getMax();
        sac.nzyear = span.getStart().get(Calendar.YEAR);
        sac.nzjday = span.getStart().get(Calendar.DAY_OF_YEAR);
        sac.nzhour = span.getStart().get(Calendar.HOUR_OF_DAY);
        sac.nzmin = span.getStart().get(Calendar.MINUTE);
        sac.nzsec = span.getStart().get(Calendar.SECOND);
        sac.nzmsec = span.getStart().get(Calendar.MILLISECOND);
        sac.iztype = SacTimeSeries.IB;

        sac.knetwk = nscl.getNetwork().replaceAll("_", "").trim();
        sac.kstnm = nscl.getStation().replaceAll("_", "").trim();
        sac.kcmpnm = nscl.getChannel().replaceAll("_", "").trim();
        sac.khole = nscl.getLocation().replaceAll("_", "").trim();

        logger.finer("Sac stla=" + sac.stla + " stlo=" + sac.stlo + " stel=" + sac.stel + " cmpaz=" + sac.cmpaz
                + " cmpinc=" + sac.cmpinc + " stdp=" + sac.stdp);
        sac.y = new double[span.getNsamp()]; // allocate space for data
        int nodata = 0;
        for (int i = 0; i < span.getNsamp(); i++) {
            sac.y[i] = span.getData(i);
            if (sac.y[i] == fill) {
                nodata++;
                //if(nodata <3) logger.finest(i+" nodata len="+span.getNsamp());
            }
        }
        if (nodata > 0) {
            logger.finest("#No data points = " + nodata + " fill=" + fill + " npts=" + sac.npts);
        }
        if (trim) {
            int trimmed = sac.trimNodataEnd(fill);
            if (trimmed > 0) {
                logger.info(trimmed + " data points trimmed from end containing no data");
            }
        }

        if (metaDataServer != null) {
            MetaDataQuery mdq = new MetaDataQuery(metaDataServer);
            ChannelMetaData md = mdq.getChannelMetaData(nscl, begin);
            sac = SacHeaders.setChannelHeader(sac, md);
        }

        return sac;
    }

    // TODO: move the getSACResponse to outputPZ or something.
    protected void outputFile(SacTimeSeries timeSeries, DateTime begin, String mask, String pzunit) {

        NSCL nscl = new NSCL(timeSeries.knetwk, timeSeries.kstnm, timeSeries.kcmpnm,
                timeSeries.khole.length() != 0 ? timeSeries.khole : "__");

        String filename = Filename.makeFilename(mask, nscl, begin);
        if (mask.equals("%N")) {
            filename += ".sac";
        }
        filename = filename.replaceAll("[__]", "_");

        try {
            timeSeries.write(filename);
            if (pzunit != null && metaDataServer != null) {
                MetaDataQuery mdq = new MetaDataQuery(metaDataServer);
                mdq.getSACResponse(nscl, begin, pzunit, filename + ".pz");
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(SacFileFactory.class.getName()).log(Level.SEVERE, "File not found writing to SAC", ex);
        } catch (IOException ex) {
            Logger.getLogger(SacFileFactory.class.getName()).log(Level.SEVERE, "IO exception writing to SAC", ex);
        }
    }
}