//=====================================================================
// File:    PartialSigNorm.java
// Class:   PartialSigNorm
// Package: AFLPcore
//
// Author:  James J. Benham
// Date:    January 6, 1999
// Contact: james_benham@hmc.edu
//
// Genographer v1.0 - Computer assisted scoring of gels.
// Copyright (C) 1998  Montana State University
// 
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; version 2
// of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// The GNU General Public License is distributed in the file GPL
//=====================================================================

package AFLPcore;

/**
 * This class normalizes a gel. The total signal in a lane is defined
 * as the sum of all of the points in a trace. Since the trace is
 * simply a set of discrete points that form a curve, the total signal
 * may also be thought of as the area under the trace curve, or as
 * the integral over the entire size range. The lanes are normalized
 * so that the total signal's are equal to the average signal in the
 * gel.
 *
 * This class extends a gel operation. The signal in each lane is
 * handled by the <code>Lane</code> class. There are no options to set.
 *
 * @author James J. Benham
 * @version 1.0.0
 * @date January 6, 1999
 */

public class PartialSigNorm extends GelOperation
{
  public static double DEFAULT_PERCENT = 0.1;

  /**
   * Creates a new PartialSigNorm object.
   */
  public PartialSigNorm()
  {
    name = "Normalize on Partial Signal";
    descript = "Normalizes the lanes based on the stronger part of the " +
	"signal intensity of the lane.";
    helpFile = "PartialSigNorm.html"; 
  }

  /**
   * This normalizes all of the lanes in the Gel based on the signal
   * stength of each lane.
   *
   * @param gel  the gel to normalize.
   */
  public void doGelOp(Gel gel)
    {
      double percentage;
      double sum;
      double minValue;
      Lane ln;
      double rawTrace[];

      // Read in the percentage from the file
      String percentStr = ProgOptions.retrieve("BASE_MIN");
      if(percentStr == null)
	{
	  percentage = DEFAULT_PERCENT;
	  System.err.println("BASE_MIN not set in config file." + 
			     "Using default.");
	}
      else
	{
	  try{
	    percentage = (new Double(percentStr)).doubleValue();
	  } catch (NumberFormatException e) {
	    percentage = DEFAULT_PERCENT;
	    System.err.println("Bad value for BASE_MIN in " +
			       "configuration file. Using " +
			       "default." + e.getMessage());
	  }
	}

      DataList lanes = gel.getLanes();
      double sigSums[] = new double[lanes.size()];

      for(int i=0; i < sigSums.length; i++)
	{
	  ln = (Lane) lanes.dataAt(i);
	  minValue = percentage*ln.getMaxHeight(ln.getMinSize(), 
						ln.getMaxSize());
	  sum = 0;
	  ln.useTrace(Lane.ORIGINAL);
	  rawTrace = ln.getTrace();

	  for(int j=0; j < rawTrace.length; j++)
	    if(rawTrace[j] > minValue)
	      sum += rawTrace[j];

	  sigSums[i] = sum;
	}
 
      double normValue;

      // use the average signal strength as the value to normalize to
      sum = 0;
      for(int i=0; i < sigSums.length; i++)
	sum += sigSums[i];
      
      normValue = sum / lanes.size();

      double convertFactor;
      double normTrace[];

      for(int i=0; i < lanes.size(); i++)
	{
	  ln = (Lane) lanes.dataAt(i);
	  // make sure we have the raw trace
	  // We already selected it above
	  rawTrace = ln.getTrace();

	  // create the normalized trace
	  normTrace = new double[rawTrace.length];
	  convertFactor = normValue/sigSums[i];
	  for(int j=0; j < rawTrace.length; j++)
	      normTrace[j] = rawTrace[j] * convertFactor;

	  // set the normalized trace and us it
	  ln.setNormTrace(normTrace);
	  ln.useTrace(Lane.NORMALIZED);
	}
    }

  /**
   * No options for this operation, so <code>null</code> is returned.
   *
   * @return <code>null</code>
   */
  public Option[] getOptions()
  {
    return null;
  }

  /**
   * Since there are no options for this operation, this method will
   * do absolutely nothing.
   */
  public void setOptions(Option[] opts)
  {
    // nothing to set.
  }

  /**
   * Gives the name of this gel operation
   *
   * @return the name
   */
  public String getName()
  {
    return name;
  }

  /**
   * Gives a one sentence description of this gel operation.
   *
   * @return the description
   */
  public String getDescription()
  {
    return descript;
  }

  /**
   * Gives a file that is the help file for this gel operation
   *
   * @return a plaintext of html file containing help information
   */
  public String getHelpFile()
  {
    return helpFile;
  }
}
