⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seedreader.java

📁 一个用java写的地震分析软件(无源码)-used to write a seismic analysis software (without source)
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package org.trinet.jasi.seed;

import java.io.*;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.util.*;
import java.lang.*;
import java.math.*;

import org.trinet.jasi.*;
import org.trinet.jdbc.*;
import org.trinet.util.Bits;
import org.trinet.util.DateTime;
import org.trinet.util.TimeSpan;
import org.trinet.util.EpochTime;
import org.trinet.util.BenchMark;

import org.trinet.util.WaveClient;

// Changed to use Fissure decoder to get Steim2
// see: http://www.seis.sc.edu/software/Fissures/seed.html
import edu.iris.Fissures.seed.codec.Steim1;
import edu.iris.Fissures.seed.codec.Steim2;

/**
 * SeedReader. Read seed files and interpret them. All methods in the class are
 * static because we want only one instance of the RemoteFileReader. The class will
 * determine if Waveform files are local or remote at instantiation time.
 * If remote, the class reads from the data source using DbBlobReader which gets
 * timeseries using a stored procedure in the dbase. <p>
 *
 * This class also knows how to read the waveforms from various data sources.
 * See the various getDataXxxxxx() methods.

 */
/*
1/15/02 Integrated AWW's DbBlobReader
*/
public class SeedReader {
/* double Precision problems!
0.01 * 300 = 3.0
0.01 * 301 = 3.0100000000000002
0.01 * 302 = 3.02
0.01 * 303 = 3.0300000000000002
0.01 * 304 = 3.04
0.01 * 305 = 3.0500000000000003
*/

protected static CallableStatement csStmt;

// SEED header
  static SeedHeader header;

  // Header fields
  /*
  static int    sequenceNumber;
  static String stationName;
  static String locationName;
  static String componentName;
  static String networkName;
  static String headerType;

  static double startTime;		// converted to local epoch

  static int    sampleCount;		// count of samples in the Seed packet
  static double samplesPerSecond;
  static double sampleMultiplier;

  static byte activityFlag;
  static byte ioFlag;
  static byte qualityFlag;
  static int  headerTimeCorrection;

  static private int blockettesFollowing;

  static int dataOffset;               //byte offset to start of data, counting from byte 0
  static int blocketteOffset;          //start of 1st blockette, counting from byte 0

// Blockette 1000
  static int encodingFormat;            // from blockette 1000
  static int wordOrder;			//0=VAX/Intel, 1=SUN/Motorola
  static int dataRecordLength;
*/
    // Data encoding formats described in SEED v2.3,  see SEED Ref. Man. pg. 106
    // ONLY STEIM1 IS CURRENTLY SUPPORTED
//    public static final byte STEIM1	  = 10;
//    public static final byte STEIM2	  = 11;
//    public static final byte GEOSCOPE24   = 12;
//    public static final byte GEOSCOPE16_3 = 13;
//    public static final byte GEOSCOPE16_4 = 14;
//    public static final byte USNSN	  = 15;
//    public static final byte CDSN	  = 16;
//    public static final byte GRAEFENBERG  = 17;
//    public static final byte IGP	  = 18;

// Blockette 1001
  static int timeQuality;
  static int timeCorrection;
  static int reserved;
  static int framesInRecord;

// reuseable variable to reduce instantiations in methods :. speed up
  static int map[] = new int[16];	// 0 - 15;			// map of compression mask
//  static float pt[];			// ref. to decompressed samples
  static int imap = -1;
  static int firstValue;
  static int lastValue;

  static final int FrameSize = 64;	// in bytes

/** Bytes per read */
  final static int READBUFFERSIZE = 16384;

/** bytes per Seed packet work area, equal to maximum Seed packet size we can handle */
  final static int DEFAULTSEEDBLOCKSIZE  = 8192;    // bytes per Seed packet

// move this to file scope?
  static byte[] buff = new byte[DEFAULTSEEDBLOCKSIZE];

  static int seedBlockSize;	// may be set otherwise someday

  static TimeSpan fileSpan = new TimeSpan(); // earliest & latest times in file

  static Waveform wf;
  static WFSegment wfseg = new WFSegment();

    // Make the FTP reader, make one at instantiation time so the connection
    // will remain open rather then getting garbage collected.
    //  static RemoteFileReader remoteReader = new RemoteFileReader();
//  static RemoteFileReader remoteReader = null;
  static DbBlobReader dbBlobReader = null;

  static boolean accessKnown = false;		// is local/remote known?

/**
 * JDBConn must already be established.
 */

