
/** 
 * ArithmeticTransformThread.java
 * do basic arithematic on the data
 * 
 *
 * Created:  Jan 8, 2004
 *
 * @author Nathan Stevens
 * @version 0.4 6/9/07
 */
import java.util.Vector;

public class ArithmeticTransformThread extends Thread {
  private TransformDialog transformDialog = null; // the dialog where results are sent
  private SpectraData[] sdata = null; // the spectra data
  private String axis = null; // which axis to operate on
  private String op = null; // the operation
  private Vector sdataVector = new Vector(); // stores the results
  private float fc = 0.0f; // the constant that being used
  
  public ArithmeticTransformThread(TransformDialog transformDialog, SpectraData[] sdata, 
                                                               String axis, String op, float fc) {
    this.transformDialog = transformDialog;
    this.sdata = sdata;
    this.axis = axis;
    this.op = op;
    this.fc = fc;
  }
  
  // The run method
  public void run() {
    if(op.equals("+")) {
      addConstant();
    }
    else if(op.equals("-")) {
      subtractConstant();
    }
    else if(op.equals("/")) {
      divideByConstant();
    }
    else if(op.equals("*")) {
      multiplyByConstant();
    }
    else if(op.equals("log")) {
      logSpectra();
    }
    else if(op.equals("exp")) {
      expSpectra();
    }
    else {
      System.err.println("Unknown Operation (" + op + ") in ArithmeticTransformThread...");
    }
  }
  
  // Method to add a constant to a number
  private void addConstant() {
     for(int i = 0; i < sdata.length; i++) {
       String[] header = (String[])sdata[i].getHeader().clone();
       String[] dmeta = (String[])sdata[i].getMetaInfo().clone();
       
       float[][] data = sdata[i].getData();
       float[][] rdata = sdata[i].getReferenceData();
       float[][] ndata = new float[data.length][2];
       float[][] nrdata = null;
       
       if(rdata != null) {
         nrdata = new float[data.length][2];
       }
       
       for(int j = 0; j < data.length; j++) {
         if(axis.equals("Y")) {
           ndata[j][0] = data[j][0];
           ndata[j][1] = data[j][1] + fc;
         }
         else {
           ndata[j][0] = data[j][0] + fc;
           ndata[j][1] = data[j][1];
         }
         
         if(rdata != null) {
           if(axis.equals("Y")) {
             nrdata[j][0] = rdata[j][0];
             nrdata[j][1] = rdata[j][1] + fc;
           }
           else {
             nrdata[j][0] = rdata[j][0] + fc;
             nrdata[j][1] = rdata[j][1];
           }
         }
       }
       
       String name = null;
       String type = sdata[i].getType();
       int direction = sdata[i].getProfileDirection();
       
       if(type.equals("pump-probe")) {
         name = sdata[i].getName() + "-" + header[3] + "-AATF";
         if(direction == 1) {
           type = "pump-probeTP";
         }
       }
       else {
         name = sdata[i].getName() + "-AATF";
       }
       
       SpectraData sd = new SpectraData(name, type, header, dmeta,
                                                                   ndata, nrdata);
       
       sd.setProfileDirection(direction);
       
       sdataVector.addElement(sd);
     }
     
     if(sdataVector.size() > 0) {
      SpectraData[] sda = SpectraDataUtil.getSpectraDataArray(sdataVector);
      transformDialog.setResults(sda);
    }
    transformDialog.setStatus(0, "No Message");
  }
  
