/*------------------------------------------------------------------------------*
 * File Name:				 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file												*
 * Copyright (c) OriginLab Corp.2002											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Echo 3/21/05 ERROR_PARAM_SIZE												*
 *	Echo 3/21/05 PARAM_WRONGLY_FREE												*
 *  Iris 3/30/05 REMOVE_FIX_SLOPE_FROM_MR										*
 *  Iris 4/21/05 MAKEFITY_SUPPORT_MULTI_REGRESSION								*
 *  Iris 5/18/05 QA70-7735 REMOVE_PASTE_FORMULA_TO_GRAPH_FROM_MR				*
 *  Iris 7/04/05 CLEANUP_MR_GRAPHS_CODES 										*
 * CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
 *  Thomas 5/24/2006 ADD_CONF_AND_PRED_BANDS_FOR_MLR							*
 *	Thomas 05/30/2006 CALL_SETREPORTWORKSHEETDESIGNATION_INSTEAD				*
 *	Max 8/4/2006 RENAME_FITMR_TO_MR												*
 *	Cheney 2006-8-31 DEL_PLOT_TYPE_NODE											*
 *  Joseph 09/15/06  HIDE_THE_CALIBRATION_TABLE									*
 *  Joseph 09/18/06 MOVE_CALIBRATION_TABLE_OUT_OUTPUT							*
 *	ML 9/20/2006 RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT					*
 *	Jasmine 09/20/06 QA70-8973 MODIFICATION_OUTPUT_BRANCH						*
 *	CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER				*
 *	Cheney 2006-11-1 CHANGE_sReg_FROM_REF_TO_POINTER							*
 *	Echo 2/15/07 ADD_ERROR_REPORT												*
 *	Cheney 2007-5-17 LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL					*	
 *	Cheney 2007-6-7 SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC							* 
 *	Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT		*
 *	Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES			*
 *  Iris 08/08/2007 v8.0677 WILL_NOT_PLOT_SOURCE_DATA_IN_MR_ANYMORE				*
 *	Cheney 2007-8-31 QA70-10330 CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
 *	Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR	*
 *	Fisher 11/14/07 ADD_MAP_ID_TO_CHM											*
 *	YuI 03/05/09 QA70-13220 WHOLE_WORKSHEET_INPUT_XYRANGE						*
 *  Iris 3/18/2009 QA80-13304 FIX_MR_RESIDUAL_PLOTS_ALL_PLOTTED_ON_FIRST_X_WITH_RESIDUAL
 *  Iris 3/30/2009 SHOW_MR_EQUATION_IN_NOTES									*
 *  Iris 3/30/2009 CHANGE_INPUT_DATA_TABLE_XY_LABELS							*
 *	Hong 06/01/09 FIX_MR_FAIL_CHECK_ERROR_IF_INDEP_NOT_SPECIFIED				*
 * 	Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL					*
 *	Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
 *------------------------------------------------------------------------------*/
 
#include <origin.h>
#include <event_utils.h>
#include <report_utils.h>
#include "FitCommon.h"
#include <o8dlg.h>

#ifdef _FOR_SMART_LOADING_ONLY
#include "wksOperation.h" //---- CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER
#include "analysis_utils.h"
#include <stats_utils.h>
#include "stats_guis.h"
#include "stats_operations.h"   
#include "nlsf_utils.h" /// Iris 7/08/2008 CLEAN_DUP_CALC_AVE_DATA_CODE_IN_NLSF_PREVIEW_AND_OP
#include "graph_utils.h" //---- Iris 11/19/2008 v8.0975 QA80-12591-P2 FIX_APPARENT_FIT_ON_GRAPH_CUSTOM_RANGE_GET_INCORRECT_X
#endif

#include <xfutils.h>  ///Echo 2/15/07 ADD_ERROR_REPORT

////////////////////////////////////////////////////////////////////////////////////
#define		MR_INDEPS_NODE_NAME_PREFIX				"InputsX"
#define		STR_PARTIAL_REGRESSION_GRAPH_TABLE		_L("Partial Leverage Plots")//"Curves for Partial Regression"
////////////////////////////////////////////////////////////////////////////////////
#define		STR_PARAM_A0_NAME						_LE("Intercept")

#define 	GRAPH_MR_PARTIAL_REGRESSION 	GRAPH_FITTING_MAX_NODES_IN_REPORT
//#define 	OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET  OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET+1
#define		OUTPUT_PARTIAL_CURVE_SHEET_RNG_INDEX  	OUTPUT_SRC_WKS_INSERTED_COLS_RNG_INDEX_2+1

#define PARTIAL_REGRESSION_CURVES_BRANCH(_TROP)	_TROP.PartialCurves
// start your functions here
//class OC_REGISTERED FitMR : public FitRegression /// Max 8/4/2006 RENAME_FITMR_TO_MR

///Echo 2/15/07 ADD_ERROR_REPORT
static bool _check_conf_level(TreeNode trConfLev)
{
	if (trConfLev.Enable)
		return check_conf_level(trConfLev);
	
	return true;		
}

static int _check_mr_data(DataRange& drData)
{
#ifndef			IMPROVE_MR_INPUT_RANGE_ERROR_CHECKING /// Hong 06/01/09 FIX_MR_FAIL_CHECK_ERROR_IF_INDEP_NOT_SPECIFIED
	DWORD	dwRules = DRR_BAD_WEGHT_EXCLUDE  | DRR_GET_DEPENDENT | DRR_NO_FACTORS;		
	
	int nRanges = drData.GetNumData();
	if (nRanges < 1)
	{
		return CER_INVALID_MR_DATA;		
	}
	int nSize = 0;
	for (int ii = 0; ii < nRanges; ii++)
	{
		vector vX, vY, vW;
		drData.GetData(dwRules, ii, NULL, NULL, &vY, &vX, NULL, NULL, &vW);
		
		nSize += vX.GetSize();
		
	}
	if (nSize <= 0 )
	{
		return CER_INVALID_MR_DATA;
	}
	
	return CER_NO_ERROR;
	
	/// Hong 06/01/09 FIX_MR_FAIL_CHECK_ERROR_IF_INDEP_NOT_SPECIFIED
#else			//IMPROVE_MR_INPUT_RANGE_ERROR_CHECKING
	int 		nRanges = drData.GetNumData();
	if ( nRanges < 1 )
		return CER_INVALID_MR_DATA;		

	DWORD		dwRules = DRR_BAD_WEGHT_EXCLUDE  | DRR_GET_DEPENDENT | DRR_NO_FACTORS | DRR_ONE_DEP_MULTIINDEP;	
	bool		bEmptyRange = true;
	for ( int ii = 0; ii < nRanges; ii++ )
	{
		vector 			vX, vY, vW;
		matrix			mXs;
		drData.GetData(dwRules, ii, NULL, NULL, &vY, &vX, &mXs, NULL, &vW);
		if ( mXs.GetNumCols() > 0 && mXs.GetNumRows() > 0 )
		{
			bEmptyRange = false;
			break;
		}
	}
	
	return bEmptyRange ? CER_INVALID_MR_DATA : CER_NO_ERROR;
#endif			//IMPROVE_MR_INPUT_RANGE_ERROR_CHECKING
	/// end FIX_MR_FAIL_CHECK_ERROR_IF_INDEP_NOT_SPECIFIED
}

static int mr_event1(TreeNode& tr, int nRow, int nEvent, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& getNCountainer, string& strAux, string& strErrMsg)
{
	DECLARE_BUTTON_ENABLES   //support more buttons enable/disable
		
	///Cheney 2007-6-7 SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC
	///Cheney 2007-7-6 SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	//if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent)
	if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent || GETNE_ON_THEME == nEvent)
	///end SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	///end SHOULD_CHECK_EVENT_ID_IN_EVENT_FUNC
	{
		DataRange drData;
		TreeNode trRange = tr.InputData;
		drData.Create();
		drData.SetTree(tr.InputData, DRTREE_DEFAULT);
		int nErr = _check_mr_data(drData);
	
		if (nErr == CER_NO_ERROR)
		{
			TreeNode trParamConf = tr.Quantities.Parameters.Confidence;
			if (!_check_conf_level(trParamConf))
			{
				nErr = CER_INVALID_CONF_LEV;
			}
		}
		///Sophy 4/11/2008 CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT
		string strRet = "";
		if( CER_NO_ERROR == nErr )
		{
			nErr = check_report_book_curve_book( tr ,strRet);
		}
		///end CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT
		if (nErr != CER_NO_ERROR)
		{
			bOKEnable = false;
			strErrMsg = nErr;
			 ///Sophy 4/14/2008 ADD_OUTPUT_ERR_STRING
			if( !strRet.IsEmpty() )
			{
				strErrMsg += ":" + strRet; 
			}
			///end ADD_OUTPUT_ERR_STRING
		}
		///Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
		if(nErr == CER_NO_ERROR)
			check_get_weight_data_err_msg(tr, strErrMsg);
		///end CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
	}
	return true;

}
///end ADD_ERROR_REPORT

string _get_picture_tag_name(int nPictureIndex, bool bIsRow = true);
/*
{
	string strPrefix = CALCULATION_GRAPH_NODE_PREIX;
	string str;
	
	///Iris 9/21/06 MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
	//str.Format("%s%d", strPrefix, nPictureIndex + 1);
	str.Format("%s%s%d", strPrefix, bIsRow?"" : "_Col", nPictureIndex + 1);
	///End MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
	return str;
}
*/
class OC_REGISTERED MR : public FitRegression
{
protected:
	//virtual 
	string GetAnalysisName(int nOption)
	{
		return _L("Multiple Regression");
	}
	//----- CPY 9/30/07 FIX_CHENEY_MODIFY_TITLE_AS_MAX_SAID
	//virtual 
	string GetDlgDescription(int nOption)
	{
		return _L("Perform Multiple Linear Regression");
	}
	//-----
	// Virtual 
	//string GetClassName() {return "FitMR";} /// Max 8/4/2006 RENAME_FITMR_TO_MR
	string GetClassName() {return "MR";}
	///Sophy 5/28/2008 QA80-10934-P8 FIX_GIVE_DEFAULT_BOOK_SHEET_NAME_TO_PARTIAL_LEVERAGE_VALUES_NODE
	//virtual
	bool	InitOutputGUIManagerPointer(const TreeNode& trGUI)
	{
		if(m_pOutputManager)//already init
			return true;
		
		m_pOutputManager = new MROutputGUIManager;	
		return (NULL != m_pOutputManager);		
	}
	
	/// YuI 03/05/09 QA70-13220 WHOLE_WORKSHEET_INPUT_XYRANGE
	virtual BOOL	IsEntireWorksheetInputSupported()
	{
		return FALSE;
	}
	/// end WHOLE_WORKSHEET_INPUT_XYRANGE
	
	//virtual
	void	SetOutputBookSheetDefaultName( TreeNode& trGUI)
	{
		FitterOperation::SetOutputBookSheetDefaultName( trGUI );
		
		TreeNode	trOperation = trGUI.Parent();
		
		SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.PartialCurves, true, GetResultCurveBookShortName(trOperation, 0, OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET));
		SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.PartialCurves, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET));

	}
	///end FIX_GIVE_DEFAULT_BOOK_SHEET_NAME_TO_PARTIAL_LEVERAGE_VALUES_NODE
	
	//virtual 
	string 	GetResultBookName(TreeNode& trGUI) { return E_STR_MR_REPORT_TABLE_BOOK_SHORT_NAME; } /// Iris 3/21/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME
	
	///Iris 3/23/05 HIDDEN_CORRELATION_IN_PR_MR
	// Virtual
	void FilterStatsReport(TreeNode& trOp)
	{
		FitterOperation::FilterStatsReport(trOp);
		
		vector<int> vnNodesToHide = {IDE_FIT_CORRELATION};
		tree_set_attributes(trOp.Calculation, vnNodesToHide, "0");
		
		///Arvin 01/19/06 REMOVE_EQUATION_NODE
		/// Iris 3/30/2009 SHOW_MR_EQUATION_IN_NOTES according to Laurie's mail
		//TreeNode trEquation = trOp.Calculation.Notes.Equation;
		//trEquation.Remove();
		///end SHOW_MR_EQUATION_IN_NOTES
		///end REMOVE_EQUATION_NODE
	}
	///end HIDDEN_CORRELATION_IN_PR_MR
	
	// virtual 
	// fisher 11/14/2007 ADD_MAP_ID_TO_CHM
	int GetHelpID()
	{
		return IDD_FIT_MR;
	}
	
	/// Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL
	/*
	/// Iris 4/17/2008 SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
	//virtual	
	string	GetReportTableGUIName(TreeNode& trGUI)
	{
		return STR_OUTPUT_MR_FIT_REPORT_TABLE;
	}
	///end SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
	*/ 
	///end CHANGE_GUI_REPORT_TABLE_LABEL

	/// Iris 6/04/05 ADD_FILTER_FITTING_GUI
	//virtual
	void    FilterFittingGUI(TreeNode& trOp)
	{
		FitRegression::FilterFittingGUI(trOp);
		
		///Cheney 2006-8-31 DEL_PLOT_TYPE_NODE
		TreeNode trPlotType = trOp.GUI.FindNodeByAttribute(STR_DATAID_ATTRIB, IDE_FIT_PLOT_TYPE);
		if(trPlotType)
			trPlotType.Remove();
		///end DEL_PLOT_TYPE_NODE
		//to hide some options
		vector<int> vnNodesToHide = {IDE_POLY_ORDER, IDE_FIT_CORRELATION, IDE_LR_FIX_SLOPE, 
		IDE_PARAM_FIX,	///Iris 10/13/05 REMOVE_FIX_FOR_LR_PR_MR Leo said "there is no place to "Fix" the parameter in LR, PR, MR, so should remove this"
		IDE_LR_FIX_SLOPE_AT, 
		//IDE_PASTE_FORMULA_TO_GRAPH, ///Iris 8/17/05
		IDE_FIT_USE_DATA_X, IDE_FIT_X_POINTS,
		IDE_FIT_X_MIN, IDE_FIT_X_MAX, IDE_FIT_RANGE_FULL_X, IDE_FIT_RANGE_MARGIN,
		IDE_FIT_DATA_TYPE_BRANCH,
		//----- Iris 8/11/06 remove Find X from Y and Find Y from X branch for MR.
		IDST_REPORT_CALIBRATION_TABLE,   ///Joseph 09/15/06  HIDE_THE_CALIBRATION_TABLE
		IDST_REPORT_CUSTOM_TABLE2_BEGIN,
		IDST_REPORT_CUSTOM_TABLE3_BEGIN,
		//-----	
		
		IDE_FIT_APPARENT_SCALE,		///Arvin 01/19/06 HIDE_APPARENT_FIT_NODE
		IDE_PARAM_DEPENDENCY, ///Arvin 05/22/07 REMOVE_DEPENDENCY_FOR_LR_PR_MR as larry's suggestion
		IDST_SEPARATE_RESULT_CURVE_SHEET,	/// Iris 01/19/2007 v8.0544 OPTION_ON_OUT_RESULT_CURVE_SHEET_SEPARATELY_OR_NOT
		
		/// Iris 01/23/2007 v8.0546 TO_CONTRL_NOT_OR_HOW_PLOT_FIT_CURVE
		IDE_FIT_PLOT_FIT_CURVE,	
		#ifdef	MARKER_VISIBILITY_OPTIONS
		IDE_FIT_SHOW_MARKER, 		///Jasmine 05/30/08 QA80-11630 ADD_OPTION_FOR_SHOW_MARKER_IN_SRC_PLOT_AFTER_FIT
		#endif //	MARKER_VISIBILITY_OPTIONS
		IDE_FIT_UPDATE_LEGEND
		///end TO_CONTRL_NOT_OR_HOW_PLOT_FIT_CURVE
		};
		
		///Iris 7/04/05 CLEANUP_MR_GRAPHS_CODES, no Residual vs. Independents Graph in MR
		//int nIndepResidualGraph = IDST_RESULT_GRAPHS + GRAPH_RESIDUALS_SCATTER;  ///Iris 8/17/05 MAKE_LASTUSE_WORK_FOR_ID_LARGER_THAN_BRANCH_MASK
		//int nIndepResidualGraph = IDE_RESULT_GRAPHS + GRAPH_RESIDUALS_SCATTER;
		//vnNodesToHide.Add(nIndepResidualGraph);
		///end CLEANUP_MR_GRAPHS_CODES		
		tree_set_attributes(trOp.GUI, vnNodesToHide, "0");
		
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE /// Iris 11/02/2009 QA81-14546 OP_DLG_NEW_STRUCTURE, XDataType has be hidden in MR
		///Arvin 11/29/06 SET_XDATA_TYPE_AS_INPUT_DATA
		TreeNode trGraph = GetGUIGraphNodes(trOp, GRAPH_FIT_CURVE);
		if(trGraph)
		{
			trGraph.XDataType.Use = FIT_CURVE_SAME_AS_DATA;
			//trGraph.CurveColor.Remove();/// Iris 07/30/2007 QA70-10073 TO_KEEP_CUSTOMIC_SETTINGS_IN_REPORT_GRAPH
		}
		///end SET_XDATA_TYPE_AS_INPUT_DATA	
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE /// Iris 11/02/2009 QA81-14546 OP_DLG_NEW_STRUCTURE

		///Arvin 05/22/07 HIDE_PLOT_SETTING_BRANCH_FOR_MR by larry's suggestion
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode trPlotSettings = trOp.GUI.Output.PlotSettings;
		TreeNode trPlotSettings = OP_GUI_GRAPH_ARRANGEMENT_NODE(trOp.GUI);
		///end OP_DLG_NEW_STRUCTURE
		if(trPlotSettings)
			trPlotSettings.Show = false;
		///end HIDE_PLOT_SETTING_BRANCH_FOR_MR
		//to reset hidden options
		tree_GETN_reset_hidden_values(trOp.GUI, vnNodesToHide);		
	}
	///----	
	///Arvin 04/29/07 v8.0610 ADD_EQUATION_NOTES_FOR_MR
	bool GetDisplayFormula(TreeNode& trOp, string& strFormula)
	{
		int nNumParams = GetParameters(trOp);
		if(nNumParams < 1)
			return false;
		
		strFormula += "y = A0";
		for(int ii = 1; ii < nNumParams; ii++)
		{
			strFormula = strFormula + "+A" + ftoa(ii) + "*x" + ftoa(ii);
		}
		return true;
	}
	///END ADD_EQUATION_NOTES_FOR_MR	
	
	///Cheney 2007-8-23 QA70-10290 FITCURVE_AND_REPORT_SHOULD_BE_SAME_BOOK_IF_SRC_DATA_FROM_DIFF_BOOK
	//virtual 
	string GetSourcePageName(TreeNode& trOp, Datasheet& ds = NULL)
	{		
		string strBook;
		DataRange drData;
		TreeNode trRange = trOp.InputData;
		drData.Create();
		drData.SetTree(trRange, DRTREE_DEFAULT);
		if(!drData.IsValid() || drData.GetNumRanges() == 0)
			return strBook;
		
		///Cheney 2007-10-15 QA70-10522-P4 CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING 
		//Worksheet wks;
		//drData.GetParent(wks);
		//if(!wks)
			//return strBook;
		//strBook = WksReportOperation::GetSourcePageName(trOp, wks);
		//return strBook;
		//return get_source_page_name(drData);
		return get_range_source_page_name(drData);
		///end CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING
	}
	///end FITCURVE_AND_REPORT_SHOULD_BE_SAME_BOOK_IF_SRC_DATA_FROM_DIFF_BOOK
	///end CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING	

	TreeNode GetOneResultCurvesTable(const TreeNode& trOp, int nDataIndex, int nTotalNumData, int nGraphIndex)
	{
		int nIndex = nDataIndex;
		if(nGraphIndex == GRAPH_RESIDUALS_SCATTER)
			nIndex = 0;
		
		TreeNode trRC = GetResultCurvesBranch(trOp, nIndex, nTotalNumData, GetOutputRangeIndex(trOp, nGraphIndex));
		if(!trRC)
			return trRC;
		
		TreeNode trTable;
		string strTable = GetOneResultCurvesTableTagName(nGraphIndex);
		if(nGraphIndex == GRAPH_RESIDUALS_SCATTER)
			strTable = strTable + ftoa(nDataIndex+1);
		
		if(strTable.IsEmpty())
		{
			error_report("getOneResultCurvesTable found invalid graph index");
			return trTable;
		}	
		trTable = trRC.GetNode(strTable);		
		return trTable;
	}
	
	//virtual
	uint	GetResultCurveTableID(TreeNode& trOp, int nDataIndex, int nTotalNumData = -1, int nGraphIndex = 0)
	{
	/// Iris 9/18/06 SUPPORT_RESIDUAL_BRANCH
		/*
		TreeNode trGraphTable;
		if(GRAPH_FIT_CURVE == nGraphIndex)
		{
			TreeNode	trFit;
			/// Iris 10/18/05 WORK_MORE_ON_PARTIAL_PLOTS
			////--- CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
			//// not sure if this is the correct info needed, may need to come back to this later
			////trFit = getPartialPlotsData(trOp, nDataIndex);
			//trFit = GetOneResultCurvesTable(trOp, nDataIndex, nTotalNumData, GRAPH_FIT_CURVE);
			////---
			trFit = GetOneResultCurvesTable(trOp, nDataIndex, m_nPartialPlots, GRAPH_FIT_CURVE);
			///End WORK_MORE_ON_PARTIAL_PLOTS
			if(trFit)
				return trFit.ID;				
		}
		
		if(GRAPH_RESIDUALS_SCATTER == nGraphIndex)  //because there is not residual scatter graph in MR
			return -1;
		return FitRegression::GetResultCurveTableID(trOp, nDataIndex, nTotalNumData, nGraphIndex);
		*/
		return FitRegression::GetResultCurveTableID(trOp, nDataIndex, m_nPartialPlots, nGraphIndex);
		///End SUPPORT_RESIDUAL_BRANCH
	}
	
	//
	int		GetResidualCurvesID()
	{ 
		return IDST_RESIDUAL_CURVE_OPTIONS; 
	}
	
	int		GetPartialCurvesID()
	{
		return IDST_PARTIAL_CURVE_OPTIONS;
	}
	
	/// Iris 05/08/2007 v8.0613 RANGE_BRANCH_DEFAULT_STATUS_SHOULD_BE_OPEN
	//virtual
	bool OnInputDataSelectionChange(TreeNode& trOperation)
	{
		// .Range1 is not existed when runned in Construct, so put the codes here
		FitterOperation::OnInputDataSelectionChange(trOperation);///Arvin 05/18/07 USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
		TreeNode 	trRange = trOperation.GUI.InputData.Range1;
		int			nTemp;
		if(trRange && !trRange.GetAttribute(STR_ATTRIB_BRANCH, nTemp))
		{
			trRange.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
			//return true; ///Arvin 05/21/07 INPUT_DATA_CHANGE_CAN_NOT_TRIGGER_EVENT_FUNCTION_IN_MR
		}
		///Arvin 05/21/07 INPUT_DATA_CHANGE_CAN_NOT_TRIGGER_EVENT_FUNCTION_IN_MR
		//return false;
		//For MR, we need set arttribute HandlerRC for sub nodes for MR, or else changing input data can not trigger off 
		//the corresponding event function
		if(trRange)
			GETN_SET_EVENT_EX_HANDLER_TO_ALL_NODES(trRange, on_input_data_change);
		
		return true;
		///end INPUT_DATA_CHANGE_CAN_NOT_TRIGGER_EVENT_FUNCTION_IN_MR		
	}
	///end RANGE_BRANCH_DEFAULT_STATUS_SHOULD_BE_OPEN
	
	///Joseph 4/10/07 ADD_ERROR_REPORT
	PEVENT_GETN	GetNewEventFunction()
	{
		return mr_event1;
	}
	///End ADD_ERROR_REPORT
	
	string GetGraphTemplate(int nGraphIndex = 0)
	{
		string str;
		if(GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex)
		{
			/// Iris 7/10/2008 v8.0899 QA80-11831 MR_PARTIAL_LEVERAGE_PLOTS_ONE_RESULT_CURVE_RANGE_NEED_TWO_DIFF_PLOTTYPE
			//str = "REPORTRESIDUAL";
			str = "ReportPartial";
			///end MR_PARTIAL_LEVERAGE_PLOTS_ONE_RESULT_CURVE_RANGE_NEED_TWO_DIFF_PLOTTYPE
		}
		else
			str = FitterOperation::GetGraphTemplate(nGraphIndex);
		return str;
	}
	
	int GetFindXYID(){ return 0;}///Jasmine 09/20/06 QA70-8973 MODIFICATION_OUTPUT_BRANCH, no FindXY output branch 
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//bool	AddResidualTables(bool bDataTbl, TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mXs, GraphLayer &grLayAppar = NULL, vector& vWeights = NULL, int nMultiplicity = 1)
	bool	AddResidualTables(bool bDataTbl, TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mXs, GraphLayer &grLayAppar = NULL, vector& vWeights = NULL, int nMultiplicity = 1, LPCSTR lpcsDataLabelCurves = NULL)
	///end CENTRALIZE_FITTING_RESULT_LABELS
	{	
		///Cheney 2007-5-17 LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL
		//if do MR from OC code, will run time error here if data set size is 0
		if(mXs.GetNumRows() == 0 || vY.GetSize() == 0)
			return false;
		///end LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL
		///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
		string 		strDataLabelCurve = strDataLabel;
		if(lpcsDataLabelCurves)
			strDataLabelCurve = lpcsDataLabelCurves;
		///end CENTRALIZE_FITTING_RESULT_LABELS
		
		string	strConvertedDataLabel(strDataLabel);
		ConvertEscapedString(strConvertedDataLabel);	
		
		//---Iris 3/18/2009 QA80-13304 FIX_MR_RESIDUAL_PLOTS_ALL_PLOTTED_ON_FIRST_X_WITH_RESIDUAL
		// old logic is not correct will cause not plot any one residual, still report residual data for plotting.
		//bool		bResDataTbl = bDataTbl;
		bool		bResDataTbl = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_SCATTER);
		//---end FIX_MR_RESIDUAL_PLOTS_ALL_PLOTTED_ON_FIRST_X_WITH_RESIDUAL
		bool		bResHist = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_HISTOGRAM);
		bool		bResFit = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_VERSUS_FITS_PLOT);
		bool		bResOrder = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_VERSUS_ORDER_PLOT);
		bool		bResLag = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_LAG_PLOT);
		
		///Arvin 12/12/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
		bool		bResRegular = GUIHasWhatTypeResidualTables(trOp, REGULAR_RESIDUAL);
		bool		bResStand = GUIHasWhatTypeResidualTables(trOp, STANDARDIZED_RESIDUAL);
		bool		bResStud = GUIHasWhatTypeResidualTables(trOp, STUDENTIZED_RESIDUAL);
		bool		bResStudDel = GUIHasWhatTypeResidualTables(trOp, STUDENTIZED_DELETED_RESIDUAL);
		///-------
	
		if (bResRegular || bResStand || bResStud || bResStudDel || bResDataTbl || bResHist || bResFit || bResOrder || bResLag)
		///------- 
		{
			vector vRe, vFitY;
			if(!FitterOperation::getResidualData(trOp, index, psFitParameter, vX, vY, vFitY, vRe, mXs, grLayAppar))
				return false;
			
			///Arvin 12/12/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
			vector vStand, vStud, vStudDel;
			int nResGraphType = GUIHasWhatTypeResidualGraph(trOp);
			if(bResStand || bResStud || bResStudDel || bResDataTbl || nResGraphType) 
			{
				if(!GetAllTypeResidualData(trOp, vX, vRe, vStand, vStud, vStudDel, index, 0, vY, vWeights, mXs))
					error_report("Can not get selected type residual data!");
			}			

			if(bResRegular || bResStand || bResStud || bResStudDel)
			{
				int nNumTable = 0;
				//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				//TreeNode trTable = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_RESIDUALS_SCATTER, STR_DIFF_RESIDUALS_DATA_TABLE, IDST_FIT_RESIDUAL_ANALYSIS, _L("Residuals"), strDataLabelCurve);
				TreeNode trTable = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_RESIDUALS_SCATTER, STR_DIFF_RESIDUALS_DATA_TABLE, IDST_FIT_RESIDUAL_ANALYSIS, GetResidualDataTableLabel(), strDataLabelCurve);
				//---CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				if(	bResRegular)
				{
					//AddDiffTypeResidualDataTable(trTable, vRe, REGULAR_RESIDUAL);
					AddDiffTypeResidualDataTable(trTable, strConvertedDataLabel, vRe, REGULAR_RESIDUAL);
					nNumTable++;
				}
				
				if(	bResStand)
				{
					//AddDiffTypeResidualDataTable(trTable, vStand, STANDARDIZED_RESIDUAL);
					AddDiffTypeResidualDataTable(trTable, strConvertedDataLabel, vStand, STANDARDIZED_RESIDUAL);
					nNumTable++;
				}
				if(	bResStud)
				{
					//AddDiffTypeResidualDataTable(trTable, vStud, STUDENTIZED_RESIDUAL);
					AddDiffTypeResidualDataTable(trTable, strConvertedDataLabel, vStud, STUDENTIZED_RESIDUAL);
					nNumTable++;
				}
				if(	bResStudDel)
				{
					//AddDiffTypeResidualDataTable(trTable, vStudDel, STUDENTIZED_DELETED_RESIDUAL);
					AddDiffTypeResidualDataTable(trTable, strConvertedDataLabel, vStudDel, STUDENTIZED_DELETED_RESIDUAL);
					nNumTable++;		
				}
			}
			
			switch(nResGraphType)
			{
			case STANDARDIZED_RESIDUAL:
				vRe = vStand;
				break;
			case STUDENTIZED_RESIDUAL:
				vRe = vStud;
				break;
			case STUDENTIZED_DELETED_RESIDUAL:
				vRe = vStudDel;
				break;
			}
			///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	   		
			vector 	vRowNum;
			
			if (bResHist || bResOrder)
				vRowNum.Data(1, vRe.GetSize(), 1);
			
			string strTableLabel = GetResidualDataTableLabel();
			string strResidualGraphTableLongName = GetResidualDataTableYDataLabel(nResGraphType, strConvertedDataLabel);
			string strTableSubLabel = GetResidualDataTableYDataSubLabel();
			
			if(bResDataTbl)
			{
				//vector		vxTransf(vX.GetSize());
				vector		*pvxUse;
				//if (grLayAppar && grLayAppar.ConvertByAxis(vX, vX.GetSize(), OKAXISTYPE_X, FALSE, vxTransf))
				//	pvxUse = &vxTransf;
				//else
				for(int ii = 0; ii < mXs.GetNumCols(); ii++)
				{
					mXs.GetColumn(vX, ii);
					pvxUse = &vX;
					/// Iris 08/08/2007 v8.0677 FIX_ALWAYS_PLOT_RESIDUAL_OF_1ST_X_IN_ALL_RESIDUAL_SCATTER_GRAPH
					// because in WksReportOperation::CheckCreateOneResultCurvesTable, Arvin used make_one_set_ID to update Table ID again, so here must set base id.
					//int	nTableID = make_one_set_ID(IDST_FIT_RESIDUALS_SCATTER, ii);
					int nTableID = IDST_FIT_RESIDUALS_SCATTER + ii;
					///end FIX_ALWAYS_PLOT_RESIDUAL_OF_1ST_X_IN_ALL_RESIDUAL_SCATTER_GRAPH
					
					///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
					//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, "ResidualData"+ftoa(ii+1), "Residuals",
					//	"Residuals vs. Independent Variable"+ftoa(ii+1), nTableID, GetOneSetResultCurvesID(), *pvxUse, "Independent Variable", vRe, "Residuals", GRAPH_RESIDUALS_SCATTER, false);
					//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
					//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, "ResidualData"+ftoa(ii+1),_L("Residuals"),
					//	_L("Residuals vs. Independent Variable")+ftoa(ii+1), nTableID, GetOneSetResultCurvesID(), *pvxUse, _L("Independent Variable"), vRe, _L("Residuals"), GRAPH_RESIDUALS_SCATTER, false);
					string strXColLongName = STR_REPORT_X_COL_LONG_NAME + " " +(ii+1);
					AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, "ResidualData"+ftoa(ii+1), strTableLabel,
						strTableSubLabel, nTableID, GetOneSetResultCurvesID(), *pvxUse, strXColLongName, vRe, strResidualGraphTableLongName, GRAPH_RESIDUALS_SCATTER, false);
					///end CENTRALIZE_FITTING_RESULT_LABELS
				}				
			}
			
			if (bResHist)
				///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_HISTOGRAM_TABLE, "Residuals",
				//		"Histogram of the Residuals", IDST_FIT_RESIDUALS_DATA, IDST_REPORT_RESIDUAL_HISTOGRAM_ONE_SET, NULL, NULL, vRe, "Residual", GRAPH_RESIDUALS_HISTOGRAM, false);
				//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_HISTOGRAM_TABLE, _L("Residuals"),
				//		_L("Histogram of the Residuals"), IDST_FIT_RESIDUALS_DATA, IDST_REPORT_RESIDUAL_HISTOGRAM_ONE_SET, NULL, NULL, vRe, _L("Residual"), GRAPH_RESIDUALS_HISTOGRAM, false);
				AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_HISTOGRAM_TABLE, strTableLabel,
						strTableSubLabel, IDST_FIT_RESIDUALS_DATA, IDST_REPORT_RESIDUAL_HISTOGRAM_ONE_SET, NULL, NULL, vRe, strResidualGraphTableLongName, GRAPH_RESIDUALS_HISTOGRAM, false);
				//---CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				///end CENTRALIZE_FITTING_RESULT_LABELS
			if (bResFit)
				///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_FIT_GRAPH_TABLE, "Residuals", "Residuals vs. Predicted Values",IDST_FIT_RESIDUALS_VERSUS_FITS_DATA,
				//	IDST_REPORT_RESIDUAL_FIT_ONE_SET, vFitY, "Fitted Y", vRe, "Residual", GRAPH_RESIDUALS_VERSUS_FITS_PLOT, false);
				//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_FIT_GRAPH_TABLE, _L("Residuals"), _L("Residuals vs. Predicted Values"),IDST_FIT_RESIDUALS_VERSUS_FITS_DATA,
				//	IDST_REPORT_RESIDUAL_FIT_ONE_SET, vFitY, _L("Fitted Y"), vRe, _L("Residual"), GRAPH_RESIDUALS_VERSUS_FITS_PLOT, false);
				AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_FIT_GRAPH_TABLE, strTableLabel,
						strTableSubLabel,IDST_FIT_RESIDUALS_VERSUS_FITS_DATA, IDST_REPORT_RESIDUAL_FIT_ONE_SET, vFitY, _L("Fitted Y"), vRe, strResidualGraphTableLongName, GRAPH_RESIDUALS_VERSUS_FITS_PLOT, false);
				//---CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS				
				///end CENTRALIZE_FITTING_RESULT_LABELS
			if (bResOrder)	// the same values as bResHist 
				///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_ORDER_GRAPH_TABLE, "Residuals", "Residuals vs. the Order of the Data",IDST_FIT_RESIDUALS_VERSUS_ORDER_DATA,
				//	IDST_REPORT_RESIDUAL_ORDER_ONE_SET, vRowNum, "Order", vRe, "Residual", GRAPH_RESIDUALS_VERSUS_ORDER_PLOT, false);
				//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_ORDER_GRAPH_TABLE, _L("Residuals"), _L("Residuals vs. the Order of the Data"),IDST_FIT_RESIDUALS_VERSUS_ORDER_DATA,
					//IDST_REPORT_RESIDUAL_ORDER_ONE_SET, vRowNum, _L("Order"), vRe, _L("Residual"), GRAPH_RESIDUALS_VERSUS_ORDER_PLOT, false);
				AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_ORDER_GRAPH_TABLE, strTableLabel, 
						strTableSubLabel,IDST_FIT_RESIDUALS_VERSUS_ORDER_DATA,	IDST_REPORT_RESIDUAL_ORDER_ONE_SET, vRowNum, _L("Order"), vRe, strResidualGraphTableLongName, GRAPH_RESIDUALS_VERSUS_ORDER_PLOT, false);
				//---CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				///end 	CENTRALIZE_FITTING_RESULT_LABELS
			if (bResLag)
			{
				vector 	vReX;
				vReX = vRe;
				vReX.RemoveAt(vReX.GetSize()-1);
				vRe.RemoveAt(0);
				///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_LAG_GRAPH_TABLE, "Residuals", "Residuals Lag Plot", IDST_FIT_RESIDUALS_LAG_DATA,
				//	IDST_REPORT_RESIDUAL_LAG_ONE_SET, vReX, "Residual(I-1)", vRe, "Residual", GRAPH_RESIDUALS_LAG_PLOT, false);
				//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				//AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_LAG_GRAPH_TABLE, _L("Residuals"), _L("Residuals Lag Plot"), IDST_FIT_RESIDUALS_LAG_DATA,
				//	IDST_REPORT_RESIDUAL_LAG_ONE_SET, vReX, _L("Residual(I-1)"), vRe, _L("Residual"), GRAPH_RESIDUALS_LAG_PLOT, false);
				AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabelCurve, STR_RESIDUALS_LAG_GRAPH_TABLE, strTableLabel, 
						strTableSubLabel, IDST_FIT_RESIDUALS_LAG_DATA, IDST_REPORT_RESIDUAL_LAG_ONE_SET, vReX, _L("Residual(I-1)"), vRe, strResidualGraphTableLongName, GRAPH_RESIDUALS_LAG_PLOT, false);
				//---CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
				///end CENTRALIZE_FITTING_RESULT_LABELS
			}
		}

		return true;
	}
	
	//--- Iris 3/16/2009 QA80-13285-P1 FIX_DUPLICATE_RESIDUAL_DATA_REPORT_FOR_DIFF_RESIDUAL_REPORT_AND_PLOT
	//virtual 
	// in MR cannot share resilt analysis data with residual plot data since residual analysis data not X data columns.
	bool UseResidualAnalysisDataReportForPlotting(TreeNode &trOp, int* pnYIndex = NULL) 
	{
		return false;
	}
	//---end FIX_DUPLICATE_RESIDUAL_DATA_REPORT_FOR_DIFF_RESIDUAL_REPORT_AND_PLOT
	
	//virtual
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//bool	ConstructCurvesAndGraphs(TreeNode &trOp, int index, int nTotalNumData, LPCSTR strDataLabel, vector &vX, vector & vY, matrix &mXs, FitParameter *psFitParameter, RegStats *psRegStats, RegCalcInternal *psReg, DWORD dwPlotObjUID, int nMultiplicity = 1, matrix& mYs = NULL, vector& vSerr = NULL, vector& vWeights = NULL)  
	bool	ConstructCurvesAndGraphs(TreeNode &trOp, int index, int nTotalNumData, LPCSTR strDataLabel, vector &vX, vector & vY, matrix &mXs, FitParameter *psFitParameter, RegStats *psRegStats, RegCalcInternal *psReg, DWORD dwPlotObjUID, int nMultiplicity = 1, matrix& mYs = NULL, vector& vSerr = NULL, vector& vWeights = NULL, LPCSTR lpcsDataLabelCurves = NULL)  
	///end CENTRALIZE_FITTING_RESULT_LABELS
	{
		GraphLayer	grLayAppar;
		if ( dwPlotObjUID && IsApparentFit(trOp) )
		{
			DataPlot		dpl;
			dpl = Project.GetObject(dwPlotObjUID);
			if (dpl.IsValid())
				dpl.GetParent(grLayAppar);
		}
		
		TreeNode trFittedCurve = GetGUIGraphNodes(trOp, GRAPH_FIT_CURVE);
		//trFittedCurve.Use = 0;
		if( trFittedCurve && trFittedCurve.nVal)
		{
			vector		vFitX, vFitY;
			FitResultCurveOptions	fitOptions;
			fitOptions = trFittedCurve;
			
			FitResultCurveDataOptions fitDataOptions;
			/// Iris 11/02/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			/*
			fitDataOptions = trFittedCurve.XDataType;
			fitDataOptions.DataType = trFittedCurve.XDataType.Use;  //DataType treenode is branch, cannot be assigned data to struct auto
			*/
			fitDataOptions = OP_GUI_FIT_X_DATA_BRANCH(trOp.GUI);
			fitDataOptions.DataType = OP_GUI_FIT_X_DATA_BRANCH(trOp.GUI).Use;			
			///end OP_DLG_NEW_STRUCTURE
			string strTableLabel, strPlotLabel, strDataLabelTemp(strDataLabel);
			ConvertEscapedString(strDataLabelTemp);
			strPlotLabel = GetAnalysisName() + " " + _L("of") + " " + strDataLabelTemp;
			
			//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
			//strTableLabel = _L("Fitted Values");
			//TreeNode	trFC = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_FIT_CURVE, STR_FIT_CURVES_TABLE, IDST_FIT_CURVES, strTableLabel, lpcsDataLabelCurves);
			TreeNode	trFC = CheckCreateOneFitCurvesTable(trOp, index, nTotalNumData);
			//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
			
			/*
			if(isPlotAverageData())
				AddAveData(trOp, index, trFC, vX, vY);
			else if(trFC)
				trFC.Reset(true);
			*/
			calcAddFitCurvesIntoTable(trOp, trFC, index, strDataLabel, mXs, vFitY, fitDataOptions, psFitParameter, grLayAppar);
			///Arvin 06/11/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
			//if(!CalcReportConfPredBandsTable(trOp, trFC, vFitX, vFitY, psFitParameter, *psRegStats, psReg, grLayAppar, GRAPH_FIT_CURVE, vSerr))
			if(!CalcReportConfPredBandsTable(trOp, trFC, vFitX, vFitY, psFitParameter, *psRegStats, psReg, grLayAppar, GRAPH_FIT_CURVE, vSerr, strDataLabel))
			///end CENTRALIZE_FITTING_RESULT_LABELS
				error_report("CalcReportConfPredBandsTable for MR Fitted Curves failed!"); 
		
			tree_hide_empty_nodes(trFC); 
		}
		////Arvin PARTIAL_REGRESSION_NO_NEED_ANY_FITTING
		//addPartialRegressionPlotsTable(trOp, index, nTotalNumData, strDataLabel, vX, vY, mXs);
		addPartialRegressionPlotsTable(trOp, index, nTotalNumData, lpcsDataLabelCurves, vX, vY, mXs, psFitParameter);
		///end PARTIAL_REGRESSION_NO_NEED_ANY_FITTING
		/// ML 9/20/2006 RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
		/*
		//AddResidualsDataTable(trOp, index, nTotalNumData, strDataLabel, psFitParameter, vX, vY, mXs);	
		AddResidualHistogramTable(trOp, index, nTotalNumData, strDataLabel, psFitParameter, vX, vY, mXs);		
		AddResidualFitTable(trOp, index, nTotalNumData, strDataLabel, psFitParameter, vX, vY, mXs);		
		AddResidualOrderTable(trOp, index, nTotalNumData, strDataLabel, psFitParameter, vX, vY, mXs);		
		///Jim 2/22/06 v8.0368 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
		AddResidualLagTable(trOp, index, nTotalNumData, strDataLabel, psFitParameter, vX, vY, mXs);
		///END ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH	
		*/		
		AddResidualTables(true, trOp, index, nTotalNumData, strDataLabel, psFitParameter, vX, vY, mXs, grLayAppar, vWeights, 1, lpcsDataLabelCurves);
		/// end RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
		
		/// Iris 01/08/2007 v8.0538 REPORT_GRAPHS_ARRANGEMENT
		//preparePartialPlotNodes(trOp, nTotalNumData);
	 	//PrepareGraphNodes(trOp, GetNumGraphs(), index, strDataLabel);  
	 	///end REPORT_GRAPHS_ARRANGEMENT
			
		return true;
	}	
	
	/// Iris 01/25/2007 v8.0547 CLEANUP_SETUP_PLOT_DETAILS_CODES
	///Arvin 12/02/06 MR_SET_PARTIAL_REGRESSION_CURVES_COLOR
	//virtual bool SetupFitCurvesPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nFittedPlot, int nNumPlots = 1, int nGraphIndex = 0)
	//{
		//TreeNode trFittedCurve = GetGUIGraphNodes(trOp, GRAPH_MR_PARTIAL_REGRESSION);		
		//if(GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex && trFittedCurve && trFittedCurve.Use )
		//{
			//int nNumFittedPlots = nNumPlots; 
			//SetupFittingCurvesPlotDetails(trOp, gl, nFittedPlot, nNumFittedPlots, nGraphIndex);
					//
			//if(GRAPH_FIT_CURVE == nGraphIndex)
			//{
				//TreeNode trXDataType = trFittedCurve.XDataType;
				//if(trXDataType)
				//{		
					//int nXDataType = trXDataType.Use;				
				//
					////set Axis
					//if(FIT_CURVE_UNIFORM_LOG == nXDataType)
					//{
						//string strXAxis = "axis -ps X S 1";
						//gl.LT_execute(strXAxis);
					//}					
				//}
			//}
		//
		//}
		//else
			//return false;
		//
		//return true;	
	//}
	///end MR_SET_PARTIAL_REGRESSION_CURVES_COLOR
	//virtual 
	int GetGraphIndexForMorePlotDetails()
	{
		return GRAPH_MR_PARTIAL_REGRESSION;
	}
	///end CLEANUP_SETUP_PLOT_DETAILS_CODES
	
	//virtual
	int GetTotalNumPictureForOneGraphType(TreeNode& trOp, int nGraphIndex = -1)
	{
		int 	nNum;
		LROptions sLROptions;
		sLROptions = trOp.GUI.Fit;			
		if(-1 == nGraphIndex)
		{
			if(trOp.GUI.Residuals.Graph7.nVal) //Partial Leverage Plots
				return sLROptions.FixIntercept ? GetNumX(trOp) : GetNumX(trOp)+1;
			
			if(trOp.GUI.Residuals.Graph2.nVal) // GRAPH_RESIDUALS_SCATTER			
				return GetNumX(trOp);
			
			return 1;			
		}
		else
		{
			switch(nGraphIndex)
			{
			case GRAPH_RESIDUALS_HISTOGRAM:
			case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
			case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
			case GRAPH_RESIDUALS_LAG_PLOT: 
				return 1;
				
			case GRAPH_FIT_CURVE:
			case GRAPH_RESIDUALS_SCATTER:
				return GetNumX(trOp);
			
			case GRAPH_MR_PARTIAL_REGRESSION:
				return sLROptions.FixIntercept ? GetNumX(trOp) : GetNumX(trOp)+1;
			}
		}
		return GetNumX(trOp);//error
	}
	
	//virtual
	int	ReportGetPlotTypeFromGraphIndex(int nGraphIndex)
	{
		if(GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex )
			return IDM_PLOT_LINE;		
		return FitRegression::ReportGetPlotTypeFromGraphIndex(nGraphIndex);
	}
	
	/// Iris 08/08/2007 v8.0677 WILL_NOT_PLOT_SOURCE_DATA_IN_MR_ANYMORE
	/*
	//virtual 
	bool IsSourceDataPlotInReport(int nGraphIndex)
	{
		if( GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex )
			return true;
		
		return false;
	}
	*/
	///end WILL_NOT_PLOT_SOURCE_DATA_IN_MR_ANYMORE

	bool 	GetCustomGraphTypeName(string& strName, int nGraphIndex)
	{
		FitRegression::GetCustomGraphTypeName(strName, nGraphIndex);
		if(GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex)
			strName = STR_PARTIAL_REGRESSION_GRAPH_TABLE;
		return true;
	}	
	
	// virtual
	BOOL CalcOneData(TreeNode &trOp, int index, int nTotalNumData, const vector<int> &vFactorSizes,
		const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights, DWORD dwPlotObjUID, int nRowColIndex, const vector<int>& vintRowsInSource)
	
	{
		m_vWeights = vWeights;
		
		m_nNumXs = mMultiIndep.GetNumCols();
		
		///Cheney 2007-5-17 LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL
		//all Fit tools except Mr should support 0 size dataset
		//so MR should check the dataset size itself
		if(mMultiIndep.GetNumRows() == 0 || vY.GetSize() == 0)
			return false;
		///end LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL	
		return FitRegression::CalcOneData(trOp, index, nTotalNumData, vFactorSizes, vstrFactors, vY, vX, mMultiIndep, vWeights, dwPlotObjUID, nRowColIndex, vintRowsInSource);
	}
	
	//--- Iris 10/17/06 NOT_SUPPORT_FINDXY_FOR_SURFACE_AND_MR
	///Joseph 09/18/06 MOVE_CALIBRATION_TABLE_OUT_OUTPUT
	bool IsReportCalibrationTable()
	{
		return false;
	}
	///End MOVE_CALIBRATION_TABLE_OUT_OUTPUT
	//---
	
	// virtual
	int GetNumX(TreeNode& trOp) 
	{
		return m_nNumXs;
	}
	
	int	 GetOutputRangeIndex(TreeNode& trOp, int nGraphIndex)
	{
		int nOutputIndex = -1;
		if( GRAPH_FIT_CURVE == nGraphIndex)
		{
			nOutputIndex = OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET;
		}
		
		if( GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex)
		{
			nOutputIndex = OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET;
		}

		if( IsResidualGraph(nGraphIndex) )
		{
			nOutputIndex = IsOutputSeparateResidualCurveSheet(trOp)? OUTPUT_RESULT_CURVE_RESIDUAL_SHEET : OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET;				
		}
		
		return nOutputIndex;
	}
	
	TreeNode GetResultCurvesBranch(TreeNode& trOp, int nDataIndex, int nTotalNumData, int nOutputRangeIndex, LPCSTR lpcszDataLabel)
	{
		TreeNode trSubTable;
		TreeNode 	trRC;
		switch(nOutputRangeIndex)
		{
		case OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET:		
			trRC = RESULT_CURVE_BRANCH(trOp);
			break;
		case OUTPUT_RESULT_CURVE_RESIDUAL_SHEET:
			trRC = RESIDUAL_CURVE_BRANCH(trOp);
			break;
		case OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET:
			trRC = CALIBRATION_CURVE_BRANCH_1(trOp);	
			break;
		case OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET:
			trRC = CALIBRATION_CURVE_BRANCH_2(trOp);		
			break;
		case OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET:
			trRC = PARTIAL_REGRESSION_CURVES_BRANCH(trOp);
			break;
		}	
		if( !trRC )
		{
			error_report("Fail to get ResultCurves node");
			return trSubTable;
		}
		if(lpcszDataLabel) // to indicate to create
		{
			int nGroupID = GetOneSetResultCurvesID(nOutputRangeIndex);
			trSubTable = check_add_enumerated_node(trRC, RESULT_CURVE_DATA_SET_PREFIX, nDataIndex + 1, make_one_set_ID(nGroupID, nDataIndex), STR_LABEL_ATTRIB, lpcszDataLabel);
			int nSingleTable = GetTableStringSupport(false);
			nSingleTable |= GETNBRANCH_CHANGE_LABEL_TYPES_IN_FLAT;
			trSubTable.SetAttribute(TREE_Table, nSingleTable);
		}
		else
		{
			///Arvin 05/30/07 v8.0629 ONE_SHEET_CALL_ONE_TIME_SET_REPORT_TREE 
			//string strCuvTable;
			//strCuvTable.Format("%s%d", RESULT_CURVE_DATA_SET_PREFIX, nDataIndex + 1);
			//trSubTable = trRC.GetNode(strCuvTable);
			if(nDataIndex < 0) //Get the whole branch
				trSubTable = trRC;
			else
			{
				string strCuvTable;
			 	strCuvTable.Format("%s%d", RESULT_CURVE_DATA_SET_PREFIX, nDataIndex + 1);
				trSubTable = trRC.GetNode(strCuvTable);
			}
			///end ONE_SHEET_CALL_ONE_TIME_SET_REPORT_TREE
		}
		return trSubTable;  
	}
	
