/*------------------------------------------------------------------------------*
 * File Name: FitterOperation.h													*
 * Creation: YuI 11/25/2002													    *
 * Purpose: Origin C header	for Operation class and other related functions		*
 * Copyright (c) OriginLab Corp.2002											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY 2/13/04 2/16/04 O8_OPERATION_REDO_USING_NEW_WORKBOOK					*
 *	ML 3/3/2004 RANGE_BASED_REGRESSIONS											*
 *	CPY 6/25/04 COMBINE_LR_PR_CODES_TO_REGRESS_CLASS							*
 *	ML 8/17/2004 QA70-6825 RLOG_QUERY											*
 *	Max 9/09/04 MODIFY_FIXINTERCEPT												* 
 *	ML 9/15/2004 QA70-6904 BETTER_BAD_WEIGHT_TREATMENT							*
 *  Iris 9/23/04 ADD_COV_AND_CORR_REPORT										*
 *	ML 10/7/2004 MULTIPLE_DATASET_OPER_TREATMENT								*
 *  Iris 10/08/04 SET_ANOVA_TABLE_ISTABLE_TO_TRUE								*
 *	CPY 10/14/04 QA70-7029 COR_CORR_USE_MATRIX									*
 *	ML 10/20/2004 QA70-7075 MASKED_DATA_REPORTING								*
 *	ML 12/17/2004 PROGRAMMATICALLY_PUTTING_A_REPORT_TABLE_INTO_A_GRAPH			*
 *  Iris 12/23/04 QA70-7135 INSERT_FORMULA_TO_SOURCE_GRAPH						*
 *	CPY 12/31/04 PICTURE_IN_REPORT_IN_BASE_CLASS								*
 *  Iris 4/12/05 MOVE_CURVE_OPTION_TO_EACH_GRAPH								*
 *  Iris 4/14/05 FIX_INCORRECT_FIT_CURVES_ID									*
 *  Iris 4/18/05 ADD_SUB_TABLE_FOR_RESIDUAL_TABLE								*
 *  Iris 4/18/05 FIX_NLSF_CONF_PREDI_BAND_NOT_WORK								*
 *  Iris 4/21/05 MAKEFITY_SUPPORT_MULTI_REGRESSION								*
 *  Iris 4/16/05 GUI_GRAPH_NODE_IF_NEED_PLOTINFO								*
 *  Iris 5/23/05 UPDATE_FIT_GRAPHS_NAME											*
 *	ML 6/1/2005 STYLE_LINKS_WITH_OFFSETS										*
 *  Iris 06/21/05 FIX_FITTED_LINE_COLOR_PROBLEM									*
 *	ML 7/20/2005 FITTING_FUNCTION_FORMULA_IN_REPORT								*
 *  Iris 7/27/05 UPDATE_FITTED_CURVE_OPTIONS									*
 *  Iris 8/15/05 QA70-8015 ADD_Y=0_TO_RESIDUAL_PLOTS							*
 *	Kevin 08/31/05 ADD_CUSTOM_TABLE_TO_REPORT_TABLE								*
 * CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
 *	Kevin 10/14/05 ADD_ELLIPSE_GRAPH_FOR_LR										*
 *	Kevin 10/19/05	SEPARATE_SETUP_FITTING_PLOT_DETAILS_TO_ONE_FUNCTION			*
 *	Kevin 11/01/05	CHANGE_COL_NAME_CAUSE_DP_NAME_CHANGE						*
 *  Iris 11/15/05 QA70-3479-P3 SETUP_FIT_GRAPH_X_AXIS							*
 *  Jim 2/22/06 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH         		*
 *  Thomas 04/06/2006 ADD_FIT_CURVE_INDEX_PAR_FOR_SETUPFITTINGCURVESPLOTDETAILS *
 *	ML 4/28/2006 FRIENDLY_CUSTOM_TABLE_THEME_GENERATION							*
 *  Thomas 05/30/2006 ADD_SETREPORTWORKSHEETDESIGNATION_FOR_FITTTEROPERATION	*
 *  Alex 06/05/06 MODIFY_MULTIPLE_REGRESSION_CLOSE_PLOT_BRANCH                  *
 *	ML 6/7/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY								*
 *  Thomas 06/08/06 MOVE_ANOVA_CHECK_BOX_TO_QUANTITIES_BRANCH					*
 *  Alex 06/14/06 SET_ANOVA_TABLE_OPEN                                          *
 *	CPY 7/14/06 FIT_LR_LEGEND_MUTL_PLOTS_ALL_SHOW_AS_FIT_CURVE					*
 *	ML 7/21/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA
 *	ML 8/10/2006 MULTIPLE_COLUMNS_IN_OUTPUT_FIND_XY								*
 *	ML 8/10/2006 REMOVING_CUSTOM_TABLE_FROM_GUI									*
 *	Cheney 2006-8-31 ADD_CAL_REPLICA_DATA										*
 *	Cheney 2006-9-1 ADD_FOR_FIT_LINARE_CONCATENATE_PLOT_TYPE					*
 *	Cheney 2006-9-1 ADD_AVERAGE_DATA											*
 *	Cheney 2006-9-13 NOT_PLOT_SRCDATA_WHEN_CONCATENATE_AND_PLOTTYPE_IS_MEAN_SE_OR_SD
 *	Cheney 2006-9-18 ADD_FOR_FIT_LINARE_DATA_MODE								*
 *  Joseph 09/18/06 MOVE_CALIBRATION_TABLE_OUT_OUTPUT							*
 *	ML 9/18/2006 DATARANGE_EXTRACTION_APPARENT_FIT								*
 *	ML 9/20/2006 RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT					*
 *	Jasmine 09/20/06 QA70-8973 MODIFICATION_OUTPUT_BRANCH						*
 *	Jasmine 09/26/06 SEP_RESIDUAL_CURVE_SHEET									*
 *	Jasmine 09/27/06 DISABLE_CALIBRATION_OUTPUT_IF_UNCHECK						*
 *	ML 10/2/2006 NLFIT_CURVES_CLEANUP											*
 *	Cheney 2006-10-10 CONCATENATE_IS_ONE_METHOD_OF_AVERAGE						*
 * 	Arvin 10/17/06 FITTING_CLASS_SHOULD_INHERIT_FORM_STATSOPBASE				*
 *  Arvin 10/23/06 FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED					*
 *	Arvin 10/23/06 FITTING_RESIDUALS_HISTOGRAM_PLOT								*
 *	Cheney 2006-11-1 CHANGE_sReg_FROM_REF_TO_POINTER							*
 *	ML 11/13/2006 THEME_DIGITS_PARAMETERS_TBL									*
 *	Cheney 2006-12-1 CLEAN_CODE													*	
 *	ML 12/18/2006 CALLING_OPERATION_FROM_OC_LT									*
 *	ML 1/25/2007 INCORRET_I1_WHEN_EXTRACTING_FINDXY_OGW							*
 *	Arvin 02/13/07 ADD_X_DATA_TO_RESIDUAL_DATA_TABLE							*
 *	ML 2/14/2007 QA70-9374 BAD_EVENT_HANDLER_DWORDS_IN_TREENODES				*
 *	Cheney 2007-3-21 IF_AUTO_UPDATE_SHOULD_KEEP_1ST_COL_OF_FINDXY_SHEET			*
 *	Arvin 23/03/07 HISTOGRAM_AND_BOX_CHART_PLOT_WRONG_IN_STATSONCOLUMN_AND_NORMALITY_TEST
 *	Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y			*
 *	Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX					*
 *	Cheney 2007-4-12 CLEAR_DATA_MODE_IN_NOTES_TABLE_WHEN_CHANGE_PARAMS			*
 *	Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE			*
 *	Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA*
 *	Cheney 2007-4-24 SHOULD_SET_ONLY_ONCE_EVENT_HANDLER_IN_ONE_TREENODE			*
 *	Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT				*
 *	Cheney 2007-5-29 SHOULD_KEEP_EXIST_LEGEND_FORMAT_WHNE_UPDATE_SRC_GRAPH		*
 *	ML 6/1/2007 LEGEND_INCORRECT_FIX											*
 *	Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT		*
 *	Arvin 07/18/07 v8.0662 FIT_COMPARISION_OF_DATASETS_INCONSISTENT_BETWEEN_NLFIT_AND_LR
 *	Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES			*
 *	Arvin 08/03/07 WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA				*
 *  Iris 08/06/2007 v8.0674 X_DATA_TYPE_JUST_EFFECT_ON_XFITDATA_NOT_CHANGE_AXIS_TYPE*
 *	Arvin 08/10/07 QA70-10197 ADD_NONE_OPTION_FOR_ERROR_AS_WEIGHT_IN_LR_PR_AND_MR
 *	Cheney 2007-8-23 QA70-10290 FITCURVE_AND_REPORT_SHOULD_BE_SAME_BOOK_IF_SRC_DATA_FROM_DIFF_BOOK
 *	Cheney 2007-9-28 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_INTO_THEME_AS_MAX_SAID*
 *	TD 10-04-2007 QA80-10478 LOCALISED_REPORTTREE_ISSUE							*
 *	Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR	*
 *	Arvin 10/23/07 QA70-10559-P2 RESIDUAL_LAG_PLOT_USE_WRONG_TEMPLATE			*
 *	Arvin 10/23/07 QA70-10559-P2 RESIDUAL_VERSUS_ORDER_PLOT_USE_WRONG_PLOT_TYPE	*
 *	Arvin 10/23/07 QA70-10559-P3 SHOULD_NOT_CREATE_EMPTY_SHEET_WHEN_UNCHECK_ALL_RESIDUALS_CHECK_BOX
 *	Jasmine 11/05/07 SUBTRACT_BASELINE_BEFORE_PFM_FIT							*
 * 	Arvin 11/09/07 NLFIT_REPORT_GRAPH_NEED_RESCALE_WHILE_PART_GRAPH_SELECTION_AS_INPUT
 *	Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION								*
 *	YuI 11/19/07 QA70-10716 GUI_LOCALIZATION_ON_CHANGE_PARAM					*
 *	Arvin 12/24/07 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_DATATYPE_ATTRIB_INTO_THEME
 *	Arvin 12/25/07 MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL as cp said			*
 *	Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said					*
 *	Arvin 01/03/08 SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS as cp said
 *	Arvin 01/07/08 QA70-10903 ADD_CHECK_ALL_BOX_FOR_BRANCH						*
 *	Folger 01/09/08 SUPPORT_SKIP_ALL_CPP_COMMENTS								*
 *	Arvin 01/28/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS				*
 *	Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
 *	Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS		*
 *	Folger 03/19/08 QA80-10598 NEW_GETN_LOCALIZAED_CHECK_MACRO					*
 *	Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said	*
 *	Hong 04/10/08 v8.0840c PEAK_FIT_REPORT_PEAK_CHARACTERISTICS_TO_SEPARATE_SHEET
 *  Iris 5/04/2008 QA80-11503 CHANGE_PARAM_CHANGED_SOURCE_PLOTS_COLOR			*
 *	Hong 08/12/08 QA80-11986 FIX_FITTED_CURVE_PLOT_FAIL_RESCALE_WHEN_SOURCE_PLOT_HAVE_ERR_BAR
 *	Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT					*
 *	Sophy 10/27/2008 v8.961 QA80-12453 ADD_REDUCED_CHI_SQR_QUANTITY_OUTPUT_FOR_REGRESSION_FIT
 *	Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
 *	Kyle 11/18/2008 QA80-12591 ADD_MORE_OPTION_FOR_INPUT_DATA_TYPE_IN_FITTING_TOOLS
 *  Iris 11/19/2008 v8.0975 QA80-12591-P1 FIX_APPARENT_FIT_MISS_DATA_WHOSE_LOGARITHM_IS_NEGATIVE*
 *  Iris 11/19/2008 v8.0975 QA80-12591-P2 FIX_APPARENT_FIT_ON_GRAPH_CUSTOM_RANGE_GET_INCORRECT_X*
 *  Iris 11/20/2008 v8.0975d QA80-12591-S1 CENTRALIZE_NEW_X_DATA_TYPE_AND_LOG_TYPE_CODES*
 *	Hong 11/27/08 QA80-12677 v8.0980d FIX_REPLICA_FAIL_GET_CORRECT_Y_FROM_X		*
 *	Folger 12/01/08 v8.0981 MORE_ON_USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
 *	Sophy 12/9/2008 v8.0983c QA80-12745 ARRANGE_ALL_SAME_PLOTS_IN_ONE_GRAPH_SHOULD_RESCALE_BY_ALL_PLOTS
 *	Folger 12/11/08 QA80-12766 v8.0985 SIGNIFICANT_DIGITS_FAILS_TO_APPLY_TO_NLSF_FITTING_REPORT
 *	Jack 12/19/2008 QA80-12329 MULTI_INDEP_DEPS_BAND_CALCULATION				*
 *	Folger 12/22/08 QA80-12766-P2 v8.0990 SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
 *	Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT				*
 *	Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION		*
 *	Sophy 12/29/2008 v8.0991b QA80-12832 SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS
 *	Sophy 1/15/2009 v8.0957 QA80-12918 FITCURVE_X_COLULMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA
 *	YuI 03/05/09 QA70-13220 WHOLE_WORKSHEET_INPUT_XYRANGE						*
 *  Iris 3/16/2009 QA80-13285-P1 FIX_DUPLICATE_RESIDUAL_DATA_REPORT_FOR_DIFF_RESIDUAL_REPORT_AND_PLOT 
 *	Folger 03/23/09 PA_FAILS_TO_MAKE_CORRECT_RESIDUAL_PLOT_WHEN_HAS_ONLY_ONE_PEAK
 *  Iris 4/14/2009 QA80-12786-P1 FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT	*
 *  Iris 4/29/2009 QA80-12017 NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ
 *	Folger 07/01/09 QA80-13774-P1 COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
 *	Folger 07/07/09 NANOSIZER_PARAMETER_SHARE_INFO_NOT_SHOW_CORRECTLY_IN_REPORT	*
 *	Hong 07/07/09 QA80-13881 FIX_FITTED_CURVE_WRONG_COLOR_IN_REPORT_SHEET_OF_CONCATENATE_FIT
 *	Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
 *	Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT			*
 *  Iris 9/24/2009 QA80-11710-P3 ALL_PLOTS_ARE_RED_IN_RESIDUAL_GRAPH_WHEN_PLOT_IN_ONE_GRAPH
 *  Iris 10/26/2009 FIX_FIT_LINEAR_PLOT_RESIDUAL_HISTOGRAM_IN_ONE_LAYER			*
 *  Iris 11/24/2009 QA81-3224-P4 FIX_WEIGHT_NOT_CORRECT_IN_NOTES_TABLE_FOR_LR_WITH_XERR
 *	Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
 *	Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU				*
 *	Folger 03/19/10 QA81-15218 ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
 *	Folger 03/24/10 QA81-15218-P2 SHOULD_TAKE_CARE_OF_ERROR_WHEN_SWITCH_TO_LINEAR_FIT
 *	Folger 04/15/10 QA81-15315 NLFIT_SHOULD_CHANGE_OUTPUT_GRAPH_AXIS_SCALE_IF_MANUAL
 *  Iris 5/28/2010 ORG-188 FIX_MR_NOT_REPORT_FITTED_CURVE_DATA					*
 *  Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG							*
 *  Iris 7/12/2010 ORG-300-P2 FIX_LCL_UCL_PLOT_COLOR_NOT_SAME_BUG				*
 *	Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
 *  Iris 8/27/2010 ORG-907 LR_NEED_CHECK_ZERO_ERROR_BAR							*
 *	Sophy 8/31/2010 ORG-945-P1 FITTING_OPERATIONS_FROM_QUICK_FIT_FAIL_TO_DETECT_WEIGHT_METHOD
 *	Sophy 9/13/2010 ORG-1037-S1 NO_APPARENT_FIT_FOOTNOTE_WHEN_BOTH_XY_AXES_LINEAR_ON_SRC_GRAPH
 *------------------------------------------------------------------------------*/
#ifndef _FITTEROPERATION_H   
#define _FITTEROPERATION_H

///Cheney 2007-5-29 SHOULD_KEEP_EXIST_LEGEND_FORMAT_WHNE_UPDATE_SRC_GRAPH
#include <..\originlab\graph_utils.h>
///end SHOULD_KEEP_EXIST_LEGEND_FORMAT_WHNE_UPDATE_SRC_GRAPH

enum 
{
	REPORT_ROW_FUNC_NAME, 
	REPORT_ROW_CHISQR, 
	REPORT_ROW_PARAM_BEGIN
};

///Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
enum
{
	WEIGHT_HAS_NAGETIVE_VALUE = 0x01,
	WEIGHT_HAS_MISSING_VALUE  = 0x02,
	WEIGHT_HAS_ZERO_VALUE = 0x04, /// Iris 8/27/2010 ORG-907 LR_NEED_CHECK_ZERO_ERROR_BAR
};
///END CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES

///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
struct FITPARAMSINFO
{
	vector<string>	*pvsParamNames;
	vector<string>	*pvsParamNamesPostfix;
	vector<string>	*pvsParamUnits;
};
///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT

///Cheney 2006-11-13 MOVE_IT_INTO_ANALYSIS.H
/////Cheney 2006-9-1 ADD_FOR_FIT_LINARE_CONCATENATE_PLOT_TYPE
//enum 
//{
	//PLOT_TYPE_RAW_DATA, 
	//PLOT_TYPE_MEAN_SD,
	//PLOT_TYPE_MEAN_SE
//};
/////end ADD_FOR_FIT_LINARE_CONCATENATE_PLOT_TYPE

/////Cheney 2006-9-18 ADD_FOR_FIT_LINARE_DATA_MODE
//enum 
//{
	//DATA_MODE_INDEP_CONSOLID,
	//DATA_MODE_INDEP_SEP,
	//DATA_MODE_CONCATENATE
//};
/////end ADD_FOR_FIT_LINARE_DATA_MODE
///end MOVE_IT_INTO_ANALYSIS.H

/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
/*
enum
{
	GRAPH_FIT_CURVE = 0,  //Fit curve always is 0
	GRAPH_RESIDUALS_SCATTER, 
	GRAPH_RESIDUALS_HISTOGRAM,
	GRAPH_RESIDUALS_VERSUS_FITS_PLOT,
	GRAPH_RESIDUALS_VERSUS_ORDER_PLOT,
	//GRAPH_PARTIAL_REGRESSION_PLOTS, /// Iris 10/18/05 WORK_MORE_ON_PARTIAL_PLOTS move it to FitMR since the graph only in MR
	
	GRAPH_FITTING_MAX_NODES_IN_REPORT		//the size of this enum
};
*/
/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES

/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
// moved to RangeEx.h
/*
///Iris 10/20/05 MOVE_ALL_FITTING_RELATED_TO_FITTER_OPERATION
#define STR_FIT_CURVES_TABLE				"FitCurves" 
#define STR_RESIDUALS_SCATTER_TABLE			"ResidualsScatter"
#define STR_RESIDUALS_HISTOGRAM_TABLE		"ResidualsHistogram"
#define STR_RESIDUALS_FIT_GRAPH_TABLE 		"ResidualsFit"
#define STR_RESIDUALS_ORDER_GRAPH_TABLE 	"ResidualsOrder"
///End MOVE_ALL_FITTING_RELATED_TO_FITTER_OPERATION
*/
/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES

///Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
#define STR_ATTRIB_DERIVED_PARAM			"derived_param"
///end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y

///Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
#define STR_FOOTNOTE_HAS_MASKED		_L("Some input data points are masked.")
#define	STR_FOOTNOTE_HAS_MISSING	_L("Some input data points are missing.")
///end ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA

#define STR_DIFF_RESIDUALS_DATA_TABLE	"DiffTypeResidual"

typedef int (* P_WKS_REPORT_PARAMS)(Worksheet& wks, int nRow, const TreeNode& trParams, const TreeNode& trCols);

///Cheney 2007-5-29 SHOULD_KEEP_EXIST_LEGEND_FORMAT_WHNE_UPDATE_SRC_GRAPH
//Link Error, so use find function
///Arvin 06/07/07 CHANGE_LEGEND_TO_USE_LONG_NAME_AND_UNIT as max's suggestion
//typedef bool (* FUNC_GL_INT)(GraphLayer& gl, int nPlot);
///Arvin 07/19/07 USE_STRING_TYPE_LEGEND_DIRECTLY as CP said
//typedef bool (* FUNC_GL_INT)(GraphLayer& gl, int nPlot, int nLegendType);
typedef bool (* FUNC_GL_INT)(GraphLayer& gl, int nPlot, LPCSTR lpcszExtraFormat, LPCSTR lpcszSep = NULL);
///end USE_STRING_TYPE_LEGEND_DIRECTLY
///end CHANGE_LEGEND_TO_USE_LONG_NAME_AND_UNIT
///end SHOULD_KEEP_EXIST_LEGEND_FORMAT_WHNE_UPDATE_SRC_GRAPH

#define MAX_MR_PARAMS	100 //------ CPY 7/17/04 FIT_PARAM_ARRAY_NEED_SIZE
//--- CPY 7/19/04 
#define GETN_OPERATION_STYLE GETN_OPTION_GRIDLINE(flexGridFlatVert) GETN_OPTION_EDIT_ALIGN("0|0|0");
//---

#define	MAX_PEAKS_FITTING		100

///Iris 11/24/2009 QA81-3224-P5 FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM_MORE
// moved from FitLinear.cpp
#define STR_FIT_LINEAR_TYPE		"FitLinearType" /// Iris 10/26/2009 QA81-14512-P1 FIX_NOT_SHOW_FLATOUT_MENU_FOR_FIT_LINEAR_WITH_XERR
enum
{
	FIT_LINEAR_NO_X_ERROR,
	FIT_LINEAR_WITH_X_ERROR,
};
///End FIX_ERRBARWEIGHT_IS_ENABLE_WHEN_CHANGE_PARAM_MORE

///Jasmine 09/27/06 DISABLE_CALIBRATION_OUTPUT_IF_UNCHECK
bool on_check_calibration_branch_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg)
{
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE_OUTPUT_PART		
	TreeNode trCalibration, trBranch1, trBranch2;
	trCalibration = tree_get_node(tr, nRow).Parent();
	if(trCalibration)
	{
		trBranch1 = trCalibration.Custom2;
		trBranch2 = trCalibration.Custom3;
		TreeNode trOutput =  tree_get_node_by_tagname(tr, "Output", true);
		///Arvin 12/25/07 MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL as cp said
		//Need support m_trNFO
		if(!trOutput)
		{
			TreeNode trRoot = tr.Parent();
			if(trRoot)
				trOutput =  tree_get_node_by_tagname(trRoot, "Output", true);
		}
		///end MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL
		trOutput = trOutput.FindXY;
		///Arvin 01/09/06 FIND_Z_FROM_XY
		//When current operation is "Find Z from X Y", trBranch1 and trBranch2 are NULL,
		//and trCalibration should be tree_get_node(tr, nRow), and trCalibration has not sub-branch trBranch1 and trBranch2.  
		if(!trBranch1 && !trBranch2)
		{
			trCalibration = tree_get_node(tr, nRow);
			if(trCalibration.Use&& trOutput)
			{
				trOutput.Enable = true;
				trOutput.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
			}
			else
			{
				trOutput.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_KEEP_SIZE_ON_COLLAPSE);
				trOutput.Enable = false;	
			}
			return true;
		}
		///end FIND_Z_FROM_XY
		if(trBranch1.Use + trBranch2.Use && trOutput)
		{
			trOutput.Enable = true;
			trOutput.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
		}
		if(!(trBranch1.Use + trBranch2.Use) && trOutput)
		{
			trOutput.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_KEEP_SIZE_ON_COLLAPSE);
			trOutput.Enable = false;
		}
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE_OUTPUT_PART
	}
	return true;
}
///End DISABLE_CALIBRATION_OUTPUT_IF_UNCHECK

///Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
/// Iris 8/27/2010 ORG-907 LR_NEED_CHECK_ZERO_ERROR_BAR
//bool    check_bad_data_for_weight(const TreeNode& trGUI, int& nBadDataMsg) 
bool    check_bad_data_for_weight(const TreeNode& trGUI, int nWeightMethods, int& nBadDataMsg) 
///End LR_NEED_CHECK_ZERO_ERROR_BAR
{
	DWORD dwRules = DRR_DEPERR_TO_WEIGHT | DRR_GET_DEPENDENT | DRR_NO_FACTORS;
	if(trGUI.Fit.ApparentFit && trGUI.Fit.ApparentFit.nVal)
		dwRules |= DRR_APPARENT;
		
	DataRange drData;
	TreeNode trRange = trGUI.InputData;
	nBadDataMsg = 0;
	if(trRange)
	{
		drData.Create();
		drData.SetTree(trRange, DRTREE_DEFAULT);
		int nNumData = drData.GetNumData(dwRules);
		for(int ii = 0; ii < nNumData; ii++)
		{
 			vector  vY, vX, vWeights;
 			STGETDATAOUTPUTINFO stOutInfo;
 			int   nn = drData.GetData(dwRules, ii, NULL, NULL, &vY, &vX, NULL, NULL, &vWeights, NULL, NULL, NULL, NULL, NULL, &stOutInfo);
			if(vWeights.GetSize() <= 0)
				continue;
				
			if( !(nBadDataMsg & WEIGHT_HAS_MISSING_VALUE) )
			{		
				if(stOutInfo.nCountMissingErrorValuesFound > 0)
					nBadDataMsg |= WEIGHT_HAS_MISSING_VALUE;
			}
				
			if(!(nBadDataMsg & WEIGHT_HAS_NAGETIVE_VALUE))
			{
				if(stOutInfo.nCountNegativeErrorValuesFound > 0)
					nBadDataMsg |= WEIGHT_HAS_NAGETIVE_VALUE;
			}
			
			/// Iris 8/27/2010 ORG-907 LR_NEED_CHECK_ZERO_ERROR_BAR
			/*
			if((nBadDataMsg & WEIGHT_HAS_MISSING_VALUE) && (nBadDataMsg & WEIGHT_HAS_NAGETIVE_VALUE))
				break;
			*/
			if(!(nBadDataMsg & WEIGHT_HAS_ZERO_VALUE))
			{				
				if(stOutInfo.nCountZeroErrorValuesFound > 0)
					nBadDataMsg |= WEIGHT_HAS_ZERO_VALUE;
			}
			
			if( ERRBARWEIGHT_INSTRUMENTAL == nWeightMethods )
			{
				if((nBadDataMsg & WEIGHT_HAS_MISSING_VALUE) && (nBadDataMsg & WEIGHT_HAS_ZERO_VALUE))
					break;				
			}
			
			if( ERRBARWEIGHT_DIRECT_WEIGHTING == nWeightMethods )
			{
				if((nBadDataMsg & WEIGHT_HAS_MISSING_VALUE) && (nBadDataMsg & WEIGHT_HAS_NAGETIVE_VALUE))
					break;				
			}	
			///End LR_NEED_CHECK_ZERO_ERROR_BAR
		}
			
		return true;
	}
		
	return false;			
}
	
bool check_get_weight_data_err_msg(const TreeNode& trGUI, string& strErrMsg)
{
	int nBadDataMsg;
	int nWeightMethod = trGUI.Fit.ErrBarWeight.nVal;
	/// Iris 8/27/2010 ORG-907 LR_NEED_CHECK_ZERO_ERROR_BAR
	//if(check_bad_data_for_weight(trGUI, nBadDataMsg))
	if(check_bad_data_for_weight(trGUI, nWeightMethod, nBadDataMsg))
	///End LR_NEED_CHECK_ZERO_ERROR_BAR
	{
		/// Iris 8/27/2010 ORG-907 LR_NEED_CHECK_ZERO_ERROR_BAR
		/*
		///Arvin 08/10/07 QA70-10197 ADD_NONE_OPTION_FOR_ERROR_AS_WEIGHT_IN_LR_PR_AND_MR
		//if(nWeightMethod && (nBadDataMsg&WEIGHT_HAS_MISSING_VALUE))
		if(nWeightMethod == ERRBARWEIGHT_INSTRUMENTAL && (nBadDataMsg&WEIGHT_HAS_MISSING_VALUE))		
		///end ADD_NONE_OPTION_FOR_ERROR_AS_WEIGHT_IN_LR_PR_AND_MR
			return ocu_load_msg_str(CER_VALUE_UNCOMPATIBLE_WITH_WEIGHT_METHOD, &strErrMsg, _L("Instrumental"), NULL, _L("missing value"));
		*/
		if(nWeightMethod == ERRBARWEIGHT_INSTRUMENTAL && ((nBadDataMsg&WEIGHT_HAS_MISSING_VALUE)||(nBadDataMsg&WEIGHT_HAS_ZERO_VALUE)) )
			return ocu_load_msg_str(CER_VALUE_UNCOMPATIBLE_WITH_WEIGHT_METHOD, &strErrMsg, _L("Instrumental"), NULL, _L("missing value or zero"));
		///End LR_NEED_CHECK_ZERO_ERROR_BAR
		
		///Arvin 08/10/07 QA70-10197 ADD_NONE_OPTION_FOR_ERROR_AS_WEIGHT_IN_LR_PR_AND_MR	
		//if(!nWeightMethod && ((nBadDataMsg&WEIGHT_HAS_MISSING_VALUE)||(nBadDataMsg&WEIGHT_HAS_NAGETIVE_VALUE)))
		if(nWeightMethod == ERRBARWEIGHT_DIRECT_WEIGHTING && ((nBadDataMsg&WEIGHT_HAS_MISSING_VALUE) || (nBadDataMsg&WEIGHT_HAS_NAGETIVE_VALUE)))
		///end ADD_NONE_OPTION_FOR_ERROR_AS_WEIGHT_IN_LR_PR_AND_MR
			return ocu_load_msg_str(CER_VALUE_UNCOMPATIBLE_WITH_WEIGHT_METHOD, &strErrMsg, _L("Direct Weighting"), NULL, _L("nagetive or missing value"));
	}
	
	return false;
}
///end CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
	
///Arvin 05/21/07 INPUT_DATA_CHANGE_CAN_NOT_TRIGGER_EVENT_FUNCTION_IN_MR
bool on_input_data_change(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nCntrlType, WndContainer& getNContainer);
///end INPUT_DATA_CHANGE_CAN_NOT_TRIGGER_EVENT_FUNCTION_IN_MR