    public SeedReader ()
    {
    }
/** Decompresses MiniSEED packets.  Returns float[] of time-series samples if
* packet header indicates a data packet, else returns null.
*
* @exception java.lang.SeedReaderException input null, input packet <512 bytes, or i/o
* error parsing packet data.  */
    public static float [] getDataSamples(byte [] seedPacket) throws SeedReaderException {
        float [] samples = null;
        try {
           if (seedPacket == null)
               throw new NullPointerException("SeedReader.getDataSamples(byte[]) Null input parameter");
           if (seedPacket.length < 512)
               throw new IllegalArgumentException("SeedReader.getDataSamples(byte[]) Input byte array length:"
                                                   + seedPacket.length + " is too short for known packet sizes");

            WFSegment wfSegment = createWFSegment(seedPacket);
      header = getHeader();

            if (header.isData() ) { // decompress only data messages
                samples = decompress (header, seedPacket);
            }
        }
        catch (NullPointerException ex) {
            throw new SeedReaderException(ex.getMessage());
        }
        catch (IllegalArgumentException ex) {
            throw new SeedReaderException(ex.getMessage());
        }
        catch (Exception ex) {
            ex.printStackTrace();
            throw new SeedReaderException("getDataSamples(): " + ex.getMessage());
        }
        return samples;
    }

/** Decodes a Collection containing miniSEED time-series data packets as elements.
* Returns a Collection of jasi.WFSegments with the same number of elements.
* @exception java.lang.SeedReaderException input null, or i/o error parsing packet data.
*/
    public static Collection getWFSegments(Collection packetList) {
        if (packetList == null)
                throw new NullPointerException("getWFSegments() Null input collection of seed packets.");

        final int MAX_PACKET_SIZE = 8192;        // test efficiency, instead of dynamically creating new arrays for each packet.
        Collection wfSegmentCollection = new ArrayList(packetList.size());
        Iterator iter = packetList.iterator();

        try {
            while (iter.hasNext()) {
                byte [] seedPacket = (byte []) iter.next();
    WFSegment wfSegment = createWFSegment(seedPacket);
    header = getHeader();

                if ( header.isData() ) { // decompress only data messages
                   wfSegment.setTimeSeries(
                        decompress (header, seedPacket)
                   );
                }
                wfSegmentCollection.add(wfSegment);
            }
        }
        catch (NullPointerException ex) {
            throw new SeedReaderException(ex.getMessage());
        }
        catch (Exception ex) {
            ex.printStackTrace();
            throw new SeedReaderException("getWFSegments(): " + ex.getMessage());
        }
        return wfSegmentCollection;
    }

/**
 * Read a file in Seed format as described in a waveform object. Returns
 * the number of WFSegments read . The access method, local or remote,
 * is determined automatically.
 */

public static int getData (Waveform wf) {
    return getData(wf, wf.getStart().doubleValue(), wf.getEnd().doubleValue());
}

public static int getData (Waveform wf, double startTime, double endTime) {
    if (wf.getWaveSourceType() == Waveform.LoadFromDataSource) {
  // Try accessing locally first, if that fails use remote access.
  if (wf.filesAreLocal()) {
      return getDataLocal(wf);	// try local access
        }
        else {
      return getDataFromDataSource(wf, startTime, endTime); // try test DB access via blob - aww
        }
  //} else {
  //    return getDataRemote(wf);	// try remote ftp access
  //}
    } else if (wf.getWaveSourceType() == Waveform.LoadFromWaveServer) {
  return getDataFromWaveServer(wf);
    }
    return 0;
}

