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.
* <pre>
* 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
* </pre>
* <pre>
* 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
* </pre>
*/
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)");
}
}