/*------------------------------------------------------------------------------*
 * File Name:	NLFitSession.h													*
 * Creation: 	Hong															*
 * Purpose: OriginC Source H file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:  															*
 *	Hong 12/05/08 v8.0860 JASIME_SAID_PEAK_CENTERS_HANDLING_IS_NOT_DIMENSION_SENSITIVE
 *	Hong 20/05/08 v8.0867 CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION					*
 *	Max 06/10/08 v8.0881 CENTRALIZE_TIP_STRINGS_FOR_BUTTONS_IN_NLFIT_AND_PA		*
 *	Hong 06/17/08 v8.0886 REFACTORING_ORTHOGONALITY								*
 *	Hong 06/26/08 v80.891e CLEAN_SESSION_CLASS_FOR_ONLY_FIT_PURPOSE				*
 *	Hong 07/23/08 QA80-11816 AUTO_PARAMS_INIT_SUPPORT_MULTI_DEPS_MULTI_INDEPS	*
 *	Hong 08/13/08 QA80-12008 REACTIVE_FIT_RELATIVE_BTN_AFTER_CONSTRAINT_CHANGE	* 
 *	Hong 08/14/08 v8.0922 FIX_MATRIX_FIT_FAIL_DO_REDUCE							*
 *	Hong, Jasmine 08/14/08 PEAKSMODE_MULTIFUNC_GLC								*
 *	Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER	*
 *	Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION					*
 *	Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION			*
 *	Hong 08/27/08 v8.0931 FIX_ORIGIN_CRASH_WHEN_CLICK_OK_AFTER_CONVERGE			*
 *	Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT					*
 *	Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION							*
 *	Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER				*
 *	Hong 09/10/08 v8.0936b FIX_FIT_OUTPUT_NOT_RESET_AFTER_PARAMS_INIT			*
 *	Hong 09/10/09 v8.0936b FIX_REPLICA_FAIL_CORRECT_ININT						*
 *	Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG				*
 *	Sim 09-10-2008 NLFIT_LABTALK_TREE_ACCESS									*
 *	Hong 09/16/08 FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK							*
 *	Hong 09/16/08 v8.0940 FIX_MULTI_DATASEST_FAIL_RESET_PARAMS_SIZE_WHEN_DECREASE_DATASET_NUM
 *	Hong 09/16/08 QA80-11406 THEME_APPLY_SHOULD_DUPLICATE_LAST_DATASET_VALUES_FOR_ADDITIONAL_DATASET
 *  Sophy 9/16/2008 CLEAN_NLFSPLITTER_FOR_81									*
 *	Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS		*
 *	Hong 09/22/08 v8.0944b FIX_PA_NEED_GET_ALL_PARAMS_IN_ONE_CALL				*
 *	Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE										*
 *	Hong 09/24/08 v8.0946 ROLLBACK_OLD_CODE_ADS_FITNL_CREATE_REPLICA_ITSELF		*
 *	Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION		*
 *	Hong 09/25/08 v8.0947 FIX_FDF_NOT_SET_FAIL_SETFUNCTION_EVEN_TRY_LOADFDF		*
 *	Hong 09/26/08 QA80-11463 FIX_NEW_SESSION_CONSTRAINT_FAIL_TO_WORK_EVEN_CONTRAINED_IN_FDF
 *	Hong 09/26/08 QA80-12063 ONLY_SINGLE_DEP_INDEP_CAN_PREVIEW_IN_SRC_PAGE		*
 *	Hong 09/26/08 v8.0948 FIX_MULTI_DEPS_INDEPS_FAIL_ITERATE					*
 *	Kyle 10/10/08 ADD_FUNCTION_GETFITRESULTSPARAMS_USED_IN_PA_BASECREATE		*
 *	Hong 10/10/08 v8.0953b NEW_MECHANISM_SHOULD_NOT_USE_SetFunctionsMultipeakFitting
 *	Hong 10/13/08 QA80-10624 NLFIT_ONLY_SUPPORT_POLAR_PLOT_WITH_THETA_AS_X		*
 *	Folger 10/13/08 SHOULD_GET_NON_TRIMMED_PARAMETERS_RESULTS_FOR_NLFIT_REPORT	*
 *	Folger 10/15/08 MOVE_COMPUTE_CONFIDENCE_LIMITS_METHODS_INTO_VC				*
 *	Folger 10/16/08 LCL&UCL_CAN_BE_CORRECTLY_GET_BY_GetParameterResults			*
 *	Folger 10/16/08 PA_FIT_CONTROL_DIALOG_NEED_TO_GET_AUTO_INIT_PARAMS_STATUS	*
 *	Hong 10/16/08 v8.0956 FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE						*
 *	Hong 10/16/08 v8.0956 FIX_MUTIL_FUNCS_AUTO_INIT_SHOULD_NOT_DEPENDENT_ON_FDF	*
 *	Hong 10/16/08 v8.0956 FIX_FIX_VALUES_NOT_SAVED_LEAD_APPLY_FAIL_IF_VALUE_NOT_CHECKED
 *	Sophy 10/17/2008 FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT				*
 *	Sophy 10/20/2008 QA80-12406 ADD_DERIVATIVE_PARAM_PAGE_IN_CODE_TAB_OF_NLFIT_DLG
 *	Jack 10/20/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT*
 *	Kyle 10/21/08 CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE	*
 *	Folger 10/21/08 SET_GET_BASELINE_PEAK_FITTING_STATUS_IN_NLPARAMSMNGR		*
 *	Hong 10/22/08 QA80-12374 FIX_UCL_LCL_MISSING_IN_REPORT_WHEN_CHECKED_AFTER_FIT_CONVERGE
 *	Hong 10/22/08 QA80-12432 FIX_LT_CMD_FIT_FAIL_FOR_REPLICA					*
 *	Hong 10/23/08 QA80-12434 TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS			*
 *	Hong 10/23/08 V8.0960 FIX_CONCATENATE_FIT_REPORT_FAIL_CORRECTLY_GENERATE_FIT_CURVE_DATA
 *	Sophy 10/24/2008 SUPPORT_MUILTI_INDEP_AND_DEP_PREVIEW_FOR_NLFIT_81			*
 *	Folger 10/24/08 v8.0960 CORRECT_FUNCTION_AND_PARAMETER_DIRTY_BITS_CHECKING	*
 *	Hong 10/27/08 v8.0961 FIX_PA_RUNTIME_ERROR_GENERATE_REPORT_WITHOUT_FIT		*
 *  Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION			*
 *	Folger 10/28/08 QA80-12465 v8.0962 SET_PARAMETER_SHOULD_CONSIDER_BOUNDS_ENABLE
 *	Hong 10/28/08 QA80-12469 v8.0963 FIX_NO_HINT_OF_LESS_REPLICA_NUM_FIRST_TIME_SET
 *  Iris 10/30/2008 v8.0963b CORRECT_ENABLE_FIT_BUTTON_CONDITION				*
 *	Jack 31/10/08 QA80-12423 SET_PA_CONSTRAINTS_WHEN_IT_IS_MULTIPLE_FUNCS_FIT	*
 *  Iris 11/01/2008 v8.0964 NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE		*
 *	Hong 11/04/08 v8.0965b FIX_GRID_NOT_UPDATE_WHEN_FIT_FAIL					*
 *	Sophy 11/4/208 UPDATE_CONCATENATE_SOURCE_PLOT_UID_AS_TO_REPORT_FITCURVE_ON_SRC_GRAPH
 *	Hong 11/04/08 QA80-12526 v8.0965b ADD_BACKWARD_COMPATIABLE					*
 *	Sophy 11/4/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
 *	Kyle 11/05/2008 TO_GET_FDF_TREE_AFTER_MODIFIED								*
 *	Folger 11/04/08 QA80-12509 v8.0965 SUPPORT_BOTH_PEAKS_SORTING_AND_REORDERING_FOR_MULTIPLE_PEAKS_FITTING
 *	Folger 11/06/08 QA80-12113 v0.966 FIX_GIBBERISH_SHOWN_IN_NLFIT_WHEN_FITTING_DID_NOT_CONVERGED
 *	Hong 11/06/08 v8.0966c FIX_BTN_NOT_DISABLED_WHEN_RESET_INPUT_DATA			*
 *	Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
 *	Sophy 11/7/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
 *	Jack 07/11/08 QA70-12329 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_SET_SEP_FIT	
 *	Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
 *	Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
 *	Folger 11/13/08 v8.0970 CHANGE_FUNCTION_SHOULD_RESET_SHARING				*
 *  Iris 11/14/2008 v8.0971b QA80-12584 FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED*
 *  Iris 11/15/2008 FIX_ADDBACKBASELINE_FAIL_TO_GET_BASELINE_DATA				*
 *  Iris 11/24/2008 v8.0987 FIX_FAIL_TO_FIND_NEGATIVE_PEAKS_IN_NLFIT			*
 *	Sophy 11/25/2008 QA80-12376 NLSF_THEME_FROM_SR4_FAIL_TO_WORK_IN_SR5			*
 *	Hong 11/25/08 v8.0979 FO_ONLY_HAVE_FDF_TREE_BUT_NO_FIT_FILE					*
 *	Sophy 11/25/2008 v8.979 QA80-12106 FIX_HISTOGRAM_RESIDUAL_PLOT_IN_NLFIT_BECAME_EMPTY_WIHT_MUILTI_INDEP_VARS
 *	Folger 12/04/08 QA80-12509 QA80-12509-P2 FIND_PEAKS_RESULT_IN_NLFIT_FAILS_TO_BE_SORTED_BY_CENTER_ASCENDINGLY
 *	Folger 12/08/08 QA80-12680 v8.0983 NON_PEAK_FUNCTION_CHANGED_FAIL_TO_DISPLAY_ERROR_MESSAGE_DUE_TO_RUNTIME_ERROR_CAUSED_BY_GETSUBVECTOR
 *	Folger 12/10/08 QA80-12751 v8.0984d SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
 *	Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE			*
 *	Sophy 12/18/2008 v8.0988 SHOW_MESSGAE_WHEN_FDF_FILE_HAS_COMPILE_ERROR		*
 *	Jack 12/19/2008 QA80-12329 MULTI_INDEP_DEPS_BAND_CALCULATION				*
 *	Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT				*
 *	Hong 12/24/08 QA80-10499 v8.0990c DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
 *	Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION		*
 *	Hong 12/30/08 QA80-12878 v8.0992 FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
 *	Sophy 1/12/2009 v8.0995c QA80-12613-P3 FIX_NLFIT_SHOW_WRONG_CUSTOMIZED_Y_MIN_MAX_ON_SURFACEFIT
 *	Sophy 1/12/2009 v8.0995c QA80-12613-P4 SHOULD_ONLY_SHOW_UNIFORM_LINEAR_ON_DATATYPE_FOR_3D_FITTING
 *	Folger 01/14/09 QA80-12955 FAIL_TO_OUTPUT_INVALID_SYNTAX_OF_CONSTRAINT_ERROR_MESSAGE
 *	Kyle 01/15/2009 SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE				*
 *	Sophy 1/19/2009 v8.0960 FIX_USE_SAME_WEIGHT_METHOD_FOR_ALL_DATASETS			*
 *	Kyle 01/20/2009 QA80-12955-P2 MAKE_OUTPUT_MESSAGE_FOR_CONSTRAINT_ERROR_SIMPLIFIED
 *	Hong 01/23/09 MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU				*
 *	Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
 *	Folger 02/09/09 QA80-13085 MORE_CLEAR_WAY_TO_INDICATE_MISSING_PARAMETERS_INSTEAD_OF_DISABLE_ITERATION
 *	Kyle 02/11/2009 QA80-12955-P3 HIDE_MESSAGE_WHICH_IS_USELESS					*
 *	Folger 02/11/09 QA80-13098-S2 SHOW_CHISQR_INFO_IN_NLFIT_STATIC_MESSAGE		*
 *	Folger 03/09/09 PROPER_HANDLE_OF_MAX_NUM_ITERATE_IN_FIT_PARAM_DIALOG		*
 *	Hong 03/11/09 FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO		*
 *	Folger 04/03/09 QA80-13408 SUPPORT_GET_COLUMN_NUMERIC_VALUES_WITH_FULL_PRECISION_FROM_NLPARAM_MANAGER
 *  Iris 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5						*
 *	Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5						*
 *	Hong 05/06/09 OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE							*
 *	Folger 05/12/09 NANOSIZER_FITTING_BASED_SUPPORT								*
 *	Hong 06/01/09 IMPROVE_DEFAULT_VALUE											*
 *	Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION					*
 *	Folger 06/18/09 CENTRALIZE_CODE_ABOUT_GETTING_PEAK_FUNC_PARAM_INDICES		*
 *  Will 06/24/2009 QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION	*
 *	Sim 09-25-2009 QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION	*
 *	Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
 *	Sophy 7/1/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION					*
 *	Jasmine 07/02/09 PA_AND_NANOSIZER_NEED_UPDATE_DATA_TYPE						* 
 *	Jasmine 07/02/09 QA80-12613-P4 X_Y_ARE_INDEPEND_DATA_IN_3D_FITTING			*
 *	Hong 07/03/09 QA80-13590-P5 NO_RESET_FIT_COUNT_MSG_IF_VALUE_NOT_REALLY_CHANGED
 *	Hong 06/07/09 QA80-13873 FIX_CONCATENATE_FIT_WEIGHT_METHOD_IN_REPORT_NOT_CORRECT_EXCEPT_FIRST_DATASET
 *	Sophy 7/8/2009 v8.1060 CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH			*
 *	Hong 10/07/09 QA80-13922 FIX_SHARED_SETTING_IS_APPLIED_EVEN_NOT_SUPPORT_SHARING
 *	Sophy 7/13/2009 v8.1063 HIDE_LOG_DATATYPE_ON_3D_FITTING_FOR_NOT_SUPPORTED	*
 *	Folger 07/16/09 NANOSIZER_FAILS_TO_REPORT_PARAMETER_BOUNDS_FROM_2ND_PEAK	*
 *	Folger 07/28/09 QA80-14021 PREIVEW_UPDATE_IN_MATRIX_FIT_AND_SURFACE_FIT_MUCH_SLOWER_THAN_SR5
 *	Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS					*
 *	Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT				*
 *	Hong 09/14/09 FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
 *	Folger 09/18/09 QA80-14333 RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF
 *  Iris 11/03/2009 QA81-14576 SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE	*
 *  Iris 11/03/2009 QA81-14576 OUTPUT_FIT_NOT_CONVERGED_INFO_TO_SCRIPT_WND		*
 *  Iris 11/03/2009 QA81-14576-P1 ADD_SUMMARY_FIT_RESULT_FOR_SEP_FIT_WITH_MULTI_DATASET
 *  Iris 11/11/2009 QA81-14576-P4 KEEP_CHI_AND_R_VALUE_IN_PARAM_FOOTNOTE		*
 *	Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
 *	Hong 01/04/10 QA80-14907 FITTING_VARIABLE_BETTER_SCOPE						*
 *	Hong 01/04/10 QA80-14907 TAG_FITTING_VARIABLE_AND_REMOVE_THOSE_CREATED_BY_LAST_FITTING
 *	Hong 01/12/10 QA80-13590-P7 ALWAYS_ACTIVE_MSG_TAB_IF_SIGNIFICANT_MSG		*
 *	Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
 *	Hong 01/25/10 QA80-15026 NLFIT_USE_EMPTY_FUNC_WHEN_SWITCH_CATEGORY			*
 *	Hong 01/12/10 QA80-14948-P2 FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT	*
 *	Hong 03/02/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
 *	Hong 04/08/10 QA80-15283 ITERATE_REACH_MAX_NO_GOOD_FIT_OUTCOME				*
 *	Folger 04/13/10 QA81-15297-P3 SHOW_LINEAR_CONSTRAINT_INFO_IN_FOOTNOTE		*
 *	Hong 03/13/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
 *	Jasmine 05/24/10 SRVC-12 ALLOW_SAME_AS_INPUT_FOR_ALL_SURFACE_FIT			*
 *	Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA				*
 *	Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
 *	Folger 08/06/10 ORG-733 FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
 *	Folger 08/12/10 ORG-733-P2 UPDATE_FIT_BUTTONS_AFTER_EDIT_FROM_WIZARD		*
 *	Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL	*
 *	Folger 08/17/10 ORG-824-P1 WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING		*
 *	Folger 08/25/10 ORG-897-P2 FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
 *------------------------------------------------------------------------------*/
#pragma PCH 

#ifndef	_NLF_SESSION_H_
#define	_NLF_SESSION_H_

///--- MACRO for debug
#ifdef _DEBUG
//#define		NLF_DEBUG
#endif
///----


///----- NLF_81 CP
#include <oc_debug.h>

#include	<ONLSF.h>
#include 	<Array.h>
#include	<xfutils.h>
#include	<..\originlab\NLFitFunction.h>
#include 	<..\originlab\NumFunctionOrganizer.h>
#include 	<NLParams.h>

#include <ocu.h> // Hong, to do

#include "NLFData.h"
#include "NLFitSelFunction.h"
#include "NLFCurves.h" /// Iris NLF_81, to do, NLFCurvesBase will be moved to FitNL
#include "curve_utils.h" /// Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION

#define	NLFIT_AREA_PARAMETER_CALCULATION_FACTOR		sqrt(PI/(4*ln(2)))

#define LARGE_DATA_SET_NUM_ROWS							240
#define LARGE_DATA_SET_NUM_COLS							420
#define LARGE_DATA_SET_ROW_SHRINK_FACTOR				6
#define LARGE_DATA_SET_COL_SHRINK_FACTOR				8

///--- Hong 10/09/08, copy from old nlfitsession.h
//vc level defined it, but here not access it, so redifine
#define		IDS_ENABLE_INIT_PARAMS				23569
///Cheney 2007-6-6 SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT	
#define		IDS_CONTROL_CONSTRAINTS				23541
///end SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT
///Cheney 2007-6-8 WHNE_SAVE_AUTO_INIT_SHOULD_ALSO_SAVE_COMPILE_BIT
#define IDS_PARAM_CHANGE_SCRIPTS				23568
///end WHNE_SAVE_AUTO_INIT_SHOULD_ALSO_SAVE_COMPILE_BIT
///end DO_SAVE_FDF
///---
#define STR_FOOTNOTE_COLOR_FORMAT_PREFIX		"\\p120(\\c4("
#define STR_FOOTNOTE_COLOR_FORMAT_POSTFIX		"))"
/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
enum PARAMS_SETTING_TYPE
{
	PARMAS_SETTING_SHARE 		= NLPARAMGRIDCOLTYPE_SHARE,
	PARMAS_SETTING_PEAK_TYPE 	= NLPARAMGRIDCOLTYPE_PEAK_NO,	///Jasmine 04/16/08 MODEL_SHOW_MULTI_FUNCS_OR_FITFUNC_IF_ONLY_ONE_IN_FITPEAK
	PARMAS_SETTING_FIXED 		= NLPARAMGRIDCOLTYPE_FIXED,	
	PARMAS_SETTING_LOWERBOUNDS 	= NLPARAMGRIDCOLTYPE_LB,
	PARMAS_SETTING_UPPERBOUNDS 	= NLPARAMGRIDCOLTYPE_UB,	
	PARMAS_SETTING_VALUES		= NLPARAMGRIDCOLTYPE_VALUE,
	PARMAS_SETTING_NAMES		= NLPARAMGRIDCOLTYPE_NAME,
	PARMAS_SETTING_UNIT		= NLPARAMGRIDCOLTYPE_UNIT,			///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	PARMAS_SETTING_MEANINGS		= NLPARAMGRIDCOLTYPE_MEANING,
	PARMAS_SETTING_SIGN_DIGITES	= NLPARAMGRIDCOLTYPE_SD,	///Jasmine 10/17/07 MISSING_SIGN_DIGITES	
	PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE = NLPARAMGRIDCOLTYPE_TOTAL,
	PARMAS_SETTING_LOWERBOUNDSENABLE,
	PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE,
	PARMAS_SETTING_UPPERBOUNDSENABLE,
};
/// end FITNL_USING_NEW_NLFSESSION

//----- CPY 10/30/07 JASMINE_FOUND_PFM_NEED_SEPARATE_PREVIEW
//	bool 	SetFitPreviewGraph(GraphPage& gpPreview, int nType);
enum {
	PREVIEW_RESIDUAL,
	
	PREVIEW_DATA_FIT,	
	PREVIEW_EXTERNAL_DATA_FIT,
	PREIVEW_2ND_DE,///Sophy 9/26/2008 NEW_PA_ADD_ADVANCE_PREVIEW_GRAPH_SUPPORT
};
//-----

///Cheney 2007-6-14 SHOULD_RESET_SHARE_VAL_WHEN_MODE_CHANGE_FROM_GLOBAL_TO_OTHERS
enum{
	SHARE_SETTING_MODE_NOT_CHANGE					=	0,
	SHARE_SETTING_MODE_RESET_ALL,					//reset current setting and back up setting
	SHARE_SETTING_MODE_BACK_UP_AND_RESET_CURRENT,   //back up current setting, then reset
	SHARE_SETTING_MODE_RESTORE,   					//copy old setting from back up vector
};
///end SHOULD_RESET_SHARE_VAL_WHEN_MODE_CHANGE_FROM_GLOBAL_TO_OTHERS

enum NLFIT_COPY_GUI_SETTING
{
	NLFIT_COPY_GUI_SETTING_PARAMS = 0x00000001,
	NLFIT_COPY_GUI_SETTING_BOUND = 0x00000002,
};

enum NLFIT_ONPARAMCHANGE
{
	NLFIT_ONPARAMCHANGE_UPDATE_DATA	= 0x0001,
	NLFIT_ONPARAMCHANGE_PREPARE_WKS	= 0x0002,
};

enum NLFIT_INIT_PARMAS
{
	NLFIT_INIT_PARMAS_AUTO			= 0x0001,
	NLFIT_INIT_PARMAS_LOAD_FDF		= 0x0002,
};

//------ Folger 10/15/08 MOVE_COMPUTE_CONFIDENCE_LIMITS_METHODS_INTO_VC
/*
enum
{
	CONF_LIMIT_METHOD_AS_BASED = 0,
	CONF_LIMIT_METHOD_MODLE_COMP_BASED,
	CONF_LIMIT_METHOD_COUNT
};
*/
//------ End MOVE_COMPUTE_CONFIDENCE_LIMITS_METHODS_INTO_VC

/// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
#define 	STR_ATTRIB_OLD_DATA_MODE	"OldFitDataMode"
#define		INVALID_DATA_MODE			-1 // maybe better add into enum DATA_MODE_* in analysis_utils.h
/// end DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION

#define		STR_FDF_SETTING_UNIT				"Unit"				///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
#define		STR_FDF_SETTING_MEANINGS			"Meanings"
#define		STR_FDF_SETTING_INIT_VAL			"InitialValues"
#define		STR_FDF_SETTING_SIGNIFICANT_DIGITS	"Number Of Significant Digits"
#define		STR_FDF_SETTING_LOWER_BOUNDS		"LowerBounds"
#define		STR_FDF_SETTING_UPPER_BOUNDS		"UpperBounds"


#define 	STR_MSG_ON_SET_DATA						"OnSetData"
#define 	STR_MSG_ON_SET_FUNC						"OnSetFunction" 
#define		STR_ON_PARAM_INIT						"On Param Init"
#define 	STR_MSG_ON_NUM_REPLICA_CHANGE			"OnNumReplicaChange"
#define 	STR_MSG_ON_FINDING_PEAK_ARG_CHANGE		"OnFindingPeakArgChange"

#define		STR_AUTO_INIT_PARAMS					"AutoInitParams"
#define		AUTO_INIT_PARAMS								1

///Jasmine 08/28/09 CENTRALIZE_FIND_PEAK_METHOD_COMBO
//#define		STR_NLFIT_LIST_REPLICA_FINDING_PEAK_METHODS			_L("Local Maximum|Window Search|1st Derivative|2nd Derivative (search Hidden peaks)|Residual after 1st Derivative (search Hidden peaks)")
///End CENTRALIZE_FIND_PEAK_METHOD_COMBO
#define		STR_SURFACEFIT_LIST_REPLICA_FINDING_PEAK_METHODS	_L("Local Maximum|1st Partial Derivative|Contour Consolidation")

/// Max 06/10/08 v8.0881 CENTRALIZE_TIP_STRINGS_FOR_BUTTONS_IN_NLFIT_AND_PA
///Sophy 6/2/2010 ORG-2 NEW_FIT_FUNCTION_WIZARD_IN_NLFIT_DLG
//#define STR_TIP_EDIT_FITTING_FUNCTIONS		_L("Create/Edit Fitting Functions")
#define STR_TIP_EDIT_FITTING_FUNCTIONS		_L("Edit Fitting Function")
#define	STR_TIP_NEW_FITTING_FUNCTIONS		_L("Create New Fitting Function")
///end NEW_FIT_FUNCTION_WIZARD_IN_NLFIT_DLG
#define STR_TIP_SAVE_FDF_FILE				_L("Save FDF File")
#define STR_TIP_FIT_UNTIL_CONVERGED			_L("Fit until converged")
#define STR_TIP_INITIALIZE_PARAM			_L("Initialize Parameters")
#define STR_TIP_ONE_ITERATION				_L("1 Iteration")
#define STR_TIP_CALCULATE_CHI_SQUARE		_L("Calculate Chi-Square")
#define STR_TIP_SIMPLEX						_L("Simplex")

#define STR_TIP_LOAD_PARAM_SETTINGS			_L("Load Parameter Settings")
#define STR_TIP_FIX_RELEASE_BASELINE_PARAM	_L("Fix or release baseline parameters")

///Sandy 2008-7-10 clean-up PA GUI poor English as Deanna Suggested
//#define STR_TIP_FIX_RELEASE_PEAKS_CENTER	_L("Fix or release peaks center")
//#define STR_TIP_FIX_RELEASE_PEAKS_WIDTH		_L("Fix or release peaks width")
#define STR_TIP_FIX_RELEASE_PEAKS_CENTER	_L("Fix or release all peak centers")
#define STR_TIP_FIX_RELEASE_PEAKS_WIDTH		_L("Fix or release all peak widths")

#define STR_TIP_SHARE_UNSHARE_WIDTH			_L("Share or unshare width")
/// END CENTRALIZE_TIP_STRINGS_FOR_BUTTONS_IN_NLFIT_AND_PA

#define		STR_ITERATION_PERFORMED			_L("Iterations Performed")

#define NLSF_3D_FITTING_GRAPH_TEMPLATE 		"XYZ2MAT3D"
#define NLSF_XYZ_3D_FITTING_GRAPH_TEMPLATE "TRICONTOUR"
#define NLSF_MAT_3D_FITTING_GRAPH_TEMPLATE "CONTOUR"

enum {
	OSD_NO_PARAM_UPDATE = 		0x1000,
	OSD_NO_PARAM_INIT = 		0x2000,
	OSD_FROM_PARAM_REPLICA_NUM_CHANGE = 0x4000, /// Iris 2/09/06 QA70-8461 v8.0365 INCLUDE_RPLICA_FOR_FITTING
	OSD_FROM_FUNC_CHANGE =		0x0100,
	OSD_FROM_EDIT_PARAM_CHANGE =0x0200,
	OSD_FROM_CLEANUP	=		0x0400,
	OSD_FROM_DATA_CHANGE =  	0x0800,
	OSD_FROM_X_DATA_TYPE_CHANGE=0x0010,  /// Iris 07/03/06 UPDATED_X_DATA_TYPE_FIT_BUTTON_MUST_ENABLE
	///Arvin 07/03/07 v8.0654 IMPROVE_MESSAGE_SHOWN as max's suggestion
	OSD_DATA_CHANGE_NOT_UPDATE_PREVIEW	 = 0x0020,
	OSD_FUNC_CHANGE_THEN_SET_DATA		 = 0x0040,
	///end IMPROVE_MESSAGE_SHOWN
	OSD_THEME_CHANGE_FACTORY_DEFAULT	= 0x0080,	 ///Cheney 2007-7-23 QA80-10090 MODIFY_STH_ABOUT_FDF_SAVING_AND_THEME_APPLY
	OSD_FINDING_PEAK_ARG_CHANGE			= 0x0001,    ///Arvin 04/03/08 QA70-11348 AUTO_PREVIEW_CHANGED_TO_AUTO_UPDATE_CLEANUP
	OSD_DATA_CHANGE_BY_FIT_MODE			= 0x0002,	//------ Folger 07/11/08 FIX_PARAMETER_INITIALIZATION_FAIL_FOR_FIT_MODE_CHANGE
};

#define OSD_FROM_CHANGE_MASK	0x4FF0

//Arvin 04/02/08 QA70-11348 AUTO_PREVIEW_CHANGED_TO_AUTO_UPDATE_CLEANUP
enum tagAutoUpdate
{
	AUTO_UPDATE_INPUT_DATA_CHANGE		= 0x0001,
	AUTO_UPDATE_FUNC_CHANGE				= 0x0002,
	AUTO_UPDATE_NUM_REPLICA_CHANGE		= 0x0004,
	AUTO_UPDATE_FINDING_PEAK_ARG_CHANGE	= 0x0008,
};

enum
{
	NLF_FUNC_CHANGE 		= 0x00000001,
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//NLF_THEME_CHANGE 		= 0x00000002,
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	NLF_RESET_SHARE_FIX		= 0x00000004,
	NLF_KEEP_OLD_DATASET	= 0x00000008,
};


enum PARAMS_VALID_STATE
{
	PARAMS_VALID_ALL,
	PARAMS_VALID_NONE,
	PARAMS_VALID_PART,
};

enum
{
	COL_CONCATENATE_X = 0,
	COL_CONCATENATE_Y,
	COL_AVE_X,
	COL_AVE_Y,
	COL_AVE_YERR,
	COL_CONCATENATE_COUNT
};

//------- CPY 3/4/08 QA-11206 XYZ_PREVIEW_NOT_SHOWING
#ifdef _DEBUG_FIT
	#define NLFIT_PREVIEW_NOCLICK_BITS 	 0
#else
	///Jasmine 08/13/2010 ORG-172-S2 CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
	//#define NLFIT_PREVIEW_NOCLICK_BITS 	(NOCLICK_DATA_PLOT | NOCLICK_TICKLABEL | NOCLICK_LAYER | NOCLICK_LAYERICON)
	#define NLFIT_PREVIEW_NOCLICK_BITS 	(OC_TOOL_NOCLICK | NOCLICK_ZOOMPAN)
	///End CENTRALIZE_NOCLICK_BIT_FOR_PREVIEW_IN_OC_TOOL
#endif
//-------
///----- end NLF_81 CP

#ifndef FITITER_GET_CHISQR
	#define FITITER_GET_CHISQR									50 
	#define FITITER_MAX_ITER_REACHED							-200
	#define FITITER_FAILED_TO_REDUCE_CHISQR_DUE_TO_POOR_DATA	-201 
	#define FITITER_FAILED_TO_REDUCE_CHISQR_NO_ITERATION		-202 
	#define FITITER_FAILED_MUTUAL_DEPEND						-203 
	#define	FITITER_FAILED_ZERO_ERROR_NOT_CONSISTENT			-204 
	#define	FITITER_FAILED_ZERO_YVALUE_NOT_CONSISTENT			-205 
	#define	FITITER_VALUE_NOT_CONSISTENT_WITH_WEIGHTING_METHOD	-206 
	#define FITITER_FAILED_OTHER_REASONS						-207
	/// ML 7/19/2007 ONLSF8_ERROR_CODES_FOR_NEGATIVE_ERRORS_WEIGHTS
	#define FITITER_FAILED_NEGATIVE_ERROR_VALUE_FOR_WEIGHT		-208
	#define FITITER_FAILED_NEGATIVE_WEIGHT						-209
	/// end ONLSF8_ERROR_CODES_FOR_NEGATIVE_ERRORS_WEIGHTS  
	#define FITITER_NO_ITERATE									-1	 ///Cheney 2007-8-7 IF_FIT_CONVERGE_SHOW_OK_BUTTON_OTHERWISE_FIT_BUTTON
	#define FITITER_FIT_NOT_COMPLETE							-1000	 /// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
#endif	//FITITER_GET_CHISQR


#define STR_FIT_OUTCOME_ATTRIB "FitOutCome"
#define STR_ATTRIB_FIT_TYPE "NLfitType"

#define	STR_QUICK_FIT_ATTRIB	"NLFitQuickFit" /// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME

//---- CPY 3/25/08 REPLACE_HARD_CODED_FIXED_ITER_COUNT 
// Arvin's was usng hardcoded 10 in many places so I have fixed by define below
#define FIXED_CENTER_ITER_COUNT		20//10	///Jasmine 03/28/08 CP said, some small peaks got lost very quickly even though init positions are good
//---- end REPLACE_HARD_CODED_FIXED_ITER_COUNT

/// Iris 9/22/2008 NEW_PA
enum
{
	ACCESS_NO_VALUE = 0,
	ACCESS_X_VALUE,
	ACCESS_Y_VALUE,
	ACCESS_BOTH_VALUE,
};

//#define		HasBaselinePeak		GetBaselineFitMode // to following old pa function name in SR3 version		///Kyle 10/21/08 CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE
///end NEW_PA

//------ Folger 04/22/08 CLEAN_UP_MEMORY_ALLOCATION_IN_FIT_SESSION
class PointerManager  ///Sophy This class is suggested to be moved to a more general place
{
public:
	PointerManager(void **pv, int nSize)
	{
		m_pv = malloc(nSize);
		*pv = m_pv;
	}
	
	~PointerManager()
	{
		free(m_pv);
	}
	
private:
	void *m_pv;
};
//------ End CLEAN_UP_MEMORY_ALLOCATION_IN_FIT_SESSION

/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
class ResetDataObjHelper
{
public:	
	ResetDataObjHelper(NLFDataBase* pDataObj, int* pBackupOldNumDataset, bool bHasReset = false)
	{		
		ASSERT( pDataObj && pBackupOldNumDataset );
		m_pDataObj = pDataObj;
		m_pBackupOldNumDataset = pBackupOldNumDataset;
		m_bHasReset = bHasReset;
		m_bFunctionReady = true; /// Hong 12/30/08 QA80-12878 v8.0992 FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
	}	
	~ResetDataObjHelper()
	{
		*m_pBackupOldNumDataset = -1;
		if ( !m_bHasReset )
		{
			if ( m_bFunctionReady ) /// Hong 12/30/08 QA80-12878 v8.0992 FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
				*m_pBackupOldNumDataset = m_pDataObj->GetNumDataset();
			m_pDataObj->Reset();
		}
	}
	void			SetHasReset(bool bHasReset = true)
	{
		m_bHasReset = bHasReset;
	}
	/// Hong 12/30/08 QA80-12878 v8.0992 FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
	void			SetFunctionNotReady()
	{
		m_bFunctionReady = false;
	}
	/// end FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
private:
	bool					m_bFunctionReady; /// Hong 12/30/08 QA80-12878 v8.0992 FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
	NLFDataBase*			m_pDataObj;
	int*					m_pBackupOldNumDataset;
	bool					m_bHasReset;
};
/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE


/**#
	Hong, to do
	This class seem will be hard to handle multiple function case, as multiple function depend on Peaks Tree which is totally different, we need to think out a solution for it,
	otherwise it may event fail to work with Parameter Manager as duplicate knowledge and will be hard to maintain
*/
class NLFitSession
{
public:	
	NLFitSession(bool bSingleFunction = true);
	~NLFitSession();
	
public:
	/// Hong 05/06/09 OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
	void			SetIs2DSupportReplica(bool bSet);
	bool			Is2DSupportReplica();
	/// end OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
	
	///------ Folger 05/12/09 NANOSIZER_FITTING_BASED_SUPPORT
	void			SetInitFromNanosizer(bool bOn = true)		{ m_bInitFromNanosizer = bOn; }
	bool			IsInitFromNanosizer()						{ return m_bInitFromNanosizer; }
	///------ End NANOSIZER_FITTING_BASED_SUPPORT
	
	bool 			SetDisableUpdate(bool bDisable = true);	
	//
	bool			InitFromOperationTree(TreeNode& trOp, bool& bHasFitGood, bool& bParamsReady = NULL, bool bDoFitAnyWay = false, DWORD dwInitParams = 0, bool bInitData = false, bool bLoadFDF = true);
	
	OperationLogBase*	InitMsgLog(OperationLogBase* pOpMsgLog = NULL);
	void			UnlinkMsgLog() { m_pOpMsgLog = NULL; }
	
	/// Hong 09/10/08 v8.0936b PARAMETER_MODIFIED_BY_GRID
	//void			SetParametersNeedUpdate();
	/// end PARAMETER_MODIFIED_BY_GRID
	
	// Function relative
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//bool			SetFunction(const TreeNode& trFitFunc, int nMultiplicity = 1, bool bResetFunc = true, int* pnSharing = NULL, int nNumSharing = 0, LPCSTR lpcszFuncName = NULL, LPCSTR lpcszCateName = NULL, 
								//int nFunc = 0, TreeNode& trInput = NULL, DWORD dwSelFuncByTheme = 0);
	//virtual bool	SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName = NULL, int nMultiplicity = 1, bool bResetFunc = true, int* pnSharing = NULL, int nCountSharing = 0, 
								//TreeNode& trInput = NULL, DWORD dwSelFuncByTheme = 0, bool bLoadFDF = true);
	/// Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
	//bool			SetFunction(const TreeNode& trFitFunc, int nMultiplicity = 1, bool bResetFunc = true, int* pnSharing = NULL, int nNumSharing = 0, LPCSTR lpcszFuncName = NULL, LPCSTR lpcszCateName = NULL, 
								//int nFunc = 0, TreeNode& trInput = NULL);
	//virtual bool	SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName = NULL, int nMultiplicity = 1, bool bResetFunc = true, int* pnSharing = NULL, int nCountSharing = 0, 
								//TreeNode& trInput = NULL, bool bLoadFDF = true);
	///Kyle 01/15/2009 SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
	//bool			SetFunction(const TreeNode& trFitFunc, int nMultiplicity = 1, bool bResetFunc = true, LPCSTR lpcszFuncName = NULL, LPCSTR lpcszCateName = NULL, int nFunc = 0, TreeNode& trInput = NULL);
	bool			SetFunction(const TreeNode& trFitFunc, int nMultiplicity = 1, bool bResetFunc = true, LPCSTR lpcszFuncName = NULL, LPCSTR lpcszCateName = NULL, int nFunc = 0, TreeNode& trInput = NULL, int * pnErrorCode = NULL);
	///End SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
	///------ Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	//virtual bool	SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName = NULL, int nMultiplicity = 1, bool bResetFunc = true, TreeNode& trInput = NULL, bool bLoadFDF = true, int nFunc = 0);
	virtual bool	SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName = NULL, int nMultiplicity = 1, bool bResetFunc = true, TreeNode& trInput = NULL, bool bLoadFDF = true, int nFunc = 0, int * pnErrCode = NULL);
	///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	/// end SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
		
	int 			GetNumberFitFunctions()	{ return m_pParamMngr->GetNumFitFunctions(); }
	///------ Folger 08/12/10 ORG-733-P2 UPDATE_FIT_BUTTONS_AFTER_EDIT_FROM_WIZARD
	//bool			IsFunctionReady(int nFunc = 0);	
	bool			IsFunctionReady(int nFunc = 0, BOOL bCheckFDFTreeOnly = FALSE);	
	///------ End UPDATE_FIT_BUTTONS_AFTER_EDIT_FROM_WIZARD
	///Sophy 10/10/2008 CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
	//TreeNode		GetTreeFDF(int nFunc = 0);
	TreeNode		GetTreeFDF(int nFunc = 0, bool bGetFilePathInfo = false );
	///end CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
	TreeNode 		GetTreeFDFModified(int nFunc = 0, bool bGetFilePathInfo = false );				///Kyle 11/05/2008 TO_GET_FDF_TREE_AFTER_MODIFIED
	void			SetTreeFDF(const TreeNode& trFDF, int nFunc = 0);
	string			GetFunctionName(string* pCategoryName = NULL, int nFunc = 0);
	///Sophy 10/10/2008 CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
	//string			GetFunctionFileName(int nFunc = 0) { return m_NFO.GetFuncFileName(GetTreeFDF(nFunc), true); }	
	string			GetFunctionFileName(int nFunc = 0) { return m_NFO.GetFuncFileName(GetTreeFDF(nFunc, true), true); }	
	///end CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS	
	string			GetFunctionDescription(int nFunc = 0); /// Hong 23/05/08 v8.0869 ADD_FIT_FUNC_FILENAME_AND_DESCRIPTION
	
	int				SetFunctionList(const TreeNode& trFunctionList);
	bool			IsMixedFunction(const TreeNode& trFuncSel = NULL) { return false; } // Hong, to do, this mechanism seems is discarded
	
	// Data relative
	NLFDataBase*	GetDataObject() { ASSERT(m_pDataObj); return m_pDataObj; }
	DWORD			GetDataRules();	
	/// Hong 10/16/08 v8.0956 FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
	//bool			SetData(TreeNode& trInputData, const TreeNode& trWTMethods = NULL, DWORD dwCntrlOnSetData = 0, DWORD dwUpdateFromTheme = 0);
	/**$
		Parameters:
			bUpdateDataOnly = [input] should only be true when trInputData is only different in plot GUIs, no data difference.
	*/
	bool			SetData(TreeNode& trInputData, const TreeNode& trWTMethods = NULL, DWORD dwCntrlOnSetData = 0, DWORD dwUpdateFromTheme = 0, bool bUpdateDataOnly = false);
	/// end FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
	/// Hong 11/04/08 QA80-12526 v8.0965b ADD_BACKWARD_COMPATIABLE
	///Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	//bool			SetData(const vector& vY, const vector& vX, const vector& vZ = NULL, int nIndex = 0, int nNumTotalDataset = 1);
#ifndef	EXTEND_INTERFACES_OF_NLFITSESSION
	bool			SetData(const vector& vY, const vector& vX, const vector& vZ = NULL, int nIndex = 0, int nNumTotalDataset = 1);
#else
	bool			SetData(const vector& vY, const vector& vX, const vector& vZ = NULL, int nIndex = 0, int nNumTotalDataset = 1, int nDataMode = INVALID_DATA_MODE, const vector& vW = NULL);
#endif	//EXTEND_INTERFACES_OF_NLFITSESSION
	///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	
	//Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
#ifdef	EXTEND_INTERFACES_OF_NLFITSESSION
	bool			SetWeightData(int nWTMethod, double dWTa, double dWTb, double dWTc, int nDataIndex = 0) { return m_pDataObj->SetWeightData(nWTMethod, dWTa, dWTb, dWTc, nDataIndex); }
#endif	//EXTEND_INTERFACES_OF_NLFITSESSION
	///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	/// end ADD_BACKWARD_COMPATIABLE
	bool			GetNumVars(int *pnDeps, int *pnIndeps, StringArray *pvstrDepVarNames = NULL, StringArray *pvstrIndepVarNames = NULL);
	bool			SetInitData(BOOL bSet);
	bool			GetOneWeight(int nIndex, int iDep, int& nMethod, double& rA, double& rB, double& rC);

	///Sophy 9/16/2008 CLEAN_NLFSPLITTER_FOR_81
	bool			GetSrcXMinMax(double& dxMin, double& dxMax );
	bool			GetSrcYMinMax(double& dyMin, double& dyMax );
	void 			UpdateXDataMinMaxByAuto(TreeNode& trXDataType);
	void 			UpdateYDataMinMaxByAuto(TreeNode& trYDataType);	
	///Jasmine 07/02/09 PA_AND_NANOSIZER_NEED_UPDATE_DATA_TYPE
	void 			UpdateDataTypeBranch(TreeNode& trGraph1, const TreeNode& trData, bool bChangeParams);
	///End PA_AND_NANOSIZER_NEED_UPDATE_DATA_TYPE
	///End CLEAN_NLFSPLITTER_FOR_81
	
	/**$
	Parameter:
		vz = [input] vector to retrieve value of Z axis for 2D input data. Notive: for 1D input data, it should be NULL, for 2D, it must be specified.
		pvWeights = [input] only available for 1D input data.
	*/
	bool			GetInputData(vector& vx, vector& vy, vector& vz = NULL, int nDatasetIndex = 0, vector* pvWeights = NULL);
	bool			GetInputData(matrix& mXs, matrix& mYs, int nDataIndex = 0);
	bool			GetInputData(vector& vData, bool bDep, int nDatasetIndex, int nIndex = 0);///Sophy 10/24/2008 SUPPORT_MUILTI_INDEP_AND_DEP_PREVIEW_FOR_NLFIT_81
	///Sophy 10/13/2008 QA80-12365 FIX_FAIL_TO_REPORT_RESIDUAL_IN_MATRIX_FIT moved to NLFCurves.h
	//bool			GetMatResidualData(matrix& matResidual, int& nRows, int& nCols, double& dXmin, double& dYmin, double& dXmax, double& dYmax);
	///end FIX_FAIL_TO_REPORT_RESIDUAL_IN_MATRIX_FIT
	DataRange		GetSrcDataRange() {return m_drSrcData;}
	bool			GetSrcSubDataRange(DataRange& drSub, int nDatasetIndex = 0, int iDep = 0, int iIndep = 0);
	int				GetNumDataset() { return m_pDataObj->GetNumDataset(); }
	
	void			SetAveType(int nType);
	DWORD			GetSrcPlotUIDConcatenate() {return m_dwSrcPlotUIDConcatenate;}

	// Curve an plot relative	
	DWORD			GetSourcePlotUID(int index);
	/// Iris NLF_81, moved IsAllSrcDataFromGraph and SetIsAllSrcDataFromGraph to NLFDataObject 
	//bool			IsAllSrcDataFromGraph() { return m_bAllSrcFromGraph; }
	//void			SetIsAllSrcDataFromGraph(bool bSrcDataFromGraph) { m_bAllSrcFromGraph = bSrcDataFromGraph; }
	///end NLF_81
	void			SetSourcePlotUID(int index, DWORD dwPlotUID); /// Iris 11/01/2008 v8.0964 NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE
	
	GraphPage   	GetSrcGraphPage();		
	bool 			UpdateResidualContourLevels(GraphLayer& gl = NULL);
	//void			SetFitCurveOptions(TreeNode& trCurveOptions);  /// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
	
	bool			IsReadyIterations(bool *pbChiSqrReady = NULL);
	
	
	
	
	// iterate/fit relative
	/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	//int				Iterate(int nMaxNumIterations, int nMethod = FITMETH_LEVENBERG_MARQUARDT, bool bAllowCancel = false, int* lpnActualInterateCount = NULL, int* lpnIterateOutCome = NULL, DWORD *pdwNLDlgUpdate = NULL);	
	//------ Folger 12/10/08 QA80-12751 v8.0984d SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
	//int				Iterate(int nMaxNumIterations, int nMethod = FITMETH_LEVENBERG_MARQUARDT, bool bAllowCancel = false, int* lpnActualInterateCount = NULL, int* lpnIterateOutCome = NULL);
	int				Iterate(int nMaxNumIterations, int nMethod = FITMETH_LEVENBERG_MARQUARDT, bool bAllowCancel = false, int* lpnActualInterateCount = NULL, int* lpnIterateOutCome = NULL, DWORD dwOption = 0);
	//------ End SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
	/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	bool			Fit(int* pnOutcome = NULL, bool bCheckLastOutcome = false, bool bAllowCancel = false);
	bool 			SetIterationSettings(int nNumIterationsWithFixedCenters);
	bool 			SetDataSteps(const vector<int>& vDataSteps); // Hong, to do, if rename to SetFitDataSteps will be better?
	/// Hong, Jasmine 08/14/08 PEAKSMODE_MULTIFUNC_GLC
	//void 			SetMultipeakOptions(DWORD dwMultipeakOptions = PEAKSMODE_MULTIPEAK_CENTERS_HANDLING) { m_NLFit.MultipeakOptions = dwMultipeakOptions; }
	void 			SetMultipeakOptions(DWORD dwMultipeakOptions = PEAKSMODE_MULTIPEAK_CENTERS_HANDLING);
	/// end PEAKSMODE_MULTIFUNC_GLC
	
	/// Jack 31/10/08 QA80-12423 SET_PA_CONSTRAINTS_WHEN_IT_IS_MULTIPLE_FUNCS_FIT
	bool			isMultipleFuncsMultiPeaksFit();
	/// End SET_PA_CONSTRAINTS_WHEN_IT_IS_MULTIPLE_FUNCS_FIT
	bool 			SetEnableLinearConstraints(const TreeNode& trLinearConstraints, bool bConstraints = true);
	///Sophy 7/1/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	//lpcszLinearConstraints is NULL, will attempt to get script from FDF tree, bConstraints indicates whether to enable constraint script
	bool			SetEnableLinearConstraints(bool bConstraints = true, LPCSTR lpcszLinearConstraints = NULL);
	///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	void			SetMaxNumIter(UINT nMaxNumIter) { m_nMaxNumIter = nMaxNumIter; }		
	int				GetMaxNumIter()					{ return m_nMaxNumIter; }		///------ Folger 03/09/09 PROPER_HANDLE_OF_MAX_NUM_ITERATE_IN_FIT_PARAM_DIALOG

	int 			GetFitType() { return m_nFitType; }
	/// Hong, to do, this interface is wrong as it give the misleading that fit type can be change dynamic which is not supported indeed
	int				SetFitType(const TreeNode& trSpecInfo);

	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/*
	double			GetChiSqr();	
	int				GetNumberItersPerformed() { return m_nNumberItersPerformed; }	
	bool	  		GetShortFitOutCome(string& strOutCome);
	string			GetFitOutCome(int nIterationOutCome);
	string  		GetFitOutCome(bool bTrimDetails = true);
	void			ResetFitOutCome() { m_nLastIterateOutCome = FITITER_NO_ITERATE; }
	bool			IsFitConverged();
	*/
	//------ Folger 12/10/08 QA80-12751 v8.0984d SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
	//void			GetChiSqr(vector& vChiSqr = NULL);
	void			GetChiSqr(vector& vChiSqr = NULL, bool bGenerateOutputs = false);
	//------ End SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
	int				GetNumberItersPerformed(int nSetIndex = 0);
	bool	  		GetShortFitOutCome(string& strOutCome, int nSetIndex = 0);
	string			GetFitOutCome(int nIterationOutCome);
	string  		GetFitOutCome(bool bTrimDetails = true, int nSetIndex = 0);
	void			ResetFitOutCome();
	bool			IsFitConverged(); // Hong, to do, how to handle this?
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	void			SetScaleParamError(bool bVal = false) { m_bScaleParamErrors = bVal; }
	void 			SetTolerance(double dTol) { m_dTolerance = dTol; }
	void			SetIsGetParamsConf(const TreeNode& trParamControl, const TreeNode& trSummaryControl, const TreeNode trCIMethod);
	void 			SetDerivsSettings(const TreeNode& trDerivsDetal);
	
	/// Hong 06/01/09 IMPROVE_DEFAULT_VALUE
	// Hong, -1 for nSetIndex is misleading now, when bPreDataset is true, it's NOT used, so no need used -1 to indicate all sets
	//bool 			GetFitResultsStats(RegStats* pRegStats, NLSFFitInfo* pFitInfo, bool bPreDataset = false, int nSetIndex = -1, int nDepIndex = 0);
	bool 			GetFitResultsStats(RegStats* pRegStats, NLSFFitInfo* pFitInfo, bool bPreDataset = false, int nSetIndex = 0, int nDepIndex = 0);
	/// end IMPROVE_DEFAULT_VALUE
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//int				GetLastIterateOutCome(){return m_nLastIterateOutCome;}
	//string			GetFitMessage();
	int				GetLastIterateOutCome(int nSetIndex = 0);
	/// Iris 11/03/2009 QA81-14576-P1 ADD_SUMMARY_FIT_RESULT_FOR_SEP_FIT_WITH_MULTI_DATASET
	//string			GetFitMessage(int nSetIndex = 0);
	string			GetFitMessage(int nSetIndex = 0, int* pnSummaryOutType = NULL, bool bForFootnote = false);
	bool			IsLastFitOutComeGoodFit(int nLastFitOutCome);
	/// Hong 01/12/10 QA80-13590-P7 ALWAYS_ACTIVE_MSG_TAB_IF_SIGNIFICANT_MSG
	bool			IsIterateFailed(int nFitOutCome);
	/// end ALWAYS_ACTIVE_MSG_TAB_IF_SIGNIFICANT_MSG
	string			GetSummaryIterateOutCome(int* pnSummaryOutType = NULL, bool bForFootnote = false);
	///end ADD_SUMMARY_FIT_RESULT_FOR_SEP_FIT_WITH_MULTI_DATASET
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	/// Hong 09/24/09 QA80-12199 FIT_LT_CALL_SPEED_UP_MOVE_CODE_TO_VC
	void			GetParamValuesAndOffsets(vector& vParamValues, vector<int>& vnParamsOffsets);
	/**$
	Parameter:
		nn = [input] for multiple dataset, stand for dataset index,
					for single dataset, if negative, mean get cumulative fitted curves of all peaks, otherwise stand for peak index
	*/
	int				GetYFromX(const double *pX, double *pY, int nCount = 1, int nn = 0);
	/// end FIT_LT_CALL_SPEED_UP_MOVE_CODE_TO_VC

	/// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION, move calc fit result codes into NLFCurvesBase class
	/*
	bool			GetFitX(vector& vFitX, int nDatasetIndex = 0, bool bSetCustomInput = true); // get input x and custom it by FitResultCurveOptions if bSetCustomInput is true	
	bool 			GetFitY(const vector& vFitX, vector& vFitY, int nDatasetIndex, int nPeak = 0); // get fitted Y for normal XY fit
	bool			GetFit(vector& vFitX, vector& vFitY, int nDatasetIndex, int nPeak = 0, bool bSetCustomInput = true);  /// Iris NLF_81
	
	bool			GetFitX(matrix& mFitXs, int nDatasetIndex = 0, bool bSetCustomInput = true); // get input Xs for multiple Indep/Dep function
	bool 			GetFitY(const matrix& mFitXs, matrix& mFitYs, int nDatasetIndex = 0); // get fitted Ys for multiple Indep/Dep function
	
	bool 			GetFitXY(vector& vX, vector& vY, bool bSetCustomInput, bool bNeedGrid = false, int* pnRows = NULL, int* pnCols = NULL);
	bool			GetFitZ(const vector& vX, const vector& vY, vector& vZ, int nIndependent = 0);
	bool 			GetFitZ(vector& vX, vector& vY, matrix& matZ, int& nRows = NULL, int& nCols = NULL, int nIndependent = 0, bool bSetCustomInput = true); 
	
	bool			GetCumulativeData(vector& vCumulative, int nDatasetIndex = 0); /// Iris NLF_81
	bool			GetResidualData(vector& vResidual, int index = 0, vector& vInX = NULL, vector& vInY = NULL, vector& vInZ = NULL, vector& vFitZ = NULL); ///Arvin 03/03/08 QA-11206 CLEAN_PREVIEW_CTRL_CLASSES
	*/
	///end NLF_81
	
	bool 			GetDifferentTypeResidualDatas(const TreeNode& trOp, const vector& vx, const vector& vRegular, vector& vStad, vector& vStud, vector& vStudDel, int index = 0, int nPeak = 0);
	bool			GetVarCovarMatrix(matrix& mVarCovar, BOOL bScaleWithChiSq = FALSE);
	bool			GetVarCorrMatrix(matrix& mVarCorr, BOOL bScaleWithChiSq = FALSE);
	bool			GetANOVAResult(RegANOVA &sRegANOVA, RegANOVARow &sCorrTotal, int nSetIndex = 0, int nDepIndex = 0);
	bool			IsNoneWeight(int nSetIndex = 0);

	/// Jack 12/19/2008 QA80-12329 MULTI_INDEP_DEPS_BAND_CALCULATION
	bool			CalcConfAndPredBands(const matrix& mIndeps, double rPerc, vector& vLower, vector& vUpper, BOOL bConf, int iDep, int iSet=0);
	/// End MULTI_INDEP_DEPS_BAND_CALCULATION
	
	/// NLF_81 Iris
	//bool			CalcConfAndPredBands(vector vMultiIndeps[], int nNumIndep, double rPerc, vector& vLower, vector& vUpper, BOOL bConf = TRUE, int iDep = 0);
	/// Jack 10/20/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
	//bool			CalcConfAndPredBands(const vector& vIndep1, double rPerc, vector& vLower, vector& vUpper, BOOL bConf = TRUE, int iDep = 0, const vector& vIndep2 = NULL);
	bool			CalcConfAndPredBands(const vector& vIndep1, double rPerc, vector& vLower, vector& vUpper, BOOL bConf = TRUE, int iDep = 0, const vector& vIndep2 = NULL, int iSet = 0);
	/// End CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
	///end NLF_81
	
	
	// Parameter relative
	NLParametersManager*	GetNLParamsMngr() { ASSERT(m_pParamMngr); return m_pParamMngr; }	
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//bool			DoUpdateParams(int nFunc = -1, bool bChangeParams = false, DWORD dwUpdatedByTheme = 0, bool bKeepOldSetting = false);
	///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS except with concatenate fit
	//bool			DoUpdateParams(int nFunc = -1, bool bKeepOldSetting = false);
	bool			DoUpdateParams(int nFunc = -1, bool bKeepOldSetting = false, DWORD dwCtrl = OSD_NO_PARAM_INIT );
	///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	bool			SetAutoInitParams(bool bAuto = true);
	//------ Folger 10/16/08 PA_FIT_CONTROL_DIALOG_NEED_TO_GET_AUTO_INIT_PARAMS_STATUS
	bool			GetAutoInitParams()		{ return m_bAutoRunInitParams; }
	//------
	bool			SetReplicaAutoInitParamInfoTree(const TreeNode& trReplicaInitParam);	
	// nFunc = [input] function index, -1 stand for all functions, dwInitCtrl can be enum like NLF_FUNC_CHANGE.
	bool			ParamsInitValues(bool bRunParamInit = true, DWORD dwInitCtrl = 0, int nFunc = -1);
	
	//------ Folger 11/13/08 v8.0970 CHANGE_FUNCTION_SHOULD_RESET_SHARING
	//bool			SetParamByFDFSettings(int nFunc, bool bKeepOldDataset = false, DWORD dwParamsToSkip = 0);
	bool			SetParamByFDFSettings(int nFunc, bool bKeepOldDataset = false, DWORD dwParamsToSkip = 0, bool bResetShare = false);
	//------
	/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	// for parameter details, see NLParametersManager::SetParamSettings
	BOOL			SetParamSettings(const TreeNode &trOperationParams, DWORD dwSettingsToSkip = 0, bool bDuplicateLastSetValues = false);
	/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	
	/// Hong 01/23/09 MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
	bool			ResetParamBounds(BOOL bInlcudeBaselineFunc);
	/// end MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
	
	//----- Iris 11/27/2008 v8.0980 PA_IMPROVE_PARAM_INIT_IF_LOAD_PARAM_SETTINGS_FROM_FDF
	int				GetParamsInitInfo(int nFunc, vector& vParamValues, vector<string>* pvsParamNames = NULL, const TreeNode& trFDF = NULL, int *pnNumParaInFDF = NULL);
	//-----
	
	// return 0 if not run, > 0 if success, < 0 if run but failed
	int 			HasRunParamInit() { return m_nRunParamInitResult; }
	int				GetNumTotalParams(int nFunc = -1);
	///Sophy 10/17/2008 FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
	//int				GetParamNamesInFunction(vector<string>& vstrParamNames, int nFunc = 0);	
	int				GetParamNamesInFunction(vector<string>& vstrParamNames, int nFunc = 0, bool bTrimPostfix = false );	
	///end FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
	
	///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	int				GetParamUnitsInFunction(vector<string>& vstrParamUnits, int nFunc = 0);
	///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT

	int				GetParameterNames(vector<string> &vstrParameterNames, int nDataset, int nNumData, bool bIncNumPostfix = false, bool bIncDerivedParams = false, vector<bool>& vbIsDerived = NULL);
	int				GetFitResultsParams(FitParameter* pFitParameter, RegStats *pstRegStats = NULL, int nDataset = 0, bool bIncDerivedParams = false);
	int				GetFitResultsParams(vector& vParams, vector& vErrors);		//Kyle 10/10/08 ADD_FUNCTION_GETFITRESULTSPARAMS_USED_IN_PA_BASECREATE

	int 			GetDerivedParameters(int nDataset, FitDerivedParameter* pstDerivedParams, int nSize);
	///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	//bool			GetDerivedParameters(int nDataset, vector<string>* pvsNames, vector<double>* pvdVals = NULL);
	bool			GetDerivedParameters(int nDataset, vector<string>* pvsNames, vector<double>* pvdVals = NULL, vector<string>* pvsUnits = NULL);
	///End ADD_UNIT_FOR_PARAMETER_SETTINGS
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	int				GetDerivedParamNum(int nFunc = 0);
	///Jasmine 08/13/08 QA80-12009 PARAM_HAS_SAME_NOTATION_AS_75_FOR_MULTI_DS_AND_REPLICA_AND_PEAK
	string 			GetMultiDataParamIndexedName(LPCSTR lpcszName, int nIndex);
	string 			GetReplicaParamIndexedName(LPCSTR lpcszName, int nIndex);
	string 			GetPeakParamIndexedName(LPCSTR lpcszName, int nIndex);
	///End PARAM_HAS_SAME_NOTATION_AS_75_FOR_MULTI_DS_AND_REPLICA_AND_PEAK
	/// end FITNL_USING_NEW_NLFSESSION
	bool			HasSharedParameters();
	bool			HasFixedParameters();
	void			GetSharedVector(vector<bool>& vbIsShared); 	
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	int				GeNumtNonSharedParams(int nNumParaInFunc = -1);
	/// end FITNL_USING_NEW_NLFSESSION	
	double			GetBaseline(); /// Hong 09/24/09 QA80-12199 FIT_LT_CALL_SPEED_UP_MOVE_CODE_TO_VC
	/// Hong 09/02/08 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	bool			IsAllowSharing();
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	bool			IsAutoRunInitParams(bool bChkAutoUpdateCheckBox = false);///Sophy 9/9/2008 UPDATE_REPLICA_PREVIEW_FOR_NLF_81
	bool			IsParamsInitSucceed() { return m_bInitParamsSucceed; }
	/// Hong 19/05/08 NEW_PARAM_MNGR
	//int				GetNumParameter(int nFunc = 0)		{ return m_nNumParaInFunc; }	
	/**$
		return the actual parameter number in FDF, but for PA, it will trim offset except first fit function, like, Guass, first peak return 4, second peak return 3.
	Notice: this logic may be wrong, as old code mix the concept and hard to understand, need fix it bug appear
	*/
	int				GetNumParameter(int nFunc = 0);
	/// end NEW_PARAM_MNGR

	///------ Folger 07/16/09 NANOSIZER_FAILS_TO_REPORT_PARAMETER_BOUNDS_FROM_2ND_PEAK
	int				GetPeakNumParams(int nPeak = 0);
	///------ End NANOSIZER_FAILS_TO_REPORT_PARAMETER_BOUNDS_FROM_2ND_PEAK

	int				CheckIfParamValuesValid(int nNumData);
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	////ParamValues, LowerBounds, UpperBounds are double vector
	//bool 			GetParamsSettingDoubleVector(vector& vParams, int nParamsSettingType);
	//bool			SetParamsSettingDoubleVector(const vector& vParams, int nParamsSettingType);
	////Fixed, Share, SignDigit are int or bool vector
	//bool 			GetParamsSettingIntVector(vectorbase& vnParams, int nParamsSettingType);
	//bool 			SetParamsSettingIntVector(const vectorbase& vnParams, int nParamsSettingType);
	////PramsNames, Meanings are string vector
	//bool			GetParamsSettingStringVector(vector<string>& vsParams, int nParamsSettingType);
	//bool			SetParamsSettingStringVector(const vector<string>& vsParams, int nParamsSettingType);
	bool			GetParamNumericValues(vectorbase& vbValues, PARAMS_SETTING_TYPE paramType);	
	bool			GetParamStringValues(StringArray& vsValues, PARAMS_SETTING_TYPE paramType);	
	/// end FITNL_USING_NEW_NLFSESSION
	///Sophy 11/7/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
	void		UpdatePeaksCenter( const vector<uint>& vnIndices );
	///end ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
	
	bool 			UpdateParamsFromUserSetting(){return UpdateParams();}
	bool			SetParamVectorsFromUserParamsSetting(const TreeNode& trUserParamsSetting, int nDataFrom = 0, bool bGlobalFit = false);
	/// Hong 11/04/08 QA80-12526 v8.0965b ADD_BACKWARD_COMPATIABLE
	/**$
		return: -2 if function not ready or other error, -1 if too many params; 1 if too few, but it was done anyway; 0 if same size
	*/
	int				SetParamValues(const vector& vParams);
	bool			SetParamShare(int nParam, bool bShare = true);
	bool			SetParamFix(int nParam, bool bFixed = true);
	/// end ADD_BACKWARD_COMPATIABLE
	
	// Peak relative
	int				GetNumFoundPeaks() { return m_nNumFoundPeaks; }
	int 			GetReplicaOffsetFromFDF(int nFunc = 0);  
	int 			GetReplicaUnitFromFDF(int nFunc = 0);
	int 			GetReplicaNumberFromFDF(int nFunc = 0);
	int				GetNumberMultiplicity(int nFunc = 0);
	int				GetNumberMultiplicity(const TreeNode& trReplica);
	int				GetNumPeaks();
	/// Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	bool			IsAllowReplicas(const TreeNode& trFDF = NULL);
	/// end KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	int 			OnReplicaNumberChange(int nNumReplica, int nFunc = 0, bool bUpdatePreview = true);
	// Operation Tree Relative
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//bool			SetGUIParamsTreeFromOperation(const TreeNode& trParams = NULL, DWORD dwThemeApplied = 0, bool bChangeParams = false);
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	/// Hong 09/02/08 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//bool			OperationGUIToParams(const TreeNode& trParams);
	/// Hong 09/16/08 QA80-11406 THEME_APPLY_SHOULD_DUPLICATE_LAST_DATASET_VALUES_FOR_ADDITIONAL_DATASET
	//bool			OperationGUIToParams(const TreeNode& trParams, DWORD dwParamsToSkip = 0);
	bool			OperationGUIToParams(const TreeNode& trParams, DWORD dwParamsToSkip = 0, bool bDuplicateLastSetValues = false);
	/// end THEME_APPLY_SHOULD_DUPLICATE_LAST_DATASET_VALUES_FOR_ADDITIONAL_DATASET
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	bool			ParamsToOperationGUI(TreeNode& trParams);
	/// Hong 09/14/09 FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
	//bool			ParamsToOperation(TreeNode& trOp, bool bUpdateRegState = false);
	bool			ParamsToOperation(TreeNode& trOp, bool bUpdateRegState = false, bool bOnlyFirstSet = true);
	/// end FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
	bool 			OperationToParams(const TreeNode& trOp);
	
	bool 			IsEnableAutoParamsInitFromOperation(const TreeNode& trAutoParamsInit);
	bool			IsEnableConstraintsFromOperation(const TreeNode& trLinearConstraints);
	/// Hong 20/05/08 v8.0867 CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
	//bool			LoadAutoParamsInitSetting(const TreeNode& trFDF);
	//bool			LoadLinearConstraintsSetting(const TreeNode& trFDF);
	bool			IsFDFEnableAutoParamsInit();
	bool			IsFDFEnableLinearConstraints();
	/// end CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
	bool			SetGUISettingToFDF(TreeNode& trFDF, int nNumParaInFunc, const TreeNode& trCodes, bool bAutoInit, bool bLinearConstraint);
	/// Hong 03/11/09 FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO
	//bool			GetFittingCodes(TreeNode& trCodes);
	bool			GetFittingCodes(TreeNode& trCodes, bool bUpdateUneditableOnly = false);
	/// end FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO
	
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//TreeNode		CheckAddNumIterNode(TreeNode &trParent);
	//TreeNode		CheckAddFitStatusNode(TreeNode &trParent);
	//TreeNode		CheckAddFitStatusErrorCode(TreeNode &trParent);
	TreeNode		CheckAddNumIterNode(TreeNode &trParent, int nSetIndex = 0);
	TreeNode		CheckAddFitStatusNode(TreeNode &trParent, int nSetIndex = 0);
	TreeNode		CheckAddFitStatusErrorCode(TreeNode &trParent, int nSetIndex = 0);
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	///---Sim 09-10-2008 NLFIT_LABTALK_TREE_ACCESS
	//int				LinkLabtalkTree(LPCSTR lpcszName, DWORD dwOption = 0);	
	///---END NLFIT_LABTALK_TREE_ACCESS
	
	// Preview Relative
	/// Hong 06/26/08 v80.891e CLEAN_SESSION_CLASS_FOR_ONLY_FIT_PURPOSE	
	//bool 			UpdatePreviewGraph(int nExecContext = FITPREVIEW_UPDATE, bool* pbUpdateLegend = NULL);
	//bool 			SetFitPreviewGraph(GraphPage& gpPreview, int nType, int nLayer = 0);
	//bool 			EnableSourceGraphPreview();// Only used for labtalk calling to enable show preivew on source graph
	//void 			UpdateFitSessionPreviewData(bool bPrepareWks = true);	
	bool 			EnableSourceGraphPreview() { return false; } // This should be removed after rewrite LT fitting
	/// end CLEAN_SESSION_CLASS_FOR_ONLY_FIT_PURPOSE
	
	// curves/plot relative
	/// Iris NLF_81, MOVE_GET_SET_SOURCE_PLOT_UIDS_FROM_SESSION_TO_NLFDATA
	bool    		GetSourceGraphLayer(GraphLayer& gl, int nDatasetIndex = 0);	
	///end NLF_81
	
	void			NotifyTreeFDFChange(BOOL bConstraints); /// Hong 08/13/08 QA80-12008 REACTIVE_FIT_RELATIVE_BTN_AFTER_CONSTRAINT_CHANGE
	void			NotifyFitCtrlOptionChanged() { resetIterations(0, false); }
	void			NotifyFitCurveOptionChange( bool bResetIter ){ if(bResetIter)resetIterations(OSD_FROM_X_DATA_TYPE_CHANGE, false); }
	/// Hong 09/10/08 v8.0936b PARAMETER_MODIFIED_BY_GRID
	void			NotifyParameterChangedByEdit();
	/// end PARAMETER_MODIFIED_BY_GRID
	bool			OnFindingPeakArgChanged();
	
	//////////////////For FitPeak, Folger, to do////////////////////////////////////	
	bool			SetFitInfoTree(TreeNode& trFitInfo)		{ return false; }
	void			SetPlotCurveType(bool bIndividualPeak = true, bool bCumulative = true)	{}
	void			GetParams(TreeNode& trPara)	{}
	int				GetPeakCenterOrWidth(vector& vXCenter, bool bGetCenter, bool bGetY = false);
	///Sophy 11/4/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
	int				GetPeakCenterX( vector& vXCenter );
	int				GetPeakCenterY( vector& vYCenter );
	///end ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
	int				GetAllFunctions(vector<string>& vsFunctions = NULL);

	/// Iris 11/12/2008 v8.0969 QA80-12584 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP, just renmae SetBaseLineMode to SetHasBaseLineMode, old name not good
	//void			SetBaseLineMode(bool bHasBaseline);
	void			SetHasBaseLine(bool bHasBaseline);
	bool			HasBaseline();
	///end OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
	void			SetBaselineFitMode(bool bBaselineFitWithPeaks);
	bool			GetBaselineFitMode();
	/// Iris 11/15/2008 FIX_ADDBACKBASELINE_FAIL_TO_GET_BASELINE_DATA
	//bool			GetBaselineData(vector& vXBaseline, vector& vYBaseline, matrix& matZBaseline = NULL);
	bool			GetBaselineData(vector& vXBaseline, vector& vYBaseline, matrix& matZBaseline = NULL, bool bCheckCondition = true);
	///end FIX_ADDBACKBASELINE_FAIL_TO_GET_BASELINE_DATA
	void			SetBaselineRange(DataRange& drBaseline);
	void 			SetSubtractedMode(bool bSubtracted);
	bool			GetSubtractedMode();
	bool			GetSubtractedDataRange(DataRange& drSubtracted);
	void			SetSubtractedDataRange(DataRange& drSubtracted);
	
	/// Iris 11/14/2008 v8.0971b QA80-12584 FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED, replaced with SetSubtractedDataRange
	/*
	/// Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION, before always pass subtracted data range to nlfsession, so data range is subtracted data range from one temp worksheet not real original data range
	// this range got from PAWizCore::GetPeaksRange when has baseline but not subtract.
	// if m_drPeaks is invalid, need do subtract_baseline on original data and save subtracted data into one newly created worksheet to construct m_drPeaks.
	void			SetPeaksRange(DataRange& drPeaks) { m_drPeaks = drPeaks; } 
	///end PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
	*/
	///end FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
	
	bool			GetResultPFWTree(TreeNode& tr); /// Iris 9/22/2008 NEW_PA, add temp not sure if still neen PFWTree later
	///////////////////////////////////////////////////////////////////////////////
	
	bool			CheckXYZRegularData( int& nRows = NULL, int& nCols = NULL);	///Sophy 1/12/2009 v8.0995c QA80-12613-P4 SHOULD_ONLY_SHOW_UNIFORM_LINEAR_ON_DATATYPE_FOR_3D_FITTING
	
	///------ Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	void			SetUseSmartX(bool bOn = true)
						{ m_bUseSmartX = bOn; }
	bool			GetUseSmartX()
						{ return m_bUseSmartX; }
	void			SetXPtsForEachPeak(int nPts = FITCURVE_POINTS_FOR_INDIVIDUAL_PEAKS)
						{ m_nXPtsForEachPeak = nPts; }
	int				GetXPtsForEachPeak()
						{ return m_nXPtsForEachPeak; }
	///------ End ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	
	///------ Folger 02/11/09 QA80-13098-S2 SHOW_CHISQR_INFO_IN_NLFIT_STATIC_MESSAGE
	string			GetReducedChiSqrInfo(const RegStats& stRegStats = NULL, int nSignDigit = -1);
	///------ End SHOW_CHISQR_INFO_IN_NLFIT_STATIC_MESSAGE

	///------ Folger 07/16/09 NANOSIZER_FAILS_TO_REPORT_PARAMETER_BOUNDS_FROM_2ND_PEAK
	int				GetFuncIndex(int nPeakIndex)			{ return GetNLParamsMngr()->GetFuncIndex(nPeakIndex); }
	int				GetPeakParameterOffset(int nPeakIndex)	{ return GetNLParamsMngr()->GetPeakParameterOffset(nPeakIndex); }
	///------ End NANOSIZER_FAILS_TO_REPORT_PARAMETER_BOUNDS_FROM_2ND_PEAK
	
protected:
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	int				GetNLFitArrayOffset();
	int				GetNumNLFitObjs();
	int				GetDatasetIndexInNLFit(int nDataSetIndex);
	NLFit&			GetNLFitObj(int iSetIndex = 0);
	bool			CheckUpdateNLFitParamsLinking(int nDataset = 0);
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	
	// Function relative
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//virtual	bool	OnSetFunction(int nFunc = 0, DWORD dwSelFuncByTheme = 0);
	///------ Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	//virtual	bool	OnSetFunction(int nFunc = 0);
	virtual	bool	OnSetFunction(int nFunc = 0, int* pErrCode = NULL);
	///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	
	// Data relative
	///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
	//virtual void	OnSetData();
	virtual void	OnSetData( int nOldDataMode = INVALID_DATA_MODE, int nNewDataMode = INVALID_DATA_MODE );
	///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
			
	// Parameter relative
	virtual void 	OnParamChange(DWORD dwPlotCurves = 0, bool bFromGUI = false);
	
	void			InitParamMngr();	
	bool 			UpdateParams(bool bFromGUI = false, bool bUpdateGraph = false, LPCSTR lpcszMsg = NULL);
	/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	//virtual int	 	GetParamsSubVectorRange(int nDataset = -1, int nFunc = -1, int* pnFrom = NULL, int* pnTo = NULL, int nPeak = -1);
	/// Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	//int	 			GetParamsSubVectorRange(int nDataset, int nFunc, int* pnFrom);
	int	 			GetParamsSubVectorRange(int nDataset, int nFunc, int* pnFrom, int* pnLastFromOnlySingleSet = NULL, int* pnLastFunc = NULL);
	/// end PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	
	// Operation Tree relative	
	bool			UpdateInputBranch(TreeNode &trInput);
	
	
	bool 			IsPlotFitCurve(DWORD dwCntrl)
	{		
		return (dwCntrl & (OSD_FROM_FUNC_CHANGE | OSD_FROM_DATA_CHANGE | OSD_FROM_PARAM_REPLICA_NUM_CHANGE | OSD_FINDING_PEAK_ARG_CHANGE)) && GetNumDataset() > 0 ? true:false;
	}		
	
	/// Hong 08/27/08 v8.0931 FIX_ORIGIN_CRASH_WHEN_CLICK_OK_AFTER_CONVERGE
	int				CallBack(int nMsg, LPCSTR lpcszStatus, int nParam, int lParam);
	int 			OnCallBack(int nMsg, LPCSTR lpcszStatus, int nParam, int lParam);
	/// end FIX_ORIGIN_CRASH_WHEN_CLICK_OK_AFTER_CONVERGE
	
private:
	///------ Folger 09/18/09 QA80-14333 RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF
	BOOL			resetParamsFromFDF(DWORD dwParamsToSkip, BOOL bInlcudeBaselineFunc);
	///------ End RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF

	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/////Arvin 06/12/07 RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS 
	//int 			GetParamsActualIndex(int nNumParaInFunc, int nDataSet, int nParamIndex);
	//void		 	GetParamsLowerUpperConfBound(vector& vConfLower, vector& vConfUpper); 
	/////end RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	
	/// Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
	bool			calcConfAndPredBands(const vector* pvIndeps, int nNumIndeps, double rPerc, vector& vLower, vector& vUpper, BOOL bConf, int iDep, int iSet=0);
	/// End CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
	
	void 			onInit(bool bSingleFunction);
	void 			onDestroy();
	
	typedef enum tagNLFDATATYPE
	{
		DATA_TYPE_INVALID = -1,
		DATA_TYPE_SINGLE_SET,
		DATA_TYPE_MULTI_SET,
		DATA_TYPE_SURFACE,
		DATA_TYPE_MATRIX, /// Hong 08/14/08 v8.0922 FIX_MATRIX_FIT_FAIL_DO_REDUCE
	} NLFDATATYPE;
	int				getDataType();
	void			onInitDataObject();
	void			onDestroyDataObject();
	
	// Function relative	
	bool			getFunctionTree(TreeNode& trFF, LPCSTR lpcszFunctionName, string& strCategoryName, bool bLoadFDF = true);
	/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	//void 			NLFitReset(int nWhat = ONLSF8RESET_ALL, bool bResetInternal = false);	
	void 			NLFitReset(int nWhat = ONLSF8RESET_ALL, bool bResetIterateCount = true);
	/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//virtual	bool	onParamsNeedUpdate(DWORD dwCntrl, LPCSTR lpcszMsg = NULL, DWORD dwUpdatedByTheme = 0, bool bChangeParams = false, int nFunc = -1, bool bKeepOldSetting = false);
	virtual	bool	onParamsNeedUpdate(DWORD dwCntrl, LPCSTR lpcszMsg = NULL, int nFunc = -1, bool bKeepOldSetting = false);
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	
	int 			replicaInitParamMsgLog(int nNumFoundPeaks, int nNumNeededPeaks); // Hong, to do, rename
	
	int				numReplicaToMultiplicity(int nNumReplica);
	int				numMultiplicityToReplica(int nNumMultiplicity);
	bool			setNumMultiplicity(int nNumMultiplicity, int nFunc);
	
	// Data relative
	/**$
	Parameter:		
		bDep = [input] true for dependent data, nIndex mean dependent index; false for independent data, nindex mean independent index
	*/
	///Sophy 10/24/2008 SUPPORT_MUILTI_INDEP_AND_DEP_PREVIEW_FOR_NLFIT_81 move to public
	//bool			getInputData(vector& vData, bool bDep, int nDatasetIndex, int nIndex = 0);
	///end SUPPORT_MUILTI_INDEP_AND_DEP_PREVIEW_FOR_NLFIT_81
	
	// for when data mode is concatenate
	DataRange		getConcatenateDataRange();
	void			prepareConcatenateDataRange();
	bool			calcConcatenateAveData();
	
	// iterate/fit relative
	bool			checkSetNLFitFunction();
	bool			checkSetNLFitData();
	bool			checkSetNLFitParameter();
	void			beforeFit(int nMethod);
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	void			afterFit();
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//void			backupSepFitResults();
	//
	//bool 			getFitResultsStats(RegStats* pRegStats, NLSFFitInfo* pFitInfo, bool bPreDataset = false, int nSetIndex = -1, int nDepIndex = 0);
	//bool			getANOVAResult(RegANOVA &sRegANOVA, RegANOVARow &sCorrTotal, int nSetIndex = 0, int nDepIndex = 0);
	//int				getFitResultsParams(FitParameter* pFitParameter, RegStats *pstRegStats = NULL, int nDataset = 0, bool bIncDerivedParams = false);
	//bool			getDerivedParameters(int nDataset, vector<string>* pvsNames, vector<double>* pvdVals = NULL);
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/// Hong 10/23/08 QA80-12434 TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	bool 			getReducedChiSq(const TreeNode& trOp, double& dSSE, int nSetIndex = 0, int nDepIndex = 0);
	/// end TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	void			setFitSettings();
	//bool 			getFitZ(vector& vx, vector& vy, matrix& mat, int nIndependent); /// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
	bool			isLastFitOutComeGoodFit();
	bool			isLastFitOutComeError();		
	// dwCntrl can be one like OSD_FUNC_CHANGE_THEN_SET_DATA
	void 			resetIterations(DWORD dwCntrl, bool bResetIterateCount = true);
		
	bool			outputOpMsgLog(int nIterNums, int nMethod, const RegStats& stRegStats, int nIterationOutCome);
	/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	//string			prepareFitOperationMessage(int nIterNums, int nMethod, const RegStats& stRegStats, int nIterationOutCome);
	// Hong, Notice!!! we assume that FitOutCome is always at the end of the string.
	string			prepareFitOperationMessage(int nIterNums, int nMethod, const RegStats& stRegStats, int nIterationOutCome, string* pstrFitOutCome = NULL);
	/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	string			constructResultTitle(int nIterationOutCome, int nMethod);
	string			constructIterationOutCome(int nIterationOutCome);
	/// Hong 03/02/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	//string			constructIterationCountsString(int nIterNums);
	string			constructIterationCountsString(int nIterNums, int nIterationOutcome);
	/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	
	// Parameter relative
	int				getParamsType();
	bool			isMultiplicityFit();
	/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
	//bool			setParamByFDFSettings(int nFunc);
	//bool			setParamByFDFSettings(int nFunc, bool bKeepOldDataset = false, DWORD dwParamsToSkip = 0);
	/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
	bool			getParamInitValues(const NumericFunction& fn, int nDataset, vector& vParamValue);
	bool			replicaAutoInitParams(int nFunc = 0, int nDataset = 0, const vector& vDefaultParams = NULL);
	bool			replicaInitOneDimensionParams(const FindPeakCtrlInfo& findPeakCtrlInfo, int nDataset, int nNumMultiplicity, const vector& vDefaultParams);
	bool			replicaInitTwoDimensionParams(const FindPeakCtrlInfo& findPeakCtrlInfo, int nDataset, int nNumMultiplicity, const vector& vDefaultParams);
	bool			getReplicaInitParamSettings(FindPeakCtrlInfo& findPeakCtrlInfo);
	bool			isNeedReinitParamType();
	/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	bool			isNeedRestoreParamsSettings();
	/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	int				getNumParamsInFDF(int nFunc, vector<string>* pvsParamNames = NULL, const TreeNode& trFDF = NULL);
	/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	//----- Iris 11/27/2008 v8.0980 PA_IMPROVE_PARAM_INIT_IF_LOAD_PARAM_SETTINGS_FROM_FDF
	//int				getParamsInitInfo(int nFunc, vector& vParamValues, vector<string>* pvsParamNames = NULL, const TreeNode& trFDF = NULL, int *pnNumParaInFDF = NULL);
	//-----
	void 			trimOffsetParameter(vectorbase& vb, int nFunc = 0);
	void 			trimOffsetParameter(vector<string>& vs, int nFunc = 0);
	bool			getParamNumericValues(NLPARAMGRIDCOLTYPE colType, vectorbase& vbValue);
	bool			getParamStringValues(NLPARAMGRIDCOLTYPE colType, vector<string>& vstrValue);
	int				getNudgeParamIndex();
	bool			tryOptimizeNudgeParam();
	void			validateParams(LPCSTR lpcszTitle);	
	
	/// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	void			updateSharedCtrl(int nDataMode, int nOldDataMode);
	void			resetSharedCtrl() { updateSharedCtrl(INVALID_DATA_MODE, INVALID_DATA_MODE); checkUpdateSharedParamBySharedCtrl(); }
	/// Hong 12/24/08 QA80-10499 v8.0990c DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
	//void			checkUpdateSharedParamBySharedCtrl(bool bBeforeOnSetData = true);
	void			checkUpdateSharedParamBySharedCtrl(bool bBeforeOnSetData = true, bool bForceResetIfNone = false);
	/// end DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
	/// end DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	
	// Operation relative
	bool			checkAddWorkArea(TreeNode& trOp);
	
	
	// result log	
	bool			isMsgLogAvailable() { return m_pOpMsgLog ? true : false; }
	// lpcstrMsg = [input] if NULL, no message will outpute, but separator and empty line is still valid for output
	/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	//void			writeMsgLog(LPCSTR lpcstrMsg, bool bStartSeparator = true, bool bEndEmptyLine = true);
	void			writeMsgLog(LPCSTR lpcstrMsg, bool bStartSeparator = true, bool bEndEmptyLine = true, bool bEmphasize = false);
	/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	
	/// Hong 06/26/08 v80.891e CLEAN_SESSION_CLASS_FOR_ONLY_FIT_PURPOSE	
	////preview relative
	//void			destroyPreviewCtrl();
	//bool 			preparePreviewCtrlInfo(bool bSimplexFit = false); 
	/// end CLEAN_SESSION_CLASS_FOR_ONLY_FIT_PURPOSE	
	/// Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	int				getReplicaOffsetFromFDF(const TreeNode& trFDF);
	/// end KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	int				getIterateResultSetIndex(int nSetIndex);
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//bool			hadBackupedFitResults();
	//bool			doesNeedBackupFitResults();
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	bool			isSeparateFit();
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	
	///
	bool			isGlobalFit();
	///
	
	/// Iris 9/22/2008 NEW_PA
	bool			peaksCenterWidthSettingsAccess(vector<int> &vsSettings, int &nValue, int nCenter, int nWidth, bool *pbChange, bool bSet = true, bool bShare = false);
	///end NEW_PA
	bool			prepareSubtractedDataRange(); /// Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
	
	bool			isKeepOldDatasetParamsSettings() { return !m_bParamsFromAutoInit; } /// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA

	///------ Folger 04/13/10 QA81-15297-P3 SHOW_LINEAR_CONSTRAINT_INFO_IN_FOOTNOTE
	BOOL			IsLinearConstraintUsed();
	///------ End SHOW_LINEAR_CONSTRAINT_INFO_IN_FOOTNOTE

	///------ Folger 08/06/10 ORG-733 FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
	void			SetLastError(int nErr, int* pnErrToSet = NULL);
	int				GetLastError();
	///------ End FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
	
protected:
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	// Hong, current variable is for backup user settings as NLFit object may not created until Iterate,
	// to do, can be removed once NLFit have interface to return such settings.
	string					m_strConstraintsCode;
	NLSF8ITERATIONSETTINGS	m_stNLSFIterSetting;	
	NLSF8DATASTEP 			m_stDataSteps[MAX_DATASET_NUMBER];
	int						m_nDataStepsSize;
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	int						m_nOldNumberDataset;
	int						m_nBackupOldNumDataset; /// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	vector<string>			m_vsFunctionList;
	
	int						m_nNumFoundPeaks;
	DWORD					m_dwSrcPlotUIDConcatenate;
	
	/// Iris NLF_81
	//it stores source data plot UID if input data from graph window; or stores preivew source data plot UID if data from worksheet window
	//so rename to m_vuSourceDataPlotUIDs, m_uFitDataPlotUIDs not make sense.
	//vector<uint>			m_uFitDataPlotUIDs; 
	vector<uint>			m_vuSourceDataPlotUIDs;
	///end NLF_81
	///Sophy 11/4/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH for replica peaks
	vector					m_vXCenter;
	vector					m_vYCenter;
	///end ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH

private:
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	// Hong, i need to have m_NLFit, because object get from m_arNLFitAdditionalObjs is return by const reference, can't edit
	NLFit					m_NLFit;
	Array<NLFit&>			m_arNLFitAdditionalObjs;
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	// Hong, to do, after Edit on Parameter Grid, need notify NLFitSession to add bit NLFIT_DIRTY_PARAMETER
	enum
	{
		NLFIT_DIRTY_FUNCTION	= 0x00000001,
		NLFIT_DIRTY_DATA		= 0x00000002,
		NLFIT_DIRTY_PARAMETER	= 0x00000004,
		NLFIT_DIRTY_ALL			= 0x00000007,
	};
	DWORD					m_dwNLFitDirtyBits;
	
	bool					m_bInitParamsSucceed;
	
	// Fit relative
	int						m_nFitType;
	double					m_dConfidence;
	double					m_dTolerance;
	bool					m_bScaleParamErrors;
	ONLSFNUMERICDERIVSSETTINGS		m_DerivsSettings;
	bool					m_bGetParamsConf;
	int						m_nConfLimitMethod;

	int						m_nMaxNumIter;
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/*
	int						m_nIterCount;		
	int						m_nLastIterateOutCome;
	int						m_nNumberItersPerformed;
	string					m_strFitMessage;
	*/
	IntArray				m_vnIterCount;
	IntArray				m_vnLastIterateOutCome;
	IntArray				m_vnNumberItersPerformed;
	StringArray				m_vsFitMessage;
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	// Function relative	
	NLFunctionList			m_NFO;
		
	// Data relative	
	NLFDataBase*			m_pDataObj;
	NLFDATATYPE				m_nlfDataType;
	BOOL					m_bInitData;
	
	// Parameter relative
	enum
	{
		NLF_PARAM_TYPE_CTRL_REPLICA 		= 0x00000001,
		NLF_PARAM_TYPE_CTRL_MULTI_SETS 		= 0x00000002,
		NLF_PARAM_TYPE_CTRL_MULTI_FUNCTIONS	= 0x00000004,
		/// Hong 05/06/09 OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
		NLF_PARAM_TYPE_CTRL_ALLOW_2D_REPLICA	= 0x00000010,
		/// end OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
	};
	NLParametersManager*	m_pParamMngr;	
	DWORD					m_dwParamTypeCtrl;
	TreeNode				m_trReplicaInitParam;
	
	/// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	enum
	{
		NLF_SHARED_CTRL_NONE,		
		NLF_SHARED_CTRL_BACKUP_RESET_CURRENT,
		NLF_SHARED_CTRL_RESTORE,
		NLF_SHARED_CTRL_NO_CHANGE,
	};
	int						m_nSharedCtrl;
	vector<int>				m_vnBackupShared;
	bool					m_bInternalSetFunctionByDataChange;
	int						m_nCurrDataMode; /// Hong 09/02/08 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	/// end DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
		
	// Operation Tree relative
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//TreeNode				m_trOpParams;
	//bool					m_bDlgChangeParams;
	//DWORD					m_dwDlgThemeApplied;
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	
	RegStats				m_RegStats;	
		
	OperationLogBase*		m_pOpMsgLog;

	bool					m_bAutoRunInitParams;
	int						m_nRunParamInitResult;
	bool					m_bParamsFromAutoInit; /// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
		
	bool					m_bDisableUpdate;
	DWORD					m_dwAutoUpdateCtrl;	
	
	// curves/plot relative
	bool					m_bAllSrcFromGraph;
	int						m_nAveType;
	bool					m_bAveSrcData;	
	bool					m_bConcatenateSrcData;	
	DataRange				m_drSrcData;
	DataRange				m_drConcatenateSrcData;
	DataRange				m_drAveData;
	Worksheet				m_wksConcatenate;
	
	// fit curve(only data) relative
	/// Iris NLF_81, to do, NLFCurvesBase used for preview and operation result, has been moved to NLFPreviewCtrl.h. Need to move to FitNL later
	//NLFCurvesBase*			m_pnlfCurves; /// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
	///end NLF_81
	
	/// Hong 06/26/08 v80.891e CLEAN_SESSION_CLASS_FOR_ONLY_FIT_PURPOSE	
	//// preview relative
	//NLFitPreviewCtrl*		m_pNLFitPreviewCtrl;
	//PreviewCtrlInfo*		m_pPreviewCtrlInfo;
	//NLFPlottingInfo*		m_pPlottingInfo;
	/// end CLEAN_SESSION_CLASS_FOR_ONLY_FIT_PURPOSE	
	
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	// Hong, to do, need to backup other fit outcomes which FitNL can access, like GetFitOutCome
	// backup fit results for separate fit as ONLY single NLFit, this code need to update once we have new result, and should be moved once NLFit support separate fit directly, possible?
	// This group of variable should NOT be used except separate fit.
	int							m_nSepFitActiveDataset;
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//typedef	struct	tagNLFitResults
	//{
		//RegStats				stFitRegStats;
		//NLSFFitInfo				stFitInfos;	
		//Array<FitParameter&>	arFitParamResults;
		//StringArray				stFitDerivedParamNames;
		//DoubleArray				stFitDerivedParamValues;
		//RegANOVA				stFitRegANOVAs;
		//RegANOVARow				stFitRegANOVARows;	
	//} NLFitResults, *PNLFitResults;
	//Array<NLFitResults&>			m_arNLFitResults;	
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT	
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	/// Iris 9/22/2008 NEW_PA
	bool					m_bHasBaseline;
	DataRange				m_drBaseline;
	/// Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
	/// Iris 11/14/2008 v8.0971b QA80-12584 FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED, replaced with m_drSubtracted;
	//DataRange				m_drPeaks; 
	///end FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
	Worksheet				m_wksSubtracted;
	///end PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
	
	//------ Folger 10/21/08 SET_GET_BASELINE_PEAK_FITTING_STATUS_IN_NLPARAMSMNGR
	//bool					m_bBaselineFitWithPeaks;
	//------
	
	bool					m_bHasSubtracted;
	///end NEW_PA
	
	/// Iris 11/12/2008 v8.0969 QA80-12584 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
	DataRange				m_drSubtracted; 
	///end OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
	
	///------ Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	bool					m_bUseSmartX;
	int						m_nXPtsForEachPeak;
	///------ End ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	
	bool					m_bInitFromNanosizer;		///------ Folger 05/12/09 NANOSIZER_FITTING_BASED_SUPPORT
	
	/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	bool					m_bIterateSettingsPolished;
	bool					m_bLastFitIterateTillConverge;
	/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	
	/// Hong 03/13/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	bool					m_bDuringGetResultWithIterate;
	/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE

	///------ Folger 08/06/10 ORG-733 FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
	int						m_nLastError;
	///------ End FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
};



//////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////NLFitSession Implementation/////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
NLFitSession::NLFitSession(bool bSingleFunction) // = true
{
	_DBSTR("------- NLFitSession::NLFitSession()");
	onInit(bSingleFunction);
}

NLFitSession::~NLFitSession()
{
	_DBSTR("------- NLFitSession::~NLFitSession()");
	onDestroy();
}

/// Hong 05/06/09 OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
void		NLFitSession::SetIs2DSupportReplica(bool bSet)
{
	if ( bSet )
		m_dwParamTypeCtrl |= NLF_PARAM_TYPE_CTRL_ALLOW_2D_REPLICA;
	else
		m_dwParamTypeCtrl &= ~NLF_PARAM_TYPE_CTRL_ALLOW_2D_REPLICA;
}

bool		NLFitSession::Is2DSupportReplica()
{
	return (NLF_PARAM_TYPE_CTRL_ALLOW_2D_REPLICA & m_dwParamTypeCtrl) ? true : false;
}
/// end OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
	
bool 		NLFitSession::SetDisableUpdate(bool bDisable) // = true
{
	bool	bOldVal = m_bDisableUpdate;
	m_bDisableUpdate = bDisable;
	return bOldVal;
}

/// Hong, to do, should move to FitNL if we want session to get rid of operation tree
bool		NLFitSession::InitFromOperationTree(TreeNode& trOp, bool& bHasFitGood, bool& bParamsReady, bool bDoFitAnyWay, DWORD dwInitParams, bool bInitData, bool bLoadFDF) // = NULL, false, 0, false, true
{
	checkAddWorkArea(trOp);
	TreeNode 	trFuncSel = trOp.GUI.FunctionSelection;
	TreeNode	trOpWork = trOp.FitWorkArea;
	
	// Hong, to do, very confuse of this fit good mechanism, because even operation tree is really fit ready, but session can still not initialized
	bHasFitGood = false;
	int		nFitComeOut;	
	if ( !trOpWork.Parameters.GetAttribute(STR_FIT_OUTCOME_ATTRIB, nFitComeOut) ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	{
		ASSERT( m_vnLastIterateOutCome.GetSize() > 0 );
		if ( m_vnLastIterateOutCome.GetSize() < 1 )
			m_vnLastIterateOutCome.SetSize(1);
		m_vnLastIterateOutCome[0] = nFitComeOut;
	}
	if( GetNumDataset() > 0 && IsFunctionReady() && isLastFitOutComeGoodFit() && !bDoFitAnyWay )
	{
		bHasFitGood = true;   
		bParamsReady = true;
		return true;
	}

	int nAutoInitParams = 0;
	trOp.FitWorkArea.GetAttribute(STR_AUTO_INIT_PARAMS, nAutoInitParams);
	bool bAutoInitParams = (dwInitParams & NLFIT_INIT_PARMAS_AUTO) || (nAutoInitParams == AUTO_INIT_PARAMS); ///Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG	
	SetAutoInitParams(bAutoInitParams);
	
	/// Hong 04/21/08 QA80-11447 FIX_REPLICA_THEME_FAIL_RUN_WHEN_NO_DLG
	//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
	//TreeNode	trReplica = trOp.GUI.Replica;
	TreeNode	trReplica = get_gui_replica_node(trOp.GUI);
	//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
	TreeNode	trReplicaInit = tree_get_node_by_id(trReplica, IDST_REPLICA_PARAM_INIT_OPTIONS);
	ASSERT(trReplicaInit);
	SetReplicaAutoInitParamInfoTree(trReplicaInit);
	/// end FIX_REPLICA_THEME_FAIL_RUN_WHEN_NO_DLG
	
	/// Iris 02/06/2007 v8.0575b CORRECT_SETINITDATA_LOGIC
	/*
	/// Iris 02/28/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	// If SetInitData to true, in ::SetFunction will reconstruct InputData branch according to Dep & Indep variable name of Function.
	// If open NLSF dialog, will do SetInitData to true and call SetFunction to chagne InputData branch in another place, so no need do this again here.
	// But for the two cases, one is selection Theme from menu, another is Data Mode is "Indep Fit - Consolidate Report", MUST SetInitData to true here to update InputData branch according to Function.
	//SetInitData(false);
	SetInitData(bInitData);
	///end CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY	
	*/
	///Cheney 2007-4-9 CORRECT_LOGIC_OF_CALLING_INIT_BRANCH
	//if(bInitData)
	//	SetInitData(true);
	/*
	From Marko's mali, design of calling init input branch should be:
	1. Under NO circumstances should to input data branch initialization (i.e. call to 
	   NLFitSessionBase::UpdateInputBranch()) (regardless whether it is from selection or not) 
	   be done from within executeWithRange().
	2. Here is where this should happen in various cases:     
        2.1. Running first time from NLFit dlg: From within NLFitSplitter in two circumstances: 
        (1) on the first init once the correct fitting function is known, 
        (2) on fitting function change by user. I think this is how it is now.
        2.2. Running from a theme, (such as <last used> or any other theme): from within 
            OnNoEdit(), more precisely, from WksReportOperation::OperationtoGUI() or from within
            InitFromSelection(trOperation) (the best is to put breakpoint into InitFromSelection(trOperation) 
            and execute <last used> and look at the stack: OnNoEdit() must be on stack) once 
            the theme has been loaded such that the fitting function is known: 
            in this case NLFitSession has to be initialized there (instead of inside FitNL::doOneFit()) and its SetFunction() needs to be called. 
        2.3. In all other cases, such as Recalculate, Change Params (unless user changes fitting 
        	function), NLFitSessionBase::UpdateInputBranch() must NOT be called. 
	*/
	SetInitData(bInitData);
	///end CORRECT_LOGIC_OF_CALLING_INIT_BRANCH
	///end CORRECT_SETINITDATA_LOGIC
	
	//SetFitInfoTree(tree_get_node_by_id(trOpWork, IDE_FITNL_OP_PFM_TREE)); // Hong, to do
	
	SetScaleParamError(trOp.GUI.Fit.ScaleError.nVal);	
	SetTolerance(trOp.GUI.Fit.Iterations.Tolerance.dVal);	
	SetIsGetParamsConf(trOp.GUI.Quantities.Parameters, trOp.GUI.Quantities.SummaryTable, trOp.GUI.Fit.CIMethod);
		
	SetFitType(trOp.SpecInfo);

	//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
	//int nMultiplicity = GetNumberMultiplicity(trOp.GUI.Replica);
	int nMultiplicity = GetNumberMultiplicity(get_gui_replica_node(trOp.GUI));
	//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE

	bool bResetFunction = true; 
	SetFunctionList(trFuncSel);  //to get all functions from the current category		
	bool	bIsMixedFunction = IsMixedFunction(trFuncSel);
	//if ( m_bInitData )
	//	;
	// The order of settings must be:
	//	1. Set Function
	//	2. Set Data
	//	3. Set Params (share, initial values, etc.)
	//----- Iris 10/13/06 FIX_SPECAIL_NLSF_TOOLS_CLICK_OK_NOT_REPORT
	//TreeNode		trInput;
	Tree			tr;
	TreeNode		trInput = tr.AddNode("DataSelection");
	//-----
	
	/// Iris 03/14/2007 v8.0581 FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
	string			strOnlyOneRangeName;
	int				nFitMode = trOp.GUI.InputData.Use;
	///end FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
	if ( m_bInitData )
	{
		//----- Iris 10/13/06 FIX_SPECAIL_NLSF_TOOLS_CLICK_OK_NOT_REPORT
		//trInput = trOp.GUI;
		trInput.AddNode(trOp.GUI.InputData);
		//----- 
		
		/// Iris 03/14/2007 v8.0581 FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
		if ( DATA_MODE_INDEP_SEP == nFitMode && 1 == trInput.InputData.GetNodeCount() )
		{
			strOnlyOneRangeName = trInput.InputData.FirstNode.tagName;
		}
		///end FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
	}

	string	strFunctionName, strCategoryName;
	if ( trFuncSel )
	{
		strFunctionName = trFuncSel.FunctionList.strVal;
		strCategoryName = trFuncSel.CategoryList.strVal;
	}
	bool	bOriginVal = SetDisableUpdate(true); // Hong, data not ready, no need do parameter value update
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//bool	bRet = SetFunction(strFunctionName, strCategoryName, nMultiplicity, bResetFunction, NULL, 0, trInput, 0, bLoadFDF);
	/// Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
	//bool	bRet = SetFunction(strFunctionName, strCategoryName, nMultiplicity, bResetFunction, NULL, 0, trInput, bLoadFDF);
	bool	bRet = SetFunction(strFunctionName, strCategoryName, nMultiplicity, bResetFunction, trInput, bLoadFDF);
	/// end SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	SetDisableUpdate(bOriginVal);	
	if ( !bRet )
		return false;		
	
	///Cheney 2007-6-18 SHOULD_UPDATE_LINEAR_CONSTRAINT_NODE_WHEN_UPDATE_IT_IN_GUI
	//as Marko said, after SetFunction called, should call SetLinearConstraints again
	ASSERT(trOp.GUI.Parameters);
	SetEnableLinearConstraints(trOp.GUI.Codes.Constraints, trOp.GUI.Parameters.LinearConstraints.nVal);
	///end SHOULD_UPDATE_LINEAR_CONSTRAINT_NODE_WHEN_UPDATE_IT_IN_GUI
	
	/// Iris 02/24/2007 v8.0569 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	//The problem only shows when open nlsf dlg from menu with Theme to create report, then click change parameter in report sheet...
	//The main reason is SetFunction will change trInput according to the number of Dep and Indep in Function, but here do not copy 
	//changed trInput back to Operation tree.
	if ( !trInput.IsEmpty() )
	{
		/// Iris 03/14/2007 v8.0581 FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
		if(DATA_MODE_INDEP_SEP == nFitMode && !strOnlyOneRangeName.IsEmpty())
		{
			Tree 		tr;
			TreeNode 	trOneRange = tr.AddNode("junk");
			trOneRange.Replace(trInput.InputData.GetNode(strOnlyOneRangeName).Clone());
			
			trInput.InputData.Reset(true);
			
			TreeNode	trTemp = trInput.InputData.AddNode("junk");
			trTemp.Replace(trOneRange.Clone());				
		}
		///end FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
		
		trOp.GUI.InputData.Replace(trInput.InputData.Clone());
	}
	///end CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	
	/// Iris 01/17/2007 v8.0543 IMPROVE_NLFIT_SPEED
	/////Cheney 2006-11-14 FIX_RUNTIME_ERROR_WHEN_CHOOSE_THEM_FROM_MENU
	//SetFitCurveOptions(trOp.GUI.Graph1); //set plot type, color,..., etc
	////if(SetData(trOp.GUI.InputData, trOp.GUI.Fit.Weighting, OSD_NO_PARAM_UPDATE))
	//if(SetData(trOp.GUI.InputData, trOp.GUI.Fit.Weighting)) //temp solution, should add member for "data and func ready", I will do it after beta1 
	if ( !SetData(trOp.GUI.InputData, trOp.GUI.Fit.Weighting) )
		return false;
	/////end FIX_RUNTIME_ERROR_WHEN_CHOOSE_THEM_FROM_MENU
	
	//SetFitCurveOptions(trOp.GUI.Graph1); /// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
	
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//if ( !bAutoInitParams )
	//	bParamsReady = SetParams(trOpWork.Parameters);
	if ( !bAutoInitParams )
		bParamsReady = OperationToParams(trOp);
	/// end FITNL_USING_NEW_NLFSESSION
	
	ASSERT(trOp.GUI.Fit.Iterations);
	SetMaxNumIter(trOp.GUI.Fit.Iterations.MaxNum.nVal);	
	return true;
}

OperationLogBase*	NLFitSession::InitMsgLog(OperationLogBase* pOpMsgLog) // = NULL
{	
	OperationLogBase* pOldMsgLog = m_pOpMsgLog;
	m_pOpMsgLog = pOpMsgLog;
	return pOldMsgLog;
}

/// Hong 09/10/08 v8.0936b PARAMETER_MODIFIED_BY_GRID
//void		NLFitSession::SetParametersNeedUpdate()
//{	
	//m_dwNLFitDirtyBits |= NLFIT_DIRTY_PARAMETER;	
//}
/// end PARAMETER_MODIFIED_BY_GRID

// Hong, to do, parameter nMultiplicity maybe removed
/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
//bool		NLFitSession::SetFunction(const TreeNode& trFitFunc, int nMultiplicity, bool bResetFunc, int* pnSharing, int nNumSharing, LPCSTR lpcszFuncName, LPCSTR lpcszCateName, 
							//int nFunc, TreeNode& trInput, DWORD dwSelFuncByTheme) // = 1, true, NULL, 0, NULL, NULL, 0, NULL, 0
/// Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
//bool		NLFitSession::SetFunction(const TreeNode& trFitFunc, int nMultiplicity, bool bResetFunc, int* pnSharing, int nNumSharing, LPCSTR lpcszFuncName, LPCSTR lpcszCateName, 
							//int nFunc, TreeNode& trInput) // = 1, true, NULL, 0, NULL, NULL, 0, NULL
///Kyle 01/15/2009 SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
//bool		NLFitSession::SetFunction(const TreeNode& trFitFunc, int nMultiplicity, bool bResetFunc, LPCSTR lpcszFuncName, LPCSTR lpcszCateName, int nFunc, TreeNode& trInput) // = 1, true, NULL, NULL, 0, NULL
bool		NLFitSession::SetFunction(const TreeNode& trFitFunc, int nMultiplicity, bool bResetFunc, LPCSTR lpcszFuncName, LPCSTR lpcszCateName, int nFunc, TreeNode& trInput, int * pnErrorCode) // = 1, true, NULL, NULL, 0, NULL, NULL
///End SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
/// end SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
{
	///------ Folger 08/06/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	SetLastError(0);
	///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	///Kyle 01/15/2009 SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
	if(pnErrorCode)
		*pnErrorCode = 0;
	///End SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
	if( !trFitFunc )
		return false;		
	
	///Sophy 12/18/2008 v8.0988 SHOW_MESSGAE_WHEN_FDF_FILE_HAS_COMPILE_ERROR
	NumericFunction nf;
	if ( !nf.SetTree(trFitFunc) )
		return false;
	
	bool bNoError = nf.CheckCompileOC();
	if ( !bNoError )
	{
		if ( isMsgLogAvailable() )
		{
			string	strMsg;
			ocu_load_msg_str(NLSF_ERR_COMPILE_NUMERIC_FUNCTION, &strMsg);			
			writeMsgLog(strMsg);
		}
		///------ Folger 08/06/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
		/////Kyle 01/15/2009 SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
		//if(pnErrorCode)
			//*pnErrorCode = NLSF_ERR_COMPILE_NUMERIC_FUNCTION;
		/////End SETFUNCTION_ADD_ARGUMENT_TO_OUTPUT_ERROR_CODE
		SetLastError(NLSF_ERR_COMPILE_NUMERIC_FUNCTION, pnErrorCode);
		///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
		return false;
	}
	///end SHOW_MESSGAE_WHEN_FDF_FILE_HAS_COMPILE_ERROR
	if ( bResetFunc )
		NLFitReset(ONLSF8RESET_ALL, true);
	
	/// Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	if ( nMultiplicity != 1 && !IsAllowReplicas(trFitFunc) )
	{	
		ERR_MSG("Do NOT support replicas, reset to 0.");	
		nMultiplicity = 1;
	}
	/// end KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	
	if ( nMultiplicity > 1 )	
		m_dwParamTypeCtrl |= NLF_PARAM_TYPE_CTRL_REPLICA;	
	else
		m_dwParamTypeCtrl &= ~NLF_PARAM_TYPE_CTRL_REPLICA;
	
	if ( isNeedReinitParamType() )
		InitParamMngr();
	
#ifdef NLF_DEBUG
	if ( NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS != m_pParamMngr->GetType() )
		ASSERT(0 == nFunc);		
#endif //NLF_DEBUG

	string	strCateName(lpcszCateName), strFullPath;
	/// Hong 11/25/08 v8.0979 FO_ONLY_HAVE_FDF_TREE_BUT_NO_FIT_FILE
	//if ( !nlf_get_fdf_filename(lpcszFuncName, &strCateName, NULL, &strFullPath) )
	if ( !nlf_get_fdf_filename(lpcszFuncName, &strCateName, NULL, &strFullPath) && NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS == GetNLParamsMngr()->GetType() )		
	/// end FO_ONLY_HAVE_FDF_TREE_BUT_NO_FIT_FILE	
			return error_report("Fail to get FDF filename!");		
	if ( m_pParamMngr->SetOneFunc(strFullPath, trFitFunc, lpcszFuncName, strCateName, nFunc) )
		return error_report("SetFunction error");
	
	if ( !setNumMultiplicity(nMultiplicity, nFunc) )
		return false;
	
	m_dwNLFitDirtyBits |= NLFIT_DIRTY_FUNCTION;		

#ifdef		__NLFIT_MULTI_DEPS_INDEPS_WEIGHTS__	
	if ( trInput && m_bInitData && NLFIT_GENERAL_XY_FITTING == GetFitType() )
		UpdateInputBranch(trInput);	
#endif		// __NLFIT_MULTI_DEPS_INDEPS_WEIGHTS__
	
	/// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	if ( !m_bInternalSetFunctionByDataChange ) // Function not change, no need reset
		resetSharedCtrl();
	/// end DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	
	m_dwAutoUpdateCtrl |= AUTO_UPDATE_FUNC_CHANGE;	
	//if ( !OnSetFunction(nFunc, dwSelFuncByTheme) )
	///------ Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	//if ( !OnSetFunction(nFunc) ) /// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	if ( !OnSetFunction(nFunc, pnErrorCode) )
	///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
		return false;
	
	return true;
}
/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
//// virtual
//bool		NLFitSession::SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName, int nMultiplicity, bool bResetFunc, int* pnSharing, int nCountSharing, 
								//TreeNode& trInput, DWORD dwSelFuncByTheme, bool bLoadFDF) // = "", 1, true, NULL, 0, NULL, 0, true
/// Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
//// virtual
//bool		NLFitSession::SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName, int nMultiplicity, bool bResetFunc, int* pnSharing, int nCountSharing, 
								//TreeNode& trInput, bool bLoadFDF) // = "", 1, true, NULL, 0, NULL, true
// virtual
///------ Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
//bool		NLFitSession::SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName, int nMultiplicity, bool bResetFunc, TreeNode& trInput, bool bLoadFDF, int nFunc) // = "", 1, true, NULL, true, 0
bool		NLFitSession::SetFunction(LPCSTR lpcszFuncName, LPCSTR lpcszCateName, int nMultiplicity, bool bResetFunc, TreeNode& trInput, bool bLoadFDF, int nFunc, int * pnErrCode/* = NULL*/)
///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
/// end SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
{
	Tree	trFF;
	/// Hong 09/25/08 v8.0947 FIX_FDF_NOT_SET_FAIL_SETFUNCTION_EVEN_TRY_LOADFDF
	//trFF = GetTreeFDF();
	TreeNode	trFDF = GetTreeFDF();
	if ( trFDF )
		trFF = trFDF;
	/// end FIX_FDF_NOT_SET_FAIL_SETFUNCTION_EVEN_TRY_LOADFDF
	string 	strCateName(lpcszCateName);
	if( !getFunctionTree(trFF, lpcszFuncName, strCateName, bLoadFDF) )
		return false;

	//return SetFunction(trFF, nMultiplicity, bResetFunc, pnSharing, nCountSharing, lpcszFuncName, strCateName, 0, trInput, dwSelFuncByTheme);
	/// Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
	//return SetFunction(trFF, nMultiplicity, bResetFunc, pnSharing, nCountSharing, lpcszFuncName, strCateName, 0, trInput); /// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	///------ Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	//return SetFunction(trFF, nMultiplicity, bResetFunc, lpcszFuncName, strCateName, nFunc, trInput);
	return SetFunction(trFF, nMultiplicity, bResetFunc, lpcszFuncName, strCateName, nFunc, trInput, pnErrCode);
	///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	/// end SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
}

///------ Folger 08/12/10 ORG-733-P2 UPDATE_FIT_BUTTONS_AFTER_EDIT_FROM_WIZARD
//bool 		NLFitSession::IsFunctionReady(int nFunc) // = 0
bool 		NLFitSession::IsFunctionReady(int nFunc, BOOL bCheckFDFTreeOnly/* = FALSE*/)
///------ End UPDATE_FIT_BUTTONS_AFTER_EDIT_FROM_WIZARD
{ 
	/// Iris 10/30/2008 v8.0963b CORRECT_ENABLE_FIT_BUTTON_CONDITION, in pa if delete all peaks, fit button still enable, should be disable
	///------ Folger 08/12/10 ORG-733-P2 UPDATE_FIT_BUTTONS_AFTER_EDIT_FROM_WIZARD
	if ( !bCheckFDFTreeOnly )
	///------ End UPDATE_FIT_BUTTONS_AFTER_EDIT_FROM_WIZARD
	{
		if( GetNLParamsMngr()->GetNumFitFunctions() <= 0 )
			return false;
	}
	///end CORRECT_ENABLE_FIT_BUTTON_CONDITION
	
	TreeNode trFF = GetTreeFDF(nFunc);
	if ( trFF && trFF.FirstNode )
		return true;
	
	return false;			
}
///Sophy 10/10/2008 CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
//TreeNode	NLFitSession::GetTreeFDF(int nFunc) // = 0
TreeNode	NLFitSession::GetTreeFDF(int nFunc, bool bGetFilePathInfo ) // = 0, false
///end CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
{	
	/// NLF_81 Sophy 
	//return GetFitFunction(nFunc)->GetFuncTree();
	TreeNode		trFDF;	
	int				nRet = GetNLParamsMngr()->GetFDFTree( trFDF, nFunc );
	/// Hong 11/04/08 QA80-12526 v8.0965b ADD_BACKWARD_COMPATIABLE
	//ASSERT(0 == nRet && trFDF);	
	/// end ADD_BACKWARD_COMPATIABLE
	///Sophy 10/10/2008 CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
	if ( bGetFilePathInfo )
	{
		string strCateName, strFuncName;
		strFuncName = GetFunctionName( &strCateName, nFunc);
		getFunctionTree(trFDF, strFuncName, strCateName, false );
	}
	///end CLEAN_PFW_TREE_MOVE_CODE_FROM_PFM_UTILS
	return trFDF;
	///end NLF_81 Sophy
}

///Kyle 11/05/2008 TO_GET_FDF_TREE_AFTER_MODIFIED
TreeNode 	NLFitSession::GetTreeFDFModified(int nFunc, bool bGetFilePathInfo ) // = 0, false
{
	TreeNode trFDF = GetTreeFDF( nFunc, bGetFilePathInfo);
	
	int nNumParaInFunc = GetNumParameter();
	Tree trCodes;
	GetFittingCodes(trCodes);
	bool bAutoInit = GetAutoInitParams();
	bool bLinearConstraint = IsFDFEnableLinearConstraints();
	SetGUISettingToFDF( trFDF, nNumParaInFunc, trCodes, bAutoInit, bLinearConstraint);

	///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	// unit
	vector<string> vsUnits;
	getParamStringValues( NLPARAMGRIDCOLTYPE_UNIT, vsUnits);
	vsUnits.SetSize(nNumParaInFunc);
	m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_UNIT).strVal = nlf_get_param_unit_list(vsUnits);
	///End ADD_UNIT_FOR_PARAMETER_SETTINGS

	////meaning
	vector<string> vsMeaning;
	getParamStringValues( NLPARAMGRIDCOLTYPE_MEANING, vsMeaning);
	vsMeaning.SetSize(nNumParaInFunc);
	m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_MEANINGS).strVal = nlf_get_param_meaning_list(vsMeaning);

	////Fixed and Value
	vector vParamValues(nNumParaInFunc), vAllParamValues;
	vector<bool> vbFixed(nNumParaInFunc), vbAllFixed;
	bool			bRet = true;
	bRet &= GetParamNumericValues(vAllParamValues, PARMAS_SETTING_VALUES);
	bRet &= GetParamNumericValues(vbAllFixed, PARMAS_SETTING_FIXED);
	vbAllFixed.GetSubVector( vbFixed, 0, nNumParaInFunc -1 );
	vAllParamValues.GetSubVector( vParamValues, 0, nNumParaInFunc -1 );
	m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_INIT_VAL).strVal = nlf_get_param_value_list(vParamValues, vbFixed);

	return trFDF;
}
///End TO_GET_FDF_TREE_AFTER_MODIFIED

void		NLFitSession::SetTreeFDF(const TreeNode& trFDF, int nFunc) // = 0
{
	/// NLF_81 Iris 
	//GetFitFunction(nFunc)->SetFuncTree(trFDF);
	GetNLParamsMngr()->SetFDFTree(trFDF);		
	///end NLF_81
}

string		NLFitSession::GetFunctionName(string* pCategoryName, int nFunc) // = NULL, 0
{	
	string		strFuncName;
	GetNLParamsMngr()->GetFuncName(strFuncName, pCategoryName, nFunc);	
	return strFuncName;
}

/// Hong 23/05/08 v8.0869 ADD_FIT_FUNC_FILENAME_AND_DESCRIPTION
string		NLFitSession::GetFunctionDescription(int nFunc) // = 0
{
	string		strDescription;
	TreeNode	trDescription = m_NFO.GetGeneralInfo(GetTreeFDF(), false, STR_FUNC_DESCRIPTION);
	if ( trDescription )
		strDescription = trDescription.strVal;
	
	return strDescription;
}
/// end ADD_FIT_FUNC_FILENAME_AND_DESCRIPTION

int			NLFitSession::SetFunctionList(const TreeNode& trFunctionList)
{
	int 	nNumFuncSet = 0;
	if ( trFunctionList && trFunctionList.FunctionList )
	{
		string		strFunctionList;
		if ( trFunctionList.GetAttribute(STR_COMBO_ATTRIB, strFunctionList) )
		{
			strFunctionList.GetTokens(m_vsFunctionList, '|');
			nNumFuncSet = m_vsFunctionList.GetSize();
		}
	}
		
	return nNumFuncSet;
}

DWORD 		NLFitSession::GetDataRules()
{
	DWORD dwRules; 
	if(NLFIT_GENERAL_XY_FITTING != GetFitType())
		dwRules = DRR_GET_Z_DEPENDENT;
	else
	{
		dwRules = DRR_NO_FACTORS | DRR_GET_DEPENDENT | DRR_RAW_ERR_WEIGHT;
	#ifdef		__NLFIT_MULTI_DEPS_INDEPS_WEIGHTS__
		dwRules |= DRR_NLFIT;
	#endif		// __NLFIT_MULTI_DEPS_INDEPS_WEIGHTS__
	}
	
	return dwRules;			
}

/// Iris NLF_81, need to call this when Plot Type changed in NLFSplitter
void		NLFitSession::SetAveType(int nType)
{
	m_nAveType = nType;
}

// Iris, also want to get concatenate data in Operation(FitNL), so keep concatenate data wks in session
DataRange NLFitSession::getConcatenateDataRange()
{
	return m_bAveSrcData? m_drConcatenateSrcData : m_drAveData;
}

void		NLFitSession::prepareConcatenateDataRange()
{	
	if( !m_wksConcatenate.IsValid() )
	{
		m_wksConcatenate.Create(NULL, CREATE_HIDDEN | CREATE_SET_MISSING_IN_MANAGER);
		m_wksConcatenate.SetSize(-1, COL_CONCATENATE_COUNT); // ConcatenateX, ConcatenateY, AveX, AveY, AveYErr, if average type is raw data, only first two columns have data
		m_wksConcatenate.SetColDesignations("XYXYE");
	}
	
	if(m_drConcatenateSrcData.IsValid())
		m_drConcatenateSrcData.Reset();
	m_drConcatenateSrcData.Add("X", m_wksConcatenate, 0, COL_CONCATENATE_X , -1, COL_CONCATENATE_X);
	m_drConcatenateSrcData.Add("Y", m_wksConcatenate, 0, COL_CONCATENATE_Y , -1,COL_CONCATENATE_Y);
	m_wksConcatenate.Columns( COL_CONCATENATE_Y ).SetLongName(_L("Concatenate data"));	
	
	if( !m_bAveSrcData )
	{		
		while(m_wksConcatenate.GetNumCols() < COL_CONCATENATE_COUNT)
			m_wksConcatenate.AddCol();
		m_wksConcatenate.SetColDesignations("XYXYE");
		
		if(m_drAveData.IsValid())
			m_drAveData.Reset();
		m_drAveData.Add("X", m_wksConcatenate, 0, COL_AVE_X , -1, COL_AVE_X);
		m_drAveData.Add("Y", m_wksConcatenate, 0, COL_AVE_Y , -1, COL_AVE_Y);
		m_drAveData.Add("ED", m_wksConcatenate, 0, COL_AVE_YERR , -1, COL_AVE_YERR);
		
		string strAveLegend = m_nAveType == PLOT_TYPE_MEAN_SE ? _L("Mean, SE") : _L("Mean, SD");
		m_wksConcatenate.Columns( COL_AVE_Y ).SetLongName(strAveLegend);
	}
	else
	{
		while(m_wksConcatenate.GetNumCols() > 2)
			m_wksConcatenate.DeleteCol(m_wksConcatenate.GetNumCols() - 1);
	}		
}

bool		NLFitSession::calcConcatenateAveData()
{
	int		nNumData = m_drSrcData.GetNumData(GetDataRules());
	if(nNumData <= 0)
		return false;

	DWORD	dwPlotID;
	vector 	vConcatenateX, vConcatenateY;
	if(m_drSrcData.GetData(DRR_COMBINED_SIMPLE | DRR_GET_DEPENDENT, 0, &dwPlotID, NULL, &vConcatenateY, &vConcatenateX) < 0)
		return false;
	
	ASSERT(m_drConcatenateSrcData); // should already prepare this data range in prepareConcatenateDataRange
	m_drConcatenateSrcData.SetData(&vConcatenateY, &vConcatenateX);
	
	
	if( !m_bAveSrcData )
	{
		ASSERT(m_drAveData); // should already prepare this data range in prepareConcatenateDataRange
	
		vector 	vAveX, vAveY, vAveErr;
		int		nAveSize = vConcatenateX.GetSize(); // ave size can be modified
		if(!nlsf_calc_ave_data(vConcatenateX, vConcatenateY, nAveSize, vAveX, vAveY, vAveErr, m_nAveType))
			return error_report("Fail to calculate ave data in NLFitSession::calcConcatenateAveData");
		
		m_drAveData.SetData(&vAveY, &vAveX);
		Dataset ds(m_wksConcatenate.Columns(COL_AVE_YERR));
		ds = vAveErr;			
	}	
	
	return true;
}
///end NLF_81

/// Hong 10/16/08 v8.0956 FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
//bool		NLFitSession::SetData(TreeNode& trInputData, const TreeNode& trWTMethods, DWORD dwCntrlOnSetData, DWORD dwUpdateFromTheme) // = NULL, 0, 0
bool		NLFitSession::SetData(TreeNode& trInputData, const TreeNode& trWTMethods/* = NULL*/, DWORD dwCntrlOnSetData/* = 0*/, DWORD dwUpdateFromTheme/* = 0*/, bool bUpdateDataOnly/* = false*/)
/// end FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
{
	/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	///// Hong 11/06/08 v8.0966c FIX_BTN_NOT_DISABLED_WHEN_RESET_INPUT_DATA
	//m_pDataObj->Reset();
	ResetDataObjHelper		resetDataObj(m_pDataObj, &m_nBackupOldNumDataset);
	///// end FIX_BTN_NOT_DISABLED_WHEN_RESET_INPUT_DATA
	
	/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	
	/// Hong 10/16/08 v8.0956 FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
	//NLFitReset(ONLSF8RESET_DATA, true);
	if ( !bUpdateDataOnly ) 
		NLFitReset(ONLSF8RESET_DATA, true);
	else
		ASSERT( NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS == getParamsType() );
	/// end FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
		
	bool bRet = okutil_is_fitter_data_node_ready(&trInputData);
	//SetNonePreview(!bRet); /// Iris NLF_81, to do
	if ( !bRet )	
		return error_report("Input Tree Not Ready for NLFit.");

	trInputData.SetAttribute(STR_ATTRIB_FIT_TYPE, m_nFitType);	/// Iris NLF_81, only _event1 used this attribute, shoulde remove STR_ATTRIB_FIT_TYPE this later
	
	//----- CPY 2/6/2008 QA70-11061 FDF_OC_CODE_NEED_ACCESS_TO_INPUT_DATA_INFO
	Project.AddTree(LTTREE_LAST_NL_INPUT, trInputData);	
	//----- end

	IntArray vnWeightMethods;
	DoubleArray vrAs, vrBs, vrCs;
	if ( !nlsf_init_datarange(m_drSrcData, trInputData, &vnWeightMethods, &vrAs, &vrBs, &vrCs) )
		return error_report("Invalid input Range for NLFit.");	
	
	int			nDeps, nIndeps;
	if ( !GetNumVars(&nDeps, &nIndeps) )
	{
		resetDataObj.SetFunctionNotReady(); /// Hong 12/30/08 QA80-12878 v8.0992 FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
		return FALSE;
	}

	const DWORD		dwRules = GetDataRules();
	DataRange dr;
	dr = m_drSrcData;

	m_bAveSrcData = false;
	m_bConcatenateSrcData = false;	
	
	//int 			nDataMode = INVALID_DATA_MODE; /// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	int				nDataMode = DATA_MODE_INDEP_CONSOLID;
	if ( trInputData.GetAttribute(STR_USE_ATTRIB, nDataMode) && DATA_MODE_CONCATENATE == nDataMode )
	{
		ASSERT( 1 == nDeps && 1 == nIndeps );
		m_bConcatenateSrcData = true;
		m_bAveSrcData = m_nAveType == PLOT_TYPE_RAW_DATA;
		
		prepareConcatenateDataRange();
		///Sophy 11/4/208 UPDATE_CONCATENATE_SOURCE_PLOT_UID_AS_TO_REPORT_FITCURVE_ON_SRC_GRAPH
		DWORD	dwPlotUID = 0;
		vector	vDeps, vIndeps, vWeightData;

		m_drSrcData.GetNLFitData( dwRules, 0, &dwPlotUID, nDeps, &vDeps, nIndeps, &vIndeps, &vWeightData );
		GraphLayer glSource;
		if( get_graph_layer_by_plot_uid( glSource, dwPlotUID ) )
		{
			m_dwSrcPlotUIDConcatenate = dwPlotUID;
		}
		///end UPDATE_CONCATENATE_SOURCE_PLOT_UID_AS_TO_REPORT_FITCURVE_ON_SRC_GRAPH
		calcConcatenateAveData();
		/// Hong 10/23/08 V8.0960 FIX_CONCATENATE_FIT_REPORT_FAIL_CORRECTLY_GENERATE_FIT_CURVE_DATA
		//dr = getConcatenateDataRange();
		dr = m_drConcatenateSrcData;
		/// end FIX_CONCATENATE_FIT_REPORT_FAIL_CORRECTLY_GENERATE_FIT_CURVE_DATA
	}	
	
	/// Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
	//---- Iris 11/12/2008 v8.0969 QA80-12584 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP, if GetSubtractedMode() is ture, m_drBaseline will be invalid before, now it is valid, but see m_drBaseline is valid as condition not obvious.
	//if( m_drBaseline ) 
	/// Iris 11/14/2008 v8.0971b QA80-12584 FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
	//if( HasBaseline() && !GetSubtractedMode() && !GetBaselineFitMode() )
	if( HasBaseline() && !GetBaselineFitMode() )
	///end FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
	//----
	{
		/// Iris 11/14/2008 v8.0971b QA80-12584 FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
		//if( !m_drPeaks )  
		if( !m_drSubtracted )
		///END FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
		{
			ASSERT(false); // subtracted peaks range should already get from PAWizCore and prepare in PeakFitHelper
			prepareSubtractedDataRange();
		}	
		/// Iris 11/14/2008 v8.0971b QA80-12584 FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
		//if( m_drPeaks )
		//	dr = m_drPeaks;
		if( m_drSubtracted )
			dr = m_drSubtracted;
		///END FITPEAK_OP_OUTPUT_SUBTRACTED_REPLACE_BASELINE_XF_OUTPUT_SUBTRACTED
		else
			error_report("NLFitSession::SetData Fail to get subtracted data range from m_drSubtracted");
	}
	///end PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION

	int			nNumData = dr.GetNumData(dwRules);
	if ( nNumData < 0 )
	{
		string strErr = "NLFitSessionBase::SetData GetNumData error: "+ nNumData;
		return error_report(strErr);
	}
	
#ifdef	NLF_DEBUG
	if ( vnWeightMethods.GetSize() > 0 )
		ASSERT( nNumData == vnWeightMethods.GetSize() ); // Hong, This assert will be fired in DATA_MODE_CONCATENATE fit mode, maybe need improve to avoid it
#endif	//NLF_DEBUG
	
	//------ Folger 07/11/08 FIX_PARAMETER_INITIALIZATION_FAIL_FOR_FIT_MODE_CHANGE
	////------ Folger 08/09/08 QA80-11816 SUPPORT_AUTO_PARAMETER_INITIALIZATION_FOR_MULTIPLE_INDEPENDNTS_AND_MULTIPLE_DEPENDENTS
	////m_nOldNumberDataset = dwUpdateFromTheme ? 0 : m_nNumberDataset;
	//m_nOldNumberDataset = dwUpdateFromTheme || dwCntrlOnSetData & OSD_FUNC_CHANGE_THEN_SET_DATA ? 0 : m_nNumberDataset;
	////------
	/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	//m_nOldNumberDataset = dwUpdateFromTheme || dwCntrlOnSetData & OSD_FUNC_CHANGE_THEN_SET_DATA || dwCntrlOnSetData & OSD_DATA_CHANGE_BY_FIT_MODE ? 0 : GetNumDataset();
	if ( dwUpdateFromTheme || dwCntrlOnSetData & OSD_FUNC_CHANGE_THEN_SET_DATA || dwCntrlOnSetData & OSD_DATA_CHANGE_BY_FIT_MODE )
		m_nOldNumberDataset = 0;
	else
	{
		if ( m_nBackupOldNumDataset <= 0 )
			m_nOldNumberDataset = GetNumDataset();
		else
			m_nOldNumberDataset = m_nBackupOldNumDataset;
	}
	/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	//------ End FIX_PARAMETER_INITIALIZATION_FAIL_FOR_FIT_MODE_CHANGE
	
	if ( nNumData > 1 || nDeps > 1 || nIndeps > 1 )
	{
		/// Hong 08/14/08 v8.0922 FIX_MATRIX_FIT_FAIL_DO_REDUCE
		//if ( NLFIT_GENERAL_XY_FITTING != GetFitType() )
			//m_nlfDataType = DATA_TYPE_SURFACE;
		//else
			//m_nlfDataType = DATA_TYPE_MULTI_SET;
		switch ( GetFitType() )
		{
		case NLFIT_XYZ_FITTING:
			m_nlfDataType = DATA_TYPE_SURFACE;
			break;
		case NLFIT_MATRIX_FITTING:
			m_nlfDataType = DATA_TYPE_MATRIX;
			break;
		case NLFIT_GENERAL_XY_FITTING:
		default:
			m_nlfDataType = DATA_TYPE_MULTI_SET;
			break;
		}
		/// end FIX_MATRIX_FIT_FAIL_DO_REDUCE
	}
	else
		m_nlfDataType = DATA_TYPE_SINGLE_SET;
	
	/// Hong 10/16/08 v8.0956 FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
	if ( !bUpdateDataOnly )
	onInitDataObject(); // Hong, to do, check if need mechanism as Parameter manager for check whether need reinit
	/// end FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
	/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	///// Hong 11/06/08 v8.0966c FIX_BTN_NOT_DISABLED_WHEN_RESET_INPUT_DATA
	////m_pDataObj->Reset();	
	///// end FIX_BTN_NOT_DISABLED_WHEN_RESET_INPUT_DATA
	m_pDataObj->Reset();
	resetDataObj.SetHasReset();
	/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE

	for (int ii = 0; ii < nNumData; ii++)
	{
		DWORD			dwPlotUID = 0;
		Worksheet		wksData;
		/// Hong 06/17/08 v8.0886 REFACTORING_ORTHOGONALITY
		//int				ndepOffset = ii * nDeps;
		//int				nindepOffset = ii * nIndeps;
		//int 			nn = m_pDataObj->SetData(m_drSrcData, dwRules, 0, &dwPlotUID, nDeps, nIndeps, ndepOffset, nindepOffset, &wksData);
		if ( m_pDataObj->SetData(dr, dwRules, ii, &dwPlotUID, nDeps, nIndeps, ii, &wksData) < 0 )
		/// end REFACTORING_ORTHOGONALITY
		{
			/// Hong 09/26/08 QA80-12063 ONLY_SINGLE_DEP_INDEP_CAN_PREVIEW_IN_SRC_PAGE
			// i see in case of multiple deps&indeps, single dataplot from source graph make this ASSERT fired, but i still don't know how to handle it			
			if ( nNumData > 1 ) /// Hong 10/13/08 QA80-10624 NLFIT_ONLY_SUPPORT_POLAR_PLOT_WITH_THETA_AS_X
				ASSERT(FALSE); // Hong, I think, this error should not appear, otherwise the result will be unexpected and user unknown
			/// end ONLY_SINGLE_DEP_INDEP_CAN_PREVIEW_IN_SRC_PAGE
			error_report("Some subrange fail to set data.");
			continue;
		}
		
		///------ Folger 08/17/10 ORG-824-P1 WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
		//if ( vnWeightMethods.GetSize() > 0 && ii < vnWeightMethods.GetSize() )
		//{
			//if ( !m_pDataObj->SetWeightData(vnWeightMethods[ii], vrAs[ii], vrBs[ii], vrCs[ii], ii) )
			//{
				//if ( nNumData > 1 ) /// Hong 10/13/08 QA80-10624 NLFIT_ONLY_SUPPORT_POLAR_PLOT_WITH_THETA_AS_X
					//ASSERT(FALSE);
				//error_report("Data weight fail to set.");
				//continue;
			//}
		//}
		BOOL	bSetDataWeightFailed = FALSE;
		for ( int jj=0; jj<nDeps; ++jj )
		{
			int		nIndex = ii * nDeps + jj;
			if ( vnWeightMethods.GetSize() > 0 && nIndex < vnWeightMethods.GetSize() )
			{
				if ( !m_pDataObj->SetWeightData(vnWeightMethods[nIndex], vrAs[nIndex], vrBs[nIndex], vrCs[nIndex], ii, jj) )
				{
					if ( nNumData > 1 )
						ASSERT(FALSE);
					error_report("Data weight fail to set.");
					bSetDataWeightFailed = TRUE;
					break;
				}
			}
		}
		if ( bSetDataWeightFailed )
			continue;
		///------ End WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
		
		/// Iris NLF_81, move logic of setSrcXFromAndTo to NLFCurvesBase, and NLFitSession will never take care preview things
		/* 
		vector vIndepData;
		//vIndepData = m_vIndependentData[nindepOffset];
		m_pNLFData->GetIndependData(vIndepData, nindepOffset);
		bool bInit = false;
		if(ii == 0)
			bInit = true;
		setSrcXFromAndTo(glSource, vIndepData, bInit); 
		OnGetOneData(ii, dr, dwPlotUID, nDataMode);
		*/
		///end NLF_81
	}
		
	if ( m_nOldNumberDataset > GetNumDataset() )
		m_nOldNumberDataset = 0;
	
	/// Hong 10/16/08 v8.0956 FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
	if ( bUpdateDataOnly )
	{
		ASSERT( m_nOldNumberDataset == GetNumDataset() );
		return TRUE;
	}
	/// end FIX_PA_DO_FIT_AGAIN_EVEN_CONVERGE
	
	/// Hong 09/16/08 v8.0940 FIX_MULTI_DATASEST_FAIL_RESET_PARAMS_SIZE_WHEN_DECREASE_DATASET_NUM
	GetNLParamsMngr()->SetNumDatasets(GetNumDataset());
	/// end FIX_MULTI_DATASEST_FAIL_RESET_PARAMS_SIZE_WHEN_DECREASE_DATASET_NUM

	m_dwNLFitDirtyBits |= NLFIT_DIRTY_DATA;
	
	/// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	int 			nOldDataMode = INVALID_DATA_MODE;
	trInputData.GetAttribute(STR_ATTRIB_OLD_DATA_MODE, nOldDataMode);
	m_nCurrDataMode = nDataMode; /// Hong 09/02/08 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	updateSharedCtrl(nDataMode, nOldDataMode);	
	/// Hong 12/24/08 QA80-10499 v8.0990c DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
	//checkUpdateSharedParamBySharedCtrl(true);
	bool			bForceResetShareIfNone = (OSD_THEME_CHANGE_FACTORY_DEFAULT & dwCntrlOnSetData);
	checkUpdateSharedParamBySharedCtrl(true, bForceResetShareIfNone);
	/// end DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
	/// end DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION

	///------ Folger 09/18/09 QA80-14333 RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF
	if ( OSD_THEME_CHANGE_FACTORY_DEFAULT & dwCntrlOnSetData )
		resetParamsFromFDF(NLPARAMETERSETTINGS_VALUE, TRUE);
	///------ End RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF

	///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
	//OnSetData();	
	OnSetData( nOldDataMode, nDataMode );	
	///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS

	/// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	/// Hong 12/24/08 QA80-10499 v8.0990c DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
	//checkUpdateSharedParamBySharedCtrl(false);
	checkUpdateSharedParamBySharedCtrl(false, bForceResetShareIfNone);
	/// end DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
	/// end DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
	validateParams("SetData");
	
	/// Hong 10/13/08 QA80-10624 NLFIT_ONLY_SUPPORT_POLAR_PLOT_WITH_THETA_AS_X
	//return TRUE;
	return GetNumDataset() > 0 ? TRUE : FALSE;
	/// end NLFIT_ONLY_SUPPORT_POLAR_PLOT_WITH_THETA_AS_X
}

/// Hong 11/04/08 QA80-12526 v8.0965b ADD_BACKWARD_COMPATIABLE
///Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
//bool		NLFitSession::SetData(const vector& vY, const vector& vX, const vector& vZ/* = NULL*/, int nIndex/* = 0*/, int nNumTotalDataset/* = 1*/)
#ifndef	EXTEND_INTERFACES_OF_NLFITSESSION
bool		NLFitSession::SetData(const vector& vY, const vector& vX, const vector& vZ/* = NULL*/, int nIndex/* = 0*/, int nNumTotalDataset/* = 1*/)
#else
bool		NLFitSession::SetData(const vector& vY, const vector& vX, const vector& vZ/* = NULL*/, int nIndex/* = 0*/, int nNumTotalDataset/* = 1*/, int nDataMode/* = INVALID_DATA_MODE*/, const vector& vW/* = NULL*/)
#endif	//EXTEND_INTERFACES_OF_NLFITSESSION
///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
{	
	if ( NULL != vZ && nNumTotalDataset > 1 )
	{
		return error_report("surface fit do NOT support multiple dataset!");
	}
	
	int			nDeps, nIndeps;
	if ( !GetNumVars(&nDeps, &nIndeps) )
		return FALSE;
	
	int			nOldDataType = getDataType();
	if ( nNumTotalDataset > 1 || nDeps > 1 || nIndeps > 1 )
	{
		switch ( GetFitType() )
		{
		case NLFIT_XYZ_FITTING:
			m_nlfDataType = DATA_TYPE_SURFACE;
			break;
		case NLFIT_MATRIX_FITTING:
			m_nlfDataType = DATA_TYPE_MATRIX;
			break;
		case NLFIT_GENERAL_XY_FITTING:
		default:
			m_nlfDataType = DATA_TYPE_MULTI_SET;
			break;
		}
	}
	else
		m_nlfDataType = DATA_TYPE_SINGLE_SET;
	
	if ( nOldDataType != getDataType() )
	{
		onInitDataObject();
		m_pDataObj->Reset();
	}
	
	///Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	//if ( m_pDataObj->SetData(vX, vY, vZ, nIndex, nDeps, nIndeps, nNumTotalDataset) < 0 )
#ifndef	EXTEND_INTERFACES_OF_NLFITSESSION
	if ( m_pDataObj->SetData(vX, vY, vZ, nIndex, nDeps, nIndeps, nNumTotalDataset) < 0 )
#else
	if ( m_pDataObj->SetData(vX, vY, vZ, nIndex, nDeps, nIndeps, nNumTotalDataset, vW) < 0 )
#endif	//EXTEND_INTERFACES_OF_NLFITSESSION
	///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
		return false;
	
	GetNLParamsMngr()->SetNumDatasets(GetNumDataset());
	m_dwNLFitDirtyBits |= NLFIT_DIRTY_DATA;
	///Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	//OnSetData();
#ifndef	EXTEND_INTERFACES_OF_NLFITSESSION
	OnSetData();
#else	//EXTEND_INTERFACES_OF_NLFITSESSION defined
	if ( nDataMode != INVALID_DATA_MODE )
	{
		int nOldDataMode = m_nCurrDataMode;
		m_nCurrDataMode = nDataMode;
		updateSharedCtrl(nDataMode, nOldDataMode);
		OnSetData(nOldDataMode, nDataMode);
	}
	else
		OnSetData();
#endif	//EXTEND_INTERFACES_OF_NLFITSESSION
	///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	validateParams("SetData");
	
	return GetNumDataset() > 0 ? TRUE : FALSE;
}
/// end ADD_BACKWARD_COMPATIABLE

bool		NLFitSession::GetNumVars(int *pnDeps, int *pnIndeps, StringArray *pvstrDepVarNames, StringArray *pvstrIndepVarNames) // = NULL, NULL
{	
	int			numDeps = m_pParamMngr->GetNumVariables(true, pvstrDepVarNames);
	int			numIndeps = m_pParamMngr->GetNumVariables(false, pvstrIndepVarNames);	
	if ( numIndeps <= 0 || numDeps <= 0 )	// not yet set?
		return error_report("Fitting function not set yet!");
	
	if ( pnDeps )
		*pnDeps = numDeps;
	if ( pnIndeps )
		*pnIndeps = numIndeps;
	
#ifdef	NLF_DEBUG
	switch ( GetFitType() )
	{
	case NLFIT_GENERAL_XY_FITTING:
		///Sophy , support multi dataset indep&deps
		//ASSERT(1 == numDeps);
		//ASSERT(1 == numIndeps);
		///----
		break;
	case NLFIT_XYZ_FITTING:
	case NLFIT_MATRIX_FITTING:
		ASSERT(1 == numDeps);
		ASSERT(2 == numIndeps);
		break;
	default:
		ASSERT(FALSE);
		break;
	}
#endif	//NLF_DEBUG

	return true;
}

bool		NLFitSession::SetInitData(BOOL bSet)
{
	bool	bPrev = m_bInitData;
	m_bInitData = bSet;
	return bPrev;
}

bool		NLFitSession::GetOneWeight(int nIndex, int iDep, int& nMethod, double& rA, double& rB, double& rC)
{
	int		nDeps;
	if ( !GetNumVars(&nDeps, NULL) )
		return FALSE;
	/// Hong 06/07/09 QA80-13873 FIX_CONCATENATE_FIT_WEIGHT_METHOD_IN_REPORT_NOT_CORRECT_EXCEPT_FIRST_DATASET
	// Hong, for concatenate fit, only one dataset when fitting, so only support one data mode
	if ( DATA_MODE_CONCATENATE == m_nCurrDataMode )
		nIndex = 0;
	/// end FIX_CONCATENATE_FIT_WEIGHT_METHOD_IN_REPORT_NOT_CORRECT_EXCEPT_FIRST_DATASET
	int		nDatasetIdx = nIndex * nDeps + iDep;
	///Sophy 1/19/2009 v8.0960 FIX_USE_SAME_WEIGHT_METHOD_FOR_ALL_DATASETS
	//if ( m_pDataObj->IsExceedLimitation(nDatasetIdx) )
	if ( m_pDataObj->IsExceedLimitation(nIndex, iDep) )
	///end FIX_USE_SAME_WEIGHT_METHOD_FOR_ALL_DATASETS
		return FALSE;
	
	PONEDATAWEIGHT	pOneDataWeight = m_pDataObj->GetWeightDatas();
	if ( !pOneDataWeight )
		return FALSE;
	
	nMethod = pOneDataWeight[nDatasetIdx].method;
	rA = pOneDataWeight[nDatasetIdx].a;
	rB = pOneDataWeight[nDatasetIdx].b;
	rC = pOneDataWeight[nDatasetIdx].c;
	
	return TRUE;
}

///Sophy 9/16/2008 CLEAN_NLFSPLITTER_FOR_81
bool		NLFitSession::GetSrcXMinMax(double& dxMin, double& dxMax )
{
	///Sophy 1/12/2009 v8.0995c QA80-12613-P3 FIX_NLFIT_SHOW_WRONG_CUSTOMIZED_Y_MIN_MAX_ON_SURFACEFIT
	//return GetDataObject()->GetXMinMax( dxMin, dxMax );
	return GetDataObject()->GetIndepMinMax( dxMin, dxMax ); //always get the first dataest's data
	///end FIX_NLFIT_SHOW_WRONG_CUSTOMIZED_Y_MIN_MAX_ON_SURFACEFIT
}

bool		NLFitSession::GetSrcYMinMax(double& dyMin, double& dyMax )
{
	///Sophy 1/12/2009 v8.0995c QA80-12613-P3 FIX_NLFIT_SHOW_WRONG_CUSTOMIZED_Y_MIN_MAX_ON_SURFACEFIT
	//return GetDataObject()->GetYMinMax( dyMin, dyMax );
	if ( NLFIT_GENERAL_XY_FITTING == GetFitType() )
		return GetDataObject()->GetDepMinMax( dyMin, dyMax );
	else
		return GetDataObject()->GetIndepMinMax( dyMin, dyMax, 0, 1 ); //always get the first dataset, Y is independent data and IndepIndex is 1 for XYZ fitting
	///end FIX_NLFIT_SHOW_WRONG_CUSTOMIZED_Y_MIN_MAX_ON_SURFACEFIT
}

void 		NLFitSession::UpdateXDataMinMaxByAuto(TreeNode& trXDataType)
{
	int nMinAuto = 0, nMaxAuto = 0;
	TreeNode trXMin = trXDataType.Min;
	TreeNode trXMax = trXDataType.Max;
	if(trXMin)
		nMinAuto = octree_get_auto_support(&trXMin);
	
	if(trXMax)
		nMaxAuto = octree_get_auto_support(&trXMax);
	
	double dxMin, dxMax;
	if(GetSrcXMinMax(dxMin, dxMax))
	{
		if(nMinAuto == 1)
			trXMin.dVal = dxMin;
		if(nMaxAuto == 1)
			trXMax.dVal = dxMax;
	}
}

void 		NLFitSession::UpdateYDataMinMaxByAuto(TreeNode& trYDataType)
{
	int nMinAuto, nMaxAuto;
	TreeNode trYMin = trYDataType.Min;
	TreeNode trYMax = trYDataType.Max;
	if(trYMin)
		nMinAuto = octree_get_auto_support(&trYMin);
	
	if(trYMax)
		nMaxAuto = octree_get_auto_support(&trYMax);
	
	double dyMin, dyMax;
	if(GetSrcYMinMax(dyMin, dyMax))
	{
		if(nMinAuto == 1)
			trYMin.dVal = dyMin;
		if(nMaxAuto == 1)
			trYMax.dVal = dyMax;
	}
}

///end CLEAN_NLFSPLITTER_FOR_81
bool		NLFitSession::GetInputData(vector& vx, vector& vy, vector& vz, int nDatasetIndex, vector* pvWeights)
{
	/// Hong 06/17/08 v8.0886 REFACTORING_ORTHOGONALITY
	/*
	if ( !vz )
	{	
		if ( !m_pDataObj->GetIndependData(vx, nDatasetIndex) )
			return false;
		m_pDataObj->GetDependData(vy, nDatasetIndex);
		if ( NULL != pvWeights )
		{
			vector		vWeights;
			m_pDataObj->GetWeightData(vWeights, nDatasetIndex);
			*pvWeights = vWeights;
		}
	}
	else
	{	
		if ( !m_pDataObj->GetIndependData(vx, nDatasetIndex * 2) )
			return false;
		if ( !m_pDataObj->GetIndependData(vy, nDatasetIndex * 2 + 1) )
			return false;		
		m_pDataObj->GetDependData(vz, nDatasetIndex);
	}
	*/
	int			nNumDeps, nNumIndeps;
	if ( !GetNumVars(&nNumDeps, &nNumIndeps) )
		return false;
	
	if ( 1 == nNumDeps && 1 == nNumIndeps )
	{
		if ( !GetInputData(vx, false, nDatasetIndex) || !GetInputData(vy, true, nDatasetIndex) )
			return false;
		if ( pvWeights )
			m_pDataObj->GetWeightData(*pvWeights, nDatasetIndex);
	}
	else if ( 1 == nNumDeps && 2 == nNumIndeps )
	{
		// Hong, to do, we assume second one is Y axis for 2D case from input datarange, but i fail to ASSERT this assumption by code
		if ( !GetInputData(vx, false, nDatasetIndex) || !GetInputData(vy, false, nDatasetIndex, 1) )
			return false;
		if ( vz )
		{
			if ( !GetInputData(vz, true, nDatasetIndex) )
				return false;
		}
	}
	else
	{
		ASSERT(FALSE);
		return error_report("Don't support multiple XYs.");
	}
	/// end REFACTORING_ORTHOGONALITY
	return true;
}
///Sophy 10/13/2008 QA80-12365 FIX_FAIL_TO_REPORT_RESIDUAL_IN_MATRIX_FIT moved to NLFCurvesBase
/*
bool	NLFitSession::GetMatResidualData(matrix& matResidual, int& nRows, int& nCols, double& dXmin, double& dYmin, double& dXmax, double& dYmax)
{
	vector 	vResidual, vX, vY;
	if( !GetResidualData(vResidual, 0, vX, vY) )
		return error_report("Fail to get residual data for surface fitting");
	
	//examine data and do the conversion if data are regular
	double dXStep, dYStep;
	ocmath_xyz_examine_data(vX.GetSize(), vX, vY, vResidual, 1.0e-8, NULL, &dXmin, 
				&dXStep, &dXmax, &dYmin, &dYStep, &dYmax);
	
	vector mat;		
	nCols = dXStep > 0 ? (int)((dXmax - dXmin) / dXStep + 0.5) + 1 : 1; 
	nRows = dYStep > 0 ? (int)((dYmax - dYmin) / dYStep + 0.5) + 1 : 1; 
	mat.SetSize(nRows * nCols); // nRows*nCols = nVar, for regular
	if(ocmath_convert_regular_xyz_to_matrix(vX.GetSize(), vX, vY, vResidual,
				mat, dXmin, dXStep, nCols, dYmin, dYStep, nRows) != OE_NOERROR)
		return false;
	
	matResidual.SetSize(nRows, nCols);
	matResidual.SetByVector(mat);
	return true;
}
*/
///end FIX_FAIL_TO_REPORT_RESIDUAL_IN_MATRIX_FIT
	
bool	NLFitSession::GetSrcSubDataRange(DataRange& drSub, int nDatasetIndex, int iDep, int iIndep)//= 0, = 0, = 0
{
	if( m_bConcatenateSrcData )
	{
		drSub = getConcatenateDataRange();
		return true;
	}
	
	DataRange dr;
	dr = GetSrcDataRange();
	
	if ( !dr.GetNLFitSubRange(drSub, DRR_NLFIT, nDatasetIndex, iDep, iIndep) || !drSub )
		return false;		
		
	return true;
}

bool	NLFitSession::GetInputData(matrix& mXs, matrix& mYs, int nDataIndex)
{
	int		nNumDeps, nNumIndeps;
	if ( !GetNumVars(&nNumDeps, &nNumIndeps) )
		return false;
	
	for ( int nIndepIndex = 0; nIndepIndex < nNumIndeps; nIndepIndex++ )
	{
		vector vx;
		if ( GetInputData(vx, false, nDataIndex, nIndepIndex) && vx.GetSize() > 0 )
		{
			mXs.SetSize(vx.GetSize(), nNumIndeps);
			mXs.SetColumn(vx, nIndepIndex);
		}
	}
	
	for ( int nDepIndex = 0; nDepIndex < nNumDeps; nDepIndex++ )
	{
		vector vy;
		if ( GetInputData(vy, true, nDataIndex, nDepIndex) && vy.GetSize() > 0 )
		{
			mYs.SetSize(vy.GetSize(), nNumDeps);
			mYs.SetColumn(vy, nDepIndex);
		}		
	}
	
	///Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
	///Sophy 11/25/2008 v8.979 QA80-12106 FIX_HISTOGRAM_RESIDUAL_PLOT_IN_NLFIT_BECAME_EMPTY_WIHT_MUILTI_INDEP_VARS
	//mXs.SetSize( mXs.GetNumRows(), (uint)nNumDeps );
	//mYs.SetSize( mYs.GetNumRows(), (uint)nNumIndeps );
	mXs.SetSize(mXs.GetNumRows(), (uint)nNumIndeps);
	mYs.SetSize(mYs.GetNumRows(), (uint)nNumDeps);	
	///end FIX_HISTOGRAM_RESIDUAL_PLOT_IN_NLFIT_BECAME_EMPTY_WIHT_MUILTI_INDEP_VARS
	///end IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
	return true;
}

GraphPage   NLFitSession::GetSrcGraphPage()
{
	GraphPage 		pg;
	GraphLayer 		gl;
	if( GetSourceGraphLayer(gl) )
	{
		pg = gl.GetPage();
	}
	return pg; 
}

bool 		NLFitSession::UpdateResidualContourLevels(GraphLayer& gl)
{
	/// NLF_81 Iris
	/*
	if ( !m_pNLFitPreviewCtrl )
		return false;
	return m_pNLFitPreviewCtrl->UpdateResidualContourLevels(gl);
	*/
	_NLF_81(UpdateResidualContourLevels);
	return false;
	///end NLF_81	
}

/// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
/*
void		NLFitSession::SetFitCurveOptions(TreeNode& trCurveOptions)
{
	m_pnlfCurves->InitFitCurveOptions(trCurveOptions);
}
*/
///end REMOVE_NLFCURVE_FROM_NLSESSION

bool		NLFitSession::IsReadyIterations(bool *pbChiSqrReady) // = NULL
{
	/// Hong 19/05/08 TAKE_BACK_CHISQR_MECHANISM
	//return m_pParamMngr->IsParametersReady() && 
	if ( pbChiSqrReady )
		*pbChiSqrReady = false;
	
	///------ Folger 08/06/10 ORG-733 FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
	/// for safe, just for OC compile fail now
	if ( NLSF_ERR_COMPILE_NUMERIC_FUNCTION == GetLastError() )
		return false;
	///------ End FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
	
	if ( !IsFunctionReady() || GetNumDataset() <= 0 )
		return false;
	
	if ( pbChiSqrReady )
		*pbChiSqrReady = true;
	///------ Folger 02/09/09 QA80-13085 MORE_CLEAR_WAY_TO_INDICATE_MISSING_PARAMETERS_INSTEAD_OF_DISABLE_ITERATION
	//if ( !m_pParamMngr->IsParametersReady() )
		//return false;
	///------ End MORE_CLEAR_WAY_TO_INDICATE_MISSING_PARAMETERS_INSTEAD_OF_DISABLE_ITERATION
	return !IsFitConverged();
	/// end TAKE_BACK_CHISQR_MECHANISM
}


/// Iris NLF_81, to do 
/*
DWORD		NLFitSession::GetSourcePlotUID(int index)
{
	if (m_vuSourceDataPlotUIDs.GetSize() <= index)
		return 0;
	
	return m_vuSourceDataPlotUIDs[index];
}

bool		NLFitSession::setSourcePlotUID(DWORD dwPlotUID, int nIndex)
{
	if(m_vuSourceDataPlotUIDs.GetSize() <= nIndex)
	{
		m_vuSourceDataPlotUIDs.Add(dwPlotUID);
	}
	else	
	{
		m_vuSourceDataPlotUIDs[nIndex] = dwPlotUID;
	}
	return true;
}

void		NLFitSession::resetSourcePlotUIDs()
{
	m_vuSourceDataPlotUIDs.SetSize(0);
}
*/
DWORD		NLFitSession::GetSourcePlotUID(int index)
{	
	return m_pDataObj->GetSourcePlotUID(index);
}
///end NLF_81

/// Iris 11/01/2008 v8.0964 NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE
void		NLFitSession::SetSourcePlotUID(int index, DWORD dwPlotUID)
{
	m_pDataObj->SetSourcePlotUID(index, dwPlotUID );
}
///end NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE

/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
//int			NLFitSession::Iterate(int nMaxNumIterations, int nMethod, bool bAllowCancel, int* lpnActualInterateCount, int* lpnIterateOutCome, DWORD *pdwNLDlgUpdate) // = FITMETH_LEVENBERG_MARQUARDT, false, NULL, NULL, NULL
//------ Folger 12/10/08 QA80-12751 v8.0984d SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
//int			NLFitSession::Iterate(int nMaxNumIterations, int nMethod, bool bAllowCancel, int* lpnActualInterateCount, int* lpnIterateOutCome) // = FITMETH_LEVENBERG_MARQUARDT, false, NULL, NULL
int			NLFitSession::Iterate(int nMaxNumIterations, int nMethod, bool bAllowCancel, int* lpnActualInterateCount, int* lpnIterateOutCome, DWORD dwOption/* = 0*/) // = FITMETH_LEVENBERG_MARQUARDT, false, NULL, NULL
//------ End SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
{
	validateParams("Iterate");
	
	int		nRet = -1;
	int 	nNumberItersPerformed = 0;
	int 	nOutcome = FITITER_FAILED;

/// Hong 12/05/08 v8.0860 JASIME_SAID_PEAK_CENTERS_HANDLING_IS_NOT_DIMENSION_SENSITIVE	
//#ifdef  2D_FIT_SUPPORT_REPLICA
/// end JASIME_SAID_PEAK_CENTERS_HANDLING_IS_NOT_DIMENSION_SENSITIVE	
	if ( FITMETH_LEVENBERG_MARQUARDT == nMethod ) // Hong, i worder if simplex can share this code too
	{
		/// Hong 12/05/08 v8.0860 JASIME_SAID_PEAK_CENTERS_HANDLING_IS_NOT_DIMENSION_SENSITIVE
		//if ( GetNumFitY() > 1 && NLFIT_GENERAL_XY_FITTING != GetFitType() )
		if ( GetNumPeaks() > 1 )
		/// end JASIME_SAID_PEAK_CENTERS_HANDLING_IS_NOT_DIMENSION_SENSITIVE
		{
			SetIterationSettings(FIXED_CENTER_ITER_COUNT);
			SetMultipeakOptions();
		}
	}
/// Hong 12/05/08 v8.0860 JASIME_SAID_PEAK_CENTERS_HANDLING_IS_NOT_DIMENSION_SENSITIVE	
//#endif //2D_FIT_SUPPORT_REPLICA
/// end /// Hong 12/05/08 v8.0860 JASIME_SAID_PEAK_CENTERS_HANDLING_IS_NOT_DIMENSION_SENSITIVE	
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	int		nCount = isSeparateFit() ? GetNumDataset() : 1;
	m_vnIterCount.SetSize(nCount);
	m_vnLastIterateOutCome.SetSize(nCount);
	m_vnNumberItersPerformed.SetSize(nCount);
	m_vsFitMessage.SetSize(nCount);
	
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//int		nBackupSize = doesNeedBackupFitResults() ? nCount : 0;
	//if ( m_arNLFitResults.GetSize() < nBackupSize )
		//m_arNLFitResults.SetSize(nBackupSize);	
	m_arNLFitAdditionalObjs.SetSize(0); // Hong, reset first, as setting maybe changed
	for ( int ii = 0; ii < nCount - GetNLFitArrayOffset(); ii++ )
	{
		NLFit*		pNLFitObj = new NLFit;
		NLFit&		firstNLFitObj = GetNLFitObj();
		// Hong, init newly created NLFit object with settings keep in first NLFit object set by class caller.
		pNLFitObj->m_bGLCsEnabled = firstNLFitObj.m_bGLCsEnabled;
		pNLFitObj->MultipeakOptions = firstNLFitObj.MultipeakOptions;
		pNLFitObj->SetDataSteps(&m_stDataSteps, m_nDataStepsSize);
		pNLFitObj->SetGLCs(m_strConstraintsCode);
		pNLFitObj->SetIterationSettings(&m_stNLSFIterSetting);
		
		m_arNLFitAdditionalObjs.Add(*pNLFitObj);
	}
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	
	for ( int iDataset = 0; iDataset < nCount; iDataset++ )
	{
		if ( nCount > 1 )  // Need to dirty bits of NLFit once do multiple fits
			m_dwNLFitDirtyBits |= NLFIT_DIRTY_ALL;
		m_nSepFitActiveDataset = iDataset;
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		beforeFit(nMethod);
	
		if ( bAllowCancel && nMaxNumIterations > 2 )
			/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
			//m_NLFit.SetCallback(this);
			GetNLFitObj(iDataset).SetCallback(this);
			/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		else
		{
			ClassObject junk;
			/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
			//m_NLFit.SetCallback(junk);
			GetNLFitObj(iDataset).SetCallback(junk);
			/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		}
		
		try {
			/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
			//nRet = m_NLFit.Fit(nMaxNumIterations, &nNumberItersPerformed, &nOutcome, NULL, nMethod);
			//------ Folger 12/10/08 QA80-12751 v8.0984d SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
			//nRet = GetNLFitObj(iDataset).Fit(nMaxNumIterations, &nNumberItersPerformed, &nOutcome, NULL, nMethod);
			nRet = GetNLFitObj(iDataset).Fit(nMaxNumIterations, &nNumberItersPerformed, &nOutcome, NULL, nMethod, dwOption);
			//------ End SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
			/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		}
		catch(int nErr)
		{
			ERR_MSG("NLF DLL Fit crashed");
			
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			//m_nLastIterateOutCome = FITITER_FAILED;		
			m_vnLastIterateOutCome[iDataset] = FITITER_FAILED;
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			if(lpnActualInterateCount)
				*lpnActualInterateCount = 0;
			if(lpnIterateOutCome)
				*lpnIterateOutCome = FITITER_FAILED; 
				
			return -1;
		}
		//validateParams("after fitting"); ///Sophy ,if want to check params, should called after OnAfterFit updating all params
		/// Hong 11/04/08 v8.0965b FIX_GRID_NOT_UPDATE_WHEN_FIT_FAIL
		//if ( nRet == 0 )
		//{
		/// end FIX_GRID_NOT_UPDATE_WHEN_FIT_FAIL
			m_pParamMngr->OnAfterFit();
			/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
			//if ( pdwNLDlgUpdate )
				//*pdwNLDlgUpdate = NLDLGPART_PARAMETERS_GRID | NLDLGPART_FIT_CONTROL_BTNS;
			/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
		/// Hong 11/04/08 v8.0965b FIX_GRID_NOT_UPDATE_WHEN_FIT_FAIL
		//}
		/// end FIX_GRID_NOT_UPDATE_WHEN_FIT_FAIL
		validateParams("after fitting"); 
		/* Hong, have move to Parameter Manager
		if ( 0 < nMaxNumIterations )
		{
			getParamConfLimit();
		}
		*/
		/// Hong 03/13/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
		if ( 0 == nMaxNumIterations && NLSFFIT_GENERATE_OUTPUTS_WITHOUT_ITERATION & dwOption )
		m_bDuringGetResultWithIterate = true;
		/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
		
		if ( FITMETH_LEVENBERG_MARQUARDT == nMethod )// Hong, i worder if simplex can share this code too
		{
			if ( 0 == nMaxNumIterations && 0 == nRet )
				nOutcome = FITITER_GET_CHISQR;
			else if(nOutcome == FITITER_ABORT_BY_USER)
			{
			}
			else if(nRet)
			{
				switch(nRet)
				{
				case NLF_MUTUALDEPEND:
					nOutcome = FITITER_FAILED_MUTUAL_DEPEND;
					break;
				case NLF_ZERO_ERROR_NOT_CONSISTENT:
					nOutcome = FITITER_FAILED_ZERO_ERROR_NOT_CONSISTENT;
					break;
				case NLF_ZERO_YVALUE_NOT_CONSISTENT:
					nOutcome = FITITER_FAILED_ZERO_YVALUE_NOT_CONSISTENT;
					break;
				case NLF_VALUE_NOT_CONSISTENT_WITH_WEIGHTING_METHOD:
					nOutcome = FITITER_VALUE_NOT_CONSISTENT_WITH_WEIGHTING_METHOD;
					break;
				case NLF_NEGATIVE_ERROR_FOR_WEIGHT:
					nOutcome = FITITER_FAILED_NEGATIVE_ERROR_VALUE_FOR_WEIGHT;
					break;
				case NLF_NEGATIVE_WEIGHT:
					nOutcome = FITITER_FAILED_NEGATIVE_WEIGHT;
					break;
				///------ Folger 01/14/09 QA80-12955 FAIL_TO_OUTPUT_INVALID_SYNTAX_OF_CONSTRAINT_ERROR_MESSAGE
				case NLF_BADCNSTRVAR:
				case NLF_CONSTRBAD:
					nOutcome = FITITER_FAILED_GENERAL_LINEAR_CONSTRAINTS;
					break;
				///------ End FAIL_TO_OUTPUT_INVALID_SYNTAX_OF_CONSTRAINT_ERROR_MESSAGE
				///------ Folger 02/09/09 QA80-13085 MORE_CLEAR_WAY_TO_INDICATE_MISSING_PARAMETERS_INSTEAD_OF_DISABLE_ITERATION
				case NLF_BADINITPARA:
					nOutcome = FITITER_FAILED_MISSING_PARAMS;
					break;
				///------ End MORE_CLEAR_WAY_TO_INDICATE_MISSING_PARAMETERS_INSTEAD_OF_DISABLE_ITERATION
				default:
					nOutcome = FITITER_FAILED_OTHER_REASONS;
					break;
				}
			}
			else if(nOutcome == FITITER_COULD_NOT_REDUCE_CHISQ_AT_LAST_ITER)
			{
				//--- CPY QA70-7932 8/22/05 FIT_PERFECTLY_INIT_PARAM_NEED_PERTERBATION_TO_PROCEED
				if(nMaxNumIterations > 0 && nNumberItersPerformed < 1)
				{
					nOutcome = FITITER_FAILED_TO_REDUCE_CHISQR_NO_ITERATION;
				}
				//---
				else if(nMaxNumIterations > 2 && nNumberItersPerformed < 2)
					nOutcome = FITITER_FAILED_TO_REDUCE_CHISQR_DUE_TO_POOR_DATA;
			}
			/// Hong 04/08/10 QA80-15283 ITERATE_REACH_MAX_NO_GOOD_FIT_OUTCOME
			//else if(nMaxNumIterations > 1 && nNumberItersPerformed > 0 && nNumberItersPerformed <= nMaxNumIterations && nOutcome > FITITER_REACHED_TOLERANCE)
			else if(nMaxNumIterations > 1 && nNumberItersPerformed > 0 && nNumberItersPerformed <= nMaxNumIterations && 
				FITITER_ABORT_BY_USER < nOutcome && nOutcome < FITITER_REACHED_TOLERANCE )
			/// end ITERATE_REACH_MAX_NO_GOOD_FIT_OUTCOME
				nOutcome = FITITER_MAX_ITER_REACHED;
			
			/// Hong 01/12/10 QA80-14948-P2 FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT
			/*
			/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
			if ( NLSFFIT_GENERATE_OUTPUTS_WITHOUT_ITERATION & dwOption )
			{
				if ( !m_bIterateSettingsPolished || !m_bLastFitIterateTillConverge )
					nOutcome = FITITER_FIT_NOT_COMPLETE;
			}
			/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
			*/
			/// end FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT
			
			if(nOutcome != FITITER_GET_CHISQR)
			{
				/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
				//m_nLastIterateOutCome = nOutcome; 
				//m_nNumberItersPerformed = nNumberItersPerformed;
				m_vnLastIterateOutCome[iDataset] = nOutcome; 
				m_vnNumberItersPerformed[iDataset] = nNumberItersPerformed;
				/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
				/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
				if ( m_nMaxNumIter > 0 && m_nMaxNumIter == nMaxNumIterations )
					m_bLastFitIterateTillConverge = true;
				/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
			}
			
			/// Hong 01/12/10 QA80-14948-P2 FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT
			if ( NLSFFIT_GENERATE_OUTPUTS_WITHOUT_ITERATION & dwOption )
			{
				ASSERT( 0 == nMaxNumIterations );
				if ( !m_bIterateSettingsPolished || !m_bLastFitIterateTillConverge )
				{
					nOutcome = FITITER_FIT_NOT_COMPLETE;
					m_vnLastIterateOutCome[iDataset] = nOutcome;
				}
				nOutcome = m_vnLastIterateOutCome[iDataset];
				nNumberItersPerformed = m_vnNumberItersPerformed[iDataset];
			}
			/// end FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT
		}
			
		if ( !isLastFitOutComeError() || FITITER_GET_CHISQR == nOutcome )
		{
			/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
			//m_NLFit.GetSummaryFitResults(&m_RegStats, NULL); /// Hong 21/05/08 v8.0867d GET_RESULT_AFTER_FIT
			GetNLFitObj(iDataset).GetSummaryFitResults(&m_RegStats, NULL);
			/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		}
		
		if ( lpnActualInterateCount )
			*lpnActualInterateCount = nNumberItersPerformed;
		if ( lpnIterateOutCome )
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			*lpnIterateOutCome = nOutcome;
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			
		outputOpMsgLog(nNumberItersPerformed, nMethod, m_RegStats, nOutcome);	
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		afterFit();
		
		/// Hong 03/13/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
		m_bDuringGetResultWithIterate = false;
		/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	}	
	
	if ( isSeparateFit() )
		m_pParamMngr->SetActiveDataset(-1);
	//// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT	
	return nRet;
}

bool		NLFitSession::Fit(int* pnOutcome, bool bCheckLastOutcome, bool bAllowCancel) // = NULL, false, false
{	
	int 	nIterations = MAX_INTERATE_NUM_TRY_CONVERGE;
	if ( m_nMaxNumIter > 0 )
		nIterations = m_nMaxNumIter;
	
	if ( bCheckLastOutcome && isLastFitOutComeGoodFit() )
		nIterations = 0;

	int nRet = Iterate(nIterations, FITMETH_LEVENBERG_MARQUARDT, bAllowCancel);
	if ( pnOutcome )
		/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		//*pnOutcome = m_nLastIterateOutCome;	
		*pnOutcome = GetLastIterateOutCome(); // Hong, to do, fail to return all fit outcome	
		/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	if ( isLastFitOutComeGoodFit() )
		return true;
		
	int		nParamToNudge;
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//if ( FITITER_FAILED_TO_REDUCE_CHISQR_NO_ITERATION == m_nLastIterateOutCome && tryOptimizeNudgeParam() )
	if ( FITITER_FAILED_TO_REDUCE_CHISQR_NO_ITERATION == GetLastIterateOutCome() && tryOptimizeNudgeParam() )
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	{		
		UpdateParams(false, false, "Fit need to nudge a parameter to try to interate again");		
		nRet = Iterate(MAX_INTERATE_NUM_TRY_CONVERGE, FITMETH_LEVENBERG_MARQUARDT, bAllowCancel);
		if(pnOutcome)
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			//*pnOutcome = m_nLastIterateOutCome;
			*pnOutcome = GetLastIterateOutCome();
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		
		if ( isLastFitOutComeGoodFit() )
			return true;
	}

	return false;
}

bool 		NLFitSession::SetIterationSettings(int nNumIterationsWithFixedCenters)
{
	NLSF8ITERATIONSETTINGS	nlsfIterSetting;
	nlsfIterSetting.nNumIterationsWithFixedCenters = nNumIterationsWithFixedCenters;
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//return m_NLFit.SetIterationSettings(&nlsfIterSetting);
	// Hong, the same as comment in SetEnableLinearConstraints
	m_stNLSFIterSetting = nlsfIterSetting;
	return GetNLFitObj().SetIterationSettings(&nlsfIterSetting);
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
}

bool 		NLFitSession::SetDataSteps(const vector<int>& vnDataSteps)
{
	const int nSize = vnDataSteps.GetSize();
	if ( nSize < 1 || nSize > MAX_DATASET_NUMBER )
		return false;
	
	NLSF8DATASTEP stDataSteps[MAX_DATASET_NUMBER];
	for ( int ii = 0; ii < nSize; ii++ )
	{
		stDataSteps[ii].lStep = vnDataSteps[ii];
		m_stDataSteps[ii].lStep = vnDataSteps[ii]; /// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	}
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//return m_NLFit.SetDataSteps(&stDataSteps, nSize);
	// Hong, the same as comment in SetEnableLinearConstraints
	m_nDataStepsSize = nSize;
	return GetNLFitObj().SetDataSteps(&stDataSteps, nSize);
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
}

/// Hong, Jasmine 08/14/08 PEAKSMODE_MULTIFUNC_GLC
void 		NLFitSession::SetMultipeakOptions(DWORD dwMultipeakOptions/* = PEAKSMODE_MULTIPEAK_CENTERS_HANDLING*/)
{
	/// Jack 31/10/08 QA80-12423 SET_PA_CONSTRAINTS_WHEN_IT_IS_MULTIPLE_FUNCS_FIT
	//if ( isMultiplicityFit() )
	//	dwMultipeakOptions |= PEAKSMODE_MULTIFUNC_GLC;
	if (isMultiplicityFit() && isMultipleFuncsMultiPeaksFit())
		dwMultipeakOptions |= PEAKSMODE_MULTIFUNC_GLC;
	///End SET_PA_CONSTRAINTS_WHEN_IT_IS_MULTIPLE_FUNCS_FIT
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//m_NLFit.MultipeakOptions = dwMultipeakOptions;
	// Hong, the same as comment in SetEnableLinearConstraints
	GetNLFitObj().MultipeakOptions = dwMultipeakOptions;
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
}
/// end PEAKSMODE_MULTIFUNC_GLC

bool		NLFitSession::SetEnableLinearConstraints(const TreeNode& trLinearConstraints, bool bConstraints) // = true
{
	///Sophy 7/1/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	/*
	string	strConstraintsCode;
	
	if ( !trLinearConstraints )
		bConstraints = false;
	else
	{
		strConstraintsCode = trLinearConstraints.strVal;
		ocu_skip_C_comments(&strConstraintsCode);
		strConstraintsCode.TrimLeft();
		strConstraintsCode.TrimRight();
		if ( strConstraintsCode.IsEmpty() )
			bConstraints = false;
	}
	*/
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/*
	bool bOldVal = m_NLFit.m_bGLCsEnabled;
	m_NLFit.m_bGLCsEnabled = bConstraints;
	/// Hong 09/26/08 QA80-11463 FIX_NEW_SESSION_CONSTRAINT_FAIL_TO_WORK_EVEN_CONTRAINED_IN_FDF
	// this fix is necessary due to change of Jack 08/12/2008 QA70-11463 POSTFIX_FOR_LINEAR_CONSTRAINTS_PARA_TOKENS	
	m_NLFit.SetGLCs(strConstraintsCode);
	/// end FIX_NEW_SESSION_CONSTRAINT_FAIL_TO_WORK_EVEN_CONTRAINED_IN_FDF
	*/
	// Hong, number of NLFit object can be determined until iterate, so, here only set the first NLFit object, 
	// and later, once new one is created, need to copy there settings from first one
	// see function Iterate(..)
	/*
	NLFit&		refNLFitObj = GetNLFitObj();
	bool bOldVal = refNLFitObj.m_bGLCsEnabled;
	refNLFitObj.m_bGLCsEnabled = bConstraints;	
	refNLFitObj.SetGLCs(strConstraintsCode);
	m_strConstraintsCode = 	strConstraintsCode;
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	
	return bOldVal;
	*/
	///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	string strConstraints = "";
	if ( trLinearConstraints )
		strConstraints = trLinearConstraints.strVal;
	
	return SetEnableLinearConstraints(bConstraints, strConstraints);
}

///Sophy 7/1/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
bool		NLFitSession::SetEnableLinearConstraints(bool bConstraints/* = true */, LPCSTR lpcszLinearConstraints/* = NLL*/)
{
	string strConstraints(lpcszLinearConstraints);
	if ( NULL == lpcszLinearConstraints )
	{
		TreeNode trFDF = GetTreeFDF();
		if ( trFDF )
		{
			TreeNode trConstraints = trFDF.CONSTRAINTS.Script;
			if ( trConstraints )
				strConstraints = trConstraints.strVal;
		}
	}
	
	ocu_skip_C_comments(&strConstraints);
	strConstraints.TrimLeft();
	strConstraints.TrimRight();
	if ( strConstraints.IsEmpty() )
		bConstraints = false;
	
	NLFit&		refNLFitObj = GetNLFitObj();
	bool bOldVal = refNLFitObj.m_bGLCsEnabled;
	refNLFitObj.m_bGLCsEnabled = bConstraints;	
	refNLFitObj.SetGLCs(strConstraints);
	m_strConstraintsCode = 	strConstraints;
	
	return bOldVal;
}
///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION

int			NLFitSession::SetFitType(const TreeNode& trSpecInfo)
{
	int		nOldVal = m_nFitType;
	
	if ( trSpecInfo && trSpecInfo.FitType )
		m_nFitType = trSpecInfo.FitType.nVal;
	else
		m_nFitType = NLFIT_GENERAL_XY_FITTING;
	
	return nOldVal;
}

/// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION, move calc fit result codes into NLFCurvesBase class
/*
bool NLFitSession::GetResidualData(vector& vResidual, int index, vector& vInX, vector& vInY, vector& vInZ, vector& vFitZ)
{
	vector 		vX, vY, vZ;	
	if ( !GetInputData(vX, vY, vZ, index) )
		return false;
	
	// Hong 06/13/08 CLEAN_UP_CODE	
	//matrix 		matFit(1, vX.GetSize());
	//if ( !getFitZ(vX, vY, matFit, index) )
		//return false;
	//
	//vector 		vFitZTemp;
	//matFit.GetAsVector(vFitZTemp, false); //get by column
	//if ( vFitZTemp.GetSize() != vZ.GetSize() )
		//return false;	
	vector vFitZTemp(vX.GetSize());
	if( !GetFitZ(vX, vY, vFitZTemp, index) )
		return false;
	
	if ( vFitZTemp.GetSize() != vZ.GetSize() )
		return false;
	/// end CLEAN_UP_CODE
	
	vResidual = vZ - vFitZTemp;
	if ( vInX )
		vInX = vX;
	if ( vInY )
		vInY = vY;
	if ( vInZ )
		vInZ = vZ;
	if ( vFitZ )
		vFitZ = vFitZTemp;
	
	return true;
}
*/
///end NLF_81

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
/*
double 		NLFitSession::GetChiSqr()
{
	Iterate(0);
	return m_RegStats.ReducedChiSq;
}

bool		NLFitSession::GetShortFitOutCome(string& strOutCome)
{
	if(m_nLastIterateOutCome >= FITITER_REACHED_TOLERANCE)
		strOutCome = _L("Succeeded");
	else if(m_nLastIterateOutCome <= FITITER_FAILED)
		strOutCome = _L("Failed");
	else
	{
		switch(m_nLastIterateOutCome)
		{
		case FITITER_ABORT_BY_USER:
			strOutCome = _L("Abort");
			break;
		case FITITER_REDUCED_CHISQ:
			strOutCome = _L("Reduced chi-sq");
			break;
		case FITITER_COULD_NOT_REDUCE_CHISQ_AT_LAST_ITER:
			strOutCome = _L("Could not further reduce chi-sq");
			break;
		case FITITER_NO_ITERATE:
			strOutCome = "";
			break;
		default:
			return false;
		}
	}
	
	strOutCome.Format("%s(%d)", strOutCome, m_nLastIterateOutCome);
	return true;
}
*/
//------ Folger 12/10/08 QA80-12751 v8.0984d SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
//void		NLFitSession::GetChiSqr(vector& vChiSqr/* = NULL*/)
void		NLFitSession::GetChiSqr(vector& vChiSqr/* = NULL*/, bool bGenerateOutputs/* = false*/)
//------ End SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
{
	//------ Folger 12/10/08 QA80-12751 v8.0984d SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
	//if ( Iterate(0) < 0 )
	if ( Iterate(0, FITMETH_LEVENBERG_MARQUARDT, false, NULL, NULL, bGenerateOutputs ? NLSFFIT_GENERATE_OUTPUTS_WITHOUT_ITERATION : 0) < 0 )
	//------ End SUPPORT_ALWAYS_GENERATE_OUTPUTS_REGARDLESS_OF_INTERATION_IN_PA_FITTING
	{
		error_report("Fail get chisqr");
		return ;
	}	
	if ( NULL != vChiSqr )
	{
		vChiSqr.RemoveAll();
		/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		/*
		if ( hadBackupedFitResults() )
		{
			for ( int ii = 0; ii < m_arNLFitResults.GetSize(); ++ii )
			{
				NLFitResults& reNLfFitResults = m_arNLFitResults.GetAt(ii);
				vChiSqr.Add(reNLfFitResults.stFitRegStats.ReducedChiSq);
			}
		}
		else
			vChiSqr.Add(m_RegStats.ReducedChiSq);
		*/
		if ( 1 == GetNumNLFitObjs() )
			vChiSqr.Add(m_RegStats.ReducedChiSq);
		else
		{
			for ( int ii = 0; ii < GetNumNLFitObjs(); ++ii )
			{
				RegStats 		stRegStats;
				CheckUpdateNLFitParamsLinking(ii);
				GetNLFitObj(ii).GetSummaryFitResults(&stRegStats, NULL);
				vChiSqr.Add(stRegStats.ReducedChiSq);
			}
		}
		/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	}
}

int			NLFitSession::GetNumberItersPerformed(int nSetIndex/* = 0*/)
{
	nSetIndex = getIterateResultSetIndex(nSetIndex);	
	/// Hong 10/27/08 v8.0961 FIX_PA_RUNTIME_ERROR_GENERATE_REPORT_WITHOUT_FIT
	//ASSERT(m_vnNumberItersPerformed.GetSize() > nSetIndex);
	//return m_vnNumberItersPerformed[nSetIndex];
	if ( m_vnNumberItersPerformed.GetSize() > nSetIndex )
	return m_vnNumberItersPerformed[nSetIndex];
	else
		return 0;
	/// end FIX_PA_RUNTIME_ERROR_GENERATE_REPORT_WITHOUT_FIT
}

bool		NLFitSession::GetShortFitOutCome(string& strOutCome, int nSetIndex/* = 0*/)
{
	int			nLastIterateOutCome = GetLastIterateOutCome(nSetIndex);
	if ( nLastIterateOutCome >= FITITER_REACHED_TOLERANCE )
		strOutCome = _L("Succeeded");
	/// Hong 01/12/10 QA80-13590-P7 ALWAYS_ACTIVE_MSG_TAB_IF_SIGNIFICANT_MSG
	//else if( nLastIterateOutCome <= FITITER_FAILED )
	else if( IsIterateFailed(nLastIterateOutCome) )
	/// end ALWAYS_ACTIVE_MSG_TAB_IF_SIGNIFICANT_MSG
		strOutCome = _L("Failed");
	else
	{
		switch ( nLastIterateOutCome )
		{
		case FITITER_ABORT_BY_USER:
			strOutCome = _L("Abort");
			break;
		case FITITER_REDUCED_CHISQ:
			strOutCome = _L("Reduced chi-sq");
			break;
		case FITITER_COULD_NOT_REDUCE_CHISQ_AT_LAST_ITER:
			strOutCome = _L("Could not further reduce chi-sq");
			break;
		case FITITER_NO_ITERATE:
			strOutCome = "";
			break;
		default:
			return false;
		}
	}
	
	strOutCome.Format("%s(%d)", strOutCome, nLastIterateOutCome);
	return true;
}
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

bool		NLFitSession::IsFitConverged()
{
	/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	if ( GetNLParamsMngr()->GetNLFitDirtyStatus() )
	{
		ResetFitOutCome();
	}
	/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	return isLastFitOutComeGoodFit();
}

int			NLFitSession::getNudgeParamIndex()
{	
	vector		vDependencies;
	if ( getParamNumericValues(NLPARAMGRIDCOLTYPE_DEPENDENCY, vDependencies) )
	{
		double		min = 0, max = 0;
		int			nIndexMin = 0;
		if ( 0 < vDependencies.GetMinMax(min, max, &nIndexMin) && 0 <= nIndexMin )
			return nIndexMin; // this is supposed to be the parameter on which chisq is the most sensitive
	}
	
	return -1;
}

bool		NLFitSession::tryOptimizeNudgeParam()
{
	const int		nParamToNudge = getNudgeParamIndex();
	if ( nParamToNudge < 0 )
		return false;
	
	vector		vParamValues;
	if ( !getParamNumericValues(NLPARAMGRIDCOLTYPE_VALUE, vParamValues) )
		return false;
	
	ASSERT(nParamToNudge < vParamValues.GetSize());
	
	double dParamNudgeSize = vParamValues[nParamToNudge] != 0.0 ? vParamValues[nParamToNudge] * 0.01 : 1E-15;
	vParamValues[nParamToNudge] += dParamNudgeSize;
	//m_pParamsMngr->SetOneFuncParam(); // Hong, to do, move to Parameter manager
	return true;
}

void		NLFitSession::SetIsGetParamsConf(const TreeNode& trParamControl, const TreeNode& trSummaryControl, const TreeNode trCIMethod)
{
	if(trParamControl)
	{
		m_bGetParamsConf = (1 == trParamControl.LCL.nVal || 1 == trParamControl.UCL.nVal || trSummaryControl.LCL.nVal || trSummaryControl.UCL.nVal);
		m_dConfidence = trParamControl.Confidence.dVal / 100;
		///Sophy 10/15/2008 CENTRALIZE_CODE_TO_UPDATE_LCL_UCL_SETTINGS
		int nComputeConfMethod = m_bGetParamsConf ? m_nConfLimitMethod : -1;
		m_pParamMngr->SetComputeConfLimitsMethod( nComputeConfMethod );
		///end CENTRALIZE_CODE_TO_UPDATE_LCL_UCL_SETTINGS
	}
	
	if ( trCIMethod )
		m_nConfLimitMethod = trCIMethod.nVal;
}

void 		NLFitSession::SetDerivsSettings(const TreeNode& trDerivsDetal)
{
	if ( trDerivsDetal )
	{
		m_DerivsSettings.rDerivStepSize		= trDerivsDetal.Delta.dVal;
		m_DerivsSettings.bFixedDerivStepSize	= trDerivsDetal.Fixed.nVal;
		m_DerivsSettings.rMinDerivStepSize	= trDerivsDetal.Minimum.dVal;
		m_DerivsSettings.rMaxDerivStepSize	= trDerivsDetal.Maximum.dVal;
	}
}

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//bool 		NLFitSession::GetFitResultsStats(RegStats* pRegStats, NLSFFitInfo* pFitInfo, bool bPreDataset, int nSetIndex, int nDepIndex) // = false, -1, 0
//{
	///// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//ASSERT(pRegStats && pFitInfo);
	//if ( !hadBackupedFitResults() )
		//return getFitResultsStats(pRegStats, pFitInfo, bPreDataset, nSetIndex, nDepIndex);
//
	//if ( nSetIndex < 0 || nSetIndex >= m_arNLFitResults.GetSize() )
	//{
		//ASSERT(FALSE);
		//return false;
	//}
	//
	//*pRegStats = m_arNLFitResults.GetAt(nSetIndex).stFitRegStats;
	//*pFitInfo = m_arNLFitResults.GetAt(nSetIndex).stFitInfos;
	//return true;
	///// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//}
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
int			NLFitSession::GetLastIterateOutCome(int nSetIndex/* = 0*/)
{
	nSetIndex = getIterateResultSetIndex(nSetIndex);	
	/// Hong 10/27/08 v8.0961 FIX_PA_RUNTIME_ERROR_GENERATE_REPORT_WITHOUT_FIT
	//ASSERT(m_vnLastIterateOutCome.GetSize() > nSetIndex);
	//return m_vnLastIterateOutCome[nSetIndex];
	if ( m_vnLastIterateOutCome.GetSize() > nSetIndex )
	return m_vnLastIterateOutCome[nSetIndex];
	else
		return FITITER_NO_ITERATE;
	/// end FIX_PA_RUNTIME_ERROR_GENERATE_REPORT_WITHOUT_FIT
}
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
/*
string		NLFitSession::GetFitMessage()
{		
	if(!m_strFitMessage.IsEmpty())
	{
		string strSep = "\r\n";
		m_strFitMessage.TrimRight(strSep);
	
		// Hong, to do, this code better remove from session, the comment below reveal that it's knowledge of report
		//----Iris 9/30/06 to remove the first two lines, Chi and R value, the two will be reported in parameter table.
		vector<string> vsLines;
		str_separate(m_strFitMessage, strSep, vsLines);
		if(vsLines.GetSize() > 2)
		{
			vsLines.RemoveAt(0);
			vsLines.RemoveAt(0);
		}
		m_strFitMessage = str_combine(vsLines, strSep);
		//----
	}

	return m_strFitMessage;	
}
*/
/// Iris 11/03/2009 QA81-14576-P1 ADD_SUMMARY_FIT_RESULT_FOR_SEP_FIT_WITH_MULTI_DATASET
//string		NLFitSession::GetFitMessage(int nSetIndex/* = 0*/)
enum
{
	SUMMARY_FIT_OUT_ALL_FAILED,
	SUMMARY_FIT_OUT_ALL_SUCCESS,
	SUMMARY_FIT_OUT_SOME_FAILED
};

string		NLFitSession::GetSummaryIterateOutCome(int* pnSummaryOutType/* = NULL*/, bool bForFootnote/* = false*/)
{
	// this logic existed in 80SR4, but missed from SR5, so add back
	string strFitMessage;
	ASSERT( isSeparateFit() && GetNumDataset() > 1 );
	if( isSeparateFit() && GetNumDataset() > 1 )
	{
		int	num = 0;
		for(int nData = 0; nData < GetNumDataset(); nData++)
		{
			int nLastFitOutCome = m_vnLastIterateOutCome[nData];
			if( IsLastFitOutComeGoodFit(nLastFitOutCome) )
				num++;
		}
		
		if( bForFootnote )
			strFitMessage += STR_FOOTNOTE_COLOR_FORMAT_PREFIX;
		
		int nSummaryOutType;
		if(0 == num)
		{
			strFitMessage += _L("Fitting failed on all datasets.");
			nSummaryOutType  = SUMMARY_FIT_OUT_ALL_FAILED;
		}
		else if(num == m_vnLastIterateOutCome.GetSize())
		{
			strFitMessage += _L("All datasets were fitted successfully.");
			nSummaryOutType  = SUMMARY_FIT_OUT_ALL_SUCCESS;
		}				
		else
		{
			strFitMessage += _L("Fitting failed on some of the datasets.");
			nSummaryOutType  = SUMMARY_FIT_OUT_SOME_FAILED;
		}	
		if( bForFootnote )
			strFitMessage += STR_FOOTNOTE_COLOR_FORMAT_POSTFIX;
		
		if( pnSummaryOutType )
			*pnSummaryOutType = nSummaryOutType; 
	}
	return strFitMessage; // return empty string except last dataset
}

string		NLFitSession::GetFitMessage(int nSetIndex/* = 0*/, int* pnSummaryOutType/* = NULL*/, bool bForFootnote/* = false*/)
///end ADD_SUMMARY_FIT_RESULT_FOR_SEP_FIT_WITH_MULTI_DATASET
{
	nSetIndex = getIterateResultSetIndex(nSetIndex);	
	
	/// Hong 10/27/08 v8.0961 FIX_PA_RUNTIME_ERROR_GENERATE_REPORT_WITHOUT_FIT
	//ASSERT( m_vsFitMessage.GetSize() > nSetIndex );
	//string		strFitMessage = m_vsFitMessage[nSetIndex];
	string		strFitMessage;
	if ( m_vsFitMessage.GetSize() > nSetIndex )
	 	strFitMessage = m_vsFitMessage[nSetIndex];
	/// end FIX_PA_RUNTIME_ERROR_GENERATE_REPORT_WITHOUT_FIT
	if ( !strFitMessage.IsEmpty() )
	{
		string strSep = "\r\n";
		strFitMessage.TrimRight(strSep);
	
		// Hong, to do, this code better remove from session, the comment below reveal that it's knowledge of report
		//----Iris 9/30/06 to remove the first two lines, Chi and R value, the two will be reported in parameter table.
		vector<string> vsLines;
		str_separate(strFitMessage, strSep, vsLines);
		/// Iris 11/11/2009 QA81-14576-P4 KEEP_CHI_AND_R_VALUE_IN_PARAM_FOOTNOTE
		// the following change never effect on param table footnote because changed vsLines combined back to m_vsFitMessage
		// before, not updated output variable strFitMessage. So comment out.
		/*
		if(vsLines.GetSize() > 2)
		{
			vsLines.RemoveAt(0);
			vsLines.RemoveAt(0);
		}
		//----	
		*/
		///end KEEP_CHI_AND_R_VALUE_IN_PARAM_FOOTNOTE
		
		/// Iris 11/03/2009 QA81-14576 SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE
		int nFitResultLine = vsLines.GetSize()-1;
		if( isSeparateFit() && GetNumDataset() > 1 )
		{
			vsLines[nFitResultLine] = GetSummaryIterateOutCome(pnSummaryOutType, bForFootnote);
		}
		else
		{
			if( bForFootnote )
				vsLines[nFitResultLine] = STR_FOOTNOTE_COLOR_FORMAT_PREFIX + vsLines[nFitResultLine] + STR_FOOTNOTE_COLOR_FORMAT_POSTFIX;
		}
		///end SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE		

		///------ Folger 04/13/10 QA81-15297-P3 SHOW_LINEAR_CONSTRAINT_INFO_IN_FOOTNOTE
		if ( bForFootnote )
		{
			if ( IsLinearConstraintUsed() )
			{
				string		str;
				ocu_load_err_msg_str(FOOTNOTE_CONSTRAINT_IS_USED, &str);
				vsLines.Add(str);
			}
		}
		///------ End SHOW_LINEAR_CONSTRAINT_INFO_IN_FOOTNOTE

		/// Iris 11/03/2009 QA81-14576 SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE
		// should keep messages in m_vsFitMessage, and need and only need update output string
		//m_vsFitMessage[nSetIndex] = str_combine(vsLines, strSep);
		strFitMessage = str_combine(vsLines, strSep);
		///end SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE		
	}

	return strFitMessage;	
}
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

///------ Folger 04/13/10 QA81-15297-P3 SHOW_LINEAR_CONSTRAINT_INFO_IN_FOOTNOTE
BOOL		NLFitSession::IsLinearConstraintUsed()
{
	return GetNLFitObj().m_bGLCsEnabled && !m_strConstraintsCode.IsEmpty();
}
///------ End SHOW_LINEAR_CONSTRAINT_INFO_IN_FOOTNOTE

/// Hong 09/24/09 QA80-12199 FIT_LT_CALL_SPEED_UP_MOVE_CODE_TO_VC
void		NLFitSession::GetParamValuesAndOffsets(vector& vParamValues, vector<int>& vnParamsOffsets)
{
	vParamValues.RemoveAll();
	vnParamsOffsets.RemoveAll();	
	vector		vFullSizeParams; /// Hong 10/22/08 QA80-12432 FIX_LT_CMD_FIT_FAIL_FOR_REPLICA
	for ( int iPeak = 0; iPeak < GetNumPeaks(); ++iPeak )
	{
		for ( int iSet = 0; iSet < GetNumDataset(); ++iSet )
		{
			vector			vParams;
			int				nRet = GetNLParamsMngr()->GetParamValues(vParams, iSet, iPeak);
			ASSERT( nRet > 0 );			
			vnParamsOffsets.Add(vParamValues.GetSize());
			/// Hong 10/22/08 QA80-12432 FIX_LT_CMD_FIT_FAIL_FOR_REPLICA
			//vParamValues.Append(vParams);
			if ( 0 == iPeak || NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS == getParamsType() )
				vFullSizeParams = vParams;
			else
			{
				ASSERT( 1 == GetNumDataset() ); // undefine for multi peaks multi dataset
				vFullSizeParams.SetSubVector(vParams, vFullSizeParams.GetSize() - vParams.GetSize());
			}
			vParamValues.Append(vFullSizeParams);
			/// end FIX_LT_CMD_FIT_FAIL_FOR_REPLICA
		}		
	}
	vnParamsOffsets.Add(vParamValues.GetSize()); // the last is the total size
}

int			NLFitSession::GetYFromX(const double *pX, double *pY, int nCount/* = 1*/, int nn/* = 0*/)
{
	TreeNode trFDF = GetTreeFDF();
	if(!trFDF.IsValid())
		return false;
	NumericFunction nf(trFDF);		
	/// Hong 22/05/08 QA80-11571 NLFIT_Y_FROM_X_SUPPORT_CUMULATIVE_FITTED_CURVE
	//vector vPara;
	//GetAllParaValues(vPara, nSet);
	//for(int ii = 0; ii < nCount; ii++, pX++, pY++)
	//	*pY = nf.Evaluate(*pX, vPara);
	int		nSet = 0, nPeakIndex = 0, nNumPeak = nPeakIndex + 1;
	if ( GetNumDataset() > 1 ) // multiple dataset
	{
		if ( nn < 0 )
			nn = 0;
		nSet = nn;
	}
	else // single dataset, multiple peaks
	{
		if ( nn >= 0 )
		{
			nPeakIndex = nn;			
			nNumPeak = nPeakIndex + 1;
		}
		else
			nNumPeak = GetNumPeaks();
	}
	
	double	dBaseline = GetBaseline();		
	const double* pXOrigin = pX;
	double* pYOrigin = pY;	
	for ( int nPeak = nPeakIndex; nPeak < nNumPeak; nPeak++ )
	{	
		vector vParams;
		///Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
		//GetNLParamsMngr()->GetParamValues(vParams, nSet, nPeak);
#ifndef	EXTEND_INTERFACES_OF_NLFITSESSION
		GetNLParamsMngr()->GetParamValues(vParams, nSet, nPeak);
#else	//EXTEND_INTERFACES_OF_NLFITSESSION	defined
		GetNLParamsMngr()->GetParamValues(vParams, nSet, nPeak, true);
#endif	
		///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
		
		for ( int ii = 0; ii < nCount; ii++, pX++, pY++ )
		{
			if ( nPeak == nPeakIndex )
				*pY = 0;
			
			*pY += nf.Evaluate(*pX, vParams);
			
			if ( nPeak > 0 )
				*pY -= dBaseline;
		}
		pX = pXOrigin;
		pY = pYOrigin;
	}	
	/// end NLFIT_Y_FROM_X_SUPPORT_CUMULATIVE_FITTED_CURVE
	return true;
}
/// end FIT_LT_CALL_SPEED_UP_MOVE_CODE_TO_VC

/// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION, move calc fit result codes into NLFCurvesBase class
/*
bool		NLFitSession::GetFitX(vector& vFitX, int nDatasetIndex, bool bSetCustomInput)
{		
	ASSERT(m_pnlfCurves);	
	return m_pnlfCurves->GetFitX(vFitX, m_pDataObj, nDatasetIndex, 0, bSetCustomInput);
}

bool 		NLFitSession::GetFitY(const vector& vx, vector& vy, int nDatasetIndex, int nPeak)
{
	ASSERT(m_pnlfCurves);	
	return m_pnlfCurves->GetFitY(vx, vy, m_pParamMngr, nDatasetIndex, nPeak);
}

bool		NLFitSession::GetFit(vector& vFitX, vector& vFitY, int nDatasetIndex, int nPeak, bool bSetCustomInput)
{
	ASSERT(m_pnlfCurves);	
	if( !m_pnlfCurves->GetFitX(vFitX, m_pDataObj, nDatasetIndex, 0, bSetCustomInput) )
		return false;
	
	if( !m_pnlfCurves->GetFitY(vFitX, vFitY, m_pParamMngr, nDatasetIndex, nPeak) )
		return false;
	
	return true;	
}


bool		NLFitSession::GetFitX(matrix& mFitXs, int nDatasetIndex, bool bSetCustomInput)
{
	int 	nNumIndeps;
	if( !GetNumVars(NULL, &nNumIndeps) )
		return false;
	
	bool	bSort = NLFIT_GENERAL_XY_FITTING != GetFitType() || 1 == nNumIndeps;
	
	ASSERT(m_pnlfCurves);	
	return m_pnlfCurves->GetFitX(mFitXs, m_pDataObj, nDatasetIndex, nNumIndeps, bSetCustomInput, bSort);
}

bool 		NLFitSession::GetFitY(const matrix& mFitXs, matrix& mFitYs, int nDatasetIndex)
{
	int 	nNumDeps;
	if( !GetNumVars(&nNumDeps, NULL) )
		return false;
	
	ASSERT(m_pnlfCurves);	
	return m_pnlfCurves->GetFitY(mFitXs, mFitYs, m_pParamMngr, nDatasetIndex, nNumDeps);
}

bool 		NLFitSession::GetFitXY(vector& vX, vector& vY, bool bSetCustomInput, bool bNeedGrid, int* pnRows, int* pnCols) // = false, NULL, NULL
{
	return false;
	
	// _NLF_81, Hong, to do	
	//if ( checkXYZRegularData(NULL, nRows, nCols) && FIT_CURVE_SAME_AS_DATA == m_fitOptionsX.DataType && FIT_CURVE_SAME_AS_DATA == m_fitOptionsY.DataType )
	//	return true;	
	//double dXFrom, dXTo; 
	//getXAxisFromAndTo(dXFrom, dXTo);
	//get_data_by_fitted_curve_options(vX, vX, m_fitOptionsX, NULL, &dXFrom, &dXTo, true, bSetCustomInput);
	//double dYFrom, dYTo; 
	//getYAxisFromAndTo(dYFrom, dYTo);
	//get_data_by_fitted_curve_options(vY, vY, m_fitOptionsY, NULL, &dYFrom, &dYTo, true, bSetCustomInput);
	// replace code above by following
	//filterFitX(vX, bSetCustomInput);
	//filterFitY(vY, bSetCustomInput);
	int 	nRows, nCols;
	nRows = vX.GetSize();	
	nCols = vY.GetSize();

	if(bNeedGrid)
	{
		/// Hong, to do, after Griding, vector size changed, check which size is pnRows wanted
		//if( !GetXYGriding(vX, vY, nRows, nCols))
		//	return error_report("Error to create XY gridding in NLFitSessionBase::GetFitXY!\n");
	}
	
	if(pnRows)
		*pnRows = nRows;
	if(pnCols)
		*pnCols = nCols;
	///end CLEAN_PREVIEW_CTRL_CLASSES
	
	return true;
}

bool		NLFitSession::GetFitZ(vector& vX, vector& vY, matrix& matZ, int& nRows, int& nCols, int nDatasetIndex, bool bSetCustomInput)
{
	int 	nRowNum, nColNum;
	if( !GetFitXY(vX, vY, bSetCustomInput, true, &nRowNum, &nColNum)) 	
		return false;

	matZ.SetSize(nRowNum, nColNum);
	if( !getFitZ(vX, vY, matZ, nDatasetIndex))
		return false;
	
	if( NULL != nRows ) 
		nRows = nRowNum;
	if( NULL != nCols ) 
		nCols = nColNum;
	
	return true;
}

bool		NLFitSession::GetFitZ(const vector& vX, const vector& vY, vector& vZ, int nDatasetIndex)
{
	ASSERT(m_pnlfCurves);	
	return m_pnlfCurves->GetFitZ(vX, vY, vZ, m_pParamMngr, nDatasetIndex);
}

bool		NLFitSession::GetCumulativeData(vector& vCumulative, int nDatasetIndex)
{
	/// Iris NLF_81, to do, hard code
	//vector		vParamValue;
	//GetNLParamsMngr()->GetParamValues(vParamValue, nDatasetIndex);
	//double 		dY0 = (vParamValue.GetSize() && !HasBaselinePeak())? vParamValue[0] : 0;//offset
	double 		dY0 = 0;
	///end NLF_81
	
	vCumulative.SetSize(0);
	for(int nPeak = 0; nPeak < GetNumPeaks(); nPeak++)
	{
		vector 	vX, vY;
		if( !GetFit(vX, vY, nDatasetIndex, nPeak) )
			return error_report("Get error from GetFit method in NLFitSessionBase::GetCumulativeData");
		else
		{
			if(0 == vCumulative.GetSize())
				vCumulative.SetSize(vY.GetSize());			
			vCumulative += vY;
			if(0 < nPeak)	///Jasmine 11/05/07 SUBTRACT_BASELINE_BEFORE_PFM_FIT
				vCumulative -= dY0;
		}
	}
	return true;
}
*/
///end NLF_81

bool 		NLFitSession::GetDifferentTypeResidualDatas(const TreeNode& trOp, const vector& vx, const vector& vRegular, vector& vStad, vector& vStud, vector& vStudDel, int index, int nPeak)
{
	int nFitOutcome;
	/// Hong 10/23/08 QA80-12434 TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	//int nFunc =  GetFuncIndex(nPeak);
	//NLFitFunction*	pFitFunc = GetFitFunction(nFunc);
	//if(NULL == pFitFunc)
		//return false;
	int			nFunc = GetNLParamsMngr()->GetFuncIndex(nPeak);
	/// end TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	
	NumericFunction nf;	
	Tree 			trFF;
	/// Hong 10/23/08 QA80-12434 TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	//trFF = pFitFunc->GetFuncTree();
	trFF = GetTreeFDF(nFunc);
	/// end TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	if(!nf.SetTree(trFF))
		return false;
	vector vPara;
	/// Hong 10/23/08 QA80-12434 TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	//GetAllParaValues(vPara, index, nPeak);
	GetNLParamsMngr()->GetParamValues(vPara, index, nPeak);
	/// end TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
	int 	nNumParaInFunc = vPara.GetSize();
	double dSSE;
	if(!getReducedChiSq(trOp, dSSE, index))
		return false;
	
	int nNumPts = vx.GetSize();
	matrix mDerivX(nNumPts, nNumParaInFunc);
	if(nNumPts <= 0)
		return false;
	
	BOOL  bb = nf.EvalVectorPartialDerivatives(vPara, nNumPts, mDerivX, vx);
	if (!bb)
		return false;
	 
	int nResSize = vRegular.GetSize();
	vStad.SetSize(nResSize); vStud.SetSize(nResSize); vStudDel.SetSize(nResSize);
	vector vCook(nResSize), vAtkinson(nResSize);
	int nRet = ocmath_diagnostic_residuals(nNumPts, nNumParaInFunc, dSSE, nResSize, vRegular, mDerivX, vStad, vStud, vStudDel, vCook, vAtkinson);
	if (nRet != STATS_NO_ERROR)
		return false;
	
	return true;
}

bool		NLFitSession::GetVarCovarMatrix(matrix& mVarCovar, BOOL bScaleWithChiSq)
{
	if(!mVarCovar)
		return false;
	
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//if(m_NLFit.GetVarCovarMatrix(&mVarCovar, bScaleWithChiSq))	
	CheckUpdateNLFitParamsLinking();
	if ( GetNLFitObj().GetVarCovarMatrix(&mVarCovar, bScaleWithChiSq) )
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		return false;
	
	return true;		
}

bool		NLFitSession::GetVarCorrMatrix(matrix& mVarCorr, BOOL bScaleWithChiSq)
{
	if(!mVarCorr)
		return false;
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//if(m_NLFit.GetVarCorrMatrix(&mVarCorr, bScaleWithChiSq))
	CheckUpdateNLFitParamsLinking();
	if ( GetNLFitObj().GetVarCorrMatrix(&mVarCorr, bScaleWithChiSq) )
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		return false;
	
	return true;
}

/// Hong 01/13/10 QA80-13590-P8 MORE_CLEAR_ERR_MSG_FOR_INCOMPATIABLE_WEIGHTING_METHOD
static void get_more_clear_weight_method_err_msg(int nWeightMethod, int& nErrMsg)
{
	vector<int>		vnNoNegativeMissing = { // invalid value: negative/missing
		WEIGHT_DIRECT
	};
	vector<int>		vnNoZeroMissing = { // invalid value: zero/missing
		WEIGHT_INSTRUMENTAL, WEIGHT_ARBITRARY_DATASET, WEIGHT_INVERSE_DATA_SQUARED, WEIGHT_IRWLS_INVERSE_FUNC_VALUE_SQUARED
	};
	vector<int>		vnNoZeroNegativeMissing = { // invalid value: zero/negative/missing
		WEIGHT_STATISTICAL, WEIGHT_INVERSE_DATA_VALUE_A_B, WEIGHT_INVERSE_DATA_VALUE_A_B_WITH_ASSAY_SENSITIVITY_TERM,
		WEIGHT_INVERSE_DATA_VALUE_A_B_C_WITH_TIME_INFORMATION, WEIGHT_IRWLS_INVERSE_FUNC_VALUE, WEIGHT_IRWLS_INVERSE_FUNC_VALUE_A_B,
		WEIGHT_IRWLS_INVERSE_FUNC_VALUE_A_B_WITH_ASSAY_SENSITIVITY_TERM, WEIGHT_IRWLS_INVERSE_FUNC_VALUE_A_B_C_WITH_TIME_INFORMATION, WEIGHT_STATISTICAL_WITH_CUTOFF
	};
	if ( -1 != find_in_list(nWeightMethod, vnNoNegativeMissing, false) )
		nErrMsg = NLFIT_WEIGHTING_METHOD_NOT_ALLOW_NEGATIVE_MISSING;
	if ( -1 != find_in_list(nWeightMethod, vnNoZeroMissing, false) )
		nErrMsg = NLFIT_WEIGHTING_METHOD_NOT_ALLOW_ZERO_MISSING;
	if ( -1 != find_in_list(nWeightMethod, vnNoZeroNegativeMissing, false) )
		nErrMsg = NLFIT_WEIGHTING_METHOD_NOT_ALLOW_ZERO_NEGATIVE_MISSING;
}
/// end MORE_CLEAR_ERR_MSG_FOR_INCOMPATIABLE_WEIGHTING_METHOD

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//bool	NLFitSession::GetANOVAResult(RegANOVA &sRegANOVA, RegANOVARow &sCorrTotal, int nSetIndex, int nDepIndex)
//{
	///// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//if ( !hadBackupedFitResults() )
		//return getANOVAResult(sRegANOVA, sCorrTotal, nSetIndex, nDepIndex);
	//
	//if ( nSetIndex < 0 || nSetIndex >= m_arNLFitResults.GetSize() )
	//{
		//ASSERT(FALSE);
		//return false;
	//}
	//
	//sRegANOVA = m_arNLFitResults.GetAt(nSetIndex).stFitRegANOVAs;
	//sCorrTotal = m_arNLFitResults.GetAt(nSetIndex).stFitRegANOVARows;
	//return true;
	///// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//}
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT

string 		NLFitSession::GetFitOutCome(int nIterationOutCome)
{
	string 	str;
	bool	bCanHaveWeightDataErrMsg = false; /// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
	switch ( nIterationOutCome )
	{
	case FITITER_REACHED_TOLERANCE:
		ocu_load_msg_str(NLFIT_OUTCOME_REACHED_TOLERANCE, &str);
		break;
		
	case FITITER_COULD_NOT_REDUCE_CHISQ_AT_LAST_ITER:
		ocu_load_msg_str(NLFIT_OUTCOME_COULD_NOT_REDUCE_CHISQ_AT_LAST_ITER, &str);
		break;
		
	case FITITER_REDUCED_CHISQ:
		ocu_load_msg_str(NLFIT_OUTCOME_REDUCED_CHISQ, &str);
		break;
		
	case FITITER_MAX_ITER_REACHED:
		ocu_load_msg_str(NLFIT_OUTCOME_MAX_ITER_REACHED, &str);
		bCanHaveWeightDataErrMsg = true; /// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
		break;
		
	case FITITER_ABORT_BY_USER:
		ocu_load_msg_str(NLFIT_OUTCOME_ABORT_BY_USER, &str);
		break;
		
	case FITITER_FAILED_TO_REDUCE_CHISQR_DUE_TO_POOR_DATA:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_TO_REDUCE_CHISQR_DUE_TO_POOR_DATA, &str);
		bCanHaveWeightDataErrMsg = true; /// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
		break;
		
	case FITITER_FAILED_MUTUAL_DEPEND:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_MUTUAL_DEPEND, &str);
		bCanHaveWeightDataErrMsg = true; /// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
		break;
		
	case FITITER_FAILED_OTHER_REASONS:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_OTHER_REASONS, &str);
		bCanHaveWeightDataErrMsg = true; /// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
		break;
		
	case FITITER_FAILED_TO_REDUCE_CHISQR_NO_ITERATION:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_TO_REDUCE_CHISQR_NO_ITERATION, &str);
		bCanHaveWeightDataErrMsg = true; /// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
		break;
		
	case FITTTER_FAILED_FROM_FUNC:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_FROM_FUNC, &str);
		break;
		
	case FITITER_FAILED_NEGATIVE_ERROR_VALUE_FOR_WEIGHT:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_NEGATIVE_ERROR_VALUE_FOR_WEIGHT, &str);
		break;
		
	case FITITER_FAILED_NEGATIVE_WEIGHT:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_NEGATIVE_WEIGHT, &str);
		break;

	case FITITER_FAILED_ZERO_ERROR_NOT_CONSISTENT:
	case FITITER_FAILED_ZERO_YVALUE_NOT_CONSISTENT:
	case FITITER_VALUE_NOT_CONSISTENT_WITH_WEIGHTING_METHOD:
	{
		/// Hong 01/13/10 QA80-13590-P8 MORE_CLEAR_ERR_MSG_FOR_INCOMPATIABLE_WEIGHTING_METHOD
		//ocu_load_msg_str(NLFIT_OUTCOME_VALUE_NOT_CONSISTENT_WITH_WEIGHTING_METHOD, &str);
		int			nErrMsg = NLFIT_OUTCOME_VALUE_NOT_CONSISTENT_WITH_WEIGHTING_METHOD;
		int			nWeightMethod;
		double		dA, dB, dC;
		if ( GetOneWeight(0, 0, nWeightMethod, dA, dB, dC) )
			get_more_clear_weight_method_err_msg(nWeightMethod, nErrMsg);
		ocu_load_msg_str(nErrMsg, &str);
		/// end MORE_CLEAR_ERR_MSG_FOR_INCOMPATIABLE_WEIGHTING_METHOD
	}
		break;
		
	case FITITER_NO_ITERATE:
		str = "";
		break;
	///------ Folger 01/14/09 QA80-12955 FAIL_TO_OUTPUT_INVALID_SYNTAX_OF_CONSTRAINT_ERROR_MESSAGE
	case FITITER_FAILED_GENERAL_LINEAR_CONSTRAINTS:
		ocu_load_msg_str(NLFIT_OUTCOME_CONSTRBAD, &str);
		break;
	///------ End FAIL_TO_OUTPUT_INVALID_SYNTAX_OF_CONSTRAINT_ERROR_MESSAGE
	///------ Folger 02/09/09 QA80-13085 MORE_CLEAR_WAY_TO_INDICATE_MISSING_PARAMETERS_INSTEAD_OF_DISABLE_ITERATION
	case FITITER_FAILED_MISSING_PARAMS:
		{
			vector<int>		vnMissingParams;
			vector<string>	vsParamNames;
			m_pParamMngr->GetColumn(NLPARAMGRIDCOLTYPE_NAME, vsParamNames, FALSE);
			m_pParamMngr->IsParametersReady(&vnMissingParams);
			
			string	strNames;
			for ( int ii=0; ii<vnMissingParams.GetSize(); ++ii )
				strNames += vsParamNames[vnMissingParams[ii]] + ",";
			strNames.Delete(strNames.GetLength() - 1);
				
			ocu_load_msg_str(NLFIT_OUTCOME_FAILED_MISSING_PARAMS, &str, strNames);
		}
		break;
	///------ End MORE_CLEAR_WAY_TO_INDICATE_MISSING_PARAMETERS_INSTEAD_OF_DISABLE_ITERATION
	/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	case FITITER_FIT_NOT_COMPLETE:
		ocu_load_msg_str(NLFIT_OUTCOME_FAILED_FIT_NOT_COMPLETE, &str);
		break;
	/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	default:
		ocu_load_msg_str(NLFIT_OUTCOME_INVALID, &str);
		bCanHaveWeightDataErrMsg = true; /// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
		break;
	}
	/// Hong 07/09/10 ORG-512 NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
	if ( bCanHaveWeightDataErrMsg && !IsNoneWeight(0) )
	{
		string		strErrMsg;
		if ( ocu_load_msg_str(NLFIT_OUTCOME_FAILED_WITH_WEIGHT_DATA, &strErrMsg) )
			str += "\r\n" + strErrMsg;
	}
	/// end NLFIT_BETTER_OUTPUT_MSG_FOR_WEIGHT_DATA
	return str;
}

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//string  	NLFitSession::GetFitOutCome(bool bTrimDetails)
//{
//	string 			str = GetFitOutCome(m_nLastIterateOutCome);
string  	NLFitSession::GetFitOutCome(bool bTrimDetails/* = true*/, int nSetIndex/* = 0*/)
{	
	string 			str = GetFitOutCome(GetLastIterateOutCome(nSetIndex));
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

	//------ Folger 11/06/08 QA80-12113 v0.966 FIX_GIBBERISH_SHOWN_IN_NLFIT_WHEN_FITTING_DID_NOT_CONVERGED
	/*
	if(bTrimDetails)
	{
		vector<string> 	vsItems;
		if( str_separate(str, " - ", vsItems) > 0)
		{
			str = vsItems[0];
		}
	}
	*/
	/// the second condition is for Japanese only, since "-" is localized to "£º" ("\0x81\0x46")
	/// which may fail to separate the fit result and the reason.
	if(bTrimDetails)
	{
		int		nPos = -1;
		string	strSeparatorJ;
		strSeparatorJ.Format("%c%c", 0x81, 0x46);
		if ( (nPos = str.Find(" - ")) >= 0 || (nPos = str.Find(strSeparatorJ)) >= 0 )
		{
			str = str.Left(nPos);
			str.TrimLeft();
			str.TrimRight();
		}
	}
	//------ End FIX_GIBBERISH_SHOWN_IN_NLFIT_WHEN_FITTING_DID_NOT_CONVERGED	
	
	return str;
}

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
void		NLFitSession::ResetFitOutCome()
{		
	for ( int ii = 0; ii < m_vnLastIterateOutCome.GetSize(); ++ii )
	{
		m_vnLastIterateOutCome[ii] = FITITER_NO_ITERATE;
	}
}
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

bool		NLFitSession::IsNoneWeight(int nSetIndex)
{
	if ( m_pDataObj->IsExceedLimitation(nSetIndex) )
		return FALSE;
	
	PONEDATAWEIGHT	pOneDataWeight = m_pDataObj->GetWeightDatas();
	if ( !pOneDataWeight )
		return FALSE;
	
	return WEIGHT_NONE == pOneDataWeight[nSetIndex].method;
}

/// Jack 12/19/2008 QA80-12329 MULTI_INDEP_DEPS_BAND_CALCULATION

/// Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
bool 		NLFitSession::calcConfAndPredBands(const vector* pvIndeps, int nNumIndeps, double rPerc, vector& vLower, vector& vUpper, BOOL bConf, int iDep, int iSet)
{
	if(nNumIndeps > MAX_INDEP_DATASET_NUMBER)
		return false;
	NLSFONEDATA multiIndepData[MAX_INDEP_DATASET_NUMBER];
	for(int iIndep = 0; iIndep < nNumIndeps; iIndep++)
	{
		multiIndepData[iIndep].pdData = pvIndeps[iIndep];
		multiIndepData[iIndep].nSize = pvIndeps[iIndep].GetSize();
		if(vLower.GetSize() != pvIndeps[iIndep].GetSize() || vUpper.GetSize() != pvIndeps[iIndep].GetSize())
			return false;
	}
	
	CheckUpdateNLFitParamsLinking(iSet);
	NLFit&		refNLFitObj = GetNLFitObj(iSet);
	
	if ( refNLFitObj.CalcConfAndPredBands(&multiIndepData, nNumIndeps, rPerc, vLower, vUpper, bConf, iDep, GetDatasetIndexInNLFit(iSet)) )
		return true;
	return false;
}
///End CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION

bool		NLFitSession::CalcConfAndPredBands(const matrix& mIndeps, double rPerc, vector& vLower, vector& vUpper, BOOL bConf, int iDep, int iSet)
{
	vector vMultiIndeps[MAX_INDEP_DATASET_NUMBER];
	if(!mIndeps || mIndeps.GetNumCols() < 1)
		return false;
	if(mIndeps.GetNumRows()<1)
		return false;
	
	int nNumIndeps = mIndeps.GetNumCols();
	ASSERT(nNumIndeps<=MAX_INDEP_DATASET_NUMBER);
	
	if(nNumIndeps > MAX_INDEP_DATASET_NUMBER)
		return false;
	
	vector vIndep;
	for(int ncol=0; ncol<nNumIndeps; ncol++)
	{
		mIndeps.GetColumn(vIndep, ncol);
		vMultiIndeps[ncol] = vIndep;
	}

/// Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION
	//NLSFONEDATA multiIndepData[MAX_INDEP_DATASET_NUMBER];
	//for(int iIndep = 0; iIndep < nNumIndeps; iIndep++)
	//{
		//multiIndepData[iIndep].pdData = vMultiIndeps[iIndep];
		//multiIndepData[iIndep].nSize = vMultiIndeps[iIndep].GetSize();
		//if(vLower.GetSize() != vMultiIndeps[iIndep].GetSize() || vUpper.GetSize() != vMultiIndeps[iIndep].GetSize())
			//return false;
	//}
	//
	//CheckUpdateNLFitParamsLinking(iSet);
	//NLFit&		refNLFitObj = GetNLFitObj(iSet);
	//
	//if ( refNLFitObj.CalcConfAndPredBands(&multiIndepData, nNumIndeps, rPerc, vLower, vUpper, bConf, iDep, GetDatasetIndexInNLFit(iSet)) )
		//return true;
	//return false;
	return calcConfAndPredBands(vMultiIndeps, nNumIndeps, rPerc, vLower, vUpper, bConf, iDep, iSet);
/// End CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION

}
/// End MULTI_INDEP_DEPS_BAND_CALCULATION


/// NLF_81 Iris
//bool		NLFitSessionBase::CalcConfAndPredBands(vector vMultiIndeps[], int nNumIndep, double rPerc, vector& vLower, vector& vUpper, BOOL bConf, int iDep)
/// Jack 10/20/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
//bool		NLFitSession::CalcConfAndPredBands(const vector& vIndep1, double rPerc, vector& vLower, vector& vUpper, BOOL bConf, int iDep, const vector& vIndep2)
bool		NLFitSession::CalcConfAndPredBands(const vector& vIndep1, double rPerc, vector& vLower, vector& vUpper, BOOL bConf, int iDep, const vector& vIndep2, int iSet)
/// End CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
///end NLF_81
{
	/// Hong, to do, code below need improvement, badly hard coded
	////////copy from FitNL.cpp, need to clean in NLFitSession, so change the argument list for this method//////	
	int nNumIndep = 1;
	vector vMultiIndeps[MAX_INDEP_DATASET_NUMBER];
	if(!vIndep1 || vIndep1.GetSize() < 1)
		return false;
	
	vMultiIndeps[0] = vIndep1;
	if(vIndep2 && vIndep2.GetSize() > 0)
	{
		vMultiIndeps[1] = vIndep2;
		nNumIndep = 2;
	}
	//////end
	
	
	////////copy from NLFitSession::CalcConfAndPredBands//////
	if(nNumIndep > MAX_INDEP_DATASET_NUMBER)
		return false;

/// Jack 12/25/2008 QA80-12329 CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION	
	//NLSFONEDATA multiIndepData[MAX_INDEP_DATASET_NUMBER];
	//for(int iIndep = 0; iIndep < nNumIndep; iIndep++)
	//{
		//multiIndepData[iIndep].pdData = vMultiIndeps[iIndep];
		//multiIndepData[iIndep].nSize = vMultiIndeps[iIndep].GetSize();
		//if(vLower.GetSize() != vMultiIndeps[iIndep].GetSize() || vUpper.GetSize() != vMultiIndeps[iIndep].GetSize())
			//return false;
	//}
	/////Jack 10/20/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
	////if(m_NLFit.CalcConfAndPredBands(&multiIndepData, nNumIndep, rPerc, vLower, vUpper, bConf, iDep))
	////	return true;
	/////Jack 07/11/08 QA70-12329 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_SET_SEP_FIT
	////if(m_NLFit.CalcConfAndPredBands(&multiIndepData, nNumIndep, rPerc, vLower, vUpper, bConf, iDep, iSet))
	////	return true;
	//
	///// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//CheckUpdateNLFitParamsLinking(iSet);
	//NLFit&		refNLFitObj = GetNLFitObj(iSet);
	///// FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/////---------Jack -by the suggestion of Hong Change into an equivalent logic form
	///*
	//if(isGlobalFit())
	//{
		//if(m_NLFit.CalcConfAndPredBands(&multiIndepData, nNumIndep, rPerc, vLower, vUpper, bConf, iDep, iSet))
			//return true;		
	//}
	//else
	//{
		//if(m_NLFit.CalcConfAndPredBands(&multiIndepData, nNumIndep, rPerc, vLower, vUpper, bConf, iDep))
			//return true;
	//}
	//*/
	///// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	////if(!isGlobalFit()) /// use the default value of iSet if it is not global fit
	////{
	////	iSet = 0;
	////}	
	////if(m_NLFit.CalcConfAndPredBands(&multiIndepData, nNumIndep, rPerc, vLower, vUpper, bConf, iDep, iSet))
	//if ( refNLFitObj.CalcConfAndPredBands(&multiIndepData, nNumIndep, rPerc, vLower, vUpper, bConf, iDep, GetDatasetIndexInNLFit(iSet)) )
	///// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		//return true;
	/////
	//
	/////End	CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_SET_SEP_FIT
	//
	/////end CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
		//
	////////end
	//
	//return false;

	return calcConfAndPredBands(vMultiIndeps, nNumIndep, rPerc, vLower, vUpper, bConf, iDep, iSet);
///End CENTRALIZE_MULTI_INDEP_DEPS_BAND_CALCULATION	
}
///end 	CALC_CONFIDENCE_AND_PREDICTION_BANDS

bool 		NLFitSession::SetAutoInitParams(bool bAuto) // = true
{
	/// Hong 10/16/08 v8.0956 FIX_MUTIL_FUNCS_AUTO_INIT_SHOULD_NOT_DEPENDENT_ON_FDF
	if ( NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS != getParamsType() )
	{
	/// end FIX_MUTIL_FUNCS_AUTO_INIT_SHOULD_NOT_DEPENDENT_ON_FDF
		// Hong, to do, i think no need do such checking as init should do nothing if no initial code
		TreeNode trFDF = GetTreeFDF();
		/// Iris 9/22/2008 NEW_PA, to centralize code, nlsf_get_param_init_code returns false means not param init code or empty
		//TreeNode trParamsInitScript = trFDF.ParametersInitialization.Script;
		//if ( !trParamsInitScript )
			//bAuto = false;
		//else
		//{
			//string strParamsInitCode = trParamsInitScript.strVal;
			//ocu_skip_C_comments(&strParamsInitCode);
			//strParamsInitCode.TrimLeft();
			//strParamsInitCode.TrimRight();
			//if(strParamsInitCode.IsEmpty())
				//bAuto = false;
		//}
		string	strCode;
		if( !nlsf_get_param_init_code(trFDF, strCode) && bAuto )
			bAuto = false;
		////end NEW_PA
	} /// Hong 10/16/08 v8.0956 FIX_MUTIL_FUNCS_AUTO_INIT_SHOULD_NOT_DEPENDENT_ON_FDF
	
	bool bOldVal = m_bAutoRunInitParams;
	m_bAutoRunInitParams = bAuto;	
	return bOldVal;
}

bool		NLFitSession::SetReplicaAutoInitParamInfoTree(const TreeNode& trReplicaInitParam)
{
	if ( !trReplicaInitParam )
		return false;
	
	m_trReplicaInitParam = trReplicaInitParam;
	return true;
}

//bool		NLFitSession::ParamsInitValues(bool bRunParamInit, DWORD dwInitCtrl) // = true, 0
bool		NLFitSession::ParamsInitValues(bool bRunParamInit, DWORD dwInitCtrl, int nFunc) // = true, 0, -1
{
	if ( GetNumDataset() <= 0 )
		return error_report("ParamsInitValues found data not setup yet");
	
	if ( GetNumberFitFunctions() <= 0 )
		return error_report("ParamsInitValues found fucntioin not setup yet");
	
	if ( nFunc < -1 )
		return error_report("Invalid function index.");

	m_bInitParamsSucceed = false;
	
	bool	bParamValChanged 		= false;
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//bool	bFromThemeChange 		= dwInitCtrl & NLF_THEME_CHANGE;	
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	bool	bKeepOldSetting			= dwInitCtrl & NLF_KEEP_OLD_DATASET;
	bool	bResetSharedAndFixed 	= dwInitCtrl & NLF_RESET_SHARE_FIX;
		
	int 	nFuncIndex = nFunc, nCount = nFunc + 1;
	if ( -1 == nFunc )
	{
		nFuncIndex = 0;
		nCount = GetNumberFitFunctions();
	}
	for ( ; nFuncIndex < nCount; nFuncIndex++ )
	{
		NumericFunction fn;
		if ( !fn.SetTree(GetTreeFDF(nFuncIndex)) )
			return error_report("ParamsInitValues Invalid function");
				
		if ( bResetSharedAndFixed ) // Hong, to do, i wandering if this can be remove, as i remembered trUserParamsSetting is feature throwed away which is the only place want to reset fix&share
		{
			// Hong, to do, need a method is retrieve the correct count of all parameters for one function
		}
	
		/// Hong 19/05/08 NEW_PARAM_MNGR
		//int 	nNumParaInFunc 	= GetFitFunction(nFunc)->GetNumParaInFunc();
		int 	nNumParaInFunc 	= GetNumParameter(nFuncIndex);
		/// end NEW_PARAM_MNGR		
		vector 	vParamValue;
		//if not auto init, each data set should use same params value if use same func tree
		if ( !bRunParamInit )
		{	
			//----- Iris 11/27/2008 v8.0980 PA_IMPROVE_PARAM_INIT_IF_LOAD_PARAM_SETTINGS_FROM_FDF
			//if ( getParamsInitInfo(nFuncIndex, vParamValue) != nNumParaInFunc )
			if ( GetParamsInitInfo(nFuncIndex, vParamValue) != nNumParaInFunc )
			//-----	
				return error_report("Parameter Init fail");
			/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
			/*
			if ( bFromThemeChange )
			{
				// enlarge vector to put all values into vParamValue
				vParamValue.SetSize(m_vbFixed.GetSize());
				TreeNode 	trValues 	= m_trOpParams.Values;
				int 		nNumCopied 	= octree_value_from_tree_sub_nodes_to_vector_double(&trValues, &vParamValue);
				// reset size to values in theme tree
				vParamValue.SetSize(nNumCopied);
	
				int		n1stFuncNumParms = GetNumTotalParams(0);
				if ( nNumCopied > n1stFuncNumParms )
				{
					int		nFrom = 0;
					GetParamsSubVectorRange(0, nFuncIndex, &nFrom);
					vParamValue.GetSubVector(vParamValue, nFrom);			
				}
				else
				{
					trimOffsetParameter(vParamValue, nFuncIndex);
				}
			}
			*/
			/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
		}

		/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
		//int	nDataset = (bKeepOldSetting && !bFromThemeChange) ? m_nOldNumberDataset : 0;
		int	nDataset = bKeepOldSetting ? m_nOldNumberDataset : 0;
		/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
		for ( ; nDataset < GetNumDataset(); nDataset++ )
		{
			if ( bRunParamInit )
			{				
				if ( !getParamInitValues(fn, nDataset, vParamValue) || vParamValue.GetSize() != nNumParaInFunc )
					return error_report("Parameter Init fail");				
			}
			
			if ( !(isMultiplicityFit() && bRunParamInit) )
			{
				/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
				//int nFrom = 0;
				//GetParamsSubVectorRange(nDataset, nFuncIndex, &nFrom);
				//for ( int nIndex = 0 ; nIndex < vParamValue.GetSize(); nIndex++ )
				//{				
					//if ( nFrom + nIndex >= GetNumTotalParams(nFuncIndex) )
						//break;
					//if ( m_pParamMngr->SetOneFuncParam(nFuncIndex, nDataset, nFrom + nIndex, &vParamValue[nIndex]) )
						//return error_report("Fail to set parameter");
				//}
				//// refer to comment // enlarge vector to put all values into vParamValue above of copy values from theme
				//if ( vParamValue.GetSize() > GetNumTotalParams(nFuncIndex) )
				//{	// trim the value that already applied
					//vParamValue.GetSubVector(vParamValue, GetNumTotalParams(nFuncIndex));
				//}	
				for ( int nIndex = 0 ; nIndex < vParamValue.GetSize(); nIndex++ )
				{
					if ( m_pParamMngr->SetOneFuncParam(nFuncIndex, nDataset, nIndex, &vParamValue[nIndex]) )
						return error_report("Fail to set parameter");
				}
				/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
				///Sophy 11/4/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
				m_vYCenter.SetSize(0);
				m_vXCenter.SetSize(0);
				///end ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
			}			
			else
			{
				if ( !replicaAutoInitParams(nFuncIndex, nDataset, vParamValue) )
					return error_report("Auto init values of parameters for replica failed!");
			}
			bParamValChanged = true;
		}
	}	
	m_bInitParamsSucceed = true;

	
	/// Hong 09/10/08 v8.0936b FIX_FIT_OUTPUT_NOT_RESET_AFTER_PARAMS_INIT
	NLFitReset(ONLSF8RESET_PARAMETERS);
	/// end FIX_FIT_OUTPUT_NOT_RESET_AFTER_PARAMS_INIT
	
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//if( !bFromThemeChange && bParamValChanged )
	if( bParamValChanged )
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	{
		m_bParamsFromAutoInit = true; /// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
		if ( isMsgLogAvailable() )
		{
			string	strMsg;
			ocu_load_msg_str(NLFIT_MSG_LOG_PARAM_INIT_CALLED, &strMsg);			
			writeMsgLog(strMsg);
		}
	}
	
	return UpdateParams(false, false, STR_ON_PARAM_INIT);	
}

int 		NLFitSession::GetNumTotalParams(int nFunc) // = -1
{
	/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	/*
	//----- CPY 4/4/08 NLFIT_REPLICA_BROKEN_DUE_TO_FOLGER_11364
	// temp solution, will wait for later rewrite with separate class
	if ( nFunc <= 0 )
	{
		//NLFitFunction* pFitFunc = GetFitFunction(0);
		//int nMultiplicity = pFitFunc->GetNumMultiplicity();
		//if(nMultiplicity > 1)
		if ( GetNumberMultiplicity() > 1 )
			return GetParamsSubVectorRange(0, 0);
	}
	//-----
	
	int		nNumTotalParams = 0;
	for ( int Index = 0; Index < GetNumberFitFunctions(); Index++ )
	{
		if(nFunc >= 0 && Index != nFunc)
			continue;
		//------ Folger 04/03/08 QA80-11364 IMRPOVE_FIT_SESSION_SET_FUNCTION_LOOP_IN_PA
		//nNumTotalParams += GetParamsSubVectorRange(0, Index); //GetNumTotalParams is only for one dataset
		/// Hong 19/05/08 NEW_PARAM_MNGR
		//NLFitFunction* pFitFunc = GetFitFunction(Index);
		//nNumTotalParams += pFitFunc->GetNumParaInFunc();
		nNumTotalParams += GetNumParameter(Index);
		/// end NEW_PARAM_MNGR
		//------
	}
	*/	
	if ( -1 == nFunc || nFunc >= GetNumberFitFunctions() )	
		nFunc = GetNumberFitFunctions() - 1;
	
	int			nNumTotalParams = 0, nCount = nFunc + 1;	
	for ( int Index = 0; Index < nCount; Index++ )
	{
		/// Hong 09/16/08 FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK
		//nNumTotalParams += GetNumParameter(Index); // Hong, to do, GetNumParameter will to return correct number when have replica
		nNumTotalParams += GetNLParamsMngr()->GetNumParamsInFunc(Index);
		/// end FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK
	}
	return nNumTotalParams;
}
///Sophy 10/17/2008 FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
//int			NLFitSession::GetParamNamesInFunction(vector<string>& vstrParamNames, int nFunc) // = 0
int			NLFitSession::GetParamNamesInFunction(vector<string>& vstrParamNames, int nFunc, bool bTrimPostfix ) // = 0, false
///end FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
{
	StringArray	saParamNames;
	///Sophy 10/17/2008 FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
	//if ( !getParamStringValues(NLPARAMGRIDCOLTYPE_NAME, saParamNames) )
		//return 0;
	if( !m_pParamMngr->GetAllParameterNames( saParamNames, bTrimPostfix ) )
		return 0;
	///end FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
	
	/// Hong 09/22/08 v8.0944b FIX_PA_NEED_GET_ALL_PARAMS_IN_ONE_CALL
	if ( -1 == nFunc )
	{
		vstrParamNames = saParamNames;
		return vstrParamNames.GetSize();
	}
	/// end FIX_PA_NEED_GET_ALL_PARAMS_IN_ONE_CALL
		
	int		nFrom = 0;
	GetParamsSubVectorRange(0, nFunc, &nFrom);
	
	/// Hong 19/05/08 NEW_PARAM_MNGR
	//int 	nNumParaInFunc = GetFitFunction(nFunc)->GetNumParaInFunc();
	/// Hong 09/24/08 v8.0946 ROLLBACK_OLD_CODE_ADS_FITNL_CREATE_REPLICA_ITSELF, need check if need clean such code in FitNL
	///// Hong 09/16/08 FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK	
	int 	nNumParaInFunc = GetNumParameter(nFunc); // Hong, to do, this is not correct as it fail to handle replica.
	//int 	nNumParaInFunc = GetNLParamsMngr()->GetNumParamsInFunc(nFunc);
	///// end FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK
	/// end ROLLBACK_OLD_CODE_ADS_FITNL_CREATE_REPLICA_ITSELF
	/// end NEW_PARAM_MNGR
	vstrParamNames.SetSize(nNumParaInFunc);	
	for ( int ii = 0; ii < nNumParaInFunc; ii++ )
	{
		if ( ii + nFrom >= saParamNames.GetSize() )	
			break;
		
		vstrParamNames[ii] = saParamNames[nFrom + ii];
	}

	return nNumParaInFunc;	
}

///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
int			NLFitSession::GetParamUnitsInFunction(vector<string>& vstrParamUnits, int nFunc ) // = 0
{
	StringArray	saParamUnits;
	if( !m_pParamMngr->GetColumn( NLPARAMGRIDCOLTYPE_UNIT, saParamUnits, false ) )
		return 0;

	if ( -1 == nFunc )
	{
		vstrParamUnits = saParamUnits;
		return vstrParamUnits.GetSize();
	}

	int		nFrom = 0;
	GetParamsSubVectorRange(0, nFunc, &nFrom);

	int 	nNumParaInFunc = GetNumParameter(nFunc); // Hong, to do, this is not correct as it fail to handle replica.
	vstrParamUnits.SetSize(nNumParaInFunc);
	for ( int ii = 0; ii < nNumParaInFunc; ii++ )
	{
		if ( ii + nFrom >= saParamUnits.GetSize() )	
			break;
		
		vstrParamUnits[ii] = saParamUnits[nFrom + ii];
	}

	return nNumParaInFunc;
}
///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT

/// NLF_81 Iris, need to move to NLParam.h later
int		NLFitSession::GetParameterNames(vector<string> &vstrParameterNames, int nDataset, int nNumData, bool bIncNumPostfix, bool bIncDerivedParams, vector<bool>& vbIsDerived)
{
	vstrParameterNames.RemoveAll();
	if(  NULL != vbIsDerived )
		vbIsDerived.RemoveAll();
	
	int 	nNumberFunctions = GetNumberFitFunctions();		
	for ( int nFunc = 0; nFunc < nNumberFunctions; nFunc++ )
	{
		vector<string> 		vsParams;
		int					nNumParamsInFunc = GetParamNamesInFunction(vsParams, nFunc);
		if(  NULL != vbIsDerived )
		{
			vector<bool>		vbIsDerivedOne(vsParams.GetSize());
			vbIsDerivedOne = false;
			vbIsDerived.Append(vbIsDerivedOne);
		}
		
		if( bIncDerivedParams )
		{
			vector<string> 	vsDerivedParamNames;
			if( GetDerivedParameters(nDataset, &vsDerivedParamNames) )
			{
				vsParams.Append(vsDerivedParamNames);
				
				if(  NULL != vbIsDerived )
				{
					vector<bool>		vbIsDerivedOne(vsDerivedParamNames.GetSize());
					vbIsDerivedOne = true;
					vbIsDerived.Append(vbIsDerivedOne);
				}
			}	
		
		}
		
		if( bIncNumPostfix )
		{
			for(int ii = 0; ii < vsParams.GetSize(); ii++)
			{
				string			str = vsParams[ii];	
				if( nNumberFunctions > 1 )
				{
					str = str + "__" + (string)(nFunc+1);
				}
				
				if( nNumData > 1 )
				{
					str = str + "_" + (string)(nDataset+1);
				}			
				vstrParameterNames.Add(str);			
			}	
		}
		else
		{
			vstrParameterNames.Append(vsParams);
		}
	}		
	return vstrParameterNames.GetSize();
}
/// end NLF_81 Iris
				
/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//int		NLFitSession::GetFitResultsParams(FitParameter* pFitParameter, RegStats *pstRegStats, int nDataset, bool bIncDerivedParams) //= 0, = false
//{
	///// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT	
	//ASSERT(pFitParameter);
		//
	//if ( !hadBackupedFitResults() )
		//return getFitResultsParams(pFitParameter, pstRegStats, nDataset, bIncDerivedParams);
				//
	//if ( nDataset < 0 || nDataset >= m_arNLFitResults.GetSize() )
	//{
		//ASSERT(FALSE);
		//return -1;	
	//}
//
	//NLFitResults&	refNLFitResults = m_arNLFitResults.GetAt(nDataset);
	//for ( int ii = 0; ii < refNLFitResults.arFitParamResults.GetSize(); ii++ )
	//{
		//*pFitParameter = refNLFitResults.arFitParamResults.GetAt(ii);
		//++pFitParameter;
	//}
	//return GetNumParameter(); // Hong, to do, This return value is very confuse
	///// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//}
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT

///Kyle 10/10/08 ADD_FUNCTION_GETFITRESULTSPARAMS_USED_IN_PA_BASECREATE
int	NLFitSession::GetFitResultsParams(vector& vParams, vector& vErrors)
{
	int nNumParaInFunc = GetNumParameter();
	vParams.SetSize(nNumParaInFunc);
	vErrors.SetSize(nNumParaInFunc);
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//if(m_NLFit.GetParameterResults(&vParams, &vErrors) == 0) // no err
	CheckUpdateNLFitParamsLinking();
	if ( GetNLFitObj().GetParameterResults(&vParams, &vErrors) == 0 ) // no err
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		return nNumParaInFunc;
		
	return -1;
}
///End ADD_FUNCTION_GETFITRESULTSPARAMS_USED_IN_PA_BASECREATE

int			NLFitSession::GetDerivedParameters(int nDataset, FitDerivedParameter* pstDerivedParams, int nSize)
{
	if ( NULL == pstDerivedParams )
		return 0;
	
	vector<string>	vsNames;
	vector<double> 	dVals;
	///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	vector<string> vsUnits;
	//if ( !GetDerivedParameters(nDataset, &vsNames, &dVals) )
	if ( !GetDerivedParameters(nDataset, &vsNames, &dVals, &vsUnits) )
	///End ADD_UNIT_FOR_PARAMETER_SETTINGS
		return 0;
	
	int				numParams = dVals.GetSize();
	for ( int ii = 0; ii < nSize; ii++ )
	{
		if ( ii > numParams )
			break;

		pstDerivedParams[ii].Value = dVals[ii];
	}
	
	return numParams / GetNumberMultiplicity();		
}

/// Hong 10/23/08 QA80-12434 TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS
bool 		NLFitSession::getReducedChiSq(const TreeNode& trOp, double& dSSE, int nSetIndex/* = 0*/, int nDepIndex/* = 0*/)
{
	ASSERT(trOp.GUI.InputData);
	int		nFitMode = trOp.GUI.InputData.Use;
	ASSERT( nFitMode == m_nCurrDataMode );
	bool	bStatsPreDataset = (DATA_MODE_GLOBAL == nFitMode) ? true : false;
	NLSFFitInfo		sFitInfo;
	RegStats		sRegStats;
	if(DATA_MODE_GLOBAL == nFitMode)
	{
		if(GetFitResultsStats(&sRegStats, &sFitInfo, false))
		{
			dSSE = sRegStats.ReducedChiSq;
			return true;
		}
		else
			return false;
	}
	else
	{
		if( GetFitResultsStats(&sRegStats, &sFitInfo, bStatsPreDataset, nSetIndex, nDepIndex) )
		{
			dSSE = sRegStats.ReducedChiSq;
			return true;
		}
		else
			return false;
	}
}
/// end TAKE_BACK_CODE_OF_CALCULATE_RESIDUAL_DATAS

/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
///Jasmine 10/27/07 QA70-10543 PFM_TREE_STRUCTURE_CHANGE
int			NLFitSession::GetDerivedParamNum(int nFunc/* = 0*/)
{
	TreeNode 	trFDF = GetTreeFDF(nFunc);
	if ( trFDF.DerivedParameters )
		return trFDF.DerivedParameters.GetNodeCount();
	
	return 0;
}
///End PFM_TREE_STRUCTURE_CHANGE

// Hong, to do, this should be remove or replace by parameter manager as only it has this knowledge, maybe FitNL should clean up to avoid calling such functions
///Jasmine 08/13/08 QA80-12009 PARAM_HAS_SAME_NOTATION_AS_75_FOR_MULTI_DS_AND_REPLICA_AND_PEAK
string 		NLFitSession::GetMultiDataParamIndexedName(LPCSTR lpcszName, int nIndex)
{
	string str;
	str.Format("%s_%d", lpcszName, nIndex);
	return str;
}
string 		NLFitSession::GetReplicaParamIndexedName(LPCSTR lpcszName, int nIndex)
{
	string str;
	str.Format("%s__%d", lpcszName, nIndex);
	return str;	
}

string 		NLFitSession::GetPeakParamIndexedName(LPCSTR lpcszName, int nIndex)
{
	string str;
	str.Format("%s__%d", lpcszName, nIndex);
	return str;	
}
///End PARAM_HAS_SAME_NOTATION_AS_75_FOR_MULTI_DS_AND_REPLICA_AND_PEAK
/// end FITNL_USING_NEW_NLFSESSION

bool		NLFitSession::HasSharedParameters()
{
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	vector<int>		vnShared;
	if ( !getParamNumericValues(NLPARAMGRIDCOLTYPE_SHARE, vnShared) )
		return false;
	
	for ( int ii = 0; ii < vnShared.GetSize(); ii++ )
	{
		if ( 1 == vnShared[ii] )
			return true;
	}
	
	return false;
	/// end FITNL_USING_NEW_NLFSESSION	
}

bool		NLFitSession::HasFixedParameters()
{
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	vector<int>		vnFixed;
	if ( !getParamNumericValues(NLPARAMGRIDCOLTYPE_FIXED, vnFixed) )
		return false;
	
	for ( int ii = 0; ii < vnFixed.GetSize(); ii++ )
	{
		if ( 1 == vnFixed[ii] )
			return true;
	}
	
	return false;
	/// end FITNL_USING_NEW_NLFSESSION	
}
void		NLFitSession::GetSharedVector(vector<bool>& vbIsShared)
{	
	if ( !getParamNumericValues(NLPARAMGRIDCOLTYPE_SHARE, vbIsShared) )
		return ;
	int nNumParaInFunc = GetNumParameter();
	vbIsShared.SetSize(nNumParaInFunc);
	
}

/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
int			NLFitSession::GeNumtNonSharedParams(int nNumParaInFunc/* = -1*/)
{
	if ( nNumParaInFunc < 0 )
		nNumParaInFunc = GetNumParameter(-1); // Hong, to do, what for nFunc??
	
	vector<int>		vnShared;
	getParamNumericValues(NLPARAMGRIDCOLTYPE_SHARE, vnShared);	
	int				nNumUnSharedPara = 0;
	for ( int ii=0; ii < nNumParaInFunc; ii++ )
	{
		if ( ii >= vnShared.GetSize() )
			break;
		
		if ( 0 == vnShared[ii] )
			nNumUnSharedPara++;
	}	
	return nNumUnSharedPara;	
}
/// end FITNL_USING_NEW_NLFSESSION

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
/////Arvin 06/12/07 RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS 
//int 		NLFitSession::GetParamsActualIndex(int nNumParaInFunc, int nDataSet, int nParamIndex)
//{
	//if ( NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS == getParamsType() )
	//{
		//return nParamIndex;
	//}
	//
	//if(nParamIndex < 0 || nParamIndex >= nNumParaInFunc)
		//return -1;
	//
	//int nActualIndex = nParamIndex;
	//int nUnSharedParams = GeNumtNonSharedParams(nNumParaInFunc);
	//int nBeforeShared = 0;
	//
	//vector<int>		vnShared;
	//if ( !getParamNumericValues(NLPARAMGRIDCOLTYPE_SHARE, vnShared) )
		//return -1;
	//if(nDataSet > 0 && !vnShared[nParamIndex])
	//{
		//for(int ii = 0; ii < nParamIndex; ii++)
		//{
			//if(vnShared[ii])
				//nBeforeShared++;
		//}
		//nActualIndex = nNumParaInFunc + (nDataSet-1)*nUnSharedParams + nParamIndex - nBeforeShared; 
	//}
		//
	//return nActualIndex;	
//}
//
//void		NLFitSession::GetParamsLowerUpperConfBound(vector& vConfLower, vector& vConfUpper)
//{
	/////Sophy 10/15/2008 CENTRALIZE_CODE_TO_UPDATE_LCL_UCL_SETTINGS
	///*
	//vector		vParamValues;
	//getParamNumericValues(NLPARAMGRIDCOLTYPE_VALUE, vParamValues);
	//if( CONF_LIMIT_METHOD_MODLE_COMP_BASED == m_nConfLimitMethod)
	//{
		//m_NLFit.ComputeParametersConfidenceLimits(&vConfLower, &vConfUpper);
	//}
	//else
	//{
		/////Arvin 06/12/07 RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS 
		////Add missing value for surplus shared params, then get right value according to m_vbShared
		////m_vConfLower = m_vParamValues - m_vConfLimits;
		////m_vConfUpper = m_vParamValues + m_vConfLimits;
		//vector		vConfLimits;
		//m_NLFit.GetParameterResults(NULL, NULL, &vConfLimits);
		//while(vConfLimits.GetSize() < vParamValues.GetSize())
			//vConfLimits.Add(NANUM);
			//
		//vConfLower = vParamValues - vConfLimits;
		//vConfUpper = vParamValues + vConfLimits;
		/////end RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS
	//}
	//*/
	///// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	////m_NLFit.ComputeParametersConfidenceLimits(&vConfLower, &vConfUpper, m_nConfLimitMethod );
	//GetNLFitObj().ComputeParametersConfidenceLimits(&vConfLower, &vConfUpper, m_nConfLimitMethod );
	///// end /// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/////end CENTRALIZE_CODE_TO_UPDATE_LCL_UCL_SETTINGS
//}
/////end RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT

/// Hong 09/24/09 QA80-12199 FIT_LT_CALL_SPEED_UP_MOVE_CODE_TO_VC
double		NLFitSession::GetBaseline()
{
	double		dVal = 0.0;
	///Kyle 10/21/08 CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE
	//if ( !HasBaselinePeak() )
	if ( !GetBaselineFitMode() )
	///End CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE
	{
		vector		vParams;
		const int	nBaselineParamIndex = 0;
		GetNLParamsMngr()->GetParamValues(vParams);
		if ( vParams.GetSize() > nBaselineParamIndex )
			dVal = vParams[nBaselineParamIndex];
	}
	return dVal;
}
/// end FIT_LT_CALL_SPEED_UP_MOVE_CODE_TO_VC

/// Hong 09/02/08 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
bool		NLFitSession::IsAllowSharing()
{
	if ( isMultiplicityFit() )
		return true;
	
	if ( GetNumDataset() > 1 && DATA_MODE_GLOBAL == m_nCurrDataMode )
		return true;
	
	return false;	
}
/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
///Sophy 9/9/2008 UPDATE_REPLICA_PREVIEW_FOR_NLF_81
bool	NLFitSession::IsAutoRunInitParams(bool bChkAutoUpdateCkBox)
{
	if(bChkAutoUpdateCkBox && m_bDisableUpdate)
		return false;

	return m_bAutoRunInitParams;
}
///end UPDATE_REPLICA_PREVIEW_FOR_NLF_81
int			NLFitSession::GetNumParameter(int nFunc) // = 0
{
	/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	if ( nFunc < 0 )
		nFunc = 0;
	/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	/// Hong 09/16/08 FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK
	//return GetNLParamsMngr()->GetNumParamsInFunc(nFunc) - GetNLParamsMngr()->GetFunctionParameterOffset(nFunc);
	return getNumParamsInFDF(nFunc) - GetNLParamsMngr()->GetFunctionParameterOffset(nFunc);
	/// end FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK
}

///------ Folger 07/16/09 NANOSIZER_FAILS_TO_REPORT_PARAMETER_BOUNDS_FROM_2ND_PEAK
int			NLFitSession::GetPeakNumParams(int nPeak/* = 0*/)
{
	return getNumParamsInFDF(GetFuncIndex(nPeak)) - GetPeakParameterOffset(nPeak);
}
///------ End NANOSIZER_FAILS_TO_REPORT_PARAMETER_BOUNDS_FROM_2ND_PEAK
		
int			NLFitSession::CheckIfParamValuesValid(int nNumData)
{
	/// NLF_81 Sophy
	/*
	vector<uint> vIndex;
	double dTarget = NANUM;
	int nNum = m_vParamValues.Find(vIndex, dTarget, dTarget);
	
	int nRet = PARAMS_VALID_ALL;
	if(nNum == m_vParamValues.GetSize())
		nRet = PARAMS_VALID_NONE;
	else if(nNum > 0)
		nRet = PARAMS_VALID_PART;
	
	return nRet;
	*/
	/// Iris 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
	//_NLF_81(CheckIfParamValuesValid);
	//return false;
	/////end NLF_81	
	vector<int> vnMissingParams;
	int nRet = PARAMS_VALID_ALL;
	if( !m_pParamMngr->IsParametersReady(&vnMissingParams) )
	{
		if( GetNumTotalParams() == vnMissingParams.GetSize() )
			nRet = PARAMS_VALID_NONE;
		else
			nRet = PARAMS_VALID_PART;
	}
	return nRet;
	///end FIX_XOP_RUNTIME_ERR_IN_SR5	
}

/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
//bool 		NLFitSession::GetParamsSettingDoubleVector(vector& vParams, int nParamsSettingType)
//{
	///// NLF_81 Iris 
	///*
	//bool bRet = true;
	//
	//switch(nParamsSettingType)
	//{
	//case PARMAS_SETTING_LOWERBOUNDS:
		//vParams = m_vParaLowerBounds;
		//break;
	//case PARMAS_SETTING_UPPERBOUNDS:
		//vParams = m_vParaUpperBounds;
		//break;
	//case PARMAS_SETTING_VALUES:
		//vParams = m_vParamValues;
		//break;
	//default:
		//bRet = false;
	//}
	//
	//return bRet;
	//*/	
	//if ( !getParamNumericValues(nParamsSettingType, vParams) )
		//return false;
		//
	//return true;
	/////end NLF_81	
//}
//
//bool 		NLFitSession::SetParamsSettingDoubleVector(const vector& vParams, int nParamsSettingType)
//{
	///// NLF_81 Iris 
	///*
	//bool bRet = true;
	//
	//switch(nParamsSettingType)
	//{
	//case PARMAS_SETTING_LOWERBOUNDS:
		//m_vParaLowerBounds = vParams;
		//break;
	//case PARMAS_SETTING_UPPERBOUNDS:
		//m_vParaUpperBounds = vParams;
		//break;
	//case PARMAS_SETTING_VALUES:
		//m_vParamValues = vParams;
		//break;
	//case PARMAS_SETTING_FIXED_PARAM_VALUE:
		//m_vFixedParamValues = vParams;
		//break;
	//default:
		//bRet = false;
	//}
	//
	//return bRet;
	//*/
	//_NLF_81(SetParamsSettingDoubleVector);
	//return false;
	/////end NLF_81	
//}
//
//bool 		NLFitSession::GetParamsSettingIntVector(vectorbase& vnParams, int nParamsSettingType)
//{
	///// NLF_81 Iris 
	///*
	//bool bRet = true;
	//
	//switch(nParamsSettingType)
	//{
	//case PARMAS_SETTING_SHARE:
		//vnParams = m_vnShared;
		//break;
	//case PARMAS_SETTING_FIXED:
		//vnParams = m_vbFixed;
		//break;
	//case PARMAS_SETTING_FIXED_PARAM_VALUE:
		//vnParams = m_vFixedParamValues;
		//break;
	//case PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE:
		//vnParams = m_vbpbExclusiveLower;
		//break;
	//case PARMAS_SETTING_LOWERBOUNDSENABLE:
		//vnParams = m_vbOnLowerBounds;
		//break;
	//case PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE:
		//vnParams = m_vbpbExclusiveUpper;
		//break;
	//case PARMAS_SETTING_UPPERBOUNDSENABLE:
		//vnParams = m_vbOnUpperBounds;
		//break;
	//case PARMAS_SETTING_SIGN_DIGITES:
		//vnParams = m_vnSignDigites;
		//break;	
	//case PARMAS_SETTING_PEAK_TYPE:	
		//vnParams = m_vnPeakTypes;
		//break;
	//default:
		//bRet = false;
	//}
	//
	//return bRet;
	//*/
	//if ( !getParamNumericValues(nParamsSettingType, vnParams) )
		//return false;
	//
	//return true;
	/////end NLF_81	
//}
//
//bool 		NLFitSession::SetParamsSettingIntVector(const vectorbase& vnParams, int nParamsSettingType)
//{
	///// NLF_81 Iris 
	///*
	//bool bRet = true;
	//
	//switch(nParamsSettingType)
	//{
	//case PARMAS_SETTING_SHARE:
		//m_vnShared = vnParams;
		//break;
	//case PARMAS_SETTING_FIXED:
		//m_vbFixed = vnParams;
		//break;
	//case PARMAS_SETTING_FIXED_PARAM_VALUE:
		//m_vFixedParamValues = vnParams;
		//break;
	//case PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE:
		//m_vbpbExclusiveLower = vnParams;
		//break;
	//case PARMAS_SETTING_LOWERBOUNDSENABLE:
		//m_vbOnLowerBounds = vnParams;
		//break;
	//case PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE:
		//m_vbpbExclusiveUpper = vnParams;
		//break;
	//case PARMAS_SETTING_UPPERBOUNDSENABLE:
		//m_vbOnUpperBounds = vnParams;
		//break;
	//case PARMAS_SETTING_SIGN_DIGITES:
		//m_vnSignDigites = vnParams;
		//break;
	//default:
		//bRet = false;
	//}
	//
	//return bRet;
	//*/
	//_NLF_81(SetParamsSettingIntVector);
	//return false;
	/////end NLF_81	
//}
//
//bool		NLFitSession::GetParamsSettingStringVector(vector<string>& vsParams, int nParamsSettingType)
//{
	///// NLF_81 Iris 
	///*
	//bool bRet = true;
	//
	//switch(nParamsSettingType)
	//{
	//case PARMAS_SETTING_NAMES:
		//vsParams = m_vsParamNames;
		//break;
	//case PARMAS_SETTING_MEANINGS:
		//vsParams = m_vsMeanings;
		//break;
	//default:
		//bRet = false;
	//}
	//
	//return bRet;
	//*/
	//if ( !getParamStringValues(nParamsSettingType, vsParams) )
		//return false;
	//
	//return true;
	/////end NLF_81	
//}
//
//bool		NLFitSession::SetParamsSettingStringVector(const vector<string>& vsParams, int nParamsSettingType)
//{
	///// NLF_81 Iris 
	///*
	//bool bRet = true;
	//
	//switch(nParamsSettingType)
	//{
	//case PARMAS_SETTING_NAMES:
		//m_vsParamNames = vsParams;
		//break;
	//case PARMAS_SETTING_MEANINGS:
		//m_vsMeanings = vsParams;
		//break;
	//default:
		//bRet = false;
	//}
	//
	//return bRet;
	//*/
	//_NLF_81(SetParamsSettingStringVector);
	//return false;
	/////end NLF_81
//}
static NLPARAMGRIDCOLTYPE _cvt_enum_param_setting_type_to_col_type(PARAMS_SETTING_TYPE paramType, bool& bNeedConvert)
{
	bNeedConvert = false;
	NLPARAMGRIDCOLTYPE		colType;
	switch ( paramType )
	{
	case PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE:		
	case PARMAS_SETTING_LOWERBOUNDSENABLE:
		bNeedConvert = true;
		colType = NLPARAMGRIDCOLTYPE_LB_CONTROL;
		break;
	case PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE:		
	case PARMAS_SETTING_UPPERBOUNDSENABLE:
		bNeedConvert = true;
		colType = NLPARAMGRIDCOLTYPE_UB_CONTROL;
		break;
	default:
		colType = paramType;
		break;
	}
	return colType;
}

bool		NLFitSession::GetParamNumericValues(vectorbase& vbValues, PARAMS_SETTING_TYPE paramType)
{
	bool				bNeedConvert = false;
	NLPARAMGRIDCOLTYPE	colType = _cvt_enum_param_setting_type_to_col_type(paramType, bNeedConvert);
	ASSERT( !bNeedConvert || (NLPARAMGRIDCOLTYPE_UB_CONTROL == colType || NLPARAMGRIDCOLTYPE_LB_CONTROL == colType) );
	
	if ( !bNeedConvert )
	{
		return getParamNumericValues(colType, vbValues);
	}
	else
	{
		vector<int>		vnControl;
		if ( !getParamNumericValues(colType, vnControl) )
			return false;
		vector<bool>	vbExclusive, vbEnable;
		GetNLParamsMngr()->ConvertBoundsControl(true, vnControl, vbEnable, vbExclusive);
		
		switch ( paramType )
		{
		case PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE:		
		case PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE:
			vbValues = vbExclusive;
			break;
		case PARMAS_SETTING_LOWERBOUNDSENABLE:		
		case PARMAS_SETTING_UPPERBOUNDSENABLE:
			vbValues = vbEnable;
			break;
		default:
			ASSERT(FALSE);
			return false;
			break;
		}		
		return true;
	}
	
	ASSERT(FALSE);
	return false;
}

bool		NLFitSession::GetParamStringValues(StringArray& vsValues, PARAMS_SETTING_TYPE paramType)
{
	bool				bNeedConvert = false;
	NLPARAMGRIDCOLTYPE	colType = _cvt_enum_param_setting_type_to_col_type(paramType, bNeedConvert);
	ASSERT( !bNeedConvert );
	
	return getParamStringValues(colType, vsValues);	
}
/// end FITNL_USING_NEW_NLFSESSION
///Sophy 11/7/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
void		NLFitSession::UpdatePeaksCenter( const vector<uint>& vnIndices )
{
	if( vnIndices.GetSize() == 0 )
		return;
	ASSERT( vnIndices.GetSize() == m_vXCenter.GetSize() );
	if( vnIndices.GetSize() != m_vXCenter.GetSize() )
		return;
	m_vXCenter.Reorder( vnIndices );
	m_vYCenter.Reorder( vnIndices );
}
///end ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH

bool		NLFitSession::SetParamVectorsFromUserParamsSetting(const TreeNode& trUserParamsSetting, int nDataFrom, bool bGlobalFit)
{
	/// NLF_81 Iris
	/*
	if(!nlf_set_bool_param_from_user_params_setting(trUserParamsSetting.Fixed, m_vbFixed, nDataFrom))
		return false;
	
	if(!nlf_set_double_param_from_user_params_setting(trUserParamsSetting.FixedValues, m_vFixedParamValues, nDataFrom))
		return false;
	
	if(!nlf_set_bool_param_from_user_params_setting(trUserParamsSetting.LowerBoundsEnable, m_vbOnLowerBounds, nDataFrom))
		return false;
	
	if(!nlf_set_bool_param_from_user_params_setting(trUserParamsSetting.LowerBoundsExclusive, m_vbpbExclusiveLower, nDataFrom))
		return false;
	
	if(!nlf_set_double_param_from_user_params_setting(trUserParamsSetting.LowerBounds, m_vParaLowerBounds, nDataFrom))
		return false;
	
	if(!nlf_set_bool_param_from_user_params_setting(trUserParamsSetting.UpperBoundsEnable, m_vbOnUpperBounds, nDataFrom))
		return false;
	
	if(!nlf_set_bool_param_from_user_params_setting(trUserParamsSetting.UpperBoundsExclusive, m_vbpbExclusiveUpper, nDataFrom))
		return false;
	
	if(!nlf_set_double_param_from_user_params_setting(trUserParamsSetting.UpperBounds, m_vParaUpperBounds, nDataFrom))
		return false;
	
	if(!nlf_set_int_param_from_user_params_setting(trUserParamsSetting.SignificantDigit, m_vnSignDigites, nDataFrom))
		return false;
	
	//Share can be set value only do global fit
	if(bGlobalFit)
	{
		if(!nlf_set_int_param_from_user_params_setting(trUserParamsSetting.Share, m_vnShared, nDataFrom))
			return false;
	}
	else
	{
		m_vnShared = 0;
	}
	
	return nlf_set_double_param_from_user_params_setting(trUserParamsSetting.Values, m_vParamValues, nDataFrom);
	*/
	/// Iris 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
	//_NLF_81(SetParamVectorsFromUserParamsSetting);
	//return false;
	///end NLF_81
	
	// labtalk user parameter setting tree can be setted by the following way:
	/*
	nlGUI.UserSettings.Parameters.Values.y0=0; 
	nlGUI.UserSettings.Parameters.Fixed.y0=1; 	
	nlGUI.UserSettings.Parameters.Values.y0_2=0; 	
	nlGUI.UserSettings.Parameters.Fixed.y0_2=1; 
	*/
	Tree trParams;
	if( !m_pParamMngr->GetParamSettings(trParams) )
	{
		ASSERT(0);
		return false;
	}
	
	/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
	bool			bAnyChanged = false;
	/// end FIX_XOP_RUNTIME_ERR_IN_SR5
	vector<string> vsParamNames;
	vsParamNames = trParams.Names.strVals;
	
	foreach(TreeNode trUserParam in trUserParamsSetting.Children)
	{	
		/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
		bool			bChanged = false;
		/// end FIX_XOP_RUNTIME_ERR_IN_SR5
		TreeNode trParam = trParams.GetNode(trUserParam.tagName, false);
		if( !trParam )
		{
			ASSERT(0);
		}
		else
		{
			vector vd;
			vector<int> vn;
			
			switch(trParam.TypeID)
			{
			case TNVAL_TYPE_DOUBLE_VECTOR:
				vd = trParam.dVals;
				foreach(TreeNode trOneUserParam in trUserParam.Children)
				{
					int index;
					if( is_in_list(trOneUserParam.tagName, vsParamNames, false, &index) && index<vd.GetSize() )
					{							
						vd[index] = trOneUserParam.dVal;
						/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
						bChanged = true;
						/// end FIX_XOP_RUNTIME_ERR_IN_SR5
					}
					else
					{
						ASSERT(0);
					}
				}
				/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
				if ( bChanged )
				/// end FIX_XOP_RUNTIME_ERR_IN_SR5
					trParam.dVals = vd;
				break;
				
			case TNVAL_TYPE_INT_VECTOR:
				vn = trParam.nVals;
				foreach(TreeNode trOneUserParam in trUserParam.Children)
				{
					int index;
					if( is_in_list(trOneUserParam.tagName, vsParamNames, false, &index) && index< vn.GetSize() )
					{							
						vn[index] = trOneUserParam.nVal;
						/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
						bChanged = true;
						/// end FIX_XOP_RUNTIME_ERR_IN_SR5
					}
					else
					{
						ASSERT(0);
					}
				}
				/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
				if ( bChanged )
				/// end FIX_XOP_RUNTIME_ERR_IN_SR5
					trParam.nVals = vn;
				break;
				
			default:
				ASSERT(0);
				break;
			}
				
		}	
		/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
		bAnyChanged |= bChanged;
		/// end FIX_XOP_RUNTIME_ERR_IN_SR5
	}
	/// Hong 4/17/2009 QA80-13469 FIX_XOP_RUNTIME_ERR_IN_SR5
	if ( !bAnyChanged )
		return true;
	/// end FIX_XOP_RUNTIME_ERR_IN_SR5
	/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	//return m_pParamMngr->SetParamSettings(trParams);
	return SetParamSettings(trParams);
	/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	///end FIX_XOP_RUNTIME_ERR_IN_SR5
}

/// Hong 11/04/08 QA80-12526 v8.0965b ADD_BACKWARD_COMPATIABLE
int			NLFitSession::SetParamValues(const vector& vParams)
{	
	if ( 1 != GetNumberFitFunctions() )
		return -2;
	
	int					nNumDataset = GetNumDataset();
	if ( nNumDataset <= 0 )
		nNumDataset = 1; // allow set first dataset parameters value before set data
	const int			nNumTotalParams = GetNumTotalParams() * nNumDataset;
	if ( vParams.GetSize() > nNumTotalParams )
		return -1;
	
	int					nDatasetIndex = 0, nIndex;
	for ( int ii = 0; ii < vParams.GetSize(); ii++ )
	{
		nDatasetIndex = ii / GetNumTotalParams(0);
		nIndex = ii % GetNumTotalParams(0);

		if ( m_pParamMngr->SetOneFuncParam(0, nDatasetIndex, nIndex, &vParams[ii]) )
		{
			error_report("Fail set value!");
			return -2;
		}
	}
	
	return nNumTotalParams == vParams.GetSize() ? 0 : 1;
}

bool		NLFitSession::SetParamShare(int nParam, bool bShare/* = true*/)
{
	if ( 1 != GetNumberFitFunctions() )
		return false;
	
	if ( !IsAllowSharing() )
		return false;
	
	int					nNumDataset = GetNumDataset();
	if ( nNumDataset <= 0 )
		nNumDataset = 1; // allow set first dataset parameters value before set data
	if ( nParam >= GetNumTotalParams() * nNumDataset )
		return false;
	
	int					nDatasetIndex = nParam / GetNumTotalParams(0), nIndex = nParam % GetNumTotalParams(0);
	int					nShare = bShare;
	if ( m_pParamMngr->SetOneFuncParam(0, nDatasetIndex, nIndex, NULL, NULL, &nShare) )	
		return error_report("Fail set value!");		
	
	return true;
}

bool		NLFitSession::SetParamFix(int nParam, bool bFixed/* = true*/)
{
	if ( 1 != GetNumberFitFunctions() )
		return false;
	
	int					nNumDataset = GetNumDataset();
	if ( nNumDataset <= 0 )
		nNumDataset = 1; // allow set first dataset parameters value before set data
	if ( nParam >= GetNumTotalParams() * nNumDataset )
		return false;
	
	int					nDatasetIndex = nParam / GetNumTotalParams(0), nIndex = nParam % GetNumTotalParams(0);	
	if ( m_pParamMngr->SetOneFuncParam(0, nDatasetIndex, nIndex, NULL, &bFixed) )	
		return error_report("Fail set value!");		
	
	return true;
}
/// end ADD_BACKWARD_COMPATIABLE

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//bool		NLFitSession::GetDerivedParameters(int nDataset, vector<string>* pvsNames, vector<double>* pvdVals) // = NULL
//{
	///// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//if ( !hadBackupedFitResults() )
		//return getDerivedParameters(nDataset, pvsNames, pvdVals);
	//
	//if ( nDataset < 0 || nDataset >= m_arNLFitResults.GetSize() )
	//{
		//ASSERT(FALSE);
		//return -1;	
	//}
	//
	//NLFitResults&	refNLFitResults = m_arNLFitResults.GetAt(nDataset);
	//*pvsNames = refNLFitResults.stFitDerivedParamNames;
	//if ( NULL != pvdVals )
		//*pvdVals = refNLFitResults.stFitDerivedParamValues;
	//
	//return true;
	///// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//}
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT

int 		NLFitSession::GetReplicaOffsetFromFDF(int nFunc) // = 0
{
	/// Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	//return nlf_get_duplicate_offset( GetTreeFDF(nFunc) );
	return getReplicaOffsetFromFDF( GetTreeFDF(nFunc) );
	/// end KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
}

int 		NLFitSession::GetReplicaUnitFromFDF(int nFunc) // = 0
{
	return nlf_get_duplicate_unit( GetTreeFDF(nFunc) );
}

int 		NLFitSession::GetReplicaNumberFromFDF(int nFunc) // = 0
{
	return nlf_get_duplicate_number( GetTreeFDF(nFunc) );	
}

int			NLFitSession::GetNumberMultiplicity(int nFunc) // = 0
{
	//return GetFitFunction(nFunc)->GetNumMultiplicity();
	int		nNumMultiplicity = 1;
	m_pParamMngr->GetNumMultiplicity(nNumMultiplicity, nFunc);
	
	return nNumMultiplicity;
}
int			NLFitSession::GetNumPeaks()
{
	//return GetNumberMultiplicity();
	return GetNumberMultiplicity(-1);
}

/// Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
bool		NLFitSession::IsAllowReplicas(const TreeNode& trFDF/* = NULL*/)
{
	if ( NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS == getParamsType() )
		return false;
	
	TreeNode		trFF = trFDF;
	if ( !trFF )
		trFF = GetTreeFDF();			
	if ( getReplicaOffsetFromFDF(trFF) <= 0 )
		return false;
		
	if ( GetNumDataset() > 1 )
		return false;		
	
#ifndef  	2D_FIT_SUPPORT_REPLICA
	/// Hong 05/06/09 OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
	//if ( NLFIT_GENERAL_XY_FITTING != GetFitType() )
	if ( !Is2DSupportReplica() && NLFIT_GENERAL_XY_FITTING != GetFitType() )
	/// end OPEN_2D_REPLICA_SUPPORT_FOR_NANOSIZE
		return false;
#endif		//2D_FIT_SUPPORT_REPLICA

	return true;
}
/// end KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER

int 		NLFitSession::OnReplicaNumberChange(int nNumReplica, int nFunc, bool bUpdatePreview) // = 0, true
{
	ASSERT( !(nNumReplica > 0 && nFunc > 0) ); // We do not support multiple functions multiple peaks right now
	/// Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	if ( nNumReplica > 0 && !IsAllowReplicas()	)	
	{
		ERR_MSG("Do NOT support replicas, reset to 0.");
		nNumReplica = 0;
	}
	/// end KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
	if ( nNumReplica > 0 )
		m_dwParamTypeCtrl |= NLF_PARAM_TYPE_CTRL_REPLICA;
	else
		m_dwParamTypeCtrl &= ~NLF_PARAM_TYPE_CTRL_REPLICA;
		
	int		nNumMultiplicity = numReplicaToMultiplicity(nNumReplica);
	if ( isNeedReinitParamType() )
	{
		Tree		trFitFunction;
		trFitFunction = GetTreeFDF();
		string		strFuncName, strCateName;
		strFuncName = GetFunctionName(&strCateName);
		/// Hong 10/28/08 QA80-12469 v8.0963 FIX_NO_HINT_OF_LESS_REPLICA_NUM_FIRST_TIME_SET
		if ( nNumReplica > 0 )
			m_dwAutoUpdateCtrl |= AUTO_UPDATE_NUM_REPLICA_CHANGE;
		/// end FIX_NO_HINT_OF_LESS_REPLICA_NUM_FIRST_TIME_SET
		/// Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
		//if ( !SetFunction(trFitFunction, nNumMultiplicity, true, NULL, 0, strFuncName) )
		if ( !SetFunction(trFitFunction, nNumMultiplicity, true, strFuncName) )
		/// end SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
			return -2;
	}
	else
	{		
		if ( !setNumMultiplicity(nNumMultiplicity, nFunc) )
			return -1;
		m_dwAutoUpdateCtrl |= AUTO_UPDATE_NUM_REPLICA_CHANGE; ///Arvin 04/02/08 QA70-11348 AUTO_PREVIEW_CHANGED_TO_AUTO_UPDATE_CLEANUP
		if ( !OnSetFunction(nFunc) )
			return -2;
	}
	return 0;
}

int			NLFitSession::GetNumberMultiplicity(const TreeNode& trReplica)
{
	int		nNumReplica = 0;
	
	if ( trReplica && trReplica.Enable )	
		nNumReplica =  trReplica.Number.nVal;
	
	//return nNumReplica + 1; //nMultiplicity = replica + 1
	return numReplicaToMultiplicity(nNumReplica);
}

/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
/*
bool		NLFitSession::SetGUIParamsTreeFromOperation(const TreeNode& trParams, DWORD dwThemeApplied, bool bChangeParams)
///end SEPRATE_BOUND_SETTING_FROM_PARAMS_SETTING_CEHCK_BOX
///end CHANGE_PARAMS_SHOULD_APLLY_LAST_PARAMS_SETTING
{
	///Cheney 2007-6-14 SHOULD_RESET_SHARE_VAL_WHEN_MODE_CHANGE_FROM_GLOBAL_TO_OTHERS
	//if(!trParams)
	//	return false;
	///end SHOULD_RESET_SHARE_VAL_WHEN_MODE_CHANGE_FROM_GLOBAL_TO_OTHERS
	///Cheney 2007-4-29 SEPRATE_BOUND_SETTING_FROM_PARAMS_SETTING_CEHCK_BOX
	//m_bDlgThemeApplied = bThemeApplied;
	m_dwDlgThemeApplied = dwThemeApplied;
	m_bDlgChangeParams	= bChangeParams;
	///end SEPRATE_BOUND_SETTING_FROM_PARAMS_SETTING_CEHCK_BOX
	if(trParams)	///Cheney 2007-6-14 SHOULD_RESET_SHARE_VAL_WHEN_MODE_CHANGE_FROM_GLOBAL_TO_OTHERS
		m_trOpParams = trParams;
	return true;
}
*/
/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
static void  _convert_tree_val_to_tree_vals(const TreeNode& trSource, TreeNode& trDest)
{
	ASSERT( trSource && trDest );
	switch(trDest.TypeID)
	{
	case TNVAL_TYPE_INT_VECTOR:
		vector<int> vn;		
		vn = trDest.nVals;
		octree_value_from_tree_sub_nodes_to_vector_int(&trSource, &vn);
		trDest.nVals = vn;
		break;
	case TNVAL_TYPE_DOUBLE_VECTOR:
		vector<double> vd;	
		vd = trDest.dVals;
		octree_value_from_tree_sub_nodes_to_vector_double(&trSource, &vd);
		trDest.dVals = vd;
		break;
	case TNVAL_TYPE_CSTRING_VECTOR:
	default:
		ASSERT(FALSE);
		break;		
	}
}

/// Hong 09/16/08 QA80-11406 THEME_APPLY_SHOULD_DUPLICATE_LAST_DATASET_VALUES_FOR_ADDITIONAL_DATASET
bool		NLFitSession::OperationGUIToParams(const TreeNode& trParams, DWORD dwParamsToSkip/* = 0*/, bool bDuplicateLastSetValues/* = false*/)
/// end THEME_APPLY_SHOULD_DUPLICATE_LAST_DATASET_VALUES_FOR_ADDITIONAL_DATASET
{
	if ( !trParams )
		return false;
	
	Tree		trFitWorkAreaParam;
	if ( !m_pParamMngr->GetParamSettings(trFitWorkAreaParam) )
		return false;
	
	_convert_tree_val_to_tree_vals(trParams.Share, trFitWorkAreaParam.Share);
	_convert_tree_val_to_tree_vals(trParams.Fixed, trFitWorkAreaParam.Fixed);
	_convert_tree_val_to_tree_vals(trParams.Values, trFitWorkAreaParam.Values);
	///Sophy 10/15/2008 QA80-12375 FIX_NLSF_THEME_APPLY_FAIL_TO_WORK_WITH_FIXED_VALUES
	///Sophy 11/25/2008 QA80-12376 NLSF_THEME_FROM_SR4_FAIL_TO_WORK_IN_SR5
	//if( trParams.FixValues && trParams.FixedValues.FirstNode && !trParams.FixedValues.FirstNode.IsEmpty() && trParams.Values && trParams.Values.FirstNode && trParams.Values.FirstNode.IsEmpty() )
	if( trParams.FixedValues && trParams.FixedValues.FirstNode && !trParams.FixedValues.FirstNode.IsEmpty() && trParams.Values && trParams.Values.FirstNode && trParams.Values.FirstNode.IsEmpty() )
	///end NLSF_THEME_FROM_SR4_FAIL_TO_WORK_IN_SR5
	{
		_convert_tree_val_to_tree_vals( trParams.FixedValues, trFitWorkAreaParam.Values ); ///Sophy, for trParams is const, derectly copy to PFW
		dwParamsToSkip |= NLPARAMETERSETTINGS_VALUE;
	}
	///end FIX_NLSF_THEME_APPLY_FAIL_TO_WORK_WITH_FIXED_VALUES
	_convert_tree_val_to_tree_vals(trParams.LowerBounds, trFitWorkAreaParam.LowerBounds);
	_convert_tree_val_to_tree_vals(trParams.UpperBounds, trFitWorkAreaParam.UpperBounds);
	_convert_tree_val_to_tree_vals(trParams.LowerBoundsExclusive, trFitWorkAreaParam.LowerBoundsExclusive);
	_convert_tree_val_to_tree_vals(trParams.UpperBoundsExclusive, trFitWorkAreaParam.UpperBoundsExclusive);
	_convert_tree_val_to_tree_vals(trParams.LowerBoundsEnable, trFitWorkAreaParam.LowerBoundsEnable);
	_convert_tree_val_to_tree_vals(trParams.UpperBoundsEnable, trFitWorkAreaParam.UpperBoundsEnable);
	_convert_tree_val_to_tree_vals(trParams.SignificantDigit, trFitWorkAreaParam.SignificantDigit);		
	/// Hong 10/07/09 QA80-13922 FIX_SHARED_SETTING_IS_APPLIED_EVEN_NOT_SUPPORT_SHARING
	if ( !IsAllowSharing() )
		dwParamsToSkip |= NLPARAMETERSETTINGS_SHARED;
	/// end FIX_SHARED_SETTING_IS_APPLIED_EVEN_NOT_SUPPORT_SHARING
	/// Hong 09/16/08 QA80-11406 THEME_APPLY_SHOULD_DUPLICATE_LAST_DATASET_VALUES_FOR_ADDITIONAL_DATASET
	//return m_pParamMngr->SetParamSettings(trFitWorkAreaParam, dwParamsToSkip);
	/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	//return m_pParamMngr->SetParamSettings(trFitWorkAreaParam, dwParamsToSkip, bDuplicateLastSetValues);
	return SetParamSettings(trFitWorkAreaParam, dwParamsToSkip, bDuplicateLastSetValues);
	/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	/// end THEME_APPLY_SHOULD_DUPLICATE_LAST_DATASET_VALUES_FOR_ADDITIONAL_DATASET
}

static void  _convert_tree_vals_to_tree_val(const TreeNode& trSource, TreeNode& trDest)
{
	ASSERT( trSource && trDest );
	switch(trSource.TypeID)
	{
	case TNVAL_TYPE_INT_VECTOR:
		vector<int> vn;
		vn = trSource.nVals;
		octree_value_from_vec_int_to_tree_sub_nodes(&vn, &trDest);
		break;
	case TNVAL_TYPE_DOUBLE_VECTOR:
		vector<double> vd;
		vd = trSource.dVals;
		octree_value_from_vec_double_to_tree_sub_nodes(&vd, &trDest);
		break;
	case TNVAL_TYPE_CSTRING_VECTOR:
	default:
		ASSERT(FALSE);
		break;		
	}
}

bool		NLFitSession::ParamsToOperationGUI(TreeNode& trParams)
{
	if ( !trParams )
		return false;
	
	Tree		trFitWorkAreaParam;
	if ( !m_pParamMngr->GetParamSettings(trFitWorkAreaParam) )
		return false;
	
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.Share, trParams.Share);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.Fixed, trParams.Fixed);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.Values, trParams.Values);	
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.Values, trParams.FixedValues); /// Hong 10/16/08 v8.0956 FIX_FIX_VALUES_NOT_SAVED_LEAD_APPLY_FAIL_IF_VALUE_NOT_CHECKED
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.LowerBounds, trParams.LowerBounds);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.UpperBounds, trParams.UpperBounds);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.LowerBoundsExclusive, trParams.LowerBoundsExclusive);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.UpperBoundsExclusive, trParams.UpperBoundsExclusive);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.LowerBoundsEnable, trParams.LowerBoundsEnable);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.UpperBoundsEnable, trParams.UpperBoundsEnable);
	_convert_tree_vals_to_tree_val(trFitWorkAreaParam.SignificantDigit, trParams.SignificantDigit);
	
	return true;
}

/// Hong 09/14/09 FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
//bool		NLFitSession::ParamsToOperation(TreeNode& trOp, bool bUpdateRegState) // = false
bool		NLFitSession::ParamsToOperation(TreeNode& trOp, bool bUpdateRegState/* = false*/, bool bOnlyFirstSet/* = true*/)
/// end FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
{
	ASSERT(trOp);
	checkAddWorkArea(trOp);

	validateParams("ParamsToOperation");
	TreeNode trParam = trOp.FitWorkArea.Parameters;		
	if ( !m_pParamMngr->GetParamSettings(trParam) )
		return error_report("Fail to get parameters.");
	
	trParam.SetAttribute(STR_FIT_OUTCOME_ATTRIB, GetLastIterateOutCome()); /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	trParam.SetAttribute(STR_FIT_DATASET_NUM_ATTRIB, GetNumDataset());
	trParam.SetAttribute(STR_FIT_1_DATASET_PARA_NUM_ATTRIB, GetNumTotalParams());

	// Hong, to do, code below should move to operation level
	if ( bUpdateRegState )
	{
		/// Hong 09/14/09 FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
		int				nCount = bOnlyFirstSet ? 1 : GetNumNLFitObjs();
		for ( int index = 0; index < nCount; index++ )
		{
		/// end FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
			RegStats		sRegStats;
			/// Hong 09/14/09 FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
			//GetFitResultsStats(&sRegStats, NULL);
			GetFitResultsStats(&sRegStats, NULL, false, index);
			/// end FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
	
			TreeNode		trRegStats = tree_check_get_node(trOp.Calculation, "RegStats", IDST_REG_STATS_RESULTS);
			// for now, support only 1st set
			/// Hong 09/14/09 FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
			//int index = 0;
			/// end FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
			TreeNode trRow = check_add_enumerated_node(trRegStats, CALCULATION_REPORT_TABLE_COL_PREFIX, index + 1, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, "FitNL Stats");
			trRow = sRegStats;
			
			CheckAddNumIterNode(trRow);
			CheckAddFitStatusNode(trRow);
			CheckAddFitStatusErrorCode(trRow);
		} /// Hong 09/14/09 FIX_LT_NLFIT_FAIL_GET_ALL_SET_CHISQR_AFTER_ITERATE_FOR_SEPARATE_FIT_MODE
	}
	
	return true;
}

bool 		NLFitSession::OperationToParams(const TreeNode& trOp)
{
	ASSERT(trOp);
	if ( !checkAddWorkArea(trOp) )
		return false;
	///Sophy 10/15/2008 QA80-12376 NLSF_THEME_FROM_SR4_FAIL_TO_WORK_IN_SR5
	if( !trOp.FitWorkArea.Parameters.FirstNode ) //params not ready
		return false;
	///end NLSF_THEME_FROM_SR4_FAIL_TO_WORK_IN_SR5
	/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	//return m_pParamMngr->SetParamSettings(trOp.FitWorkArea.Parameters);
	return SetParamSettings(trOp.FitWorkArea.Parameters);
	/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
}

/// Hong 20/05/08 v8.0867 CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
/*
bool		NLFitSession::LoadAutoParamsInitSetting(const TreeNode& trFDF)
{
	bool bAutoInit = true;
	nlf_is_auto_init_params(trFDF, bAutoInit);
	
	return bAutoInit;
}
*/
bool		NLFitSession::IsFDFEnableAutoParamsInit()
{	
	bool bAutoInit = true;
	nlf_is_auto_init_params(GetTreeFDF(), bAutoInit);
	
	return bAutoInit;
}
/// end CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
	
bool 		NLFitSession::IsEnableAutoParamsInitFromOperation(const TreeNode& trAutoParamsInit)
{
	if ( trAutoParamsInit && !trAutoParamsInit.IsEmpty() )
			return trAutoParamsInit.nVal;	
	
	/// Hong 20/05/08 v8.0867 CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
	//return LoadAutoParamsInitSetting(GetTreeFDF());
	return IsFDFEnableAutoParamsInit();
	/// end CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
}

bool		NLFitSession::IsEnableConstraintsFromOperation(const TreeNode& trLinearConstraints)
{
	if( trLinearConstraints && !trLinearConstraints.IsEmpty() )
		return trLinearConstraints.nVal;

	/// Hong 20/05/08 v8.0867 CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
	//return LoadLinearConstraintsSetting(GetTreeFDF());	
	return IsFDFEnableLinearConstraints();
	/// end CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
}

/// Hong 20/05/08 v8.0867 CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION
/*
bool		NLFitSession::LoadLinearConstraintsSetting(const TreeNode& trFDF)
{
	bool bConstraints = true;
	nlf_is_enable_linear_constraints(trFDF, bConstraints);
	
	return bConstraints;
}
*/
bool		NLFitSession::IsFDFEnableLinearConstraints()
{
	bool bConstraints = true;
	nlf_is_enable_linear_constraints(GetTreeFDF(), bConstraints);
	
	return bConstraints;
}
/// end CLEAN_UPDATE_EVENTS_TO_ONE_FUNCTION

/// Hong 03/11/09 FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO
//bool		NLFitSession::GetFittingCodes(TreeNode& trCodes)
bool		NLFitSession::GetFittingCodes(TreeNode& trCodes, bool bUpdateUneditableOnly/* = false*/)
/// end FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO
{
	if ( !trCodes )
		return false;
	
	Tree	trFDF;
	trFDF = GetTreeFDF();
	if ( !trFDF.IsValid() )
		return false;	
			
	string strParaInitCodes, strFormula;
	/// Hong 03/11/09 FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO
	/*
	strParaInitCodes = nlsf_get_param_init_code(trFDF);
	strFormula = nlsf_get_formula(trFDF);		
	
	trCodes.ParaInitCode.strVal = strParaInitCodes;
	trCodes.FunctionCode.strVal = strFormula;
		
#ifdef ALLOW_SCRIPT_BEFORE_AFTER_FITTING
	trCodes.BeforeFit.strVal = nlsf_get_before_or_after_fitting_codes(trFDF, true);
#endif //ALLOW_SCRIPT_BEFORE_AFTER_FITTING

	trCodes.Constraints.strVal = nlsf_get_constraints_codes(trFDF);		
	trCodes.AfterFit.strVal = nlsf_get_before_or_after_fitting_codes(trFDF, false);
	trCodes.DerivParam.strVal = nlsf_get_deriv_param_codes( trFDF );///Sophy 10/20/2008 QA80-12406 ADD_DERIVATIVE_PARAM_PAGE_IN_CODE_TAB_OF_NLFIT_DLG
	*/
	strFormula = nlsf_get_formula(trFDF);
	trCodes.FunctionCode.strVal = strFormula;
	if ( !bUpdateUneditableOnly )
	{
		strParaInitCodes = nlsf_get_param_init_code(trFDF);
		trCodes.ParaInitCode.strVal = strParaInitCodes;
			
	#ifdef ALLOW_SCRIPT_BEFORE_AFTER_FITTING
		trCodes.BeforeFit.strVal = nlsf_get_before_or_after_fitting_codes(trFDF, true);
	#endif //ALLOW_SCRIPT_BEFORE_AFTER_FITTING
	
		trCodes.Constraints.strVal = nlsf_get_constraints_codes(trFDF);		
		trCodes.AfterFit.strVal = nlsf_get_before_or_after_fitting_codes(trFDF, false);
		trCodes.DerivParam.strVal = nlsf_get_deriv_param_codes( trFDF );///Sophy 10/20/2008 QA80-12406 ADD_DERIVATIVE_PARAM_PAGE_IN_CODE_TAB_OF_NLFIT_DLG
	}
	/// end FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO

	return true;
}

///Cheney 2007-6-8 ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC
bool		NLFitSession::SetGUISettingToFDF(TreeNode& trFDF, int nNumParaInFunc, const TreeNode& trCodes, bool bAutoInit, bool bLinearConstraint)
{
	////Fixed and Value
	vector vParamValues(nNumParaInFunc);
	vector<bool> vbFixed(nNumParaInFunc);
	string strParaValueList = m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_INIT_VAL).strVal;
	nlf_set_param_values_vector(strParaValueList, vParamValues, nNumParaInFunc);
	//if fixed value, save to FDF, otherwise, not change
	bool			bRet = true;
	vector			vAllParamValues;
	bRet &= GetParamNumericValues(vAllParamValues, PARMAS_SETTING_VALUES);
	vector<bool>	vbAllFixed;
	bRet &= GetParamNumericValues(vbAllFixed, PARMAS_SETTING_FIXED);
	vbAllFixed.GetSubVector( vbFixed, 0, nNumParaInFunc -1 );
	for(int ii = 0; ii < nNumParaInFunc; ii++)
	{
		vParamValues[ii] = vbFixed[ii]? vAllParamValues[ii] : vParamValues[ii];
	}
	m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_INIT_VAL).strVal = nlf_get_param_value_list(vParamValues, vbFixed);
	
	////nSignDigites
	vector<int> vnSignDigites(nNumParaInFunc);
	vector<int> vnAllSignDigites;
	bRet &= GetParamNumericValues(vnAllSignDigites, PARMAS_SETTING_SIGN_DIGITES);
	vnAllSignDigites.GetSubVector( vnSignDigites, 0, nNumParaInFunc -1 );
	m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_SIGNIFICANT_DIGITS).strVal = nlf_get_param_significant_digits_list(vnSignDigites);
	
	//Exclusive and Bounds
	//Lower
	vector vParaLowerBounds(nNumParaInFunc);
	vector<bool> vbpbExclusiveLower(nNumParaInFunc), vbOnLowerBounds(nNumParaInFunc);
	vector 			vAllParaLowerBounds(nNumParaInFunc);
	vector<bool>	vbAllpbExclusiveLower, vbAllOnLowerBounds;	
	bRet &= GetParamNumericValues(vAllParaLowerBounds, PARMAS_SETTING_LOWERBOUNDS);
	bRet &= GetParamNumericValues(vbAllpbExclusiveLower, PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE);
	bRet &= GetParamNumericValues(vbAllOnLowerBounds, PARMAS_SETTING_LOWERBOUNDSENABLE);	
	vAllParaLowerBounds.GetSubVector( vParaLowerBounds, 0, nNumParaInFunc -1 );
	vbAllpbExclusiveLower.GetSubVector( vbpbExclusiveLower, 0, nNumParaInFunc -1 );
	vbAllOnLowerBounds.GetSubVector( vbOnLowerBounds, 0, nNumParaInFunc -1 );
	m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_LOWER_BOUNDS).strVal = nlf_get_param_bound_list(vParaLowerBounds, vbpbExclusiveLower, vbOnLowerBounds);

	//Upper
	vector vParaUpperBounds(nNumParaInFunc);
	vector<bool> vbpbExclusiveUpper(nNumParaInFunc), vbOnUpperBounds(nNumParaInFunc);
	vector 			vAllParaUpperBounds(nNumParaInFunc);
	vector<bool>	vbAllpbExclusiveUpper, vbAllOnUpperBounds;	
	bRet &= GetParamNumericValues(vAllParaUpperBounds, PARMAS_SETTING_UPPERBOUNDS);
	bRet &= GetParamNumericValues(vbAllpbExclusiveUpper, PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE);
	bRet &= GetParamNumericValues(vbAllOnUpperBounds, PARMAS_SETTING_UPPERBOUNDSENABLE);
	ASSERT(bRet);
	vAllParaUpperBounds.GetSubVector( vParaUpperBounds, 0, nNumParaInFunc -1 );
	vbAllpbExclusiveUpper.GetSubVector( vbpbExclusiveUpper, 0, nNumParaInFunc -1 );
	vbAllOnUpperBounds.GetSubVector( vbOnUpperBounds, 0, nNumParaInFunc -1 );
	m_NFO.GetFittingPara(trFDF, true, STR_FDF_SETTING_UPPER_BOUNDS).strVal = nlf_get_param_bound_list(vParaUpperBounds, vbpbExclusiveUpper, vbOnUpperBounds);

	//Function Code
	TreeNode trFunctionCode = trCodes.FunctionCode;
	if(!trFunctionCode)
		return false;
	m_NFO.GetFormula(trFDF, true, STR_FUNC_SCRIPT).strVal = trFunctionCode.strVal;
	
	//Para Init Code
	TreeNode trParaInitCode = trCodes.ParaInitCode;
	if(!trParaInitCode)
		return false;	
	m_NFO.GetParaInit(trFDF, true, STR_FUNC_SCRIPT).strVal = trParaInitCode.strVal;
	
	//Constraints
#ifdef ALLOW_LINEAR_CONSTRAINT_WHEN_FITTING  //Cheney 2007-5-28 TEMP_HIDE_LINEAR_CONSTRAIN_TAB_AND_CHECK_BOX
	TreeNode trConstraints = trCodes.Constraints;
	if(!trConstraints)
		return false;
	m_NFO.GetConstraints(trFDF, true, STR_FUNC_SCRIPT).strVal = trConstraints.strVal;
#endif //ALLOW_LINEAR_CONSTRAINT_WHEN_FITTING  //Cheney 2007-5-28 TEMP_HIDE_LINEAR_CONSTRAIN_TAB_AND_CHECK_BOX
	
	//auto init check box
	TreeNode trEnableParamInit = tree_check_get_node( trFDF.Controls, "EnableParametersInitialization", IDS_ENABLE_INIT_PARAMS);
	trEnableParamInit.nVal = bAutoInit;
	
	///Cheney 2007-6-8 WHNE_SAVE_AUTO_INIT_SHOULD_ALSO_SAVE_COMPILE_BIT
	TreeNode trCompileOnParamChangeScript = tree_check_get_node( trFDF.Controls, "CompileOnParamChangeScript", IDS_PARAM_CHANGE_SCRIPTS);
	trCompileOnParamChangeScript.nVal = bAutoInit;
	///end WHNE_SAVE_AUTO_INIT_SHOULD_ALSO_SAVE_COMPILE_BIT
	
	//Linear Constraints check box
	///Cheney 2007-6-6 SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT	
	TreeNode trLinearConstraints = tree_check_get_node( trFDF.Controls, "GeneralLinearConstraints", IDS_CONTROL_CONSTRAINTS);
	trLinearConstraints.nVal = bLinearConstraint;
	///end SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT
	
	return true;
}
///end ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC


/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//TreeNode	NLFitSession::CheckAddNumIterNode(TreeNode &trParent)
TreeNode	NLFitSession::CheckAddNumIterNode(TreeNode &trParent, int nSetIndex/* = 0*/)
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
{
	TreeNode trNumIter = tree_check_get_node(trParent, "NumIter", 1, STR_LABEL_ATTRIB, _L("Number of Iterations"));
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//trNumIter.nVal = GetNumberItersPerformed();
	trNumIter.nVal = GetNumberItersPerformed(nSetIndex);
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	trNumIter.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
	return trNumIter;
}
//------

//------ Folger 02/13/08 QA80-10929 ACCESS_FIT_STATUS_FROM_LT_TREE
/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//TreeNode	NLFitSession::CheckAddFitStatusNode(TreeNode &trParent)
TreeNode	NLFitSession::CheckAddFitStatusNode(TreeNode &trParent, int nSetIndex/* = 0*/)
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
{
	TreeNode trFitStatus = tree_check_get_node(trParent, "FitStatus", 2, STR_LABEL_ATTRIB, _L("Fit Status"));
	string strMsg;
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//GetShortFitOutCome(strMsg);
	GetShortFitOutCome(strMsg, nSetIndex);
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	trFitStatus.strVal = strMsg;
	return trFitStatus;
}

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//TreeNode	NLFitSession::CheckAddFitStatusErrorCode(TreeNode &trParent)
TreeNode	NLFitSession::CheckAddFitStatusErrorCode(TreeNode &trParent, int nSetIndex/* = 0*/)
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
{
	TreeNode trFitStatusErr = tree_check_get_node(trParent, "FitStatusErr", 3, STR_LABEL_ATTRIB, _L("Fit Status Error Code"));
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//trFitStatusErr.nVal = m_nLastIterateOutCome;
	trFitStatusErr.nVal = GetLastIterateOutCome(nSetIndex);;
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	return trFitStatusErr;
}

///---Sim 09-10-2008 NLFIT_LABTALK_TREE_ACCESS
//int			NLFitSession::LinkLabtalkTree(LPCSTR lpcszName, DWORD dwOption) // = 0
//{
	//return m_pParamMngr->LinkLabtalkTree(lpcszName, dwOption);	
//}
///---END NLFIT_LABTALK_TREE_ACCESS

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
int			NLFitSession::GetNLFitArrayOffset()
{
	return 1; // Hong, 1 is m_NLFit
}

int			NLFitSession::GetNumNLFitObjs()
{
	return m_arNLFitAdditionalObjs.GetSize() + GetNLFitArrayOffset();
}

int			NLFitSession::GetDatasetIndexInNLFit(int nDataSetIndex)
{
	if ( isSeparateFit() )
		return 0;
	
	if ( nDataSetIndex < 0 || nDataSetIndex >= GetNumDataset() )
		return 0;
	
	return nDataSetIndex;
}

NLFit&		NLFitSession::GetNLFitObj(int iSetIndex/* = 0*/)
{
	ASSERT( GetNumNLFitObjs() > 0 );
	if ( iSetIndex < 0 || iSetIndex >= GetNumNLFitObjs() )
	{
		ASSERT( NLPMGRTYPE_MULTIPLE_SETS == GetNLParamsMngr()->GetType() );
		iSetIndex = 0;
	}
	
	if ( 0 == iSetIndex )
		return m_NLFit;
	
	return m_arNLFitAdditionalObjs.GetAt(iSetIndex - GetNLFitArrayOffset());
}

bool		NLFitSession::CheckUpdateNLFitParamsLinking(int nDataset/* = 0*/)
{			
	if ( nDataset < 0 || nDataset >= GetNumDataset() )
		return false;
			
	if ( 1 == GetNumNLFitObjs() )
		return true;
	ASSERT( isSeparateFit() );
	m_pParamMngr->SetActiveDataset(nDataset);
	return ( 0 == GetNLFitObj(nDataset).UpdateParamsLinking(*m_pParamMngr) );
}
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT

/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
//// virtual
//bool		NLFitSession::OnSetFunction(int nFunc, DWORD dwSelFuncByTheme) // = 0, 0
// virtual
///------ Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
//bool		NLFitSession::OnSetFunction(int nFunc) // = 0
bool		NLFitSession::OnSetFunction(int nFunc, int* pErrCode/* = NULL*/)
///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
{
	//------ Folger 11/13/08 v8.0970 CHANGE_FUNCTION_SHOULD_RESET_SHARING
	//SetParamByFDFSettings(nFunc);
	SetParamByFDFSettings(nFunc, false, 0, true);
	//------
	
	//return DoUpdateParams(nFunc, m_bDlgChangeParams, dwSelFuncByTheme);
	///------ Folger 07/27/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	//return DoUpdateParams(nFunc); /// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	if ( !DoUpdateParams(nFunc) )
	{
		///------ Folger 08/06/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
		//if ( pErrCode )
			//*pErrCode = NLSF_ERR_UPDATE_PARAMS_FAILED;
		SetLastError(NLSF_ERR_UPDATE_PARAMS_FAILED, pErrCode);
		///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
		return false;
	}
	return true;
	///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
}

// virtual
///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
//void		NLFitSession::OnSetData()
void		NLFitSession::OnSetData( int nOldDataMode, int nNewDataMode )//INVALID_DATA_MODE,INVALID_DATA_MODE
///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
{
	if ( GetNumDataset() <= 0 )
	{
		error_report("No valid data is set.");
		return ;
	}
	else if ( GetNumDataset() > 1 )
		m_dwParamTypeCtrl |= NLF_PARAM_TYPE_CTRL_MULTI_SETS;
	else
		m_dwParamTypeCtrl &= ~NLF_PARAM_TYPE_CTRL_MULTI_SETS;
	
	if ( isNeedReinitParamType() )
	{
		ASSERT( NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS != getParamsType() );
		if ( GetNumberFitFunctions() <= 0 ) // Function not set yet
			return ;
		Tree		trFitFunction;
		trFitFunction = GetTreeFDF();
		string		strFuncName, strCateName;
		strFuncName = GetFunctionName(&strCateName);		
		int			nNumMultiplicity = 1;
		m_bInternalSetFunctionByDataChange = true; /// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
		/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
		Tree		trParamsSetttingsBackup;
		if ( isNeedRestoreParamsSettings() )
			m_pParamMngr->GetParamSettings(trParamsSetttingsBackup);
		/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
		/// Hong 09/25/09 SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
		//if ( !SetFunction(trFitFunction, nNumMultiplicity, true, NULL, 0, strFuncName, strCateName) )
		if ( !SetFunction(trFitFunction, nNumMultiplicity, true, strFuncName, strCateName) )
		/// end SIMPLY_INTERFACE_AS_SHARING_NOT_AVOID_WHEN_SET_FUNCTION
			error_report("Fail SetFunction after SetData");
		/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
		else if ( !trParamsSetttingsBackup.IsEmpty() )
			/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
			//m_pParamMngr->SetParamSettings(trParamsSetttingsBackup);
			SetParamSettings(trParamsSetttingsBackup);
			/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
		/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
		m_bInternalSetFunctionByDataChange = false; /// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION		
		return ;
	}
	else // Hong, to do, this mechanism may need more thinking and testing
	{
		///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		bool bDataUpdate = ( INVALID_DATA_MODE == nOldDataMode || DATA_MODE_CONCATENATE == nOldDataMode || DATA_MODE_CONCATENATE == nNewDataMode || nNewDataMode == nOldDataMode );
		///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		
		/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
		if ( GetNumDataset() > 1 ) // Hong, only multiple datasets have to reload FDF settings when set data as for single set, settings already be loaded by SetFunction
		{
			ASSERT( 1 == GetNumberFitFunctions() );
			///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
			//SetParamByFDFSettings(0, true, NLPARAMETERSETTINGS_VALUE);
			if( bDataUpdate )
				/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
				//SetParamByFDFSettings(0, true, NLPARAMETERSETTINGS_VALUE);
				SetParamByFDFSettings(0, isKeepOldDatasetParamsSettings(), NLPARAMETERSETTINGS_VALUE);
				/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
			///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		}
		/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
		///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		//m_dwAutoUpdateCtrl |= AUTO_UPDATE_INPUT_DATA_CHANGE; ///Arvin 04/02/08 QA70-11348 AUTO_PREVIEW_CHANGED_TO_AUTO_UPDATE_CLEANUP
		if( bDataUpdate )
			m_dwAutoUpdateCtrl |= AUTO_UPDATE_INPUT_DATA_CHANGE; ///Arvin 04/02/08 QA70-11348 AUTO_PREVIEW_CHANGED_TO_AUTO_UPDATE_CLEANUP
		///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
		//DoUpdateParams(-1, m_bDlgChangeParams, m_dwDlgThemeApplied, true);
		/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
		//DoUpdateParams(-1, true);
		DoUpdateParams(-1, isKeepOldDatasetParamsSettings());
		/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
		/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	}
}

// virtual 
void 		NLFitSession::OnParamChange(DWORD dwPlotCurves, bool bFromGUI) // = 0, false
{
}

void		NLFitSession::InitParamMngr()
{
	///------ Folger 05/12/09 NANOSIZER_FITTING_BASED_SUPPORT
	//m_pParamMngr->Initialize(getParamsType());
	DWORD	dwCntrl = 0;
	if ( IsInitFromNanosizer() )
	{
		dwCntrl |=NLPARAMMNGRCNTRL_NANOSIZER ;
		SetInitFromNanosizer(false);
	}
	m_pParamMngr->Initialize(getParamsType(), dwCntrl);
	///------ End NANOSIZER_FITTING_BASED_SUPPORT
	///Sophy 10/15/2008 CENTRALIZE_CODE_TO_UPDATE_LCL_UCL_SETTINGS
	int nComputeConfMethod = m_bGetParamsConf ? m_nConfLimitMethod : -1;
	m_pParamMngr->SetComputeConfLimitsMethod( nComputeConfMethod );
	///end CENTRALIZE_CODE_TO_UPDATE_LCL_UCL_SETTINGS
}

/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
//bool 		NLFitSession::DoUpdateParams(int nFunc, bool bChangeParams, DWORD dwUpdatedByTheme, bool bKeepOldSetting) // = -1, false, 0, false
///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS except with concatenate fit
//bool 		NLFitSession::DoUpdateParams(int nFunc, bool bKeepOldSetting) // = -1, false
bool 		NLFitSession::DoUpdateParams(int nFunc, bool bKeepOldSetting, DWORD dwCntrl ) // = -1, false, OSD_NO_PARAM_INIT
///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
{
	m_nRunParamInitResult = 0; //Parameters initialization hasn't run
	if ( m_bDisableUpdate )
		return true; // Hong, disable update should be deal as update success
	///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS except with concatenate fit
	//DWORD dwCntrl = 0;
	DWORD dwInitParam = ~OSD_NO_PARAM_INIT;
	///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
	string strMsg = "";
	if ( m_dwAutoUpdateCtrl & AUTO_UPDATE_INPUT_DATA_CHANGE )
	{
		///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS except with concatenate fit
		dwCntrl &= dwInitParam;
		///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		dwCntrl |= OSD_FROM_DATA_CHANGE;
		strMsg = STR_MSG_ON_SET_DATA;
	}
	//keep the original logic
	if ( m_dwAutoUpdateCtrl & AUTO_UPDATE_FUNC_CHANGE )
	{
		///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS except with concatenate fit
		dwCntrl &= dwInitParam;
		///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		dwCntrl |= OSD_FROM_FUNC_CHANGE;
		strMsg = STR_MSG_ON_SET_FUNC;
	}
	if ( m_dwAutoUpdateCtrl & AUTO_UPDATE_NUM_REPLICA_CHANGE )
	{
		///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS except with concatenate fit
		dwCntrl &= dwInitParam;
		///end SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		dwCntrl |= OSD_FROM_PARAM_REPLICA_NUM_CHANGE;
		strMsg = STR_MSG_ON_NUM_REPLICA_CHANGE;
	}
	if ( m_dwAutoUpdateCtrl & AUTO_UPDATE_FINDING_PEAK_ARG_CHANGE )
	{
		///Sophy 11/11/2008 v8.968c QA80-12567 SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS except with concatenate fit
		if( isMultiplicityFit() )
			dwCntrl &= dwInitParam;
		///end 	SWITCH_BETWEEN_FIT_MODE_SHOULD_NOT_ALWAYS_INIT_PARAMS
		dwCntrl |= OSD_FINDING_PEAK_ARG_CHANGE;
		strMsg = STR_MSG_ON_FINDING_PEAK_ARG_CHANGE;
	}
	
	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//bool 	bRet = onParamsNeedUpdate(dwCntrl, strMsg, dwUpdatedByTheme, bChangeParams, nFunc, bKeepOldSetting);
	bool 	bRet = onParamsNeedUpdate(dwCntrl, strMsg, nFunc, bKeepOldSetting);
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	
	int		nFpkRet = 0;
	if( (m_dwAutoUpdateCtrl & AUTO_UPDATE_NUM_REPLICA_CHANGE) || (m_dwAutoUpdateCtrl & AUTO_UPDATE_FINDING_PEAK_ARG_CHANGE) )
	{
		nFpkRet = replicaInitParamMsgLog(GetNumFoundPeaks(), GetNumberMultiplicity());
	}

	if ( 0 == nFpkRet )
		m_nRunParamInitResult = 0;
	else		
		m_nRunParamInitResult = nFpkRet > 0 ? 1 :-1;
	
	m_dwAutoUpdateCtrl = 0; //After update params, reset DWORD to 0
	
	return bRet;	
}

bool 		NLFitSession::UpdateParams(bool bFromGUI, bool bUpdateGraph, LPCSTR lpcszMsg) // = false, false, NULL
{	
	if( GetNumParameter() < 1 )	
		return error_report("Error setting parameters before setting function");
		
	if( GetNumDataset() < 0 )
		return error_report("Error setting parameters before setting data");

	string strMsg = lpcszMsg ? lpcszMsg: "SetParam";
	validateParams(strMsg);
	
	m_dwNLFitDirtyBits |= NLFIT_DIRTY_PARAMETER;

	OnParamChange(bUpdateGraph? NLFIT_ONPARAMCHANGE_UPDATE_DATA	| NLFIT_ONPARAMCHANGE_PREPARE_WKS : 0, bFromGUI);
	
	return true;
}

/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
//int			NLFitSession::GetParamsSubVectorRange(int nDataset, int nFunc, int* pnFrom, int* pnTo, int nPeak) // = -1, -1, NULL, NULL, -1
//{
	//if( nDataset < 0 && nFunc < 0 )
	//{
		//error_report("GetParamsSubVectorRange sees nDataset < 0 && nFunc < 0"); 
		//return 0;
	//}
	///// _NLF_81, Hong
	///*	
	//int 	nNumParaInFunc = m_nNumParaInFunc;
	//NLFitFunction* pFitFunc = GetFitFunction(nFunc);
	//nNumParaInFunc = pFitFunc->GetNumParaInFunc();
	//
	//int nMyFrom = 0, nMyTo = 0;
	//int nNumParams = nNumParaInFunc;
	//nNumParams = GetParamsSubVectorRange(pFitFunc, nDataset, nFunc, &nMyFrom, &nMyTo, nPeak);	
	//if ( nNumParams < 0 )
	//{
		//error_report("GetParamsSubVectorRange err: " + (string)nNumParams); 
		//return 0;
	//}
	//
	//if(nMyTo >= 0 && nMyFrom >= 0 )
	//{
		//nNumParams = nMyTo - nMyFrom + 1;
		//if ( pnFrom )
			//*pnFrom = nMyFrom;
		//if ( pnTo ) 
			//*pnTo = nMyTo;
	//}
	//
	//return nNumParams;
	//*/
	//return GetNumParameter(nFunc);
	///// end _NLF_81, Hong
//}
/// Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
//int			NLFitSession::GetParamsSubVectorRange(int nDataset, int nFunc, int* pnFrom)
int			NLFitSession::GetParamsSubVectorRange(int nDataset, int nFunc, int* pnFrom, int* pnLastFromOnlySingleSet/* = NULL*/, int* pnLastFunc/* = NULL*/)
/// end PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
{
	if ( NULL == pnFrom || nDataset < 0 || nFunc < 0 || nFunc >= GetNumberFitFunctions() )		
		return 0;	
	
	int		nSingleSetTotalParamNum = 0;
	/// Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	//for ( int ii = 0; ii < nFunc; ++ii )
	int		ii = 0;
	bool	bHasLastResult = false;
	if ( NULL != pnLastFromOnlySingleSet && NULL != pnLastFunc && -1 != *pnLastFromOnlySingleSet && -1 != *pnLastFunc )
	{
		nSingleSetTotalParamNum = *pnLastFromOnlySingleSet;
		ii = *pnLastFunc;
		bHasLastResult = true;
	}
	for ( ; ii < nFunc; ++ii )
	/// end PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	{		
		// Hong, to do, this will be problem with replica, need talk with Folger allow parameter manager to return number of parameters with replicas,
		// maybe need another function to return 7 instead of 4 as there is still place want 4 as return value
		/// Hong 09/16/08 FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK
		//nSingleSetTotalParamNum += GetNumParameter(ii);		
		nSingleSetTotalParamNum += GetNLParamsMngr()->GetNumParamsInFunc(ii);				
		/// end FIX_GET_TOTAL_NUM_PARAMS_FAIL_TO_WORK
	}
	*pnFrom = nSingleSetTotalParamNum * (nDataset + 1);
	/// Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	if ( NULL != pnLastFromOnlySingleSet )
		*pnLastFromOnlySingleSet = nSingleSetTotalParamNum;
	if ( NULL != pnLastFunc )
		*pnLastFunc = ii;
	/// end PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	
	return GetNumParameter(nFunc);
}
/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER

bool		NLFitSession::UpdateInputBranch(TreeNode &trInput)
{
	StringArray		vstrIndepVars, vstrDepVars;
	int				numDeps, numIndeps;	
	if ( !GetNumVars(&numDeps, &numIndeps, &vstrDepVars, &vstrIndepVars) )	// not yet set?
	{
		return error_report("NLFitSession::UpdateInputBranch() failed to get function info");
	}
	
	TreeNode		trInputData;	
	if ( !okutil_create_fitter_data_node_ex(&trInputData, &trInput, STR_INPUT_RANGE_NAME, STR_INPUT_RANGE_LABEL, &vstrIndepVars, &vstrDepVars, WEIGHT_NONE, TRUE) )
		return error_report("Failed to create fitter data node");
	
	SetInitData(false);	
	return true;
}

/// Hong 08/27/08 v8.0931 FIX_ORIGIN_CRASH_WHEN_CLICK_OK_AFTER_CONVERGE
int			NLFitSession::CallBack(int nMsg, LPCSTR lpcszStatus, int nParam, int lParam)
{
	return OnCallBack(nMsg, lpcszStatus, nParam, lParam);
}

int 		NLFitSession::OnCallBack(int nMsg, LPCSTR lpcszStatus, int nParam, int lParam)
{
	switch(nMsg)
	{
	case NLFI_BEGIN:
		okutil_system_message(NULL, 8);
		// ESC has the problem of getting into Code Builder break, so we better use something else
		okutil_system_message(_L("Hit Ctrl-C to abort"), 1);
		//okutil_system_message(_L("Hit ESC to abort"), 1);
		break;
	case NLFI_END:
		okutil_system_message(NULL);
		break;
	default:
		if(lpcszStatus)
			okutil_system_message(lpcszStatus, 1);
		if(is_key_hit('C', true, VK_CONTROL))
		//if(is_key_hit()) // this is for ESC (default)
			return 1;
		break;
	}
	return 0;
}
/// end FIX_ORIGIN_CRASH_WHEN_CLICK_OK_AFTER_CONVERGE

/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
BOOL		NLFitSession::SetParamSettings(const TreeNode &trOperationParams, DWORD dwSettingsToSkip/* = 0*/, bool bDuplicateLastSetValues/* = false*/)
{
	m_bParamsFromAutoInit = false;
	return m_pParamMngr->SetParamSettings(trOperationParams, dwSettingsToSkip, bDuplicateLastSetValues);
}
/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	
void 		NLFitSession::onInit(bool bSingleFunction)
{
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	m_arNLFitAdditionalObjs.SetAsOwner(TRUE);	
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	
	m_dwNLFitDirtyBits	= 0;
	
	m_nOldNumberDataset	= 0;	
	m_nBackupOldNumDataset = 0; /// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
	m_nNumFoundPeaks	= 0;
	
	m_nRunParamInitResult	= 0;
	m_bDisableUpdate	= false;
	m_dwAutoUpdateCtrl	= 0;	
	
	m_pDataObj 		= NULL; // can't determine type here yet, pending it's init to set data
	m_bInitData		= true;
	
	m_nlfDataType = DATA_TYPE_SINGLE_SET;
	onInitDataObject(); // Hong, to do, maybe need to find out a more proper place
	//m_pnlfCurves	= new NLFCurvesBase; /// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
	
	m_dTolerance	= 1e-9;
	m_dConfidence	= 0.95;
	m_bGetParamsConf	= false;
	m_bScaleParamErrors = true;
	m_DerivsSettings.rDerivStepSize 	= 0.005;	
	m_DerivsSettings.rMinDerivStepSize	= 5e-30;
	m_DerivsSettings.rMaxDerivStepSize	= 5e30;//5e-30;	///Jasmine 12/20/07 FIX_PFW_FIT_NOT_CONVERGE_BUG, appear in FraserSuzuki.fdf and ConsGaussian.fdf. I see default value in FitNL.cpp is 5E30, so I think here is a typo...
	m_DerivsSettings.bFixedDerivStepSize= 0;
	
	m_pParamMngr	= new NLParametersManager;
	m_dwParamTypeCtrl = bSingleFunction ? 0 : NLF_PARAM_TYPE_CTRL_MULTI_FUNCTIONS;
	InitParamMngr(); // Hong, to do, maybe need to find out a more proper place	
	
	m_pOpMsgLog 	= NULL;

	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	//m_bDlgChangeParams	= false;
	//m_dwDlgThemeApplied = 0;	
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	
	resetIterations(OSD_FROM_CLEANUP); 	
	if ( !bSingleFunction ) /// Hong 09/26/08 v8.0948 FIX_MULTI_DEPS_INDEPS_FAIL_ITERATE
		SetMultipeakOptions(); /// Hong, Jasmine 08/14/08 PEAKSMODE_MULTIFUNC_GLC
	
	m_bInternalSetFunctionByDataChange = false; /// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION

	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	m_nSepFitActiveDataset = 0;
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//m_arNLFitResults.SetAsOwner(TRUE);
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/// Hong 01/25/10 QA80-15026 NLFIT_USE_EMPTY_FUNC_WHEN_SWITCH_CATEGORY
	//m_vnLastIterateOutCome.Add(FITITER_FAILED); // Hong, to do, LastIterateOutCome is access before fit, which is bug, temp fix
	m_vnLastIterateOutCome.Add(FITITER_NO_ITERATE);
	/// end NLFIT_USE_EMPTY_FUNC_WHEN_SWITCH_CATEGORY
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	///------ Folger 02/04/09 QA80-12962 ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	m_bUseSmartX = false;
	m_nXPtsForEachPeak = FITCURVE_POINTS_FOR_INDIVIDUAL_PEAKS;
	///------ End ADD_OPTION_IN_PA_FIT_TO_SWTICH_BACK_TO_OLD_FIT_CURVE_DATA_GENERATION_MECHANISM
	
	m_nMaxNumIter = MAX_INTERATE_NUM_TRY_CONVERGE;		///------ Folger 03/09/09 PROPER_HANDLE_OF_MAX_NUM_ITERATE_IN_FIT_PARAM_DIALOG
	
	m_bInitFromNanosizer = false;				///------ Folger 05/12/09 NANOSIZER_FITTING_BASED_SUPPORT
	
	m_bParamsFromAutoInit = false; /// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	
	/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	m_bIterateSettingsPolished = false;
	m_bLastFitIterateTillConverge = false;
	/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	
	/// Hong 03/13/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	m_bDuringGetResultWithIterate = false;
	/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE

	///------ Folger 08/06/10 ORG-504 RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
	m_nLastError = 0;
	///------ End RESIDUAL_PLOT_IN_REPORT_SHEET_FAILED_TO_SHOW_FOR_MULTIPLE_INDEPS_FITTING
}

void 		NLFitSession::onDestroy()
{
	if ( m_pParamMngr )
	{
		///---Sim 09-10-2008 NLFIT_LABTALK_TREE_ACCESS
		//m_pParamMngr->LinkLabtalkTree(NULL);
		///---END NLFIT_LABTALK_TREE_ACCESS
		delete m_pParamMngr;
		m_pParamMngr = NULL;
	}
		
	onDestroyDataObject();
	
	if(m_wksConcatenate)
		m_wksConcatenate.Destroy();
	
	/// Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
	if(m_wksSubtracted)
		m_wksSubtracted.Destroy();
	///end PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
}

int			NLFitSession::getDataType()
{		
	return m_nlfDataType;
}

void		NLFitSession::onInitDataObject()
{	
	onDestroyDataObject();
	
	switch ( getDataType() )
	{
	case DATA_TYPE_SINGLE_SET:
		m_pDataObj = new NLFDataSingleIndep;
		break;
	case DATA_TYPE_MULTI_SET:
		m_pDataObj = new NLFDataMultiIndeps;
		break;
	/// Hong 07/14/08 v8.0901 DATA_OBJ_SUPPORT_SURFACE_DATA
	case DATA_TYPE_SURFACE:
		m_pDataObj = new NLFDataSurface;
		break;
	/// end DATA_OBJ_SUPPORT_SURFACE_DATA
	/// Hong 08/14/08 v8.0922 FIX_MATRIX_FIT_FAIL_DO_REDUCE
	case DATA_TYPE_MATRIX:
		m_pDataObj = new NLFDataMatrix;
		break;
	/// end FIX_MATRIX_FIT_FAIL_DO_REDUCE
	default:
		ASSERT(FALSE);
		break;
	}
}

void		NLFitSession::onDestroyDataObject()
{
	if ( m_pDataObj )
	{
		delete m_pDataObj;
		m_pDataObj = NULL;
	}
}

bool		NLFitSession::getFunctionTree(TreeNode& trFF, LPCSTR lpcszFunctionName, string& strCategoryName, bool bLoadFDF) // = true
{
	if ( !m_NFO.LoadEx(trFF, lpcszFunctionName, strCategoryName, bLoadFDF) )
		return false;
	
	return true;
}

/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
//void 		NLFitSession::NLFitReset(int nWhat, bool bResetInternal) //  = ONLSF8RESET_ALL, false
void 		NLFitSession::NLFitReset(int nWhat, bool bResetIterateCount) //  = ONLSF8RESET_ALL, true
/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
{
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//m_NLFit.Reset(nWhat);
	for ( int ii = 0; ii < GetNumNLFitObjs(); ++ii )
	{
		GetNLFitObj(ii).Reset(nWhat);
	}
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	
	/// Hong 21/05/08 v8.0867d FIX_ITRATE_WORK_ONLY_ONCE
	DWORD	dwNLFDirtyBits = 0;
	DWORD	dwResetIteration = 0; /// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	switch ( nWhat )
	{
	case ONLSF8RESET_ALL:
	case ONLSF8RESET_FUNCTIONS:		
		dwNLFDirtyBits = NLFIT_DIRTY_FUNCTION | NLFIT_DIRTY_FUNCTION | NLFIT_DIRTY_DATA;
		dwResetIteration = OSD_FROM_FUNC_CHANGE; /// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
		break;
	case ONLSF8RESET_DATA:
		dwNLFDirtyBits = NLFIT_DIRTY_DATA | NLFIT_DIRTY_PARAMETER;
		dwResetIteration = OSD_FROM_DATA_CHANGE; /// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
		break;
	case ONLSF8RESET_PARAMETERS:
		dwNLFDirtyBits = NLFIT_DIRTY_PARAMETER;		
		dwResetIteration = OSD_FROM_EDIT_PARAM_CHANGE; /// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
		break;
	}
	m_dwNLFitDirtyBits |= dwNLFDirtyBits;
	
	if ( dwNLFDirtyBits != 0 )
	{
		m_pParamMngr->OnAfterResetNLFit();						
	}	
	/// end FIX_ITRATE_WORK_ONLY_ONCE
	/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	if ( 0 != dwResetIteration)
	{	// Hong, to do, DWORD here is NOT accurate, need more work
		resetIterations(dwResetIteration, bResetIterateCount);
	}
	/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG	
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	///// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//if ( 0 != dwNLFDirtyBits && m_arNLFitResults.GetSize() > 0 ) // Empty backup of fit results once NLFit Reset
	//{
		//m_arNLFitResults.SetSize(0);
	//}
	///// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/// Hong, to do, i think code below is redundant in new mechanism of Parameter Manager, so remove first
	//if(bResetInternal)
	//{
	//	if(nWhat <= ONLSF8RESET_FUNCTIONS)
	//	{
	//		//ResizeParamsVectors(OSD_FROM_FUNC_CHANGE, SHARE_SETTING_MODE_RESET_ALL, true); // Hong, to do
	//	}
	//}
}

/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
//bool 		NLFitSession::onParamsNeedUpdate(DWORD dwCntrl, LPCSTR lpcszMsg, DWORD dwUpdatedByTheme, bool bChangeParams, int nFunc, bool bKeepOldSetting) // NULL, 0, false, -1, false
bool 		NLFitSession::onParamsNeedUpdate(DWORD dwCntrl, LPCSTR lpcszMsg, int nFunc, bool bKeepOldSetting) // NULL, -1, false
/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
{
	if ( dwCntrl & OSD_NO_PARAM_UPDATE )
		return false;

	/// Hong 08/19/08 v8.0925 REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	/*
	TreeNode	trParams;
	if ( dwUpdatedByTheme || bChangeParams )
	{
		trParams = m_trOpParams;
	//else if ( dwUpdatedByTheme & OSD_THEME_CHANGE_FACTORY_DEFAULT ) // seem the mechanism of original setting is not used anymore
	//	trParams = m_trOriginal;
		OperationGUIToParams(trParams);
	}	
	if ( !bChangeParams && !(dwCntrl & OSD_NO_PARAM_INIT) && GetNumDataset() > 0 && GetNumTotalParams(nFunc) > 0 )
	{		
		DWORD	dwInitCtrl = 0;
		if ( dwUpdatedByTheme & NLFIT_COPY_GUI_SETTING_PARAMS )
			dwInitCtrl |= NLF_THEME_CHANGE;
		if ( bKeepOldSetting )
			dwInitCtrl |= NLF_KEEP_OLD_DATASET;		
			
		if ( !ParamsInitValues(m_bAutoRunInitParams, dwInitCtrl, nFunc) )
			return error_report("Parameters initialization failed!");
	}
	*/
	/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	//if ( !(dwCntrl & OSD_NO_PARAM_INIT) && GetNumDataset() > 0 && GetNumTotalParams(nFunc) > 0 )
	if ( !(dwCntrl & OSD_NO_PARAM_INIT) && GetNumDataset() > 0 && GetNumParameter(nFunc) > 0 )
	/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	{		
		DWORD	dwInitCtrl = 0;
		if ( bKeepOldSetting )
			dwInitCtrl |= NLF_KEEP_OLD_DATASET;		
			
		if ( !ParamsInitValues(m_bAutoRunInitParams, dwInitCtrl, nFunc) )
			return error_report("Parameters initialization failed!");
	}
	/// end REMOVE_THEME_KNOWLEDGE_OUT_OF_SESSION
	bool bPlotFitCurve = IsPlotFitCurve(dwCntrl);	
	return UpdateParams(0, bPlotFitCurve, lpcszMsg);
}

enum {
	RPK_NO_PKS_FOUND = -1,
	RPK_TOO_FEW_PKS = -2,
	
	RPK_SUCCESS = 1, // success, 
	RPK_FOUND_TOO_MANY, // still ok
};
int 		NLFitSession::replicaInitParamMsgLog(int nNumFoundPeaks, int nNumNeededPeaks)
{
	if ( isMsgLogAvailable() )
	{		
		string strTitle = _L("----------Parameters Initialization for Replica----------");
		writeMsgLog(strTitle);
	}
	
	int 		nRet = 0;	
	string 		strMsg, strFindPeaks;
	strFindPeaks.Format("%d peaks", nNumFoundPeaks);		
	if ( nNumFoundPeaks == nNumNeededPeaks )
	{
		nRet = RPK_SUCCESS;
		ocu_load_msg_str(NLFIT_MSG_LOG_REPLICA_PARAM_INIT_SUCCESS, &strMsg, NULL, &nNumFoundPeaks);
	}
	else if(nNumFoundPeaks <= 0)
	{
		nRet = RPK_NO_PKS_FOUND;
		ocu_load_msg_str(NLFIT_MSG_LOG_REPLICA_FIND_PEAK_FAILED, &strMsg);
	}
	else if(nNumFoundPeaks < nNumNeededPeaks)
	{
		nRet = RPK_TOO_FEW_PKS;
		ocu_load_msg_str(NLFIT_MSG_LOG_REPLICA_FIND_LESS_PEAK, &strMsg, strFindPeaks, &nNumNeededPeaks);		
		if ( isMsgLogAvailable() )
			writeMsgLog(strMsg, false);		
		
		ocu_load_msg_str(NLFIT_MSG_LOG_REPLICA_ADJUST_SETTINGS, &strMsg);
	}
	else// if(nNumFoundPeaks > nNumNeededPeaks)
	{
		nRet = RPK_FOUND_TOO_MANY;
		ASSERT(nNumFoundPeaks > nNumNeededPeaks);
		ocu_load_msg_str(NLFIT_MSG_LOG_REPLICA_FIND_ENOUGH_PEAK, &strMsg, strFindPeaks, &nNumNeededPeaks);
	}
	
	if ( isMsgLogAvailable() )
		writeMsgLog(strMsg, false);
	
	return nRet;
}

int			NLFitSession::numReplicaToMultiplicity(int nNumReplica)
{
	return nNumReplica + 1;
}

int			NLFitSession::numMultiplicityToReplica(int nNumMultiplicity)
{
	return nNumMultiplicity - 1;
}

bool		NLFitSession::setNumMultiplicity(int nNumMultiplicity, int nFunc)
{
	if ( nNumMultiplicity > 1 )
	{
		ASSERT(0 == nFunc);
		ASSERT(NLPMGRTYPE_SINGLE_SET_SINGLE_FUNCTION_MULTIPEAKS == m_pParamMngr->GetType());
		if ( !m_pParamMngr->SetNumMultiplicity(nNumMultiplicity) )
			return error_report("SetNumMultiplicity fail.");
	}
	return true;
}
///Sophy 10/24/2008 SUPPORT_MUILTI_INDEP_AND_DEP_PREVIEW_FOR_NLFIT_81 change as public
//bool		NLFitSession::getInputData(vector& vData, bool bDep, int nDatasetIndex, int nIndex) // = 0
bool		NLFitSession::GetInputData(vector& vData, bool bDep, int nDatasetIndex, int nIndex) // = 0
///end SUPPORT_MUILTI_INDEP_AND_DEP_PREVIEW_FOR_NLFIT_81
{
	if ( bDep )
	{
		if ( !m_pDataObj->GetDependData(vData, nDatasetIndex, nIndex) )
			return false;
	}
	else
	{
		if ( !m_pDataObj->GetIndependData(vData, nDatasetIndex, nIndex) )
			return false;
	}
	return true;
}
bool		NLFitSession::checkSetNLFitFunction()
{
	/// Hong 09/11/08 v8.0937 CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG
	//if ( m_dwNLFitDirtyBits & NLFIT_DIRTY_FUNCTION )
	bool		bMngrFuncDirty = (NLFITDIRTY_FUNCTION & GetNLParamsMngr()->GetNLFitDirtyStatus()) ? true : false;
	if ( bMngrFuncDirty || m_dwNLFitDirtyBits & NLFIT_DIRTY_FUNCTION )
	/// end CLEAN_NLFIT_DLG_MSG_TRY_AVOIDING_POST_MSG	
	{
		//------ Folger 10/24/08 v8.0960 CORRECT_FUNCTION_AND_PARAMETER_DIRTY_BITS_CHECKING
		/// after set function, parameters always become dirty
		m_dwNLFitDirtyBits |= NLFIT_DIRTY_PARAMETER;
		//------ End CORRECT_FUNCTION_AND_PARAMETER_DIRTY_BITS_CHECKING
		
		/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		//if ( m_NLFit.SetFunctions(*m_pParamMngr) )
		int		nDatasetIndex = isSeparateFit() ? m_nSepFitActiveDataset : 0;
		if ( GetNLFitObj(nDatasetIndex).SetFunctions(*m_pParamMngr) )
		/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
			return false;
		m_dwNLFitDirtyBits &= ~NLFIT_DIRTY_FUNCTION;
	}
	return true;
}

bool		NLFitSession::checkSetNLFitData()
{
#ifdef	NLF_DEBUG	
	int		nNumDepsInFunc, nNumIndepsInFunc, nNumDepsInData, nNumIndepsInData;	
	if ( !GetNumVars(&nNumDepsInFunc, &nNumIndepsInFunc) )
	{
		m_pDataObj->GetNumVars(nNumDepsInData, nNumIndepsInData);
		ASSERT(nNumDepsInFunc == nNumDepsInData);
		ASSERT(nNumIndepsInFunc == nNumIndepsInData);
	}
#endif	//NLF_DEBUG
	if ( m_dwNLFitDirtyBits & NLFIT_DIRTY_DATA )
	{
		PNLSFONEDATA 	pstDependentData, pstIndependentData;
		PONEDATAWEIGHT	pstWeightDesc;
		/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT	
		//pstDependentData	= m_pDataObj->GetDependData();
		//pstIndependentData	= m_pDataObj->GetIndependData();
		//pstWeightDesc		= m_pDataObj->GetWeightData();
		//if ( m_NLFit.SetData(GetNumDataset(), pstDependentData, pstIndependentData, pstWeightDesc) )
			//return false;
		int		nDatasetIndex = isSeparateFit() ? m_nSepFitActiveDataset : 0;
		pstDependentData	= m_pDataObj->GetDependDatas(nDatasetIndex);
		pstIndependentData	= m_pDataObj->GetIndependDatas(nDatasetIndex);
		pstWeightDesc		= m_pDataObj->GetWeightDatas(nDatasetIndex);

		ASSERT(pstDependentData && pstIndependentData);
		int		nNumDatasetToFit = isSeparateFit() ? 1 : GetNumDataset();
		/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		//if ( m_NLFit.SetData(nNumDatasetToFit, pstDependentData, pstIndependentData, pstWeightDesc) )
		if ( GetNLFitObj(nDatasetIndex).SetData(nNumDatasetToFit, pstDependentData, pstIndependentData, pstWeightDesc) )
		/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
			return false;
		/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT			
		m_dwNLFitDirtyBits &= ~NLFIT_DIRTY_DATA;
	}
	return true;
}

bool		NLFitSession::checkSetNLFitParameter()
{
#ifdef	NLF_DEBUG
	if ( NLPMGRTYPE_MULTIPLE_SETS == m_pParamMngr->GetType() )
	{
		ASSERT( DATA_TYPE_MULTI_SET == getDataType() && GetNumDataset() > 1 );
	}
	else
	{
		ASSERT( 1 == GetNumDataset() );
	}
	
	if ( isSeparateFit() )
		ASSERT( m_dwNLFitDirtyBits & NLFIT_DIRTY_PARAMETER );
#endif	//NLF_DEBUG
	//------ Folger 10/24/08 v8.0960 CORRECT_FUNCTION_AND_PARAMETER_DIRTY_BITS_CHECKING
	//if ( m_dwNLFitDirtyBits & NLFIT_DIRTY_PARAMETER )
	bool		bMngrParamsDirty = (NLFITDIRTY_PARAMETERS & GetNLParamsMngr()->GetNLFitDirtyStatus()) ? true : false;
	if ( bMngrParamsDirty || (m_dwNLFitDirtyBits & NLFIT_DIRTY_PARAMETER) )
	//------ End CORRECT_FUNCTION_AND_PARAMETER_DIRTY_BITS_CHECKING
	{
		/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		if ( isSeparateFit() )
			m_pParamMngr->SetActiveDataset(m_nSepFitActiveDataset);
		/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		//if ( m_NLFit.SetParams(*m_pParamMngr) )
		int		nDatasetIndex = isSeparateFit() ? m_nSepFitActiveDataset : 0;
		if ( GetNLFitObj(nDatasetIndex).SetParams(*m_pParamMngr) )
		/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		{	
			validateParams("SetParams");
			return false;
		}
		m_dwNLFitDirtyBits &= ~NLFIT_DIRTY_PARAMETER;
	}
	return true;
}

void		NLFitSession::beforeFit(int nMethod)
{			
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//if ( FITMETH_LEVENBERG_MARQUARDT == nMethod && 0 == m_nIterCount )
	if ( FITMETH_LEVENBERG_MARQUARDT == nMethod && 0 == m_vnIterCount[m_nSepFitActiveDataset] )
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	{
		string	strScript = nlsf_get_before_or_after_fitting_codes(GetTreeFDF(), true);
		if ( !strScript.IsEmpty() )		
		{			
			/// Hong 01/04/10 QA80-14907 FITTING_VARIABLE_BETTER_SCOPE
			LTVarTempChange		addToGlobalScope("@global", 1);
			/// end FITTING_VARIABLE_BETTER_SCOPE
			/// Hong 01/04/10 QA80-14907 TAG_FITTING_VARIABLE_AND_REMOVE_THOSE_CREATED_BY_LAST_FITTING
			const int			nNLFitLTVarGroup = 1;
			string				strDelLastFitVar;
			strDelLastFitVar.Format("del -vgc %d", nNLFitLTVarGroup);
			LT_execute(strDelLastFitVar);
			LTVarTempChange		enableNLFitLTVarGroup("@vg", nNLFitLTVarGroup);
			/// end TAG_FITTING_VARIABLE_AND_REMOVE_THOSE_CREATED_BY_LAST_FITTING
			LT_execute(strScript);
		}
	}
	
	BOOL	bRet = TRUE;
	bRet &= checkSetNLFitFunction();
	bRet &= checkSetNLFitData();	
	bRet &= checkSetNLFitParameter();
	ASSERT(bRet);	
	
	setFitSettings();
}

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
void		NLFitSession::afterFit()
{
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//if ( doesNeedBackupFitResults() )
	//{
		//backupSepFitResults();
	//}	
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	m_bIterateSettingsPolished = true; /// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
}

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//void		NLFitSession::backupSepFitResults()
//{
	//ASSERT( doesNeedBackupFitResults() );
	//
	//int				nNumResults = GetNumDataset();
	//if ( m_arNLFitResults.GetSize() < nNumResults )
		//m_arNLFitResults.SetSize(nNumResults);
	//
	//BOOL 			bRet = TRUE;	
	//
	//RegStats			stFitRegStats;
	//NLSFFitInfo			stFitInfos;	
	//StringArray			stFitDerivedParamNames;
	//DoubleArray			stFitDerivedParamValues;
	//RegANOVA			stFitRegANOVAs;
	//RegANOVARow			stFitRegANOVARows;
	//FitParameter*		pstFitParamResults;
	//const int			nSize = GetNumTotalParams();
	//PointerManager		pmParamResults(&pstFitParamResults, sizeof(FitParameter) * nSize);	
	//
	//bRet &= getFitResultsStats(&stFitRegStats, &stFitInfos, false, 0);
	//bRet &= (0 == getFitResultsParams(pstFitParamResults, NULL, 0)) ? FALSE : TRUE;
	//bRet &= getDerivedParameters(0, &stFitDerivedParamNames, &stFitDerivedParamValues);
	//bRet &= getANOVAResult(stFitRegANOVAs, stFitRegANOVARows, 0);
	//
	//NLFitResults*	pNLFitResults = new NLFitResults;
	//pNLFitResults->arFitParamResults.SetAsOwner(TRUE);
	//for ( int ii = 0; ii < nSize; ii++ )
	//{
		//FitParameter*		pTemp = new FitParameter;
		//*pTemp = *pstFitParamResults;
		//++pstFitParamResults;
		//pNLFitResults->arFitParamResults.Add(*pTemp);
	//}
	//
	//pNLFitResults->stFitRegStats = stFitRegStats;
	//pNLFitResults->stFitInfos = stFitInfos;	
	//pNLFitResults->stFitDerivedParamNames= stFitDerivedParamNames;
	//pNLFitResults->stFitDerivedParamValues= stFitDerivedParamValues;
	//pNLFitResults->stFitRegANOVAs = stFitRegANOVAs;
	//pNLFitResults->stFitRegANOVARows = stFitRegANOVARows;
	//
	//bRet &= m_arNLFitResults.SetAt(m_nSepFitActiveDataset, *pNLFitResults);
	//ASSERT(bRet);
//}
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	
/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//bool 		NLFitSession::getFitResultsStats(RegStats* pRegStats, NLSFFitInfo* pFitInfo, bool bPreDataset/* = false*/, int nSetIndex/* = -1*/, int nDepIndex/* = 0*/)
/// Hong 06/01/09 IMPROVE_DEFAULT_VALUE
//bool 		NLFitSession::GetFitResultsStats(RegStats* pRegStats, NLSFFitInfo* pFitInfo, bool bPreDataset/* = false*/, int nSetIndex/* = -1*/, int nDepIndex/* = 0*/)
bool 		NLFitSession::GetFitResultsStats(RegStats* pRegStats, NLSFFitInfo* pFitInfo, bool bPreDataset/* = false*/, int nSetIndex/* = 0*/, int nDepIndex/* = 0*/)
/// end IMPROVE_DEFAULT_VALUE
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
{
	CheckUpdateNLFitParamsLinking(nSetIndex); /// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	ASSERT(pRegStats);
	if ( bPreDataset )
	{
		RegStatsPerDataset stRegStatsPerDataset;
		/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		//if ( 0 == m_NLFit.GetFitResultsPerDataset(&stRegStatsPerDataset, nSetIndex, nDepIndex) )
		if ( 0 == GetNLFitObj(nSetIndex).GetFitResultsPerDataset(&stRegStatsPerDataset, GetDatasetIndexInNLFit(nSetIndex), nDepIndex) )
		/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		{	
			pRegStats->SSR = stRegStatsPerDataset.SSR;
			pRegStats->RSqCOD = stRegStatsPerDataset.RSqCOD;
			pRegStats->Rvalue = stRegStatsPerDataset.Rvalue;
		}
		else
			return error_report("Fail to get statistics result for each dataset");
	}	
	else
	{
		/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		//if( 0 != m_NLFit.GetSummaryFitResults(pRegStats, pFitInfo) )
		if( 0 != GetNLFitObj(nSetIndex).GetSummaryFitResults(pRegStats, pFitInfo) )
		/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
			return false;		
	}	
	
	return true;	
}

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//bool		NLFitSession::getANOVAResult(RegANOVA &sRegANOVA, RegANOVARow &sCorrTotal, int nSetIndex/* = 0*/, int nDepIndex/* = 0*/)
bool		NLFitSession::GetANOVAResult(RegANOVA &sRegANOVA, RegANOVARow &sCorrTotal, int nSetIndex/* = 0*/, int nDepIndex/* = 0*/)
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
{
	if ( m_pDataObj->IsExceedLimitation(nSetIndex, nDepIndex) )
		return false;
	
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//if ( m_NLFit.GetANOVAResults(&sRegANOVA, &sCorrTotal, nSetIndex, nDepIndex) )
	CheckUpdateNLFitParamsLinking(nSetIndex);
	if ( GetNLFitObj(nSetIndex).GetANOVAResults(&sRegANOVA, &sCorrTotal, GetDatasetIndexInNLFit(nSetIndex), nDepIndex) )
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		return false;
	
	return true;
}

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//int			NLFitSession::getFitResultsParams(FitParameter* pFitParameter, RegStats *pstRegStats/* = NULL*/, int nDataset/* = 0*/, bool bIncDerivedParams/* = false*/)
int			NLFitSession::GetFitResultsParams(FitParameter* pFitParameter, RegStats *pstRegStats/* = NULL*/, int nDataset/* = 0*/, bool bIncDerivedParams/* = false*/)
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
{	
	CheckUpdateNLFitParamsLinking(nDataset); /// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/// Hong 10/22/08 QA80-12374 FIX_UCL_LCL_MISSING_IN_REPORT_WHEN_CHECKED_AFTER_FIT_CONVERGE
	// this is necessary due to code below---Folger 10/16/08 LCL&UCL_CAN_BE_CORRECTLY_GET_BY_GetParameterResults
	if ( m_bGetParamsConf )
	{
		/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
		//m_NLFit.ComputeParametersConfidenceLimits(NULL, NULL, m_nConfLimitMethod);
		GetNLFitObj(nDataset).ComputeParametersConfidenceLimits(NULL, NULL, m_nConfLimitMethod);
		/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	}
	/// end FIX_UCL_LCL_MISSING_IN_REPORT_WHEN_CHECKED_AFTER_FIT_CONVERGE
	
	/// Hong 10/10/08 v8.0953b NEW_MECHANISM_SHOULD_NOT_USE_SetFunctionsMultipeakFitting
	/////Jasmine 10/25/07 QA70-10543 NEW_METHOD_TO_GET_PARAM_RESULT_FOR_PFM
	//------ Folger 10/13/08 SHOULD_GET_NON_TRIMMED_PARAMETERS_RESULTS_FOR_NLFIT_REPORT
	//if(m_NLFit.GetParameterResults(pFitParameter, nDataset) == 0) // no err
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//if(m_NLFit.GetParameterResults(pFitParameter, nDataset, FALSE) == 0) // no err
	if ( GetNLFitObj(nDataset).GetParameterResults(pFitParameter, GetDatasetIndexInNLFit(nDataset), FALSE) == 0 ) // no err
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//------
	//if(GetParameterResults(pFitParameter, nDataset) == 0) // no err	
	/////End NEW_MECHANISM_SHOULD_NOT_USE_SetFunctionsMultipeakFitting
	/// end NEW_PARMA_MNGE_SHOULD_USE_SIMPLE_INTERFACE
	{
		///Arvin 08/03/07 WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
		int 	nMultiplicity = GetNumberMultiplicity();
		int		nUnit = GetReplicaUnitFromFDF();
		int 	nParams = GetNumParameter();
		bool	bReplicaFit = nMultiplicity > 1 ? true : false;
		if(bReplicaFit)
			nParams = nParams + nUnit*(nMultiplicity-1);
		///END WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
		if(1 < GetNumberFitFunctions())
		{
			vector<string> vstrParameterNames;
			nParams = GetParamNamesInFunction(vstrParameterNames, -1);
		}
		//------ Folger 10/16/08 LCL&UCL_CAN_BE_CORRECTLY_GET_BY_GetParameterResults
		/*
		/// Iris 12/20/2006 v8.0529 CORRECT_THE_METHOD_OF_COMPUTION_PARAM_CONF_LIMIT
		if(m_bGetParamsConf && CONF_LIMIT_METHOD_AS_BASED == m_nConfLimitMethod)
		{
			vector		vConfLimits;
			m_NLFit.GetParameterResults(NULL, NULL, &vConfLimits);
			if(vConfLimits.GetSize() < GetNumParameter())
				error_report("beyond the bound of m_vConfLimits");
			else
			{			
				///Arvin 06/13/07 RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS 
				//If isLastFitOutComeError in function Iterate, vectors m_vConfLower and m_vConfUpper are all missing value,
				//so we need call GetParamsLowerUpperConfBound to calculate lower and upper conf band by confidence limits here.
				vector vConfLower, vConfUpper;
				GetParamsLowerUpperConfBound(vConfLower, vConfUpper);
				///end RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS
				
				///Arvin 08/03/07 WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
				//for(int index=0; index < m_nNumParaInFunc; index++)
				for(int index=0; index < nParams; index++)
				///end 	WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
				{
					///Cheney 2007-4-5 GET_CONF_IN_PREVIEW_WHEN_CONF_METHOD_IS_BASE
					//pFitParameter[index].LCL = pFitParameter[index].Value - m_vConfLimits[index];
					//pFitParameter[index].UCL = pFitParameter[index].Value + m_vConfLimits[index];
					///Arvin 06/13/07 RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS 
					//Get right value according to m_vbShared
					//pFitParameter[index].LCL = m_vConfLower[index];
					//pFitParameter[index].UCL = m_vConfUpper[index];
					
					///Arvin 08/03/07 WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
					//int nConfIndex = GetParamsActualIndex(m_nNumParaInFunc, nDataset, index);
					int nConfIndex = index;
					if(!bReplicaFit)
						nConfIndex = GetParamsActualIndex(GetNumParameter(), nDataset, index);
					///end WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
					if(nConfIndex < vConfLower.GetSize() && nConfIndex < vConfUpper.GetSize())
					{
						pFitParameter[index].LCL = vConfLower[nConfIndex];
						pFitParameter[index].UCL = vConfUpper[nConfIndex];
					}
					///end RUNTIME_ERROR_AND_WRONG_PARAMS_CONF_WHILE_HAVE_SHARED_PARAMS
					///end GET_CONF_IN_PREVIEW_WHEN_CONF_METHOD_IS_BASE
				}
			}
		}
		///end CORRECT_THE_METHOD_OF_COMPUTION_PARAM_CONF_LIMIT
		*/
		//------ End LCL&UCL_CAN_BE_CORRECTLY_GET_BY_GetParameterResults
		
		/// Iris 02/06/2007 v8.0556 OUTPUT_T_P_VALUES_IN_PARAMS_TABLE
		// The following arithmetic supported by Echo
		///Arvin 08/03/07 WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
		//for(int index=0; index < m_nNumParaInFunc; index++)
		for(int index=0; index < nParams; index++)
		///end 	WRONG_PARAMETER_VALUES_WHILE_FIT_REPLICA
		{
	#ifdef	_DEBUG
			FitParameter	pTempFitParameter;
			pTempFitParameter = pFitParameter[index];
	#endif	//_DEBUG
			pFitParameter[index].tValue = (is_missing_value(pFitParameter[index].Value) || is_missing_value(pFitParameter[index].Error) || 0 == pFitParameter[index].Error) ? NANUM : pFitParameter[index].Value / pFitParameter[index].Error;
			double	dof;
			if(NULL != pstRegStats)
				dof = pstRegStats->DOF;
			pFitParameter[index].Prob = (is_missing_value(pFitParameter[index].tValue)) ? NANUM : 2 * (1 - invt(fabs(pFitParameter[index].tValue), dof));		
		}
		///end OUTPUT_T_P_VALUES_IN_PARAMS_TABLE
		return GetNumParameter();
	}
	
	return -1;
}

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//bool		NLFitSession::getDerivedParameters(int nDataset, vector<string>* pvsNames, vector<double>* pvdVals/* = NULL*/)
///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
//bool		NLFitSession::GetDerivedParameters(int nDataset, vector<string>* pvsNames, vector<double>* pvdVals/* = NULL*/)
bool		NLFitSession::GetDerivedParameters(int nDataset, vector<string>* pvsNames, vector<double>* pvdVals/* = NULL*/, vector<string>* pvsUnits/* = NULL*/)
///End ADD_UNIT_FOR_PARAMETER_SETTINGS
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
{
	if ( NULL == pvsNames )
		return false;
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	//int nRet = m_NLFit.GetDerivedParameters(nDataset, pvsNames, pvdVals);
	CheckUpdateNLFitParamsLinking(nDataset);
	///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	//int nRet = GetNLFitObj(nDataset).GetDerivedParameters(GetDatasetIndexInNLFit(nDataset), pvsNames, pvdVals);
	int nRet = GetNLFitObj(nDataset).GetDerivedParameters(GetDatasetIndexInNLFit(nDataset), pvsNames, pvdVals, pvsUnits);
	///End ADD_UNIT_FOR_PARAMETER_SETTINGS
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	if (nRet >= 0 )
		return true;
	
	pvsNames->SetSize(0);
	if ( NULL != pvdVals )
		pvdVals->SetSize(0);
	///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	if ( NULL != pvsUnits )
		pvsUnits->SetSize(0);
	///End ADD_UNIT_FOR_PARAMETER_SETTINGS
	
	return false;	
}
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

void		NLFitSession::setFitSettings()
{
	/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
	/*
	ONLSFSETTINGS 	stNLSF;
	m_NLFit.GetSettings(&stNLSF);
	
	stNLSF.rTolerance = m_dTolerance;
	stNLSF.rConfidence = m_dConfidence;
	stNLSF.bErrorsWithChisq = m_bScaleParamErrors;
	stNLSF.stNumericDerivsSettings = m_DerivsSettings;
	
	m_NLFit.SetSettings(&stNLSF);		
	*/		
	
	
	ONLSFSETTINGS 	stNLSF;
	GetNLFitObj(0).GetSettings(&stNLSF);
	
	stNLSF.rTolerance = m_dTolerance;
	stNLSF.rConfidence = m_dConfidence;
	stNLSF.bErrorsWithChisq = m_bScaleParamErrors;
	stNLSF.stNumericDerivsSettings = m_DerivsSettings;
	
	int		nDatasetIndex = isSeparateFit() ? m_nSepFitActiveDataset : 0;			
	GetNLFitObj(nDatasetIndex).SetSettings(&stNLSF);	
	/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
}

/// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
/*
bool 		NLFitSession::getFitZ(vector& vx, vector& vy, matrix& mat, int nIndependent)
{
	ASSERT(m_pnlfCurves);	
	return m_pnlfCurves->GetFitZ(vx, vy, mat, m_pParamMngr, nIndependent);
}
*/
///end REMOVE_NLFCURVE_FROM_NLSESSION

/// Iris 11/03/2009 QA81-14576-P1 ADD_SUMMARY_FIT_RESULT_FOR_SEP_FIT_WITH_MULTI_DATASET
/*
bool 		NLFitSession::isLastFitOutComeGoodFit()
{	
	if ( FITITER_REACHED_TOLERANCE == GetLastIterateOutCome() ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		return true;
	if ( FITITER_COULD_NOT_REDUCE_CHISQ_AT_LAST_ITER == GetLastIterateOutCome() ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		return true;
	return false;
}
*/
bool 		NLFitSession::IsLastFitOutComeGoodFit(int nLastFitOutCome)
{
	if ( FITITER_REACHED_TOLERANCE == nLastFitOutCome ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		return true;
	if ( FITITER_COULD_NOT_REDUCE_CHISQ_AT_LAST_ITER == nLastFitOutCome ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		return true;
	return false;	
}

/// Hong 01/12/10 QA80-13590-P7 ALWAYS_ACTIVE_MSG_TAB_IF_SIGNIFICANT_MSG
bool		NLFitSession::IsIterateFailed(int nFitOutCome)
{
	return (nFitOutCome <= FITITER_FAILED);
}
/// end ALWAYS_ACTIVE_MSG_TAB_IF_SIGNIFICANT_MSG

bool 		NLFitSession::isLastFitOutComeGoodFit()
{	
	int nLastFitOutCome = GetLastIterateOutCome();
	return IsLastFitOutComeGoodFit(nLastFitOutCome);
}
///end ADD_SUMMARY_FIT_RESULT_FOR_SEP_FIT_WITH_MULTI_DATASET

bool 		NLFitSession::isLastFitOutComeError()
{
	if ( FITITER_FAILED == GetLastIterateOutCome() ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		return true;
	if ( FITITER_FAILED_TO_REDUCE_CHISQR_DUE_TO_POOR_DATA == GetLastIterateOutCome() ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		return true;
	if ( FITTTER_FAILED_FROM_FUNC == GetLastIterateOutCome() ) /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		return true;
	//--------------- CPY QA70-7932 8/30/05 FIT_PERFECTLY_INIT_PARAM_NEED_PERTERBATION_TO_PROCEED
	// these are poor fits, but not errors
	//if(m_nLastIterateOutCome >= FITITER_FAILED_MUTUAL_DEPEND && m_nLastIterateOutCome <= FITITER_FAILED_OTHER_REASONS)
	//	return true;
	//---------------		
	return false;
}

void 		NLFitSession::resetIterations(DWORD dwCntrl, bool bResetIterateCount) // = true
{
	_DBSTR("Reset iteration outcome");
	bool		bIterCountChanged = false; /// Hong 07/03/09 QA80-13590-P5 NO_RESET_FIT_COUNT_MSG_IF_VALUE_NOT_REALLY_CHANGED
	if ( bResetIterateCount )
	{
		/// Hong 07/03/09 QA80-13590-P5 NO_RESET_FIT_COUNT_MSG_IF_VALUE_NOT_REALLY_CHANGED
		for ( int ii = 0; ii < m_vnIterCount.GetSize(); ii++ )
		{
			if ( 0 != m_vnIterCount[ii] )
			{
				bIterCountChanged = true;
				break;
			}
		}
		/// end NO_RESET_FIT_COUNT_MSG_IF_VALUE_NOT_REALLY_CHANGED
		/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		//m_nIterCount = 0;
		m_vnIterCount = 0;
		/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	} 	
	ResetFitOutCome();
	
	if(OSD_FROM_CLEANUP == dwCntrl)
		return;
	
	m_bIterateSettingsPolished = false; /// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	
	///Kyle 02/11/2009 QA80-12955-P3 HIDE_MESSAGE_WHICH_IS_USELESS
	/// Hong 07/03/09 QA80-13590-P5 NO_RESET_FIT_COUNT_MSG_IF_VALUE_NOT_REALLY_CHANGED
	//if(OSD_FROM_EDIT_PARAM_CHANGE == (dwCntrl & OSD_FROM_CHANGE_MASK) && !(dwCntrl & OSD_FUNC_CHANGE_THEN_SET_DATA) && !bResetIterateCount)
	if( !bIterCountChanged )
	/// end NO_RESET_FIT_COUNT_MSG_IF_VALUE_NOT_REALLY_CHANGED
		return;
	///End HIDE_MESSAGE_WHICH_IS_USELESS
	
	if ( isMsgLogAvailable() )
	{
		string strChangeFrom;
		switch ( dwCntrl & OSD_FROM_CHANGE_MASK )
		{
		case OSD_FROM_FUNC_CHANGE:
			ocu_load_msg_str(NLFIT_MSG_LOG_CHANGE_FUNC, &strChangeFrom);
			break;
		case OSD_FUNC_CHANGE_THEN_SET_DATA:
			ocu_load_msg_str(NLFIT_MSG_LOG_FUNC_CHANGE_THEN_SET_DATA, &strChangeFrom);
			break;
		case OSD_DATA_CHANGE_NOT_UPDATE_PREVIEW: 
		case OSD_FROM_DATA_CHANGE:
			ocu_load_msg_str(NLFIT_MSG_LOG_DATA_CHANGE, &strChangeFrom);
			break;
		case OSD_FROM_EDIT_PARAM_CHANGE:
			ocu_load_msg_str(NLFIT_MSG_LOG_EDIT_PARAM_CHANGE, &strChangeFrom);
			break;
		case OSD_FROM_PARAM_REPLICA_NUM_CHANGE:
			ocu_load_msg_str(NLFIT_MSG_LOG_PARAM_REPLICA_NUM_CHANGE, &strChangeFrom);
			break;
		case OSD_FROM_X_DATA_TYPE_CHANGE:
			ocu_load_msg_str(NLFIT_MSG_LOG_X_DATA_TYPE_CHANGE, &strChangeFrom);
			break;
		default:
			strChangeFrom = "";
			break;
		}

		if ( !(dwCntrl & OSD_FUNC_CHANGE_THEN_SET_DATA) )
		{		
			string strMsg;
			if ( bResetIterateCount )				
				ocu_load_msg_str(NLFIT_MSG_LOG_ITERA_RESET_AND_COUNT_RESET_TO_0, &strMsg);				
			else				
				ocu_load_msg_str(NLFIT_MSG_LOG_ITERA_RESET_BUT_COUNT_CONTINUE, &strMsg);
						
			strChangeFrom += strMsg;
		}
		writeMsgLog(strChangeFrom);
	}
}

bool		NLFitSession::outputOpMsgLog(int nIterNums, int nMethod, const RegStats& stRegStats, int nIterationOutCome) // Hong, to do, refactoring rename
{
	bool	bFitReport = false;
	if ( FITMETH_LEVENBERG_MARQUARDT == nMethod && nIterationOutCome != FITITER_GET_CHISQR )
		bFitReport = true;
		
	/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	//string	strFitResult = prepareFitOperationMessage(nIterNums, nMethod, stRegStats, nIterationOutCome);
	string	strFitOutCome;
	string	strFitResultWithFitOutCome = prepareFitOperationMessage(nIterNums, nMethod, stRegStats, nIterationOutCome, &strFitOutCome);
	string	strFitResult = strFitResultWithFitOutCome + strFitOutCome;
	/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	
	if ( isMsgLogAvailable() )			
	{
		/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
		//writeMsgLog(strFitResult);	
		writeMsgLog(strFitResultWithFitOutCome, true, false);
		writeMsgLog(strFitOutCome, false, true, IsIterateFailed(nIterationOutCome));
		/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	}

	if ( bFitReport )
	{
		/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		//m_strFitMessage = strFitResult;	
		ASSERT( m_nSepFitActiveDataset < m_vsFitMessage.GetSize() );
		m_vsFitMessage[m_nSepFitActiveDataset] = strFitResult;
		/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		vector<string> vsMessages;
		string strSep = "\r\n";
		int nLines = str_separate(m_vsFitMessage[m_nSepFitActiveDataset], strSep, vsMessages); /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		if(nLines > 0)
		{
			vsMessages.RemoveAt(0); //remove title line
			m_vsFitMessage[m_nSepFitActiveDataset] = str_combine(vsMessages, strSep); /// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		}
	}
		
	return true;
}

/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
//string		NLFitSession::prepareFitOperationMessage(int nIterNums, int nMethod, const RegStats& stRegStats, int nIterationOutCome)
string		NLFitSession::prepareFitOperationMessage(int nIterNums, int nMethod, const RegStats& stRegStats, int nIterationOutCome, string* pstrFitOutCome/* = NULL*/)
/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
{
	string	strResult;
	if ( FITMETH_LEVENBERG_MARQUARDT == nMethod && FITITER_FAILED == nIterationOutCome )
	{
		strResult = _L("Iteration failed");
		return strResult;
	}
	
	strResult = constructResultTitle(nIterationOutCome, nMethod);	

	string strTemp;
	if ( FITMETH_LEVENBERG_MARQUARDT == nMethod )
	{
		///Kyle 01/20/2009 QA80-12955-P2 MAKE_OUTPUT_MESSAGE_FOR_CONSTRAINT_ERROR_SIMPLIFIED
		if(nIterationOutCome == FITITER_FAILED_GENERAL_LINEAR_CONSTRAINTS)
		{
			/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
			//strResult = constructIterationOutCome(nIterationOutCome);
			strTemp = constructIterationOutCome(nIterationOutCome);
			if ( pstrFitOutCome )
			{
				*pstrFitOutCome = strTemp;
				strResult = "";
			}
			else
				strResult = strTemp;
			/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
		}
		else
		///End MAKE_OUTPUT_MESSAGE_FOR_CONSTRAINT_ERROR_SIMPLIFIED
		{
			///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
			//strTemp = _L("Reduced Chi-sqr") + " " + _L("=") + " " + ftoa(stRegStats.ReducedChiSq, "*12*") + "\r\n";	
			///------ Folger 02/11/09 QA80-13098-S2 SHOW_CHISQR_INFO_IN_NLFIT_STATIC_MESSAGE
			//strTemp = _L("Reduced Chi-sqr") + " = " + ftoa(stRegStats.ReducedChiSq, "*12*") + "\r\n";	
			strTemp = GetReducedChiSqrInfo(stRegStats, 12) + "\r\n";
			///------ End SHOW_CHISQR_INFO_IN_NLFIT_STATIC_MESSAGE
			///End SET_NO_NEED_TO_LOCALIZE
			strResult += strTemp;
			
			if(nIterNums > 0)
			{
				///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
				//strResult += _L("COD(R^2)") + " " + _L("=") + " " + ftoa(stRegStats.RSqCOD) + "\r\n";
				strResult += "COD(R^2) = " + ftoa(stRegStats.RSqCOD) + "\r\n";
				///End SET_NO_NEED_TO_LOCALIZE
			}
			
			if(nIterationOutCome != FITITER_GET_CHISQR)
			{
				/// Hong 03/02/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
				//strResult += constructIterationCountsString( nIterNums);
				strResult += constructIterationCountsString(nIterNums, nIterationOutCome);
				/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
				/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
				//strResult += constructIterationOutCome(nIterationOutCome);
				strTemp = constructIterationOutCome(nIterationOutCome);
				if ( pstrFitOutCome )
					*pstrFitOutCome = strTemp;
				else
					strResult = strTemp;
				/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
			}
		}
	}
	else
	{
		strTemp = _L("Evaluated") + " " + ftoa(nIterNums)+ " " + _L("simplex vertices.") +"\r\n";		
		if ( nIterNums > 0 )
			strTemp += _L("Chi-sqr is reduced");
		else
			strTemp += _L("Chi-sqr is not reduced");
		strTemp += "\r\n";				
		///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
		//strTemp += _L("Reduced Chi-sqr") + " " + _L("=") + " " + ftoa(stRegStats.ReducedChiSq, "*12*") + "\r\n";
		strTemp += _L("Reduced Chi-sqr") + " = " + ftoa(stRegStats.ReducedChiSq, "*12*") + "\r\n";
		///End SET_NO_NEED_TO_LOCALIZE
		
		strResult += strTemp;
	}
	
	return strResult;
}

string		NLFitSession::constructResultTitle(int nIterationOutCome, int nMethod)
{
	int nTotalWidth = 40;
	
	string strTitle;
	if ( FITMETH_LEVENBERG_MARQUARDT == nMethod )
		strTitle = _L("Levenberg-Marquardt");
	else
		strTitle = _L("Simplex Fit");
		
	if ( nIterationOutCome == FITITER_GET_CHISQR )	
		strTitle = _L("Chi-Square");
	
	string str = str_pad_char(strTitle, nTotalWidth, DISPLAY_CENTER, '-');
	return str + "\r\n";
}

string		NLFitSession::constructIterationOutCome(int nIterationOutCome)
{
	string str = GetFitOutCome(nIterationOutCome);
	return str + "\r\n";
}

/// Hong 03/02/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
//string		NLFitSession::constructIterationCountsString(int nIterNums)
string		NLFitSession::constructIterationCountsString(int nIterNums, int nIterationOutcome)
/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
{
	///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
	//string str = _L("Iterations Performed") + " " + _L("=") + " " + nIterNums + " \r\n";
	string str = STR_ITERATION_PERFORMED + " = " + nIterNums + " \r\n";
	///End SET_NO_NEED_TO_LOCALIZE
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//m_nIterCount += nIterNums;
	//str += _L("Total Iterations in Session") + " " + _L("=") + " " + m_nIterCount + "\r\n";	
	ASSERT( m_nSepFitActiveDataset < m_vnIterCount.GetSize() );
	/// Hong 03/02/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	// Hong, see Hong 01/12/10 QA80-14948-P2 FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT in function Iterate
	/// Hong 03/13/10 QA80-14948-P2 FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	//if ( FITITER_FIT_NOT_COMPLETE != nIterationOutcome && FITITER_GET_CHISQR != nIterationOutcome )	
	if ( !m_bDuringGetResultWithIterate )
	/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
	/// end FIX_TOTAL_ITERATE_COUNT_INCORRECT_WHEN_REPORT_WITH_DONE_BTN_IF_EVER_ITERATE
		m_vnIterCount[m_nSepFitActiveDataset] += nIterNums;
	///Kyle 09/24/08 SET_NO_NEED_TO_LOCALIZE
	//str += _L("Total Iterations in Session") + " " + _L("=") + " " + m_vnIterCount[m_nSepFitActiveDataset] + "\r\n";
	str += _L("Total Iterations in Session") + " = " + m_vnIterCount[m_nSepFitActiveDataset] + "\r\n";
	///End SET_NO_NEED_TO_LOCALIZE
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	return	str;
}

int			NLFitSession::getParamsType()
{
	if ( NLF_PARAM_TYPE_CTRL_MULTI_SETS & m_dwParamTypeCtrl )
	{		
		ASSERT( !(NLF_PARAM_TYPE_CTRL_MULTI_FUNCTIONS & m_dwParamTypeCtrl || NLF_PARAM_TYPE_CTRL_REPLICA & m_dwParamTypeCtrl) );
		return NLPMGRTYPE_MULTIPLE_SETS;
	}
	
	if ( NLF_PARAM_TYPE_CTRL_MULTI_FUNCTIONS & m_dwParamTypeCtrl )
	{
		ASSERT( !(NLF_PARAM_TYPE_CTRL_REPLICA & m_dwParamTypeCtrl) );
		return NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS;
	}
	
	///------ Folger 05/12/09 NANOSIZER_FITTING_BASED_SUPPORT
	//if ( NLF_PARAM_TYPE_CTRL_REPLICA & m_dwParamTypeCtrl )
	if ( (NLF_PARAM_TYPE_CTRL_REPLICA & m_dwParamTypeCtrl) || Is2DSupportReplica() )
	///------ End NANOSIZER_FITTING_BASED_SUPPORT
		return NLPMGRTYPE_SINGLE_SET_SINGLE_FUNCTION_MULTIPEAKS;
	
	return NLPMGRTYPE_SINGLE_SET_NO_REPLICAS;
}


bool		NLFitSession::isMultiplicityFit()
{
	if ( NLPMGRTYPE_SINGLE_SET_SINGLE_FUNCTION_MULTIPEAKS == m_pParamMngr->GetType() || NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS == m_pParamMngr->GetType() )
		return true;
	
	return false;
}

/// Jack 31/10/08 QA80-12423 SET_PA_CONSTRAINTS_WHEN_IT_IS_MULTIPLE_FUNCS_FIT
bool		NLFitSession::isMultipleFuncsMultiPeaksFit()
{
	if ( NLPMGRTYPE_SINGLE_SET_MULTIPLE_FUNCTIONS_MULTIPEAKS == m_pParamMngr->GetType() )
		return true; // if it is PA case
	return false;
}
///End SET_PA_CONSTRAINTS_WHEN_IT_IS_MULTIPLE_FUNCS_FIT


//------ Folger 11/13/08 v8.0970 CHANGE_FUNCTION_SHOULD_RESET_SHARING
///// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
////bool		NLFitSession::setParamByFDFSettings(int nFunc)
//bool		NLFitSession::SetParamByFDFSettings(int nFunc, bool bKeepOldDataset/* = false*/, DWORD dwParamsToSkip/* = 0*/)
///// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
bool		NLFitSession::SetParamByFDFSettings(int nFunc, bool bKeepOldDataset/* = false*/, DWORD dwParamsToSkip/* = 0*/, bool bResetShare/* = false*/)
//------ End CHANGE_FUNCTION_SHOULD_RESET_SHARING
{
	/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
	if ( bKeepOldDataset && m_nOldNumberDataset >= GetNumDataset() )		
		return true;
	/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
	
	vector<int>		vnSignDigites;
	vector			vParamValues, vParaLowerBounds, vParaUpperBounds;
	vector<string> 	vsParamNames, vsMeanings;
	vector<bool> 	vbFixed, vbpbExclusiveLower, vbpbExclusiveUpper, vbOnLowerBounds, vbOnUpperBounds;	
		
	TreeNode trFF = GetTreeFDF(nFunc);
	if( trFF.IsEmpty() )
	{
		string strCategoryName;
		string strFunctionName = GetFunctionName(&strCategoryName, nFunc);
		getFunctionTree(trFF, strFunctionName, strCategoryName); 
	}
	/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER	
	//int				nNumParaInFDF = -1;		//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	int				nNumParaInFDF = 0;
	/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	
	// Value&Name	
	//----- Iris 11/27/2008 v8.0980 PA_IMPROVE_PARAM_INIT_IF_LOAD_PARAM_SETTINGS_FROM_FDF
	//int				nNumParaInFunc = getParamsInitInfo(nFunc, vParamValues, &vsParamNames, trFF, &nNumParaInFDF);
	int				nNumParaInFunc = GetParamsInitInfo(nFunc, vParamValues, &vsParamNames, trFF, &nNumParaInFDF);
	//-----
	
	///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	//Unit
	vector<string> vsUnits;
	string 			strUnitList = m_NFO.GetFittingPara(trFF, true, STR_FDF_SETTING_UNIT).strVal;
	nlf_set_param_unit_vector(strUnitList, vsUnits, nNumParaInFDF);
	trimOffsetParameter(vsUnits, nFunc);
	///End ADD_UNIT_FOR_PARAMETER_SETTINGS

	//Meaning
	string 			strMeaningList = m_NFO.GetFittingPara(trFF, true, STR_FDF_SETTING_MEANINGS).strVal;
	nlf_set_param_meaning_vector(strMeaningList, vsMeanings, nNumParaInFDF);
	trimOffsetParameter(vsMeanings, nFunc);		//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	
	//nSignDigites
	string 			strSignDigites = m_NFO.GetFittingPara(trFF, true, STR_FDF_SETTING_SIGNIFICANT_DIGITS).strVal;
	nlf_set_param_significant_digits_vector(strSignDigites, vnSignDigites, nNumParaInFDF);
	trimOffsetParameter(vnSignDigites, nFunc);	//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	
	//Fixed
	string 			strParaValueList = m_NFO.GetFittingPara(trFF, true, STR_FDF_SETTING_INIT_VAL).strVal;
	nlf_set_param_fixed_vector(strParaValueList, vbFixed, nNumParaInFDF);
	trimOffsetParameter(vbFixed, nFunc);		//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	
	/* Hong, to do
	int 			nFixed = 0;
	if ( 0 == nFunc && HasBaselinePeak(NULL, &nFixed) )
	{
		if(nFixed)
			vbFixed = nFixed;
	}
	*/
	
	string strParaBoundList = m_NFO.GetFittingPara(trFF, true, STR_FDF_SETTING_LOWER_BOUNDS).strVal;	
	///OnLowerBounds
	nlf_set_param_on_bounds_vector(strParaBoundList, vbOnLowerBounds, nNumParaInFDF);		
	//ExclusiveLower
	nlf_set_param_exclusive_vector(strParaBoundList, vbpbExclusiveLower, nNumParaInFDF);	
	//LowerBounds
	nlf_set_param_bounds_vector(strParaBoundList, vParaLowerBounds, nNumParaInFDF);
	
	//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	trimOffsetParameter(vbOnLowerBounds, nFunc);
	trimOffsetParameter(vbpbExclusiveLower, nFunc);
	trimOffsetParameter(vParaLowerBounds, nFunc);
	//------ End SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	
	strParaBoundList = m_NFO.GetFittingPara(trFF, true, STR_FDF_SETTING_UPPER_BOUNDS).strVal;
	///OnUpperBounds
	nlf_set_param_on_bounds_vector(strParaBoundList, vbOnUpperBounds, nNumParaInFDF);	
	//ExclusiveUpper
	nlf_set_param_exclusive_vector(strParaBoundList, vbpbExclusiveUpper, nNumParaInFDF);	
	//UpperBounds
	nlf_set_param_bounds_vector(strParaBoundList, vParaUpperBounds, nNumParaInFDF);
		
	//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	trimOffsetParameter(vbOnUpperBounds, nFunc);
	trimOffsetParameter(vbpbExclusiveUpper, nFunc);
	trimOffsetParameter(vParaUpperBounds, nFunc);
	//------ End SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
		
	ASSERT( nNumParaInFunc == vParamValues.GetSize() );
	ASSERT( nNumParaInFunc == vParaLowerBounds.GetSize() );
	ASSERT( nNumParaInFunc == vParaUpperBounds.GetSize() );
	ASSERT( nNumParaInFunc == vsMeanings.GetSize() );
	ASSERT( nNumParaInFunc == vbFixed.GetSize() );
	ASSERT( nNumParaInFunc == vbpbExclusiveLower.GetSize() );
	ASSERT( nNumParaInFunc == vbpbExclusiveUpper.GetSize() );
	ASSERT( nNumParaInFunc == vbOnLowerBounds.GetSize() );
	ASSERT( nNumParaInFunc == vbOnUpperBounds.GetSize() );	
	
	/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
	int			nFirstDatasetToUpdate = bKeepOldDataset ? m_nOldNumberDataset : 0;
	double*		pdValue = NULL;
	/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS	
	/// Hong 01/23/09 MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
	bool*		pbFixed = NULL;
	int*		pnSignDigits = NULL;
	LPCSTR 		lpcszMeaning = NULL;	
	LPCSTR 		lpcszUnit = NULL;			///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
	/// end MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
	for (int ii = 0; ii < nNumParaInFunc; ii++ )
	{
		/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
		//if ( m_pParamMngr->SetOneFuncParam(nFunc, 0, ii, &vParamValues[ii], &vbFixed[ii], NULL, vsParamNames[ii], vsMeanings[ii],
		//								&vnSignDigites[ii], &vbpbExclusiveUpper[ii], &vParaUpperBounds[ii], &vbpbExclusiveLower[ii], &vParaLowerBounds[ii]) )
		if ( !(NLPARAMETERSETTINGS_VALUE & dwParamsToSkip) )
			pdValue = &vParamValues[ii];
		/// Hong 01/23/09 MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
		if ( !(NLPARAMETERSETTINGS_FIXED & dwParamsToSkip) )
			pbFixed = &vbFixed[ii];
		if ( !(NLPARAMETERSETTINGS_SD & dwParamsToSkip) )
			pnSignDigits = &vnSignDigites[ii];
		///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
		if ( !(NLPARAMETERSETTINGS_UNIT & dwParamsToSkip) )
			lpcszUnit = vsUnits[ii];
		///End ADD_UNIT_FOR_PARAMETER_SETTINGS
		if ( !(NLPARAMETERSETTINGS_MEANING & dwParamsToSkip) )
			lpcszMeaning = vsMeanings[ii];
		/// end MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
		
		//------ Folger 11/13/08 v8.0970 CHANGE_FUNCTION_SHOULD_RESET_SHARING
		int		nShared = 0;
		/// Hong 01/23/09 MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU		
		////if ( m_pParamMngr->SetOneFuncParam(nFunc, nFirstDatasetToUpdate, ii, pdValue, &vbFixed[ii], NULL, /*vsParamNames[ii], */vsMeanings[ii],
		//if ( m_pParamMngr->SetOneFuncParam(nFunc, nFirstDatasetToUpdate, ii, pdValue, &vbFixed[ii], bResetShare ? &nShared : NULL, /*vsParamNames[ii], */vsMeanings[ii],
		////------
		//								//------ Folger 10/28/08 QA80-12465 v8.0962 SET_PARAMETER_SHOULD_CONSIDER_BOUNDS_ENABLE
		//								&vnSignDigites[ii], &vbOnLowerBounds[ii], &vbpbExclusiveLower[ii], &vParaLowerBounds[ii], &vbOnUpperBounds[ii], &vbpbExclusiveUpper[ii], &vParaUpperBounds[ii]) )
		//								//------
		///Kyle 08/06/2009 QA80-14077 ADD_UNIT_FOR_PARAMETER_SETTINGS
		//if ( m_pParamMngr->SetOneFuncParam(nFunc, nFirstDatasetToUpdate, ii, pdValue, pbFixed, bResetShare ? &nShared : NULL, lpcszMeaning,
		//								pnSignDigits, &vbOnLowerBounds[ii], &vbpbExclusiveLower[ii], &vParaLowerBounds[ii], &vbOnUpperBounds[ii], &vbpbExclusiveUpper[ii], &vParaUpperBounds[ii]) )
		if ( m_pParamMngr->SetOneFuncParam(nFunc, nFirstDatasetToUpdate, ii, pdValue, pbFixed, bResetShare ? &nShared : NULL, lpcszUnit, lpcszMeaning,
										pnSignDigits, &vbOnLowerBounds[ii], &vbpbExclusiveLower[ii], &vParaLowerBounds[ii], &vbOnUpperBounds[ii], &vbpbExclusiveUpper[ii], &vParaUpperBounds[ii]) )
		///End ADD_UNIT_FOR_PARAMETER_SETTINGS
		/// end MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
		/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS		
			return error_report("Fail to set parameter");
	}
		
	if ( GetNumberMultiplicity(nFunc) > 1 )
	{		
		/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
		//if ( !m_pParamMngr->DuplicateReplicaParameterSettings() )
		ASSERT(!bKeepOldDataset); // should NOT come here if do keep old dataset				
		if ( !m_pParamMngr->DuplicateReplicaParameterSettings(dwParamsToSkip | NLPARAMETERSETTINGS_VALUE) ) // Hong, for replica, always do NOT duplicate values
		/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
		{
			ASSERT(FALSE); // should not fail
		}
	}
	
	/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
	//for ( int nDatasetIndex = 1; nDatasetIndex < GetNumDataset(); nDatasetIndex++ )
	for ( int nDatasetIndex = nFirstDatasetToUpdate + 1; nDatasetIndex < GetNumDataset(); nDatasetIndex++ )
	/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
	{
		/// Hong 09/16/08 v8.0940 NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
		//if ( !m_pParamMngr->DuplicateDatasetParameterSettings(nDatasetIndex, 0) )
		if ( !m_pParamMngr->DuplicateDatasetParameterSettings(nDatasetIndex, nFirstDatasetToUpdate, dwParamsToSkip) )
		/// end NEW_ADDED_DATASET_SHOULD_INIT_WITH_FDF_SETTTINGS
		{
			ASSERT(FALSE); // should not fail
		}
	}		
	
	return true;
}

/// Hong 01/23/09 MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU
bool		NLFitSession::ResetParamBounds(BOOL bInlcudeBaselineFunc)
{
	///------ Folger 09/18/09 QA80-14333 RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF
	//if ( !IsFunctionReady() )
	//return false;
	/////Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	////DWORD			dwParamsToSkip = NLPARAMETERSETTINGS_VALUE | NLPARAMETERSETTINGS_SHARED | NLPARAMETERSETTINGS_NAME | NLPARAMETERSETTINGS_MEANING | NLPARAMETERSETTINGS_FIXED | NLPARAMETERSETTINGS_SD;
	//DWORD			dwParamsToSkip = NLPARAMETERSETTINGS_VALUE | NLPARAMETERSETTINGS_SHARED | NLPARAMETERSETTINGS_NAME | NLPARAMETERSETTINGS_UNIT | NLPARAMETERSETTINGS_MEANING | NLPARAMETERSETTINGS_FIXED | NLPARAMETERSETTINGS_SD;
	/////End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
	//for ( int ii = 0; ii < GetNumberFitFunctions(); ii++ )
	//{
	//if ( 0 == ii && !bInlcudeBaselineFunc && GetBaselineFitMode() )
	//continue;		
	//SetParamByFDFSettings(ii, false, dwParamsToSkip);
	//}
	//return true;
	DWORD		dwParamsToSkip = NLPARAMETERSETTINGS_VALUE
								| NLPARAMETERSETTINGS_SHARED
								| NLPARAMETERSETTINGS_NAME
								| NLPARAMETERSETTINGS_UNIT
								| NLPARAMETERSETTINGS_MEANING
								| NLPARAMETERSETTINGS_FIXED
								| NLPARAMETERSETTINGS_SD
								;
	return resetParamsFromFDF(dwParamsToSkip, bInlcudeBaselineFunc);
	///------ End RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF
}
/// end MORE_PRECISE_BOUND_CLEAR_AND_RESET_CONTEXT_MENU

///------ Folger 09/18/09 QA80-14333 RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF
BOOL		NLFitSession::resetParamsFromFDF(DWORD dwParamsToSkip, BOOL bInlcudeBaselineFunc)
{
	if ( !IsFunctionReady() )
		return false;
	
	for ( int ii = 0; ii < GetNumberFitFunctions(); ii++ )
	{
		if ( 0 == ii && !bInlcudeBaselineFunc && GetBaselineFitMode() )
			continue;
		
		SetParamByFDFSettings(ii, false, dwParamsToSkip);
	}
	return true;
}
///------ End RESET_THEME_SHOULD_LOAD_PARAMETER_DEFAULT_SETTINGS_FROM_FDF

bool		NLFitSession::getParamInitValues(const NumericFunction& fn, int nDataset, vector& vParamValue)
{	
	/// Hong 06/17/08 v8.0886 REFACTORING_ORTHOGONALITY
	/*
	vector 	vecX, vecY, vecZ;	
	bool	bAutoInitSucceed = false;	
	// Get X/Y index better put into a function
	int 	nXIndex = NLFIT_GENERAL_XY_FITTING != GetFitType()? nDataset * 2 : nDataset;
	int 	nYIndex = NLFIT_GENERAL_XY_FITTING != GetFitType()? nXIndex + 1 : nDataset;

	if ( MAX_DATASET_NUMBER <= nXIndex || MAX_DATASET_NUMBER <= nYIndex )
	{
		ASSERT(FALSE);
		return bAutoInitSucceed;
	}
	
	// Hong
	//vecX = m_vIndependentData[nXIndex];
	m_pDataObj->GetIndependData(vecX, nXIndex);
	
	int nErr;
	if ( NLFIT_GENERAL_XY_FITTING != GetFitType() )
	{	
		// Hong
		//vecY = m_vIndependentData[nYIndex];
		//vecZ = m_vDependentData[nDataset];
		m_pDataObj->GetIndependData(vecY, nYIndex);
		m_pDataObj->GetDependData(vecZ, nDataset);	
		
		reduceVectorDatas(vecX, vecY, vecZ, nDataset);
		bAutoInitSucceed = fn.ParamInit(vParamValue, vecX, vecY, vecZ, nErr);
	}
	
	else
	{
		// Hong
		//vecY = m_vDependentData[nYIndex];
		m_pDataObj->GetDependData(vecY, nYIndex);
		bAutoInitSucceed = fn.ParamInit(vParamValue, vecX, vecY, nErr);
	}
	if ( bAutoInitSucceed && 0 != nErr )
		bAutoInitSucceed = false;	
	return bAutoInitSucceed;
	*/	
	int			nErr = 0;
	bool		bAutoInitSucceed;
	/// Hong 07/23/08 QA80-11816 AUTO_PARAMS_INIT_SUPPORT_MULTI_DEPS_MULTI_INDEPS
	/*
	vector		vX, vY, vZ;
	if ( !GetInputData(vX, vY, vZ, nDataset) )
		return false;
	
	if ( vZ.GetSize() > 0 )
	{		
	*/
	if ( NLFIT_XYZ_FITTING == GetFitType() || NLFIT_MATRIX_FITTING == GetFitType() )
	{
		vector		vX, vY, vZ;
		if ( !GetInputData(vX, vY, vZ, nDataset) )
			return false;
	/// end AUTO_PARAMS_INIT_SUPPORT_MULTI_DEPS_MULTI_INDEPS
		/// Hong 08/14/08 v8.0922 FIX_MATRIX_FIT_FAIL_DO_REDUCE
		if ( NLFIT_MATRIX_FITTING == GetFitType() )
		{
			int		nCols, nRows;			
			if ( GetDataObject()->GetDimention(nDataset, nRows, nCols) && (nCols > LARGE_DATA_SET_NUM_COLS) && (nRows > LARGE_DATA_SET_NUM_ROWS) ) // for a large matrix data do a matrix reduction before put to initilization
			{
		/// end FIX_MATRIX_FIT_FAIL_DO_REDUCE
				int 	nRowShrFactor = LARGE_DATA_SET_ROW_SHRINK_FACTOR; // hard code the shrinkd factor or reduced factor for the matrix, with a ratio proper for a standard image
				int 	nColShrFactor = LARGE_DATA_SET_COL_SHRINK_FACTOR;
				int 	nRowsShr = (int)(nRows * 1.0 / nRowShrFactor) + 1; // !Note: hard code 1 is used to make sure the buffer size for reduced matrix is always larger than that calculated in (and return from) ocmath_reduce_2D_data
				int 	nColsShr = (int)(nCols * 1.0 / nColShrFactor) + 1; // Avoid run time error due to buffer size unmatch
				int		nReducedSize = nRowsShr * nColsShr;
				vector 	vecXReduced(nReducedSize), vecYReduced(nReducedSize), vecZReduced(nReducedSize);
				
				int 	nRet = ocmath_reduce_2D_data(nRows*nCols, vX, vY, vZ, nRows, nCols, vecXReduced, vecYReduced, vecZReduced, nColShrFactor, nRowShrFactor);
				if ( nRet > 0 )			
				{		
					vecXReduced.SetSize(nRet);
					vecYReduced.SetSize(nRet);
					vecZReduced.SetSize(nRet);
					
					vX = vecXReduced;
					vY = vecYReduced;
					vZ = vecZReduced;
				}
			}	
		}
		bAutoInitSucceed = fn.ParamInit(vParamValue, vX, vY, vZ, nErr);
	}
	else
	{
		/// Hong 07/23/08 QA80-11816 AUTO_PARAMS_INIT_SUPPORT_MULTI_DEPS_MULTI_INDEPS
		//bAutoInitSucceed = fn.ParamInit(vParamValue, vX, vY, nErr);
		vector		*pvDeps, *pvIndeps;
		pvDeps = m_pDataObj->GetDependData(nDataset);
		pvIndeps = m_pDataObj->GetIndependData(nDataset);
		if ( NULL == pvDeps || NULL == pvIndeps )
			return false;
		
		bAutoInitSucceed = fn.ParamInit(vParamValue, pvIndeps, pvDeps, nErr);
		/// end AUTO_PARAMS_INIT_SUPPORT_MULTI_DEPS_MULTI_INDEPS
	}
	
	if ( bAutoInitSucceed && 0 != nErr )
		bAutoInitSucceed = false;
	
	return bAutoInitSucceed;
	/// end REFACTORING_ORTHOGONALITY		
}

bool		NLFitSession::replicaAutoInitParams(int nFunc, int nDataset, const vector& vDefaultParams) // = 0, 0, NULL
{
	ASSERT(0 == nFunc); // only single function support replica right now
	int 		nNumMultiplicity = GetNumberMultiplicity(nFunc);
	ASSERT(nNumMultiplicity > 1);

	FindPeakCtrlInfo findPeakCtrlInfo;
	if ( !getReplicaInitParamSettings(findPeakCtrlInfo) )
		return error_report("Can not get settings of prameter initialization");		

	bool		bRet = false;
	switch ( GetFitType() )
	{
	case NLFIT_GENERAL_XY_FITTING:
		bRet = replicaInitOneDimensionParams(findPeakCtrlInfo, nDataset, nNumMultiplicity, vDefaultParams);
		break;
	case NLFIT_XYZ_FITTING:
	case NLFIT_MATRIX_FITTING:
		bRet = replicaInitTwoDimensionParams(findPeakCtrlInfo, nDataset, nNumMultiplicity, vDefaultParams);
		break;
	default:
		ASSERT(FALSE);
		break;
	}
	
	return bRet;
}

typedef	int	(*FUNC_INTT_1D_PEAK_PARAMETERS_FOR_REPLICA_FITTING)(const vector& vX, const vector& vY, int nNeededPeakNum, vector& vXCenter, vector& vYCenter, vector& vXWidth, const FindPeakCtrlInfo* pFindPeakCtrlInfo);
bool		NLFitSession::replicaInitOneDimensionParams(const FindPeakCtrlInfo& findPeakCtrlInfo, int nDataset, int nNumMultiplicity, const vector& vDefaultParams)
{
	vector		vX, vY, vPeaksY, vXCenter, vYCenter, vXWidth;
	if ( !GetInputData(vX, vY, NULL, nDataset) )
		return error_report("Fail to get input data");
	FUNC_INTT_1D_PEAK_PARAMETERS_FOR_REPLICA_FITTING	pfn = Project.FindFunction("init_1d_peak_parameters_for_replica_fitting", "OriginLab\\curve_utils.c", true);
	if ( pfn )
		m_nNumFoundPeaks = pfn(vX, vY, nNumMultiplicity, vXCenter, vYCenter, vXWidth, &findPeakCtrlInfo);
	
	if ( m_nNumFoundPeaks < 1 )
	{
		error_report("No peak found!");
		return true;
	}
	/// Hong 09/10/09 v8.0936b FIX_REPLICA_FAIL_CORRECT_ININT
	if ( vXCenter.GetSize() > nNumMultiplicity )
	{
		ASSERT(vXCenter.GetSize() == vXWidth.GetSize() && vXCenter.GetSize() == vYCenter.GetSize() && vXCenter.GetSize() == vXWidth.GetSize());

		//------ Folger 12/04/08 QA80-12509 QA80-12509-P2 FIND_PEAKS_RESULT_IN_NLFIT_FAILS_TO_BE_SORTED_BY_CENTER_ASCENDINGLY
		///// Iris 11/24/2008 v8.0987 FIX_FAIL_TO_FIND_NEGATIVE_PEAKS_IN_NLFIT
		//// sort and remain bigger height peaks according to nNumMultiplicity
		//vector vYCenterAbs;
		//vYCenterAbs = abs(vYCenter);
		//vector<uint> vnIndices;
		//vYCenterAbs.Sort(SORT_DESCENDING, true, vnIndices);
		//vXCenter.Reorder(vnIndices);
		//vYCenter.Reorder(vnIndices);
		//vXWidth.Reorder(vnIndices);
		///// end FIX_FAIL_TO_FIND_NEGATIVE_PEAKS_IN_NLFIT
		//------ End FIND_PEAKS_RESULT_IN_NLFIT_FAILS_TO_BE_SORTED_BY_CENTER_ASCENDINGLY
		
		vXCenter.SetSize(nNumMultiplicity);
		vYCenter.SetSize(nNumMultiplicity);
		vXWidth.SetSize(nNumMultiplicity);
	}
	/// end FIX_REPLICA_FAIL_CORRECT_ININT	
	
	//------ Folger 12/04/08 QA80-12509 QA80-12509-P2 FIND_PEAKS_RESULT_IN_NLFIT_FAILS_TO_BE_SORTED_BY_CENTER_ASCENDINGLY
	vector<uint> vnIndices;
	vXCenter.Sort(SORT_ASCENDING, false, vnIndices);
	vYCenter.Reorder(vnIndices);
	vXWidth.Reorder(vnIndices);
	//------ End FIND_PEAKS_RESULT_IN_NLFIT_FAILS_TO_BE_SORTED_BY_CENTER_ASCENDINGLY
	
	double		dBaseline = 0.0;
	int			nBaselineParamIndex = 0; // Hong, to do, after SR2, need centralize this baseline index assumation into nlsf_utils, like get_baseline_param_index
	if ( vDefaultParams && vDefaultParams.GetSize() > nBaselineParamIndex )
		dBaseline= vDefaultParams[nBaselineParamIndex];
	
	//---Hong, to do, the following knowledge should be kept in Parameter Manager and should calculate with formula get from FDF file, but for now, hard as gauss
	static const double l_dSqrt = NLFIT_AREA_PARAMETER_CALCULATION_FACTOR;
	vector		vHeight;
	vHeight = vYCenter * vXWidth * l_dSqrt;
	//---	
	if ( m_pParamMngr->SetReplicasInitialParameters(vXCenter, vXWidth, vHeight, dBaseline, vDefaultParams) )
		return error_report("Fail to init replica paramters.");

	/* _NLF_81, Hong, to do
	//------ Folger 05/28/08 QA80-11614 SHOULD_RESTORE_SHARE_WHEN_SET_PARAMS_FROM_OPERATION_TREE_FOR_REPLICA
	int nNumParaInFunc = GetFitFunction(nFunc)->GetNumParaInFunc();
	if ( GeNumtNonSharedParams(nNumParaInFunc) != nNumParaInFunc &&		// is there something shared ?
		m_vParamValues.GetSize() == m_vsParamNames.GetSize() )			// if shared, has m_vParamValues been trimed ?
	{
		restoreSharedParametersForReplicaFit();
	}
	//------
	*/
	///Sophy 11/4/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
	m_vYCenter = vYCenter;
	m_vXCenter = vXCenter;
	///end ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
	
	return true;
}

typedef	int	(*FUNC_INIT_2D_PEAK_PARAMETERS_FOR_REPLICA_FITTING)(const vector& vxGrid, const vector& vyGrid, const vector& vzGrid, int nReplica, vector& vXCenter, vector& vYCenter, vector& vZCenter, vector& vXWidth, vector& vYWidth, const FindPeakCtrlInfo* pFindPeakCtrlInfo);
bool		NLFitSession::replicaInitTwoDimensionParams(const FindPeakCtrlInfo& findPeakCtrlInfo, int nDataset, int nNumMultiplicity, const vector& vDefaultParams)
{
	vector 		vxGrid, vyGrid, vzGrid;
	vector 		vXCenter, vYCenter, vZCenter, vXWidth, vYWidth;
	FUNC_INIT_2D_PEAK_PARAMETERS_FOR_REPLICA_FITTING	pfn = Project.FindFunction("init_2d_peak_parameters_for_replica_fitting", "OriginLab\\curve_utils.c", true);
	if ( pfn )
		m_nNumFoundPeaks = pfn(vxGrid, vyGrid, vzGrid, nNumMultiplicity, vXCenter, vYCenter, vZCenter, vXWidth, vYWidth, &findPeakCtrlInfo);
	
	if ( m_nNumFoundPeaks < 1 )
	{
		error_report("No peak found!");
		return true;
	}
	
	/// Hong, to do, not sure if 2D replica have baseline concept
	//if ( m_pParamMngr->SetReplicasInitialParameters(vXCenter, vYCenter, vZCenter, vXWidth, vYWidth, vDefaultParams) )
	//	return error_report("Fail to init replica paramters.");
	
	return true;
}

bool		NLFitSession::getReplicaInitParamSettings(FindPeakCtrlInfo& findPeakCtrlInfo)
{
	///Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	//if ( !m_trReplicaInitParam )
		//return false;
#ifndef	EXTEND_INTERFACES_OF_NLFITSESSION
	if ( !m_trReplicaInitParam )
		return false;
#else	//EXTEND_INTERFACES_OF_NLFITSESSION defined
    if ( !m_trReplicaInitParam )
    {
    	Tree tr;
    	TreeNode trReplicaInitParam = tr.AddNode("ReplicaInitParam");
    	if ( !add_auto_init_params_branch_under_replica(trReplicaInitParam) )
    		return false;
    	
    	SetReplicaAutoInitParamInfoTree(trReplicaInitParam); //init replica init param tree and continue the remains.
    }
#endif	//EXTEND_INTERFACES_OF_NLFITSESSION
	///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
	
	Tree 		tr;
	TreeNode 	trTemp = tr.AddNode("Junk");
	trTemp = findPeakCtrlInfo;
	tree_copy_values_by_id(m_trReplicaInitParam, trTemp);
	findPeakCtrlInfo = trTemp;	
	findPeakCtrlInfo.dwCtrl = PK_DIR_INDEX_TO_BITS(findPeakCtrlInfo.nDirection);
	
	return true;
}

bool		NLFitSession::isNeedReinitParamType()
{
	return (getParamsType() != m_pParamMngr->GetType());
}

/// Hong 12/15/08 QA80-10499-P6 FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE
bool		NLFitSession::isNeedRestoreParamsSettings()
{
	if ( !m_bInternalSetFunctionByDataChange )
		return false;
	
	// only convert from single to multiple dataset need restore old parameter settings, see our old dataset design (m_nOldNumberDataset)
	if ( NLPMGRTYPE_SINGLE_SET_NO_REPLICAS != m_pParamMngr->GetType() || NLPMGRTYPE_MULTIPLE_SETS != getParamsType() )
		return false;
	
	if ( m_nOldNumberDataset <= 0 )
		return false;
	
	/// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	if ( !isKeepOldDatasetParamsSettings() )
		return false;
	/// end AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
	return true;
}
/// end FIX_FAIL_KEEP_OLD_DATASET_PARAMS_VALUE

//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
void 		NLFitSession::trimOffsetParameter(vectorbase& vb, int nFunc/* = 0*/)
{
	int		nParamOffset = m_pParamMngr->GetFunctionParameterOffset(nFunc);
	
	ASSERT(nParamOffset <= vb.GetSize());
	//------ Folger 12/08/08 QA80-12680 v8.0983 NON_PEAK_FUNCTION_CHANGED_FAIL_TO_DISPLAY_ERROR_MESSAGE_DUE_TO_RUNTIME_ERROR_CAUSED_BY_GETSUBVECTOR
	/// negative return value means error, for here means vb.GetSize() == nParamOffset, some work around for this case ...
	//vb.GetSubVector(vb, nParamOffset);
	if ( vb.GetSubVector(vb, nParamOffset) < 0 )
	{
		vb.RemoveAll();
	}
	//------ End NON_PEAK_FUNCTION_CHANGED_FAIL_TO_DISPLAY_ERROR_MESSAGE_DUE_TO_RUNTIME_ERROR_CAUSED_BY_GETSUBVECTOR
}
void 		NLFitSession::trimOffsetParameter(vector<string>& vs, int nFunc/* = 0*/)
{
	int		nParamOffset = m_pParamMngr->GetFunctionParameterOffset(nFunc);
	
	while ( nParamOffset-- > 0 )
	{
		ASSERT(vs.GetSize());
		vs.RemoveAt(0);
	}
}
//------ End SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET

/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
int			NLFitSession::getNumParamsInFDF(int nFunc, vector<string>* pvsParamNames/* = NULL*/, const TreeNode& trFDF/* = NULL*/)
{
	ASSERT(nFunc >= 0);
	TreeNode 	trFitFunction;
	if ( trFDF )
		trFitFunction = trFDF;
	else
		trFitFunction = GetTreeFDF(nFunc);
		
	vector<string>	vsParamNames;
	int			nNumParamInFDF = nlsf_get_fit_param_names(trFitFunction, vsParamNames);
	
	if ( pvsParamNames )
		*pvsParamNames = vsParamNames;
	
	return nNumParamInFDF;
}
/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER

//----- Iris 11/27/2008 v8.0980 PA_IMPROVE_PARAM_INIT_IF_LOAD_PARAM_SETTINGS_FROM_FDF
//int			NLFitSession::getParamsInitInfo(int nFunc, vector& vParamValues, vector<string>* pvsParamNames, const TreeNode& trFDF, int *pnNumParaInFDF/* = NULL*/) // = NULL, NULL
int			NLFitSession::GetParamsInitInfo(int nFunc, vector& vParamValues, vector<string>* pvsParamNames, const TreeNode& trFDF, int *pnNumParaInFDF/* = NULL*/) // = NULL, NULL
//-----
{
	TreeNode 	trFitFunction;
	if ( trFDF )
		trFitFunction = trFDF;
	else
		trFitFunction = GetTreeFDF(nFunc);
		
	vector<string>	vsParamNames;
	/// Hong 09/10/08 v8.0936b CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	//int			nNumParamInFunc = nlsf_get_fit_param_names(trFitFunction, vsParamNames);
	int			nNumParamInFunc = getNumParamsInFDF(nFunc, &vsParamNames, trFitFunction);
	/// end CLEAN_CODE_DUE_TO_NEW_PARAMETER_MANAGER
	
	/// Hong 12/30/08 QA80-12878 v8.0992 FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION
	if ( nNumParamInFunc <= 0 )
	{
		if ( pnNumParaInFDF )
			*pnNumParaInFDF = 0;
		return 0;
	}
	/// end FAST_POPUP_DLG_BY_SKIP_INIT_USING_NULL_FUNCTION

	string 		strParaValueList = m_NFO.GetFittingPara(trFitFunction, true, STR_FDF_SETTING_INIT_VAL).strVal;
	nlf_set_param_values_vector(strParaValueList, vParamValues, nNumParamInFunc);
	
	trimOffsetParameter(vParamValues, nFunc);
	trimOffsetParameter(vsParamNames, nFunc);
	
	/// Hong 19/05/08 NEW_PARAM_MNGR
	//ASSERT(GetFitFunction(nFunc)->GetNumParaInFunc() == nSize);
	ASSERT(GetNumParameter(nFunc) == vParamValues.GetSize());
	/// end NEW_PARAM_MNGR
	
	if ( pvsParamNames )
		*pvsParamNames = vsParamNames;
		
	//------ Folger 09/05/08 SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
	if ( pnNumParaInFDF )
		*pnNumParaInFDF = nNumParamInFunc;
	//------ End SHOULD_TRIM_PARAMETER_SETTING_VECTOR_BY_FUNCTION_OFFSET
		
	return vParamValues.GetSize();
}

bool		NLFitSession::getParamNumericValues(NLPARAMGRIDCOLTYPE colType, vectorbase& vbValue)
{
	///------ Folger 04/03/09 QA80-13408 SUPPORT_GET_COLUMN_NUMERIC_VALUES_WITH_FULL_PRECISION_FROM_NLPARAM_MANAGER
	//StringArray		saParamValue;
	//if ( !getParamStringValues(colType, saParamValue) )
		//return false;
	//
	//vector			vdParamsVal;
	//convert_str_vector_to_num_vector(saParamValue, vdParamsVal);
	//vbValue = vdParamsVal;
	//return true;
	return m_pParamMngr->GetNumericColumn(colType, vbValue) >= 0 ? true : false;
	///------ End SUPPORT_GET_COLUMN_NUMERIC_VALUES_WITH_FULL_PRECISION_FROM_NLPARAM_MANAGER
}

bool		NLFitSession::getParamStringValues(NLPARAMGRIDCOLTYPE colType, vector<string>& vstrValue)
{	
	//------ Folger 11/04/08 QA80-12509 v8.0965 SUPPORT_BOTH_PEAKS_SORTING_AND_REORDERING_FOR_MULTIPLE_PEAKS_FITTING
	//if ( m_pParamMngr->GetColumn(colType, vstrValue) <= 0 )
	if ( m_pParamMngr->GetColumn(colType, vstrValue, FALSE) <= 0 )
	//------
		return false;
	
	return true;
}

void 		NLFitSession::validateParams(LPCSTR lpcszTitle)
{
#ifdef NLF_DEBUG	
	vector<bool>	vbParamsFixed;
	getParamNumericValues(NLPARAMGRIDCOLTYPE_FIXED, vbParamsFixed);	
	
	vector			vdParamsValues;
	getParamNumericValues(NLPARAMGRIDCOLTYPE_VALUE, vdParamsValues);
	
	ASSERT( vbParamsFixed.GetSize() == vdParamsValues.GetSize() );
	
	Tree		trParams;
	m_pParamMngr->GetParamSettings(trParams);	
#endif //NLF_DEBUG
}

/// Hong 08/26/08 v8.0930 DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION
void		NLFitSession::updateSharedCtrl(int nDataMode, int nOldDataMode)
{	
	if ( INVALID_DATA_MODE == nDataMode || INVALID_DATA_MODE == nOldDataMode )
	{
		m_nSharedCtrl = NLF_SHARED_CTRL_NONE;
		return ;
	}
	
	m_nSharedCtrl = NLF_SHARED_CTRL_NO_CHANGE;
	if (  nDataMode == nOldDataMode )	
		return ;	
	
	if ( DATA_MODE_GLOBAL == nDataMode )
	{
		m_nSharedCtrl = NLF_SHARED_CTRL_RESTORE;
	}
	else if ( DATA_MODE_GLOBAL == nOldDataMode )
	{
		m_nSharedCtrl = NLF_SHARED_CTRL_BACKUP_RESET_CURRENT;
	}			
}

/// Hong 12/24/08 QA80-10499 v8.0990c DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
//void		NLFitSession::checkUpdateSharedParamBySharedCtrl(bool bBeforeOnSetData/* = true*/)
void		NLFitSession::checkUpdateSharedParamBySharedCtrl(bool bBeforeOnSetData/* = true*/, bool bForceResetIfNone/* = false*/)
/// end DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
{
	switch ( m_nSharedCtrl )
	{
	case NLF_SHARED_CTRL_NONE:
		m_vnBackupShared.RemoveAll();
		/// Hong 12/24/08 QA80-10499 v8.0990c DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
		if ( !bBeforeOnSetData && bForceResetIfNone )
		{
			int		nShared = 0;
			int		nFunc = 0;
			for ( int ii = 0; ii < GetNumParameter(nFunc); ii++ )
				m_pParamMngr->SetOneFuncParam(nFunc, 0, ii, NULL, NULL, &nShared);
		}
		/// end DEFAULT_THEME_SHOULD_FORCE_RESET_SHARE_AS_NO_SETFUNCTION_CALLED
		break;	
	case NLF_SHARED_CTRL_BACKUP_RESET_CURRENT:
		// Hong, to do, before do back/reset and restore, maybe necessary to check whenther proper, as Data Mode can be updated after SetData in case remove one dataset of two
		if ( bBeforeOnSetData )
		{
			getParamNumericValues(NLPARAMGRIDCOLTYPE_SHARE, m_vnBackupShared);
		}
		else
		{
			int		nShared = 0;
			ASSERT(1 == GetNumberFitFunctions());
			int		nFunc = 0;
			int		nSize = GetNumParameter(nFunc);
			for ( int ii = 0; ii < nSize; ii++ )
			{
				m_pParamMngr->SetOneFuncParam(nFunc, 0, ii, NULL, NULL, &nShared);
			}
		}
		break;
	case NLF_SHARED_CTRL_RESTORE:
		if ( !bBeforeOnSetData )
		{
			ASSERT(1 == GetNumberFitFunctions());
			int		nFunc = 0;
			int		nSize = min(m_vnBackupShared.GetSize(), GetNumParameter(nFunc));
			for ( int ii = 0; ii < nSize; ii++ )
			{
				m_pParamMngr->SetOneFuncParam(nFunc, 0, ii, NULL, NULL, &m_vnBackupShared[ii]);
			}
		}
		break;
	case NLF_SHARED_CTRL_NO_CHANGE:
	default:
		break;
	}
}
/// end DATA_MODE_SHOULD_BE_SELF_CONTAINED_BY_SESSION

bool		NLFitSession::checkAddWorkArea(TreeNode& trOp)
{
	ASSERT(trOp);
	if ( trOp.FitWorkArea )
	{
		if ( trOp.FitWorkArea.Parameters )
			return true;
	}
	
	_DBSTR("adding FitWorkArea to op tree");
	trOp.FitWorkArea.ID = 1;
	trOp.FitWorkArea.Parameters.ID = 2;
	
	return false;
}
bool    	NLFitSession::GetSourceGraphLayer(GraphLayer& gl, int nDatasetIndex)
{	
	/// Iris NLF_81
	/*
	if(nDatasetIndex >= m_vuSourceDataPlotUIDs.GetSize())
	{
		string 	str;
		str.Format("GetSourceGraphLayer asking for nDatasetIndex outside bound of m_vuSourceDataPlotUIDs, index = %d", nDatasetIndex);
		return error_report(str);
	}

	return get_graph_layer_by_plot_uid(gl, GetSourcePlotUID(nDatasetIndex));	
	*/
	return m_pDataObj->GetSourceGraphLayer(gl, nDatasetIndex);
	///end NLF_81
}

/// Hong 08/13/08 QA80-12008 REACTIVE_FIT_RELATIVE_BTN_AFTER_CONSTRAINT_CHANGE
void		NLFitSession::NotifyTreeFDFChange(BOOL bConstraints)
{
	if ( bConstraints )
	{
		resetIterations(OSD_FROM_FUNC_CHANGE, false);
	}
}
/// end REACTIVE_FIT_RELATIVE_BTN_AFTER_CONSTRAINT_CHANGE

/// Hong 09/10/08 v8.0936b PARAMETER_MODIFIED_BY_GRID
void		NLFitSession::NotifyParameterChangedByEdit()
{
	NLFitReset(ONLSF8RESET_PARAMETERS, false);
	m_bParamsFromAutoInit = false; /// Hong 06/26/09 QA80-13846 AUTO_INIT_PARAMETER_IF_USER_HAVE_NOT_EDITED_PARAMETER_WHEN_CHANGE_DATA
}
/// end PARAMETER_MODIFIED_BY_GRID
	
bool		NLFitSession::OnFindingPeakArgChanged()
{
	//Set AUTO_UPDATE_FINDING_PEAK_ARG_CHANGE bit first
	m_dwAutoUpdateCtrl |=  AUTO_UPDATE_FINDING_PEAK_ARG_CHANGE;
	//Default value temporarily
	int		nFunc = 0;
	return DoUpdateParams(nFunc, false );
}

/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
//void		NLFitSession::writeMsgLog(LPCSTR lpcstrMsg, bool bStartSeparator, bool bEndEmptyLine) // = true, true
void		NLFitSession::writeMsgLog(LPCSTR lpcstrMsg, bool bStartSeparator, bool bEndEmptyLine, bool bEmphasize/* = false*/) // = true, true
/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
{
	ASSERT(isMsgLogAvailable());
	
	if ( bStartSeparator )
		m_pOpMsgLog->WriteSeparator(true, false);
	
	if ( lpcstrMsg != NULL )
	{
		/// Hong 01/13/10 QA80-13590-P9 NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
		//m_pOpMsgLog->Write(lpcstrMsg);
		BOOL*				pbBold = NULL;
		BOOL				bEmphasizeBold = TRUE;
		COLORREF*			pcrTextColor = NULL;
		COLORREF			crEmphasizeTextColor = COLOR_RED;
		if ( bEmphasize )
		{
			pbBold = &bEmphasizeBold;
			pcrTextColor = &crEmphasizeTextColor;
		}
		m_pOpMsgLog->Write(lpcstrMsg, pbBold, pcrTextColor);
		/// end NLFIT_SUPPORT_BOLD_AND_RED_COLOR_FOR_ERR_MSG_IN_MSG_LOG
	}
	
	if ( bEndEmptyLine )
		m_pOpMsgLog->WriteLine();
}

/// Hong 08/14/08 v8.0922 KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER
int			NLFitSession::getReplicaOffsetFromFDF(const TreeNode& trFDF)
{
	if ( !trFDF )
		return -1;
	
	return nlf_get_duplicate_offset(trFDF);
}
/// end KEEP_REPLICA_KNOWLEDGE_IN_SESSION_BUT_NOT_SPLITTER

/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
int			NLFitSession::getIterateResultSetIndex(int nSetIndex)
{
	ASSERT( m_vnLastIterateOutCome.GetSize() > 0 ); // Hong, to do
	if ( nSetIndex < 0 || nSetIndex >= m_vnLastIterateOutCome.GetSize() )
	{
		ASSERT( NLPMGRTYPE_MULTIPLE_SETS == GetNLParamsMngr()->GetType() );
		return 0;
	}
	
	return nSetIndex;
}

/// Hong 11/10/08 QA80-12329 FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT
//bool		NLFitSession::hadBackupedFitResults()
//{
	//if ( m_arNLFitResults.GetSize() > 0 )
	//{
		//ASSERT( doesNeedBackupFitResults() );
		//return true;
	//}
	//
	//return false;	
//}
//
//bool		NLFitSession::doesNeedBackupFitResults()
//{
	//return isSeparateFit();
//}
/// end FIX_CONFIDENCE_BAND_ONLY_ONE_RESULT_FOR_SEPARATE_FIT_CONSOLIDATE_REPORT

bool		NLFitSession::isSeparateFit()
{
	// Hong, to do, separate report is NOT the same as consolidate, so maybe trun of support it
	//return false;
	if ( GetNumDataset() <= 1 )
		return false;
	ASSERT(NLPMGRTYPE_MULTIPLE_SETS == GetNLParamsMngr()->GetType());
	return DATA_MODE_INDEP_CONSOLID == m_nCurrDataMode || DATA_MODE_INDEP_SEP == m_nCurrDataMode;
}
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT


///Jack 07/11/08 QA70-12329 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_SET_SEP_FIT
bool		NLFitSession::isGlobalFit()
{
	bool bGlobalFit = DATA_MODE_GLOBAL == m_nCurrDataMode;
	return bGlobalFit;
}
///End CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_SET_SEP_FIT

//////////////////For FitPeak, Folger, to do////////////////////////////////////
int			NLFitSession::GetAllFunctions(vector<string>& vsFunctions)
{
	vector<string> vsFunctionsTemp;
	for(int nFunc = 0; nFunc < GetNumberFitFunctions(); nFunc++)
	{
		vsFunctionsTemp.Add(GetFunctionName(NULL, nFunc));
	}
	if( vsFunctions )
		vsFunctions = vsFunctionsTemp;
	
	return vsFunctionsTemp.GetSize();
}

/// Iris 11/12/2008 v8.0969 QA80-12584 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
bool		NLFitSession::HasBaseline()
{
	return m_bHasBaseline;
}
///end OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
 
/// Iris 11/12/2008 v8.0969 QA80-12584 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP, just renmae SetBaseLineMode to SetHasBaseLineMode, old name not good
//void		NLFitSession::SetBaseLineMode(bool bHasBaseline)
void		NLFitSession::SetHasBaseLine(bool bHasBaseline)
///end OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
{
	m_bHasBaseline = bHasBaseline;
}


void		NLFitSession::SetBaselineFitMode(bool bBaselineFitWithPeaks)
{
	//------ Folger 10/21/08 SET_GET_BASELINE_PEAK_FITTING_STATUS_IN_NLPARAMSMNGR
	//m_bBaselineFitWithPeaks = bBaselineFitWithPeaks;
	GetNLParamsMngr()->SetBaselineFittingWithPeaks(bBaselineFitWithPeaks);
	//------
}

bool		NLFitSession::GetBaselineFitMode() // == old function HasBaselinePeak
{
	//------ Folger 10/21/08 SET_GET_BASELINE_PEAK_FITTING_STATUS_IN_NLPARAMSMNGR
	//return m_bBaselineFitWithPeaks;
	return GetNLParamsMngr()->GetBaselineFittingWithPeaks();
	//------
}

/// Iris 11/15/2008 FIX_ADDBACKBASELINE_FAIL_TO_GET_BASELINE_DATA
//bool		NLFitSession::GetBaselineData(vector& vXBaseline, vector& vYBaseline, matrix& matZBaseline)
bool		NLFitSession::GetBaselineData(vector& vXBaseline, vector& vYBaseline, matrix& matZBaseline, bool bCheckCondition)
///end FIX_ADDBACKBASELINE_FAIL_TO_GET_BASELINE_DATA
{
	if( !m_drBaseline )
		return false;
	
	/// Iris 11/12/2008 v8.0969 QA80-12584 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP, always set baseline range to fitsession now since AddBackBaseline need this range if subtracted data.
	// so need to check, if meet the following conditions, should not has baseline data. 
	/// Iris 11/15/2008 FIX_ADDBACKBASELINE_FAIL_TO_GET_BASELINE_DATA
	if(	bCheckCondition )
	///end FIX_ADDBACKBASELINE_FAIL_TO_GET_BASELINE_DATA
	{
		if( !HasBaseline() || GetSubtractedMode() || GetBaselineFitMode() )
		{
			return false;
		}
	}
	///end OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP

	
	if( NULL != matZBaseline )
		return m_drBaseline.GetData(matZBaseline) > 0;
	
	return m_drBaseline.GetData( DRR_GET_MISSING |  DRR_GET_DEPENDENT | DRR_NO_FACTORS, 0, NULL, NULL, &vYBaseline, &vXBaseline) >= 0;	
}

void		NLFitSession::SetBaselineRange(DataRange& drBaseline)
{
	m_drBaseline = drBaseline;
}

void 		NLFitSession::SetSubtractedMode(bool bSubtracted)
{
	m_bHasSubtracted = bSubtracted;
}

bool		NLFitSession::GetSubtractedMode()
{
	return m_bHasSubtracted;
}

/// Iris 11/12/2008 v8.0969 QA80-12584 OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP
bool		NLFitSession::GetSubtractedDataRange(DataRange& drSubtracted)
{
	drSubtracted = m_drSubtracted;
	return m_drSubtracted.IsValid();
}

void		NLFitSession::SetSubtractedDataRange(DataRange& drSubtracted)
{
	m_drSubtracted = drSubtracted;
}
///end OUTPUT_BASELINE_AND_SUBTRACTED_DATA_IN_FIT_PEAK_OP

/// Iris 9/22/2008 NEW_PA, add temp not sure if still neen PFWTree later
bool		NLFitSession::GetResultPFWTree(TreeNode& tr) 
{
	return m_pParamMngr->GetFuncsAndParamsMultiFuncsPeakFitting(tr);	
}	
//////////////////end For FitPeak ////////////////////////////////////	
///Sophy 1/12/2009 v8.0995c QA80-12613-P4 SHOULD_ONLY_SHOW_UNIFORM_LINEAR_ON_DATATYPE_FOR_3D_FITTING
bool		NLFitSession::CheckXYZRegularData( int& nRows, int& nCols )
{
	///Jasmine 05/24/10 SRVC-12 ALLOW_SAME_AS_INPUT_FOR_ALL_SURFACE_FIT
	if(	NLFIT_XYZ_FITTING == GetFitType() )
	{
		if( NULL != nRows )	//it will use input data size not nRows&nCols	
			nRows = 1;
		if( NULL != nCols )		
			nCols = 1;
		return true;
	}
	///End ALLOW_SAME_AS_INPUT_FOR_ALL_SURFACE_FIT
	///------ Folger 07/28/09 QA80-14021 PREIVEW_UPDATE_IN_MATRIX_FIT_AND_SURFACE_FIT_MUCH_SLOWER_THAN_SR5
	//vector vX, vY, vZ;
	//NLFDataBase*	pDataObj = GetDataObject();
	//ASSERT( pDataObj );
	//if( !pDataObj )
		//return false;
	//
	/////Jasmine 07/02/09 QA80-12613-P4 X_Y_ARE_INDEPEND_DATA_IN_3D_FITTING
	////pDataObj->GetDependData( vX, 0, 0 );
	////pDataObj->GetDependData( vY, 0, 1 );
	////pDataObj->GetIndependData( vZ, 0, 0 );
	//pDataObj->GetIndependData( vX, 0, 0 );
	//pDataObj->GetIndependData( vY, 0, 1 );
	//pDataObj->GetDependData( vZ, 0, 0 );
	/////End X_Y_ARE_INDEPEND_DATA_IN_3D_FITTING
	//
	//bool bRegular = false;		
	//if(vX.GetSize() == vY.GetSize() && vX.GetSize() == vZ.GetSize() && vX.GetSize() != 0)
	//{
		//double 	dPrecision = 1E-8;
		//int 	nSize = vX.GetSize();
		//double 	Xmin, Ymin, Xstep, Ystep, Xmax, Ymax;
	//
		/////---Sim 09-25-2009 QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION
		////int nRet = ocmath_xyz_examine_data(nSize, vX, vY ,vZ, dPrecision, &nSize, &Xmin,
					////&Xstep, &Xmax, &Ymin, &Ystep, &Ymax, true);	
		//int nRet = xyz_examine_data(nSize, vX, vY ,vZ, dPrecision, &nSize, &Xmin,
					//&Xstep, &Xmax, &Ymin, &Ystep, &Ymax, true);	
		/////---End QA80-13783 CHANGE_PROTOTYPE_AND_ALGORITHM_FOR_EXAMINATION
			//
		//if(NULL != nCols) nCols = Xstep > 0 ? (int)((Xmax - Xmin) / Xstep + 0.5) + 1 : 1; 
		//if(NULL != nRows) nRows = Ystep > 0 ? (int)((Ymax - Ymin) / Ystep + 0.5) + 1 : 1; 
		//if(Examine_XYZ_Regular == nRet)
			//bRegular = true;
	//}
	//return bRegular;
	NLFDataBase*	pDataObj = GetDataObject();
	return NULL == pDataObj ? false : pDataObj->CheckXYZRegularData(nRows, nCols);
	///------ End PREIVEW_UPDATE_IN_MATRIX_FIT_AND_SURFACE_FIT_MUCH_SLOWER_THAN_SR5
}
///end SHOULD_ONLY_SHOW_UNIFORM_LINEAR_ON_DATATYPE_FOR_3D_FITTING

int			NLFitSession::GetPeakCenterOrWidth(vector& vXCenter, bool bGetCenter, bool bGetY)//false
{
	if( bGetY && NLFIT_GENERAL_XY_FITTING == GetFitType() )
		return -1;
	
	int 	nFix 	= true;
	bool 	bChange = false;
	int 	nCenter = ACCESS_NO_VALUE;
	int 	nWidth =  ACCESS_NO_VALUE;
	if(bGetCenter)
	{
		nCenter = bGetY? ACCESS_Y_VALUE : ACCESS_X_VALUE;
	}
	else
	{
		nWidth = bGetY? ACCESS_Y_VALUE : ACCESS_X_VALUE;
	}
	
	vector<int>	vnFixed;
	//int nFixSize = m_vbFixed.GetSize();
	//vnFixed.SetSize(nFixSize);
	//------ Folger 11/04/08 QA80-12509 v8.0965 SUPPORT_BOTH_PEAKS_SORTING_AND_REORDERING_FOR_MULTIPLE_PEAKS_FITTING
	//vector<string> vstrFixed;
	//m_pParamMngr->GetColumn(NLPARAMGRIDCOLTYPE_FIXED, vstrFixed);
	//convert_string_vector_to_int_vector(vstrFixed, vnFixed);
	GetParamNumericValues(vnFixed, NLPARAMGRIDCOLTYPE_FIXED);
	//------ End SUPPORT_BOTH_PEAKS_SORTING_AND_REORDERING_FOR_MULTIPLE_PEAKS_FITTING
	vnFixed = false;
	
	//after fix center, if vnFixed[index] == true, means parameter of this index is center
	if( peaksCenterWidthSettingsAccess(vnFixed, nFix, nCenter, nWidth, &bChange) && bChange )
	{
		///Jasmine 05/05/08 GET_ELEMENT_FROM_VECTOR_BY_ANOTHER_FILTER_VECTOT
		/// Iris 9/22/2008 NEW_PA
		//vXCenter = m_vParamValues;
		vector			vParamValues;
		//------ Folger 11/04/08 QA80-12509 v8.0965 SUPPORT_BOTH_PEAKS_SORTING_AND_REORDERING_FOR_MULTIPLE_PEAKS_FITTING
		//vector<string> 	vstrParamValues;		
		//m_pParamMngr->GetColumn(NLPARAMGRIDCOLTYPE_VALUE, vstrParamValues);
		//convert_str_vector_to_num_vector(vstrParamValues, vParamValues);
		GetParamNumericValues(vParamValues, NLPARAMGRIDCOLTYPE_VALUE);
		//------ End SUPPORT_BOTH_PEAKS_SORTING_AND_REORDERING_FOR_MULTIPLE_PEAKS_FITTING
		vXCenter = vParamValues;
		///end NEW_PA
		return trim_vector(vXCenter, vnFixed);		
		///End GET_ELEMENT_FROM_VECTOR_BY_ANOTHER_FILTER_VECTOT
	}
	
	return -1;
}
///Sophy 11/4/2008 QA80-12510 ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
int		NLFitSession::GetPeakCenterX( vector& vXCenter )
{
	vXCenter = m_vXCenter;
	return vXCenter.GetSize();
}

int		NLFitSession::GetPeakCenterY( vector& vYCenter )
{
	vYCenter = m_vYCenter;
	return vYCenter.GetSize();
}
///end ADD_LABEL_OBJECT_FOR_NLFIT_REPLICA_PEAK_ON_NLFIT_PREVIEW_GRAPH
//------ Folger 04/24/08 CENTRALIZE_CODE_OF_SET_FIX_AND_SHARE_PARAMETERS
static bool _toggle_para_setting(vector<int>& vnSettings, int nValue, int nFrom, int nParamIndex, int nOffset, int nSize, bool& bChange)
{
	int index = nFrom + nParamIndex - nOffset;
	if(nSize <= index)
		return false;
	if(vnSettings[index] != nValue)
	{
		vnSettings[index] = nValue;
		bChange = true;
	}
	
	return true;
}

static int _get_para_setting(const vector<int>& vnSettings, int nFrom, int nParamIndex, int nOffset)
{
	int index = nFrom + nParamIndex - nOffset;
	if(vnSettings.GetSize() <= index)
		return false;
	
	return vnSettings[index];
}
//------ End CENTRALIZE_CODE_OF_SET_FIX_AND_SHARE_PARAMETERS

bool	NLFitSession::peaksCenterWidthSettingsAccess(vector<int> &vnSettings, int &nValue, int nCenter, int nWidth, bool *pbChange, bool bSet, bool bShare)	//true, false
{
	string 		strFunction;
	TreeNode 	trFDF;	
	int 		nXCenter, nXWidth, nYCenter, nYWidth;
	int			nOffset;
	int			nSize 	= vnSettings.GetSize();
	int 		nPeaks 	= GetNumPeaks();
	bool		b2DFit 	= NLFIT_GENERAL_XY_FITTING != GetFitType();
	
	///Jasmine 05/05/08 SUGGESTION_ABOUT_WHEN_TO_GET_PEAK_CENTER
	//this loop now do these: 
	//1. nlsf_get_peak_center_width_index  from trFDF
	//2. GetParamsSubVectorRange from trFDF
	//3. calculate one peak center/width param index 
	//4. set/get center/width param Fix/Share value
	//I think 1, 2 and 3 depend on trFDF and nMultiplicity, so we should keep 
	//m_XCenterIndexes and m_YCenterIndexes and set these 2 vectors when SetFuncTree or change Multiplicity
	///End SUGGESTION_ABOUT_WHEN_TO_GET_PEAK_CENTER
	/// Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	int				nLastFromOnlySingleSet = -1, nLastFunc = -1;
	/// end PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
	for(int nFunc = 0; nFunc < nPeaks; nFunc++)
	{
		///Kyle 10/21/08 CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE
		//if( 0 == nFunc && HasBaselinePeak() )
		if( 0 == nFunc && GetBaselineFitMode() )
		///End CHANGE_FUNCTION_NAME_HASBASELINEPEAK_TO_GETBASELINEFITMODE
			continue;	
			
		/// Iris 9/22/2008 NEW_PA
		//NLFitFunction* pFitFunc = GetFitFunction(nFunc);
		//if(NULL == pFitFunc)
			//return false;
		
		//if( strFunction.IsEmpty() || strFunction.CompareNoCase( pFitFunc->GetFuncName() ) != 0 )
		//{
			//trFDF = pFitFunc->GetFuncTree();
		if( strFunction.IsEmpty() || strFunction.CompareNoCase( GetFunctionName(NULL, nFunc)  ) != 0 )
		{
			trFDF = GetTreeFDF(nFunc);
		///end NEW_PA
						
			bool bRet;
			///------ Folger 06/18/09 CENTRALIZE_CODE_ABOUT_GETTING_PEAK_FUNC_PARAM_INDICES
			//if(b2DFit)
				//bRet = nlsf_get_2d_peak_center_width_index(trFDF, &nXCenter, &nYCenter, &nXWidth, &nYWidth);
			//else
				//bRet = nlsf_get_peak_center_width_index(trFDF, &nXCenter, &nXWidth);
			if(b2DFit)
				bRet = nlsf_get_2d_peak_param_indices(trFDF, &nXCenter, &nYCenter, &nXWidth, &nYWidth);
			else
				bRet = nlsf_get_peak_param_indices(trFDF, &nXCenter, &nXWidth);
			///------ End CENTRALIZE_CODE_ABOUT_GETTING_PEAK_FUNC_PARAM_INDICES
			if(!bRet)
				return false;
			
			nXCenter--;//1-offset
			nXWidth--; 
			nYCenter--; 
			nYWidth--;
			nOffset = nlf_get_duplicate_offset(trFDF) - 1;
		}
		
		int nFrom;
		/// Hong 12/23/08 v8.0990 PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
		//GetParamsSubVectorRange(0, nFunc, &nFrom);		
		GetParamsSubVectorRange(0, nFunc, &nFrom, &nLastFromOnlySingleSet, &nLastFunc);
		/// end PA_AVOID_NESTED_LOOP_BY_CACHE_LAST_RESULT
		
		//------ Folger 04/15/08 INIT_FIXED_RELEASE_BUTTONS_STATUS
		if ( !bSet )
		{
			if ( ACCESS_NO_VALUE != nCenter )//bCenter
			{
				if(ACCESS_Y_VALUE != nCenter)
				{
					if ( (nValue = _get_para_setting(vnSettings, nFrom, nXCenter, nFunc > 0 ? nOffset : 0)) )
						return true; /// Iris 9/22/2008 NEW_PA, more comment to explain why directly return here: for fix state, if fix one(either X or Y), the fix state will be same as true and no need check another one.
				}
				if(ACCESS_X_VALUE != nCenter)
				{
					if ( b2DFit )
						nValue = _get_para_setting(vnSettings, nFrom, nYCenter, nFunc > 0 ? nOffset : 0);
				}
				return true;
			}
			
			if ( ACCESS_NO_VALUE != nWidth )//bWidth
			{
				if(ACCESS_Y_VALUE != nWidth)
				{
					if ( (nValue = _get_para_setting(vnSettings, nFrom, nXWidth, nFunc > 0 ? nOffset : 0)) )
						return true;
				}
				if(ACCESS_X_VALUE != nWidth )
				{
					if ( b2DFit )
						nValue = _get_para_setting(vnSettings, nFrom, nYWidth, nFunc > 0 ? nOffset : 0);
				}
				return true;
			}
			return false;
		}
		//------ End INIT_FIXED_RELEASE_BUTTONS_STATUS

		
		if(ACCESS_NO_VALUE != nCenter)//bCenter
		{
			if(ACCESS_Y_VALUE != nCenter)
			{
				if( !_toggle_para_setting(vnSettings, nValue, nFrom, nXCenter, nFunc > 0 ? nOffset : 0, nSize, *pbChange) )
					return false;
			}
			if(ACCESS_X_VALUE != nCenter)			
			{
				if(b2DFit && !_toggle_para_setting(vnSettings, nValue, nFrom, nYCenter, nFunc > 0 ? nOffset : 0, nSize, *pbChange) )
					return false;
			}
		}
		
		if(ACCESS_NO_VALUE != nWidth)//bWidth
		{
			if(ACCESS_Y_VALUE != nWidth)
			{
				if( !_toggle_para_setting(vnSettings, nValue, nFrom, nXWidth, nFunc > 0 ? nOffset : 0, nSize, *pbChange) )
					return false;
			}
			if(ACCESS_X_VALUE != nWidth)			
			{
				if(b2DFit && !_toggle_para_setting(vnSettings, nValue, nFrom, nYWidth, nFunc > 0 ? nOffset : 0, nSize, *pbChange) )
					return false;
			}
		}
		
		if ( bSet && bShare && nValue != 0 )
			++nValue;		
	}
	
	return true;
}

/// Iris 10/27/2008 v8.0961 PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION
enum
{
	COL_PEAKS_X = 0,
	COL_PEAKS_SUBTRACTED_Y,
	COL_PEAKS_COUNT
};

//------ Folger, 10/27/08, temp fix for liking error in curve_utils, need to talk to Iris
typedef	bool (*FUNC_VECR_VECR_VECR_VECR_BOOL)(vector& vx, vector& vy, vector& vbx, vector& vby, bool bResize_vb = false);
//------

bool		NLFitSession::prepareSubtractedDataRange()
{
	if( m_drSubtracted )
		return true;
	if( !m_drBaseline )
		return false;
	
	if( !m_wksSubtracted.IsValid() )
	{
		m_wksSubtracted.Create(NULL, CREATE_HIDDEN | CREATE_SET_MISSING_IN_MANAGER);
		m_wksSubtracted.SetSize(-1, COL_PEAKS_COUNT);
		m_wksSubtracted.SetColDesignations("XY");
	}	
	
	if(m_drSubtracted.IsValid())
		m_drSubtracted.Reset();
	m_drSubtracted.Add("X", m_wksSubtracted, 0, COL_PEAKS_X , -1, COL_PEAKS_X);
	m_drSubtracted.Add("Y", m_wksSubtracted, 0, COL_PEAKS_SUBTRACTED_Y , -1, COL_PEAKS_SUBTRACTED_Y);
	
	vector vX, vY;
	DWORD dwRules = DRR_GET_DEPENDENT | DRR_NO_FACTORS;
	if( m_drSrcData.GetData(dwRules, 0, NULL, NULL, &vY, &vX) < 0 )// returns input data row index	
		return false;	
	
	vector vBaselineX, vBaselineY;	
	if( m_drBaseline.GetData(dwRules, 0, NULL, NULL, &vBaselineY, &vBaselineX) < 0 )// returns input data row index	
		return false;	

	//------ Folger, 10/27/08, temp fix for liking error in curve_utils, need to talk to Iris
	//subtract_baseline(vX, vY, vBaselineX, vBaselineY);
	FUNC_VECR_VECR_VECR_VECR_BOOL		pfn = Project.FindFunction("subtract_baseline", "OriginLab\\curve_utils.c", true);
	if ( pfn )
		pfn(vX, vY, vBaselineX, vBaselineY);
	//------
	
	m_drSubtracted.SetData(&vY, &vX);
	
	return true;	
}
///end PREPARE_SUBTRACTED_DATA_RANGE_IN_NLFSESSION

///------ Folger 02/11/09 QA80-13098-S2 SHOW_CHISQR_INFO_IN_NLFIT_STATIC_MESSAGE
string			NLFitSession::GetReducedChiSqrInfo(const RegStats& stRegStats/* = NULL*/, int nSignDigit/* = -1*/)
{
	RegStats*	pstRegStats = stRegStats == NULL ? &m_RegStats : &stRegStats;
	string	strFormat = "*";
	if ( nSignDigit > 0 )
		strFormat.Format("*%d*", nSignDigit);
	return _L("Reduced Chi-sqr") + " = " + ftoa(pstRegStats->ReducedChiSq, strFormat);
}
///------ End SHOW_CHISQR_INFO_IN_NLFIT_STATIC_MESSAGE

///Jasmine 07/02/09 PA_AND_NANOSIZER_NEED_UPDATE_DATA_TYPE
//Since NLFitSession has nothing to do	with GUI, after SR6, 
//we should move these two functions out of NLFitSession 
static void		_update_fitted_curve_data_type_combo(TreeNode& trDataType, bool bIncludeSameInputData = true, bool bIncludeLog = true, bool bIncludeLinear = true)
{
	if ( !trDataType )
		return;
	
	string	strList;
	///Sophy 1/16/2009 v8.0957 FIX_DATATYPE_BRANCH_EMPTY_WHEN_FIT_FROM_GRAPH
	//if ( bIncludeLinear )
		//strList = STR_FITTED_CURVE_DATA_TYPE_UNIFORM_LINEAR + STR_TOKEN_SEP;
	//
	//if ( bIncludeLog )
		//strList += STR_FITTED_CURVE_DATA_TYPE_UNIFORM_LOG + STR_TOKEN_SEP;
	//
	//if ( bIncludeSameInputData )
		//strList += STR_FITTED_CURVE_DATA_TYPE_SAME_INPUT + STR_TOKEN_SEP;
	trDataType.GetAttribute(STR_ATTRIB_BRANCH_COMBO, strList);
	if ( !bIncludeLinear )
		remove_str_from_str_list(STR_FITTED_CURVE_DATA_TYPE_UNIFORM_LINEAR, strList);
	else
		insert_str_to_str_list(STR_FITTED_CURVE_DATA_TYPE_UNIFORM_LINEAR, strList);
	
	if ( !bIncludeLog )
		remove_str_from_str_list(STR_FITTED_CURVE_DATA_TYPE_UNIFORM_LOG, strList);
	else
		insert_str_to_str_list(STR_FITTED_CURVE_DATA_TYPE_UNIFORM_LOG, strList);
	
	if ( !bIncludeSameInputData )
		remove_str_from_str_list(STR_FITTED_CURVE_DATA_TYPE_SAME_INPUT, strList);
	else
		insert_str_to_str_list(STR_FITTED_CURVE_DATA_TYPE_SAME_INPUT, strList);
	///end FIX_DATATYPE_BRANCH_EMPTY_WHEN_FIT_FROM_GRAPH
	
	///Sophy 7/8/2009 v8.1060 CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
	int nNumItems = strList.GetNumTokens('|');
	if ( trDataType.Use >= nNumItems )
		trDataType.Use = 0;
	///end CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
	
	trDataType.SetAttribute(STR_ATTRIB_BRANCH_COMBO, strList);
}

typedef	void	(*FUNC_UPDATE_DATA_FORMAT)(const TreeNode& trRange, TreeNode& tr, LPCSTR lpcszStartNode, LPCSTR lpcszEndNode, LPCSTR lpcszIntervalNode, int nAxisType
											///------ Folger 08/25/10 ORG-897-P2 FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
											, LPCSTR pFormatDate = "D10"
											, LPCSTR  pFormatTime = "T2"
											///------ End FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
										  );
										  
///------ Folger 08/25/10 ORG-897-P2 FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
static	void	_get_date_time_fmt_string(string& strDate, string& strTime, const TreeNode& trData, LPCSTR lpcszNode)
{
	strDate = "D10";
	strTime = "T2";
	
	TreeNode	trNode = tree_get_node_by_tagname(trData, lpcszNode, true);
	if ( !trNode )
		return;
	
	Column		col;
	if ( okxf_resolve_string_get_origin_object(trNode.strVal, &col) && col )
	{
		int		nFormat = col.GetFormat();
		switch ( nFormat )
		{
		case OKCOLTYPE_DATE:
			strDate.Format("D%d", col.GetSubFormat());
			break;
		case OKCOLTYPE_TIME:
			strTime.Format("T%d", col.GetSubFormat());
			break;
		default:
			break;
		}
	}
}
///------ End FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
	
void 			NLFitSession::UpdateDataTypeBranch(TreeNode& trGraph1, const TreeNode& trData, bool bChangeParams)
{
	bool bEnableSameInput = false;
	bool bEnableLog = false;
	if ( NLFIT_GENERAL_XY_FITTING != GetFitType() )
	{
		bEnableSameInput = CheckXYZRegularData();
	}
	else
	{
		///Sophy 7/8/2009 v8.1060 CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
		//bEnableLog = true;
		///end CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
		bEnableLog = true;	///Sophy 7/13/2009 v8.1063 HIDE_LOG_DATATYPE_ON_3D_FITTING_FOR_NOT_SUPPORTED
		bEnableSameInput = true;
	}
	
	///Sophy 7/8/2009 v8.1060 CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
	///Sophy 7/13/2009 v8.1063 HIDE_LOG_DATATYPE_ON_3D_FITTING_FOR_NOT_SUPPORTED
	//bEnableLog = ( NLFIT_MATRIX_FITTING != GetFitType() );
	///end HIDE_LOG_DATATYPE_ON_3D_FITTING_FOR_NOT_SUPPORTED
	///end CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
	
	///------ Folger 08/25/10 ORG-897-P2 FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
	string		strDate, strTime;
	///------ End FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT

	TreeNode trXDataType = trGraph1.XDataType;
	if(trXDataType)
	{
		UpdateXDataMinMaxByAuto( trXDataType );		  
		
		///------ Folger 03/28/09 QA80-12786 SUPPORT_DATA_TIME_FORMAT_DISPLAY_FOR_GENERAL_FITTING_TOOLS_CUSTOM_XDATATYPE
		FUNC_UPDATE_DATA_FORMAT	pfn = Project.FindFunction("update_dataformat_start_end_interval", "OriginLab\\event_utils.c", true);
		if ( pfn )
		///------ Folger 08/25/10 ORG-897-P2 FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
			//pfn(trData, trXDataType, "Min", "Max", NULL, OKDATAOBJ_DESIGNATION_X);
		{
			_get_date_time_fmt_string(strDate, strTime, trData, "X");
			pfn(trData, trXDataType, "Min", "Max", NULL, OKDATAOBJ_DESIGNATION_X, strDate, strTime);
		}
		///------ End FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
		///------ End SUPPORT_DATA_TIME_FORMAT_DISPLAY_FOR_GENERAL_FITTING_TOOLS_CUSTOM_XDATATYPE
		
		_update_fitted_curve_data_type_combo(trXDataType, bEnableSameInput, bEnableLog, true); //always include linear

		///Sophy 4/1/2009 QA80-13386 SET_XDATATYPE_BE_SAME_AS_INPUT_FOR_MULTI_INDEPS_FUNCTION
		if ( !bChangeParams ) ///Sophy 4/28/2009 QA80-13386-P1 SHOULD_NOT_CHANGE_XDATATYPE_WHEN_OPEN_FROM_CHANGE_PARAMETER
		{
			int nNumIndeps;
			GetNumVars(NULL, &nNumIndeps);
			if ( nNumIndeps > 1 && NLFIT_GENERAL_XY_FITTING == GetFitType() ) //for surface & matrix fitting, should skip this logic
			{
				if ( bEnableSameInput )
					trXDataType.Use = FIT_CURVE_SAME_AS_DATA;
			}
		}
		///end SET_XDATATYPE_BE_SAME_AS_INPUT_FOR_MULTI_INDEPS_FUNCTION
	}

	TreeNode trYDataType = trGraph1.YDataType;
	if ( NLFIT_GENERAL_XY_FITTING != GetFitType() && trYDataType)
	{							  
		UpdateYDataMinMaxByAuto( trYDataType );	

		FUNC_UPDATE_DATA_FORMAT	pfn = Project.FindFunction("update_dataformat_start_end_interval", "OriginLab\\event_utils.c", true);
		if ( pfn )
		///------ Folger 08/25/10 ORG-897-P2 FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT
			//pfn(trData, trYDataType, "Min", "Max", NULL, OKDATAOBJ_DESIGNATION_Y);
		{
			_get_date_time_fmt_string(strDate, strTime, trData, "Y");
			pfn(trData, trYDataType, "Min", "Max", NULL, OKDATAOBJ_DESIGNATION_Y, strDate, strTime);
		}
		///------ End FITNL_X_DATA_TYPE_FOLLOW_SOURCE_X_DATE_TIME_FORMAT

		_update_fitted_curve_data_type_combo(trYDataType, bEnableSameInput, bEnableLog, true); //always include linear	
	}

}
///End PA_AND_NANOSIZER_NEED_UPDATE_DATA_TYPE

///------ Folger 08/06/10 ORG-733 FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED
void			NLFitSession::SetLastError(int nErr, int* pnErrToSet/* = NULL*/)
{
	m_nLastError = nErr;
	if ( pnErrToSet )
		*pnErrToSet = nErr;
}
int				NLFitSession::GetLastError()
{
	return m_nLastError;
}
///------ End FIT_BUTTON_FAILED_TO_BE_DISABLED_IF_FUNC_COMPILE_FAILED

#endif	//_NLF_SESSION_H_
