package com.isti.traceview.data;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Date;
import org.apache.log4j.Logger;
import com.isti.traceview.TraceViewException;
import com.isti.traceview.processing.IstiUtilsMath;
import com.isti.traceview.processing.RunEvalResp;
import edu.sc.seis.fissuresUtil.freq.Cmplx;
/**
* Class to represent response
* @author Max Kokoulin
*
*/
public class Response {
private static final Logger logger = Logger.getLogger(Response.class);
private static final boolean verboseDebug = false;
String network = null;
String station = null;
String location = null;
String channel = null;
String content = null;
String fileName = null;
/**
*
* @param network network code
* @param station station code
* @param location location code
* @param channel channel code
* @param content String with content of evalresp response file
* @param fileName name of file from which response was loaded
*/
public Response(String network, String station, String location, String channel, String content, String fileName) {
this.network = network;
this.station = station;
this.location = location;
this.channel = channel;
this.content = content;
this.fileName = fileName;
}
public String getNetwork() {
return network;
}
public String getStation() {
return station;
}
public String getLocation() {
return location;
}
public String getChannel() {
return channel;
}
public String getFileName(){
return fileName;
}
/**
* Get default store file name for response
*/
public String getLocalFileName(){
return "RESP."+getNetwork()+"."+getStation()+"."+getLocation()+"."+getChannel();
}
public String getContent() {
return content;
}
/**
* Generate response as complex spectra
*
* @param date
* Time stamp to search response
* @param minFreqValue
* minimum requested frequency
* @param maxFreqValue
* maximum requested frequency
* @param len
* length of generated response array
* @return response as array of complex numbers
* @throws TraceViewException
* if thrown in
* {@link com.isti.traceview.processing.RunEvalResp#generateResponse(double, double, int, Date, Reader)}
*/
public Cmplx[] getResp(Date date, double minFreqValue, double maxFreqValue,
int len) throws TraceViewException {
RunEvalResp evalResp = new RunEvalResp(false, verboseDebug);
return evalResp.generateResponse(minFreqValue, maxFreqValue, len, date,
new StringReader(getContent()));
}
public double[] getRespAmp(Date date, double minFreqValue, double maxFreqValue, int len) throws TraceViewException {
RunEvalResp evalResp = new RunEvalResp(false, verboseDebug);
double[] respAmp = IstiUtilsMath.getSpectraAmplitude(evalResp.generateResponse(minFreqValue, maxFreqValue, len, date, new StringReader(getContent())));
if (respAmp.length != len) {
throw new TraceViewException(getLocalFileName() + ": The length of the RESPONSE AMPLITUDE (" + respAmp.length + ") does not match the number of frequencies ("
+ len + ")");
}
// Calper = 1/calibration frequency (Frequency of sensitivity)
final double calper = Math.pow(evalResp.frequencyOfSensitivity, -1.0);
// Calval = 1/overal sensitivity (Sensitivity)
final double calib = Math.pow(evalResp.sensitivity, -1.0);
if (IstiUtilsMath.calibAmpResp(respAmp, calper, calib, minFreqValue, maxFreqValue, len) != IstiUtilsMath.ISTI_UTIL_SUCCESS) {
throw new TraceViewException(getLocalFileName() + ": Calibration frequency is " + calper + " outside range of <" + minFreqValue + " : " + maxFreqValue
+ ">: continue without proper calibration");
}
return respAmp;
}
public boolean equals(Object o) {
if (o instanceof Response) {
Response r = (Response) o;
return (getNetwork().equals(r.getNetwork()) && getStation().equals(r.getStation()) && getChannel().equals(r.getChannel()) && getLocation()
.equals(r.getLocation()));
} else {
return false;
}
}
/**
* Computes frequency parameters which should be used to compute proper response function out of RESP file
*
* @param numSamples the number of samples.
* @param sampRate the sample rate.
* @return the frequency parameters.
*/
/*
public static FreqParameters getFreqParameters(int numSamples, double sampRate) {
final double endFreq = sampRate / 2.0;
final double startFreq = 1.e-30;
final int numFreq = (int) (numSamples / 2.0 + 1.0 + 0.5); // 0.5 for double to int conversion
final double sampFreq = (endFreq - startFreq) / ((double) (numFreq - 1.0));
return new FreqParameters(startFreq, endFreq, sampFreq, numFreq);
}
*/
public static FreqParameters getFreqParameters(int numSamples, double sampRate) {
final double endFreq = sampRate / 2.0;
final int numFreq = (int) (numSamples / 2.0 + 1.0 + 0.5); // 0.5 for double to int conversion
final double startFreq = endFreq/numFreq;
//(double)
final double sampFreq = (endFreq - startFreq) / (numFreq - 1.0);
return new FreqParameters(startFreq, endFreq, sampFreq, numFreq);
}
/**
* Initialize response from file
*/
public static Response getResponse(File file){
Response resp = null;
Reader respReader = null;
if(!file.getName().startsWith("RESP.")){
logger.error("getResponse("+file.getName()+"): response file should starts with RESP.");
return null;
}
try {
String[] split = file.getName().split("\\.");
String network = split[1];
String station = split[2];
String location = split[3];
String channel = split[4];
respReader = new BufferedReader(new FileReader(file));
int len = (int) file.length();
char[] cbuf = new char[len];
respReader.read(cbuf, 0, len);
resp = new Response(network, station, location, channel, new String(cbuf), file.getCanonicalPath());
} catch (Exception ex) {
StringBuilder message = new StringBuilder();
message.append("Could not open file: " + file.getName());
logger.error(message.toString(), ex);
} finally {
try {
respReader.close();
} catch (IOException e) {
logger.error("IOException:", e);
}
}
return resp;
}
/**
*
*
*/
public static class FreqParameters {
public final double startFreq;
public final double endFreq;
public final double sampFreq;
public final int numFreq;
public FreqParameters(double startFreq, double endFreq, double sampFreq, int numFreq) {
this.startFreq = startFreq;
this.endFreq = endFreq;
this.sampFreq = sampFreq;
this.numFreq = numFreq;
}
}
}