    //** Get timeseries from a wave server */
    public static int getDataFromWaveServer (Waveform waveform) {

       WaveClient waveClient = (WaveClient) Waveform.getWaveSource();

       //       System.out.println ("SeedReader: waveClient ="+waveClient);

       try {

     // Get the time-series
     waveClient.setTruncatetAtTimeGap(false);

        // not sure this is always true
        waveform.setAmpUnits(Units.COUNTS);

     return waveClient.getJasiWaveformDataRaw (waveform);

       }
       catch (Exception ex) {
     System.err.println(ex.toString());
     ex.printStackTrace();
       }
       finally {
     //	   if (waveClient != null) waveClient.close();
       }

       return 0;
    }


/**
 * Return a ChannelableList of Waveform objects extracted from a Local or NFS mounted file
 * containing Seed format.  Returns null on fatal error. */

public static ChannelableList getDataFromFile (String filename, int traceoff) {

    ChannelableList wfList = new ChannelableList();
    Waveform wf = null;

    FileInputStream seedStream;
    File file = new File(filename);

    long filesize = file.length();
    filesize -= traceoff;

    //    System.out.println ("SeedReader opening "+file+ "  "+traceoff+"  "+nbytes);

    // open the Seed File
    try {
//      seedStream = new FileInputStream(filename);
      seedStream = new FileInputStream(file);
    } catch (FileNotFoundException exc) {
  System.out.println ("File not found: " + filename);
  return null;
    } catch (IOException exc) {
  System.err.println ("IO error: " + exc.toString());
  return null;
    }

    BufferedInputStream inbuff =
  new BufferedInputStream (seedStream, READBUFFERSIZE);

    int buffOffset = 0;
    int dataSize = 0;
    int totalBytes = 0;
    int lastChannelStart = 0;

// skip the proper byte offset in the file

    if (traceoff > 0) {
  try {
    long bytesSkippped = inbuff.skip(traceoff);

    // catch non-exception problems
    if (bytesSkippped != traceoff) {
        System.err.println ("IO error: could only skip "+bytesSkippped+
          " wanted to skip " + traceoff);
        return null;
    }
      } catch (IOException exc) {
    System.err.println ("IO error skipping to data offset: " +
            exc.toString());
    return null;
      }
    }

// file read loop; while data is there and we haven't yet gotten all the bytes
    try {
     while (inbuff.available() > 0) {
     // && totalBytes < nbytes) {

  buffOffset = 0;
/*
 * NOTE: Seed packets can be of various sizes, although the size must be a power of 2.
 * You don't know what the size is until you read the header of the packet.
 */
// <1> read the header

//NOTE: DANGER HERE: THIS ASSUMES THE HEADER IS TOTALLY CONTAINED WITHIN THE
//      FIRST 64-BYTE FRAME. HEADERS MAY EXTEND INTO SUBSEQUENT FRAMES IF THE
//      BLOCKETTES FILL THE FIRST ONE (E.G. THE "V" HEADERS ARE > 64 BYTES)
  totalBytes +=
      inbuff.read(buff, buffOffset, FrameSize);	// read one Seed header (64 bytes)

  lastChannelStart =  totalBytes - FrameSize;   // beginning of a channel's data

  header = SeedHeader.parseSeedHeader(buff);

  if (header == null) {
     System.out.println("Skipping malformed SEED header");
     continue;  // continue while loop to read next frame
  } else if (!header.isData()) {
     System.out.println("Skipping non-data header of type "+ header.headerType);
     continue;  // continue while loop to read next frame
  }

  wfseg = SeedReader.createWFSegment(header);
  if (wfseg == null) return null;   // bad data

// <2> read the data part now that we know how big it is (=blockSize)

  dataSize = header.seedBlockSize - FrameSize;

  buffOffset = FrameSize;	    // start storing bytes in buffer at # 64

  totalBytes +=
      inbuff.read(buff, buffOffset, dataSize);	// append Seed data frames

  if ( header.isData() )	// a data "record"
  {

       // decompress the data into the WFSegment
    wfseg.setTimeSeries( decompress (header, buff) );

     // is it a channel we already have in our list
     wf = (Waveform) wfList.getByChannel(wfseg.getChannelObj());

     if (wf == null) {            // not in list :. a new channel/waveform
        wf = Waveform.create();

        // not sure this is always true
        wf.setAmpUnits(Units.COUNTS);
        wf.setFileOffset(lastChannelStart);
        wf.setFilename(filename);
        wf.setFileOffset(traceoff);
        wf.setChannelObj(wfseg.getChannelObj());
        wf.format.setValue(Waveform.SEED_FORMAT);
        wf.setSampleRate(1.0/wfseg.getSampleInterval());
        wf.encoding.setValue(header.encodingFormat);
        wf.setStart(wfseg.getStart());
    //           wf.id = evid;   // no meaningfull file!

        wfList.add(wf);
     }
       // add segment to the Waveform
    wf.getSegmentList().add(wfseg);
    wf.setEnd(wfseg.getEnd());       // push back end time

   } else {	// skip non-data blocks
    // noop
   }

      // progress
      System.out.print ("\rRead: " +(int) (((double)totalBytes/(double)filesize) * 100.0)+"%  "+
                       totalBytes+ "  / "+ filesize);

     } // end of while loop
      System.out.println ("");

      inbuff.close();
      seedStream.close();
    } catch (IOException exc) {
    System.err.println ("IO error: " + exc.toString());
    exc.printStackTrace();
    } catch (Exception exc) {
    System.err.println ("General exception: " + exc.toString());
    exc.printStackTrace();
    }

    // collapse multiple segements into minimum possible
    Waveform wfa[] = (Waveform[]) wfList.toArray(new Waveform[0]);
    for (int i = 0; i < wfa.length; i++) {

      if (wfa[i] != null ) {
        wfa[i].collapse();
        // set max, min, bias values

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -