/*-
 * #%L
 * Fluorescence lifetime analysis in SciJava Ops.
 * %%
 * Copyright (C) 2024 SciJava developers.
 * %%
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * #L%
 */

package org.scijava.ops.flim;

import net.imglib2.img.Img;
import net.imglib2.type.numeric.integer.IntType;
import net.imglib2.type.numeric.real.FloatType;

/**
 * The collection of all results generated by a single fit of an image. Fields
 * named {@code xxMap} are image representations of the particular attribute.
 * Other fields are not intended to be used by external programs and should be
 * ignored when this object is processed with in the fitting ops.
 *
 * @author Dasong Gao
 */
public class FitResults {

	/** The return code for a good fit */
	public static final int RET_OK = 0;

	/** The return code for a fit that failed by flimlib */
	public static final int RET_BAD_FIT_DIVERGED = -1;

	/** The return code for a fit that succeeded but has chisq &gt; 1e5 */
	public static final int RET_BAD_FIT_CHISQ_OUT_OF_RANGE = -2;

	/** The return code for a fit that failed because of improper arguments */
	public static final int RET_BAD_SETTING = -3;

	/**
	 * The return code for a fit that was not performed because the intensity is
	 * below threshold
	 */
	public static final int RET_INTENSITY_BELOW_THRESH = -4;

	/**
	 * The return code for a fit that failed because of error in native code (e.g.
	 * malloc)
	 */
	public static final int RET_INTERNAL_ERROR = -5;

	/** The return code for unknown fit status */
	public static final int RET_UNKNOWN = -6;

	/** The index of lifetime and parameter axis */
	public int ltAxis;

	/** The return code of the fit */
	public int retCode;

	/** The image representation of return codes of the fit over the dataset */
	public Img<IntType> retCodeMap;

	/**
	 * The image representation of the intensity distribution obtained by summing
	 * up photon counts.
	 */
	public Img<FloatType> intensityMap;

	/** The fitted parameters of the fit */
	public float[] param;

	/**
	 * The image representation of fitted parameters of the fit over the the
	 * dataset
	 */
	public Img<FloatType> paramMap;

	/** The fitted transients of the fit */
	public float[] fitted;

	/**
	 * The image representation of fitted transients of the fit over the the
	 * dataset
	 */
	public Img<FloatType> fittedMap;

	/** The residuals (y - y_fitted) of the fit */
	public float[] residuals;

	/** The image representation of residuals of the fit over the the dataset */
	public Img<FloatType> residualsMap;

	/**
	 * The reduced chi-squared of the fit. For global analysis, this is the global
	 * chi-squared value.
	 */
	public float chisq;

	/**
	 * The image representation of reduced chi-squared of the fit over the the
	 * dataset
	 */
	public Img<FloatType> chisqMap;

	/**
	 * Create a new instance of {@link FitResults} with shallow copy (maps are not
	 * duplicated).
	 *
	 * @return A clone of the current instance.
	 */
	public FitResults copy() {
        var newResults = new FitResults();
		newResults.ltAxis = ltAxis;
		newResults.retCode = retCode;
		newResults.retCodeMap = retCodeMap;
		newResults.intensityMap = intensityMap;
		newResults.param = param;
		newResults.paramMap = paramMap;
		newResults.fitted = fitted;
		newResults.fittedMap = fittedMap;
		newResults.residuals = residuals;
		newResults.residualsMap = residualsMap;
		newResults.chisq = chisq;
		newResults.chisqMap = chisqMap;
		return newResults;
	}
}