///Arvin 11/09/07 NLFIT_REPORT_GRAPH_NEED_RESCALE_WHILE_PART_GRAPH_SELECTION_AS_INPUT
//Just a temporary solution
/*
bool _is_need_expand(double dDataFrom, double dDataTo, double& dScaleFrom, double& dScaleTo)
{
	bool bNeedExpand = false;
	if(dDataFrom < dScaleFrom)	{ bNeedExpand = true; dScaleFrom = dDataFrom;}
	if(dDataTo > dScaleTo)	{ bNeedExpand = true; dScaleTo = dDataTo;}
	return 	bNeedExpand;
}

bool _is_need_shrink(double dDataFrom, double dDataTo, double dScaleInc, double& dScaleFrom, double& dScaleTo)
{
	double dLower, dUpper, dMedian, dMargin;
	dMargin = (dScaleTo - dScaleFrom)*0.08;
	dLower = (dScaleFrom + dScaleInc) + dMargin;
	dUpper = (dScaleTo - dScaleInc) - dMargin;
	dMedian = (dScaleTo + dScaleFrom)/2.0;
	bool bNeedShrink = false;
	if(dDataFrom > dLower && dDataTo < dUpper)	
	{ 
		bNeedShrink = true; 
		dScaleFrom = dDataFrom; dScaleTo = dDataTo;
	}
	if(dDataFrom >= dMedian)
	{ 
		bNeedShrink = true; dScaleFrom = dDataFrom;
	}
	
	if(dDataTo <= dMedian) 				
	{ 
		bNeedShrink = true; dScaleTo = dDataTo;
	}
	
	return bNeedShrink;
}
*/
bool  rescale_graph_layer_by_plot(DataPlot& dp, DataRange& drSrc, bool bFitCurvePlot, DWORD dwRules)
{
	if(!dp.IsValid())
		return false;
	
	GraphLayer gl;
	dp.GetParent(gl);
	if(!gl.IsValid())
		return false;
	
	DataRange dr;
	if(!dp.GetDataRange(dr))
		return false;
	
	/// Iris 4/14/2009 QA80-12786-P1 FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT
	//double x1, x2, y1, y2, dx, dy;
	double x1, x2, y1, y2;
	///end FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT
	if(!get_data_range_xy_scale(dr, x1, x2, y1, y2, dwRules))
		return false;
	
	//---- Iris 11/20/2008 v8.0975d QA80-12591-S1 CENTRALIZE_NEW_X_DATA_TYPE_AND_LOG_TYPE_CODES
	//dx = get_min_max_inc(x1, x2, false,0.08, 10);
	//dy = get_min_max_inc(y1, y2, false,0.08, 8);
	/// Iris 4/14/2009 QA80-12786-P1 FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT
	// no need compute increment, but need to round min and max
	//dx = get_min_max_inc(x1, x2, SCALE_TYPE_LINEAR, 0.08, 10);
	//dy = get_min_max_inc(y1, y2, SCALE_TYPE_LINEAR, 0.08, 8);
	get_min_max_inc(x1, x2, SCALE_TYPE_LINEAR, 0.08);
	get_min_max_inc(y1, y2, SCALE_TYPE_LINEAR, 0.08);
	///end FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT
	//----
	if(drSrc) 
	{
		double dx1, dx2, dy1, dy2;
		if(get_data_range_xy_scale(drSrc, dx1, dx2, dy1, dy2, dwRules))
		{
			if(dy1 < y1) { y1 = dy1;}
			if(dy2 > y2) { y2 = dy2;} 
		}
	}
	/// Iris 4/14/2009 QA80-12786-P1 FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT
	//double dxFrom, dxTo, dyFrom, dyTo, dxInc, dyInc;
	//dxInc = dx; dyInc = dy;
	double dxFrom, dxTo, dyFrom, dyTo;
	///end FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT
	if(!bFitCurvePlot)
	{
		dxFrom = gl.X.From; dxTo  = gl.X.To; 
		dyFrom = gl.Y.From; dyTo  = gl.Y.To;
		if(x1 < dxFrom)	{ dxFrom = x1;}
		if(x2 > dxTo)	{ dxTo = x2;}
		if(y1 < dyFrom)	{ dyFrom = y1;}
		if(y2 > dyTo)	{ dyTo = y2;}
	}
	else
	{
		dxFrom = x1; dxTo = x2;
		dyFrom = y1; dyTo = y2;
	}
	
	///------ Folger 04/15/10 QA81-15315 NLFIT_SHOULD_CHANGE_OUTPUT_GRAPH_AXIS_SCALE_IF_MANUAL
	//gl.X.From = dxFrom;
	//gl.X.To = dxTo;
	set_axis_scale_properties(gl.X, &dxFrom, &dxTo, NULL);
	///------ End NLFIT_SHOULD_CHANGE_OUTPUT_GRAPH_AXIS_SCALE_IF_MANUAL
	//gl.X.Inc = dxInc; /// Iris 4/14/2009 QA80-12786-P1 FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT, keep original steps just as plot line on GUI
	///------ Folger 04/15/10 QA81-15315 NLFIT_SHOULD_CHANGE_OUTPUT_GRAPH_AXIS_SCALE_IF_MANUAL
	//gl.Y.From = dyFrom;
	//gl.Y.To = dyTo;
	set_axis_scale_properties(gl.Y, &dyFrom, &dyTo, NULL);
	///------ End NLFIT_SHOULD_CHANGE_OUTPUT_GRAPH_AXIS_SCALE_IF_MANUAL
	//gl.Y.Inc = dyInc;	/// Iris 4/14/2009 QA80-12786-P1 FIX_TOO_DENSE_TICK_LABEL_FOR_DATA_TYPE_INPUT, keep original steps just as plot line on GUI
	return true;
}
///end 	NLFIT_REPORT_GRAPH_NEED_RESCALE_WHILE_PART_GRAPH_SELECTION_AS_INPUT

/// Iris 4/30/2008 QA80-10442 WANT_REMEMBER_X_DATA_TYPE_IN_THEME
/////Arvin 12/24/07 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_DATATYPE_ATTRIB_INTO_THEME
//void  remove_datatype_attrib_from_theme(TreeNode& trGUI);
/////end XDATATYPE_SHOULD_NOT_SAVE_DATATYPE_ATTRIB_INTO_THEME
///end WANT_REMEMBER_X_DATA_TYPE_IN_THEME

///Cheney 2007-4-24 SHOULD_SET_ONLY_ONCE_EVENT_HANDLER_IN_ONE_TREENODE	
/////Cheney 2006-9-7 ADD_DATA_MODE_EVENT 
//static bool _fit_curv_data_mode_even(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nCntrlType, WndContainer& getNContainer)
//{
	//TreeNode trInputData = tr.InputData; 
	//if( !trInputData )
		//return false;
	//
	//int nReportControl;
	//trInputData.GetAttribute(STR_USE_ATTRIB, nReportControl);
//
	////find graph node
	//TreeNode trGraph;
	//if(tr.DataID == IDST_INPUT_DATA_OPTIONS) //in NLF, variable tr is InputData tree node
	//{
		//TreeNode trGUI = tr.Parent();
		//if(trGUI)
			//trGraph = trGUI.FittedCurve.Graph1;
	//}
	//else
		//trGraph = tr.Graph1;
	//
	//if(!trGraph)
		//return false;
	//
	////if Concatenate, PlotType node will show
	////else not show it.
	//if(trGraph.PlotType)
	//{
		//int nAttrib = (nReportControl == DATA_MODE_CONCATENATE) ? 1 : 0;
		//trGraph.PlotType.SetAttribute(STR_SHOW_ATTRIB, nAttrib);
	//}
	//
	//return true;
//}
/////end ADD_DATA_MODE_EVENT
///end SHOULD_SET_ONLY_ONCE_EVENT_HANDLER_IN_ONE_TREENODE

/// Iris 4/29/2009 QA80-12017 NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ
#define VER_FITTER_OP 			2.0
#define STR_OP_NAME_FITTER_OP  "FitterOperation"
///end NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ

///Arvin 10/17/06 FITTING_CLASS_SHOULD_INHERIT_FORM_STATSOPBASE
////class	FitterOperation	: public WksReportOperation
class	FitterOperation	: public StatsOpBase
///END FITTING_CLASS_SHOULD_INHERIT_FORM_STATSOPBASE
{	
public:
	/// Iris 4/29/2009 QA80-12017 NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ
//	#ifdef INSERT_NEW_REPORT_ENTRY_IN_OLD_OPJ_WHEN_RECALCULATE
	FitterOperation()
	{
		m_mvCur.AddVersion(STR_OP_NAME_FITTER_OP, VER_FITTER_OP);
	}
//	#endif //INSERT_NEW_REPORT_ENTRY_IN_OLD_OPJ_WHEN_RECALCULATE
	///end NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ
protected:
	/// Iris 11/09/2009 QA81-14599 IMPROVE_STATS_ON_COLS_CALCULATION_SPEED
	//virtual
	TreeNode GetGUIGraphNodesEx(const TreeNode& trGUI, int nGraphIndex)
	{
		TreeNode trGraph = WksReportOperation::GetGUIGraphNodesEx(trGUI, nGraphIndex);
		if( trGraph )
			return trGraph;
		
		if( GRAPH_FIT_CURVE == nGraphIndex )
		{
			/// Iris 5/28/2010 ORG-188 FIX_MR_NOT_REPORT_FITTED_CURVE_DATA
			//return OP_GUI_FITCURVE_PLOT_CHECKBOX(trGUI);
			trGraph = OP_GUI_FITCURVE_PLOT_CHECKBOX(trGUI);
			if( !trGraph )
				trGraph = trGUI.Quantities.Graph1;
			ASSERT(trGraph);
			return trGraph;
			///End FIX_MR_NOT_REPORT_FITTED_CURVE_DATA
		}
		else
		{
			TreeNode trResiduals = OP_GUI_BRANCH_OF_RESIDUAL_PLOTS_CHECKBOX(trGUI);
			return trResiduals.GetNode(op_get_graph_tag_name(nGraphIndex));
		}
	}
	
	bool	IsPlotStatsGraph(TreeNode& trOp)
	{
		TreeNode trResidual = GetGUIGraphNodes(trOp, GRAPH_RESIDUALS_HISTOGRAM);
		if( trResidual && trResidual.nVal )
			return true;
		return false;
	}
	///end IMPROVE_STATS_ON_COLS_CALCULATION_SPEED

	/// Iris 4/29/2009 QA80-12017 NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ
	//virtual
	void		GUIOnUpdateTreeBeforeRunning(const MultipleVersion& mvOld, TreeNode &trGUINew, TreeNode &trGUIOriginal, TreeNode& trOperation);
	///end NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ

	/// TD 10-04-2007 QA80-10478 LOCALISED_REPORTTREE_ISSUE
	///Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said
	//TreeNode	stats_tree_add_Parameters(const string &strDataLabel, bool bDataLabelAsTableMainHeader, TreeNode &trOp, int index, const FitParameter* pFitParams, vector<string> &vstrParamNames, vector<string>& vstrParamNamesPostfix, vector<string> &vstrFactors, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0);
	///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	//TreeNode	stats_tree_add_Parameters(const string &strDataLabel, bool bDataLabelAsTableMainHeader, TreeNode &trOp, int index, const FitParameter* pFitParams, vector<string> &vstrParamNames, vector<string>& vstrParamNamesPostfix, vector<string> &vstrFactors, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0, vector<bool> &vbIsShared = NULL);
	TreeNode	stats_tree_add_Parameters(const string &strDataLabel, bool bDataLabelAsTableMainHeader, TreeNode &trOp, int index, const FitParameter* pFitParams, const FITPARAMSINFO& stParamInfo, vector<string> &vstrFactors, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0, vector<bool> &vbIsShared = NULL);
	///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	///end ADD_STAR_MARK_FOR_SHARED_PARAMS
	
	///------ Folger 12/22/08 QA80-12766-P2 v8.0990 SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
	////------ Folger 12/11/08 QA80-12766 v8.0985 SIGNIFICANT_DIGITS_FAILS_TO_APPLY_TO_NLSF_FITTING_REPORT
	//virtual	int	GetSignDigitsArray(vector<int>& vnSignDigits)		{ return 0; }
	////------
	virtual	int	GetSignDigitsArray(vector<int>& vnSignDigits, int nDataIndex = 0)		{ return 0; }
	///------ End SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
	
	virtual string	getTranslatedParamStr(LPCSTR lpcszParam){return lpcszParam;}
	/// end LOCALISED_REPORTTREE_ISSUE
	virtual void ConstructAddBeforeQuantitiesToCompute(TreeNode& trGUI) {}
	//---- CPY 10/17/04 SEPARATE_FIT_CURVE_INTO_SEPARATE_BRANCH
	//virtual
	int GetResultCurvesID() { return IDST_REPORT_CURVE_OPTIONS;}	
	//----
	/// Iris 9/13/06 QA70-8973 REPORT_RESIDUAL_DATA_IN_SEP_REPORT_SHEET
	int		GetResidualCurvesID()	{ return IDST_RESIDUAL_CURVE_OPTIONS; }
	///End REPORT_RESIDUAL_DATA_IN_SEP_REPORT_SHEET
	int GetFindXYID(){ return IDST_FIND_XY_OPTIONS;}///Jasmine 09/20/06 QA70-8973 MODIFICATION_OUTPUT_BRANCH, add FindXY output branch 
	//---------------------------------------------------------------
	virtual int GetDataMode() { return INPUTDATA_CURVES; }
	
	/// Iris 04/03/2007 RESET_DATA_MODE_AFTER_APPLIED_THEME_AND_CHOOSE_DATA
	//virtual
	/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
	//BOOL	OperationtoGUI(TreeNode& trOperation, bool bInit, string* pstrSelectedTheme = NULL, bool bSetDefaultInputOnInit = true);
	///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	//BOOL	OperationtoGUI(TreeNode& trOperation, bool bInit, string* pstrSelectedTheme = NULL, bool bSetDefaultInputOnInit = true, bool bFromHotkey = false);
	BOOL	OperationtoGUI(TreeNode& trOperation, bool bInit, string* pstrSelectedTheme = NULL, bool bSetDefaultInputOnInit = true, DWORD dwExeCtrl = 0, DWORD dwParam = 0);
	///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
	void	CheckResetFitMode(TreeNode& trOperation);
	///end RESET_DATA_MODE_AFTER_APPLIED_THEME_AND_CHOOSE_DATA

	/// YuI 11/19/07 QA70-10716 GUI_LOCALIZATION_ON_CHANGE_PARAM
	// virtual
	int		getLocUpdateInputDataStringsMode()
				{ return LUIDMODE_DEFAULT;}
	/// end GUI_LOCALIZATION_ON_CHANGE_PARAM

	//virtual
	///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	//DWORD GetOutputOptions()
	virtual DWORD GetOutputOptions(const TreeNode& trOp)
	///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	{
		DWORD dwOptions = REPORT_GRAPH_PLOT_INFO | REPORT_KEEP_SESSION_GRAPH | REPORT_PASTE_RESULT_TABLES_TO_GRAPH | REPORT_RESULT_CURVE_OPTION | REPORT_ARRANGE_GRAPHS_TO_COLS;
		return dwOptions;
	}

	/// Iris 2/25/2008 v8.0811 MAKE_FIT_CURVE_PLOT_AND_DATA_HAVE_SEPARATE_CONTROL
	//virtual 
	bool	IsCreateReportGraph(TreeNode& trOp, int nGraphIndex = -1)
	{
		/// Iris 8/28/2008 QA80-12105 FIX_MULTI_INDEP_INCORRECT_RESIDUAL_PLOTS
		TreeNode trGraph = GetGUIGraphNodes(trOp, nGraphIndex);
		if( trGraph && !trGraph.Show )
			return false;
		///end FIX_MULTI_INDEP_INCORRECT_RESIDUAL_PLOTS
		
		if(GRAPH_FIT_CURVE == nGraphIndex)
		{
			//TreeNode trGraph = GetGUIGraphNodes(trOp, nGraphIndex); /// Iris 8/28/2008 QA80-12105 FIX_MULTI_INDEP_INCORRECT_RESIDUAL_PLOTS
			
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE
			if(trGraph && trGraph.DoPlot)
			{
				if(!tree_is_true(trGraph))
					return false;
				else 
					return tree_is_true(trGraph.DoPlot);
			}
			else
				return tree_is_true(trGraph);
#else //OP_DLG_TOTALLY_NEW_STRUCTURE
			TreeNode trIsPlot = OP_GUI_FITCURVE_PLOT_CHECKBOX(trOp.GUI);
			if(trIsPlot)
			{
				if(!tree_is_true(trGraph))
					return false;
				else 
					return tree_is_true(trIsPlot);
			}
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE
		}
		
		return StatsOpBase::IsCreateReportGraph(trOp, nGraphIndex);

	}
	///end MAKE_FIT_CURVE_PLOT_AND_DATA_HAVE_SEPARATE_CONTROL
	
	/// Iris 5/26/2008 QA80-11607 v8.0870 FIT_CURVE_NOT_PLOT_ON_SOURCE_IF_NOT_PLOT_IN_REPORT
	//virtual 
	bool	IsPlotOnSourceGraph(TreeNode& trOp, int nGraphIndex = -1)
	{
		if(GRAPH_FIT_CURVE == nGraphIndex)
		{
			TreeNode trGraph = GetGUIGraphNodes(trOp, nGraphIndex);
			if(trGraph && trGraph.PlotFit && trGraph.PlotFit.Enable && trGraph.PlotFit.Show )
			{
				return tree_is_true(trGraph.PlotFit);
			}			
		}
		return StatsOpBase::IsPlotOnSourceGraph(trOp, nGraphIndex);
	}
	///end FIT_CURVE_NOT_PLOT_ON_SOURCE_IF_NOT_PLOT_IN_REPORT
	
	///Cheney 2007-10-15 QA70-10522-P4 CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING 
	/////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;
		//TreeNode trInput = trOp.GUI.InputData;
		//DataRange dr;
		//dr.Create(trInput, FALSE);
		//if( !dr.IsValid() )
			//return strBook;
		//
		//DataRange drSub;
		//dr.GetSubRange(drSub, GetDataRules(trOp), 0);
		//if( !drSub.IsValid() || drSub.GetNumRanges() == 0)
			//return strBook;
		//
		//Worksheet wks;
		//drSub.GetParent(wks);
		//if(!wks)
			//return strBook;
		//
		//strBook = WksReportOperation::GetSourcePageName(trOp, wks);
		//return strBook;
	//}
	/////end FITCURVE_AND_REPORT_SHOULD_BE_SAME_BOOK_IF_SRC_DATA_FROM_DIFF_BOOK
	///end CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING
	
	//virtual
	BOOL Construct(TreeNode& trOperation, int nOption = 0)
	{
		if( WksReportOperation::Construct(trOperation, nOption) )
		{
			//GETN_OPERATION(trGUI)
			//GETN_OPERATION_STYLE
			///Iris 01/20/05 CONSTRUCT_GUI_CLEANUP
			//TreeNode trGUI = ConstructGUI();
			TreeNode	trGUI = ConstructAddGUI(trOperation);
			///end CONSTRUCT_GUI_CLEANUP
			
			/// ML 7/20/2005 FITTING_FUNCTION_FORMULA_IN_REPORT
			/// Iris 02/28/2007 REORDER_ROWS_IN_NOTES_TABLE, by Max's suggestion
			//trOperation.Calculation.Notes.Equation.ID = IDE_NOTES_EQUATION; 
			TreeNode trAU = trOperation.Calculation.Notes.AutoUpdateMode;
			if(trAU)
				trOperation.Calculation.Notes.InsertNode(trAU, "Equation", IDE_NOTES_EQUATION);
			else
				trOperation.Calculation.Notes.Equation.ID = IDE_NOTES_EQUATION;
			///end REORDER_ROWS_IN_NOTES_TABLE
			/// end FITTING_FUNCTION_FORMULA_IN_REPORT
			
			/// Iris 8/16/08 v8.0863 REMOVE_DATA_MODE_LIST_FOR_MR
			//tree_construct_add_input_branch(trGUI);
			tree_construct_add_input_branch(trGUI, GetDataMode());
			/// ML 2/14/2007 QA70-9374 BAD_EVENT_HANDLER_DWORDS_IN_TREENODES
			/*
			PEVENT_NODE_FUNC fnEvent = _fit_curv_data_mode_even;
			DWORD dwFnEvent = (DWORD)fnEvent;
			string strEvent = dwFnEvent;
			
			TreeNode trInputData = trGUI.InputData;
			trInputData.SetAttribute(STR_ATTRIB_HANDLER_RC, strEvent);
			*/
			///Cheney 2007-4-24 SHOULD_SET_ONLY_ONCE_EVENT_HANDLER_IN_ONE_TREENODE
			setTreeInputEvent(trGUI.InputData);
			//TreeNode trInputData = trGUI.InputData;
			//GETN_SET_EVENT_EX_HANDLER(trInputData, _fit_curv_data_mode_even)
			///end SHOULD_SET_ONLY_ONCE_EVENT_HANDLER_IN_ONE_TREENODE
			/// end BAD_EVENT_HANDLER_DWORDS_IN_TREENODES
			///end REMOVE_DATA_MODE_LIST_FOR_MR
			

			ConstructAddBeforeQuantitiesToCompute(trGUI);
			
			ConstructAddFitQuantitiesToCompute(trGUI);		
			
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE			
			///Arvin 12/08/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
			ConstructAddResidualAnalysisGUI(trGUI);
			///END ADD_RESIDUAL_ANALYSIS_FOR_FITTING
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE
			
			// prepare the basic tree nodes here
			TreeNode trOut = trOperation.Calculation; // Calculation node should have already been prepared in base class
			trOut.Parameters.ID = IDST_FIT_PARAMETER;
			
			trOut.RegStats.ID = IDST_REG_STATS_RESULTS;
			trOut.RegStats.SetAttribute(STR_LABEL_ATTRIB, _L("Statistics"));			
			
			trOut.Summary.ID = IDST_FIT_PARAMETERS_SUMMARY;/// Iris 01/09/2007 v8.0539 ADD_PARAMTERS_SUMMARY_TABLE
			
			/// Iris 01/19/2007 v8.0544 OPTION_ON_OUT_RESULT_CURVE_SHEET_SEPARATELY_OR_NOT
			//ConstructAddReportCommon(trOperation, REPORT_GRAPH_PLOT_INFO | REPORT_KEEP_SESSION_GRAPH | REPORT_PASTE_RESULT_TABLES_TO_GRAPH , IDST_REPORT_OPTIONS_LR, true);
			//DWORD dwOptions = REPORT_GRAPH_PLOT_INFO | REPORT_KEEP_SESSION_GRAPH | REPORT_PASTE_RESULT_TABLES_TO_GRAPH | REPORT_RESULT_CURVE_OPTION | REPORT_ARRANGE_GRAPHS_TO_COLS;
			///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
			//ConstructAddReportCommon(trOperation, GetOutputOptions(), IDST_REPORT_OPTIONS_LR, true);
			ConstructAddReportCommon(trOperation, GetOutputOptions(trOperation), IDST_REPORT_OPTIONS_LR, true);
			///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
			///end OPTION_ON_OUT_RESULT_CURVE_SHEET_SEPARATELY_OR_NOT
			
#ifdef OP_DLG_TOTALLY_NEW_STRUCTURE
			ConstructAddResidualAnalysisGUI(trGUI);
			if(IsReportCalibrationTable())
			{
				constructCalibrationBranch(trOperation); 		
			}
			ConstructAddReportGraphsOptions(trOperation, GetOutputOptions(trOperation));
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE	
		
#ifdef OP_DLG_TOTALLY_NEW_STRUCTURE_OUTPUT_PART
			RebuildOutputBranch(trOperation);
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE_OUTPUT_PART

			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			/*
			///Sophy 8/12/2008 QA80-12000-S3 DEFAULT_TURN_OFF_REPORT_MASKED_DATA_FOR_STATS_TOOL
			if( trGUI.Output.Create.MaskedData )
				trGUI.Output.Create.MaskedData.nVal = 1; //for fit, keep default value : turn on
			///end DEFAULT_TURN_OFF_REPORT_MASKED_DATA_FOR_STATS_TOOL
			///Sophy 8/12/2008 QA80-12000-S1 DEFAULT_TURN_OFF_REPORT_MISSING_DATA_FOR_STATS_TOOL
			if( trGUI.Output.Create.MissingData )
				trGUI.Output.Create.MissingData.nVal = 1; //for fit, keep default value : turn on
			///end DEFAULT_TURN_OFF_REPORT_MISSING_DATA_FOR_STATS_TOOL
			///Cheney 2007-8-31 QA70-10330 CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
			//should set it to 0, otherwise can not tell whether from theme or default
			trGUI.Output.PlotSettings.GraphNumCols.nVal = 1;	
			///end CLEAN_UP_PLOT_SETTING_BRANCH_IN_OUTPUT_RESULT_NODE
			*/			
			if( OP_GUI_OUTPUT_TABLES_BRANCH(trGUI).MaskedData )
				OP_GUI_OUTPUT_TABLES_BRANCH(trGUI).MaskedData.nVal = 1; //for fit, keep default value : turn on
			if( OP_GUI_OUTPUT_TABLES_BRANCH(trGUI).MissingData )
				OP_GUI_OUTPUT_TABLES_BRANCH(trGUI).MissingData.nVal = 1; //for fit, keep default value : turn on
			OP_GUI_GRAPH_ARRANGEMENT_NODE(trGUI).GraphNumCols.nVal = 1;
			///end OP_DLG_NEW_STRUCTURE
			
			//Construct Fitting Curve branch
			ConstructAddFitResultsOptionsCommon(GetGUIGraphNodes(trOperation, GRAPH_FIT_CURVE), nOption);
			
			FilterFittingGUI(trOperation);  // remove or move some options for each special tool			
			
			ConstructAddCommonBottom(trGUI);			

			trOut.ANOVAs.ID = IDST_ANOVA_TABLE;
			trOut.ANOVAs.SetAttribute(STR_LABEL_ATTRIB, STR_ANOVA_TABLE);
			
#ifndef SEPARATE_RESULT_CURVES_FROM_CALCULATION_BRANCH			
			trOut.FitCurves.ID = IDST_FIT_CURVES;
			trOut.FitCurves.SetAttribute(STR_LABEL_ATTRIB, _L("Fit Data"));
#endif			
			trOut.Covariance.ID = IDST_REG_COV_TABLE;
			trOut.Covariance.SetAttribute(STR_LABEL_ATTRIB, _L("Covariance"));
			trOut.Correlation.ID = IDST_REG_CORR_TABLE;
			trOut.Correlation.SetAttribute(STR_LABEL_ATTRIB, _L("Correlation"));
			return TRUE;
		}

		return FALSE;
	}
	

#ifdef OP_DLG_TOTALLY_NEW_STRUCTURE
	virtual void RebuildFitCurvePlotOptions(TreeNode& trOp);
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE

#ifdef OP_DLG_TOTALLY_NEW_STRUCTURE_OUTPUT_PART
	virtual void RebuildOutputBranch(TreeNode& trOp);
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE_OUTPUT_PART
	
	/// Iris 3/26/2008 v8.0832 CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS
	//virtual
	bool	InitOutputGUIManagerPointer(const TreeNode& trGUI)
	{
		if(m_pOutputManager)//already init
			return true;
		
		m_pOutputManager = new FitOutputGUIManager;	
		return (NULL != m_pOutputManager);		
	}
	///end CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS
	/// Sophy 5/05/2008 QA80-10934-P5 v8.0856 SUPPORT_SEPARATE_FINDXY_OUTPUT_SHEET_NAME
	//virtual
	TreeNode GetSheetNameNode( TreeNode& trBookSheetBranch, int nIndex)
	{
		if( 1 == nIndex )
			return trBookSheetBranch.SheetName2;
		return WksReportOperation::GetSheetNameNode( trBookSheetBranch, nIndex);
	}
	/// End SUPPORT_SEPARATE_FINDXY_OUTPUT_SHEET_NAME
	/// Sophy 5/07/2008 QA80-10934-P5 v8.0857 FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME
	virtual void SetFindXYOutputSheetDefaultName( TreeNode& trGUI)
	{
		TreeNode trOperation = trGUI.Parent();		
		
		/// Iris 11/03/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		/*
		SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET),0);
		SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET),1);
		*/
		TreeNode trFindXY = OP_GUI_OUTPUT_TO_FINDXY_BRANCH(trGUI);
		ASSERT(trFindXY);
		SetOneOutputBookSheetDefaultName(trGUI, trFindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET),0);
		SetOneOutputBookSheetDefaultName(trGUI, trFindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET),1);
		///end OP_DLG_NEW_STRUCTURE

	}
	/// End FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME
	/// Iris 4/01/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME_AFTER_CLEAN_OUTPUT_GUI_CODES
	//virtual 
	void SetOutputBookSheetDefaultName(TreeNode& trGUI)
	{
		WksReportOperation::SetOutputBookSheetDefaultName(trGUI);
		
		TreeNode	trOperation = trGUI.Parent();
		bool 		bSeparateSheetForDataset = IsSeparateSheetForDataset(trOperation);
		
		//Residual
		/// Iris 4/11/2008 SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.Residual, true, GetResultCurveBookFullName(trOperation, 0, OUTPUT_RESULT_CURVE_RESIDUAL_SHEET, bSeparateSheetForDataset));
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.Residual, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_RESIDUAL_SHEET));
		///Sophy 10/30/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.Residual, true, GetResultCurveBookShortName(trOperation, 0, OUTPUT_RESULT_CURVE_RESIDUAL_SHEET));
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.Residual, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_RESIDUAL_SHEET));
		TreeNode trResidual = OP_GUI_OUTPUT_TO_RESIDUAL_BRANCH(trGUI);
		SetOneOutputBookSheetDefaultName(trGUI, trResidual, true, GetResultCurveBookShortName(trOperation, 0, OUTPUT_RESULT_CURVE_RESIDUAL_SHEET));
		SetOneOutputBookSheetDefaultName(trGUI, trResidual, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_RESIDUAL_SHEET));
		///end OP_DLG_NEW_STRUCTURE
		///end SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK

		//FindXY
		/// Iris 4/11/2008 SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, true, GetResultCurveBookFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET, bSeparateSheetForDataset));
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET));
		///Sophy 10/30/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, true, GetResultCurveBookShortName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET));
		TreeNode trFindXY = OP_GUI_OUTPUT_TO_FINDXY_BRANCH(trGUI);
		SetOneOutputBookSheetDefaultName(trGUI, trFindXY, true, GetResultCurveBookShortName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET));
		///end OP_DLG_NEW_STRUCTURE
		/// Sophy 5/07/2008 QA80-10934-P5 v8.0857 FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME
		/*
		/// Sophy 5/05/2008 QA80-10934-P5 v8.0856 SUPPORT_SEPARATE_FINDXY_OUTPUT_SHEET_NAME
		//SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET));
		SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET),0);
		SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET),1);
		/// End SUPPORT_SEPARATE_FINDXY_OUTPUT_SHEET_NAME
		*/
		SetFindXYOutputSheetDefaultName( trGUI );
		/// End FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME
		
		///end SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK
		
	}
	///end ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME_AFTER_CLEAN_OUTPUT_GUI_CODES
	/// Hong 04/10/08 v8.0840c PEAK_FIT_REPORT_PEAK_CHARACTERISTICS_TO_SEPARATE_SHEET
	virtual string GetResultCurveDefBookName(TreeNode& trOperation, int nDataIndex = 0, int nOption = -1)
	{
		string		strBookName;
		switch(nOption)
		{
		case OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET:
			strBookName = STR_RESULT_CURVE_BOOK_LONG_NAME;
			break;
		case OUTPUT_RESULT_CURVE_RESIDUAL_SHEET:
			strBookName = STR_RESIDUAL_CURVE_BOOK_LONG_NAME;
			break;
		///Joseph 09/27/06 FINDXY_TO_SEPERATE_SHEET  
		//add the findxy data book name
		case OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET:
		case OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET:
			strBookName = STR_FINDXY_CURVE_BOOK_LONG_NAME;
			break;
		default:
			strBookName = _L("Curve Data");
			break;
		///Joseph FINDXY_TO_SEPERATE_SHEET
		}
		return strBookName;
	}
	// end PEAK_FIT_REPORT_PEAK_CHARACTERISTICS_TO_SEPARATE_SHEET
	//virtual 
	string GetResultCurveBookName(TreeNode& trOperation, int nDataIndex = 0, int nOption = -1, bool bSeparateSheetForDataset = false)
	{
		/// Iris 9/13/06 QA70-8973 REPORT_RESIDUAL_DATA_IN_SEP_REPORT_SHEET
		/// Hong 04/10/08 v8.0840c PEAK_FIT_REPORT_PEAK_CHARACTERISTICS_TO_SEPARATE_SHEET
		/*
		//return "Fit Curves";
		string		strBookName;
		switch(nOption)
		{
		case OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET:
			strBookName = "Fitted Data";
			break;
		case OUTPUT_RESULT_CURVE_RESIDUAL_SHEET:
			strBookName = "Residual Data";
			break;
		///Joseph 09/27/06 FINDXY_TO_SEPERATE_SHEET  
		//add the findxy data book name
		case OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET:
		case OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET:
			strBookName = "FindXY";//"XYOrYX Data";
			break;
		default:
			strBookName = "Curve Data";
			break;
		///Joseph FINDXY_TO_SEPERATE_SHEET
		}
		*/
		string		strBookName = GetResultCurveDefBookName(trOperation, nDataIndex, nOption);
		/// end PEAK_FIT_REPORT_PEAK_CHARACTERISTICS_TO_SEPARATE_SHEET
		if(bSeparateSheetForDataset)/// Iris 01/19/2007 v8.0544 OPTION_ON_OUT_RESULT_CURVE_SHEET_SEPARATELY_OR_NOT
		{
			string 	strData;
			GetEscapedMainDataString(trOperation, strData, nDataIndex+1); //+1 mean LT index, offset is 1
			ConvertEscapedString(strData);	
			if( !strData.IsEmpty() )
				strBookName = strData + " - " + strBookName;
		}
		
		return strBookName;
		///end REPORT_RESIDUAL_DATA_IN_SEP_REPORT_SHEET	
	}
	
	/// Iris 01/19/2007 v8.0543 NOT_SHOW_DATA_LABEL_ON_REPORT_SHEET_NAME, from Easwar's email
	/*
	/// Iris 2/06/06 QA70-8388 INDEP_DATA_CONSOLID_OR_SEP_REPORT
	//virtual
	string	GetResultSheetName() 
	{
		string 	strName = GetClassName();
		
		//will move the block of codes to one centralized place later
		Tree 	trOp;
		GetTree(trOp);		
		TreeNode 	trInputData = trOp.GUI.InputData;		
		
		if( MDINPUT_INDEPENDENT_SEPARATE == trInputData.Use) //if selection separate output, the output sheet name must contain column name
		{
			string strDataLabel;
			GetOneDataLabel(trOp, 0, 0, strDataLabel);
			ConvertEscapedString(strDataLabel);
			strName += "-" + strDataLabel; // change to LR-DataName
		}	
		
		return strName;	
	}  
	*/
	/// end NOT_SHOW_DATA_LABEL_ON_REPORT_SHEET_NAME
	
	/// Iris 4/23/2008 FIX_NO_FIND_XY_REPORT
	//virtual
	bool	AllowReportEmptyResultCurve()
	{
		return true; //find xy table is empty
	}
	///end FIX_NO_FIND_XY_REPORT
	
	///Cheney 2007-9-28 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_INTO_THEME_AS_MAX_SAID
	//virtual 
	void ThemeUpdateLastUsed(LPCSTR lpcszClassName, TreeNode& tr, bool bThemesTree = false);
	///end XDATATYPE_SHOULD_NOT_SAVE_INTO_THEME_AS_MAX_SAID
	
	///End INDEP_DATA_CONSOLID_OR_SEP_REPORT
	///Jasmine 09/26/06 SEP_RESIDUAL_CURVE_SHEET
	
	///Arvin 10/23/07 QA70-10559-P3 SHOULD_NOT_CREATE_EMPTY_SHEET_WHEN_UNCHECK_ALL_RESIDUALS_CHECK_BOX
	bool IsOutputAnyTypeResidualData(const TreeNode& trOp)
	{
		return GUIHasWhatTypeResidualTables(trOp, ANY_TYPE_RESIDUAL);
	}
	
	bool IsOutputAnyTypeResidualGraph(const TreeNode& trOp)
	{
		bool		bResScatter  = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_SCATTER);
		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);
		
		return      (bResScatter || bResHist || bResFit || bResOrder || bResLag);
	}
	///end SHOULD_NOT_CREATE_EMPTY_SHEET_WHEN_UNCHECK_ALL_RESIDUALS_CHECK_BOX
	
	bool IsOutputSeparateResidualCurveSheet(const TreeNode& trOp)
	{
		///Arvin 10/23/07 QA70-10559-P3 SHOULD_NOT_CREATE_EMPTY_SHEET_WHEN_UNCHECK_ALL_RESIDUALS_CHECK_BOX
		bool		bOutputResData		= IsOutputAnyTypeResidualData(trOp);
		bool		bOutputResGraph		= IsOutputAnyTypeResidualGraph(trOp);
		///end SHOULD_NOT_CREATE_EMPTY_SHEET_WHEN_UNCHECK_ALL_RESIDUALS_CHECK_BOX
		
		///Sophy 10/30/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode trResidual = trOp.GUI.Output.Residual;
		TreeNode trResidual = OP_GUI_OUTPUT_TO_RESIDUAL_BRANCH(trOp.GUI);
		///end OP_DLG_NEW_STRUCTURE
		if(!trResidual || !trResidual.Show || !trResidual.Enable)
			return false;
		int nSpecialType = str_to_predefined_type(trResidual.Sheet.strVal);
		///Arvin 10/23/07 QA70-10559-P3 SHOULD_NOT_CREATE_EMPTY_SHEET_WHEN_UNCHECK_ALL_RESIDUALS_CHECK_BOX
		//return PDS_NEW == nSpecialType || PDS_CUSTOM == nSpecialType;	
		return  (bOutputResData || bOutputResGraph) && (PDS_NEW == nSpecialType || PDS_CUSTOM == nSpecialType);	
		///end SHOULD_NOT_CREATE_EMPTY_SHEET_WHEN_UNCHECK_ALL_RESIDUALS_CHECK_BOX
	}	
	///End SEP_RESIDUAL_CURVE_SHEET
	bool IsOutputSeparateCalibrationSheet(const TreeNode& trOp, int nXfromY) 
	{
		/// Iris 9/30/06 CORRECT_OUT_SEP_CALIBATION_SHEET_LOGIC
		/*
		TreeNode trOutput = trOp.GUI.Output.FindXY;
		if(!trOutput || !trOutput.Show || !trOutput.Enable)
			return false;		
		
		/// YuI 09/29/06 don't know what to put here - does not compile. put _1 for now
		//TreeNode trCalibration = CALIBRATION_CURVE_BRANCH(trOp);
		TreeNode trCalibration = CALIBRATION_CURVE_BRANCH_1(trOp);
		/// end YuI 09/29/06 
		
		//if( !trCalibration || trCalibration.GetNodeCount() == 0 )
			//return false;
		return PDS_NEW == str_to_predefined_type(trOutput.Sheet.strVal);
		*/
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode 	trCalibration = trOp.GUI.Calibration;
		TreeNode 	trCalibration = OP_GUI_CALIBRATION_BRANCH(trOp.GUI);
		///end OP_DLG_NEW_STRUCTURE
		if(!trCalibration)
			return false;
		
		bool	bOutputXfromY = (trCalibration.FirstNode && trCalibration.FirstNode.Use)? true : false;
		bool	bOutputYfromX = (trCalibration.LastNode && trCalibration.LastNode.Use)? true : false;		
		if(1 == nXfromY)		
			return bOutputXfromY;
		else if(0 == nXfromY)
			return bOutputYfromX;
		else
			return bOutputXfromY || bOutputYfromX;
		
		return false;
		///end CORRECT_OUT_SEP_CALIBATION_SHEET_LOGIC		
	}
	/// Iris 9/21/06 QA70-8973 REPORT_RESIDUAL_DATA_IN_SEP_REPORT_SHEET
	//virtual 
	int	 GetOutputRangeIndex(TreeNode& trOp, int nGraphIndex)
	{
		int nOutputIndex = -1;
		if( GRAPH_FIT_CURVE == nGraphIndex)
		{
			nOutputIndex = OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET;
		}
		
		if( IsResidualGraph(nGraphIndex) )
		{
			nOutputIndex = IsOutputSeparateResidualCurveSheet(trOp)? OUTPUT_RESULT_CURVE_RESIDUAL_SHEET : OUTPUT_RESULT_CURVE_FIT_CURVES_SHEET;				
		}
		
		return nOutputIndex;
	}	
	///End REPORT_RESIDUAL_DATA_IN_SEP_REPORT_SHEET
	
	/// Iris 3/12/2009 CLEANUP_UpdateDataModeNode_CODES
	virtual string GetFitModeCombo()
	{
		return L_STR_FIT_REPORT_MODE_COMBO;
	}
	///end CLEANUP_UpdateDataModeNode_CODES
	
	///Arvin 01/03/08 SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS as cp said
	void UpdateDataModeNode(TreeNode& trOp, int nDataMode, int nTotalNumData)
	{
		if(nTotalNumData > 1 || MDINPUT_CMBND_SIMPLE == nDataMode)
		{
			TreeNode		trTable = GetTreeNode_Notes(trOp);
			if( trTable )
			{
				string		strCombo;
				/// Iris 3/12/2009 CLEANUP_UpdateDataModeNode_CODES
				//trOp.GUI.InputData.GetAttribute(STR_ATTRIB_BRANCH_COMBO, strCombo);
				if( !trOp.GUI.InputData.GetAttribute(STR_ATTRIB_BRANCH_COMBO, strCombo) )
					strCombo = GetFitModeCombo();
				///end CLEANUP_UpdateDataModeNode_CODES
				
				string		str = strCombo.GetToken(nDataMode, '|');
				if( !str.IsEmpty() )
				{			
					trTable.DataMode.strVal = str;
					trTable.DataMode.ID = IDE_NOTES_DATA_MODE;
					trTable.DataMode.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_DATA_MODE);
					trTable.DataMode.Show = true; /// Iris 3/12/2009 QA80-13268 NOTES_TABLE_ADD_SPECIAL_INPUT_HANDLING
				}
			}
		}
	}
	///end SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS

	//virtual
	void UpdateReportingTables(TreeNode &trOperation, int nTotalNumData, int nExeMode)
	{
		WksReportOperation::UpdateReportingTables(trOperation, nTotalNumData, nExeMode);		
		
		///Iris 5/22/06 ADD_ANOVA_TABLE_FOR_NLSF
		TreeNode trTable = trOperation.Calculation.ANOVAs;
		///Arvin 11/24/06 MULTI_DATA_NEED_MULTI_COVARIANCE_AND_CORRELATION_TABLE
		int		nOneTable = atof(GetTableStringMain(false));
		bool	bHaveSubLevel = 1 < nTotalNumData;
		//-----
		if (trTable)
		{
			//int		nOneTable = GetTableStringSupport(false);///Alex 06/14/06 SET_ANOVA_TABLE_OPEN
			///Arvin 11/24/06 MULTI_DATA_NEED_MULTI_COVARIANCE_AND_CORRELATION_TABLE
			//int		nOneTable = atof(GetTableStringMain(false));
			//bool	bHaveSubLevel = 1 < nTotalNumData;
			///-----
	#ifndef ANOVA_IN_SEPARATE_TABLES
				#pragma message("ANOVA_IN_SEPARATE_TABLES not defined")
				bHaveSubLevel = false;				
	#endif // ANOVA_IN_SEPARATE_TABLES
			//UpdateTableString(trTable, bHaveSubLevel);///Alex 06/14/06 SET_ANOVA_TABLE_OPEN
			UpdateTableString(trTable, bHaveSubLevel,true,nOneTable,nOneTable);
		}
		///End ADD_ANOVA_TABLE_FOR_NLSF
		
		///Arvin 11/24/06 MULTI_DATA_NEED_MULTI_COVARIANCE_AND_CORRELATION_TABLE
		bHaveSubLevel = 1 < nTotalNumData; //Iris 01/24/2007 v8.0547 bHaveSubLevel is updated when added ANOVA table
		TreeNode trCov = trOperation.Calculation.Covariance;
		if (trCov)		
			UpdateTableString(trCov, bHaveSubLevel,true,nOneTable,nOneTable);
		
		TreeNode trCorr = trOperation.Calculation.Correlation;
		if (trCorr)		
			UpdateTableString(trCorr, bHaveSubLevel,true,nOneTable,nOneTable);
		///end MULTI_DATA_NEED_MULTI_COVARIANCE_AND_CORRELATION_TABLE
		
		/// ML 7/20/2005 FITTING_FUNCTION_FORMULA_IN_REPORT
		string			strFormula;
		if ( GetDisplayFormula(trOperation, strFormula) )
		{
			TreeNode		trTable = GetTreeNode_Notes(trOperation);
			trTable.Equation.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_EQUATION);
			//------ Folger 01/09/08 SUPPORT_SKIP_ALL_CPP_COMMENTS
			//ocu_skip_C_comments(&strFormula); ///Cheney 2007-8-20 v8.0685 QA70-10256-P3 SKIP_C_COMMENT_FOR_FDF_FORMULA
			ocu_skip_C_comments(&strFormula, false);
			//------
			strFormula.TrimLeft();	// some formulas seem to have redundant empty lines around, which
			strFormula.TrimRight();	// some formulas seem to have redundant empty lines around, which
								// makes report look ugly.
			trTable.Equation.strVal = strFormula;
		}
		/// end FITTING_FUNCTION_FORMULA_IN_REPORT
		
		/// Iris 07/28/2007 v8.0572 ADD_DATA_MODE_IN_REPORT
		//---- Iris 02/05/2007 need to show this node when fit mode is Concatenate Fit.
		//if(nTotalNumData > 1)
		int		nFitMode = trOperation.GUI.InputData.Use;
		///Arvin 01/03/08 SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS as cp said
		//if(nTotalNumData > 1 || MDINPUT_CMBND_SIMPLE == nFitMode)
		////---- 
		//{
			//TreeNode		trTable = GetTreeNode_Notes(trOperation);
			//if( trTable )
			//{
				//string		strCombo;
				//trOperation.GUI.InputData.GetAttribute(STR_ATTRIB_BRANCH_COMBO, strCombo);
				//string		str = strCombo.GetToken(nFitMode, '|');
				//if( !str.IsEmpty() )
				//{
					//trTable.DataMode.strVal = str;
					//trTable.DataMode.ID = IDE_NOTES_DATA_MODE;
					//trTable.DataMode.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_DATA_MODE);
				//}
			//}
		//}
		UpdateDataModeNode(trOperation, nFitMode, nTotalNumData);
		///end SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS
		//end ADD_DATA_MODE_IN_REPORT
	}
	
	/// ML 6/7/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY
	// virtual
	/// ML 7/21/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA
	//bool	addAdditionalCustomTables(TreeNode &trOp)
	//{
	//	bool		bb = addFindXYorYXTable(trOp, false);
	//	bb = addFindXYorYXTable(trOp, true) || bb;
	//	
	//	return bb;
	//}
	///Arvin 1/04/06 FIND_Z_FROM_XY
	//bool	addAdditionalCustomTables(TreeNode &trOp, int index, int nNumData)
	virtual bool	addAdditionalCustomTables(TreeNode &trOp, int index, int nNumData)
	///end FIND_Z_FROM_XY
	{
		bool		bb = addFindXYorYXTable(trOp, false, index, nNumData);
		bb = addFindXYorYXTable(trOp, true, index, nNumData) || bb;
		
		return bb;
	}
	/// end CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA
	
	virtual	string	getXYorYXFormulaSectionName(bool bYfromX)
	{
		if ( bYfromX )
			return "FitterOp_YfromX";
		else
			return "FitterOp_XfromY";
	}
	virtual	bool	GetXFromYorYFromX(bool bXfromY, DataRange &src, DataRange &dest, int nID)
	{
		Tree		trOp;
		GetTree(trOp);
		//int			nBaseTableID = IDST_REPORT_CUSTOM_TABLE1 + (bXfromY ? 1 : 2);
		int			nBaseTableID = GetCustomTableID((bXfromY ? 1 : 2), 0);
		int			index = nID - nBaseTableID;
		if (index < 0)
			return false;
		DWORD		dwRules = DRR_GET_MISSING | DRR_NO_FACTORS;
		vector		vSrc;
		DWORD		ouidAux = 0;
		///Arvin 1/04/06 FIND_Z_FROM_XY
		//int			nn = src.GetData(dwRules, 0, &ouidAux, NULL, &vSrc);
		//if (nn < 0)
		//	return false;
		///----
		
		//bool		bOK = false;
		if (bXfromY)
		{
			///Arvin 1/04/06 FIND_Z_FROM_XY
			/// ML 1/25/2007 INCORRET_I1_WHEN_EXTRACTING_FINDXY_OGW  
			//int			nn = src.GetData(dwRules, 0, &ouidAux, NULL, &vSrc);
			int			nn = src.GetData(dwRules | DRR_FILL_MISSING_BEFORE_BEGIN, 0, &ouidAux, NULL, &vSrc);
			/// end INCORRET_I1_WHEN_EXTRACTING_FINDXY_OGW  
			if (nn < 0)
				return false;
			///------
			// How many columns of output:
			Worksheet	wksOut;
			/// ML 8/10/2006 MULTIPLE_COLUMNS_IN_OUTPUT_FIND_XY
			//int			c1, c2;
			//if ( !dest.GetRange(wksOut, c1, c2) )
			//	return false;
			int			c1, c20, c1Last, c2;
			if ( !dest.GetRange(wksOut, c1, c20, 0) )
				return false;
			int			numRngs = dest.GetNumRanges();
			if ( !dest.GetRange(wksOut, c1Last, c2, numRngs - 1) )
				return false;
			
			int			nTotalDestCols = c2 - c1 + 1;
			if ( nTotalDestCols <= 0 )
				return false;		// nothing to do
			
			//bOK = GetXFromY(vDest, vSrc, index, trOp);
			return GetXFromY(vSrc, index, wksOut, c1, c2, trOp);
		}
		else
		{
			///Arvin 1/04/06 FIND_Z_FROM_XY
			//vector		vDest;
			//if ( GetYFromX(vSrc, vDest, index, trOp) )
			//	return dest.SetData(vDest);
			//return false;
			if(HasZ(trOp))
			{
				vector vx, vy;
				//int		nn = src.GetData(dwRules, 0, &ouidAux, NULL, &vy, &vx);
				int		nn1 = src.GetData(&vx, 0);
				int		nn2 = src.GetData(&vy, 1);
				if (nn1 < 0 || nn2 < 0)
					return false;
				
				vector		vDest;
				///Cheney 2007-10-11 SHOULD_FILL_VEC_WITH_NANUM_IF_TWO_VEC_SIZE_NOT_EQUAL
				//otherwise GetZFromXY will return false, then last operation result will disappear
				int nvxSize = vx.GetSize(), nvySize = vy.GetSize();
				if(nvxSize != nvySize)
				{
					vector* pvtemp = nvxSize < nvySize? &vx : &vy;
					int nLoops = abs(nvySize - nvxSize);
					for(int ii = 0; ii < nLoops; ii++)
						pvtemp->Add(NANUM);
				}
				///end SHOULD_FILL_VEC_WITH_NANUM_IF_TWO_VEC_SIZE_NOT_EQUAL
				if ( GetZFromXY(vx, vy, vDest, index, trOp) )
					return dest.SetData(vDest);
				
				return false;
			}
			else
			{
				/// ML 1/25/2007 INCORRET_I1_WHEN_EXTRACTING_FINDXY_OGW  
				//int			nn = src.GetData(dwRules, 0, &ouidAux, NULL, &vSrc);
				int			nn = src.GetData(dwRules | DRR_FILL_MISSING_BEFORE_BEGIN, 0, &ouidAux, NULL, &vSrc);
				/// end INCORRET_I1_WHEN_EXTRACTING_FINDXY_OGW
				if (nn < 0)
					return false;
		
				vector		vDest;
				/// Hong 11/27/08 QA80-12677 v8.0980d FIX_REPLICA_FAIL_GET_CORRECT_Y_FROM_X
				//if ( GetYFromX(vSrc, vDest, index, trOp) )
				TreeNode	trReplica = get_gui_replica_node(trOp.GUI);
				int			nPeaks = (tree_is_editable(trReplica) && trReplica.Number.nVal > 0) ? (trReplica.Number.nVal + 1) : 1;
				if ( GetYFromX(vSrc, vDest, index, trOp, NULL, nPeaks) )
				/// end FIX_REPLICA_FAIL_GET_CORRECT_Y_FROM_X
					return dest.SetData(vDest);
				return false;	
			}
			///end FIND_Z_FROM_XY
		}
	}
	
	
	/// Iris 8/09/06 FIND_XY_FOR_PR
	//// For each x-value in vx evaluate as many y-values as possible, up to a maximum of c2Dest - c1Dest + 1,
	//// and put the results into the columns c1Dest to c2Dest of wksDest.  
	//virtual	bool	GetXFromY(vector &vx, int index, Worksheet &wksDest, int c1Dest, int c2Dest, TreeNode &trOp = NULL)
	//{
		//// By default it has only one output (like in LR):
		//vector		vOut;
		//if (GetXFromY(vOut, vx, index, trOp))
		//{
			//Dataset		ds(wksDest, c1Dest);	// the first and only putput goes into c1Dest 
			//if (ds.IsValid())
				//ds = vOut;
		//}
		//
		//return false;
	//}	
	virtual	bool	GetXFromY(vector &vy, int index, Worksheet &wksDest, int c1Dest, int c2Dest, TreeNode &trOp = NULL)
	{
		matrix 	mXs;
		if(!GetXFromY(mXs, vy, index, trOp) )
			return false;
		
		int 	nXs = 0;
		for(int cc = c1Dest; cc<= c2Dest; cc++)
		{
			vector		vX;
			if( nXs < mXs.GetNumRows() )
			{
				mXs.GetRow(vX, nXs);
				nXs++;
				
				Dataset		ds(wksDest, cc);
				if (ds.IsValid())
					ds = vX;
			}			
		}	
		
		return true;
	}
	
	//virtual 
	bool GetXFromY(matrix& mXs, const vector& vy, int nOuputIndex = 0, TreeNode& trOp = NULL);
	
	///Arvin 1/04/06 FIND_Z_FROM_XY
	virtual bool 	GetZFromXY(const vector& vx, const vector& vy, vector& vz, int nOuputIndex = 0, TreeNode& trOp = NULL, const matrix& mXs = NULL){ return false;}
	///end FIND_Z_FROM_XY
	
	///Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	//int GetFitParams(vector& vParams, int nOuputIndex, TreeNode& trOp = NULL)
	int GetFitParams(vector& vParams, int nOuputIndex, TreeNode& trOp = NULL, bool bGetDerivedParams = true)
	///end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	{
		if(NULL == trOp)
			GetTree(trOp);
		
		Tree trParams;
		///Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
		//if(!GetFitParameters(trOp, trParams))
		if(!GetFitParameters(trOp, trParams, bGetDerivedParams))
		///end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
		{
			error_report("failed to get Parameters tree");
			return -1;
		}		
		
		FitParameter	sFitParameter[MAX_MR_PARAMS + 1];		// max num parameters (9 + 1 for constant term)
		int 			nParams = GetFitParameters(trOp, trParams, nOuputIndex, sFitParameter, MAX_MR_PARAMS + 1);		
		if( nParams < 0 )
			return -2;
		
		vParams.RemoveAll(); //reset 
		for (int ii = 0; ii < nParams; ii++)
			vParams.Add( sFitParameter[ii].Value );			
		
		return nParams;
	}
	
	///end FIND_XY_FOR_PR
	
	virtual double GetBaseLineY0(FitParameter *psFitParameter = NULL)
	{
		if(NULL != psFitParameter)
			return psFitParameter[0].Value; //Iris 07/06/06 always to get the first parameter's value as Y0 since for now the functions all are Peak fitting function when nMultiplicity > 1 
		return 0.0;
	}
	virtual void ParameterGetShared(vector<int>& vnShared){}	///Jasmine 11/08/07 ADD_SHARED_TO_PARAMETER_REPORT_TABLE
	virtual bool IsMulFuncsFit(){return false;}

	///------ Folger 07/07/09 NANOSIZER_PARAMETER_SHARE_INFO_NOT_SHOW_CORRECTLY_IN_REPORT
	virtual	BOOL	IsFitPeak()		{ return FALSE; }
	///------ End NANOSIZER_PARAMETER_SHARE_INFO_NOT_SHOW_CORRECTLY_IN_REPORT

	/// Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	//virtual bool GetPeakNumber(int nIndex, int& nPeakNo, bool& bFuncFirstParam){return false;}///Jasmine 11/07/07 ADD_PEAK_NUMBER_TO_PFM_PARAMETERS
	virtual bool GetPeakNumber(int nIndex, int& nPeakNo, bool& bFuncFirstParam, int* pnLastPeakNoWithoutOffset = NULL, int* pnLastPeaksNum = NULL){return false;}
	/// end PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	///Jasmine 11/05/07 SUBTRACT_BASELINE_BEFORE_PFM_FIT
	virtual void CumulativeSubtractBaseline(const vector vx, vector& vCumulate, int nNum, double dY0 = 0)
	{
		///Arvin 06/20/07 v8.0645 WRONG_CONF_PRED_BAND_FOR_MULTI_PEAKS_FIT
		//Always get vCumulate as vFitY to calculate confidence and predict band 
		/// Iris 07/2007/07 FIX_GET_INVAID_Y0_IN_PFM
		//double 	dY0 = psFitParameter[0].Value; //Iris 07/06/06 always to get the first parameter's value as Y0 since for now the functions all are Peak fitting function when nMultiplicity > 1
		//double	dY0 = GetBaseLineY0(psFitParameter);
		///end FIX_GET_INVAID_Y0_IN_PFM
		vCumulate -= dY0 * nNum;
	}
	///End SUBTRACT_BASELINE_BEFORE_PFM_FIT
	//virtual bool HasBaselinePeak(TreeNode trPFM){return false;}	///Jasmine 11/14/07 FIT_BASELINE_AS_WELL_AS_OTHER_PEAKS
	virtual bool HasBaselinePeak(){return false;}	///Jasmine 06/15/09 NO_NEED_PFM_TREE
	///Arvin 12/05/06 MR_NEED_FIND_Y_FROM_X
	///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
	//virtual 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");

		TreeNode		trInputCol = trRow.FirstNode;		// the input will be the first column
		if ( !trInputCol.IsValid() )
			return false;
		trInputCol.SetAttribute(STR_LABEL_ATTRIB, strInputColLabel);
		trInputCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nInputColType);
		///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		DWORD	dwCntrl = SRC_COL_PROPERTY_FORMAT;
		okutil_source_column_property(&trInputCol, &nInputSrcUID, &dwCntrl, FALSE);
		///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		
		// We want the second column to have the formula:
		TreeNode		trCol = trRow.Children.Item(1);
		if ( !trCol.IsValid() )
			return false;
		
		trCol.SetAttribute(STR_LABEL_ATTRIB, strOutColLabel);
		trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nOutputColType);			
		trCol.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(&trCol, &nOutputSrcUID, &dwCntrl, FALSE);
		///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		
		// If there are any more output columns, set the labels to them:
		int				nCountOutputCols = trRow.Children.Count() - 1;
		for (int kk = 1; kk < nCountOutputCols; kk++)
		{
			trCol = trRow.Children.Item(kk + 1);
			string		strMoreOutLabel;
			strMoreOutLabel.Format("%s %d", strOutColLabel, kk + 1);  
			trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nOutputColType);///Joesph/Iris 9/26/06 QA70-7120 MOVE_CUSTOM_TABLE_TO_SEPARATE_SHEET
			trCol.SetAttribute(STR_LABEL_ATTRIB, strMoreOutLabel);
			///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
			okutil_source_column_property(&trCol, &nOutputSrcUID, &dwCntrl, FALSE);
			///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		}
		return true;
	}
	///end MR_NEED_FIND_Y_FROM_X
	/// Joesph/Iris 9/26/06 QA70-7120 MOVE_CUSTOM_TABLE_TO_SEPARATE_SHEET
	///// ML 7/21/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA
	//bool	addFindXYorYXTable(TreeNode &trOp, bool bYfromX, int nNumData)
	bool	addFindXYorYXTable(TreeNode &trOp, bool bYfromX, int index, int nNumData)
	{
		string			strSection = getXYorYXFormulaSectionName(bYfromX);
		if ( strSection.IsEmpty() )
			return false;	// no support
		
		string			strInputColLabel; 
		string			strOutColLabel;
		//string			strMoreOutLabel;
		if ( bYfromX )
		{
			strInputColLabel = _L("Enter X values:");
			strOutColLabel = _L("Y Value");
			//strMoreOutLabel = _L("More Y values");
		}
		else
		{
			strInputColLabel = _L("Enter Y values:");
			strOutColLabel = _L("X Value");
			//strMoreOutLabel = _L("More X values");
		}	
				
		string		strValueToStore = "RegrFindXYorYX.txt|" + strSection;
		int			indexTbl = bYfromX ? 2 : 1;		
		/// Joesph/Iris 9/26/06 QA70-7120 MOVE_CUSTOM_TABLE_TO_SEPARATE_SHEET		
		/*
		TreeNode		trParent;
		if (1 < nNumData)			// need to create the intermediary parent for multiple data
		{
			int			nIdParentOfTables = bYfromX ? IDST_REPORT_CUSTOM_TABLES3_ROOT : IDST_REPORT_CUSTOM_TABLES2_ROOT;
			string		strTagName = bYfromX ? "YfromX" : "XfromY";
			string		strTblLabel;
			bool		bEnabled = false;
			if ( !getCustomTableProps(&strTblLabel, trOp, indexTbl, -1, &bEnabled) || !bEnabled )
				return false;
			trParent = tree_check_get_node(trOp.Calculation, strTagName, nIdParentOfTables, STR_LABEL_ATTRIB, strTblLabel);
			trParent.SetAttribute(TREE_Table, GetTableStringSupport(false));
		}
		
		for (int jj = 0; jj < nNumData; jj++)
		{
			bool			bEnabled = false;
			string			str;
			LPCSTR			lpcszLabel = NULL;
			if (1 < nNumData)
			{
				//str.Format("TT%u", jj + 1);
				GetEscapedMainDataString(trOp, str, jj + 1);
				lpcszLabel = str;
			}
			TreeNode		trCustom = addCustomTableToReport(trOp, indexTbl, &bEnabled, jj, lpcszLabel, trParent);
			if ( !trCustom.IsValid() || !bEnabled )
				return false;
			
			// The column is the second dim, so first get the first row:
			TreeNode		trRow = trCustom.FirstNode;
			if ( !trRow.IsValid() )
				return false;
	
			TreeNode		trInputCol = trRow.FirstNode;		// the input will be the first column
			if ( !trInputCol.IsValid() )
				return false;
			
			// We want the second column to have the formula:
			TreeNode		trCol = trRow.Children.Item(1);
			if ( !trCol.IsValid() )
				return false;
			
			trInputCol.SetAttribute(STR_LABEL_ATTRIB, strInputColLabel);
			trCol.SetAttribute(STR_LABEL_ATTRIB, strOutColLabel);
			
			trCol.SetAttribute(STR_ATT_COLUMN_FORMULA, strValueToStore);
			
			// If there are any more output columns, set the labels to them:
			int				nCountOutputCols = trRow.Children.Count() - 1;
			for (int kk = 1; kk < nCountOutputCols; kk++)
			{
				trCol = trRow.Children.Item(kk + 1);
				string		strMoreOutLabel;
				strMoreOutLabel.Format("%s %d", strOutColLabel, kk + 1);
				trCol.SetAttribute(STR_LABEL_ATTRIB, strMoreOutLabel);
			}
		}
		
		DWORD		dwGetNBranchBits = GETNBRANCH_HIDE_ROW_HEADINGS | GETNBRANCH_WRITABLE | GETNBRANCH_HIDE_ROW_LABELS;
		if ( bHideColLabels )
			dwGetNBranchBits |= GETNBRANCH_HIDE_COL_LABELS;
		trCustom.SetAttribute(TREE_Table, GetTableStringSupport(false, false, true, dwGetNBranchBits));		
		*/		
		string		strDataLabel;
		GetEscapedMainDataString(trOp, strDataLabel, index + 1);
		ConvertEscapedString(strDataLabel);
		
		int nOption = bYfromX? OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET : OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET;
		///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
		//TreeNode 	trCustomTable = GetResultCurvesBranch(trOp, index, nNumData, nOption, strDataLabel);
		//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS		
		/*
		string			strDataLabelCurves = _L("Fit Curve");
		strDataLabelCurves += " ";
		strDataLabelCurves += index + 1;
		*/
		string strDataLabelCurves = GetResultCurveMainTableLabel(trOp, nNumData, strDataLabel);
		//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		TreeNode 	trCustomTable = GetResultCurvesBranch(trOp, index, nNumData, nOption, strDataLabelCurves);
		///end CENTRALIZE_FITTING_RESULT_LABELS
		if(!trCustomTable)
			return error_report("Fail to create Calibration table");

		string		strTblLabel;
		bool		bEnabled = false;
		if ( !GetCustomTableProps(&strTblLabel, trOp, indexTbl, -1, &bEnabled, strDataLabel) )
			return error_report("addFindXYorYXTable failed GetCustomTableProps");
		if( !bEnabled )
			return true;
	
		///Cheney 2007-3-21 IF_AUTO_UPDATE_SHOULD_KEEP_1ST_COL_OF_FINDXY_SHEET
		//string		strTagName = bYfromX ? "YfromX" : "XfromY";
		string		strTagName = bYfromX ? STR_Y_FROM_X : STR_X_FROM_Y;
		///end IF_AUTO_UPDATE_SHOULD_KEEP_1ST_COL_OF_FINDXY_SHEET
		//int			nIdParentOfTables = bYfromX ? IDST_REPORT_CUSTOM_TABLES3_ROOT : IDST_REPORT_CUSTOM_TABLES2_ROOT;
		int 		nIDTable = GetCustomTableID(indexTbl, index);
		
		//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS		
		// label of all sub tables of ResultCurves will be put to column parameters label when report, need remove Parameters row, see #13285-P2 a. point. 
		//TreeNode 	trCustom = tree_check_get_node(trCustomTable, strTagName, nIDTable, STR_LABEL_ATTRIB, strTblLabel);
		TreeNode 	trCustom = tree_check_get_node(trCustomTable, strTagName, nIDTable);
		//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		
		int			nInputColType = bYfromX? OKDATAOBJ_DESIGNATION_X : OKDATAOBJ_DESIGNATION_Y;
		int			nOutputColType = bYfromX? OKDATAOBJ_DESIGNATION_Y : OKDATAOBJ_DESIGNATION_X;
		if( !AddCustomTableToReport(trOp, trCustom, indexTbl) )
			return error_report("addFindXYorYXTable failed AddCustomTableToReport");
		
				
		// The column is the second dim, so first get the first row:
		///Arvin 12/05/06 MR_NEED_FIND_Y_FROM_X	
		/*
		TreeNode		trRow = trCustom.FirstNode;
		if ( !trRow.IsValid() )
			return error_report("addFindXYorYXTable trCustom invalid");

		TreeNode		trInputCol = trRow.FirstNode;		// the input will be the first column
		if ( !trInputCol.IsValid() )
			return false;
		trInputCol.SetAttribute(STR_LABEL_ATTRIB, strInputColLabel);
		trInputCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nInputColType);
		
		// We want the second column to have the formula:
		TreeNode		trCol = trRow.Children.Item(1);
		if ( !trCol.IsValid() )
			return false;
		
		trCol.SetAttribute(STR_LABEL_ATTRIB, strOutColLabel);
		trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nOutputColType);			
		trCol.SetAttribute(STR_ATT_COLUMN_FORMULA, strValueToStore);
		
		// If there are any more output columns, set the labels to them:
		int				nCountOutputCols = trRow.Children.Count() - 1;
		for (int kk = 1; kk < nCountOutputCols; kk++)
		{
			trCol = trRow.Children.Item(kk + 1);
			string		strMoreOutLabel;
			strMoreOutLabel.Format("%s %d", strOutColLabel, kk + 1);  
			trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nOutputColType);///Joesph/Iris 9/26/06 QA70-7120 MOVE_CUSTOM_TABLE_TO_SEPARATE_SHEET
			trCol.SetAttribute(STR_LABEL_ATTRIB, strMoreOutLabel);
		}
		*/
		///------ Folger 08/25/10 ORG-897-P3 FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		//setFindXYorYXTable(trCustom, strInputColLabel, nInputColType, strOutColLabel,nOutputColType, strValueToStore);
		XYRange		xy;
		int			nInputSrcUID = 0, nOutputSrcUID = 0;
		GetInput(xy);
		if ( xy )
		{
			Column	colX;
			if ( xy.GetXColumn(colX, index) && colX )
			{
				if ( bYfromX )
				{
					nInputSrcUID = colX.GetUID(TRUE);
					nOutputSrcUID = 0;
				}
				else
				{
					nInputSrcUID = 0;
					nOutputSrcUID = colX.GetUID(TRUE);
				}
			}
		}
		setFindXYorYXTable(trCustom, strInputColLabel, nInputColType, strOutColLabel,nOutputColType, strValueToStore, nInputSrcUID, nOutputSrcUID);
		///------ End FITTER_OPERATION_FINDXY_X_COLUMN_SHOULD_FOLLOW_SOURCE
		///end MR_NEED_FIND_Y_FROM_X
		DWORD		dwGetNBranchBits = GETNBRANCH_HIDE_ROW_HEADINGS | GETNBRANCH_WRITABLE | GETNBRANCH_HIDE_ROW_LABELS | GETNBRANCH_CHANGE_LABEL_TYPES_IN_FLAT;
		trCustom.SetAttribute(TREE_Table, GetTableStringSupport(false, true, true, dwGetNBranchBits));	
		///end MOVE_CUSTOM_TABLE_TO_SEPARATE_SHEET		
		
		return true;
	}
	/// end CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA

	/// ML 7/21/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA
	/*
	// If !bYfromX, then XfromY.
	bool	addFindXYorYXTable(TreeNode &trOp, bool bYfromX)
	{
		string			strSection = getXYorYXFormulaSectionName(bYfromX);
		if ( strSection.IsEmpty() )
			return false;	// no support
		
		int				indexTbl = bYfromX ? 2 : 1;
		bool			bEnabled = false;
		TreeNode		trCustom = addCustomTableToReport(trOp, indexTbl, &bEnabled);
		if ( !trCustom.IsValid() || !bEnabled )
			return false;
		
		string			strValueToStore = "RegrFindXYorYX.txt|" + strSection;
		// The column is the second dim, so first get the first row:
		TreeNode		trRow = trCustom.FirstNode;
		if ( !trRow.IsValid() )
			return false;

		TreeNode		trInputCol = trRow.FirstNode;		// the input will be the first column
		if ( !trInputCol.IsValid() )
			return false;
		
		// We want the second column to have the formula:
		TreeNode		trCol = trRow.Children.Item(1);
		if ( !trCol.IsValid() )
			return false;
		
		string			strInputColLabel; 
		string			strOutColLabel;
		if ( bYfromX )
		{
			strInputColLabel = _L("Enter X values:");
			strOutColLabel = _L("Y Values");
		}
		else
		{
			strInputColLabel = _L("Enter Y values:");
			strOutColLabel = _L("X Values");
		}
		
		trInputCol.SetAttribute(STR_LABEL_ATTRIB, strInputColLabel);
		trCol.SetAttribute(STR_LABEL_ATTRIB, strOutColLabel);
		
		return trCol.SetAttribute(STR_ATT_COLUMN_FORMULA, strValueToStore);
	}
	*/
	/// end CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA
	/// end CUSTOM_TABLES_FOR_FIND_XY

	///Iris 4/06/05 INIT_GRAPH_NUMBER
	//virtual
	virtual int ConstructGraphNumber()
	{
		
		//return 5;
		return 6;  ///Jim 2/22/06 v8.0368 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
		
	}
	
	bool 	GetCustomGraphTypeName(string& strName, int nGraphIndex)
	{
		switch( nGraphIndex )
		{
		case GRAPH_FIT_CURVE:
			strName = _L("Fitted Curves Plot");  /// AW 10/26/07 WRONG_LOCALIZE_MACRO
			break;
		
		case GRAPH_RESIDUALS_SCATTER:
			strName = _L("Residual vs. Independent Plot");
			break;
			
		case GRAPH_RESIDUALS_HISTOGRAM:
			strName = _L("Histogram of the Residual Plot");
			break;
			
		case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
			strName = _L("Residual vs. Predicted Values Plot");
			break;
			
		case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
			strName = _L("Residual vs. the Order of the Data Plot");
			break;
		
		///Jim 2/22/06 v8.0368 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
		case GRAPH_RESIDUALS_LAG_PLOT:
			strName = _L("Residual Lag Plot");
			break;
		//END ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
			
		default:
			return false;
		}
		
		return true;
	}
	
	virtual int	ReportGetPicureIndexFromDataIndex(int nGraphIndex, int nDataIndex)
	{
		/// Iris 9/11/06 SURFACE_FIT_REPORT_MAT_FIT_DATA
		//switch( ReportGetPlotTypeFromGraphIndex(nGraphIndex) )
		//{
		//case IDM_PLOT_HISTOGRAM_TYPE:
		//case IDM_PLOT_LINE:
		//case IDM_PLOT_SCATTER:
		//case IDM_PLOT_LINESYMB:
			//return nDataIndex;
		//}
		//
		//return -1;
		return nDataIndex; 
		///End SURFACE_FIT_REPORT_MAT_FIT_DATA
	}
	
	virtual int	ReportGetPlotTypeFromGraphIndex(int nGraphIndex)
	{
		switch( nGraphIndex )
		{			
		case GRAPH_FIT_CURVE:
			return IDM_PLOT_LINE;
		case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
		///Arvin 10/23/07 QA70-10559-P2 RESIDUAL_VERSUS_ORDER_PLOT_USE_WRONG_PLOT_TYPE	
		//	return IDM_PLOT_LINESYMB; 
		///END RESIDUAL_VERSUS_ORDER_PLOT_USE_WRONG_PLOT_TYPE
		case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
		case GRAPH_RESIDUALS_SCATTER:  	/// Iris 6/02/05 ADD_RESIDUALS_SCATTER_GRAPH
		case GRAPH_RESIDUALS_LAG_PLOT:	///Jim 2/242/06 v8.0368 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANC
			return IDM_PLOT_SCATTER;		
		
		case GRAPH_RESIDUALS_HISTOGRAM:			
			return IDM_PLOT_HISTOGRAM_TYPE;		
		
		default:	
			break;
		}
		
		return -1;
	}
	
	//virtual
	int		ReportGraphGetRescaleOption(TreeNode& trOp, int nGraphIndex)
	{
		if(GRAPH_FIT_CURVE == nGraphIndex)
		{
			TreeNode trFittedCurve = GetGUIGraphNodes(trOp, nGraphIndex);
			/// Iris 11/02/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//TreeNode trXDataType = trFittedCurve.XDataType;
			TreeNode trXDataType = OP_GUI_FIT_X_DATA_BRANCH(trOp.GUI);
			ASSERT(trXDataType);
			///end OP_DLG_NEW_STRUCTURE
			if(trXDataType && FIT_CURVE_UNIFORM_LINEAR == trXDataType.Use && FIT_CURVE_SPAN_AXIS == trXDataType.Range.nVal)
			{
				return ANL_NO_EXPAND;
			}
		}
		return WksReportOperation::ReportGraphGetRescaleOption(trOp, nGraphIndex);
	}
	
	///Arvin 11/09/07 NLFIT_REPORT_GRAPH_NEED_RESCALE_WHILE_PART_GRAPH_SELECTION_AS_INPUT
	//virtual 
	/// Hong 08/12/08 QA80-11986 FIX_FITTED_CURVE_PLOT_FAIL_RESCALE_WHEN_SOURCE_PLOT_HAVE_ERR_BAR
	//void 	RescaleReportGraph(TreeNode& trOp, GraphLayer& gl, int nGraphIndex, int nPicRowIndex, int nPicColIndex)
	void 	RescaleReportGraph(TreeNode& trOp, GraphLayer& gl, int nGraphIndex, int nPicRowIndex, int nPicColIndex, int nFirstFittedPlotIndex)
	/// end FIX_FITTED_CURVE_PLOT_FAIL_RESCALE_WHEN_SOURCE_PLOT_HAVE_ERR_BAR
	{
		int 	nNumPlots = gl.DataPlots.Count();
		DWORD dwRules = GetDataRules(trOp);
		int nRescaleOption = ReportGraphGetRescaleOption(trOp, nGraphIndex);
		/// Iris 5/14/2008 v8.0862 QA80-11545 NOT_GET_XYRANGE_FROM_GRAPH_LAYER_WHEN_RANGE_IS_FULL_AXIS_RANGE, want not to do rescale 
		//if(nRescaleOption >= 0 && nGraphIndex == GRAPH_FIT_CURVE && nNumPlots > 1 && !HasZ(trOp) && !isPlotAverageData())
		///Sophy 12/29/2008 v8.0991b QA80-12832 SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS on Multi Indeps&Deps, nDataIndex if not the same as picture index, drInput.GetSubRange(drSrc, dwRules, nDataIndex) can not get correct datarange, may call base class's rescale method.
		//if( !(nRescaleOption & ANL_NO_EXPAND) && nGraphIndex == GRAPH_FIT_CURVE && nNumPlots > 1 && !HasZ(trOp) && !isPlotAverageData())
		if( !(nRescaleOption & ANL_NO_EXPAND) && nGraphIndex == GRAPH_FIT_CURVE && nNumPlots > 1 && !HasZ(trOp) && !isPlotAverageData() && !(GetNumX(trOp) > 1 || GetNumY(trOp) > 1))
		///end SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS
		///end NOT_GET_XYRANGE_FROM_GRAPH_LAYER_WHEN_RANGE_IS_FULL_AXIS_RANGE
		{
			int nDataIndex = nPicRowIndex * GetReportGraphTableColNum(trOp, nGraphIndex) + nPicColIndex;
			DataRange drInput, drSrc;
			GetInput(drInput);
			drInput.GetSubRange(drSrc, dwRules, nDataIndex);
				
			int iPlot = 0;
			TreeNode trPlotInfo = CheckGetPlotInfoNode(trOp, nGraphIndex, nPicRowIndex, nPicColIndex);
			if(trPlotInfo.SourcePlotType.IsValid())
				iPlot = 1;
			/// Hong 08/12/08 QA80-11986 FIX_FITTED_CURVE_PLOT_FAIL_RESCALE_WHEN_SOURCE_PLOT_HAVE_ERR_BAR
			if ( -1 != nFirstFittedPlotIndex )
				iPlot = nFirstFittedPlotIndex;
			/// end FIX_FITTED_CURVE_PLOT_FAIL_RESCALE_WHEN_SOURCE_PLOT_HAVE_ERR_BAR
			bool bFitCurvePlot = true; 
			///Sophy 12/9/2008 v8.0983c QA80-12745 ARRANGE_ALL_SAME_PLOTS_IN_ONE_GRAPH_SHOULD_RESCALE_BY_ALL_PLOTS
			if( (0 != nPicRowIndex || 0 != nPicColIndex) && IsPlotAllPlotsInOneGraph(trOp, nGraphIndex))
			{
				bFitCurvePlot = false;
			}
			///end ARRANGE_ALL_SAME_PLOTS_IN_ONE_GRAPH_SHOULD_RESCALE_BY_ALL_PLOTS
			dwRules |= DRR_GET_DEPENDENT;
			while(iPlot < nNumPlots)
			{
				DataPlot dp = gl.DataPlots(iPlot);
				if(is_plot_requir_rescale(dp, RESCALE_SHOW_ALL | RESCALE_SHRINK_X | RESCALE_SHRINK_Y))
				{
					rescale_graph_layer_by_plot(dp, drSrc, bFitCurvePlot, dwRules);
				}
				bFitCurvePlot = false;
				iPlot++;
			 }
		}
		else
			/// Hong 08/12/08 QA80-11986 FIX_FITTED_CURVE_PLOT_FAIL_RESCALE_WHEN_SOURCE_PLOT_HAVE_ERR_BAR
			//WksReportOperation::RescaleReportGraph(trOp, gl, nGraphIndex, nPicRowIndex, nPicColIndex);
			WksReportOperation::RescaleReportGraph(trOp, gl, nGraphIndex, nPicRowIndex, nPicColIndex, nFirstFittedPlotIndex);
			/// end FIX_FITTED_CURVE_PLOT_FAIL_RESCALE_WHEN_SOURCE_PLOT_HAVE_ERR_BAR
	}
	///end NLFIT_REPORT_GRAPH_NEED_RESCALE_WHILE_PART_GRAPH_SELECTION_AS_INPUT
	
	/// ML 12/18/2006 CALLING_OPERATION_FROM_OC_LT
	// virtual
	///Arvin 07/18/07 v8.0662 FIT_COMPARISION_OF_DATASETS_INCONSISTENT_BETWEEN_NLFIT_AND_LR
	//BOOL	OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, XYRange &xyrng, LPCSTR lpcszStr1 = NULL, LPCSTR lpcszStr2 = NULL)
	///Arvin 01/29/08 SHOULD_NOT_ADD_USER_PARAM_SETTING_TREE_IN_CLASS_LT_NLFit
	//int 	OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, DataRange &dr, LPCSTR lpcszStr1 = NULL, LPCSTR lpcszStr2 = NULL)
	///------- Folger 07/01/09 QA80-13774-P1 COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
	//int 	OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, DataRange &dr, LPCSTR lpcszStr1 = NULL, LPCSTR lpcszStr2 = NULL, bool bNeedUserParamSetting = true)
	int 	OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, DataRange &dr, LPCSTR lpcszStr1 = NULL, LPCSTR lpcszStr2 = NULL, bool bNeedUserParamSetting = true, TreeNode& trOriginalInput = NULL)
	///------- End COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
	///end SHOULD_NOT_ADD_USER_PARAM_SETTING_TREE_IN_CLASS_LT_NLFit
	///end FIT_COMPARISION_OF_DATASETS_INCONSISTENT_BETWEEN_NLFIT_AND_LR
	{
		Tree			trInput;
		TreeNode		trInputDataTemp;
		trInputDataTemp = trInput.AddNode("InputData");
		///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
		//if ( !xyrng.GetTree(trInputDataTemp, FALSE) )
		//		return FALSE;
		if ( !dr.GetTree(trInputDataTemp, FALSE) )
			return OP_FAILED_GET_TREE_FROM_DATA_RANGE;
		///end CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
	
		trInputData.Replace(trInputDataTemp, TRUE, TRUE);
		///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
		//return TRUE;
		return OP_NOERROR;
		///end CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
	}
	/// end CALLING_OPERATION_FROM_OC_LT

	
	///Cheney 2006-11-1 CHANGE_sReg_FROM_REF_TO_POINTER, otherwise cannot check if is NULL and run time error
	/////Iris 4/18/05 FIX_NLSF_CONF_PREDI_BAND_NOT_WORK
	////move from FitRegression to let Confidence Band and Prediction Band work in NLSF
	////virtual 
	//bool MakeFitErrConf(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* sFitParameter, RegStats& sRegStats, RegCalcInternal& sReg)
	bool MakeFitErrConf(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* sFitParameter, RegStats& sRegStats, RegCalcInternal* psReg)
	///end CHANGE_sReg_FROM_REF_TO_POINTER
	{
		double db_Err = sFitParameter[1].Error;
	
		LROptions sLROptions;
		sLROptions = trOp.GUI.Fit;
		if( sLROptions.FixIntercept )
		{
			vFitErr = fabs(vFitX) * db_Err;
		}
		else
		{
			///Cheney 2006-11-1 CHANGE_sReg_FROM_REF_TO_POINTER
			//if(sReg == NULL)
				//return false;
			//
			//vFitErr = sqrt(1.0 / sReg.dSumWeight + (vFitX - sReg.dxAve)^2 / sReg.dSxx) * sRegStats.RMSESD;
			if(psReg == NULL)
				return false;
			
			vFitErr = sqrt(1.0 / psReg->dSumWeight + (vFitX - psReg->dxAve)^2 / psReg->dSxx) * sRegStats.RMSESD;
			///end CHANGE_sReg_FROM_REF_TO_POINTER
		}
		
		return true;
	}
	//virtual 
	///Cheney 2006-11-1 CHANGE_sReg_FROM_REF_TO_POINTER
	//bool MakeFitErrPred(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* sFitParameter, RegStats& sRegStats, RegCalcInternal& sReg = NULL)
	bool MakeFitErrPred(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* sFitParameter, RegStats& sRegStats, RegCalcInternal* psReg = NULL)
	///end CHANGE_sReg_FROM_REF_TO_POINTER
	{
		///Cheney 2006-11-1 CHANGE_sReg_FROM_REF_TO_POINTER
		//if(sReg == NULL)
			//return false;
		//
		//vFitErr = sqrt(1.0 + 1.0 / sReg.dSumWeight + (vFitX - sReg.dxAve)^2 / sReg.dSxx) * sRegStats.RMSESD;
		if(psReg == NULL)
			return false;
		
		vFitErr = sqrt(1.0 + 1.0 / psReg->dSumWeight + (vFitX - psReg->dxAve)^2 / psReg->dSxx) * sRegStats.RMSESD;
		///end CHANGE_sReg_FROM_REF_TO_POINTER
		return true;
	}
	
	/// Iris 5/19/05 QA70-6365 SETUP_FITY_CONFID_PRODI_LINE_COLOR
	//virtual
	bool SetupPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nFittedPlot, int nNumPlots = 1, int nGraphIndex = 0, int nDataIndex = 0, bool bIsSourceGraph = false, bool bUpdateExistedReportGraph = false)
	{			
		//---- Iris 11/10/06 PLOT_MORE_ONE_RESULT_PLOTS_AFTER_CHANGE_PARAMS
		if( !WksReportOperation::SetupPlotDetails(trOp, gl, nFittedPlot, nNumPlots, nGraphIndex, nDataIndex, bIsSourceGraph, bUpdateExistedReportGraph))
			return false;		
		
		if(GetGraphIndexForMorePlotDetails() == nGraphIndex)
		{
			//Arvin 06/01/07 v8.0631 WRONG_LEGEND_IN_SOURCE_GRAPH_AFTER_FITTING
			//SetupFittedCurvesPlotDetails(trOp, gl, nFittedPlot, nNumPlots, nGraphIndex, bIsSourceGraph);
			SetupFittedCurvesPlotDetails(trOp, gl, nFittedPlot, nNumPlots, nGraphIndex, bIsSourceGraph, nDataIndex, bUpdateExistedReportGraph);
			///end WRONG_LEGEND_IN_SOURCE_GRAPH_AFTER_FITTING
		}
		
		///Jim 3/1/06 v8.0370 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
		///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
		//if(GRAPH_RESIDUALS_LAG_PLOT == nGraphIndex && !bUpdateExistedReportGraph)
		//	SetupLagPlotDetails(trOp, gl, nGraphIndex); 
		/// Iris 9/24/2009 QA80-11710-P3 ALL_PLOTS_ARE_RED_IN_RESIDUAL_GRAPH_WHEN_PLOT_IN_ONE_GRAPH
		/*
		if(GRAPH_RESIDUALS_SCATTER <= nGraphIndex && nGraphIndex <= GRAPH_RESIDUALS_LAG_PLOT 
			&& nGraphIndex != GRAPH_RESIDUALS_HISTOGRAM && !bUpdateExistedReportGraph)
			SetupResidualScatterPlotDetails(trOp, gl, nGraphIndex, nDataIndex);
		*/
		if(GRAPH_RESIDUALS_SCATTER <= nGraphIndex && nGraphIndex <= GRAPH_RESIDUALS_LAG_PLOT 
			&& nGraphIndex != GRAPH_RESIDUALS_HISTOGRAM)
			SetupResidualScatterPlotDetails(trOp, gl, nGraphIndex, nDataIndex, bUpdateExistedReportGraph);
		///end ALL_PLOTS_ARE_RED_IN_RESIDUAL_GRAPH_WHEN_PLOT_IN_ONE_GRAPH
		///end 	SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
		//END ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
		
		///Arvin 05/25/07 v8.0626 APPARENT_FIT_NOT_WORK
		if(GRAPH_FIT_CURVE == nGraphIndex && IsApparentFit(trOp) && !bUpdateExistedReportGraph)
		{
			DataPlot dp = GetSourceDataPlot(nDataIndex, trOp);
			if(dp)
			{
				GraphLayer glSource;
				dp.GetParent(glSource);
				Scale sYFitCurve(gl.Y), sYSource(glSource.Y);
				if(sYFitCurve && sYSource)
					sYFitCurve.Type = sYSource.Type;
				
				Scale sXFitCurve(gl.X), sXSource(glSource.X);
				if(sXFitCurve && sXSource)
					sXFitCurve.Type = sXSource.Type;
			}
		}
		///end APPARENT_FIT_NOT_WORK
		return true;		
	}
	
	/// Iris 01/25/2007 v8.0547 CLEANUP_SETUP_PLOT_DETAILS_CODES
	virtual int GetGraphIndexForMorePlotDetails()
	{
		return GRAPH_FIT_CURVE;
	}
	///end CLEANUP_SETUP_PLOT_DETAILS_CODES
	
	/// Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG
	/*
	bool	isNewlyAddedPlotting(bool bUpdateExistedReportGraph, int nPlotIndex, int nFirstPlotIndex, int nNumPlots)
	{
		if(!bUpdateExistedReportGraph)
			return true;
		
		if(nPlotIndex >= nFirstPlotIndex && nPlotIndex <= nFirstPlotIndex + nNumPlots - 1)
			return true;
	*/
	bool	isNewlyAddedPlotting(int nPlotIndex, int nNumOfAllPlots, int nNumOfNewlyAddedPlots)
	{
		if( nPlotIndex >= nNumOfAllPlots - nNumOfNewlyAddedPlots )
			return true;
	///End FIX_LCI_UCI_PLOT_COLOR_BUG
		
		return false;
	}
	
	//Arvin 06/01/07 v8.0631 WRONG_LEGEND_IN_SOURCE_GRAPH_AFTER_FITTING
	//void SetupFittedCurvesPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nFittedPlot, int nNumFittedPlots, int nGraphIndex, bool bIsSourceGraph = false)
	virtual void SetupFittedCurvesPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nFittedPlot, int nNumFittedPlots, int nGraphIndex, bool bIsSourceGraph = false, int nDataIndex = 0, bool bUpdateExistedReportGraph = false)
	///end WRONG_LEGEND_IN_SOURCE_GRAPH_AFTER_FITTING
	{
		/// Iris 5/04/2008 QA80-11503 CHANGE_PARAM_CHANGED_SOURCE_PLOTS_COLOR
		if( nFittedPlot < 0 || nNumFittedPlots <= 0 )
			return;
		///end CHANGE_PARAM_CHANGED_SOURCE_PLOTS_COLOR
		
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE
		TreeNode trFitCurve = GetGUIGraphNodes(trOp, nGraphIndex);
		if( !trFitCurve )
		{
			error_report("fail to find Fitting curve graph gui node");
			return;
		}
		if( !trFitCurve.Use )
			return;
#else
		TreeNode trGraph = OP_GUI_FITCURVE_PLOT_CHECKBOX(trOp.GUI);
		TreeNode trFitCurve = OP_GUI_FITCURVE_PLOT_SETTINGS(trOp.GUI);
		if( !trFitCurve || ! trGraph )
		{
			error_report("fail to find Fitting curve graph gui node");
			return;
		}
		
		if( !trFitCurve.Use || !trGraph.nVal )
			return;
#endif //OP_DLG_TOTALLY_NEW_STRUCTURE
		
		
		///Arvin 06/07/07 CHANGE_LEGEND_TO_USE_LONG_NAME_AND_UNIT as max's suggestion
		int nStartPlot = nFittedPlot;
		int nEndPlot = nFittedPlot + nNumFittedPlots - 1;
		///end CHANGE_LEGEND_TO_USE_LONG_NAME_AND_UNIT
		
		if(!bUpdateExistedReportGraph)
		{
			///Cheney/Iris 2006-9-1 AVE_REPLICA_DATA_IF_PLOTTYPE_EXIST_AND_NOT_RAW_DATA
			///Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
			//if(isPlotAverageData())
			TreeNode trHowPlot = trFitCurve.PlotFit;
			bool bPlotAveDataInSrcGraph = bIsSourceGraph && trHowPlot && trHowPlot.Enable && trHowPlot.nVal == 2? true : false;
			if((isPlotAverageData() && !bIsSourceGraph) || (isPlotAverageData() && bPlotAveDataInSrcGraph))
			///end FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
			{
				int nPlotAverage = nFittedPlot; //average data is belong to source data, so put before fitted line.
				/// Hong 07/07/09 QA80-13881 FIX_FITTED_CURVE_WRONG_COLOR_IN_REPORT_SHEET_OF_CONCATENATE_FIT
				//nFittedPlot += 2; //+2, average plot with error bar
				nFittedPlot += 1; // source data plot in report sheet
				TreeNode 		trPlotType = trFitCurve.PlotType;
				if ( trPlotType && trPlotType.nVal != PLOT_TYPE_RAW_DATA )
					nFittedPlot += 1; // error bar
				/// end FIX_FITTED_CURVE_WRONG_COLOR_IN_REPORT_SHEET_OF_CONCATENATE_FIT
				nNumFittedPlots = 1; //---- Iris 11/03/06 correct it here since only has one fitted plot for average 
				
				//update the average plot from Line to Scatter
				DataPlot dpAve = gl.DataPlots(nPlotAverage);
				update_plot_type(dpAve, IDM_PLOT_SCATTER);
			}
			///End AVE_REPLICA_DATA_IF_PLOTTYPE_EXIST_AND_NOT_RAW_DATA
		}
		
		DataPlot	dp;
		if(!bUpdateExistedReportGraph)
		{
			///Arvin 12/08/06 SET_COLOR_BY_FITTED_CURVE_OPTION
			//DataPlot	dp = gl.DataPlots(nFittedPlot);
			//dp.SetColor(GetCurveLineColor(trOp, nGraphIndex));
			dp = gl.DataPlots(nFittedPlot);
			if(HasZ(trOp))
			{
				Tree 		trColor;
				trColor = dp.GetFormat(FPB_STYLE_COLOR, FOB_ALL, true, true);
				
				//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
				/*
				TreeNode trn = trColor.Root.Grids;
				///Arvin 11/15/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
				//trn.Color.nVal = GetCurveLineColor(trOp, nGraphIndex);
				trn.Color.nVal = GetCurveLineColor(trOp, nGraphIndex, nDataIndex, bIsSourceGraph);
				//end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
				*/
				TreeNode trn = tree_get_node_by_tagname(trColor, "Color", true);
				if ( trn )
					trn.nVal = GetCurveLineColor(trOp, nGraphIndex, nDataIndex, bIsSourceGraph);
				//------ End SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
				
			  	dp.ApplyFormat(trColor, true, true);	
			}
			else
				///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
				//dp.SetColor(GetCurveLineColor(trOp, nGraphIndex));
				dp.SetColor(GetCurveLineColor(trOp, nGraphIndex, nDataIndex, bIsSourceGraph));
				///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
		  	///end SET_COLOR_BY_FITTED_CURVE_OPTION	
		}
	
		//---- Iris 10/31/06 WRONG_COLOR_ON_MULTI_PEAK_FITTED_CURVE
		//For mutliple peaks fit, the number of fitted line may be >1, so the color of all fitted line should be different.
		/// Iris 08/10/2007 v8.0679 GROUP_FITCURVE_FOR_MULTI_PEAKS_AND_SOURCE_DATA_IS_GROUPED
		/*
		gl.GroupPlots(nFittedPlot, nFittedPlot + nNumFittedPlots -1);
		nFittedPlot += nNumFittedPlots -1; 
		
		//------ Iris 11/02/06 v8.0502e CORRECT_COLOR_OF_LCL_UCL_LINE
		//the color of LCL & ULC line should be different with the color of fitted line. So the color of LCL should started from color of last fitted line + 1
		double 	dColorOfLastFittedLine;
		dp = gl.DataPlots(nFittedPlot);
		if(dp)
		{
			string 	strLT;
			strLT.Format("get %d -c ccc", dp.GetDatasetName());
			gl.LT_execute(strLT);			
			LT_get_var("ccc", &dColorOfLastFittedLine);	
		}
		//------
		*/
		
		///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
		//if(trOp.GUI.Fit.Replica.Number && trOp.GUI.Fit.Replica.Number.nVal > 0)
		//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		//if(trOp.GUI.Replica.Number && trOp.GUI.Replica.Number.nVal > 0)
		/// Iris 7/12/2010 ORG-300-P2 FIX_LCL_UCL_PLOT_COLOR_NOT_SAME_BUG		
		// the following original set plots as group code is out of time, the current fitted curve when replica num > 0:
		// case 1: only one calmulative curve plot 
		// case 2: only individual peak curve
		// case 3: cumulative curve and individual peak curve both are ploted
		// So cannot simply to group all plots including LCL, UCL, LPL, UPL, group all will cause incorrect color.
		/*
		if(get_gui_replica_node(trOp.GUI).Number && get_gui_replica_node(trOp.GUI).Number.nVal > 0)
		//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		///end 	MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		{
			///Arvin 11/27/07 WRONG_CURVES_COLOR_FOR_REPLICA_IN_SOURCE_GRAPH
			//gl.GroupPlots(nStartPlot, nEndPlot);
			//I don't know why GroupPlots can not work in source graph, but if don't do this, curves' colors are wrong
			if(bIsSourceGraph)
			{
				int nColor = GetCurveLineColor(trOp, nGraphIndex, nDataIndex, bIsSourceGraph);
				set_color_by_group_plots(gl, nStartPlot, nEndPlot, nColor);
			}
			else
				gl.GroupPlots(nStartPlot, nEndPlot);
			///end WRONG_CURVES_COLOR_FOR_REPLICA_IN_SOURCE_GRAPH
		}
		else
		*/	
		TreeNode trReplica = get_gui_replica_node(trOp.GUI);
		if( trReplica && trReplica.Number && trReplica.Number.nVal > 0 
			&& trReplica.PeakCurve && 0 != trReplica.PeakCurve.nVal )
		{
			int nFitPeakCurveStartPlot = nStartPlot;
			int nFitPeakCurveEndPlot = nStartPlot + get_gui_replica_node(trOp.GUI).Number.nVal;
			if( trReplica.CumulativeCurve && 0 != trReplica.CumulativeCurve.nVal )
				nFitPeakCurveEndPlot++;
			
			int nColor = GetCurveLineColor(trOp, nGraphIndex, nDataIndex, bIsSourceGraph);			
			set_color_by_group_plots(gl, nFitPeakCurveStartPlot, nFitPeakCurveEndPlot, nColor);
		}
		///End FIX_LCL_UCL_PLOT_COLOR_NOT_SAME_BUG
		///End FIX_LCL_UCL_PLOT_COLOR_NOT_SAME_BUG
		{
		///end GROUP_FITCURVE_FOR_MULTI_PEAKS_AND_SOURCE_DATA_IS_GROUPED
			//---- 
			
			/// Iris 08/13/2007 v8.0680 FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
			//int 	nColorOfLastFittedLine = GetCurveLineColor(trOp, nGraphIndex);
			int nIndex = -1;			
			///end FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
			
			///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
			int  nSourceColor = 0;
			bool bMultiPlotUseSourceColor = false;
			TreeNode trCurves = GetGUIGraphNodes(trOp, nGraphIndex);
			TreeNode trSetColor = trCurves.SetColor;
			///Arvin 02/14/08 QA70-11094-P3 FITTED_CURVES_COLOR_FOLLOW_SOURCE_GRAPH_IF_CHECK_SET_COLOR
			//if(bIsSourceGraph && trSetColor && trSetColor.nVal)
			if(trSetColor && trSetColor.nVal && (bIsSourceGraph || IsPlotAllPlotsInOneGraph(trOp, nGraphIndex)))
			///end 	FITTED_CURVES_COLOR_FOLLOW_SOURCE_GRAPH_IF_CHECK_SET_COLOR
			{
				bMultiPlotUseSourceColor = true;
				nSourceColor = GetCurveLineColor(trOp, nGraphIndex, nDataIndex, bIsSourceGraph);
			}
			///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
			TreeNode trConfBands = trFitCurve.ConfBands;
			if(trConfBands && trConfBands.nVal)
			{
				/// Iris 08/13/2007 v8.0680 FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
				/*
				int nColorOfConfBands = ++nColorOfLastFittedLine;//------ Iris 11/02/06 v8.0502e CORRECT_COLOR_OF_LCL_UCL_LINE				
				dp = gl.DataPlots(++nFittedPlot);
				if(dp) 
					dp.SetColor(nColorOfConfBands, true);	
					
				dp = gl.DataPlots(++nFittedPlot);
				if(dp) 
					dp.SetColor(nColorOfConfBands, true);	
				*/	
				int nColorOfConfBands = SYSCOLOR_GREEN;
				///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
				if(bMultiPlotUseSourceColor)
					nColorOfConfBands = nSourceColor;
				///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
				
				nIndex = find_plot_index_by_key(gl, "LCL", NULL, nStartPlot);
				dp = gl.DataPlots(nIndex);
				/// Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG
				//if( dp && isNewlyAddedPlotting(bUpdateExistedReportGraph, nIndex, nStartPlot, nNumFittedPlots) )
				if( dp && isNewlyAddedPlotting(nIndex, gl.DataPlots.Count(), nNumFittedPlots) )
				///End FIX_LCI_UCI_PLOT_COLOR_BUG
					dp.SetColor(nColorOfConfBands, true);	
						
				nIndex = find_plot_index_by_key(gl, "UCL", NULL, nStartPlot);
				dp = gl.DataPlots(nIndex);				
				/// Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG
				//if( dp && isNewlyAddedPlotting(bUpdateExistedReportGraph, nIndex, nStartPlot, nNumFittedPlots) )
				if( dp && isNewlyAddedPlotting(nIndex, gl.DataPlots.Count(), nNumFittedPlots) )
				///End FIX_LCI_UCI_PLOT_COLOR_BUG
					dp.SetColor(nColorOfConfBands, true);	
				//end FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
			}
			
			
			TreeNode trPredBands = trFitCurve.PredBands;
			if( trPredBands && trPredBands.nVal)
			{
				/// Iris 08/13/2007 v8.0680 FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
				/*
				int nColorOfPredBands = ++nColorOfLastFittedLine;//------ Iris 11/02/06 v8.0502e CORRECT_COLOR_OF_LCL_UCL_LINE
				dp = gl.DataPlots(++nFittedPlot);
				if(dp) 
					dp.SetColor(nColorOfPredBands, true);
						
				dp = gl.DataPlots(++nFittedPlot);
				if(dp) 
					dp.SetColor(nColorOfPredBands, true);
				*/
				int nColorOfPredBands = SYSCOLOR_BLUE;
				///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
				if(bMultiPlotUseSourceColor)
					nColorOfPredBands = nSourceColor;
				///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
				
				nIndex = find_plot_index_by_key(gl, "LPL", NULL, nStartPlot);
				dp = gl.DataPlots(nIndex);
				/// Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG
				//if( dp && isNewlyAddedPlotting(bUpdateExistedReportGraph, nIndex, nStartPlot, nNumFittedPlots) )
				if( dp && isNewlyAddedPlotting(nIndex, gl.DataPlots.Count(), nNumFittedPlots) )
				///End FIX_LCI_UCI_PLOT_COLOR_BUG
					dp.SetColor(nColorOfPredBands, true);	
						
				nIndex = find_plot_index_by_key(gl, "UPL", NULL, nStartPlot);
				dp = gl.DataPlots(nIndex);				
				/// Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG
				//if( dp && isNewlyAddedPlotting(bUpdateExistedReportGraph, nIndex, nStartPlot, nNumFittedPlots) )
				if( dp && isNewlyAddedPlotting(nIndex, gl.DataPlots.Count(), nNumFittedPlots) )
				///End FIX_LCI_UCI_PLOT_COLOR_BUG
					dp.SetColor(nColorOfPredBands, true);	
				//end FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
			}
			
			TreeNode trEllipse = trFitCurve.Ellipse;
			if( trEllipse && trEllipse.Use)
			{
				if(trEllipse.Mean.Use)
				{
					/// Iris 08/13/2007 v8.0680 FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
					/*
					dp = gl.DataPlots(++nFittedPlot); //Ellipse Mean plot
					if(dp)
					{
						dp.SetColor(++nColorOfLastFittedLine, true);
					}
					*/
					///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
					int nColorOfEllipseMean = SYSCOLOR_CYAN;
					if(bMultiPlotUseSourceColor)
						nColorOfEllipseMean = nSourceColor;
					///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
					nIndex = find_plot_index_by_key(gl, "Ellipse", "Mean");
					dp = gl.DataPlots(nIndex);
					/// Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG
					//if( dp && isNewlyAddedPlotting(bUpdateExistedReportGraph, nIndex, nStartPlot, nNumFittedPlots) )
					if( dp && isNewlyAddedPlotting(nIndex, gl.DataPlots.Count(), nNumFittedPlots) )
					///End FIX_LCI_UCI_PLOT_COLOR_BUG
					///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
						//dp.SetColor(SYSCOLOR_CYAN, true);
						dp.SetColor(nColorOfEllipseMean, true);
						///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
					//end FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
					
				}				
				
				if(trEllipse.Pred.Use)
				{
					/// Iris 08/13/2007 v8.0680 FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
					/*
					dp = gl.DataPlots(++nFittedPlot); //Ellipse Pred plot
					if(dp)
					{
						dp.SetColor(++nColorOfLastFittedLine, true);
					}
					*/
					///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
					int nColorOfEllipsePred = SYSCOLOR_MAGENTA;
					if(bMultiPlotUseSourceColor)
						nColorOfEllipsePred = nSourceColor;
					///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
					nIndex = find_plot_index_by_key(gl, "Ellipse", "Pred");
					dp = gl.DataPlots(nIndex);
					/// Iris 6/17/2010 ORG-300 FIX_LCI_UCI_PLOT_COLOR_BUG
					//if( dp && isNewlyAddedPlotting(bUpdateExistedReportGraph, nIndex, nStartPlot, nNumFittedPlots) )
					if( dp && isNewlyAddedPlotting(nIndex, gl.DataPlots.Count(), nNumFittedPlots) )
					///End FIX_LCI_UCI_PLOT_COLOR_BUG
						///Arvin 10/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
						//dp.SetColor(SYSCOLOR_MAGENTA, true);
						dp.SetColor(nColorOfEllipsePred, true);
						///end  ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
					//end FIX_NEW_ADDED_PLOT_ARE_RED_AFTER_CHANGE_PARAM
					
				}				
				
			}
			
			
		}/// Iris 08/10/2007 v8.0679 GROUP_FITCURVE_FOR_MULTI_PEAKS_AND_SOURCE_DATA_IS_GROUPED
		
		
		/// Iris 01/23/2007 v8.0546 CONTROL_UPDATE_OR_NOT_UPDATE_LEGEND
		///Arvin 11/29/07 CONTROL_UPDATE_OR_NOT_UPDATE_SOURCE_GRAPH_LEGEND_BY_CHECK_BOX
		//bool	bUpdateLegend = true; //should be auto update fitted curve legend as default since there is not a control to ask if update legend in Fit Linear, only in NLSF now
		//if(bIsSourceGraph)
		//{
			////to check if update Legend on Original Graph
			//TreeNode trUpdateLegend = trOp.GUI.Graph1.UpdateLegend;
			//if(trUpdateLegend)
			//{
				//if(!trUpdateLegend.Enable || !trUpdateLegend.Show || 0 == trUpdateLegend.nVal)
				//{
					//bUpdateLegend = false;
				//}
			//}
		//}
		//
		//if(bUpdateLegend) 
		//{
			//for(int nPlot = nStartPlot; nPlot <= nEndPlot; nPlot++)
				//legend_append_plot(gl, nPlot, "@LG");
		//}
		///end CONTROL_UPDATE_OR_NOT_UPDATE_SOURCE_GRAPH_LEGEND_BY_CHECK_BOX
			///end SHOULD_KEEP_EXIST_LEGEND_FORMAT_WHNE_UPDATE_SRC_GRAPH
		///end CONTROL_UPDATE_OR_NOT_UPDATE_LEGEND		

		/// Iris 08/06/2007 v8.0674 X_DATA_TYPE_JUST_EFFECT_ON_XFITDATA_NOT_CHANGE_AXIS_TYPE, from Max's suggestion
		/*
		/// Iris 11/15/05 QA70-3479-P3 SETUP_FIT_GRAPH_X_AXIS			
		if(GRAPH_FIT_CURVE == nGraphIndex && !bIsSourceGraph) //only set for Fitted Curve here, and did not update on Source Graph
		{
			TreeNode trXDataType = trFitCurve.XDataType;
			if(trXDataType)
			{				
				if(FIT_CURVE_UNIFORM_LINEAR == trXDataType.Use || FIT_CURVE_UNIFORM_LOG == trXDataType.Use)
				{
					int		nType = trXDataType.Use; //0 = linear, 1 = log, etc.
					string 	strXAxis = "axis -ps X S " + nType;
					gl.LT_execute(strXAxis);
				}					
			}
		}
		///End SETUP_FIT_GRAPH_X_AXIS
		*/
		///end X_DATA_TYPE_JUST_EFFECT_ON_XFITDATA_NOT_CHANGE_AXIS_TYPE
		

	}	


	///Jim 3/1/06 v8.0370 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
	///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	//void SetupLagPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nGraphIndex)
	//{		
		//foreach(DataPlot dp in gl.DataPlots)
		//{
			//dp.SetColor(SYSCOLOR_RED, true);					
		//}		
	//}	
	
	/// Iris 9/24/2009 QA80-11710-P3 ALL_PLOTS_ARE_RED_IN_RESIDUAL_GRAPH_WHEN_PLOT_IN_ONE_GRAPH
	// Residual Scatter plot not check if bUpdateExistedReportGraph when plot in one graph same as fit curve, always keep data plot color increame.
	//virtual BOOL SetupResidualScatterPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nGraphIndex, int nDataIndex)
	virtual BOOL SetupResidualScatterPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nGraphIndex, int nDataIndex, bool bUpdateExistedReportGraph)
	///end ALL_PLOTS_ARE_RED_IN_RESIDUAL_GRAPH_WHEN_PLOT_IN_ONE_GRAPH
	{
		DataPlot dp = gl.DataPlots(nDataIndex);
		if(!dp.IsValid())
			return FALSE;
		if(IsPlotAllPlotsInOneGraph(trOp, nGraphIndex))
			return dp.SetColor(SYSCOLOR_RED + nDataIndex);
		
		/// Iris 9/24/2009 QA80-11710-P3 ALL_PLOTS_ARE_RED_IN_RESIDUAL_GRAPH_WHEN_PLOT_IN_ONE_GRAPH
		//return dp.SetColor(SYSCOLOR_RED);
		if( !bUpdateExistedReportGraph )
			return dp.SetColor(SYSCOLOR_RED); 	
		return TRUE;
		///end ALL_PLOTS_ARE_RED_IN_RESIDUAL_GRAPH_WHEN_PLOT_IN_ONE_GRAPH
	}
	///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	//END ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH

	//virtual 
	bool 	OnInputDataSelectionChange(TreeNode& trOperation);
	///Arvin 06/15/07 WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS
	virtual bool IsCreateHistogramGraph(TreeNode& trOp)
	{
		return IsCreateReportGraph(trOp, GRAPH_RESIDUALS_HISTOGRAM);
	}
	///end WRONG_HISTOGRAM_AND_BOXCHART_PLOTS_WHILE_DATA_HAVE_FACTORS
	
	///Arvin 05/18/07 USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
	bool IsDatasetHasWeight(TreeNode& trInput, int nIndex = 0, string& strWeight = NULL)
	{
		// if not select error col, then should disable Error as Weight control
		bool		bHasErr = false;
		int ii = 0;
		foreach(TreeNode trRange in trInput.Children)
		{
			if(ii == nIndex)
			{
				if(trRange.ED && !trRange.ED.IsEmpty() )
				{
					if(strWeight)
						strWeight = trRange.ED.strVal;
					
					return true;
				}
				/// Iris 11/24/2009 QA81-3224-P4 FIX_WEIGHT_NOT_CORRECT_IN_NOTES_TABLE_FOR_LR_WITH_XERR
				else if(trRange.EI && !trRange.EI.IsEmpty() )
				{
					if(strWeight)
						strWeight = trRange.EI.strVal;
					return true;
				}
				///end FIX_WEIGHT_NOT_CORRECT_IN_NOTES_TABLE_FOR_LR_WITH_XERR
				///Sophy 8/31/2010 ORG-945-P1 FITTING_OPERATIONS_FROM_QUICK_FIT_FAIL_TO_DETECT_WEIGHT_METHOD
				else if ( trRange.W && !trRange.W.IsEmpty() )
				{
					if ( strWeight )
						strWeight = trRange.W.strVal;
					return true;
				}
				///end FITTING_OPERATIONS_FROM_QUICK_FIT_FAIL_TO_DETECT_WEIGHT_METHOD
				else
					return false;
			}
			
			ii++;
		}			
	
		return false;
	}	
	///end USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
	
	/// Iris 10/26/2009 FIX_FIT_LINEAR_PLOT_RESIDUAL_HISTOGRAM_IN_ONE_LAYER
	/*
	///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	virtual int	GetNumberLayersInOneGraph(TreeNode& trOp, int nGraphIndex)
	{
		if(GRAPH_RESIDUALS_HISTOGRAM == nGraphIndex && IsPlotAllPlotsInOneGraph(trOp, nGraphIndex))
			return GetTotalNumPictureForOneGraphType(trOp, nGraphIndex);
		
		return 1;
	}
	///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	*/
	///end FIX_FIT_LINEAR_PLOT_RESIDUAL_HISTOGRAM_IN_ONE_LAYER
	
	bool	IsAppendParamFootnote(TreeNode& trOp); /// Iris 4/16/2008 REMOVE_PARAM_TABLE_IF_IT_IS_EMPTY
	
	///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
	bool UpdateOneXColumnFormat(TreeNode& trCol, int nIndex);
	///end FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