private:
	/// Iris 01/08/2007 v8.0538 REPORT_GRAPHS_ARRANGEMENT
	/*
	bool preparePartialPlotNodes(TreeNode& trOp, int nTotalNumData)
	{
		TreeNode trPict, trInfo;
		
		int nGraphIndex = GRAPH_MR_PARTIAL_REGRESSION;
		
		//int nPicNum = GetPictureNum(trOp, nTotalNumData, nGraphIndex);
		int nPicNum = GetPictureNum(trOp, m_nPartialPlots, nGraphIndex); /// Iris 10/18/05 WORK_MORE_ON_PARTIAL_PLOTS nTotalNumData always is 1, but there are nXs+1 regression plots even though only one Y data	
		
		DataRange 	dr;
		GetInput(dr);		
		for(int nPic=0; nPic<nPicNum; nPic++)
		{
			string		strIndep, strDep;
			get_fit_data_label(dr, strIndep, strDep, trOp.GUI.Fit.FixIntercept.nVal, nPic);
			string		strLabel = strDep + " vs. " + strIndep;	
			CheckCreateImagSubNodes(trOp, nGraphIndex, trPict, trInfo);		
		}
		return true;
	}	
	*/
	///end REPORT_GRAPHS_ARRANGEMENT
	
	//---- CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
	/*
	TreeNode getPartialPlotsData(TreeNode& trOp, int nDataIndex)
	{
		TreeNode	trFit;
		TreeNode	trFitCuvesTable = FIT_CURVES_BRANCH(trOp.Calculation);
		if(trFitCuvesTable)
		{
			TreeNodeCollection trColl(trFitCuvesTable, CALCULATION_FIT_CURVES_PREFIX);
			if(trColl.Count() > 0)
			{
				nDataIndex++;
				string strTable = CALCULATION_FIT_CURVES_PREFIX + nDataIndex;
				trFit = trFitCuvesTable.GetNode(strTable);
			}
			else
				trFit = trFitCuvesTable;
		}
		return trFit;

	}
	*/
	///Arvin PARTIAL_REGRESSION_NO_NEED_ANY_FITTING
	//bool addPartialRegressionPlotsTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, vector &vX, vector &vY, matrix &mXs)
	bool addPartialRegressionPlotsTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, vector &vX, vector &vY, matrix &mXs, FitParameter *psFitParameter)
	///------
	{
		//Calculate partial regression result
		LROptions sLROptions;
		sLROptions = trOp.GUI.Fit;
		
		int 	nVSizeM = mXs.GetNumCols();
		int 	nOSizeN = mXs.GetNumRows();

		matrix 	mPlot;
		int 	nFitSize = sLROptions.FixIntercept ? nVSizeM : nVSizeM + 1;
		mPlot.SetSize(nOSizeN, 2*nFitSize);		
	
		int 	nRet = ocmath_partial_reg_plots(mXs, nOSizeN, nVSizeM, vY, &sLROptions, mPlot, 2*nFitSize);
		if(nRet)
			return error_report("ocmath_partial_reg_plots fail to work in addPartialRegressionPlotsTable");		
		
		
		//add partial regression table
		DataRange 	dr;
		GetInput(dr);
		
		int 	nPlot = 0;
		int 	nPlotNum = mPlot.GetNumCols()/2;
		
		int nParamStart = sLROptions.FixIntercept ? 1 : 0;
		for(int nCol=0; nCol<mPlot.GetNumCols(); )
		{
			vector		vPartialX, vPartialY;			
			mPlot.GetColumn(vPartialX, nCol++);
			mPlot.GetColumn(vPartialY, nCol++);				
				
			//nParamStart++;	///Arvin 08/07/07 WRONG_REFERENCE_LINE_DATA		
			///Arvin 05/30/07 v8.0629 ONE_SHEET_CALL_ONE_TIME_SET_REPORT_TREE
			//string 		strLabel = "Fit" + nPlot;
			string strLabel 	= strDataLabel;
			///end ONE_SHEET_CALL_ONE_TIME_SET_REPORT_TREE
			int			nTableID = make_one_set_ID(IDST_MR_PARTIAL_CURVE, nPlot);	
			
			string		strIndep, strDep;
			///Arvin 02/14/07 WRONG_LABEL_WHEN_FIX_INTERCEPT
			//get_fit_data_label(dr, strIndep, strDep, trOp.GUI.Fit.FixIntercept.nVal, nPlot+1);
			bool bFixIntercept = trOp.GUI.Fit.FixIntercept.nVal;
			if(bFixIntercept)
				get_fit_data_label(dr, strIndep, strDep, bFixIntercept, nPlot+1);
			else
				get_fit_data_label(dr, strIndep, strDep, bFixIntercept, nPlot);
			///END WRONG_LABEL_WHEN_FIX_INTERCEPT
			string	strXLabel = _L("Partial X") + " / " + _L(strIndep);
			string	strYLabel = _L("Partial Y") + " / " + _L(strIndep);
			
			//add FitCurve Table and PartailX and  PartialY columns	
			//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
			//AddGraphDataOneTable(trOp, nPlot, nPlotNum, strLabel, "FitCurves", STR_PARTIAL_REGRESSION_GRAPH_TABLE, NULL, nTableID,
			AddGraphDataOneTable(trOp, nPlot, nPlotNum, strLabel, "FitCurves", GetResidualDataTableLabel(), NULL, nTableID,
			//---
				GetOneSetResultCurvesID(), vPartialX, strXLabel, vPartialY, strYLabel, GRAPH_MR_PARTIAL_REGRESSION, true, CALCULATION_FIT_CURVES_PREFIX);
			
			TreeNode	trTable = GetOneResultCurvesTable(trOp, nPlot, nPlotNum, GRAPH_MR_PARTIAL_REGRESSION);	
			
			// add reference line
			vector		vReferenceLine;
			vReferenceLine = vPartialX * psFitParameter[nParamStart].Value;
			TreeNode	trReferenceLine = tree_check_get_node(trTable, "ReLine", make_one_set_ID(IDST_MR_PARTIAL_CURVE, nPlot), STR_LABEL_ATTRIB, _L("Reference Line"));
			trReferenceLine.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
			trReferenceLine.dVals = vReferenceLine;					
			
			nPlot++;
			nParamStart++;	///Arvin 08/07/07 WRONG_REFERENCE_LINE_DATA	
		}
		
		m_nPartialPlots = nPlot;  /// Iris 10/18/05 WORK_MORE_ON_PARTIAL_PLOTS

		return true;
	}
	///Arvin 11/28/06 ADD_FIT_CURVES_TABLE
	bool calcAddFitCurvesIntoTable(TreeNode& trOp, TreeNode& trFC, int index, LPCSTR lpcszDataLabel, matrix& mXs, vector& vFitY, const FitResultCurveDataOptions& fitDataOptions, FitParameter *psFitParameter, GraphLayer& grLayAppar)
	{
		vector vFitX;
		///Cheney 2007-5-17 LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL
		//if do MR from OC code, will run time error here if data set size is 0
		if(mXs.GetNumRows() == 0)
			return false;
		///end LINEAR_FIT_SHOULD_CONSISTENT_WITH_FIT_NL
		MakeFitY(index, trOp, vFitX, vFitY, psFitParameter, mXs);
		if(vFitY.GetSize() == 0)
			return false;
		
		matrix mFitY(vFitY.GetSize(), 1);
		mFitY.SetColumn(vFitY, 0);
		FitterOperation::addOneFitDataIntoTable(trFC, mXs, grLayAppar, true, index, lpcszDataLabel);
		FitterOperation::addOneFitDataIntoTable(trFC, mFitY, grLayAppar, false, index, lpcszDataLabel);
		return true;
	}
	///end ADD_FIT_CURVES_TABLE
	
	int GetOutputSlot(int nDataIndex, bool bTableMustBeOutside, int nOutputIndex)
	{
		int	nRangeIndex;  //the range index of columns of the output data table
		Tree trOp;
		GetTree(trOp);
		int nOutputTemp = IsOutputSeparateResidualCurveSheet(trOp)? OUTPUT_RESULT_CURVE_RESIDUAL_SHEET : OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET;				
		if(nOutputTemp == nOutputIndex && nDataIndex > 0)
			nDataIndex = 0;
		
		nRangeIndex = WksReportOperation::GetOutputSlot(nDataIndex, bTableMustBeOutside, nOutputIndex);
		if(nOutputIndex == OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET)
			nRangeIndex = OUTPUT_PARTIAL_CURVE_SHEET_RNG_INDEX;
		
		int nOutputCount = 6;  //one partial regression curve table + one fit curves table + one residual curve table + two calibration tables + one result table in source wks
		nRangeIndex += nOutputCount * nDataIndex; 	
		
		return nRangeIndex;	
	}
	
	void getGUIResultCurveNode(const TreeNode& trGUI, TreeNode& trResultCurve, int nOutputIndex)
	{
		WksReportOperation::getGUIResultCurveNode(trGUI, trResultCurve, nOutputIndex);
		if(nOutputIndex == OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET)
			trResultCurve = trGUI.Output.PartialCurves;
	}
	
	string GetResultCurveBookName(TreeNode& trOperation, int nDataIndex = 0, int nOption = -1, bool bSeparateSheetForDataset = false)
	{
		string		strBookName;
		strBookName = FitterOperation::GetResultCurveBookName(trOperation, nDataIndex, nOption, bSeparateSheetForDataset);
		if(nOption == OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET)
		{
			int nLen = strBookName.GetLength();
			int nStart = strBookName.ReverseFind('-');
			strBookName.Delete(nStart+1, nLen-nStart);
			strBookName = strBookName + "Partial Leverage Val";
		}
		
		return 	strBookName;
	}
	
	/// Iris 4/11/2008 SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK
	string 	GetResultCurveBookShortName(TreeNode& trOperation, int nIndex = 0, int nOption = -1)
	{
		string		strBookName;
		if(nOption == OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET)
		{
			strBookName = _LE(E_STR_MR_PARTIAL_CURVE_BOOK_SHORT_NAME);
		}
		else
			strBookName = FitterOperation::GetResultCurveBookShortName(trOperation, nIndex, nOption);
		
		return strBookName;
	}
	///end SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK
	
	///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
	//bool setFindXYorYXTable(TreeNode &trCustom, string &strInputColLabel, int nInputColType, string &strOutColLabel, int nOutputColType, string &strValueToStore)
	virtual bool setFindXYorYXTable(TreeNode &trCustom, string &strInputColLabel, int nInputColType, string &strOutColLabel, int nOutputColType, string &strValueToStore, int nInputSrcUID, int nOutputSrcUID)
	///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
	{
		TreeNode		trRow = trCustom.FirstNode;
		if ( !trRow.IsValid() )
			return error_report("addFindXYorYXTable trCustom invalid");
		
		// We want the second column to have the formula:
		TreeNode		trCol = trRow.Children.Item(0);
		if ( !trCol.IsValid() )
			return false;
		
		//trCol.SetAttribute(STR_LABEL_ATTRIB, strInputColLabel);
		//trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nInputColType);			
		//trCol.SetAttribute(STR_ATT_COLUMN_FORMULA, strValueToStore);

		///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		DWORD	dwCntrl = SRC_COL_PROPERTY_FORMAT;
		///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE		
		int				nCountOutputCols = trRow.Children.Count() - 1;
		for (int kk = 0; kk < nCountOutputCols; kk++)
		{
			trCol = trRow.Children.Item(kk);
			string		strMoreInputLabel;
			strMoreInputLabel.Format("%s %d", strInputColLabel, kk+1);  
			trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nInputColType);
			trCol.SetAttribute(STR_LABEL_ATTRIB, strMoreInputLabel);
			///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
			okutil_source_column_property(&trCol, &nInputSrcUID, &dwCntrl, FALSE);
			///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		}
		
		TreeNode		trOutputCol = trRow.Children.Item(nCountOutputCols);		
		if ( !trOutputCol.IsValid() )
			return false;
		trOutputCol.SetAttribute(STR_LABEL_ATTRIB, strOutColLabel);
		trOutputCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nOutputColType);
		trOutputCol.SetAttribute(STR_ATT_COLUMN_FORMULA, strValueToStore);
		///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		okutil_source_column_property(&trOutputCol, &nOutputSrcUID, &dwCntrl, FALSE);
		///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		
		return true;
	}
	
protected:
	///Arvin 01/22/06 LISTING_INPUT_DATA_AS_A_VERTICAL_LIST_FOR_MR change as Fred's suggestion 
	void	UpdateDataSourceInReportingHeader(TreeNode &trInputTable, const vector<string> &vstrFactors, int ii, LPCSTR lpcszXLabel = NULL, int numSubRanges = 0, DWORD dwRules = 0)
	{
		/*
		if ( 1 < numSubRanges )
		{
			AddCombinedDataSourcesToReportInputTable(trInputTable, vstrFactors, ii, WKSH_OPERATION_INFO_Y_DATA_SOURCE, numSubRanges, dwRules, WKSH_OPERATION_INFO_X_DATA_SOURCE);
			return;
		}
		*/
		int			indexLT = ii + 1;
		TreeNode	trCalc = trInputTable.Parent();
		TreeNode	trOp = trCalc.Parent();
	
		tree_add_more_labels(trInputTable, vstrFactors);
		/// Iris 3/30/2009 CHANGE_INPUT_DATA_TABLE_XY_LABELS according to Laurie's mail
		//string strXLabel = WKSH_OPERATION_INFO_X_DATA_SOURCE;
		string strXLabel = "X";
		///end CHANGE_INPUT_DATA_TABLE_XY_LABELS
		if(strXLabel.IsEmpty())
			strXLabel = "Data Range";
		
		string strDataLabel = "Data";
		int			numX = GetNumX(trOp);
		string		strXLabelUse;
		for (int iX = 0; iX < numX; iX++)
		{
			if (1 < numX)
				/// Iris 3/30/2009 CHANGE_INPUT_DATA_TABLE_XY_LABELS remove whitespace, according to Laurie's mail
				//strXLabelUse.Format("%s %u", strXLabel, iX + 1);
				strXLabelUse.Format("%s%u", strXLabel, iX + 1);
				///end CHANGE_INPUT_DATA_TABLE_XY_LABELS
			else
				strXLabelUse = strXLabel;
			
			//In order to list input data as a vertical list, we must make sure same column's nodes' ID and tagName  are same
			TreeNode trX = check_add_enumerated_node(trInputTable, "R", iX+1, make_one_set_ID(IDST_REPORT_INPUT_ONE_SET, ii+iX), STR_LABEL_ATTRIB, strXLabelUse); 
			string		strValue;
			///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
			//getEscapedDataString(strValue, indexLT, false, 'P', 'X', ESC_LABEL_ADD_NONE, 0, iX + 1);
			report_get_escaped_data_string(&strValue, indexLT, false, 'P', 'X', ESC_LABEL_ADD_NONE, 0, iX + 1);
			///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
			string strTagName = "X";
			TreeNode trCol = tree_check_get_node(trX, strTagName, IDE_INPUT_X,  STR_LABEL_ATTRIB, strDataLabel);
			trCol.strVal = strValue;
			///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
			//getEscapedDataString(strValue, indexLT, false, 'R', 'X', ESC_LABEL_ADD_NONE, 0, iX + 1);
			report_get_escaped_data_string(&strValue, indexLT, false, 'R', 'X', ESC_LABEL_ADD_NONE, 0, iX + 1);
			///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
			strTagName = "X_Excel";
			trCol = tree_check_get_node(trX, strTagName, IDE_INPUT_X_EXCEL,  STR_LABEL_ATTRIB, strDataLabel);
			trCol.strVal = strValue;
			trCol.Show = false;
			
			AddOneInputDataTableCell(trX, WKSH_OPERATION_INFO_DATA_SOURCE_RANGE, indexLT, FALSE, 'G', 'R');
		}
		
		/// Iris 3/30/2009 CHANGE_INPUT_DATA_TABLE_XY_LABELS according to Laurie's mail
		//string			strMainTitle = WKSH_OPERATION_INFO_Y_DATA_SOURCE; 
		string			strMainTitle = "Y";
		///end CHANGE_INPUT_DATA_TABLE_XY_LABELS		
		TreeNode trY = check_add_enumerated_node(trInputTable, "R", numX+1, make_one_set_ID(IDST_REPORT_INPUT_ONE_SET, ii+numX), STR_LABEL_ATTRIB, strMainTitle); 
		//string strDataLabel = "Data";
		
		//In order to list input data as a vertical list, we must make sure same column's nodes' ID and tagName  are same
		string		strValue;
		///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
		//getEscapedDataString(strValue, indexLT, FALSE, 'P', 0);
		report_get_escaped_data_string(&strValue, indexLT, FALSE, 'P', 0);
		///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
		string strTagName = "X";
		TreeNode trCol = tree_check_get_node(trY, strTagName, IDE_INPUT_X,  STR_LABEL_ATTRIB, strDataLabel);
		trCol.strVal = strValue;
		///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
		//getEscapedDataString(strValue, indexLT, FALSE, 'R', 0);
		report_get_escaped_data_string(&strValue, indexLT, FALSE, 'R', 0);
		///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
		strTagName = "X_Excel";
		trCol = tree_check_get_node(trY, strTagName, IDE_INPUT_X_EXCEL,  STR_LABEL_ATTRIB, strDataLabel);
		trCol.strVal = strValue;
		trCol.Show = false;
		
		///Arvin 08/17/07 ADD_WEIGHT_DATA_TABLE_IN_INPUT_DATA_TABLE
		TreeNode trInputData = trOp.GUI.InputData;
		if(IsDatasetHasWeight(trInputData, ii))
			AddOneInputDataTableCell(trY, WKSH_OPERATION_INFO_WEIGHT_DATA_SOURCE, indexLT, FALSE, 'P', 'W');
		///end ADD_WEIGHT_DATA_TABLE_IN_INPUT_DATA_TABLE
		
		//The Range column:
		AddOneInputDataTableCell(trY, WKSH_OPERATION_INFO_DATA_SOURCE_RANGE, indexLT, FALSE, 'G', 'R');
	
		return;
	}
	///END LISTING_INPUT_DATA_AS_A_VERTICAL_LIST_FOR_MR

	bool IsResultsPlotInReport(int nGraphIndex)
	{
		bool bRet = FitterOperation::IsResultsPlotInReport(nGraphIndex);
		if(nGraphIndex == GRAPH_MR_PARTIAL_REGRESSION)
			bRet = true;
		
		return bRet;
	}	


	
	DWORD	GetDataRules(const TreeNode& trOp, bool bIgnoreCombineInfo = false)
	{
		DWORD	dwRules = FitRegression::GetDataRules(trOp, bIgnoreCombineInfo);
		dwRules |= DRR_ONE_DEP_MULTIINDEP;
		return dwRules;
	}
	/*
	void	UpdateDataSourceInReportingHeader(TreeNode &trTable, bool bInit)
	{
		if (bInit)
		{
			trTable.Inputs.strVal = "";
			trTable.Inputs.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_Y_DATA_SOURCE);
			//trTable.InputsX.strVal = "";
			//trTable.InputsX.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_X_DATA_SOURCE);
		}
		else
		{
			string			str = OPERATION_ESCAPE_STRING_PREFIX;
			str += "R=1";
			trTable.Inputs.strVal = str;
			
			trTable.RemoveChildrenWithPrefix(MR_INDEPS_NODE_NAME_PREFIX);
			
			TreeNode		trCalc = trTable.Parent();
			TreeNode		trOp = trCalc.Parent();
			int				nParams = trOp.Input.nParams.nVal;

			string			strValue, strNodeName, strLabel;
			for (int ii = 1; ii < nParams; ii++)
			{
				strValue.Format("%sX%d", str, ii);
				strNodeName.Format("InputsX%d", ii);
				TreeNode	trX = trTable.AddNode(strNodeName);
				
				trX.strVal = strValue;
				
				strLabel.Format("%s %d", WKSH_OPERATION_INFO_X_DATA_SOURCE, ii);
				trX.SetAttribute(STR_LABEL_ATTRIB, strLabel);
			}
		}
	}
	*/

	/// Iris 9/23/04 ADD_COV_AND_CORR_REPORT
	//int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
	//		FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, RegCalcInternal* psInternal)
	///Arvin 05/18/07 USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
	//int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
			//FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, 
			//RegCalcInternal* psInternal, matrix& mCov, matrix& mCorr, vector& vSerr = NULL)
	int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
			FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, 
			RegCalcInternal* psInternal, matrix& mCov, matrix& mCorr, vector& vSerr = NULL, int index = 0)
	///end USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
	{
		TreeNode		trGUI = trOp.GUI;

		TreeNode		trFit = trGUI.Fit;
		
		////////////////////////		
		// Input settings:
		LROptions		sLROptions;
		sLROptions = trGUI.Fit;
		sLROptions.Confidence = trGUI.Quantities.Parameters.Confidence.dVal; /// Iris 8/11/06 v8.0460 QA70-7735-11 Confidence node has been move into Quantities to Compute branch
		sLROptions.Confidence /= 100;		
		////////////////////////
		// number of params:
		// I have to remember here the number so I can use it inside GetNumParams().
		int				nNumRows = mMultiIndep.GetNumCols();
		trOp.Input.nParams.nVal = nNumRows + 1; 		
		
		/// Iris 9/27/04 ADD_COV_AND_CORR_REPORT
		//return stats_multiple_linear_regression(mMultiIndep, vY, vWeights, sLROptions, psFitParameter, nSizeFitParams, psRegStats, psRegANOVA);
		//return stats_linear_fit(vY, vX, vWeights, sLROptions, psFitParameter, psRegStats, psRegANOVA, psInternal);
		
		///Echo 3/21/05 ERROR_PARAM_SIZE
		//if(trGUI.Fit.FixIntercept.nVal)
			//nSizeFitParams = nNumRows;
		//else
		nSizeFitParams = nNumRows + 1;
		///END ERROR_PARAM_SIZE
		
		///Arvin 05/18/07 USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
		TreeNode trInput = trGUI.InputData;
		if(!IsDatasetHasWeight(trInput, index))
			sLROptions.UseReducedChiSq = true;
		///end USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
		
		///Echo 3/21/05 PARAM_WRONGLY_FREE
		//psFitParameter = (FitParameter*)calloc(nSizeFitParams, sizeof(FitParameter) );	
		int nRet = stats_multiple_linear_regression(mMultiIndep, vY, vWeights, sLROptions, psFitParameter, nSizeFitParams, psRegStats, psRegANOVA, mCov, mCorr, NULL, vSerr);

		///Echo 3/21/05 PARAM_WRONGLY_FREE
		//free(psFitParameter);
		
		return nRet;
		///End ADD_COV_AND_CORR_REPORT
	}

	int		GetParameters(TreeNode &trOp, int index = 0, vector<string> &vstrParameterNames = NULL, bool bIncNumPostfix = false, bool bIncDerivedParams = false, vector<bool>& vbIsDerived = NULL)
	{
		int			nParams = trOp.Input.nParams.nVal;
		if(NULL == vstrParameterNames)
			return nParams;
		
		vstrParameterNames.SetSize(nParams);		
		
		DataRange 	dr;
		GetInput(dr, index);	
		
		for(int ii = 0; ii < nParams; ii++)
		{
			string		strIndep, strDep;
			///Arvin 02/14/07 GET_PAREMETERS_SHOULD_NOT_CONSIDER_FIX_INTERCEPT
			//get_fit_data_label(dr, strIndep, strDep, trOp.GUI.Fit.FixIntercept.nVal, ii);
			get_fit_data_label(dr, strIndep, strDep, false, ii);
			///end GET_PAREMETERS_SHOULD_NOT_CONSIDER_FIX_INTERCEPT
			vstrParameterNames[ii] = strIndep;
			
			/// Iris 12/29/2006 v8.0534 PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
			if(bIncNumPostfix)
			{
				ParamsNamesAddPostfix(vstrParameterNames, index);
			}
			///end PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
		}		
		
		return nParams;
	}	
	
	//virtual 
	/*
	int	plotInputData(DataRange &rngInput, const TreeNode& trOp, GraphLayer& gl, int index, int nPlotType = IDM_PLOT_SCATTER, int iIndep = 0, int iDep = 0)
	{
		DataRange	dpRange;
		rngInput.GetSubRange(dpRange, GetDataRules(trOp), index);
		if(!dpRange)
		{
			error_report("Error in adding Input data to report graph");
			return -1;
			
		}
		DataRange drSubRange;
		int nStartPlot = -1;
		for(int nRange=0; nRange < dpRange.GetNumRanges(); nRange++)
		{
			int c1, c2, r1, r2;
			Worksheet wksTemp;
			dpRange.GetRange(nRange, r1, c1, r2, c2, wksTemp);
			
			//create a new data range with range name "X", "Y", "Err" and so on according to col type
			for( int nCol = c1; nCol <= c2; nCol++ )
			{
				Column col(wksTemp, nCol);
				if( col )
				{
					string strRange;
					switch( col.GetType() )
					{
					case OKDATAOBJ_DESIGNATION_X:
						strRange = "X";
						break;
						
					case OKDATAOBJ_DESIGNATION_Y:				
						strRange = "Y";
						break;
						
					case OKDATAOBJ_DESIGNATION_ERROR:				
						strRange = "ED";				
						break;
			
					case OKDATAOBJ_DESIGNATION_WEIGHT:
						strRange = "W";
					default:
						break;
					}
				
					if( !strRange.IsEmpty() )
					{
						if("X" == strRange && drSubRange && nCol-c1 == iIndep)
						{
							drSubRange.Add();
							drSubRange.Add(wksTemp, nCol, strRange);
						}
						
						if("X" != strRange)
							drSubRange.Add(wksTemp, nCol, strRange);
					}
				}
			}
		}
		int nPlot = gl.AddPlot(drSubRange, nPlotType);
		return nPlot;
	}
	*/
	
	/// Iris 08/08/2007 v8.0677 WILL_NOT_PLOT_SOURCE_DATA_IN_MR_ANYMORE
	/*
	/// Iris 08/01/2007 QA70-10133 ONLY_RECALCULATE_TIME_NEED_CHECK_RESCALE_IF_DATA_OUTSIDE
	//int AddWksInputDataPlot(int index, GraphLayer& gl, const TreeNode& trOp, int PlotType = IDM_PLOT_SCATTER, bool bRescale = true, int nXIndex = 0, int nYIndex = 0)
	int AddWksInputDataPlot(int index, GraphLayer& gl, const TreeNode& trOp, int nGraphIndex = 0, int PlotType = IDM_PLOT_SCATTER, bool bRescale = true, int nXIndex = 0, int nYIndex = 0)
	///end ONLY_RECALCULATE_TIME_NEED_CHECK_RESCALE_IF_DATA_OUTSIDE
	{
		/// Iris 08/01/2007 QA70-10133 ONLY_RECALCULATE_TIME_NEED_CHECK_RESCALE_IF_DATA_OUTSIDE
		//duplicate variable names in declaration: nGraphIndex
		//int			nGraphIndex = GRAPH_MR_PARTIAL_REGRESSION;
		nGraphIndex = GRAPH_MR_PARTIAL_REGRESSION;
		///end ONLY_RECALCULATE_TIME_NEED_CHECK_RESCALE_IF_DATA_OUTSIDE
		TreeNode	trFC = GetOneResultCurvesTable(trOp, index, m_nPartialPlots, nGraphIndex);
		int 		nTableID = trFC.ID;
		
		DataRange	rgFitCurvesTable;
		DataRange 	drTable;
		if(!GetResultCurvesDataRange(trOp, rgFitCurvesTable, index, nGraphIndex, GetOutputRangeIndex(trOp, nGraphIndex)))
		{
			error_report("error, AddWksInputDataPlot found bad report range");
			return -2;
		}
		
		vector<uint> vnTemp;
		vnTemp.Add(nTableID);
		if(!rgFitCurvesTable.GetSubRange(vnTemp, drTable, false) || !drTable.IsValid())
		{
			error_report("error, AddWksInputDataPlot found bad sub table range");
			return -3;
		}

		int 		c1, c2, r1, r2;
		Worksheet 	wksTemp;
		drTable.GetRange(0, r1, c1, r2, c2, wksTemp);
		if( !wksTemp || c1 < 0 || c2 < 0 || c2 <= c1 )
			return -4;
		
		Curve 		cv(wksTemp, c1, c1+1 );
		int 		nPlot = gl.AddPlot(cv, PlotType);
		
		if( bRescale && nPlot >= 0 )
			gl.Rescale();
		
		return nPlot;
		
		
	}
	*/
	///end WILL_NOT_PLOT_SOURCE_DATA_IN_MR_ANYMORE
	
	///Arvin 11/02/06 MR_DOES_NOT_PLOT_SORUCE_DATA
	/// Iris 08/06/2007 v8.0674 NOT_PLOT_AGAIN_IF_PLOTTED_FOR_REPORT_GRAPH
	//int PlotOneResultsDataRange(TreeNode& trOp, GraphLayer& gl, DataRange drTable, int nPlotType, int nGraphIndex, int nPictureIndex, int nPicColIndex, bool bIsSourceGraph = false)
	///Arvin 08/15/07 QA70-10212-P3 ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
	//int PlotOneResultsDataRange(TreeNode& trOp, GraphLayer& gl, DataRange drTable, int nPlotType, int nGraphIndex, int nPictureIndex, int nPicColIndex, bool bIsSourceGraph = false, bool bCheckIfHasPlot = false)
	int PlotOneResultsDataRange(TreeNode& trOp, GraphLayer& gl, DataRange drTable, int nPlotType, int nGraphIndex, int nPictureIndex, int nPicColIndex, bool bIsSourceGraph = false, bool bCheckIfHasPlot = false, int* pStartPlotIndex = NULL)
	///end ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
	///end NOT_PLOT_AGAIN_IF_PLOTTED_FOR_REPORT_GRAPH
	{
		int nPlot;
		if( GetReportGraphTableRowNum(trOp, nGraphIndex) > 1 && nGraphIndex == GRAPH_RESIDUALS_SCATTER)
		{
			/// Iris 08/08/2007 QA70-10073 TO_KEEP_CUSTOMIC_SETTINGS_IN_REPORT_GRAPH
			//nPlot = plot_wks_one_xy_from_data_range(drTable, gl, nPlotType);		
			//--- Iris 3/18/2009 QA80-13304 FIX_MR_RESIDUAL_PLOTS_ALL_PLOTTED_ON_FIRST_X_WITH_RESIDUAL
			nPlot = plot_wks_one_xy_from_data_range(drTable, gl, nPlotType, 0, 0, bCheckIfHasPlot);	
			//nPlot = plot_wks_one_xy_from_data_range(drTable, gl, nPlotType, nPictureIndex, 0, bCheckIfHasPlot);	
			//---end FIX_MR_RESIDUAL_PLOTS_ALL_PLOTTED_ON_FIRST_X_WITH_RESIDUAL
			///end TO_KEEP_CUSTOMIC_SETTINGS_IN_REPORT_GRAPH
		}
		/// Iris 7/10/2008 v8.0899 QA80-11831 MR_PARTIAL_LEVERAGE_PLOTS_ONE_RESULT_CURVE_RANGE_NEED_TWO_DIFF_PLOTTYPE
		else if(GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex)
		{
			DataRange 	drPlotRange;
			convert_result_curve_range_to_one_plotted_range(drTable, drPlotRange);			
			
			DWORD 		dwDataRules = DRR_GET_DEPENDENT | DRR_NO_FACTORS;
			vector<int> vnPlotTypes = {IDM_PLOT_SCATTER, IDM_PLOT_LINE};
			int			nNumData = drPlotRange.GetNumData(dwDataRules);
			ASSERT(nNumData == vnPlotTypes.GetSize());
			
			for(int nRange = 0; nRange < nNumData; nRange++)
			{
				DataRange drSub;
				drPlotRange.GetSubRange(drSub, dwDataRules, nRange);
				
				int		nPlotType = vnPlotTypes[nRange];
				nPlot = plotDataRange(drSub, gl, nPlotType, GAP_USE_TEMPLATE, bCheckIfHasPlot);	
			}			
		}
		///end MR_PARTIAL_LEVERAGE_PLOTS_ONE_RESULT_CURVE_RANGE_NEED_TWO_DIFF_PLOTTYPE
		else
		{
			/// Iris 08/08/2007 QA70-10073 TO_KEEP_CUSTOMIC_SETTINGS_IN_REPORT_GRAPH
			//uint nCntrl = GAP_USE_TEMPLATE | GAP_ALLOW_DUPLICATE_COL;
			//nPlot = plot_data_range(drTable, gl, nPlotType, nCntrl);
			uint 	nCntrl = GAP_GROUP_PLOTS;
			DWORD 	dwDataRules = GetDataRules(trOp);
			///Arvin 08/15/07 QA70-10212-P3 ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
			//nPlot = plot_data_range(drTable, gl, nPlotType, nCntrl, NULL, bCheckIfHasPlot, &dwDataRules);
			nPlot = plot_data_range(drTable, gl, nPlotType, nCntrl, NULL, bCheckIfHasPlot, &dwDataRules, pStartPlotIndex);
			///end ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
			///end TO_KEEP_CUSTOMIC_SETTINGS_IN_REPORT_GRAPH
		}
		
		return nPlot;
	}
	
	
	/*
	int PlotResultsTableInLayer(TreeNode& trOp, GraphLayer& gl, DataPlot& dp, TreeNode& trPlotInfo, int nDataIndex, int* pnPlot = NULL, int* pnNumPlots = NULL, int nGraphIndex = GRAPH_FIT_CURVE, int nPictureIndex = 0, int nPicColIndex = 0)
	{
 		int nResultTableID = trPlotInfo.TableID.nVal;
 	
		DataRange drTable;
		if(!GetResultTableData(trOp, nResultTableID, nDataIndex, nGraphIndex, drTable))
			return 0;
		///end FITTING_HISTOGRAM_PLOT
		
		int nStartPlotIndex = gl.DataPlots.Count();	
		_DBINT("Before nStartPlotIndex add plots, index = ", nStartPlotIndex);	
		
		int nPlot, nNumPlots;
		if( GetReportGraphTableColNum(trOp, nGraphIndex) > 1)
		{
			int		nXIndex = nPictureIndex;
			int		nYIndex = nPictureIndex;
			nPlot = plot_wks_one_xy_from_data_range(drTable, gl, trPlotInfo.PlotType.nVal, nXIndex, nYIndex);		
		}
		else
		{
			uint nCntrl = GAP_USE_TEMPLATE | GAP_ALLOW_DUPLICATE_COL;
			nPlot = plot_data_range(drTable, gl, trPlotInfo.PlotType.nVal, nCntrl);
		}
		///end MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
		if( nPlot<0 )
			return error_report("Fail to add plot");
		///End SURFACE_FIT_REPORT_MAT_FIT_DATA
		
		int nPlotsAdded = gl.DataPlots.Count() - nStartPlotIndex;	
		if(nPlot >= 0)
		{
			for(int index = nStartPlotIndex; index < gl.DataPlots.Count(); index++)
			{
				dp = gl.DataPlots(index);
				if(dp.IsValid())
				{
					setDataPlotEventHandler(dp, nDataIndex);											
				}
			}
		}
		if(NULL != pnPlot)
			*pnPlot = nPlot;
		if(NULL != pnNumPlots)
			*pnNumPlots = nPlotsAdded;
		
		if(nPlotsAdded)
		{		
			uint nn = ReportPlotTypeGrouppingMethod(trPlotInfo.PlotType.nVal);
			if(nPlotsAdded > 1 && (nn & RP_GROUP_TABLE))
				gl.GroupPlots(nStartPlotIndex);
			
			return (nn | RP_NEED_RESCALE);
		}
		return 0;
	}
	*/
	///end MR_DOES_NOT_PLOT_SORUCE_DATA
	
	//virtual
	int GetDataMode() { return INPUTDATA_RANGES;}
	
	//virtual 
	string	GetResultCurveSheetName(TreeNode& trOperation, int nIndex = 0, int nSheetType = OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET)
	{
		string strSheetName;
		if(nSheetType == OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET)
		{
			/// Iris 01/26/2007 v8.0548 UPDATE_DESIGN_BY_MAX
			//DataRange 	dr;
			//GetInput(dr);	
			//
			//string	strIndep, strDep;
			//get_fit_data_label(dr, strIndep, strDep, trOperation.GUI.Fit.FixIntercept.nVal, nIndex);
				//strSheetName = strIndep;
			strSheetName = _LE(E_STR_MR_PARTIAL_SHEET_NAME);
			///end UPDATE_DESIGN_BY_MAX
		}
		else
		{
			strSheetName = WksReportOperation::GetResultCurveSheetName(trOperation, nIndex, nSheetType);
		}
		
		return strSheetName;
		
	}
	///Arvin 11/20/06 MR_WRONG_NUMBER_PARTIAL_REGRESSION_PICTURE
	//virtual 
	string GetReportGraphLabel(TreeNode& trOp, int nGraphIndex, int nPicRow, int nPicCol) 
	{ 
		string		strLabel;
		int			nPicIndex = nPicRow * GetReportGraphTableColNum(trOp, nGraphIndex) + nPicCol;
		if(nPicIndex >= GetTotalNumPictureForOneGraphType(trOp, nGraphIndex))
			return strLabel; //return error

		if(GRAPH_MR_PARTIAL_REGRESSION == nGraphIndex)
		{
			DataRange 	dr;
			GetInput(dr);	
			
			string		strIndep, strDep;
			///Arvin 02/14/07 WRONG_LABEL_WHEN_FIX_INTERCEPT
			//get_fit_data_label(dr, strIndep, strDep, trOp.GUI.Fit.FixIntercept.nVal, nPicIndex);
			bool bFixIntercept = trOp.GUI.Fit.FixIntercept.nVal;
			if(bFixIntercept)
				get_fit_data_label(dr, strIndep, strDep, bFixIntercept, nPicIndex+1);
			else
				get_fit_data_label(dr, strIndep, strDep, bFixIntercept, nPicIndex);
			///END WRONG_LABEL_WHEN_FIX_INTERCEPT
			
			strLabel = strDep + " vs. " + strIndep;	
		}
		else if(GRAPH_RESIDUALS_SCATTER == nGraphIndex)
		{
			strLabel = "X" + (nPicIndex+1);
		}	

		return strLabel;		
	}
	
	//MR can not do residual plots successfully, so we hide this branch temporarily
	int ConstructGraphNumber()
	{
		return 7;  
	}
	
	BOOL Construct(TreeNode& trOp, int nOption = 0)
	{
		if( FitRegression::Construct(trOp, nOption) )
		{	
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE		
			//----- Iris 01/27/2007 v8.0548
			// Move Fitted Curve check box to Fit Options -> Quantities Branch
			// Should put these codes inside UpdateGUIGraphs, but fail to remove XDataType branch, so put here
			TreeNode	trFitCurves = GetGUIGraphNodes(trOp, GRAPH_FIT_CURVE);
			TreeNode 	trQuantities = trOp.GUI.Quantities;
			if(trFitCurves && trQuantities)
			{
				trFitCurves.Reset(true);
			
				TreeNode 	trNewFitCurves = trQuantities.AddNode("Temp");
				trNewFitCurves.Replace(trFitCurves.Clone());
				trFitCurves.Remove();
				
				trNewFitCurves.SetAttribute(STR_LABEL_ATTRIB, _L("Fitted Values"));
				trNewFitCurves.nVal = 1; ///Arvin 04/06/07 v8.0596 SET_DEFAULT_CHECK_OUTPUT_FIT_CURVES
				trNewFitCurves.ID = TRGP_CHECK;
				trNewFitCurves.RemoveAttribute(STR_USE_ATTRIB);
				trNewFitCurves.RemoveAttribute(STR_REPEAT_ID_ATTRIB);
			}
			//-----
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE

			// Add PartialCurves to store the DATA of Partial Curve 
			TreeNode trRC = trOp.ResultCurves;
			trOp.InsertNode(trRC, "PartialCurves");
			trOp.PartialCurves.ID = IDST_MR_PARTIAL_CURVE;
			
			///Cheney 2007-8-31 QA70-10330 CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//trOp.GUI.OutPut.PlotSettings.Show = false;
			OP_GUI_GRAPH_ARRANGEMENT_NODE(trOp.GUI).Show = false;
			///end OP_DLG_NEW_STRUCTURE
			trOp.GUI.OutPut.RCSheet.Show = false;
			///end CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
			
			///Cheney 2007-8-31 QA70-10330 CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
			//should set it to 1 for MR
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//trOp.GUI.Output.PlotSettings.GraphNumCols.nVal = 1;	
			OP_GUI_GRAPH_ARRANGEMENT_NODE(trOp.GUI).GraphNumCols.nVal = 1;
			///end OP_DLG_NEW_STRUCTURE
			///end CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
			
			return TRUE;
		}
		return FALSE;
	}
	///END MR_WRONG_NUMBER_PARTIAL_REGRESSION_PICTURE
	
	/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
#ifdef OP_DLG_TOTALLY_NEW_STRUCTURE	
//virtual
	void	RebuildFitCurvePlotOptions(TreeNode& trOp)
	{	
		TreeNode	trFitCurves = GetGUIGraphNodes(trOp, GRAPH_FIT_CURVE);
		ASSERT(trFitCurves);
		while(trFitCurves.GetNodeCount()>0)
			trFitCurves.FirstNode.Remove();
		trFitCurves.ID = TRGP_CHECK;		
		trFitCurves.RemoveAttribute(STR_USE_ATTRIB);
		trFitCurves.nVal = 1;
		trFitCurves.SetAttribute(STR_LABEL_ATTRIB, _L("Fitted Values"));
	}
	///end OP_DLG_NEW_STRUCTURE
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE
	
	//virtual 
	void 	UpdateGUIGraphs(TreeNode& trOp)
	{
		FitRegression::UpdateGUIGraphs(trOp);
		
		// Move Partial Plots into Plots Branch from Create Branch
		TreeNode 	trPartial = GetGUIGraphNodes(trOp, GRAPH_MR_PARTIAL_REGRESSION);
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode 	trResiduals = trOp.GUI.Residuals;
		TreeNode 	trResiduals = OP_GUI_BRANCH_OF_RESIDUAL_PLOTS_CHECKBOX(trOp.GUI);
		ASSERT(trResiduals);
		///End OP_DLG_NEW_STRUCTURE
		TreeNode 	trNewPartial = trResiduals.InsertNode(trResiduals.FirstNode, "Temp");
		trNewPartial.Replace(trPartial.Clone());
		trNewPartial.nVal = 0; 
		trNewPartial.ID = TRGP_CHECK;
		trNewPartial.RemoveAttribute(STR_USE_ATTRIB);
		trNewPartial.RemoveAttribute(STR_REPEAT_ID_ATTRIB);
		trPartial.Remove();
		
		//Change the Label from Residuals to Plots for Graphs branch
		trResiduals.SetAttribute(STR_LABEL_ATTRIB, _L("Plots"));
	
	}
	
	///Arvin 01/22/06 REMOVE_SUB_NODES_OF_PARTIAL_REGRESSION by Max's suggestion
	///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
	//int GetCurveLineColor(const TreeNode& trOp, int nCurveIndex) 
	int GetCurveLineColor(const TreeNode& trOp, int nCurveIndex, int nDataIndex, bool bIsSourceGraph) 
	///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
	{
		if(nCurveIndex == GRAPH_MR_PARTIAL_REGRESSION)
			return 2; //The color is red
		///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
		//return WksReportOperation::GetCurveLineColor(trOp, nCurveIndex); 
		return WksReportOperation::GetCurveLineColor(trOp, nCurveIndex, nDataIndex, bIsSourceGraph); 
		///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
	}
	
	///Arvin 01/24/06 REMOVE_SUB_NODES_OF_FIT_CURVE_AND_MOVE_IT_TO_QUANTITIES_BRANCH by Max's suggestion
	bool	IsCreateReportGraph(TreeNode& trOp, int nGraphIndex = -1)
	{
		if(nGraphIndex == GRAPH_FIT_CURVE)
			return false;
		
		return WksReportOperation::IsCreateReportGraph(trOp, nGraphIndex);
	}
	/// Iris 01/17/2007 v8.0543 CORRECT_THE_WAY_TO_GET_DATA_LABEL
	/*
	///Arvin 11/28/06 GET_Y_COLUMN_STRING
	void GetOneInputColString(int index, int nCol, string& strCol)
	{
		DataRange rngInput;
		GetInput(rngInput);
		if(!rngInput)
			error_report("Get input data rang failed!");
		
		int r1, r2, c1, c2;
		Worksheet sourceWks;
		string strRange;
		int colNum;
		int numRange = rngInput.GetNumRanges();
		for( int ii = 0; ii < numRange; ii++)
		{
			rngInput.GetRange(ii, r1, c1, r2, c2, sourceWks, &strRange);
			bool bY = strRange.Compare("Y") == 0 ? true : false;
			if(bY)
			{
				colNum = c1;
				break;
			}
		}
		Column col(sourceWks, colNum);
		if(col)
		{
			col.GetRangeString(strCol);
			strCol.Replace("Col(", "");
			strCol.Replace(")", "");
			strCol = GetAnalysisName()+ " of " + strCol;
		}
	}
	///END GET_Y_COLUMN_STRING
	*/
	///end CORRECT_THE_WAY_TO_GET_DATA_LABEL
