package lab10; import java.awt.Color; import java.util.Scanner; import java.io.*; import edu.mines.jtk.dsp.Sampling; // see documentation online import edu.mines.jtk.mosaic.*; /** * Convenient class for tiltmeter data; for internal use only (not public). */ class TiltData { Sampling t; // uniform time sampling, in hours since 2004.09.01 float[] x; // measured tilts, in nrad (nanoradians!) TiltData(Sampling t, float[] x) { this.t = t; this.x = x; } } /** * Reads and writes tiltmeter data. * Data were extracted from Matlab files provided by * Professor Hartmut Spetzler, University of Colorado. *
 * Text file format: 
 * line 1: number of samples
 * line 2: time sampling interval, in hours since 2004.09.01
 * line 3: time of first sample, in hours since 2004.09.01
 * all remaining lines contain tilts, in nanoradians
 * 
*
 * Binary file format: 
 * int: number of samples
 * float: time sampling interval, in hours since 2004.09.01
 * float: time of first sample, in hours since 2004.09.01
 * all remaining floats contain tilts, in nanoradians
 * 
*/ public class TiltMeter { /** * Main program. (No args required.) */ public static void main(String[] args) { TiltData td; // Text file I/O; when done, tilt.txt and tilt2.txt should be identical. td = readText("src/lab10/tilt.txt"); plot(td); writeText(td,"src/lab10/tilt2.txt"); td = readText("src/lab10/tilt2.txt"); plot(td); // Binary file I/O; when done, tilt.dat and tilt2.dat should be identical. td = readBinary("src/lab10/tilt.dat"); plot(td); writeBinary(td,"src/lab10/tilt2.dat"); td = readBinary("src/lab10/tilt2.dat"); plot(td); // Some useful processing. plot(td, despike(td)); } /** * Reads tiltmeter data from text file. * @param fileName name of text file. * @return tiltmeter data; null, if I/O exception is thrown. */ static TiltData readText(String fileName) { FileInputStream fis = null; try { fis = new FileInputStream(fileName); } catch (IOException e) { System.out.println(e); System.exit(0); } Scanner s = new Scanner(fis); int n = s.nextInt(); float interval = s.nextFloat(); float initial = s.nextFloat(); float[] f = new float[n]; for (int i = 0; i < n; i++) { f[i] = s.nextFloat(); } s.close(); return new TiltData(new Sampling(n, interval, initial), f); } /** * Writes tiltmeter data to text file. * @param td tiltmeter data. * @param fileName name of text file. */ static void writeText(TiltData td, String fileName) { try { FileOutputStream fos = new FileOutputStream(fileName); PrintWriter pw = new PrintWriter(fos); int n = td.t.getCount(); float interval = (float)td.t.getDelta(); float initial = (float)td.t.getFirst(); pw.println(n); pw.println(interval); pw.println(initial); for (int i = 0; i < n; i++) { pw.println(td.x[i]); } pw.close(); } catch (IOException e) { System.out.println(e); } } /** * Reads tiltmeter data from binary file. * @param fileName name of binary file. * @return tiltmeter data; null, if I/O exception is thrown. */ static TiltData readBinary(String fileName) { try { FileInputStream fis = new FileInputStream(fileName); DataInputStream dis = new DataInputStream(fis); int n = dis.readInt(); float interval = dis.readFloat(); float initial = dis.readFloat(); float[] f = new float[n]; for (int i = 0; i < n; i++) { f[i] = dis.readFloat(); } dis.close(); return new TiltData(new Sampling(n, interval, initial), f); } catch (IOException e) { System.out.println(e); } return null; } /** * Writes tiltmeter data to binary file. * @param td tiltmeter data. * @param fileName name of binary file. */ static void writeBinary(TiltData td, String fileName) { try { FileOutputStream fos = new FileOutputStream(fileName); DataOutputStream dos = new DataOutputStream(fos); int n = td.t.getCount(); float interval = (float)td.t.getDelta(); float initial = (float)td.t.getFirst(); dos.writeInt(n); dos.writeFloat(interval); dos.writeFloat(initial); for (int i = 0; i < n; i++) { dos.writeFloat(td.x[i]); } dos.close(); } catch (IOException e) { System.out.println(e); } } /** * Removes noise spikes from tiltmeter data. * For all except the first and last samples, output values equal * the median of the three nearest input samples. * @param td input tiltmeter data; not modified * @return output despiked tiltmeter data */ static TiltData despike(TiltData td) { float[] f = td.x; int n = td.t.getCount(); Sampling sampling = td.t; float[] d = new float[n]; for (int i = 0; i < n; i++) { if (i == 0) // first sample { d[0] = f[0]; } else { if (i == n-1) //last sample { d[n-1] = f[n-1]; } else { float before = f[i-1]; float current = f[i]; float after = f[i+1]; if ((before <= current && before >= after) || (before >= current && before <= after)) d[i] = before; else if ((current <= before && current >= after) || (current >= before && current <= after)) d[i] = current; else d[i] = after; } } } return new TiltData(sampling, d); } /** * Plots tiltmeter data. * @param td tiltmeter data */ static void plot(TiltData td) { SimplePlot sp = SimplePlot.asPoints(td.t,td.x); sp.setTitle("Tiltmeter data"); sp.setHLabel("time (hours)"); sp.setVLabel("tilt (nrad)"); } /** * Plots two sequences of tiltmeter data. * @param td1 tiltmeter data * @param td2 tiltmeter data */ static void plot(TiltData td1, TiltData td2) { SimplePlot sp = new SimplePlot(); PointsView pv1 = sp.addPoints(td1.t,td1.x); pv1.setLineColor(Color.RED); PointsView pv2 = sp.addPoints(td2.t,td2.x); pv2.setLineColor(Color.BLUE); sp.setTitle("Tiltmeter data"); sp.setHLabel("time (hours)"); sp.setVLabel("tilt (nrad)"); } }