private:
	bool isMatValid(const matrix& mCov)
	{
		if(mCov == NULL)
			return false;
		if(mCov.GetNumRows() > 0 && mCov.GetNumCols() > 0)
			return true;
		
		return false;
	}
	

protected:	
	//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	string GetResultCurveMainTableLabel(TreeNode& trOp, int nTotalNumData, LPCSTR lpcszDataLabel) 
	{
		string			strLabel; // keep it empty for one dataset
		if(!IsSeparateSheetForDataset(trOp) && 1 < nTotalNumData)
		{
			string	strConvertedDataLabel(lpcszDataLabel);
			ConvertEscapedString(strConvertedDataLabel);
			
			/// Iris 3/23/2009 QA80-13331-P1 CENTRILIZE_REPORT_COL_LABEL_CODES
			//strLabel = _L("Fit Curve") + " " + _L("of") + " " + strConvertedDataLabel;		
			strLabel = ConstructReportDataColLabel(_L("Fit Curve"), strConvertedDataLabel);
			///end CENTRILIZE_REPORT_COL_LABEL_CODES
		}	
		return strLabel;
	}	
	
	string GetResidualDataTableLabel()
	{
		return STR_REPORT_RESIDUAL_TABLE_LABEL;
	}
	
	string GetDiffResidualDataTableTagName(int nResType);	
	string GetResidualDataTableYDataLabel(int nResType, LPCSTR lpcszDataLabel = NULL); //--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	
	string GetResidualDataTableYDataSubLabel()
	{
		return STR_REPORT_RESIDUAL_TABLE_SUB_LABEL;
	}
	
	TreeNode CheckCreateOneFitCurvesTable(TreeNode& trOp, int index, int nTotalNumData)
	{
		string			strData;
		GetEscapedMainDataString(trOp, strData, index + 1);
		ConvertEscapedString(strData);		
		
		string 		strTableLabel = GetResultCurveMainTableLabel(trOp, nTotalNumData, strData);
		
		/// Iris 3/19/2009 QA80-13285-P2 FIT_RESULT_CURVE_COL_LABEL_NEW_DESIGN
		//TreeNode	trFC = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_FIT_CURVE, STR_FIT_CURVES_TABLE, IDST_FIT_CURVES, STR_REPORT_FIT_CURVE_SUB_TABLE_LABEL, strTableLabel);
		string		strTableSubLabel = STR_REPORT_FIT_CURVE_SUB_TABLE_LABEL;
		TreeNode	trFC = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_FIT_CURVE, STR_FIT_CURVES_TABLE, IDST_FIT_CURVES, strTableSubLabel, strTableLabel);
		///end FIT_RESULT_CURVE_COL_LABEL_NEW_DESIGN
		
		return trFC;
	}	
	//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	
	virtual bool UseResidualAnalysisDataReportForPlotting(TreeNode &trOp, int* pnYIndex = NULL); //--- Iris 3/16/2009 QA80-13285-P1 FIX_DUPLICATE_RESIDUAL_DATA_REPORT_FOR_DIFF_RESIDUAL_REPORT_AND_PLOT

	///Arvin 01/07/08 QA70-10903 ADD_CHECK_ALL_BOX_FOR_BRANCH
	virtual bool AddCheckAllBoxForPlotsNode(TreeNode& trPlots)
	{
		return tree_set_branch_attribute_for_branch(trPlots, GETNBRANCH_CHECK_CONTROL|GETNBRANCH_CHECK_CONTROL_ONE_EVENT);
	}
	///end ADD_CHECK_ALL_BOX_FOR_BRANCH
	
	///////////////////////////////////////////////////////////	
	/// Iris 11/16/06 CLEAR_OUT_TABLES_BEFORE_CALC_WHEN_DO_CHANGE_PARAMS
	/*
	void	OnBeforeCalculations(TreeNode& trOperation)
	{
		WksReportOperation::OnBeforeCalculations(trOperation);
		
		TreeNode trParameters = getParameters(trOperation);
		if( trParameters.IsValid())
			trParameters.RemoveChildrenWithPrefix(CALCULATION_PARAMETER_PREFIX);			
	}
	*/
	///Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION	
	//Need call this method from oc code, so move it to public session
	//void  ClearOutputTables(TreeNode& trOperation)
	//{
		//StatsOpBase::ClearOutputTables(trOperation);	
		//
		//bool		bKeepAttrib = true;
		//TreeNode 	trOut = trOperation.Calculation;
		//if(trOut.Parameters)
			//trOut.Parameters.Reset(bKeepAttrib);
		//if(trOut.RegStats)
			//trOut.RegStats.Reset(bKeepAttrib);
		//if(trOut.Summary)
			//trOut.Summary.Reset(bKeepAttrib);
		/////Arvin 05/31/07 CLEAR_COVARIANCE_AND_CORRELATION_MATRIX_TABLE
		//if(trOut.Covariance)
			//trOut.Covariance.Reset(bKeepAttrib);
		//if(trOut.Correlation)
			//trOut.Correlation.Reset(bKeepAttrib);
		/////end CLEAR_COVARIANCE_AND_CORRELATION_MATRIX_TABLE
		/////Cheney 2007-4-12 CLEAR_DATA_MODE_IN_NOTES_TABLE_WHEN_CHANGE_PARAMS
		//if(trOut.Notes.DataMode)
			//trOut.Notes.DataMode.Remove();
		/////end CLEAR_DATA_MODE_IN_NOTES_TABLE_WHEN_CHANGE_PARAMS
	//}
	///end XOP_NEED_SUPPORT_CHANGE_FUNCTION
	///end CLEAR_OUT_TABLES_BEFORE_CALC_WHEN_DO_CHANGE_PARAMS
	
	///Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	//TreeNode getParameters(TreeNode& trOperation)
	TreeNode getParameters(TreeNode& trOperation, bool bGetDerivedParams = true)
	///end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	{
		///Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
		//return trOperation.Calculation.Parameters;
		TreeNode trParams = trOperation.Calculation.Parameters;
		
		if(!bGetDerivedParams)
		{
			foreach(TreeNode trNode in trParams.Children)

			{
				int nDerivedparam;
				trNode.GetAttribute(STR_ATTRIB_DERIVED_PARAM, nDerivedparam);
				if(nDerivedparam)
					trNode.Remove();
			}
		}
	
		return trParams;
		///end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	}
	virtual void	FilterParameterQuantities(TreeNode& trRow) {}
	
	virtual void	FilterFittingGUI(TreeNode& trOp) 
	{
		///Iris 6/04/05 MOVE_FITTED_CURVES_TO_ROOT_LEVEL
		UpdateGUIGraphs(trOp);
		///end MOVE_FITTED_CURVES_TO_ROOT_LEVEL
		
		///Arvin 01/07/08 QA70-10903 ADD_CHECK_ALL_BOX_FOR_BRANCH
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode trOptionalReport = trOp.GUI.Output.Create;
		TreeNode trOptionalReport = OP_GUI_OUTPUT_TABLES_BRANCH(trOp.GUI);
		///end OP_DLG_NEW_STRUCTURE
		if(trOptionalReport)
			AddCheckAllBoxForOptionalReport(trOptionalReport);	
		TreeNode trResPlots = trOp.GUI.Residuals;
		if(trResPlots)
			AddCheckAllBoxForPlotsNode(trResPlots);
		///END ADD_CHECK_ALL_BOX_FOR_BRANCH		
		
		///Jasmine 11/08/07 ADD_SHARED_TO_PARAMETER_REPORT_TABLE
		vector<int> vnNodesToHide = {IDE_PARAM_SHARED};
		tree_set_attributes(trOp.GUI, vnNodesToHide, "0");
		///End ADD_SHARED_TO_PARAMETER_REPORT_TABLE
	}
	
	/// Iris 12/29/2006 v8.0534 PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
	//virtual	int		GetNumParams(TreeNode &trOp, vector<string> &vstrParameterNames, int index = 0)
	virtual	int		GetParameters(TreeNode &trOp, int index = 0, vector<string> &vstrParameterNames = NULL, bool bIncNumPostfix = false, bool bIncDerivedParams = false, vector<bool>& vbIsDerived = NULL)
	{
		error_report("GetParameters not implemented");
		return 0;
	}
	
	///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	virtual int		GetParamUnits(TreeNode& trOp, int index = 0, vector<string> &vstrParameterUnits = NULL, bool bIncDerivedUnits = false, vector<bool>& vbIsDerived = NULL)
	{
		error_report("GetParamUnits not implemented");
		return 0;
	}
	///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT

	/// ML 11/13/2006 THEME_DIGITS_PARAMETERS_TBL
	bool	makeParamsTblTheme(TreeNode &trOp, TreeNode &treeTh, int numData);
	// virtual
	void	OnAfterCreateReport(TreeNode &trOp, Worksheet& wksReport, DataRange& rngInput, DataRange &rgReportSheetOutput, int nExeMode, bool bNewResultBookCreatedHidden, int nTotalNumData);
	/// end THEME_DIGITS_PARAMETERS_TBL

	///Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
	//virtual
	bool 	AddHintsForMissingAndMasked(TreeNode& trOperation);
	///end ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
	
	/// ML 10/20/2004 QA70-7075 MASKED_DATA_REPORTING
	// virtual
	bool	HasX()
	{
		return true;
	}
	/// end MASKED_DATA_REPORTING
	
	/// ML 9/18/2006 DATARANGE_EXTRACTION_APPARENT_FIT
	bool	IsApparentFit(TreeNode &trOp);
	/// end DATARANGE_EXTRACTION_APPARENT_FIT

	//virtual
	DWORD	GetDataRules(const TreeNode& trOperation, bool bIgnoreCombineInfo = false)
	{
		/// Iris 6/02/05 GET_RAW_ERR_COLUMN_AS_WEIGHTING
		//DWORD		dw = DRR_DEPERR_TO_WEIGHT | DRR_GET_DEPENDENT | DRR_NO_FACTORS | DRR_BAD_WEIGHT_TREATMENT;
		DWORD		dw = DRR_GET_DEPENDENT | DRR_NO_FACTORS | DRR_RAW_ERR_WEIGHT;
		///end GET_RAW_ERR_COLUMN_AS_WEIGHTING
		/// ML 9/18/2006 DATARANGE_EXTRACTION_APPARENT_FIT
		if ( IsApparentFit(trOperation) )
			dw |= DRR_APPARENT;
		/// end DATARANGE_EXTRACTION_APPARENT_FIT
		
		return CheckDataRules(trOperation, dw, bIgnoreCombineInfo);
	}
	//virtual 
	bool UpdateInsertedColumns(TreeNode& trOperation, const DataRange& rngInput, int nDataIndex, int nTotalNumData, DataRange& rngOutput, int nOutOption);
	
	/// Iris 12/30/2006 v8.0534 CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE
	//bool	AddOneDataStatsResultsToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, const FitParameter* pFitParams, const RegANOVA& sANOVA, const RegStats &sRegStats, matrix& mCov = NULL, matrix& mCorr = NULL, const vector<string>& vsDerivedParamNames=NULL, const vector<double>& vdDerivedParamValues = NULL);
	///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
	//bool	AddOneDataStatsResultsToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesWithPostfix, const RegANOVA& sANOVA, const RegStats &sRegStats, matrix& mCov = NULL, matrix& mCorr = NULL, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, bool bReportStats = true, bool bReportANOVA = true);
	///Arvin 08/03/07 WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
	//bool	AddOneDataStatsResultsToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesWithPostfix, const RegANOVA& sANOVA, const RegStats &sRegStats, matrix& mCov = NULL, matrix& mCorr = NULL, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, bool bReportStats = true, bool bReportANOVA = true, RegANOVARow& stCorrTotal = NULL);
	///Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said
	//bool	AddOneDataStatsResultsToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesWithPostfix, const RegANOVA& sANOVA, const RegStats &sRegStats, matrix& mCov = NULL, matrix& mCorr = NULL, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, bool bReportStats = true, bool bReportANOVA = true, RegANOVARow& stCorrTotal = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0);
	//------ Folger 12/01/08 v8.0981 MORE_ON_USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
	//bool	AddOneDataStatsResultsToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesWithPostfix, const RegANOVA& sANOVA, const RegStats &sRegStats, matrix& mCov = NULL, matrix& mCorr = NULL, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, bool bReportStats = true, bool bReportANOVA = true, RegANOVARow& stCorrTotal = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0, vector<bool> &vbIsShared = NULL);
	///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	//bool	AddOneDataStatsResultsToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesWithPostfix, const RegANOVA& sANOVA, const RegStats &sRegStats, matrix& mCov = NULL, matrix& mCorr = NULL, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, bool bReportStats = true, bool bReportANOVA = true, RegANOVARow& stCorrTotal = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0, vector<bool> &vbIsShared = NULL, const string* pstrDataLabelUnconverted = NULL);
	bool	AddOneDataStatsResultsToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, vector &vY, vector &vX, matrix &mMultiIndep, const FitParameter* pFitParams, const FITPARAMSINFO& stParamInfo, const RegANOVA& sANOVA, const RegStats &sRegStats, matrix& mCov = NULL, matrix& mCorr = NULL, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, bool bReportStats = true, bool bReportANOVA = true, RegANOVARow& stCorrTotal = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0, vector<bool> &vbIsShared = NULL, const string* pstrDataLabelUnconverted = NULL);
	///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	//------
	///end ADD_STAR_MARK_FOR_SHARED_PARAMS
	///end WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
	///END ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
	///end CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE
	/// end NLFITTER_OPERATION_IMPLEMENTATION
	
	/// Iris 5/19/2008 RENAME_OLD_FUNCTION_AND_MOVE_TO_SUIT_PLACE
	//virtual void 	OnAfterAddOneDataStatsResultsToReportTree(TreeNode &trOp, int index);
	virtual void 	OnAfterAddParamtersSummaryTable(TreeNode &trOp, int index);
	///end RENAME_OLD_FUNCTION_AND_MOVE_TO_SUIT_PLACE	
	
	// virtual
	BOOL	GetCustomTableDefaultTheme(TreeNode &treeTh);

	virtual	int		GetStatisticsTablePropertiesForCustomTable(vector<int> &vn);
	/// ML 4/28/2006 FRIENDLY_CUSTOM_TABLE_THEME_GENERATION
	// virtual
	int		GetTableIdForGraph(string *pstr, TreeNode& trOp);
	/// end FRIENDLY_CUSTOM_TABLE_THEME_GENERATION

	
protected:
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//virtual bool AddRegStatsToReportTree(TreeNode& trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, const RegStats &sRegStats);
	virtual bool AddRegStatsToReportTree(TreeNode& trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, const RegStats &sRegStats, int* pnSetIndex = NULL);
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	///Arvin 05/23/07 v8.0624 COV_AND_CORR_TABLE_CHAOS_WHILE_CHANGE_PARAMETER
	///Arvin 05/23/07 v8.0624 COV_AND_CORR_TABLE_CHAOS_WHILE_CHANGE_PARAMETER
	//bool AddCovOrCorrMatrixToReportTree(TreeNode &trOp, const string& strDataLabel, int index, int nTotalNumData, int nID, const matrix& mCovOrCorr, const vector<string> &vstrParamNames);
	bool AddCovOrCorrMatrixToReportTree(TreeNode &trOp, const string& strDataLabel, int index, int nTotalNumData, int nID, const matrix& mCovOrCorr, const vector<string> &vstrParamNames, vector<bool> &vbIsDerived = NULL);
	///end COV_AND_CORR_TABLE_CHAOS_WHILE_CHANGE_PARAMETER
	///end COV_AND_CORR_TABLE_CHAOS_WHILE_CHANGE_PARAMETER
	
	///Arvin 06/12/07 OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT
	void RemoveUnusedParams(vector<string> &vstrParamNames, vector<bool> &vbUnused);
	///end OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT
	
	///Arvin 11/09/07 SUPPORT_FIX_SLOPE_IN_FITLINEAR
	//virtual
	virtual bool  RemoveFixedInterceptAndSlope(TreeNode& trGUI, vector<string>& vStrParams);
	///end SUPPORT_FIX_SLOPE_IN_FITLINEAR
	
	//virtual
	
	/// YuI 12/07/04 v7.5172 PICTURE_IN_REPORT_IMPROVEMENT
	/*
	bool PlotReportGraph(int index, GraphLayer& gl, Worksheet& wksReport, DataRange& rReport, TreeNode& trOp, int nTotalNumData, int nGraphIndex = 0)
	{
		TreeNode	trFit = getFitCuvesTable(trOp, nTotalNumData, index);
		
		XYRange xyR;
		xyR.xMin = xyR.xMax = xyR.yMin = xyR.yMax = NANUM;
		
		addInputDataPlot(index, gl, trFit, trOp, xyR.yMin, xyR.yMax);
		// add fit curves after data, so fit is in front of data is layer drawing order
		uint uID = PlotFitCurves(trOp, gl, rReport, trFit.ID, &xyR);
		if( uID )
		{
			if(checkRangeAddMargin(xyR.xMin, xyR.xMax))
			{
				gl.X.From = xyR.xMin;
				gl.X.To = xyR.xMax;
			}
			if(checkRangeAddMargin(xyR.yMin, xyR.yMax))
			{
				gl.Y.From = xyR.yMin;
				gl.Y.To = xyR.yMax;
			}
			/// ML 12/17/2004 PROGRAMMATICALLY_PUTTING_A_REPORT_TABLE_INTO_A_GRAPH
			addReportTableToGraph(gl, rReport);
			/// end PROGRAMMATICALLY_PUTTING_A_REPORT_TABLE_INTO_A_GRAPH
			gl.LT_execute("legend");
			return true;
		}
		return error_report("FitterOperation PlotReportGraph failed");
	}
	*/
	///Iris 4/01/05 FIT_REGRESSION_PLOTS
	/* 
	virtual uint	GetResultCurveTableID(TreeNode& trOp, int nDataIndex, int nTotalNumData)
	{
		TreeNode trFit = getFitCuvesTable(trOp, nDataIndex, nTotalNumData);
		if( trFit )
			return trFit.ID;
		
		return WksReportOperation::GetResultCurveTableID(trOp, nDataIndex, nTotalNumData);
	}
	
	virtual bool IsSourceDataPlotInReport()
	{
		return true;
	}
	*/
	
	//--- Iris 3/16/2009 QA80-13285-P1 FIX_DUPLICATE_RESIDUAL_DATA_REPORT_FOR_DIFF_RESIDUAL_REPORT_AND_PLOT
	//virtual 
	BOOL			GetResultTableData(TreeNode& trOp, int nResultTableID, int nDataIndex, int nGraphIndex, DataRange& drTable, DataRange& drFitCurvesRange = NULL);
	//---
	
	virtual uint	GetResultCurveTableID(TreeNode& trOp, int nDataIndex, int nTotalNumData = -1, int nGraphIndex = 0)
	{
		//--- Iris 3/16/2009 QA80-13285-P1 FIX_DUPLICATE_RESIDUAL_DATA_REPORT_FOR_DIFF_RESIDUAL_REPORT_AND_PLOT
		int nResType = GUIHasWhatTypeResidualGraph(trOp);
		if( GRAPH_RESIDUALS_SCATTER == nGraphIndex && UseResidualAnalysisDataReportForPlotting(trOp) )
		{
			return GetOneResultCurvesTableID(IDST_FIT_RESIDUAL_ANALYSIS, nDataIndex);
		}
		//--- FIX_DUPLICATE_RESIDUAL_DATA_REPORT_FOR_DIFF_RESIDUAL_REPORT_AND_PLOT

		TreeNode trGraphTable;
		//--- CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
		/*
		switch(nGraphIndex)
		{
		case GRAPH_FIT_CURVE:
			trGraphTable = getFitCuvesTable(trOp, nDataIndex, nTotalNumData);
			break;		
		case GRAPH_RESIDUALS_SCATTER:  /// Iris 6/02/05 ADD_RESIDUALS_SCATTER_GRAPH
		case GRAPH_RESIDUALS_HISTOGRAM:
		case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
		case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
			trGraphTable = getOneResidualTable(trOp, nDataIndex, nTotalNumData, nGraphIndex);
			break;
		default:
			break;
		}
		*/
		trGraphTable = GetOneResultCurvesTable(trOp, nDataIndex, nTotalNumData, nGraphIndex);
		//---
		if( trGraphTable )
			return trGraphTable.ID;		
			
		return WksReportOperation::GetResultCurveTableID(trOp, nDataIndex, nTotalNumData);		
	}	
	//virtual 
	bool IsGraphTableInsertBackToSourceType(int nGraphIndex)
	{
		//--- Iris 10/13/06 v8.0495 OUTPUT_FIT_CURVE_TO_SOURCE_NOT_WORK
		//if(GRAPH_FIT_CURVE == nGraphIndex)		
			//return true;
		//return false;
		return true;
		//---
		
	}
	
	virtual bool IsSourceDataPlotInReport(int nGraphIndex)
	{		
		switch(nGraphIndex)
		{
		case GRAPH_FIT_CURVE:
		///Cheney 2006-9-13 NOT_PLOT_SRCDATA_WHEN_CONCATENATE_AND_PLOTTYPE_IS_MEAN_SE_OR_SD
			return !isPlotAverageData();
		///end NOT_PLOT_SRCDATA_WHEN_CONCATENATE_AND_PLOTTYPE_IS_MEAN_SE_OR_SD		
		default:
			return false;
		}
		return false;
	}
	virtual bool IsResultsPlotInReport(int nGraphIndex)
	{
		switch(nGraphIndex)
		{
		case GRAPH_FIT_CURVE:
		case GRAPH_RESIDUALS_SCATTER: /// Iris 6/02/05 ADD_RESIDUALS_SCATTER_GRAPH
		case GRAPH_RESIDUALS_HISTOGRAM:
		case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
		case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
		case GRAPH_RESIDUALS_LAG_PLOT: ///Jim 2/22/06 v8.0368 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
			return true;
		default:
			return false;			
		}
		return false;
	}
	
	///Iris 3/23/05 HIDDEN_CORRELATION_IN_PR_MR
	virtual void FilterStatsReport(TreeNode &trOp)
	{
		//------ Folger 03/19/08 QA80-10598 NEW_GETN_LOCALIZAED_CHECK_MACRO
		//tree_copy_values_to_attributes(trOp.GUI.Quantities, trOp.Calculation, STR_LABEL_ATTRIB);
		FilterStatsReport(trOp.GUI.Quantities, trOp.Calculation);
		//------ End NEW_GETN_LOCALIZAED_CHECK_MACRO
		return;
	}
	
	/// Iris 12/29/2006 v8.0534 PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
	virtual bool 	ParamsNamesAddPostfix(vector<string>& vsParamNames, int index = 0, int nFunc = 0);
	///end PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
	
public:
	///Sophy 6/4/2008 CORRECT_FIT_OUTPUT_GUI_CURVE_NAME
	//virtual
	string  GetResultCurveGUIName(TreeNode& trGUI)
	{
		return STR_OUTPUT_FIT_RESULT_CURVE_TABLES;
	}
	///end CORRECT_FIT_OUTPUT_GUI_CURVE_NAME
	
	///Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION
	//virtual
	void  ClearOutputTables(TreeNode& trOperation);
	///end XOP_NEED_SUPPORT_CHANGE_FUNCTION
	
	///Cheney 2006-9-1 ADD_AVERAGE_DATA
	bool 		AddAveData(TreeNode& trOp, int nIndex, TreeNode& trFC, vector& vX, vector& vY);
	///end ADD_AVERAGE_DATA
	/// ML 9/20/2006 RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
	//bool 		AddResidualsDataTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mMultiIndep);
	//bool 		AddResidualHistogramTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mXs);
	//bool 		AddResidualFitTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mXs);
	//bool 		AddResidualOrderTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mXs);
	//bool 		AddResidualLagTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mXs); ///Jim 2/24/06 v8.0368 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
	bool		GUIHasResidualTable(TreeNode &trOp, int nGraphIndex);
	///Arvin 12/11/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	//virtual bool	AddResidualTables(bool bDataTbl, TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, vector &vX, vector &vY, matrix &mXs, GraphLayer &grLayAppar = NULL);
	///Arvin 01/17/06 CALC_RESIDUAL_WITH_REPLICA
	//virtual 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);
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//virtual 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);
	virtual 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
	///end CALC_RESIDUAL_WITH_REPLICA
	///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	///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, matrix &mXs, matrix &mYs);
	bool		AddResidualTables(bool bDataTbl, TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, FitParameter *psFitParameter, matrix &mXs, matrix &mYs, LPCSTR lpcsDataLabelCurves = NULL);
	///end CENTRALIZE_FITTING_RESULT_LABELS
	/// end RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
	
	///Arvin 12/11/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	///Arvin 01/18/06 CALC_RESIDUAL_WITH_REPLICA
	//We can not do residual analysis for muti-peak fitting, so disable it temporarily
	//bool GetOneTypeResidualData(const TreeNode &trOp, const vector& vX, const vector &vY, FitParameter *psFitParameter, vector& vResidual, int nResType, int index, int nMultiplicity, vector &vWeights, matrix &mXs, GraphLayer &grLayAppar);
	bool GetOneTypeResidualData(const TreeNode &trOp, const vector& vX, const vector& vRegularRes, vector& vResidual, int index = 0, int nPeak = 0, int nResType = REGULAR_RESIDUAL, vector &vY = NULL, vector &vWeights = NULL, matrix &mXs = NULL);
	///end CALC_RESIDUAL_WITH_REPLICA	

	//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	//bool AddDiffTypeResidualDataTable(TreeNode &trTable, vector& vRe, int nResType = REGULAR_RESIDUAL);
	bool AddDiffTypeResidualDataTable(TreeNode &trTable, LPCSTR lpcszDataLabel, vector& vRe, int nResType = REGULAR_RESIDUAL);
	//--- CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	
	virtual 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);
	bool	GUIHasWhatTypeResidualTables(TreeNode &trOp, int nResType = REGULAR_RESIDUAL);
	int		GUIHasWhatTypeResidualGraph(TreeNode &trOp);
	///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	
	///Arvin 02/13/07 ADD_X_DATA_TO_RESIDUAL_DATA_TABLE
	bool AddXDataTable(TreeNode &trTable, vector& vX);
	///end ADD_X_DATA_TO_RESIDUAL_DATA_TABLE
	
	///Arvin 01/17/06 CALC_RESIDUAL_WITH_REPLICA
	///Arvin 12/10/07 WRONG_RESIDUAL_DATA_IN_PFW
	//bool GetCumRegularResidualData(const TreeNode &trOp, const vector& vX, const vector &vY, FitParameter *psFitParameter, vector& vCumRegular, vector& vFitY, int index, int nMultiplicity, vector &vWeights, matrix &mXs, GraphLayer &grLayAppar, matrix& mResiduals);
	virtual bool GetCumRegularResidualData(const TreeNode &trOp, const vector& vX, const vector &vY, FitParameter *psFitParameter, vector& vCumRegular, vector& vFitY, int index, int nMultiplicity, vector &vWeights, matrix &mXs, GraphLayer &grLayAppar, matrix& mResiduals);
	///end WRONG_RESIDUAL_DATA_IN_PFW
	bool GetDiffCumResidualData(const TreeNode &trOp, const vector& vX, const vector &vY, const matrix& mRegular, FitParameter *psFitParameter, vector& vStand, vector& vStud, vector& vStudDel, int index = 0, int nMultiplicity = 1, vector &vWeights = NULL, matrix &mXs = NULL);
	///end CALC_RESIDUAL_WITH_REPLICA

private:
	/// Iris 7/08/2008 CLEAN_DUP_CALC_AVE_DATA_CODE_IN_NLSF_PREVIEW_AND_OP
	/////Cheney 2006-12-1 CLEAN_CODE		
	/////Cheney 2006-8-31 ADD_CAL_REPLICA_DATA
	////bool 		calReplicaData(vector& vX, vector& vY, int nAveSize, vector& vAveX, vector& vAveY, vector& vAveErr, int nErrType);
	//bool 		calReplicaData(vector& vX, vector& vY, int nAveSize, vector& vAveX, vector& vAveY, vector* pvAveErr = NULL, int nErrType = AVMC_SE);
	/////end ADD_CAL_REPLICA_DATA
	/////end CLEAN_CODE
	///end CLEAN_DUP_CALC_AVE_DATA_CODE_IN_NLSF_PREVIEW_AND_OP
	
	/// ML 9/20/2006 RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
	//bool 		getResidualData(TreeNode &trOp, int index, FitParameter *psFitParameter, const vector &vX, const vector &vY, vector& vFitY, vector &vResidual, const matrix &mXs = NULL);
	///Arvin 01/17/06 CALC_RESIDUAL_WITH_REPLICA
	//bool 		getResidualData(TreeNode &trOp, int index, FitParameter *psFitParameter, const vector &vX, const vector &vY, vector& vFitY, vector &vResidual, const matrix &mXs = NULL, GraphLayer &grLayAppar = NULL);
	bool 		getResidualData(TreeNode &trOp, int index, FitParameter *psFitParameter, const vector &vX, const vector &vY, vector& vFitY, vector &vResidual, const matrix &mXs = NULL, GraphLayer &grLayAppar = NULL, int nPeak = 0);
	///end CALC_RESIDUAL_WITH_REPLICA
	bool 		getResidualData(TreeNode &trOp, int index, FitParameter *psFitParameter, matrix &mXs, matrix &mYs, matrix &mFitYs, matrix &mResiduals);
	/// end RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
	//--- CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
	//TreeNode 	getFitCuvesTable(const TreeNode& trOp, int nDataIndex= 0, int nTotalNumData = -1);
	//TreeNode 	getOneResidualTable(const TreeNode& trOp, int nDataIndex, int nTotalNumData, int nGraphIndex = GRAPH_RESIDUALS_HISTOGRAM);
	//string		getOneResultCurvesTableTagName(int nGraphIndex);  /// Iris 10/20/05 MOVE_REPORT_GRAPH_CODES_TO_BASE_CLASS
	///Cheney 2007-4-24 SHOULD_SET_ONLY_ONCE_EVENT_HANDLER_IN_ONE_TREENODE
	bool		setTreeInputEvent(TreeNode &trInput);
	///end SHOULD_SET_ONLY_ONCE_EVENT_HANDLER_IN_ONE_TREENODE
	
protected:
	//virtual
	/// Iris 10/20/05 MOVE_REPORT_GRAPH_CODES_TO_BASE_CLASS
	//TreeNode	GetResultCurvesBranch(TreeNode& trOp, int nDataIndex, int nTotalNumData, LPCSTR lpcszDataLabelToCreate = NULL);
	//TreeNode 	GetOneResultCurvesTable(const TreeNode& trOp, int nDataIndex, int nTotalNumData, int nGraphIndex);
	//TreeNode	CheckCreateOneResultCurvesTable(TreeNode& trOp, int nDataIndex, int nTotalNumData, int nGraphIndex, const string& strDataLabel, LPCSTR lpcszTableName, int nTableID, LPCSTR lpcszTableLabel);
	string		GetOneResultCurvesTableTagName(int nGraphIndex);
	///End MOVE_REPORT_GRAPH_CODES_TO_BASE_CLASS
private:
	//---
	
	bool checkRangeAddMargin(double& x1, double& x2)
	{
		if(is_missing_value(x1) || is_missing_value(x2))
			return false;
		
		double margin = (x2-x1) * 0.08; // 8% margin, should let user set this later
		if(margin == 0) margin = 1;
		x1 -= margin;
		x2 += margin;
		return true;
	}
		
	/// YuI 12/07/04 v7.5172 PICTURE_IN_REPORT_IMPROVEMENT
	/*
	bool addInputDataPlot(int index, GraphLayer& gl, const TreeNode& trFit, const TreeNode& trOp, double& dMin, double& dMax)
	{
		int nPlot;
		DataPlot dp;
		dp = GetSourceDataPlot(trFit, &dMin, &dMax);
		if(dp)
			nPlot = gl.AddPlot(dp);
		else
		{
			/// Iris 9/14/04 MOVE_INPUT_DATAPLOT_TO_BASE_CLASS
			/*
			DataRange rngInput;
			GetInput(rngInput);
			if(rngInput)
			{
				DataRange dpRange;
				rngInput.GetSubRange(dpRange, GetDataRules(trOp), index);
				if(dpRange)
				{
					gl.AddPlot(rngInput);
					//gl.Rescale(); // need to improve rescale to be dependent on 
					return true;
				}
			}
			*/
			/*
			nPlot = AddWksInputDataPlot(index, gl, trOp);
			///End MOVE_INPUT_DATAPLOT_TO_BASE_CLASS
		}
		if(nPlot >= 0)
			return true;
		
		return error_report("Error in adding Input data to report graph");
	}	
	*/
	/// end PICTURE_IN_REPORT_IMPROVEMENT
protected:
	//--- CPY 12/31/04 PICTURE_IN_REPORT_IN_BASE_CLASS
	/*
	uint PlotFitCurves(const TreeNode& trOperation, GraphLayer& gl, const DataRange& rReport, uint unFitCuvTable, XYRange* pXY = NULL)
	{
		if(!gl)
		{
			error_report("Must provide valid graph layer for PlotFitCurves");
			return 0;
		}
		if(!rReport)
		{
			error_report("Must provide valid Report DataRange for PlotFitCurves");
			return 0;
		}
		uint ucolor = 2;

		plotFitCurve(gl, rReport, unFitCuvTable, IDST_FIT_X, IDST_FIT_LCB, pXY, ucolor);
		plotFitCurve(gl, rReport, unFitCuvTable, IDST_FIT_X, IDST_FIT_UCB, pXY, ucolor);
		ucolor = 3;
		plotFitCurve(gl, rReport, unFitCuvTable, IDST_FIT_X, IDST_FIT_LPB, pXY, ucolor);
		plotFitCurve(gl, rReport, unFitCuvTable, IDST_FIT_X, IDST_FIT_UPB, pXY, ucolor);

		int nPlot = plotFitCurve(gl, rReport, unFitCuvTable, IDST_FIT_X, IDST_FIT_Y, pXY, GetCurveLineColor(trOperation));
		if( nPlot < 0 )
		{
			error_report("Err: PlotFitCurves failed");
			return 0;
		}
		
		DataPlot dp;
		dp = gl.DataPlots(nPlot);
		return dp.GetUID(TRUE);
	}
private:
	// return index of plot. -1 if failed
	int plotFitCurve(GraphLayer gl, DataRange rReport, uint unTableID, uint unXid, uint unYid, XYRange* pXY, DWORD dwColor)
	{
		/// Iris 10/27/04 PLOT_REPORT_WITHOUT_X_DATA
		//return PlotReportXYData(gl, rReport, unTableID, unXid, unYid, IDM_PLOT_LINE, pXY, dwColor);
		return PlotReportXYData(gl, rReport, unTableID, IDM_PLOT_LINE, unYid, unXid, pXY, dwColor);
	}
	*/
	//--- end CPY 12/31/04 PICTURE_IN_REPORT_IN_BASE_CLASS
	
	/// ML 7/20/2005 FITTING_FUNCTION_FORMULA_IN_REPORT
	/*
	//virtual 
	bool AddResultTextLabelInLayer(TreeNode& trOp, GraphLayer& gl)
	{
		string str;
		if(GetDisplayFormula(trOp, str))
			return InsertUpdateLabelToReportGraph(trOp, gl, str);
		
		return false;		
	} 
	*/
	/// end FITTING_FUNCTION_FORMULA_IN_REPORT
	
	///Arvin 10/23/06 FITTING_RESIDUALS_HISTOGRAM_PLOT
	void OnAfterCalculations(TreeNode& trOp)
	{
		WksReportOperation::OnAfterCalculations(trOp);
	}
	/*
	void PutTempStatsTreeNode(TreeNode& trOp, DataRange& dr, int nDataIndex)
	{
		int r1, c1, r2, c2;
		Datasheet ds; 
		string strRange;
		if(dr)
		{
			int ii = 0; //The DataRange dr have only one data, when plot histogram
			dr.GetRange(ii, r1, c1, r2, c2, ds, &strRange);
			DatasetObject dsObj;
			Worksheet wks(ds);
			if(wks.IsValid())
			{
				Column col(wks, c2);
				DatasetObject dsObjTemp(col);
				dsObj = dsObjTemp;
			}
			else
			{
				MatrixLayer ml(ds);	
				if(ml)
				{
					MatrixObject mo = ml.MatrixObjects(ii);
					DatasetObject dsObjTemp(mo);
					dsObj = dsObjTemp;
				}
			}
			//TreeNode trStats = tree_check_get_node(trOp.Temp, strLabel);
			TreeNode trStats = getTempStatsTreeNode(trOp, ii+nDataIndex-1);
			string strTag;
			GetDataPlotEventHandlerName(strTag, nDataIndex-1);
			okutil_make_valid_c_name(&strTag);
			dsObj.PutBinaryStorage(strTag, trStats);
			///Arvin 04/06/07 v8.0596 THE_10TH_HISTOGRAM_CAN_NOT_PLOTTED
			trStats.Remove();
			///------
		}
		///Arvin 04/06/07 v8.0596 THE_10TH_HISTOGRAM_CAN_NOT_PLOTTED
		//if( trOp.Temp )
		//{
			//string strLabel = STATS_TREE_NODE_PREFIX + ftoa(nDataIndex); 
			//trOp.Temp.RemoveChildrenWithPrefix(strLabel);
		//}
		///END THE_10TH_HISTOGRAM_CAN_NOT_PLOTTED
	}
	*/
	///end FITTING_RESIDUALS_HISTOGRAM_PLOT
	
	void AddGraphDataOneTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, 
	LPCSTR lpcszTableName, LPCSTR lpcszTableLabel, LPCSTR lpcszTableSubLabel, int nTableID, int nSubTableID, vector &vX = NULL, LPCSTR lpcszXLabel = NULL, vector &vY = NULL, LPCSTR lpcszYLabel = NULL, int nGraphIndex = 0, bool bIsSameX = true, string strGraphPrefix = CALCULATION_RESIDUAL_GRAPH_PREIX)
	{
		/// Iris 3/19/2009 QA80-13285-P2 FIT_RESULT_CURVE_COL_LABEL_NEW_DESIGN
		string strTableSubLabel;
		if( !GetCustomGraphTypeName(strTableSubLabel, nGraphIndex) )
			strTableSubLabel = lpcszTableSubLabel;
		///end FIT_RESULT_CURVE_COL_LABEL_NEW_DESIGN
		
		TreeNode	trOneTable =
		CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, nGraphIndex, lpcszTableName, nTableID, lpcszTableLabel, strDataLabel);
		if(trOneTable)
		{
			/*
			TreeNode  	trRow;
			trRow = tree_check_get_node(trOneTable, "X", IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, lpcszXLabel);
			trRow.dVals = vX;
			trRow.ID = make_one_set_ID(nSubTableID+1, index);	
			trRow.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_X);  ///Iris 9/17/05 INCLUDE_RESIDUAL_IN_FIT_CURVE_BRANCH
	
			trRow = tree_check_get_node(trOneTable, "Y", IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, lpcszYLabel);
			trRow.dVals = vY;	 
			trRow.ID = make_one_set_ID(nSubTableID+2, index);		
			trRow.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);  ///Iris 9/17/05 INCLUDE_RESIDUAL_IN_FIT_CURVE_BRANCH
			*/
			///Arvin 10/18/06 FITTING_HISTOGRAM_PLOT
			//addOneColToResultCurveTable(trOneTable, vX, lpcszXLabel, nSubTableID, 0, OKDATAOBJ_DESIGNATION_X);
			//addOneColToResultCurveTable(trOneTable, vY, lpcszYLabel, nSubTableID, 1, OKDATAOBJ_DESIGNATION_Y);
			if(vX)
			{
				///Arvin 01/19/06 EXCHANGE_PARAMETER_LABEL_WITH_TABLE_SUB_LABEL
				//addOneColToResultCurveTable(trOneTable, vX, lpcszTableSubLabel, lpcszXLabel, nSubTableID, 0, OKDATAOBJ_DESIGNATION_X);
#ifndef	__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__	///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
				AddOneColToResultCurveTable(trOneTable, vX, strTableSubLabel, lpcszXLabel, nSubTableID, 0, OKDATAOBJ_DESIGNATION_X);
				///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
#else
				TreeNode trColX = AddOneColToResultCurveTable(trOneTable, vX, strTableSubLabel, lpcszXLabel, nSubTableID, 0, OKDATAOBJ_DESIGNATION_X);
				UpdateOneXColumnFormat(trColX, index);
#endif
				///end FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
				///------
			}
			if(vY)
				///Arvin 01/19/06 EXCHANGE_PARAMETER_LABEL_WITH_TABLE_SUB_LABEL
				//addOneColToResultCurveTable(trOneTable, vY, lpcszTableSubLabel, lpcszYLabel, nSubTableID, 1, OKDATAOBJ_DESIGNATION_Y);
				AddOneColToResultCurveTable(trOneTable, vY, strTableSubLabel, lpcszYLabel, nSubTableID, 1, OKDATAOBJ_DESIGNATION_Y);
				///END EXCHANGE_PARAMETER_LABEL_WITH_TABLE_SUB_LABEL
			///end FITTING_HISTOGRAM_PLOT
				
		}
	}
	
	void AddGraphDataOneTable(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, 
	LPCSTR lpcszTableName, LPCSTR lpcszTableLabel, LPCSTR lpcszTableSubLabel, int nTableID, int nSubTableID, matrix& mXs = NULL, LPCSTR lpcszXLabel = NULL, matrix& mYs = NULL, LPCSTR lpcszYLabel = NULL, int nGraphIndex = 0)
	{		
		/// Iris 3/19/2009 QA80-13285-P2 FIT_RESULT_CURVE_COL_LABEL_NEW_DESIGN
		string strTableSubLabel;
		if( !GetCustomGraphTypeName(strTableSubLabel, nGraphIndex) )
			strTableSubLabel = lpcszTableSubLabel;
		///end FIT_RESULT_CURVE_COL_LABEL_NEW_DESIGN

		TreeNode	trOneTable =
		CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, nGraphIndex, lpcszTableName, nTableID, lpcszTableLabel, strDataLabel);
		if(trOneTable)
		{
			int		nNumCol = 0;
			///Arvin 10/18/06 FITTING_HISTOGRAM_PLOT
			/*
			for(int nx=0; nx < mXs.GetNumCols(); nx++)
			{
				vector 	vData;
				string	strLabel = lpcszXLabel + nx;
				mXs.GetColumn(vData, nx);
				addOneColToResultCurveTable(trOneTable, vData, strLabel, nSubTableID, nNumCol, OKDATAOBJ_DESIGNATION_X);
				nNumCol++;
			}
			
			for(int ny=0; ny < mYs.GetNumCols(); ny++)
			{
				vector 	vData;
				string	strLabel = lpcszYLabel + ny;
				mYs.GetColumn(vData, ny);
				addOneColToResultCurveTable(trOneTable, vData, strLabel, nSubTableID, nNumCol, OKDATAOBJ_DESIGNATION_Y);
				nNumCol++;
			}
			*/
			if(mXs)
			{
				for(int nx=0; nx < mXs.GetNumCols(); nx++)
				{
					vector 	vData;
					string	strLabel(lpcszXLabel);
					if(mXs.GetNumCols() > 1)
						strLabel += " " + (nx+1);
					///Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
					//mXs.GetColumn(vData, nx);
					if(mXs.GetNumRows() > 0)
						mXs.GetColumn(vData, nx);
					///end IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
#ifndef	__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__	///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
					AddOneColToResultCurveTable(trOneTable, vData, strTableSubLabel, strLabel, nSubTableID, nNumCol, OKDATAOBJ_DESIGNATION_X);
					///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
#else
					TreeNode trColX = AddOneColToResultCurveTable(trOneTable, vData, strTableSubLabel, strLabel, nSubTableID, nNumCol, OKDATAOBJ_DESIGNATION_X);
					UpdateOneXColumnFormat(trColX, index);
#endif	//__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__
					///end FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
					nNumCol++;
				}
			}
			if(mYs)
			{
				for(int ny=0; ny < mYs.GetNumCols(); ny++)
				{
					vector 	vData;
					string	strLabel(lpcszYLabel);
					if(mYs.GetNumCols() > 1)
						strLabel += " " + (ny+1);
					///Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
					//mYs.GetColumn(vData, ny);
					if(mYs.GetNumRows() > 0)
						mYs.GetColumn(vData, ny);
					///end IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
					AddOneColToResultCurveTable(trOneTable, vData, strTableSubLabel, strLabel, nSubTableID, nNumCol, OKDATAOBJ_DESIGNATION_Y);
					nNumCol++;
				}
			}
			///end FITTING_HISTOGRAM_PLOT
		}
	}

protected:
	TreeNode	AddOneColToResultCurveTable(TreeNode& trTable, const vector& vData, LPCSTR lpcszTableSubLabel, LPCSTR lpcszLabel, int nGroupID, int index = 0, int nColType = OKDATAOBJ_DESIGNATION_Y)	
	{
		TreeNode  	trCol;
		trCol = check_add_enumerated_node(trTable, "Col", index + 1, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, lpcszLabel);
		///Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
		//trCol.dVals = vData;
		if(vData.GetSize() > 0)
			trCol.dVals = vData;
		else
			trCol.dVals = NANUM;
		///end IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
		trCol.ID = make_one_set_ID(nGroupID, index + 1);	
		trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nColType);		
		
		if(lpcszTableSubLabel)
		{
			vector<string> vs;
			vs.Add(lpcszTableSubLabel);
			tree_add_more_labels(trCol, vs);
		}
		
		
#ifndef	__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__	///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
		//index here is not dataset index, so should not be called in this method.
		///Sophy 1/15/2009 v8.0957 QA80-12918 FITCURVE_X_COLULMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA
		if ( OKDATAOBJ_DESIGNATION_X == nColType )
			UpdateOneXColumnFormat(trCol, index);
		///end FITCURVE_X_COLULMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA
#endif	//__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__ ///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
		return trCol;
	}
	
	//----------------------------- CPY 8/10/04 QA70-6784 v8.0115 GET_INCOMING_OPERATION_CHANGE
public:
	//virtual 
	///Joseph 09/27/06 FINDXY_TO_SEPERATE_SHEET
	//bool GetFitCurve(vector& vx, vector& vy, int nIndex = 0)
	///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	//bool GetFitCurve(TreeNode& trOp, vector& vx, vector& vy, int nIndex = 0)
	bool GetFitCurve(TreeNode& trOp, vector& vx, vector& vy, int& nPeaks, int nIndex = 0)
	///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	{
		//Tree trOp;
		//GetTree(trOp);
		//DataRange 	rReport;
		//Worksheet	wksOutput;
		//if(!GetOutput(rReport, wksOutput))
			//return false;
		///End FINDXY_TO_SEPERATE_SHEET
		//ASSERT(FALSE);	// this function does not appear to be called anywhere. In case it is called, 

		TreeNode	trFit = GetOneResultCurvesTable(trOp, nIndex, 0, GRAPH_FIT_CURVE); //getFitCuvesTable(trOp, nIndex);
		if(!trFit)
			return false;
		
		/// Iris 8/09/06 FIND_XY_FOR_PR
		//Worksheet wks;
		//int nXcol = GetWksCol(rReport, trFit.ID, IDST_FIT_X, &wks);
		//Dataset dx(wks, nXcol);
		//if(dx)
		//{
			//Worksheet wks1;
			//int nYcol = GetWksCol(rReport, trFit.ID, IDST_FIT_Y, &wks1);
			//Dataset dy(wks1, nYcol);
			//if(dy)
			//{
				//vy = dy;
				//vx = dx;
				//return true;
			//}
		//}
		//return false;		
		///Joseph 09/27/06 FINDXY_TO_SEPERATE_SHEET
		//TreeNode trX = tree_get_node_by_id(trFit, IDST_FIT_X, true);
		TreeNodeCollection trColl(trFit, "FitX");
		TreeNode trX = trColl.Item(0); //only one X for this method
		
		TreeNodeCollection trCol2(trFit, "FitY");
		
		///End FINDXY_TO_SEPERATE_SHEET
		
		if(trX)
			vx = trX.dVals;
		else
			return false;
		
		///Joseph 09/27/06 FINDXY_TO_SEPERATE_SHEET
		TreeNode trY = trCol2.Item(0); //only one Y for this method
		//TreeNode trY = tree_get_node_by_id(trFit, IDST_FIT_Y, true);
		///End FINDXY_TO_SEPERATE_SHEET
		if(trY)
			vy = trY.dVals;
		else
			return false;
		///end FIND_XY_FOR_PR
		
		return true;
	}
protected:
	///Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	//bool GetFitParameters(const TreeNode& trOp, TreeNode&	trParams)
	bool GetFitParameters(const TreeNode& trOp, TreeNode&	trParams, bool bGetDerivedParams = true)
	///end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	{
		// for now, we just get it from OP, even though we should realy get this from report sheet
		///Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
		//TreeNode trOpParams = getParameters(trOp);
		TreeNode trOpParams = getParameters(trOp, bGetDerivedParams);
		///end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
		if(!trOpParams)
			return false;
		///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
		//trParams.AddNode(trOpParams.Clone());
		//should delete footnote if it exists
		TreeNode trOpParamsCopy = trOpParams.Clone();
		TreeNode trFootNote = trOpParamsCopy.GetNode( "Footnote");
		if(trFootNote)
			trFootNote.Remove();
		
		trParams.AddNode(trOpParamsCopy.Clone());
		///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
		
		return true;
	}
	int GetFitParameters(const TreeNode& trOp, TreeNode& trCalc, int nIndex, FitParameter* pFitParams, int nSize)
	{
		vector<string>	vstrParamNames;
		int				nParams = GetParameters(trOp, nIndex, vstrParamNames);
		if(nSize < nParams)
			return -2;

		return stats_tree_get_Parameters(trCalc, nIndex, pFitParams, vstrParamNames);
	}
	//----------------------------- end CPY 8/10/04 QA70-6784 v8.0115 GET_INCOMING_OPERATION_CHANGE
private:
	/// YuI 12/07/04 v7.5172 PICTURE_IN_REPORT_IMPROVEMENT
	/*
	bool	plotAddOneFitCurveToDataLayer(TreeNode& trFit, const TreeNode& trOp, const DataRange& rReport)
	{
		DataPlot dp;
		dp = GetSourceDataPlot(trFit);
		if(!dp)
			return error_report("Plotobj UID in tree does not lead to valid plot obj");
		GraphLayer gl;
		dp.GetParent(gl);
		if(!gl)
			return error_report("System error: Data Plot didn't have a valid graph layer");
		
		uint uFitUID = PlotFitCurves(trOp, gl, rReport, trFit.ID);
		if(uFitUID)
			trFit.SetAttribute(STR_PLOTOBJ_UID_ATTRIB, ftoa(uFitUID));
		else
			error_report("PlotFitCurves failed to construct fit curve");
		
		return true;
	}
	*/
	/// end PICTURE_IN_REPORT_IMPROVEMENT
	
	
	/// YuI 12/07/04 v7.5172 PICTURE_IN_REPORT_IMPROVEMENT
	/*
	bool plotFitCurvesToDataLayer(const DataRange& rReport, const TreeNode& trOp, int nTotalNumData)
	{
		if(!rReport)
			return error_report("Report UID invalid in DataRange");
		
		TreeNode	trFitCuvesTable = FIT_CURVES_BRANCH(trOp.Calculation);
		if(!trFitCuvesTable)
			return true; // no fit curves for this type of analysis

		bool		bHaveSubLevel = 1 < nTotalNumData;

		
		
		if ( bHaveSubLevel )
		{
			TreeNodeCollection	trFitCurvesColl(trFitCuvesTable, CALCULATION_FIT_CURVES_PREFIX);
			foreach (TreeNode trFit in trFitCurvesColl)
			{
				/*
				DataPlot dp;
				dp = GetSourceDataPlot(trFit);
				if(!dp)
					return error_report("Plotobj UID in tree does not lead to valid plot obj");
				GraphLayer gl;
				dp.GetParent(gl);
				if(!gl)
					return error_report("System error: Data Plot didn't have a valid graph layer");
				
				uint uFitUID = PlotFitCurves(trOp, gl, rReport, trFit.ID);
				if(uFitUID)
					trFit.SetAttribute(STR_PLOTOBJ_UID_ATTRIB, ftoa(uFitUID));
				else
					error_report("PlotFitCurves failed to construct fit curve");
				*/
				/*
				if ( !plotAddOneFitCurveToDataLayer(trFit, trOp, rReport) )
					return false;
			}
		}
		else
			return plotAddOneFitCurveToDataLayer(trFitCuvesTable, trOp, rReport);
		
		return true;
	}	
	*/
	/// end PICTURE_IN_REPORT_IMPROVEMENT
	