public:
	
	///Arvin 12/12/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	bool GetAllTypeResidualData(const TreeNode &trOp, const vector& vX, const vector& vRegularRes, vector& vStand, vector& vStud, vector& vStudDel, int index = 0, int nPeak = 0, vector &vY = NULL, vector &vWeights = NULL, matrix &mXs = NULL)
	{
		TreeNode		trGUI = trOp.GUI;
		TreeNode		trFit = trGUI.Fit;
		
		LROptions		sLROptions;
		sLROptions = trGUI.Fit;
		sLROptions.Confidence = trGUI.Quantities.Parameters.Confidence.dVal; 
		sLROptions.Confidence /= 100;		
		
		int				nNumCols = mXs.GetNumCols();
		trOp.Input.nParams.nVal = nNumCols + 1; 		
		int nSizeFitParams = nNumCols + 1;
		
		FitParameter	sFitParameter[MAX_MR_PARAMS + 1];	
		RegStats		sRegStats;
		RegANOVA		sRegANOVA;
		RegCalcInternal	sReg;
		vector vSerr;
		vector vH;
		int nRet = stats_multiple_linear_regression(mXs, vY, vWeights, sLROptions, &sFitParameter, nSizeFitParams, &sRegStats, &sRegANOVA, NULL, NULL, vH, vSerr);
		if(nRet != STATS_NO_ERROR)
			return false;
		
		int nNumPts = mXs.GetNumRows();
		int nCols = mXs.GetNumCols();
		matrix mx = mXs;
		mx.SetSize(nNumPts, nCols+1, true);
		vector vTemp(nNumPts);
		vTemp = 1;
		mx.SetColumn(vTemp, nCols);
		int nParam = nSizeFitParams;
		vStand.SetSize(nNumPts); vStud.SetSize(nNumPts); vStudDel.SetSize(nNumPts);
		vector vCook(nNumPts), vAtkinson(nNumPts);
		nRet = ocmath_diagnostic_residuals(nNumPts, nParam, sRegStats.ReducedChiSq, vRegularRes.GetSize(), vRegularRes, mx, vStand, vStud, vStudDel, vCook, vAtkinson, vH);
		if (nRet != STATS_NO_ERROR)
				return false;
		
		return true;
	}
	///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	///Iris 4/21/05 MAKEFITY_SUPPORT_MULTI_REGRESSION
	bool MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* sFitParameter, const matrix& mXs, int nPeak)
	{
		int nNumRow = mXs.GetNumRows();
		if(nNumRow != 0)
		{
			vFitY.SetSize(nNumRow);
			
			int nNumParams = GetParameters(trOp);
			for(int nRow=0; nRow<nNumRow; nRow++)
			{
				mXs.GetRow(vFitX, nRow);				
				
				vFitY[nRow] = sFitParameter[0].Value;
				for(int ii = 1; ii < nNumParams; ii++)
					vFitY[nRow] += (vFitX[ii-1]) * sFitParameter[ii].Value;				
				
			}
		}	
			
		return true;
	}
	///end MAKEFITY_SUPPORT_MULTI_REGRESSION
	
	/// Iris 01/26/2007 v8.0548 UPDATE_MR_DESIGN_BY_MAX
	/*
	void  DoAllResultsCurveSheet(TreeNode& trOperation, int nTotalNumData, Worksheet& wksInputFirstRange, Worksheet& wksOutput,Worksheet& wksFitCurve, bool bCreateResultsCurveSheet, bool bCreateResidualCurveSheet)
	{
		WksReportOperation::DoAllResultsCurveSheet(trOperation, nTotalNumData, wksInputFirstRange, wksOutput,wksFitCurve, bCreateResultsCurveSheet,bCreateResidualCurveSheet);

		Worksheet 	wksPartialFitCurve;
		TreeNode 	trCurveBranch = trOperation.GUI.Output.PartialCurves;
		string 		str;
		int 		nType = str_to_predefined_type(trCurveBranch.Book.strVal, &str);		
		if(nType != PDS_NEW)
			wksPartialFitCurve = wksFitCurve;
		
		string		strResultsCurveBook, strResultsCurveSheet;
		for(int nDataIndex = 0; nDataIndex < GetTotalNumPictureForOneGraphType(trOperation, GRAPH_MR_PARTIAL_REGRESSION); nDataIndex++)  /// Iris 9/30/06 ONE_DATA_ONE_REPORT_BOOK
		{	
			if(nDataIndex > 0)
			{
				WorksheetPage wp;
				wksPartialFitCurve.GetParent(wp);
				trCurveBranch.Book.strVal = STR_EXISTING + wp.GetName();
			}
			
			/// Iris 01/19/2007 v8.0544 OPTION_ON_OUT_RESULT_CURVE_SHEET_SEPARATELY_OR_NOT
			//if ( !doResultsCurveSheet(trOperation, trCurveBranch, wksInputFirstRange, nDataIndex, strResultsCurveSheet, strResultsCurveBook, &wksOutput, OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET, &wksPartialFitCurve) )
			if ( !doResultsCurveSheet(trOperation, trCurveBranch, wksInputFirstRange, nDataIndex, strResultsCurveSheet, strResultsCurveBook, OUTPUT_PARTIAL_REGRESSION_CURVES_SHEET, false, &wksOutput, &wksPartialFitCurve) )
			///end OPTION_ON_OUT_RESULT_CURVE_SHEET_SEPARATELY_OR_NOT
				error_report("Fail to report result curve sheet");
		}
				
	}
	*/
	///end UPDATE_MR_DESIGN_BY_MAX
	
	//virtual 
	///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	//bool GetYFromX(const vector& vx, vector& vy, int nOuputIndex, TreeNode& trOp, const matrix& mXs)
	bool GetYFromX(const vector& vx, vector& vy, int nOuputIndex, TreeNode& trOp, const matrix& mXs, int nPeaks = 1, vector& vParams = NULL)
	///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	{
		vector<string> vsNames;
		int nParams = GetParameters(trOp, 0, vsNames);
		
		///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
		//vector vParams;
		vector  vParamstemp;
		vParamstemp.SetSize(nParams);
		///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
		
		if(getFitParams(vParamstemp, nParams, nOuputIndex, trOp))
		{
			vector vtemp(mXs.GetNumCols());
			double dtemp;
			vtemp = 1;
			vy = 0;
			for (int ii = 0; ii< nParams + 1; ii++)
			{
				dtemp = vParamstemp[ii];	
				vy += vtemp * dtemp;				
				mXs.GetColumn(vtemp, ii);
			}
			
			///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
			if(vParams)
				vParams = vParamstemp;
			///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
			return true;
		}
		return false;
	}
	
