
/** 
 * PumpProbeTransformThread.java
 * normalizes raw pump-probe data
 * 
 *
 * Created:  July 17, 2005
 *
 * @author Nathan Stevens
 * @version 0.1 7/16/05
 */
import java.util.Vector;

public class PumpProbeTransformThread extends Thread {
  private TransformViewer transformViewer = null;
  private SpectraData[] sda = null; // pump-probe data
  private SpectraData[] rsda = null; // the reference data
  private Vector sdataVector = new Vector();
  private float minWL = 0.0f;
  private float maxWL = 0.0f;
  private int code = 0;  // used to indicate any errors
  
  // The main constructor
  public PumpProbeTransformThread(TransformViewer transformViewer, SpectraData[] sda, 
  SpectraData[] rsda, float minWL, float maxWL) {
    this.transformViewer = transformViewer;
    this.sda = sda;
    this.rsda = rsda;
    this.minWL = minWL;
    this.maxWL = maxWL;
  }
  
  // The run method
  public void run() {
    normalizePumpProbe();
  }
  
  // Method to generate normlized pump-probe spectra from raw intensity data
  private void normalizePumpProbe() {
    int ntf = 1;
    
    float[][] pdata = rsda[0].getData(); // probe signal, no pump pulse
    float[][] rdata = rsda[0].getReferenceData(); // reference signal, no pump pulse
    float[][] fmdata = null; // used to correct for fluorescence of the sample in the probe channel
    float[][] fs1data = null; // used to correct for fluorescence of the sample in the reference channel
    
    // get the size of the normalized data
    int ndata_size = getNormalizeDataSize(pdata);
    
    if(rsda.length == 2) {
      ntf = 2;
      fmdata = rsda[2].getData();
      fs1data = rsda[2].getReferenceData();
    }
    
    // the index for keeping track of the count in the ndata array
    int index = 0;
    
    for(int i = 0; i < sda.length; i++) {
      String[] header = (String[])sda[i].getHeader().clone();
      String[] dmeta = (String[])sda[i].getMetaInfo().clone();
      
      float[][] mdata = sda[i].getData();
      float[][] s1data = sda[i].getReferenceData();
      float[][] ndata = new float[ndata_size][2];
      
      float od = 0.0f;
      float logod = 0.0f;
      
      for(int j = 0; j < mdata.length; j++) {
        // check to see if to add this to the ndata array
        if(mdata[j][0] < minWL || mdata[j][0] > maxWL) {
          continue;
        }
        
        ndata[index][0] = mdata[j][0];
        
        if(ntf == 1) {
          od = (pdata[j][1]/mdata[j][1])*(s1data[j][1]/rdata[j][1]);
        }
        else if (ntf == 2) {
          od = ((s1data[j][1] - fs1data[j][1])/(mdata[j][1] - fmdata[j][1]))*(rdata[j][1]/pdata[j][1]);
        }
        
        String ods = "" + od;
        if(od <= 0.0f || ods.equals("NaN") || ods.equals("Infinity")) {
          System.err.println("OD is Negative or Zero");
          ndata[index][1] = 0.0f;
        }
        else {
          ndata[index][1] = log10(od);
        }
        
        index++;
      }
      
      // reset index to 0
      index = 0;
      
      header[0] = "" + ndata[0][0];
      header[1] = "" + ndata[ndata.length - 1][0];
      
      String name = sda[i].getName() + "NTF";
      
      SpectraData sd = new SpectraData(name, sda[i].getType(), header, dmeta, 
      ndata, null);
      
      sd.setDelay(sda[i].getDelay());
      
      String xlabel = name + "-" + sda[i].getDelay() + "-wl";
      String ylabel = name + "-" + sda[i].getDelay() + "-int";
      sd.setColumnLabels(xlabel, ylabel);
      
      sdataVector.addElement(sd);
    }
    
    if(sdataVector.size() > 0) {
       SpectraData[] new_sda = SpectraDataUtil.getSpectraDataArray(sdataVector);
       transformViewer.setResults(new_sda);
     }
  }
  
  // Method to get size of the normalize data array
  private int getNormalizeDataSize(float[][] data) {
    int size = 0;
    
    for(int i = 0; i < data.length; i++) {
      float wl = data[i][0];
      if(wl >= minWL && wl <= maxWL) {
        size++;
      }
    }
    
    return size;
  }
  
  // Method to return the base ten log
  private float log10(float value) {
    return (float)(Math.log(value) / Math.log(10.0f));
  }
}// --end class PumpProbeTransformThread