protected:
	virtual bool GetDisplayFormula(TreeNode& trOp, string& strFormula)
	{
		TreeNode 	trFormula = trOp.GUI.Codes.FunctionCode;
		if(trFormula)
		{
			strFormula = trFormula.strVal;
			return strFormula.IsEmpty()?false:true;
		}
		return false;
	}
	
protected:
	virtual bool MakeFitX(int index, const string &strDataLabel, vector& vX, vector& vFitX, TreeNode trOp, const tagFitResultCurveDataOptions& fitOptions)
	{
		///Iris 7/29/05 UPDATE_FITTED_CURVE_OPTIONS
		/////Iris 6/03/05 CENTRALIZE_TO_GET_GRAPH_GUI_NODE
		/////Iris 4/12/05 MOVE_CURVE_OPTION_TO_EACH_GRAPH
		////if(trOp.GUI.Output.Data.ResultCurves.UseDataX.nVal)
		////TreeNode trCurve = GetCurveOptions(trOp.GUI, 0);
		//TreeNode trCurve = GetGUIGraphNodes(trOp, 0);
		/////end CENTRALIZE_TO_GET_GRAPH_GUI_NODE
		//
		//if(trCurve && trCurve.UseDataX.nVal)
		//{
			//vFitX = vX;
			//return true;
		//}
		//
		//double Xmin, Xmax, Xinc;
		//if(!updateResultCurveXRangeSettings(trOp, index, strDataLabel, vX, Xmin, Xmax))
			//return false;
		//
		//if(fitOptions.N < 1)
			//return false;
		//
		//Xinc = (Xmax - Xmin) / (fitOptions.N - 1);	
		//vFitX.Data(Xmin, Xmax, Xinc);
		//return true;
		////return get_fitting_data_by_options(vX, fitOptions, vFitX, true);
		///Arvin 04/12/07 v8.0599 PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE by cp's suggestion	
		//GraphLayer gl = Project.ActiveLayer();
		//return updateResultCurveXRangeSettings(vX, vFitX, fitOptions, gl);
		return updateResultCurveXRangeSettings(trOp, index, vX, vFitX, fitOptions);
		///end PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE
		///end UPDATE_FITTED_CURVE_OPTIONS

	}
	
	///Iris 9/21/06 MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
	virtual bool MakeFitX(int index, const string &strDataLabel, matrix& mXs, matrix& mFitXs, TreeNode trOp, const tagFitResultCurveDataOptions& fitOptions)
	{		
		return false;
	}
	///end MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
	
	
	///Iris 4/21/05 MAKEFITY_SUPPORT_MULTI_REGRESSION
	///// YuI 8/30/04 QA70-4387 NLFITTER_OPERATION_IMPLEMENTATION
	////	virtual bool MakeFitY(TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* psFitParameter)
	//virtual bool MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* psFitParameter)
	virtual bool MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* sFitParameter, const matrix& mXs = NULL, int nPeak = 0)
	/// end NLFITTER_OPERATION_IMPLEMENTATION
	/// END MAKEFITY_SUPPORT_MULTI_REGRESSION
	{
		return false;
	}
	
	virtual bool MakeFitY(TreeNode &trOp, const matrix& mFitXs, matrix& mFitYs, int index)
	{
		return false;
	}
	
	///Iris 4/18/05 FIX_NLSF_CONF_PREDI_BAND_NOT_WORK
	/*
	virtual bool MakeFitErrConf(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* psFitParameter, RegStats& sRegStats, RegCalcInternal& sReg)
	{
		return false;
	}
	virtual bool MakeFitErrPred(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* psFitParameter, RegStats& sRegStats, RegCalcInternal& sReg)
	{
		return false;
	}	
	*/
	///end FIX_NLSF_CONF_PREDI_BAND_NOT_WORK
	//virtual
	///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)
	virtual void	UpdateDataSourceInReportingHeader(TreeNode &trInputTable, const vector<string> &vstrFactors, int ii, LPCSTR lpcszXLabel = NULL, int numSubRanges = 0, DWORD dwRules = 0)
	///END LISTING_INPUT_DATA_AS_A_VERTICAL_LIST_FOR_MR
	{
		if ( 1 < numSubRanges )
		{
			AddCombinedDataSourcesToReportInputTable(trInputTable, vstrFactors, ii, WKSH_OPERATION_INFO_Y_DATA_SOURCE, numSubRanges, dwRules, WKSH_OPERATION_INFO_X_DATA_SOURCE);
			return;
		}
		
		///Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		TreeNode		trOp;
		GetTree(trOp);
		bool bHasXIndep = false, bHesYIndep = false;
		bool bHasZ = HasZ(trOp, &bHasXIndep, &bHesYIndep);
		///end REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		
		int			indexLT = ii + 1;
		// the base class function will add the X node
		///Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		//TreeNode	trRow = AddXDataSourceToReportInputTable(trInputTable, vstrFactors, ii, WKSH_OPERATION_INFO_X_DATA_SOURCE, 'X', numSubRanges, dwRules);
		TreeNode	trRow = AddReportInputTable(trInputTable, vstrFactors, ii);
		if(bHasXIndep)
			trRow = AddXDataSourceToReportInputTable(trRow, ii, WKSH_OPERATION_INFO_X_DATA_SOURCE, 'X', numSubRanges, dwRules);
		///end REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		//string	strRange;
		//GetEscapedMainDataString(strRange, indexLT, 'R', 'Y');
		//TreeNode trY = tree_check_get_node(trInput,"Y", IDE_INPUT_Y, STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_Y_DATA_SOURCE);
		//trY.strVal = strRange;
		//return trInput;
		/// ML 11/8/2005 QA70-8135 Z_IN_REPORT_TABELS
		/*
		AddOneInputDataTableCell(trRow, WKSH_OPERATION_INFO_Y_DATA_SOURCE, indexLT, FALSE, 'P');

		// The excel formatted Y column
		TreeNode trCol = AddOneInputDataTableCell(trRow, WKSH_OPERATION_INFO_Y_DATA_SOURCE, indexLT, FALSE, 'R', 'Y');
		if(trCol)
			trCol.Show = false;
		*/
		///Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		//TreeNode		trOp = trInputTable.Parent().Parent(); 
		//bool			bHasZ = HasZ(trOp);
		///end REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		string			strMainTitle = bHasZ ? WKSH_OPERATION_INFO_Z_DATA_SOURCE : WKSH_OPERATION_INFO_Y_DATA_SOURCE; 
		TreeNode 		trCol;
		///Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		//if (bHasZ)
		if (bHasZ && bHesYIndep)
		///end REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
		{
			// Need to add Y-indep:
			AddOneInputDataTableCell(trRow, WKSH_OPERATION_INFO_Y_DATA_SOURCE, indexLT, FALSE, 'P', 'Y');
			trCol = AddOneInputDataTableCell(trRow, WKSH_OPERATION_INFO_Y_DATA_SOURCE, indexLT, FALSE, 'R', 'Y');
			if(trCol)
				trCol.Show = false;
		}
		// The main:
		AddOneInputDataTableCell(trRow, strMainTitle, indexLT, FALSE, 'P', 0);
		trCol = AddOneInputDataTableCell(trRow, strMainTitle, indexLT, FALSE, 'R', 0);
		if(trCol)
			trCol.Show = false;
		/// end Z_IN_REPORT_TABELE
		
		// The Range column:
		AddOneInputDataTableCell(trRow, WKSH_OPERATION_INFO_DATA_SOURCE_RANGE, indexLT, FALSE, 'G', 'R');
		
		///Sophy 6/20/2008 MAKE_WEIGHT_DATA_SOURCE_NAME_AMBULATORY_IN_RESULT_WKS_IN_RESULT_WKS
		/*
		///Arvin 08/17/07 ADD_WEIGHT_DATA_TABLE_IN_INPUT_DATA_TABLE
		TreeNode trInputData = trOp.GUI.InputData;
		CheckAddWeightInfoRowForInputTable(trInputData, trRow, ii);
		///end ADD_WEIGHT_DATA_TABLE_IN_INPUT_DATA_TABLE
		*/
		TreeNode	trInputData = trOp.GUI.InputData;
		string		strWeight;
		if ( IsDatasetHasWeight( trInputData, ii, strWeight) )
		{
			AddOneInputDataTableCell( trRow, WKSH_OPERATION_INFO_WEIGHT_DATA_SOURCE, indexLT, FALSE, 'P', 'W');
		}
		///end MAKE_WEIGHT_DATA_SOURCE_NAME_AMBULATORY_IN_RESULT_WKS_IN_RESULT_WKS
		
		return;
	}
	//----------
protected:
	/// Iris 6/11/05 NLSF_SUPPORT_XYZ_DATA
	//--- CPY 10/14/04 QA70-7029 COR_CORR_USE_MATRIX
	//TreeNode getSubReportNode(TreeNode& trBranch, int index, int nGroupID, const string& strDataLabel, const string& strPrefix, int nSingleTable)
	TreeNode GetSubReportNode(TreeNode& trBranch, int index, int nGroupID, const string& strDataLabel, const string& strPrefix, int nSingleTable)
	{
		TreeNode	trFC;
		if ( !strPrefix.IsEmpty() )
		{
			///Iris 4/18/05 SUB_TABLE_ID_FOR_MUL_GRAPHS
			///// YuI 04/14/05 MULTIPLE_CURVE_ANALYSIS_BUG
			////	trFC = check_add_enumerated_node(trBranch, strPrefix, index + 1, index + nGroupID, STR_LABEL_ATTRIB, strDataLabel);
			//trFC = check_add_enumerated_node(trBranch, strPrefix, index + 1, make_one_set_ID(IDST_REPORT_FITDATA_ONE_SET, index), STR_LABEL_ATTRIB, strDataLabel);
			trFC = check_add_enumerated_node(trBranch, strPrefix, index + 1, make_one_set_ID(nGroupID, index), STR_LABEL_ATTRIB, strDataLabel);
			/// end MULTIPLE_CURVE_ANALYSIS_BUG
			/// END SUB_TABLE_ID_FOR_MUL_GRAPHS
			
			trBranch.SetAttribute(TREE_Table, GetTableStringSupport(false));
			trFC.SetAttribute(TREE_Table, nSingleTable);
		}
		else
		{
			trFC = trBranch;
			
			/// YuI 04/14/05 MULTIPLE_CURVE_ANALYSIS_BUG
			// if prefix is empty means numData is 1
			// in that case FitCurves (and other nodes) are used directly
			// without Fit1, Fit2, subnodes.
			ASSERT(index == 0);
			/// end MULTIPLE_CURVE_ANALYSIS_BUG
			
			//trFC.ID = index + nGroupID;  ///Iris 4/18/05 SUB_TABLE_ID_FOR_MUL_GRAPHS
			trBranch.SetAttribute(TREE_Table, nSingleTable);
		}
		return trFC;
	}
	//----
protected:	
	virtual void 	UpdateGUIGraphs(TreeNode& trOp);


	///Iris 4/01/05 FIT_REGRESSION_PLOTS
	///// YuI 8/13/04 QA70-4387 NLFITTER_OPERATION_IMPLEMENTATION
	////  moved from FitRegression
	//bool	ConstructCurvesAndGraphs(TreeNode &trOp, int index, int nTotalNumData, const string &strDataLabel, vector &vX, vector & vY, FitParameter *psFitParameter, RegStats *psRegStats, RegCalcInternal *psReg, DWORD dwPlotObjUID);
	///Arvin 12/04/06 ADD_CONF_PRED_BANDS_FOR_MR
	//virtual 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);  /// Iris 2/17/06 QA70-8461 v8.0365 INCLUDE_RPLICA_FOR_FITTING
	///Arvin 12/12/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	//virtual 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);
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//virtual 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);
	virtual 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
	///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING
	///end ADD_CONF_PRED_BANDS_FOR_MR
	///Cheney 2006-11-1 CHANGE_sReg_FROM_REF_TO_POINTER
	///// ML 9/20/2006 RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
	////virtual bool 	CalcReportConfPredBandsTable(TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal &stReg = NULL);
	//virtual bool 	CalcReportConfPredBandsTable(TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal &stReg = NULL, GraphLayer &grLayAppar = NULL);
	///Arvin 12/04/06 ADD_CONF_PRED_BANDS_FOR_MR
	//virtual bool 	CalcReportConfPredBandsTable(TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg = NULL, GraphLayer &grLayAppar = NULL, int nGraphIndex = GRAPH_FIT_CURVE); ///Arvin 12/02/06 MR_NEED_CLAC_CONF_OR_PRED_FOR_PARTIAL_REGRESSION
	///Arvin 06/11/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion	
	//virtual bool 	CalcReportConfPredBandsTable(TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg = NULL, GraphLayer &grLayAppar = NULL, int nGraphIndex = GRAPH_FIT_CURVE, vector& vSerr = NULL); ///Arvin 12/02/06 MR_NEED_CLAC_CONF_OR_PRED_FOR_PARTIAL_REGRESSION
	///Arvin 01/11/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS
	//virtual bool 	CalcReportConfPredBandsTable(TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg = NULL, GraphLayer &grLayAppar = NULL, int nGraphIndex = GRAPH_FIT_CURVE, vector& vSerr = NULL, LPCSTR lpcszDataLabel = NULL); ///Arvin 12/02/06 MR_NEED_CLAC_CONF_OR_PRED_FOR_PARTIAL_REGRESSION
	///Arvin 01/25/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS
	virtual bool CalcReportConfPredBandsTable(TreeNode &trOp, TreeNode &trFC, vector &vIndep1, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg = NULL, GraphLayer &grLayAppar = NULL, int nGraphIndex = GRAPH_FIT_CURVE, vector& vSerr = NULL, LPCSTR lpcszDataLabel = NULL, vector &vIndep2 = NULL, int index = 0);	
	///end CALC_CONFIDENCE_AND_PREDICTION_BANDS
	///end CENTRALIZE_FITTING_RESULT_LABELS
	///end ADD_CONF_PRED_BANDS_FOR_MR
	////bool			makeConfOrPredTbl(BOOL bDo, bool bConf, GraphLayer &grLayAppar, TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal &stReg, double tvalue, LPCSTR lpcszConfLevel);
	///Arvin 12/04/06 ADD_CONF_PRED_BANDS_FOR_MR
	//bool			makeConfOrPredTbl(BOOL bDo, bool bConf, GraphLayer &grLayAppar, TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, double tvalue, LPCSTR lpcszConfLevel);
	///Arvin 06/11/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//bool			makeConfOrPredTbl(BOOL bDo, bool bConf, GraphLayer &grLayAppar, TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, double tvalue, LPCSTR lpcszConfLevel, vector& vSE = NULL);
	///Arvin 01/11/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS
	//bool			makeConfOrPredTbl(BOOL bDo, bool bConf, GraphLayer &grLayAppar, TreeNode &trOp, TreeNode &trFC, vector &vFitX, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, double tvalue, LPCSTR lpcszConfLevel, vector& vSE = NULL, LPCSTR lpcszDataLabel = NULL);
	
	/// Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
	//void 			GetConfOrPredTblLabelAndID(bool bConf, string& strTagL, string& strTagU, string& strLabelL, string& strLabelU, string& strType, int* pnIdL, int* pnIdU, LPCSTR lpcszLevel, LPCSTR lpcszDataLabel = NULL);
	void 			GetConfOrPredTblLabelAndID(bool bConf, string& strTagL, string& strTagU, string& strLabelL, string& strLabelU, string& strType, int* pnIdL, int* pnIdU, LPCSTR lpcszLevel, LPCSTR lpcszDataLabel = NULL, bool bMultiIndepDepCase = false, int iDep=0);
	/// End CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
	
	virtual bool 	CalcConfOrPredBounds(TreeNode &trOp, bool bConf, double dBoundLevel, vector& vLower, vector& vUpper, vector& vIndep1, vector &vFitY, GraphLayer& grLayAppar, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, vector& vSE = NULL, vector& vIndep2 = NULL, int index = 0);
	bool			MakeConfOrPredTbl(TreeNode &trOp, TreeNode& trFC, bool bConf, GraphLayer &grLayAppar, vector &vIndep1, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, int nGraphIndex = GRAPH_FIT_CURVE, vector& vSE = NULL, LPCSTR lpcszDataLabel = NULL, vector& vIndep2 = NULL, int index = 0);
	///end CALC_CONFIDENCE_AND_PREDICTION_BANDS
	
	/// Jack 12/19/2008 QA80-12329 MULTI_INDEP_DEPS_BAND_CALCULATION
	virtual bool 	CalcConfOrPredBounds(TreeNode &trOp, bool bConf, double dBoundLevel, vector& vLower, vector& vUpper, matrix &mIndeps, vector &vFitY, GraphLayer& grLayAppar, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, vector& vSE = NULL, int index = 0, int iDep = 0);
	bool			MakeConfOrPredTbl(TreeNode &trOp, TreeNode& trFC, bool bConf, GraphLayer &grLayAppar, matrix &mIndeps, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, int nGraphIndex, vector& vSE, LPCSTR lpcszDataLabel, int index, int numDeps=1);
	bool			CalcReportConfPredBandsTableMultiIndepDep(TreeNode &trOp, TreeNode &trFC, matrix &mIndeps, vector &vFitY, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg = NULL, GraphLayer &grLayAppar = NULL, int nGraphIndex = GRAPH_FIT_CURVE , vector& vSerr = NULL, LPCSTR lpcszDataLabel = NULL, int index=0, int numDeps=1);
	/// Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
	//void 			GetConfOrPredTblLabelAndIDMultiDep(bool bConf, string& strTagL, string& strTagU, string& strLabelL, string& strLabelU, string& strType, int* pnIdL, int* pnIdU, LPCSTR lpcszLevel, LPCSTR lpcszDataLabel = NULL, int iDep = 0); // centralize into GetConfOrPredTblLabelAndID
	/// End CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
	
	/// End MULTI_INDEP_DEPS_BAND_CALCULATION
	
	
	///end CENTRALIZE_FITTING_RESULT_LABELS
	///end ADD_CONF_PRED_BANDS_FOR_MR
	///// end RESIDUAL_TABLES_CONSOLIDATION_AND_APPARENT_FIT
	///end CHANGE_sReg_FROM_REF_TO_POINTER
	
	string GetGraphName(int nGraphIndex = 0, bool bLongName = false)
	{
		string str;
		/*
		switch(ReportGetPlotTypeFromGraphIndex(nGraphIndex))
		{
		case IDM_PLOT_HISTOGRAM_TYPE:
			str = "Histogram";
			break;
		case IDM_PLOT_LINESYMB:
			str = "LineScatter";
			break;
		case IDM_PLOT_LINE:
			str = "FitLine";
			break;
		default:
			break;
		}
		*/
		if(bLongName)
		{
			switch(nGraphIndex)
			{
			case GRAPH_FIT_CURVE:
				str = GetAnalysisName();
				break;
				
			case GRAPH_RESIDUALS_SCATTER:
			case GRAPH_RESIDUALS_HISTOGRAM:
			case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
			case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
			case GRAPH_RESIDUALS_LAG_PLOT:				
				GetCustomGraphTypeName(str, nGraphIndex);
				str += " in " + GetAnalysisName();
				break;
			}
		}
		else
		{
			switch(nGraphIndex)
			{
			case GRAPH_FIT_CURVE:
				str = "FitLine";
				break;
			case GRAPH_RESIDUALS_SCATTER:
				str = "ResIndp";
				break;
			case GRAPH_RESIDUALS_HISTOGRAM:
				str = "ResHist";
				break;
			case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
				str = "ResPre";
				break;
			case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
				str = "ResOrder";
				break;
			case GRAPH_RESIDUALS_LAG_PLOT:
				str = "ResLag";
				break;
			}
		}
		
		if(str.IsEmpty())
			str = WksReportOperation::GetGraphName(nGraphIndex, bLongName);
		return str;		
	}
	
	string GetGraphTemplate(int nGraphIndex = 0)
	{
		string str;
		/// Iris 8/19/05 RECREATE_TEMPLATE
		//switch(ReportGetPlotTypeFromGraphIndex(nGraphIndex))
		//{
		//case IDM_PLOT_LINESYMB:
			//str = "ReportLineScatter";
			//break;
		//case IDM_PLOT_LINE:
			//str = "ReportFitLine";
			//break;
		//default:
			//break;
		//}
		///end RECREATE_TEMPLATE
		/// Iris 8/15/05 QA70-8015 ADD_Y=0_TO_RESIDUAL_PLOTS
		switch(nGraphIndex)
		{
		/// Iris 8/19/05 RECREATE_TEMPLATE
		case GRAPH_FIT_CURVE:
			str = "ReportFit";
			break;
		case GRAPH_RESIDUALS_HISTOGRAM:
			str = "ReportHistogram";
			break;
		///end RECREATE_TEMPLATE
		case GRAPH_RESIDUALS_SCATTER:
		case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
		case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
		///Arvin 10/23/07 QA70-10559-P2 RESIDUAL_LAG_PLOT_USE_WRONG_TEMPLATE
		case GRAPH_RESIDUALS_LAG_PLOT: 
		///END 	RESIDUAL_LAG_PLOT_USE_WRONG_TEMPLATE
			str = "ReportResidual";
			break;
		///Jim 2/24/06 v8.0368 ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
		///Arvin 10/23/07 QA70-10559-P2 RESIDUAL_LAG_PLOT_USE_WRONG_TEMPLATE
		//case GRAPH_RESIDUALS_LAG_PLOT: 
		//	str = "ReportResidualLag";
		//	break;
		///END RESIDUAL_LAG_PLOT_USE_WRONG_TEMPLATE
		//END ADD_RESIDUAL_LAG_PLOT_TO_RESIDUALS_PLOTS_BRANCH
		default:
			break;
		}
		///end ADD_Y=0_TO_RESIDUAL_PLOTS
		if(str.IsEmpty())
			str = WksReportOperation::GetGraphTemplate(nGraphIndex);
		
		return str;
		
	}	
	
	bool Add2Yplots(GraphLayer& gl, const Worksheet& wks, int nCol, const TreeNode& trY1, const TreeNode& trY2, DWORD dwColor, int nPlotType = IDM_PLOT_LINE)
	{
		Dataset dy1(wks, nCol);
		Dataset dy2(wks, nCol + 1);
		dy1 = trY1.dVals;
		dy2 = trY2.dVals;
		if(AddXYplot(gl, wks, nCol, dwColor, nPlotType))
			return AddXYplot(gl, wks, nCol + 1, dwColor, nPlotType);
		
		return true;
	}
	
	bool AddXYplot(GraphLayer& gl, const Worksheet& wks, int nCol, DWORD dwColor, int nPlotType = IDM_PLOT_LINE, int nXCol = 0)
	{
		Curve cuv(wks, nXCol, nCol);
		int nPlot = gl.AddPlot(cuv, IDM_PLOT_LINE);
		if(nPlot >= 0)
		{
			DataPlot dp = gl.DataPlots(nPlot);
			dp.SetColor(dwColor);
			return true;
		}
		return error_report("Add XY plot failed");
	}
	/// end NLFITTER_OPERATION_IMPLEMENTATION
	
	//bool updateResultCurveXRangeSettings(TreeNode& trOp, int index, const string &strDataLabel, const vector& vX, double &Xmin, double &Xmax)
	/// ML 10/2/2006 NLFIT_CURVES_CLEANUP
	//bool updateResultCurveXRangeSettings(const vector& vData, vector& vFit, const FitResultCurveDataOptions& fitOptions, GraphLayer& gl = NULL)
	///Arvin 04/12/07 v8.0599 PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE by cp's suggestion	
	//bool updateResultCurveXRangeSettings(const vector& vData, vector& vFit, const FitResultCurveDataOptions& fitOptions, GraphLayer& gl = NULL, bool bSort = true)
	bool updateResultCurveXRangeSettings(TreeNode& trOp, int index, const vector& vData, vector& vFit, const FitResultCurveDataOptions& fitOptions, bool bSort = true)
	///end PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE
	/// end NLFIT_CURVES_CLEANUP
	{
		///Iris 7/29/05 UPDATE_FITTED_CURVE_OPTIONS
		///Iris 6/03/05 CENTRALIZE_TO_GET_GRAPH_GUI_NODE
		///Iris 4/12/05 MOVE_CURVE_OPTION_TO_EACH_GRAPH
		//TreeNode trCurves = trOp.GUI.Output.Data.ResultCurves;
		//TreeNode trCurves = GetCurveOptions(trOp.GUI);	
		//TreeNode trCurve = GetGUIGraphNodes(trOp);
		///end CENTRALIZE_TO_GET_GRAPH_GUI_NODE
		
		//vX.GetMinMax(Xmin, Xmax);
		//if( trCurves.SpanXAxis.nVal )
		//{
			//GraphLayer gl = get_graph_layer(trOp.Input);
			//if( gl )
			//{
				//Xmin = gl.X.From;
				//Xmax = gl.X.To;					
			//}
		//}
		//else
		//{
			//Xmin = trCurves.XMin.dVal;
			//Xmax = trCurves.XMax.dVal;
		//}
		//
		//double dAbsoluteRangeMargin = ( Xmax - Xmin ) * trCurves.RangeMargin.dVal / 100.0;
		//Xmin -= dAbsoluteRangeMargin;
		//Xmax += dAbsoluteRangeMargin;
		/// Iris 11/21/06 CORRECT_SPAN_AXIS_AS_FITX_WHEN_GET_INPUT_FROM_WKS
		/*
		double 		dAxisMin, dAxisMax;
		if(gl)
		{
			dAxisMin = gl.X.From;
			dAxisMax = gl.X.To;
		}
		/// ML 10/2/2006 NLFIT_CURVES_CLEANUP
		//get_data_by_fitted_curve_options(vData, vFit, fitOptions, &dAxisMin, &dAxisMax);
		get_data_by_fitted_curve_options(vData, vFit, fitOptions, &dAxisMin, &dAxisMax, bSort);
		/// end NLFIT_CURVES_CLEANUP
		*/
		///Arvin 04/12/07 v8.0599 PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE by cp's suggestion	
		//get_data_by_fitted_curve_options(vData, vFit, fitOptions, gl, bSort);
		TreeNode 	trInputData = trOp.GUI.InputData;
		int nDataMode;
		trInputData.GetAttribute(STR_USE_ATTRIB, nDataMode);
		GraphLayer gl;
		if(nDataMode != DATA_MODE_CONCATENATE)
		{
			///Get souce graph layer
			DataRange		rngInput;
			if ( !GetInput(rngInput) )
				return false;
			
			DWORD dwRules = GetDataRules(trOp);
			DWORD			dwPlotUID;
			vector vy;
			int nRet = rngInput.GetData(dwRules, index, &dwPlotUID, NULL, &vy);
			DataPlot dp;
			dp = (DataPlot)Project.GetObject((int)dwPlotUID);
			if(dp)
				dp.GetParent(gl);

			/// Iris 11/19/2008 v8.0975 QA80-12591-P1 FIX_APPARENT_FIT_MISS_DATA_WHOSE_LOGARITHM_IS_NEGATIVE
			/*
			///Kyle 11/18/2008 QA80-12591 ADD_MORE_OPTION_FOR_INPUT_DATA_TYPE_IN_FITTING_TOOLS
			//get_data_by_fitted_curve_options(vData, vFit, fitOptions, gl, NULL, NULL, bSort);
			get_data_by_fitted_curve_options(vData, vFit, fitOptions, gl, true, NULL, NULL, bSort);
			///End ADD_MORE_OPTION_FOR_INPUT_DATA_TYPE_IN_FITTING_TOOLS
			*/
			if( IsApparentFit(trOp) && (FIT_CURVE_UNIFORM_LOG == fitOptions.DataType || FIT_CURVE_SAME_AS_SOURCE_GRAPH == fitOptions.DataType) )
			{
				// if choose Apparent Fit DataRule will containt DRR_APPARENT bit, DataRange::GetData will get data convert with logarithm, 
				// so for option in fact should same as uniform linear.
				fitOptions.DataType = FIT_CURVE_UNIFORM_LINEAR;
				
				//---- Iris 11/19/2008 v8.0975 QA80-12591-P2 FIX_APPARENT_FIT_ON_GRAPH_CUSTOM_RANGE_GET_INCORRECT_X
				double 	dMin, dMax;
				vData.GetMinMax(dMin, dMax);
				
				int 	nXScaleType = -1;
				axis_get_scale_type(gl, &nXScaleType);
				
				if(fitOptions.Range == FIT_CURVE_CUSTOM)
				{
					if(nXScaleType >= 0)
					{
						fitOptions.Min = real_space(fitOptions.Min, nXScaleType);
						fitOptions.Max = real_space(fitOptions.Max, nXScaleType);
					}
				}
				else if(fitOptions.Range == FIT_CURVE_SPAN_AXIS)
				{
					if(gl && nXScaleType >= 0)
					{
						dMin = real_space(gl.X.From, nXScaleType);
						dMax = real_space(gl.X.To, nXScaleType);
					}
					else
					{
						//---- Iris 11/20/2008 v8.0975d QA80-12591-S1 CENTRALIZE_NEW_X_DATA_TYPE_AND_LOG_TYPE_CODES
						//get_min_max_inc(dMin, dMax, false);
						get_min_max_inc(dMin, dMax, SCALE_TYPE_LINEAR); //if data from worksheet, to add default left & right margin 0.08
						//----
					}
				}					
				//----	
				
				get_data_by_fitted_curve_options(vData, vFit, fitOptions, NULL, true, &dMin, &dMax, bSort);
			}
			else
			{
				get_data_by_fitted_curve_options(vData, vFit, fitOptions, gl, true, NULL, NULL, bSort);
			}
			///end FIX_APPARENT_FIT_MISS_DATA_WHOSE_LOGARITHM_IS_NEGATIVE
		}		
		else
			///Kyle 11/18/2008 QA80-12591 ADD_MORE_OPTION_FOR_INPUT_DATA_TYPE_IN_FITTING_TOOLS
			//get_data_by_fitted_curve_options(vData, vFit, fitOptions, NULL, NULL, NULL, bSort);
			get_data_by_fitted_curve_options(vData, vFit, fitOptions, NULL, true, NULL, NULL, bSort);
			///End ADD_MORE_OPTION_FOR_INPUT_DATA_TYPE_IN_FITTING_TOOLS
		///end PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE
		///end CORRECT_SPAN_AXIS_AS_FITX_WHEN_GET_INPUT_FROM_WKS
		///end UPDATE_FITTED_CURVE_OPTIONS
		
		return true;
	}
	//------
		
	/// Iris 2/15/06 QA70-8461 v8.0365 INCLUDE_RPLICA_FOR_FITTING
	virtual void 	calcAddMultiPeaksFitCurveTable(TreeNode& trOp, TreeNode& trFC, int index, vector& vX, vector& vFitX, vector& vFitY, const tagFitResultCurveDataOptions& fitOptions, FitParameter *psFitParameter, int nMultiplicity = 1);  
	///End INCLUDE_RPLICA_FOR_FITTING