private:
	bool getFitParams(vector& vParams, int nParams, int nOuputIndex, TreeNode& trOp = NULL)
	{
		if(NULL == trOp)
			GetTree(trOp);
		
		Tree trParams;
		if(!GetFitParameters(trOp, trParams))
			return error_report("GetYFromX failed to get Parameters tree");
		
		if ( nParams < 1 )
			return false;
		
		vParams.SetSize(nParams);
		
		FitParameter	sFitParameter[MAX_MR_PARAMS + 1];		// max num parameters (9 + 1 for constant term)
		if(GetFitParameters(trOp, trParams, nOuputIndex, sFitParameter, MAX_MR_PARAMS + 1) == nParams)
		{
			for (int ii = 0; ii < nParams; ii++)
				vParams[ii] = sFitParameter[ii].Value;
			
			return true;
		}
		return false;
	}
	
	
private:
	int 	m_nPartialPlots; /// Iris 10/18/05 WORK_MORE_ON_PARTIAL_PLOTS the number of partial plots
	vector  m_vWeights; /// Thomas 5/24/2006 ADD_CONF_AND_PRED_BANDS_FOR_MLR
	int		m_nNumXs; //CPY 11/17/06 MR_COMPILE_ERR_DUE_TO_WRONG_DATA_MEMBER
}; 	  