  // Method to substract a constant
  private void subtractConstant() {
    for(int i = 0; i < sdata.length; i++) {
       String[] header = (String[])sdata[i].getHeader().clone();
       String[] dmeta = (String[])sdata[i].getMetaInfo().clone();
       
       float[][] data = sdata[i].getData();
       float[][] rdata = sdata[i].getReferenceData();
       float[][] ndata = new float[data.length][2];
       float[][] nrdata = null;
       
       if(rdata != null) {
         nrdata = new float[data.length][2];
       }
       
       for(int j = 0; j < data.length; j++) {
         if(axis.equals("Y")) {
           ndata[j][0] = data[j][0];
           ndata[j][1] = data[j][1] - fc;
         }
         else {
           ndata[j][0] = data[j][0] - fc;
           ndata[j][1] = data[j][1];
         }
         
         if(rdata != null) {
           if(axis.equals("Y")) {
             nrdata[j][0] = rdata[j][0];
             nrdata[j][1] = rdata[j][1] - fc;
           }
           else {
             nrdata[j][0] = rdata[j][0] - fc;
             nrdata[j][1] = rdata[j][1];
           }
         }
       }
       
       String name = null;
       String type = sdata[i].getType();
        int direction = sdata[i].getProfileDirection();
       
       if(type.equals("pump-probe")) {
         name = sdata[i].getName() + "-" + header[3] + "-ASTF";
         if(direction == 1) {
           type = "pump-probeTP";
         }
       }
       else {
         name = sdata[i].getName() + "-ASTF";
       }
       
       SpectraData sd = new SpectraData(name, type, header, dmeta,
                                     ndata, nrdata);
       
       sd.setProfileDirection(direction);
       
       sdataVector.addElement(sd);
     }
     
     if(sdataVector.size() > 0) {
      SpectraData[] sda = SpectraDataUtil.getSpectraDataArray(sdataVector);
      transformDialog.setResults(sda);
    }
    transformDialog.setStatus(0, "No Message");
  }
  
  // Method to devide spectra by constant
  private void divideByConstant() {
    for(int i = 0; i < sdata.length; i++) {
       String[] header = (String[])sdata[i].getHeader().clone();
       String[] dmeta = (String[])sdata[i].getMetaInfo().clone();
       
       float[][] data = sdata[i].getData();
       float[][] rdata = sdata[i].getReferenceData();
       float[][] ndata = new float[data.length][2];
       float[][] nrdata = null;
       
       if(rdata != null) {
         nrdata = new float[data.length][2];
       }
       
       for(int j = 0; j < data.length; j++) {
         if(axis.equals("Y")) {
           ndata[j][0] = data[j][0];
           ndata[j][1] = data[j][1]/fc;
         }
         else {
           ndata[j][0] = data[j][0]/fc;
           ndata[j][1] = data[j][1];
         }
         
         if(rdata != null) {
           if(axis.equals("Y")) {
             nrdata[j][0] = rdata[j][0];
             nrdata[j][1] = rdata[j][1]/fc;
           }
           else {
             nrdata[j][0] = rdata[j][0]/fc;
             nrdata[j][1] = rdata[j][1];
           }
         }
       }
       
       String name = null;
       String type = sdata[i].getType();
       int direction = sdata[i].getProfileDirection();
       
       if(type.equals("pump-probe")) {
         name = sdata[i].getName() + "-" + header[3] + "-ADTF";
         if(direction == 1) {
           type = "pump-probeTP";
         }
       }
       else {
         name = sdata[i].getName() + "-ADTF";
       }
       
       SpectraData sd = new SpectraData(name, type, header, dmeta,
                                                                   ndata, nrdata);
       
       sd.setProfileDirection(direction);
       
       sdataVector.addElement(sd);
     }
     
     if(sdataVector.size() > 0) {
      SpectraData[] sda = SpectraDataUtil.getSpectraDataArray(sdataVector);
      transformDialog.setResults(sda);
    }
    transformDialog.setStatus(0, "No Message");
  }
  
  // Method to devide spectra by constant
  private void multiplyByConstant() {
    for(int i = 0; i < sdata.length; i++) {
       String[] header = (String[])sdata[i].getHeader().clone();
       String[] dmeta = (String[])sdata[i].getMetaInfo().clone();
       
       float[][] data = sdata[i].getData();
       float[][] rdata = sdata[i].getReferenceData();
       float[][] ndata = new float[data.length][2];
       float[][] nrdata = null;
       
       if(rdata != null) {
         nrdata = new float[data.length][2];
       }
       
       for(int j = 0; j < data.length; j++) {
         if(axis.equals("Y")) {
           ndata[j][0] = data[j][0];
           ndata[j][1] = data[j][1]*fc;
         }
         else {
           ndata[j][0] = data[j][0]*fc;
           ndata[j][1] = data[j][1];
         }
         
         if(rdata != null) {
           if(axis.equals("Y")) {
             nrdata[j][0] = rdata[j][0];
             nrdata[j][1] = rdata[j][1]*fc;
           }
           else {
             nrdata[j][0] = rdata[j][0]*fc;
             nrdata[j][1] = rdata[j][1];
           }
         }
       }
       
       
       String name = null;
       String type = sdata[i].getType();
       int direction = sdata[i].getProfileDirection();
       
       if(type.equals("pump-probe")) {
         name = sdata[i].getName() + "-"  + header[3] + "-AMTF";
         if(direction == 1) {
           type = "pump-probeTP";
         }
       }
       else {
         name = sdata[i].getName() + "-AMTF";
       }
       
       SpectraData sd = new SpectraData(name, type, header, dmeta,
                                                                   ndata, nrdata);
       
        sd.setProfileDirection(direction);
       
       sdataVector.addElement(sd);
     }
     
     if(sdataVector.size() > 0) {
      SpectraData[] sda = SpectraDataUtil.getSpectraDataArray(sdataVector);
      transformDialog.setResults(sda);
    }
    transformDialog.setStatus(0, "No Message");
  }
  