private:
	bool calcAddFitCurvesIntoTable(TreeNode& trOp, TreeNode& trFC, int index, LPCSTR lpcszDataLabel, vector& vX, vector& vFitX, vector& vFitY, const FitResultCurveDataOptions& fitDataOptions, FitParameter *psFitParameter, GraphLayer&grLayAppar);
	bool calcAddFitCurvesIntoTable(TreeNode& trOp, TreeNode& trFC, int index, LPCSTR lpcszDataLabel, matrix& mXs, matrix& mFitXs, matrix& mFitYs, const FitResultCurveDataOptions& fitDataOptions, GraphLayer& grLayAppar);
	///Sophy 1/15/2009 v8.0957 QA80-12918 FITCURVE_X_COLULMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA
	bool updateFitCurvesXColumnFormat(TreeNode& trFC, int nNumX, int nDatasetIndex);
	///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING move to protected
	//bool updateOneXColumnFormat(TreeNode& trCol, int nIndex);
	///end FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
	///end FITCURVE_X_COLULMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA
	/// Arvin 11/03/06 ALL_LEGEND_SAME_NAME_FOR_FIT_GRAPH
	//bool addOneFitDataIntoTable(TreeNode& trFC, matrix& mFitData, GraphLayer& grLayAppar, bool bIsX);
	bool addOneFitDataIntoTable(TreeNode& trFC, matrix& mFitData, GraphLayer& grLayAppar, bool bIsX, int index = 0, LPCSTR lpcszDataLabel = NULL);
	///end ALL_LEGEND_SAME_NAME_FOR_FIT_GRAPH	

	///Joseph 09/18/06 MOVE_CALIBRATION_TABLE_OUT_OUTPUT
	void constructCalibrationBranch( TreeNode& trOperation )
	{
		TreeNode trGUI = trOperation.GUI;
		GETN_USE(trGUI)	
		
			GETN_BEGIN_BRANCH(Calibration, _L(/*"Calibration Tables"*/ "Find Specific X/Y"))///Arvin 12/29/06 MODIFY_BY_MAX_SUGGESTION 
				GETN_ID_BRANCH(IDST_REPORT_CALIBRATION_TABLE)  ///Joseph 09/15/06  HIDE_THE_CALIBRATION_TABLE
				
				GETN_BEGIN_BRANCH(Custom2, _L("Find X from Y")) GETN_ID_BRANCH(IDST_REPORT_CUSTOM_TABLE2_BEGIN) GETN_CHECKBOX_BRANCH(0) GETN_ID_REPEAT_BRANCH(2) GETN_OPTION_EVENT(on_check_calibration_branch_event)	///Jasmine 09/27/06 DISABLE_CALIBRATION_OUTPUT_IF_UNCHECK
					/// Iris 03/09/2007 v8.0578 CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
					//tree_construct_gui_custom_table_branch(GETN_CURRENT_NODE, 5, 2, false, true);
					tree_construct_gui_custom_table_branch(GETN_CURRENT_NODE, 5, 1, _L("Number of X Columns"), false, true);
					////end CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
				GETN_END_BRANCH(Custom2)
	
				GETN_BEGIN_BRANCH(Custom3, _L("Find Y from X")) GETN_ID_BRANCH(IDST_REPORT_CUSTOM_TABLE3_BEGIN) GETN_CHECKBOX_BRANCH(0) GETN_ID_REPEAT_BRANCH(3) GETN_OPTION_EVENT(on_check_calibration_branch_event)	///Jasmine 09/27/06 DISABLE_CALIBRATION_OUTPUT_IF_UNCHECK
					/// Iris 03/09/2007 v8.0578 CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
					//tree_construct_gui_custom_table_branch(GETN_CURRENT_NODE, 5, 2, false, true);
					tree_construct_gui_custom_table_branch(GETN_CURRENT_NODE, 5, 1, _L("Number of Y Columns"), false, true);
					////end CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
				GETN_END_BRANCH(Custom3)			
			
			GETN_END_BRANCH(Calibration)
	}
	///end MOVE_CALIBRATION_TABLE_OUT_OUTPUT
	
	/// ML 6/7/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY
	/// Iris 03/09/2007 v8.0578 CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
	//static	void	tree_construct_gui_custom_table_branch(TreeNode &trTbl, int nRows, int nCols, bool bThemeName, bool bTableLabel, LPCSTR lpcz = NULL)
	static	void	tree_construct_gui_custom_table_branch(TreeNode &trTbl, int nRows, int nCols, LPCSTR lpcszColLabel, bool bThemeName, bool bTableLabel, LPCSTR lpcz = NULL)
	///end CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
	{
		GETN_USE(trTbl)
		/// Iris 9/11/06 QA70-8926-5 v8.0478 REMOVE_1_FROM_CUSTOM_TABLE_ROW_COL_NUM
		//GETN_COMBO(Rows, "Number of Rows", nRows, "|1|2|3|4|5|6|7|8|9") GETN_ID(IDE_REPORT_CUSTOM_TABLE_ROWS) GETN_OPTION_NUM_FORMAT( "%d" )
		//GETN_COMBO(Cols, "Number of Columns", nCols, "|1|2|3|4|5|6|7|8|9") GETN_ID(IDE_REPORT_CUSTOM_TABLE_COLS) GETN_OPTION_NUM_FORMAT( "%d" )
		///Joseph 09/27/06 FINDXY_TO_SEPERATE_SHEET
		//GETN_COMBO(Rows, "Number of Rows", nRows, "|2|3|4|5|6|7|8|9") GETN_ID(IDE_REPORT_CUSTOM_TABLE_ROWS) GETN_OPTION_NUM_FORMAT( "%d" )
		///End FINDXY_TO_SEPERATE_SHEET
		/// Iris 03/09/2007 v8.0578 CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
		//GETN_COMBO(Cols, "Number of Columns", nCols, "|2|3|4|5|6|7|8|9") GETN_ID(IDE_REPORT_CUSTOM_TABLE_COLS) GETN_OPTION_NUM_FORMAT( "%d" )
		GETN_COMBO(Cols, lpcszColLabel, nCols, "|1|2|3|4|5|6|7|8|9") GETN_ID(IDE_REPORT_CUSTOM_TABLE_COLS) GETN_OPTION_NUM_FORMAT( "%d" )
		///end CHANGE_NUMOFCOLS_TO_NUMOFOUTCOLS
		///End REMOVE_1_FROM_CUSTOM_TABLE_ROW_COL_NUM
		
		if ( bThemeName )
		{
			GETN_STR(Theme, _L("Theme"), "") GETN_ID(IDST_REPORT_CUSTOM_TABLE_THEME)
		}
		
		///Joseph 09/27/06 FINDXY_TO_SEPERATE_SHEET
		//don't use the Table title any more.
		//temp remove this
		//if ( bTableLabel )
		//{
			//GETN_STR(TblTitle, _L("Table title"), lpcz) GETN_ID(IDE_REPORT_CUSTOM_TABLE_TITLE)
		//}
		///End FINDXY_TO_SEPERATE_SHEET
	}
	/// end CUSTOM_TABLES_FOR_FIND_XY
	///End MOVE_CALIBRATION_TABLE_OUT_OUTPUT

	
	///Cheney/Iris 2006-9-4 AVE_REPLICA_DATA_IF_PLOTTYPE_EXIST_AND_NOT_RAW_DATA
	bool 	isPlotAverageData()
	{
		Tree 	trOp;
		GetTree(trOp);
		
		bool bPlotAveData = false;
		
		TreeNode 	trInputData = trOp.GUI.InputData;
		int nDataMode;
		trInputData.GetAttribute(STR_USE_ATTRIB, nDataMode);
		if(nDataMode == DATA_MODE_CONCATENATE)
			bPlotAveData = true;
		
		return bPlotAveData
	}
	///end AVE_REPLICA_DATA_IF_PLOTTYPE_EXIST_AND_NOT_RAW_DATA
	

	
protected:
	//virtual 
	bool	IsResidualGraph(int nGraphIndex) 
	{ 
		if( nGraphIndex >= GRAPH_RESIDUALS_SCATTER && nGraphIndex <= GRAPH_RESIDUALS_LAG_PLOT )
			return true;
		return false;
	}
	
	///Iris 1/18/06 CENTRALIZE_TO_GET_GRAPH_GUI_NODE
	/////Iris 6/04/05 MOVE_FITTED_CURVES_TO_ROOT_LEVEL
	//TreeNode GetGUIGraphNodes(TreeNode& trOp, int nGraphIndex = 0)
	//{
		////int nID = IDST_RESULT_GRAPHS + nGraphIndex;  ///Iris 8/17/05 MAKE_LASTUSE_WORK_FOR_ID_LARGER_THAN_BRANCH_MASK
		//int nID = IDE_RESULT_GRAPHS + nGraphIndex;
		//TreeNode trN = tree_get_node_by_id(trOp.GUI, nID, true);		
		//return trN;
	//}
	///End CENTRALIZE_TO_GET_GRAPH_GUI_NODE
	
	/// Iris 9/19/05 QA70-7889 PASTE_CUSTOM_TABLE_TO_FIT_CURVE_GRAPH_TABLE
	//virtual
	bool	IsPasteCustomTableToReportGraph(int nGraphIndex);
	///End PASTE_CUSTOM_TABLE_TO_FIT_CURVE_GRAPH_TABLE
	
//---- CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
//	/// Iris 9/19/05 QA70-8015-P15 OUTPUT_RESULT_CURVE_TO_WKS
//	//virtual 
//	bool GetReportDatasInOneTable(TreeNode& trOp, TreeNode& trTable, int nIndex, int nTotalNumData);
//	///End OUTPUT_RESULT_CURVE_TO_WKS
//----	

protected:
	///Arvin 08/03/07 WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
	//virtual bool AddParamterTableToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors,
	//		const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesPostfix, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL);
	///Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said
	//virtual bool AddParamterTableToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors,
	//		const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesPostfix, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0);
	///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	//virtual bool AddParamterTableToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors,
			//const FitParameter* pFitParams, vector<string>& vstrParamNames, vector<string>& vstrParamNamesPostfix, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0, vector<bool> &vbIsShared = NULL);
	virtual bool AddParamterTableToReportTree(TreeNode &trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors,
			const FitParameter* pFitParams, const FITPARAMSINFO& stParamInfo, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, vector<bool> &vbIsDerived = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0, vector<bool> &vbIsShared = NULL);
	///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	///end ADD_STAR_MARK_FOR_SHARED_PARAMS
	///end WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
	
	/// Iris 01/09/2007 v8.0539 ADD_PARAMTERS_SUMMARY_TABLE
	///Arvin 08/03/07 WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
	//virtual bool AddParamtersSummaryTableToReportTree(TreeNode& trOp, int index, LPCSTR lpcszDataLabel, int nTotalNumData, const FitParameter* pFitParams, const vector<string>& vstrParamNames, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, const RegStats &sRegStats = NULL);
	virtual bool AddParamtersSummaryTableToReportTree(TreeNode& trOp, int index, LPCSTR lpcszDataLabel, int nTotalNumData, const FitParameter* pFitParams, const vector<string>& vstrParamNames, const FitDerivedParameter* pstDerivedParams = NULL, int nNumDerivedParams = 0, const RegStats &sRegStats = NULL, vector<bool> &vbIsDerived = NULL, int nMultiplicity = 1, int nNumParamInFunc = 0, int nDupUnit = 0);
	///end WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
	///end ADD_PARAMTERS_SUMMARY_TABLE
	
	///Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
	//virtual
	int		GetDelColNum(TreeNode& trOp, int nGraphIndex);
	///end FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE

	/// Iris 9/04/06 SET_COL_DESIG_SEPARATELY
	///// Thomas 05/30/2006 ADD_SETREPORTWORKSHEETDESIGNATION_FOR_FITTTEROPERATION
	//void SetReportWorksheetDesignation(TreeNode &trOp, TreeNode &trFC, int nGraphIndex = GRAPH_FIT_CURVE)
	//{
		//if(nGraphIndex == GRAPH_FIT_CURVE) {
			//int 		nColIndex = 0;
			//vector<int> vecDesignation;
			//GetColumnDesignation(trOp, trFC.Children.Count(), vecDesignation);
			//foreach(TreeNode trSub in trFC.Children)
			//{
				//trSub.SetAttribute(STR_COL_DESIGNATION_ATTRIB, vecDesignation[nColIndex]);
				//nColIndex++;
			//}
			//return;
		//}
		//
	//}
	///// End ADD_SETREPORTWORKSHEETDESIGNATION_FOR_FITTTEROPERATION
///Arvin 10/23/06 FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED
public:
	///Arvin 01/17/06 CALC_RESIDUAL_WITH_REPLICA
	//virtual bool CalcAddStatsHistPlotData(TreeNode& trOp, int index, FitParameter* psFitParameter, vector &vY, vector &vX, const vector<string> &vstrFactors, const matrix &mXs,  const vector &vWeights, string& strDataLabel, DWORD dwPlotObjUID)
	virtual bool CalcAddStatsHistPlotData(TreeNode& trOp, int index, FitParameter* psFitParameter, vector &vY, vector &vX, const vector<string> &vstrFactors, const matrix &mXs,  const vector &vWeights, string& strDataLabel, DWORD dwPlotObjUID, int nMultiplicity = 1)
	///end CALC_RESIDUAL_WITH_REPLICA
	{
		if( !IsCreateReportGraph(trOp, GRAPH_RESIDUALS_HISTOGRAM) )
			return true;
			
		GraphLayer	grLayAppar;
		if ( dwPlotObjUID && IsApparentFit(trOp) )
		{
			DataPlot		dpl;
			dpl = Project.GetObject(dwPlotObjUID);
			if (dpl.IsValid())
				dpl.GetParent(grLayAppar);
		}
		///Arvin 01/18/06 CALC_RESIDUAL_WITH_REPLICA
		/*
		if(!getResidualData(trOp, index, psFitParameter, vX, vY, vFitY, vRe, mXs, grLayAppar))
			return false;
		*/
		//We can not do residual analysis for muti-peak fitting, so disable it temporarily
		vector vRe, vFitY;
		///------ Folger 03/23/09 PA_FAILS_TO_MAKE_CORRECT_RESIDUAL_PLOT_WHEN_HAS_ONLY_ONE_PEAK
		//if(nMultiplicity > 1)
		//{
			//matrix mRegular;
			//if(!GetCumRegularResidualData(trOp, vX, vY, psFitParameter, vRe, vFitY, index, nMultiplicity, vWeights, mXs, grLayAppar, mRegular))
				//return false;
		//}
		//else
		//{
			//if(!getResidualData(trOp, index, psFitParameter, vX, vY, vFitY, vRe, mXs, grLayAppar))
				//return false;
		//}
		matrix mRegular;
		if ( !GetCumRegularResidualData(trOp, vX, vY, psFitParameter, vRe, vFitY, index, nMultiplicity, vWeights, mXs, grLayAppar, mRegular) )
			return false;
		///------ End PA_FAILS_TO_MAKE_CORRECT_RESIDUAL_PLOT_WHEN_HAS_ONLY_ONE_PEAK
		
		///end CALC_RESIDUAL_WITH_REPLICA
		vector vResidual;
		int nResType = GUIHasWhatTypeResidualGraph(trOp);
		if(GetOneTypeResidualData(trOp, vX, vRe, vResidual, index, 0, nResType, vY, vWeights, mXs))
			vRe = vResidual;
	
		/// Iris 04/20/09 QA80-12574-P1 RESET_ALL_GRAPHS_FAILS_TO_PLOT_RESIDUAL_HISTOGRAM_IN_SR4_OPJ
		/*
		double dMin, dMax;
		vRe.GetMinMax(dMin, dMax);
		if((is_double_legal(&dMin) && is_double_legal(&dMax)) || (is_missing_value(dMin) && is_missing_value(dMax)))
		{
			AddBinDataTableAndGraphNodes(trOp, index, vRe, vstrFactors, strDataLabel);
		}
		if(!calcStatsData(trOp, index, vRe, vWeights))
			return false;
		
		return true;
		*/
		return CalcAddStatsHistPlotData(trOp, index, vRe, vWeights, vstrFactors, strDataLabel);
		///end RESET_ALL_GRAPHS_FAILS_TO_PLOT_RESIDUAL_HISTOGRAM_IN_SR4_OPJ		
	}
///end FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED

	/// Iris 01/17/2007 v8.0543 CORRECT_THE_WAY_TO_GET_DATA_LABEL
	/////Arvin 11/03/06 ALL_LEGEND_SAME_NAME_FOR_FIT_GRAPH
	//virtual void GetOneInputColString(int index, int nCol, string& strCol);
	/////END ALL_LEGEND_SAME_NAME_FOR_FIT_GRAPH
	///end CORRECT_THE_WAY_TO_GET_DATA_LABEL
	
};


class FitRegression : public FitterOperation
{
///Arvin 08/02/07 CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES
private:	
	void 	appendFitFootnoteToParamTable(TreeNode& trOp);
///end CHECK_WEIGHT_DATA_HAS_MISSING_AND_NEGATIVE_VALUES

	///Sophy 9/13/2010 ORG-1037-S1 NO_APPARENT_FIT_FOOTNOTE_WHEN_BOTH_XY_AXES_LINEAR_ON_SRC_GRAPH
	bool	isSourceGraphLinearScale(TreeNode& trOp);
	///end NO_APPARENT_FIT_FOOTNOTE_WHEN_BOTH_XY_AXES_LINEAR_ON_SRC_GRAPH

protected:
	//virtual
	void ConstructAddBeforeQuantitiesToCompute(TreeNode& trGUI)
	{
		ConstructAddFitLROptions(trGUI);
	}
	
	/// YuI 03/05/09 QA70-13220 WHOLE_WORKSHEET_INPUT_XYRANGE
	virtual BOOL	IsEntireWorksheetInputSupported()
	{
		return TRUE;
	}
	/// end WHOLE_WORKSHEET_INPUT_XYRANGE
	
	//virtual
	BOOL Construct(TreeNode& tr, int nOption = 0)
	{
		nOption = 1; //1 means in FittedCurve options, should show "Same X as Data" not "Same XY as Data"
		if( FitterOperation::Construct(tr, nOption) )
		{
			/// YuI 03/06/07 regressions should have Error node in input data
			if( tr.GUI )
			{
				TreeNode trInputData = tr.GUI.InputData;
				if( trInputData )
				{
					trInputData.SetAttribute(STR_INTERACTIVE_CONTROL_OPTIONS_ATTRIB, ICOPT_SUPPORT_ERROR_BAR);
					/// YuI 03/05/09 QA70-13220 WHOLE_WORKSHEET_INPUT_XYRANGE
					if( IsEntireWorksheetInputSupported() )
						octree_composite_range_set_entire_worksheet_support(&trInputData, -1);
					/// end WHOLE_WORKSHEET_INPUT_XYRANGE
				}
			}
			/// end yuI
			
			return TRUE;
		}
		return FALSE;
	}

protected:
	void	FilterParameterQuantities(TreeNode& trRow)
	{
		///Iris 01/31/2007 SHOW_DEPENDENCY_IN_PARAMS_TABLE
		//vector<int> vnNodesToHide = {IDE_PARAM_DEPENDENCY, IDE_PARAM_FIX};  ///Iris 10/13/05 REMOVE_FIX_FOR_LR_PR_MR
		vector<int> vnNodesToHide = {IDE_PARAM_FIX};
		///end SHOW_DEPENDENCY_IN_PARAMS_TABLE
		tree_set_attributes(trRow, vnNodesToHide, "0");
		octree_delete_nodes_by_attribute(&trRow, STR_SHOW_ATTRIB, false);
	}
	
	//virtual
	void	FilterFittingGUI(TreeNode& trOp) 
	{
		FitterOperation::FilterFittingGUI(trOp);
		
		///Cheney 2007-11-16 ONLY_NLFIT_XYFITTING_SHOW_REPLICA_RELATED_CHECK_BOX
		//hidden some unused options
		//vector<int> vnNodesToHide = {IDE_FIT_X_WEIGHTING_METHOD, IDE_FIT_Y_WEIGHTING_METHOD, 
		//IDE_FIT_USE_DATA_XY, IDE_FIT_Y_POINTS,  IDE_FIT_Y_MIN, IDE_FIT_Y_MAX, IDE_FIT_RANGE_FULL_XY, IDE_FIT_REDUCED_CHI_SQUARE, IDE_FIT_NUMBER_ITER, IDE_FIT_STATUS};
		///Sophy 10/27/2008 v8.961 QA80-12453 ADD_REDUCED_CHI_SQR_QUANTITY_OUTPUT_FOR_REGRESSION_FIT
		/*
		vector<int> vnNodesToHide = {IDE_FIT_X_WEIGHTING_METHOD, IDE_FIT_Y_WEIGHTING_METHOD, 
							IDE_FIT_USE_DATA_XY, IDE_FIT_Y_POINTS,  IDE_FIT_Y_MIN, IDE_FIT_Y_MAX, 
							IDE_FIT_RANGE_FULL_XY, IDE_FIT_REDUCED_CHI_SQUARE, IDE_FIT_NUMBER_ITER, IDE_FIT_STATUS,
							IDE_REPLICA_NUM, IDE_REPLICA_FROM_NTH_PARAM, IDE_NUM_OF_PARAMS_IN_REPLICA};	
		*/
		vector<int> vnNodesToHide = {IDE_FIT_X_WEIGHTING_METHOD, IDE_FIT_Y_WEIGHTING_METHOD, 
							IDE_FIT_USE_DATA_XY, IDE_FIT_Y_POINTS,  IDE_FIT_Y_MIN, IDE_FIT_Y_MAX, 
							IDE_FIT_RANGE_FULL_XY, IDE_FIT_NUMBER_ITER, IDE_FIT_STATUS,
							IDE_REPLICA_NUM, IDE_REPLICA_FROM_NTH_PARAM, IDE_NUM_OF_PARAMS_IN_REPLICA};	
		///end ADD_REDUCED_CHI_SQR_QUANTITY_OUTPUT_FOR_REGRESSION_FIT
		///end ONLY_NLFIT_XYFITTING_SHOW_REPLICA_RELATED_CHECK_BOX
		tree_set_attributes(trOp.GUI, vnNodesToHide, "0");

		trOp.GUI.Quantities.Statistics.ReducedChiSq.nVal = 0;
		
		/// Iris 02/28/2007 v8.0572 ADD_OPTIONS_TO_CONTRL_CONTENTS_IN_SUMMARY_TABLE
		trOp.GUI.Quantities.SummaryTable.ReducedChiSq.Show = false;
		trOp.GUI.Quantities.SummaryTable.ReducedChiSq.nVal = 0;
		///end ADD_OPTIONS_TO_CONTRL_CONTENTS_IN_SUMMARY_TABLE
		
		///Iris 8/15/05 QA70-8015 REMOVE_KEEP_SESSION_GRAPH
		//trOp.GUI.Output.KeepSessionGraph.Show = 1;
		trOp.GUI.Output.KeepSessionGraph.Show = false;
		trOp.GUI.Output.KeepSessionGraph.nVal = 0;
		///end REMOVE_KEEP_SESSION_GRAPH
		
	}

	/// Iris 05/17/2007 v8.0619 GET_ROW_INDEX_FOR_STATS_EXTREME_VAL_TABLE	
	//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);				
	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 = NULL);
	///end GET_ROW_INDEX_FOR_STATS_EXTREME_VAL_TABLE
	
	/// ML 11/11/2004 QA70-6845 CELL_VALUE_LINKING
	virtual	BOOL		AddToCustomTables(TreeNode &trOp, int index, int nTotalNumData, int nTableID)
	{
		return TRUE;
	}
	/// end CELL_VALUE_LINKING
	
	//virtual
	DWORD	GetDataRules(const TreeNode& trOperation, bool bIgnoreCombineInfo = false)
	{
		///Arvin 08/10/07 QA70-10197 ADD_NONE_OPTION_FOR_ERROR_AS_WEIGHT_IN_LR_PR_AND_MR
		/*
		DWORD		dw;
		if(trOperation.GUI.Fit.ErrBarWeight.nVal)
			///Echo 12/9/04 BIT_MEANING_CHANGED
			//dw = DRR_DEPERR_TO_WEIGHT | DRR_GET_DEPENDENT | DRR_NO_FACTORS | DRR_BAD_WEIGHT_TREATMENT;
			dw = DRR_DEPERR_TO_WEIGHT | DRR_GET_DEPENDENT | DRR_NO_FACTORS;
		else
			///Echo 12/9/04 BIT_MEANING_CHANGED			
			//dw = DRR_DEPERR_TO_WEIGHT | DRR_GET_DEPENDENT | DRR_NO_FACTORS;	
			dw = DRR_BAD_WEGHT_EXCLUDE  | DRR_GET_DEPENDENT | DRR_NO_FACTORS;	
		*/
		DWORD		dw = DRR_GET_DEPENDENT | DRR_NO_FACTORS;
		int nEWMethod = trOperation.GUI.Fit.ErrBarWeight.nVal;
		switch(nEWMethod)
		{
		case ERRBARWEIGHT_INSTRUMENTAL:
			dw |= DRR_DEPERR_TO_WEIGHT;
			break;
		case ERRBARWEIGHT_DIRECT_WEIGHTING:
			dw |= DRR_BAD_WEGHT_EXCLUDE;
			break;
		case ERRBARWEIGHT_NO_WEIGHTING:
			dw |= DRR_NO_WEIGHTS;
			break;
		}
		///end ADD_NONE_OPTION_FOR_ERROR_AS_WEIGHT_IN_LR_PR_AND_MR
			/// ML 9/18/2006 DATARANGE_EXTRACTION_APPARENT_FIT
		if(IsApparentFit(trOperation))
			dw |= DRR_APPARENT;
		/// end DATARANGE_EXTRACTION_APPARENT_FIT

		return CheckDataRules(trOperation, dw, bIgnoreCombineInfo);
	}
	
	/// Iris 5/22/06 ADD_ANOVA_TABLE_FOR_NLSF
	////virtual
	//void UpdateReportingTables(TreeNode &trOperation, int nTotalNumData, int nExeMode)
	//{
		//FitterOperation::UpdateReportingTables(trOperation, nTotalNumData, nExeMode);
//
		//TreeNode trTable = trOperation.Calculation.ANOVAs;
		//if (trTable)
		//{
			//int		nOneTable = GetTableStringSupport(false);
			//bool		bHaveSubLevel = 1 < nTotalNumData;
			////---- CPY 12/21/04 CLEANUP_ANOVA1_AND_USE_BASE_CLASS_FIX
			///*
			//if ( bHaveSubLevel )
			//{
				////---- Iris 9/13/04 ADD_TABLE_BIT_TO_TREETABLE
				////string strTable = GetTableStringSupport(false); 
				//int nTable = GetTableStringSupport(false, false, true, false);
				////----
				//
				//trTable.SetAttribute(TREE_Table, nTable);
	//#ifdef ANOVA_IN_SEPARATE_TABLES
				//foreach(TreeNode trSub in trTable.Children)
					//trSub.SetAttribute(TREE_Table, nOneTable);				
	//#endif // ANOVA_IN_SEPARATE_TABLES
			//}
			//else
				//trTable.SetAttribute(TREE_Table, nOneTable);
			//*/
	//#ifndef ANOVA_IN_SEPARATE_TABLES
				//#pragma message("ANOVA_IN_SEPARATE_TABLES not defined")
				//bHaveSubLevel = false;				
	//#endif // ANOVA_IN_SEPARATE_TABLES
			//UpdateTableString(trTable, bHaveSubLevel);
			////---- end CLEANUP_ANOVA1_AND_USE_BASE_CLASS_FIX
		//}
		//else
			//error_report("FitRegression found invalid Calculation.ANOVA node");		
	//}
	///End ADD_ANOVA_TABLE_FOR_NLSF
	
	/// Iris 9/23/04 ADD_COV_AND_CORR_REPORT
	//virtual	int		CallLLOC(TreeNode &trOp, vector &vY, vector &vX, matrix &mMultiIndep, vector &vWeights,
	//		FitParameter* psFitParameter, uint nSizeFitParams, RegStats* psRegStats, RegANOVA* psRegANOVA, RegCalcInternal* psInternal)
	///Arvin 12/04/06 ADD_CONF_PRED_BANDS_FOR_MR
	///Arvin 05/18/07 USE_REDUCED_CHISQ_CHECKBOX_NOT_WORK
	//virtual	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)
	virtual	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
	///END ADD_CONF_PRED_BANDS_FOR_MR
	{
		error_report("CallLLOC not implemented!");
		return -1;
	}
	
	/// end RANGE_BASED_REGRESSIONS
	
	///Iris 4/18/05 FIX_NLSF_CONF_PREDI_BAND_NOT_WORK
	/*
	//----- CPY 6/25/04 COMBINE_LR_PR_CODES_TO_REGRESS_CLASS
	//-------------------------------------------------
	// the following MakeFitY, MakeFitErrConf and MakeFitErrPred are taken
	// from from LR 
	//virtual 
	bool MakeFitErrConf(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* sFitParameter, RegStats& sRegStats, RegCalcInternal& sReg)
	{
		double db_Err = sFitParameter[1].Error;
	
		LROptions sLROptions;
		sLROptions = trOp.GUI.Fit;
		///Max 9/09/04 MODIFY_FIXINTERCEPT
		//if( sLROptions.ThroughZero )
		if( sLROptions.FixIntercept )
		///End MODIFY_FIXINTERCEPT
		{
			vFitErr = fabs(vFitX) * db_Err;
		}
		else
		{
			vFitErr = sqrt(1.0 / sReg.dSumWeight + (vFitX - sReg.dxAve)^2 / sReg.dSxx) * sRegStats.RMSESD;
		}
		
		return true;
	}
	//virtual 
	bool MakeFitErrPred(TreeNode &trOp, const vector& vFitX, vector& vFitErr, FitParameter* sFitParameter, RegStats& sRegStats, RegCalcInternal& sReg)
	{
		vFitErr = sqrt(1.0 + 1.0 / sReg.dSumWeight + (vFitX - sReg.dxAve)^2 / sReg.dSxx) * sRegStats.RMSESD;
		return true;
	}
	//virtual 
	*/
	/// end FIX_NLSF_CONF_PREDI_BAND_NOT_WORK
	
	///Iris 4/21/05 MAKEFITY_SUPPORT_MULTI_REGRESSION
	///// YuI 8/30/04 QA70-4387 NLFITTER_OPERATION_IMPLEMENTATION
	////	bool MakeFitY(TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* sFitParameter)
	//bool MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* sFitParameter)
	///// end NLFITTER_OPERATION_IMPLEMENTATION
	virtual bool MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* sFitParameter, const matrix& mXs, int nPeak)
	///end MAKEFITY_SUPPORT_MULTI_REGRESSION
	{
		//double dSlope = sFitParameter[1].Value;	
		//double dIntercept = sFitParameter[0].Value;
		//vFitY = vFitX * dSlope + dIntercept;
		int 	nOrder = GetParameters(trOp, index);	
		if(vFitX.GetSize() > 0) ///Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
		{
			vFitY = sFitParameter[0].Value;
			for(int ii = 1; ii < nOrder; ii++)
				vFitY += (vFitX^ii) * sFitParameter[ii].Value;
		}
			
		return true;
	}
	//----- end COMBINE_LR_PR_CODES_TO_REGRESS_CLASS
	
	/// Iris 06/29/06 QA70-8726 CHECK_INPUT_DATA_BEFORE_CALCULATION
	//virtual 
	int 	CheckInputData(const TreeNode& trGUI, const TreeNode& trOperation)
	{
		int nRet = WksReportOperation::CheckInputData(trGUI, trOperation);
		
		DataRange dr;
		dr.Create(trGUI.InputData, false);
		if(dr)
		{		
			DWORD dwRules = GetDataRules(trOperation);
			int nNumData = dr.GetNumData(dwRules);
			for(int ii=0; ii<nNumData; ii++)
			{
				vector			vY, vX;
				DWORD			dwPlotUID;
				int				nColOrRowIndex = dr.GetData(dwRules, ii, NULL, NULL, &vY, &vX);
				if(nColOrRowIndex < 0)
					return CER_NO_DATA;
				if(vX.GetSize() < 2 || vY.GetSize() < 2)
					return CER_DATA_TOO_FEW;			
			}
		}
		
		return nRet;		
	}
	///End CHECK_INPUT_DATA_BEFORE_CALCULATION

	///------ Folger 03/19/10 QA81-15218 ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
	virtual	BOOL	OperationtoGUI(TreeNode& trOperation, bool bInit, string* pstrSelectedTheme = NULL, bool bSetDefaultInputOnInit = true, DWORD dwExeCtrl = 0, DWORD dwParam = 0);
	///------ End ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
};

///------ Folger 03/19/10 QA81-15218 ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
class	FitterOperationUpdateFromQuickfitHelper
{
public:
	FitterOperationUpdateFromQuickfitHelper(TreeNode&				trGUI
											, DWORD					dwParam
											, DWORD&				dwExeCtrl
											);

	BOOL	UpdateData();

	void	UpdateConditions(string*&				pstrSelectedTheme
							, bool&					bSetDefaultInputOnInit
							);

private:
	virtual	void	GetIndepsAndDeps(vector<string>& vsIndeps, vector<string>& vsDeps)		{ ASSERT(FALSE); }
	///------ Folger 03/24/10 QA81-15218-P2 SHOULD_TAKE_CARE_OF_ERROR_WHEN_SWITCH_TO_LINEAR_FIT
	virtual	int		GetDataNodeID()															{ ASSERT(FALSE); return -1; }
	///------ End SHOULD_TAKE_CARE_OF_ERROR_WHEN_SWITCH_TO_LINEAR_FIT

protected:
	string				m_strFunc, m_strCateg;
	vector				m_vParams;
	vector<string>		m_vstrParamNames;
	QuickFitPlotInfo	m_stPlotInfo;

	TreeNode			m_trGUI;

private:
	DWORD				m_dwExeCtrl;
	DataPlot			m_dp;
};
///------ End ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU

#endif //_FITTEROPERATION_H