  // Method to calculate the log of a spectra
  private void logSpectra() {
    for(int i = 0; i < sdata.length; i++) {
       String[] header = (String[])sdata[i].getHeader().clone();
       String[] dmeta = (String[])sdata[i].getMetaInfo().clone();
       
       float[][] data = sdata[i].getData();
       float[][] rdata = sdata[i].getReferenceData(); // don't touch the reference data
       float[][] ndata = new float[data.length][2];
       
       for(int j = 0; j < data.length; j++) {
         if(axis.equals("Y")) {
           ndata[j][0] = data[j][0];
           
           if(data[j][1] > 1.0f) { // avoid negative numbers
             ndata[j][1] = (float)Math.log(data[j][1]);
           }
           else {
             ndata[j][1] = 0.0f;
           }
         }
         else {
           if(data[j][0] > 1.0f) { // avoid negative numbers
             ndata[j][0] = (float)Math.log(data[j][0]);
           }
           else {
             ndata[j][0] = 0.0f;
           }
           
           ndata[j][1] = data[j][1];
         }
       }
       
       String name = null;
       String type = sdata[i].getType();
       int direction = sdata[i].getProfileDirection();
       
       if(type.equals("pump-probe")) {
         name = sdata[i].getName() + "-"  + header[3] + "-AMTF";
         if(direction == 1) {
           type = "pump-probeTP";
         }
       }
       else {
         name = sdata[i].getName() + "-LnTF";
       }
       
       SpectraData sd = new SpectraData(name, type, header, dmeta,
                                                                   ndata, rdata);
       
       sd.setProfileDirection(direction);
       
       sdataVector.addElement(sd);
     }
     
     if(sdataVector.size() > 0) {
      SpectraData[] sda = SpectraDataUtil.getSpectraDataArray(sdataVector);
      transformDialog.setResults(sda);
    }
    transformDialog.setStatus(0, "No Message");
  }
  
  // Method to calculate the exp of a spectra
  private void expSpectra() {
    for(int i = 0; i < sdata.length; i++) {
       String[] header = (String[])sdata[i].getHeader().clone();
       String[] dmeta = (String[])sdata[i].getMetaInfo().clone();
       
       float[][] data = sdata[i].getData();
       float[][] rdata = sdata[i].getReferenceData(); // don't touch the reference data
       float[][] ndata = new float[data.length][2];
       
       for(int j = 0; j < data.length; j++) {
         if(axis.equals("Y")) {
           ndata[j][0] = data[j][0];
           
           if(data[j][1] > 1.0f) { // avoid negative numbers
             ndata[j][1] = (float)Math.exp(data[j][1]);
           }
           else {
             ndata[j][1] = 0.0f;
           }
         }
         else {
           if(data[j][0] > 1.0f) { // avoid negative numbers
             ndata[j][0] = (float)Math.exp(data[j][0]);
           }
           else {
             ndata[j][0] = 0.0f;
           }
           
           ndata[j][1] = data[j][1];
         }
       }
       
       String name = null;
       String type = sdata[i].getType();
       int direction = sdata[i].getProfileDirection();
       
       if(type.equals("pump-probe")) {
         name = sdata[i].getName() + "-"  + header[3] + "-AMTF";
         if(direction == 1) {
           type = "pump-probeTP";
         }
       }
       else {
         name = sdata[i].getName() + "-expTF";
       }
       
       SpectraData sd = new SpectraData(name, type, header, dmeta,
                                                                   ndata, rdata);
       
       sd.setProfileDirection(direction);
       
       sdataVector.addElement(sd);
     }
     
     if(sdataVector.size() > 0) {
      SpectraData[] sda = SpectraDataUtil.getSpectraDataArray(sdataVector);
      transformDialog.setResults(sda);
    }
    transformDialog.setStatus(0, "No Message");
  }
} //--end class ArithemeticTransformThread
