/*------------------------------------------------------------------------------*
 * File Name: FitNL.cpp															*
 * Creation: YuI 08/13/2004													    *
 * Purpose: implementation of FitNL class			 							*
 * Copyright (c) OriginLab Corp.2002, 2003, 2004, 2005							*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY 9/14/04 CONSOLIDATE_OP_BRANCH_AND_AUTOUPDATE							*
 *	CPY 10/8/04 QA70-4387 CENTRALIZE_NLF_TO_GETN_BASED_CODES					*
 *	CPY 12/13/04 KEEP_SESSION_TEMP_GRAPH_WHEN_FIT_FROM_WKS						*
 *	ML 12/14/2004 QA70-7240 GETTING_MISSING_VALUES_AND_ROWS						*
 *  Iris 4/12/05 MOVE_CURVE_OPTION_TO_EACH_GRAPH								*
 *  Iris 4/18/05 FIX_NLSF_CONF_PREDI_BAND_NOT_WORK								*
 *  Iris 5/18/05 REMOVE_TVALUE_PROB_FROM_NLSF									*
 *  Iris 7/25/05 GRAPH_TABLE_TEMP_SOLUTION_FOR_XYZ_DATA							*
 *	CPY 8/15/05 NLFIT_USE_MODLESS_DIALOG										*
 *  Kevin 09/02/05 ADD_CL_COMPUTATION_METHOD_GETNLIST							*
 *  Iris 11/02/05 QA70-8135-P6 NOT_SHOW_SURFACE_FITTED_DATA						*
 *	ML 11/2/2005 QA70-8135 MISSING_AND_MASKED_DATA_FOR_XYZ						*
 *	ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION					*
 *	ML 11/7/2005 QA70-8135 SURFACE_FITTING_VIA_XFUNC_NEW_WAY					*
 *  Iris 02/04/06 QA70-8461 ADD_REPLICA_OPTIONS									*
 *	Jasmine 03/13/06 v8.0374 REPLACE_VECTOR_POINTER_WITH_VECTOR					*
 *	ML 4/28/2006 FRIENDLY_CUSTOM_TABLE_THEME_GENERATION							*
 *	TD 5-12-06 CL_CHANGE_UPDATE													*
 *  Iris 5/15/06 v8.0410 CLEANUP_ISXYZDATA_CODES								*
 *	Jasmine 05/18/06 v8.0411 RETURN_SEL_FUNCTION								*
 *	ML 8/28/2006 MULTIPLE_DEPS_INDEPS_NLFIT										*
 *	ML 9/5/2006 MASKED_MISSING_NLFIT_TABLES										*
 *  Joseph 9/18/06 CHANGE_FINDX_FROMY_STEP										*
 *	ML 9/29/2006 GETTING_PLOUID_FROM_SESSION_OBJ								*
 *	TD 9-2-06 QA70-9012 DYNACONTROL_MULTILINEEDIT_BUTTON						*
 *	ML 10/2/2006 NLFIT_CURVES_CLEANUP											*
 *	CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER				*
 *	Arvin 10/23/06 FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED					*
 *  Iris 10/23/06 ONLY_UPDATE_DATA_LABEL_FOR_STATS_REPORT						*
 *	Arvin 10/25/06 ORIGINAL_DATA_SCATTER_UNSHOW									*
 *  Iris 11/02/06 v8.0502e COMMENT_IT_AS_IT_CAUSE_LOTS_TIME_TO_CALC				*
 *	ML 11/6/2006 SELECT_FITTING_FUNCTION_PANEL_CHANGES							*
 *	Jasmine 11/07/06 CHANGE_NLFIT_MODAL											*
 *	ML 11/10/2006 NLFIT_ALWAYS_MODAL											*
 *	ML 11/10/2006 NLFIT_MODAL_CLEANUP											*
 *	Jasmine 11/16/06 INITIALIZATION_SCRIPT_TO_SCRIPT_BEFORE_FITTING				*
 *	Jasmine 11/24/06 SEL_FUNC_AFTER_OPEN										*
 *	ML 12/15/2006 CALLING_NLFIT_FROM_OC_LT										*
 *	ML 12/18/2006 CALLING_OPERATION_FROM_OC_LT									*
 *  Iris 12/30/2006 v8.0534 CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE		*
 *	Cheney 2006-1-1 ADD_ONE_MORE_CHECK_BOX_FOR_REPLICA_CONTROL					*
 *	Arvin 01/23/06 INPUT_MASKED_AND_MISSING_DATA_TABLE_INCOMPLETE_CONCATENATE   *
 *	Jasmine 01/27/07 SHOW_FUNC_DESCRIPTION_INSTEAD_OF_FDF_PATH					*
 *  Iris 02/24/2007 v8.0569 FAIL_APPLY_PARAM_FROM_THEME_WHEN_CHOOSE_THEME_FROM_MENU*
 *  Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE								*
 *  Iris 02/27/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY			*
 *  Iris 02/28/2007 v8.0572 FIX_INDEP_FIT_MULTI_DATA_REPORT_FAIL_TO_DO_AU		*
 *  Iris 03/12/2007 v8.0579 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY			*
 *	Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y			*
 *	Jasmine 03/24/07 REMOVE_SCRIPT_BEFORE_AFTER_FITTING							*
 *	Arvin/Cheney 03/26/07 QA70-9527 SUPPORT_SETTING_PARAMS_FROM_OC_LT			*
 *	Cheney 2007-3-28 USE_FIT_TYPE_TO_GET_DATA_RULE								*
 *	Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG							*
 *	Arvin 03/29/07 v8.0592 CAN_NOT_PLOT_MULTI_HISTOGRAMS_FOR_MULTI_DATASET		*
 *	Cheney 2007-4-2 FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
 *	Cheney 2007-4-2 USE_SHORT_STRING_IN_STATISTIC_COLUMN						*
 *	Cheney 2007-4-2 ADD_HINTS_IN_FOOTNOTE_WHEN_EXISTS_MISSING_OR_MASKED_DATA	*
 *	Cheney 2007-4-2 IF_SHARE_PARAMETERS_ADD_HINTS_IN_FOOTNOTE					*
 *	ML 4/2/2007 INCORRECT_MAIN_DATA_STRING_NLFIT								*
 *	Joseph 04/02/07 ADD_NLSF_ERR_MSG_EVENT										*
 *	Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX					*
 *	Cheney 2007-4-4 ADD_FOOTNOTE_FOR_FIT_STATUS_AS_LARRY_SUGGEST				*
 *	Cheney 2007-4-4 SHOW_LB_UB_IN_REPORT_SHEET									*
 *	Cheney 2007-4-9 CORRECT_LOGIC_OF_CALLING_INIT_BRANCH						*
 *	Cheney 2007-4-10 IF_SEP_FIT_SHOULD_DISABLE_FIT_AND_ITER_BUTTON				*
 *	Cheney 2007-4-11 ONLY_FIT_NL_NEED_LB_UB										*
 *	Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA*
 *	Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE			*
 *	Cheney 2007-4-13 CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP		*
 *	Cheney 2007-4-17 FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED		*
 *	Arvin 04/24/07 v8.0607 SURFACE_FIT_NEED_UPDATE_TROPERATION_BEFORE_RUNNING_CHANGE_PARAM_AND_RECALCULATE
 *	Arvin 04/24/07 v8.0607 SURFACE_FIT_RESIDUAL_DATA_PLOTS						*
 *	Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD										*
 *	Cheney 2007-4-25 CALL_NLFIT_FROM_OC_ALSO_NEED_GET_FUNC_CODE					*
 *	Cheney 2007-4-29 SEPRATE_BOUND_SETTING_FROM_PARAMS_SETTING_CEHCK_BOX		*
 *	Joseph 04/02/07 ADD_NLSF_ERR_MSG_EVENT										*
 *	Cheney 2007-5-5 FUNC_DESCRIPTION_NOT_WORK									*
 *	Arvin 05/08/07 QA70-9498 SCALE_PARAMETER_ERRORS_WITH_CHI_SQR				*
 *	Cheney 2007-5-11 RESET_FIXED_LABEL_AS_MAX_SUGGEST							*
 *	Cheney 2007-5-14 RENAME_FIT_TOOL_CHECK_BOX_NAME								*
 *	Arvin 05/15/07 SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE					*
 *	Cheney 2007-5-16 NLFIT_SHOULD_CHECK_IF_EXIST_EMPTY_SUBRANGE					*
 *	Cheney 2007-5-22 SHOULD_RESET_FITSESSION_OBJ_IF_SEP_FIT						*
 *	Cheney 2007-5-28 TEMP_HIDE_LINEAR_CONSTRAIN_TAB_AND_CHECK_BOX				*
 *	Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT				*
 *	Cheney 2007-5-29 SHOULD_HIDE_RES_ANALYSIS_IF_MULTI_XY_FITTING				*
 *	Jasmine 05/29/07 ONLY_SHOW_SPECIFIED_CATEGORY_FOR_SPECIAL_FIT				*
 *	ML 6/1/2007 LEGEND_INCORRECT_FIX											*
 *	Cheney 2007-6-6 SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT							*
 *	Joseph 06/07/07 DIFF_EVENT_SHOULD_USE_DIFF_TREE								*
 *	Cheney 2007-6-8 ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC		*
 *	Arvin 06/12/07 OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT						*
 *	Arvin 06/12/07 USE_WRONG_REG_STATS_RESULT_FOR_GLOBAL_FIT					*
 *	Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT		*
 *	Cheney 2007-6-22 SHOULD_ADD_AUTOINIT_AND_LINEARCONSTRA_FOR_OCCODE_CALL_NLFIT*
 *  Iris 06/25/2007 v8.0648 SHOULD_ALWASY_SET_NLFIT_SETTINGS_AGAIN_AFTER_DEL_FIT_SESSION_POINTER*
 *  Iris 06/28/2007 SEPARATE_PFM_OP_CLASS										*
 *	Nicole 07/05/2007 v8.0655 REMOVE_SPACE_FOR_LOCATION_STRING					*
 *	Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG		*
 *	Cheney 2007-7-16 SHOULD_SHARE_CODE_BETWEEN_NLFITSPLITTER_AND_FITNL_ABOUT_AUTOINIT_AND_LINEAR_CONSTRAINT
 *	Cheney 2007-7-17 SHOULD_UPDATE_SPECI_INFO_WHEN_THEME_LOAD_OR_FUNC_CHANGE_IF_IS_SPECI_FIT
 *	CPY 7/17/2007 QA70-10010-P3 LAST_USED_THEME_WHEN_NOT_FOUND_BREAK_UPDATE_INPUT_TREE
 *	Cheney 2007-7-23 QA80-10090 MODIFY_STH_ABOUT_FDF_SAVING_AND_THEME_APPLY		*
 *	Cheney 2007-7-30 ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF						*
 *	Cheney 2007-7-31 CUSTOM_RANGE_NEED_CHECK_FROM_AND_TO						*
 *	Cheney 2007-8-1 CORRECT_LOGIC_OF_LOADING_THEME								*
 *	Cheney 2007-8-21 QA70-10256-P7 ADD_GLOBAL_FUC_FOR_UPDATE_CONTOUR_LEVEL		* 
 *	Cheney 2007-8-22 SHOULD_ADD_PARAMS_TO_TREE_WHEN_SEP_FIT						*
 *	Cheney 2007-8-29 FIX_STH_ABOUT_NLFIT_INIT_CODE								*
 *	Cheney 2007-8-30 QA70-10290-sug4 FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT	*
 *	Cheney 2007-9-6 FINDZ_NODE_SHOULD_PREPARED_WHEN_CHANGE_PARAM				*
 *	Cheney 2007-9-7 SHOULD_JUST_SET_SHOW_AS_FALSE_IF_NOT_CHECK_PLOT_FIT_CURVE	*
 *	Cheney/Arvin 2007-9-10 XOP_NEED_SUPPORT_PFM									*
 *	Cheney 2007-9-13 SUPPORT_FIT_MATRIX_FROM_GRAPH								*
 *	Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG	*
 *	Cheney 2007-9-21 QA70-10376 MATRIX_FTTING_SUPPORT_GET_MISSING_DATA_IN_REPORT*
 *	Cheney 2007-9-28 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_INTO_THEME_AS_MAX_SAID*
 *	Jasmine 09/30/07 QA70-10462 CHECK_REPLACE_USER_FITTING_FUNCTION_TO_GROUP_ONE*
 *	ML 10/1/2007 QA70-10268 MATRIX_FIT_FROM_CONTOUR_PLOT						*
 *	RVD 10/4/2007 v8.0715 qa7-10463 FIX_NLFIT_LIMIT_20_PARAMETERS				*
 *	Cheney 2007-10-8 QA70-10463 FIX_AUTOFIT_OGW_LAST_TWO_DATASET_CAN_NOT_WORK_WHEN_CHANGE_PARAM
 *	Jasmine 10/08/07 QA70-10490 RUNTIME_ERR_IF_INVALID_FUNC_SEL_IN_THEME		*
 *	Jasmine 10/12/07 QA70-10522 GET_REPLICA_PARAM_IF_NO_DERIVED_PARAM			*
 *	Jasmine 10/17/07 MISSING_SIGN_DIGITES										*
 *	Arvin 11/06/07 USE_WRONG_REG_STATS_RESULT_TO_CAL_CONF_PRED_BANDS_FOR_GLOBAL_FIT
 *	Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION								*
 *	Arvin 11/10/07 OPERATION_RUNNING_FROM_OC_SUPPORT_RECALCULATION				*
 *	Cheney 2007-11-12 QA70-10666 LCL_AND_UCL_WERE_WRONG_IN_NLFIT_IN_SOME_CASE	*
 *	Folger 11/15/07 FIT_REPORT_TABLE_LOCALIZATION								*
 *	ML 11/16/2007 QA70-10708 PROPER_VECTOR_OF_DOUBLES_TO_SUBNODES_CODE			*
 *	Hong 11/17/07 QA80-10499 FIX_NLFIT_LAST_USED_THEME_MISSING_SOMESETTINGS		*
 *	Hong 10/17/07 QA80-10499 NLFIT_LAST_USED_THEME_SHOULD_SAVE_ALL_SETTING		*
 *  Arvin 11/20/07 QA70-10708 CHECK_AND_CONVERT_DOUBLE_VALUES_FROM_GERMAN_TO_ENGLISH
 *	Arvin 11/27/07 WRONG_MASKED_AND_MISSING_TABLE_FOR_MULTI_DATASET				*
 *  Arvin 12/24/07 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_DATATYPE_ATTRIB_INTO_THEME
 *	Hong 12/26/07 QA80-10499 FIX_LOST_THEME_VALUES_WHEN_FROM_MRU_NOT_AUTO_INIT	*
 *	Arvin 12/25/07 MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL as cp said			*
 *	Folger QA70-10890 01/02/08 ADD_SCRIPT_AFTER_FITTING							*
 *	Arvin 01/03/08 SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS as cp said
 *	Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said					*
 *	Hong 01/23/08 QA80-10969 MOVE_PREVIEW_TO_HIGHER_LEVEL_IN_GUI				*
 *	Hong 01/24/08 QA80-10929 LT_NLFIT_SUPPORT_SOUURCE_GRAPHPAGE_PREVIEW			*
 *	Arvin 01/29/08 GENERATE_REPORT_FOR_LT_NLFit									*
 *	Folger 01/31/08 QA80-10929 CENTRALIZE_CODE_TO_GENERATE_NUMBER_OF_ITERATION	*
 *	Hong 02/01/08 v8.0798 FIX_CONTANTENATE_FIT_FAIL_WORK						*
 *	Folger 02/13/08 QA80-10929 ACCESS_FIT_STATUS_FROM_LT_TREE					*
 *	Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
 *	Jasmine 03/08/08 REUSE_FITSESSION_IN_PAW_OR_SPFW							*
 *	Arvin 03/11/08  QA70-11234 REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
 *	Arvin 03/12/08 REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT as CP said			*
 *	Folger 03/12/08 QA80-11244 SHOULD_NOT_OUTPUT_DATA_TO_MATRIX_FOR_XYZ_FITTING	*
 *	Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS		*
 *	Folger 03/18/08 QA80-11260 FIX_RUNTIME_ERROR_IN_MATRIX_FITTING_PREVIEW_AND_REPORT_GRAPH
 *	Folger 03/19/08 QA80-11281 FIX_XY_FIT_CURVE_NOT_SHOW_SOURCE_PLOTS			*
 *	Hong 03/19/08 8.0827 NLFIT_REMOVE_SETTINGS_ALLREADY_IN_FDF_FILE_FROM_THEME	*
 *	Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said	*
 *	Arvin 03/28/08 HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT							*
 *	Folger 04/01/08 QA80-11304 SHOW_SHARED_SIGN_IN_REPORT_SHEET_FOR_REPLICA_FITTING
 *  Iris 4/01/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME_AFTER_CLEAN_OUTPUT_GUI_CODES
 *	Folger 04/07/08 CENTRALIZE_CODE_OF_LOADING_FDF_FILE							*
 *	Sim 04-07-2008 QA80-11371 THEME_SAVING_OPTIONS								*
 *  Iris 4/16/2008 REMOVE_PARAM_TABLE_IF_IT_IS_EMPTY							*
 *	Jasmine 04/16/08 MOVE_UPDATE_MODEL_CODES_IN_FITNL_CLASS						*
 *	Folger 04/17/08 QA80-11434 TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
 *	Folger 04/18/08 SHOULD_SET_DEFAULT_TO_BOTH_AS_PA_ACCORDING_TO_MAX			*
 *  Iris 4/21/2008 SHOW_NLFIT1_AS_SHEET_NAME_IN_XYZFIT							*
 *	Hong 04/21/08 v8.0846c FIX_REPLICA_FIT_REPORT_FAIL_GET_CORRECT_DATASET_NAME	*
 *	Folger 04/22/08 CLEAN_UP_MEMORY_ALLOCATION_IN_FIT_SESSION					*
 *  Iris 4/22/2008 ALWAYS_SHOW_0_FOR_WEIGHT_ARGUMENTS							*
 *	Hong 13/05/08 QA80-11541 ADD_FOOTNODE_IF_UNCHECK_USE_REDUCED_CHISQR			*
 *	Jasmine 05/27/08 QA80-11234 v8.0871 USE_GETFIT_TO_GENERATE_XY_ACCORDING_NUM_OF_POINT
 *	Hong 05/30/08 v8.0874 FIX_FIT_CONVERGE_FAIL_CORRECTLY_RESTORE_SRC_GRAPH_LEGEND
 *	Hong 05/30/08 QA80-11632 FIX_SURFACE_FIT_REPORT_FIT_CURVE_FAIL_CORRECT_RESCALE
 *	Folger 05/30/08 QA80-11632 HIDE_SOURCE_PLOT_RELATED_NODE_FOR_3D_FITTING		*
 *	Max 6/4/08 v8.0877 THIS_BRANCH_SHOULD_CLOSE_BY_DEFAULT						*
 *	YuI 06/06/08 QA70-11619 MORE_CLEAR_WORKSHEET_PROBLEM						*
 *	Hong 06/10/08 v8.0881 FIX_FLAYOUT_THEME_LOSE_RESULT_FOR_FIND_X_FROM_Y		*
 *	Folger 06/20/08 QA80-11749 REMOVE_UNWANTED_SUBNODES_FOR_GENERAL_XY_FITTING	*
 *	Hong 06/23/08 QA80-10536 FIX_ABNORMAL_BOOK_SHOULD_NOT_OUTPUT_TO_SOURCE		*
 *	Folger 08/15/08 QA80-12034 FIX_PARAMETER_FIXED_MISSING_IN_RECALCULATION		*
 *	Folger 08/18/08 QA80-12036 FIX_BOUNDS_MISSING_IN_REPORT_SHEET_FOR_REPLICA_FIT
 *  Iris 8/15/2008 QA80-12025 TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL		*
 *	Folger 08/18/08 QA80-12040 FIX_BOUNDS_OUPUT_FOR_MULTIPLE_SETS_FIT			*
 *	Folger 08/19/08 QA80-12042 FIX_PARAMETERS_VALUES_AND_BOUNDS_WRONG_FOR_INDEPENDENT_FIT_CONSOLIDATED_REPORT
 *	Jasmine 08/13/08 QA80-12009 PARAM_HAS_SAME_NOTATION_AS_75_FOR_MULTI_DS_AND_REPLICA_AND_PEAK
 *	Folger 08/25/08 ADD_CONTEXT_HELP_FOR_NLFIT_THEME_SETTINGS_DIALOG			*
 *	Sim 09-05-2008 QA80-12151 NLFIT_TOO_SLOW_TO_OPEN							*
 *	Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION							*
 *	Sim 09-10-2008 NLFIT_LABTALK_TREE_ACCESS									*
 *	Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT					*
 *	Sophy 9/24/2008 NEW_PA if use existing session, shall not destroy it		*
 *	Hong 09/27/08 FIX_LT_TREE_FAIL_GET_SESSION_PTR								*
 *	Hong 09/28/08 QA80-12305 v8.0949 FIX_FIND_Z_FROM_XY_FAIL_IF_HAVE_DERIVED_PARAMS
 *	Hong 10/10/08 QA80-11014 FIX_AFTER_FIT_NOT_USED_IF_SAVE_IN_FALY_OUT_THEME	*
 *	Sophy 10/14/2008 QA80-12370 FIX_RUNTIME_IN_2ND_TIME_RECALCULATE_MATRIX_FIT_ANALYSIS_TEMPLATE
 *	Folger 10/14/08 WRONG_NLF_CURVES_CLASS_IN_PA_MAKES_WRONG_REPORT				*
 *	Sophy 10/17/2008 FIX_MISSING_MASKED_DATA_STATE_ERROR_ON_RECALCULATE			*
 *	Sophy 10/17/2008 FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT				*
 *	Sim 10-20-2008 FIX_NLFIT_LAST_USED_THEME_FAILED_TO_SAVE_FIXED_VALUE			*
 *	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*
 *	Hong 10/17/08 QA80-10624 NLFIT_SUPPORT_FIT_SWAPPED_POLAR_PLOT				*
 *	Folger 10/24/08 v8.0960 MISSING_DATA_RULES_ON_VALUE_CHANGE_EVENT_CAUSE_ERROR_MESSAGE_DISAPPEAR_IN_NLFIT_DIALOG
 *	Sophy 10/27/2008 USE_NLFCURVES_TO_PLOT_IN_REPORT_GRAPH						*
 *	Hong 11/01/08 QA80-12465 FIX_ASSAYS_OGW_FAIL_RECALCULATE_WITH_FUNCTION_CHANGED_TWICE
 *	Sophy 11/4/2008 RESET_FDF_ON_INIT_SESSION_LEAD_TO_RESET_AUTORUNINITPARAMS	*
 *	Folger 11/05/08 QA80-12525 v8.0965 PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
 *	Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
 *	Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET	*
 *	Sophy 11/19/2008 v8.975b QA80-12613-P1 KEEP_OLD_LOGIC_SHOULD_FIT_XY_BEFORE_FIT_Z
 *	Sophy 11/21/2008 v8.976 QA80-12591-P3 ADD_ERRMSG_WHEN_FITCURVE_XDATATYPE_IS_LOG_WITH_NEGATIVE_INPUT
 *	Sophy 11/24/2008 v8.978c CHECK_SET_XDATATYPE_VALUE_ON_APPLY_THEME			*
 *	Folger 11/28/08 v8.0980 CLEAN_UP_REPLICA_FITTING_JUDGEMENT					*
 *	Sophy 11/28/2008 v8.0980d QA80-12591-P5 ADD_AUTO_SUPPORT_FOR_LR_AND_PR_FITCURVE_XDATATYPE
 *	Folger 11/28/08 v8.0980 USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
 *	Folger 12/01/08 v8.0981 MORE_ON_USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
 *	Sophy 12/11/2008 v8.984d NLFIT_XDATATYPE_SHOULD_BE_SOURCE_GRAPH_SCALE_TYPE_AS_LR_WHEN_DATA_FROM_GRAPH
 *	Folger 12/11/08 QA80-12766 v8.0985 SIGNIFICANT_DIGITS_FAILS_TO_APPLY_TO_NLSF_FITTING_REPORT
 *	Jack 12/19/2008 QA80-12329 MULTI_INDEP_DEPS_BAND_CALCULATION				*
 *	Folger 12/22/08 QA80-12766-P2 v8.0990 SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
 *	Sophy 12/23/2008 v8.0990 QA80-12832 SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
 *	Folger 12/23/08 v8.0990 FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
 *	Sophy 12/29/2008 v8.0991b QA80-12832 SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS
 *	Folger 01/06/09 QA80-12878-P1 v8.0993e NLFIT_FAILS_TO_GET_ALL_DATAPLOTS_FROM_GRAPH
 *	Folger 01/19/09 SUPPORT_MULTI_SETS_FOR_MULTI_DEPS_INDEPS_MAKE_RESET_ALL_GRAPHS_BROKEN
 *	Sophy 1/19/2009 v8.0960 FIX_USE_SAME_WEIGHT_METHOD_FOR_ALL_DATASETS			*
 *	Kyle 01/23/2009 CHECK_ERROR_IF_THE_SELECTED_FUNCTION_IS_EMPTY				*
 *	Kyle 01/24/2009 NO_NEED_TO_CALC_HIST_PLOT_DATA_IF_CREATE_REPORT_GRAPH_FALSE	*
 *	YuI 01/26/09 QA70-13023 MATRIX_FIT_IN_IMAGE_FORM_PROBLEMS					*
 *	Kyle 02/01/2009 QA80-13020 CHECK_ERROR_IF_MATRIX_DATA_IS_IMAGE				*
 *	Kyle 02/06/2009 CHECK_IF_DATA_FROM_WORKBOOK_WHEN_FIT_TYPE_IS_MATRIX			*
 *	Sophy 2/16/2009 v8.0979b QA80-13121 CUSTOM_LEGEND_NEED_SIMPLER_LINE_SUPPORT	*
 *	Folger 02/24/09 ALWAYS_GET_FIT_RESULT_STATS_REGARDLESS_OF_OUTPUT_OF_STATS_TABLE
 *	Folger 02/26/09 QA80-10626 FAILS_TO_SHOW_REPLICA_INFO_IN_STATS_TABLE_WHEN_REPLICA_NUMBER_IS_ZERO
 *	Sophy 3/3/2009 v8.0990 FIX_RUNTIME_ERROR_WHEN_USE_CHEBYSHEV2D_AS_FUNCTION_IN_MATRIX_FITTING
 *	Folger 03/03/09 PARAMETER_STATS_INFO_MISSING_IN_FOOTNOTE_WHEN_SHARING		*
 *	Folger 03/10/09 INCORRECT_INPUT_DATA_DISPLAY_IN_NLFIT_LT_TREE				*
 *	Hong 03/11/09 FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO		*
 *	Folger 03/24/09 QA80-13331-P1 CUSTOMIZED_OUTPUT_COLUMN_LONGNAME_FORMAT_SUPPORT
 *	Hong 03/25/09 QA80-12551 RESET_PLOT_ROW_RANGE_IF_USER_UPDATE_INPUT_DATARANGE_WHEN_CHANGE_PARAMETER
 *	Folger 04/03/09 OPEN_NLFIT_WITH_MULTI_SETS_PLUS_MULTI_INDEPS_DEPS_FROM_THEME_MISSING_ERROR_MSG
 *	Sim 04-02-2009 QA80-13403 ADD_INDIVIDUAL_OP_VERSION_FOR_CONVERT_GUI_TREE	*
 *  Iris 4/15/2009 FIX_NO_DERIVED_PARAM_INFO_IN_PARAM_TABLE_FOOTNOTE_IN_PA		*
 *  Iris 4/29/2009 QA80-12017 NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ
 *	Folger 05/27/09 QA80-13669 FIT_COMPARE_MODELS_CAUSE_ORIGIN_CRASH_UNDER_SPECIFIC_CIRCUMSTANCES
 *  Iris 6/11/2009 QA80-13776 FIX_XYZFIT_APPEND_RESIDUAL_DATA_AFTER_RECALCULATE	*
 *  Iris 6/16/2009 QA80-13776-P2 FIX_FAIL_CREATE_X_Y_COL_IN_RESIDUAL_DATA_TABLE	*
 *	Folger 07/01/09 QA80-13774-P1 COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
 *	Hong 06/07/09 QA80-13865 FIX_INDPES_DEPS_FUNC_CONTAIN_REDUNDENT_MISSING_ROW_IN_REPORT_TABLE
 *	Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
 *	Sophy 7/8/2009 v8.1060 CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH			*
 *	Sophy 7/22/2009 v8.1073 NANOSIZER_NEED_TO_GET_ORIGINAL_INPUTDATA			*
 *  Iris 7/23/2009 QA80-14000-P1 2D_FIT_NOT_PLOT_RESIDUAL_CAUSE_FIT_DATA_ERROR	*
 *  Iris 7/23/2009 QA80-14000-P2 2D_FIT_FITTED_DATA_ALWAYS_REPORT_EVEN_UNCHECKED *
 *  Iris 7/29/2009 QA80-14029 FAIL_CHANGE_INNER_OUTTER_RESIDUAL_LIMIT_ON_CHANGE_PARAM
 *	Folger 07/31/09 QA80-13998 DESTROY_OPERATION_AND_ALL_RELATED_OUTPUTS		*
 *	Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT				*
 *	Jasmine 09/01/09 QA81-14165 DISPLAY_BUT_DISABLE_PRO_OPTION_IN_REG_VERSION	*
 *	Kyle 09/03/2009 QA80-14077-P1 Unit_IS_ONLY_NEEDED_FOR_NLSF					*
 *	Hong 09/04/09 QA80-14258 HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING	*
 *  Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE*
 *	Folger 09/25/09 LINEAR_CONSTRAINTS_NOT_WORK_WHEN_RUN_PA_IN_SCRIPT_MODE		*
 *  Iris 10/11/2009 FIX_NLFIT_STILL_REPORT_EMPTY_ANOVA_TABLE_IF_NOT_CHECKED_ON_GUI
 *  Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL					*
 *  Iris 11/03/2009 QA81-14576 OUTPUT_FIT_NOT_CONVERGED_INFO_TO_SCRIPT_WND		*
 *  Iris 11/03/2009 QA81-14576 SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE *
 *	Folger 11/05/09 QA81-14595-P1 NLFIT_SHOULD_NOT_LOAD_GAUSS_WHEN_DO_ANALYSIS_WITH_THEME_WHICH_HAS_NO_FUNCTION
 *  Iris 12/08/2009 FIX_GIBBERISH_MESSAGE_IN_SCRIPT_WND_IN_J_BUILD				*
 *	Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
 *	Hong 01/04/10 QA80-14907-P1 TAKE_BACK_SCRIPT_BEFORE_FITTING					*
 *	Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU				*
 *	Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN			*
 *	Sophy 1/15/2010 QA80-14832 QUICKFIT_SWITCH_TO_NLFIT_SHOULD_USE_EXISTING_DATAMARKER_WHEN_SELECT_RANGE
 *	Hong 01/12/10 QA80-14948-P2 FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT	*
 *	Sophy 2/22/2010 QA80-14832 QUICKFIT_SWITCH_TO_NLFIT_SHOULD_USE_EXISTING_DATAMARKER_WHEN_SELECT_RANGE
 *	Folger 03/19/10 QA81-15218 ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
 *	Folger 03/24/10 QA81-15218-P2 SHOULD_TAKE_CARE_OF_ERROR_WHEN_SWITCH_TO_LINEAR_FIT
 *	Jasmine 05/24/10 SRVC-12 ALLOW_SAME_AS_INPUT_FOR_ALL_SURFACE_FIT			*
 *	Folger 08/17/10 ORG-824-P1 WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING		*
 *	Folger 09/16/2010 ORG-1057-P1 MATRIX_FITTING_FAILED_TO_CLOSE_DIALOG_AFTER_FIT_WITH_EMPTY_DATA
 *------------------------------------------------------------------------------*/

#include <origin.h>

#pragma labtalk(0) //CPY 12/6/06 QA70-12736 LT_NEED_MORE_CNTRL_ON_ALLOWING_OC_FUNCS

#include <event_utils.h>
#include <report_utils.h>
#include "FitCommon.h"
#include "nlsf_utils.h" ///Leo 2005-12-06 MOVE_NLSF_FUNTIONS_TO_NSLF_UTILS
///Arvin 03/03/08 QA-11206 CLEAN_PREVIEW_CTRL_CLASSES
//#include "NLFitSession.h"
///Arvin 03/14/08 SPLIT_SURFACE_FIT_SESSION_FROM_PREVIEW_CTRL	
//#include "SurfaceFitPreviewCtrl.h"
// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
//#include "SurfaceFitSession.h"
#include "NLFitSession.h"
/// end FITNL_USING_NEW_NLFSESSION
///end 	SPLIT_SURFACE_FIT_SESSION_FROM_PREVIEW_CTRL
///end CLEAN_PREVIEW_CTRL_CLASSES

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

//#include "FitCommon.h"
#include "FitNL.h"

//#include "NLFitting.h"
/// TD 9-2-06 QA70-9012 DYNACONTROL_MULTILINEEDIT_BUTTON
#include "Odlg8.h"
/// end DYNACONTROL_MULTILINEEDIT_BUTTON

#include <o8dlg.h>		//------ Folger 08/25/08 ADD_CONTEXT_HELP_FOR_NLFIT_THEME_SETTINGS_DIALOG
	

#define	_DMSG(_msg)

#define NLF_CODES_ROW_MINMAX	"3-20"

//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
enum
{
	NLFIT_XYZ_SOURCE_PLOT,
	NLFIT_XYZ_RESULT_PLOT,
};
//------

//#define STR_XYMAP_ATTRIB  		"XYMap" ///Arvin 11/20/06 SURFACE_FIT_SET_XY_MAP

///Arvin 03/28/08 HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT
//#define		HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT
///END HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT
///Arvin 01/09/06 FIND_Z_FROM_XY by Iris' suggestion
//Declare two function as follow, their body are in wksOperation.c
//bool operation_output_findxy_book_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg);
bool operation_output_findxy_book_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg);
///Sophy 5/28/2008 QA80-10934-P8 FIX_GIVE_DEFAULT_BOOK_SHEET_NAME_TO_PARTIAL_LEVERAGE_VALUES_NODE
//bool operation_output_sheet_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg);
bool operation_output_findxy_sheet_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg);
///end FIX_GIVE_DEFAULT_BOOK_SHEET_NAME_TO_PARTIAL_LEVERAGE_VALUES_NODE
///----

///Arvin 12/25/07 MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL as cp said
//Just declare function
bool operation_output_findxy_branch_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg);
///end MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL

/// Iris 4/01/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME_AFTER_CLEAN_OUTPUT_GUI_CODES
//bool operation_output_book_sheet_name_changed(TreeNode& tr, int nRow, int nType, Dialog& Dlg);
bool operation_output_book_sheet_name_changed(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& theDlg);
///end ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME_AFTER_CLEAN_OUTPUT_GUI_CODES

///Cheney 2007-4-17 FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED
#define STR_FOOTNOTE_SOME_PARAMS_FIXED  "\r\n" + _L("Some parameter values were fixed.")
///end FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED

///Joseph 04/02/07 ADD_NLSF_ERR_MSG_EVENT
//check whether the confidence is enable. if enable and err, show errmsg, else don't show errmsg.
static bool _check_conf_enable(const TreeNode trConf)
{
	int nEnable;
	if(trConf.GetAttribute(STR_ENABLE_ATTRIB, nEnable))
		return nEnable;
	else
		return false;
}

///Arvin 11/20/07 QA70-10708 CHECK_AND_CONVERT_DOUBLE_VALUES_FROM_GERMAN_TO_ENGLISH
#define		CHAR_GERMAN_RADIX_POINT		','
#define		CHAR_ENGLISH_RADIX_POINT	'.'
///END CHECK_AND_CONVERT_DOUBLE_VALUES_FROM_GERMAN_TO_ENGLISH

///Joseph 05/04/07 SHOW_ERR_MSG_ON_NLSF_INIT

enum{
	CONSOLIDATE_REPORT,
	SEPERATE_REPORT,
	CONCATENATE_FIT,
	GLOBAL_FIT
};
static bool _is_independent_mode(int nMode)
{
	if(SEPERATE_REPORT == nMode || CONSOLIDATE_REPORT == nMode )
		return true;
	
	return false;
}
///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
//static bool _is_multi_dataset(const TreeNode& trNode)
static bool _is_multi_dataset(const TreeNode& trNode, const bool bIsOnChanged)
///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
{
	string strDataRules;
	int nTotalNumData;
	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
	/*
	if(trNode.GetAttribute("DataRules", strDataRules))
	{
		DataRange dr;
		dr.Create();
		dr.SetTree(trNode.DataSelection.InputData);
		int nTotalNumData = 0;
		if(dr)
		{
			int		numSubData = 0;
			nTotalNumData = dr.GetNumData((DWORD)(atoi(strDataRules)), NULL, NULL, NULL, &numSubData);
		}
		
		if(nTotalNumData > 1)
			return true;
	}
	*/
	TreeNode trInput;
	if(bIsOnChanged)
	{
		//------ Folger 10/24/08 v8.0960 MISSING_DATA_RULES_ON_VALUE_CHANGE_EVENT_CAUSE_ERROR_MESSAGE_DISAPPEAR_IN_NLFIT_DIALOG
		//trNode.GetAttribute("DataRules", strDataRules);
		//------
		trInput = trNode.DataSelection.InputData;
	}
	else
	{
		trInput = trNode.InputData;
		//------ Folger 10/24/08 v8.0960 MISSING_DATA_RULES_ON_VALUE_CHANGE_EVENT_CAUSE_ERROR_MESSAGE_DISAPPEAR_IN_NLFIT_DIALOG
		//if(! trInput)
			//return false;
		//trInput.GetAttribute("DataRules", strDataRules);
		//------ End MISSING_DATA_RULES_ON_VALUE_CHANGE_EVENT_CAUSE_ERROR_MESSAGE_DISAPPEAR_IN_NLFIT_DIALOG
	}
	
	//------ Folger 10/24/08 v8.0960 MISSING_DATA_RULES_ON_VALUE_CHANGE_EVENT_CAUSE_ERROR_MESSAGE_DISAPPEAR_IN_NLFIT_DIALOG
	if(! trInput)
		return false;
	trInput.GetAttribute("DataRules", strDataRules);
	//------ End MISSING_DATA_RULES_ON_VALUE_CHANGE_EVENT_CAUSE_ERROR_MESSAGE_DISAPPEAR_IN_NLFIT_DIALOG
		
	if(! strDataRules.IsEmpty())
	{
		DataRange dr;
		dr.Create();
		
		dr.SetTree(trInput);
		int nTotalNumData = 0;
		if(dr)
		{
			int		numSubData = 0;
			nTotalNumData = dr.GetNumData((DWORD)(atoi(strDataRules)), NULL, NULL, NULL, &numSubData);
		}
		
		if(nTotalNumData > 1)
			return true;
	}
	///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
	
	return false;
}
///End SHOW_ERR_MSG_ON_NLSF_INIT

///Jasmine 08/28/09 CENTRALIZE_FIND_PEAK_METHOD_COMBO
typedef	bool (*FUNC_IS_FIND_PEAK_METHOD_AVAILABLE)(int nMethod);
///End CENTRALIZE_FIND_PEAK_METHOD_COMBO

static int _nlsf_event1(TreeNode& tr, int nRow, int nEvent, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& getNCountainer, string& strAux, string& strErrMsg)
{
	DECLARE_BUTTON_ENABLES   //support more buttons enable/disable
	int nErr;
	if(!tr)
		return false;
	
	//should not decide wether there are errmsg by the errmsg string is empty.
	bool bNoErrMsg = true; 	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
	
	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
	///Kyle 01/23/2009 CHECK_ERROR_IF_THE_SELECTED_FUNCTION_IS_EMPTY, maybe it should rename to bIsGUITree
	//bool bIsOnChanged = (GETNE_ON_VALUE_CHANGE == nEvent );
	bool bIsOnChanged = tr.OpGUI ? true : false;		// actually it's used to consider the tree structure, maybe it should be renamed to bIsGUITree, need to clean
	///End CHECK_ERROR_IF_THE_SELECTED_FUNCTION_IS_EMPTY
	
	///Joseph 06/21/07 v8.0645 NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
	//on click some buttons, need to support
	TreeNode trInput;
	///Cheney 2007-8-27 IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
	//if(bIsOnChanged)
	if(bIsOnChanged || GETNE_ON_CUSTOM_BUTTON1 == nEvent)
	///end IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
		trInput = tr.DataSelection.InputData;
	else
		trInput = tr.InputData;
	///End NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
	
	//if(GETNE_ON_VALUE_CHANGE == nEvent)
	///Cheney 2007-7-6 SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	//if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent)
	if(GETNE_ON_VALUE_CHANGE == nEvent  || GETNE_ON_INIT == nEvent || GETNE_ON_THEME == nEvent)
	///end SHOULD_CHECK_ERR_WHEN_THEME_CHANGE_ALSO
	///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
	{
		//For Fit Curve Tab
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//TreeNode trFittedCurve = tr.FittedCurve;
		//TreeNode trNum = trFittedCurve.Graph1.XDataType.N;
		//TreeNode trRangeMargin = trFittedCurve.Graph1.XDataType.RangeMargin;
		//TreeNode trConfidence = trFittedCurve.Graph1.Confidence;
		///Cheney 2007-7-31 CUSTOM_RANGE_NEED_CHECK_FROM_AND_TO
		//TreeNode trNum, trRangeMargin, trConfidence;
		TreeNode trNum, trRangeMargin, trConfidence, trXDataType;
		///end CUSTOM_RANGE_NEED_CHECK_FROM_AND_TO
		if(bIsOnChanged)
		{
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE
			TreeNode trFittedCurve = tr.FittedCurve;
#else
			TreeNode trFittedCurve = tr.OpGUI.Plots;
#endif
			
			trNum = trFittedCurve.Graph1.XDataType.N;
			
			trRangeMargin = trFittedCurve.Graph1.XDataType.RangeMargin;
			
			trConfidence = trFittedCurve.Graph1.Confidence;
			
			trXDataType = trFittedCurve.Graph1.XDataType; ///Cheney 2007-7-31 CUSTOM_RANGE_NEED_CHECK_FROM_AND_TO
		}
		else
		{
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE
			TreeNode trFittedCurve = tr.Graph1;
#else
			TreeNode trFittedCurve = tr.Plots.Graph1;
			ASSERT(trFittedCurve);
#endif

			trNum = trFittedCurve.XDataType.N;
			
			trRangeMargin = trFittedCurve.XDataType.RangeMargin;
			
			trConfidence = trFittedCurve.Confidence;
			
			trXDataType = trFittedCurve.XDataType; ///Cheney 2007-7-31 CUSTOM_RANGE_NEED_CHECK_FROM_AND_TO
		}
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE		
		
		///Joseph 05/04/07 SHOW_ERR_MSG_ON_NLSF_INIT	
		//if multi dataset, and choose indepedent mode, should show warning message by Max's suggestion.
		///Joseph 06/21/07 v8.0645 NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
		//int nUseValue;
		/*
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//TreeNode trInput = tr.DataSelection.InputData;
		TreeNode trInput;
		if(bIsOnChanged)
			
			trInput = tr.DataSelection.InputData;
		else
			trInput = tr.InputData;	
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		*/
		///End NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
		
		///Kyle 01/23/2009 CHECK_ERROR_IF_THE_SELECTED_FUNCTION_IS_EMPTY
		TreeNode trFunctionSelection = tr.FunctionSelection;
		if(trFunctionSelection)
		{
			TreeNode trFuncList = trFunctionSelection.FunctionList;
			if(trFuncList && 0 == strlen(trFuncList.strVal))
			{
				strErrMsg = CER_FUNCTION_EMPTY;		//"Function is empty. Please specify it to continue."
				bNoErrMsg = false;
			}
		}
		///End CHECK_ERROR_IF_THE_SELECTED_FUNCTION_IS_EMPTY
		
		///Cheney 2007-5-16 NLFIT_SHOULD_CHECK_IF_EXIST_EMPTY_SUBRANGE
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() && (!okutil_is_fitter_data_node_ready(&trInput)) )
		if(bNoErrMsg && trInput && (!okutil_is_fitter_data_node_ready(&trInput)) )
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		{
			strErrMsg = CER_INPUT_RANGE_EMPTY;
			
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
		///end NLFIT_SHOULD_CHECK_IF_EXIST_EMPTY_SUBRANGE		
		
		///Cheney 2007-7-11 SHOULD_CHECK_DATARANGE_IF_IS_VALID
		if(bNoErrMsg && trInput)
		{
			int nFitType = NLFIT_GENERAL_XY_FITTING;
			if(trInput.GetAttribute( STR_ATTRIB_FIT_TYPE, nFitType ))
			{
				DataRange dr;
				if( (nFitType == NLFIT_GENERAL_XY_FITTING && !nlsf_init_datarange(dr, trInput))
					|| (nFitType != NLFIT_GENERAL_XY_FITTING && !dr.Create(trInput, true)) )
				{	
					strErrMsg = XFERR_INVALID_RANGE;
					bNoErrMsg = false;
				}
				///Kyle 02/01/2009 QA80-13020 CHECK_ERROR_IF_MATRIX_DATA_IS_IMAGE
				if(bNoErrMsg && nFitType == NLFIT_MATRIX_FITTING && nlsf_init_datarange(dr, trInput))
				{
					///Kyle 02/06/2009 CHECK_IF_DATA_FROM_WORKBOOK_WHEN_FIT_TYPE_IS_MATRIX
					//MatrixLayer ml;
					//int c1, c2;
					//dr.GetRange(ml, c1, c2);
					//MatrixObject mo(ml, c1);
					//if(mo && ml.HasImage() && !mo.HasData())
					//{
						//strErrMsg = NLSF_ERR_INPUT_IMAGE;//"Please convert the input image to numeric data before fitting. "
						//bNoErrMsg = false;
					//}
					int c1, c2;
					Datasheet ds;
					dr.GetRange(ds, c1, c2);
					MatrixLayer ml(ds);
					if(ml)
					{
						MatrixObject mo(ml, c1);
						if(mo && ml.HasImage() && !mo.HasData())
						{
							strErrMsg = NLSF_ERR_INPUT_IMAGE;//"Please convert the input image to numeric data before fitting. "
							bNoErrMsg = false;
						}
					}
					else
					{
						strErrMsg = XFERR_INVALID_RANGE;
						bNoErrMsg = false;
					}
					///End CHECK_IF_DATA_FROM_WORKBOOK_WHEN_FIT_TYPE_IS_MATRIX
				}
				///End CHECK_ERROR_IF_MATRIX_DATA_IS_IMAGE
			}
		}
		///end SHOULD_CHECK_DATARANGE_IF_IS_VALID		
		
		//Points should be positive integer.
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() &&  (! check_is_positive_integer(trNum)))
		if(bNoErrMsg && trNum &&  (! check_is_positive_integer(trNum)))
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		{
			strErrMsg = CER_INVALID_POSITIVE_INTEGER;
			strErrMsg += ":";
			strErrMsg += STR_POINTS_NUM;
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
		
		//Range Margin(%). (It should be inside [0,100].)
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() && (! check_margin_value(trRangeMargin)))
		if(bNoErrMsg && trRangeMargin && (! check_margin_value(trRangeMargin)))
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		{
			strErrMsg = CER_INVALID_RANGE_MARGIN;
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
		
		///Cheney 2007-7-31 CUSTOM_RANGE_NEED_CHECK_FROM_AND_TO
		if(bNoErrMsg && trXDataType.Min && trXDataType.Max && trXDataType.Range
			&& trXDataType.Range.nVal == FIT_CURVE_CUSTOM && trXDataType.Min.dVal > trXDataType.Max.dVal)
		{
			strErrMsg = CER_INVALID_CUSTOM_RANGE_SETTING;
			bNoErrMsg = false;
		}
		///end CUSTOM_RANGE_NEED_CHECK_FROM_AND_TO
		
		//Confidence Level for Curves(%). (It should be inside (0,100).)
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() && !check_conf_level(trConfidence) && _check_conf_enable(trConfidence))
		if(bNoErrMsg && trConfidence && !check_conf_level(trConfidence) && _check_conf_enable(trConfidence))
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE 
		{
			strErrMsg = CER_CONF_LEVS;
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
	
		//For Advanced tab 
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		/*
		TreeNode trOpGUI = tr.OpGUI; 
		TreeNode trMaxNum = trOpGUI.Fit.Iterations.MaxNum;
		TreeNode trToler = trOpGUI.Fit.Iterations.Tolerance;
		TreeNode trConf = trOpGUI.Quantities.Parameters.Confidence;
		TreeNode trGraphNumCols = trOpGUI.Output.PlotSettings.GraphNumCols;
		*/
		TreeNode trMaxNum, trToler, trConf, trGraphNumCols;
		if(bIsOnChanged)
		{	
			TreeNode trOpGUI = tr.OpGUI; 
			trMaxNum = trOpGUI.Fit.Iterations.MaxNum;
			trToler = trOpGUI.Fit.Iterations.Tolerance;
			trConf = trOpGUI.Quantities.Parameters.Confidence;
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE
			trGraphNumCols = tr.OutputResults.Output.PlotSettings.GraphNumCols;
#else
			trGraphNumCols = OP_GUI_GRAPH_ARRANGEMENT_NODE(tr.OpGUI).GraphNumCols; // is right ??
			ASSERT(trGraphNumCols);
#endif 
		}
		else
		{
			trMaxNum = tr.Fit.Iterations.MaxNum;
		
			trToler = tr.Fit.Iterations.Tolerance;
			
			trConf = tr.Quantities.Parameters.Confidence;
				
#ifndef OP_DLG_TOTALLY_NEW_STRUCTURE
			trGraphNumCols = tr.Output.PlotSettings.GraphNumCols;
#else
			trGraphNumCols = OP_GUI_GRAPH_ARRANGEMENT_NODE(tr.OpGUI).GraphNumCols;
			ASSERT(trGraphNumCols);
#endif 
		}
		///End 	NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		
		//Max Num Iter. (it should be positive integer.)
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() && !check_is_positive_integer(trMaxNum) )
		if(bNoErrMsg && trMaxNum && !check_is_positive_integer(trMaxNum) )
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		{
			strErrMsg = CER_INVALID_POSITIVE_INTEGER;
			strErrMsg += ":";
			strErrMsg += STR_MAX_INTR_NUM;
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
		
		//Tolerance. (it should be >0.)
		//--- Iris 06/04/2007 Max said Tolerance can be 0
		//if(strErrMsg.IsEmpty() && trToler.dVal <= 0)
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() && trToler.dVal < 0)
		if(bNoErrMsg && trToler && trToler.dVal < 0)
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//---
		{
			strErrMsg = CER_INVALID_TOLERANCE;
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
		
		//Confidence Level for Parameters (%). (It should be inside (0,100).)
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() && !check_conf_level(trConf) && _check_conf_enable(trConf))
		if(bNoErrMsg && trConf && !check_conf_level(trConf) && _check_conf_enable(trConf))
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		{
			strErrMsg = CER_CONF_LEVS;
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
		
		//Arrange Graphs into Cloumns. (it should be positive integer.)
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(strErrMsg.IsEmpty() && (! check_is_positive_integer(trGraphNumCols)))
		if(bNoErrMsg && trGraphNumCols && (! check_is_positive_integer(trGraphNumCols)))
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		{
			strErrMsg = CER_INVALID_POSITIVE_INTEGER;
			strErrMsg += ":";
			strErrMsg += STR_GRAPH_INTO_NUM_COLS;
			bNoErrMsg = false;	///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		}
		
		///Sophy 4/11/2008 CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT
		if( bNoErrMsg )
		{
			string strRet = "";
			int nErr = check_report_book_curve_book( tr ,strRet);
			if(CER_NO_ERROR != nErr)
			{
				strErrMsg = nErr;
				strErrMsg += ":" + strRet + " ";
				bNoErrMsg = false;
			}
		}		
		///end CHECK_REPORT_DATA_BOOK_NAME_DIFFERENT
		///Sophy 11/21/2008 v8.976 QA80-12591-P3 ADD_ERRMSG_WHEN_FITCURVE_XDATATYPE_IS_LOG_WITH_NEGATIVE_INPUT
		if( bNoErrMsg )
		{
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//int nErr = check_input_logx_datatype(trInput,(bIsOnChanged ? tr.FittedCurve.Graph1.XDataType : tr.Graph1.XDataType));
			int nErr = check_input_logx_datatype(trInput, trXDataType);
			///end OP_DLG_NEW_STRUCTURE
			if(CER_NO_ERROR != nErr )
			{
				strErrMsg = nErr;
				bNoErrMsg = false;
			}
		}
		
		if( bNoErrMsg )
		{
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//int nErr = check_logx_customize_x_range( (bIsOnChanged ? tr.FittedCurve.Graph1.XDataType : tr.Graph1.XDataType) );
			int nErr = check_logx_customize_x_range( trXDataType );
			///end OP_DLG_NEW_STRUCTURE
			if( CER_NO_ERROR != nErr )
			{
				strErrMsg = nErr;
				bNoErrMsg = false;
			}
		}
		///end ADD_ERRMSG_WHEN_FITCURVE_XDATATYPE_IS_LOG_WITH_NEGATIVE_INPUT

		///Jasmine 09/01/09 QA81-14165 DISPLAY_BUT_DISABLE_PRO_OPTION_IN_REG_VERSION
		if( bNoErrMsg && bIsOnChanged)
		{
			TreeNode trInitMethod = tr.OpGUI.Replica.ReplicaInitParam.InitMethod;
			int nMethod;
			trInitMethod.GetAttribute(STR_CHANGED_ATTRIB, nMethod);
			FUNC_IS_FIND_PEAK_METHOD_AVAILABLE	pfn = Project.FindFunction("is_find_peak_method_available", "OriginLab\\curve_utils.c", true);
			if( pfn && !pfn(nMethod) )
			{
				string strList 	= get_node_combo_str(trInitMethod);
				string strPro	= strList.GetToken(nMethod, '|');
				trInitMethod.RemoveAttribute(STR_CHANGED_ATTRIB);
				strErrMsg = XFERR_PRO_OPTION_WARNNING_MSG;
				strErrMsg += ":" + strPro;
				bNoErrMsg = false;
			}				

		}
		///End DISPLAY_BUT_DISABLE_PRO_OPTION_IN_REG_VERSION
		
		if (! bNoErrMsg)
		{
			bOKEnable = false;
			return false;
		}
	///Joseph 06/21/07 v8.0645 NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
	}
	
	if( GETNE_ON_CUSTOM_BUTTON1 == nEvent)
	{
		/// Iris 07/03/2007 v8.0654 SHOW_PARAMINITSECCEED_NODE_IN_SETTINGS_TAB_LEFT_SIDE
		/*
		TreeNode trParamInit = tr.ParamInitSecceed;
		if(trParamInit)
		{
			bool	bParamsInitSucceed = trParamInit.nVal;
		*/
		int		nParamsInitSucceed;
		if( tr.GetAttribute(STR_PARAM_INIT_RESULT, nParamsInitSucceed) )
		{
		///end SHOW_PARAMINITSECCEED_NODE_IN_SETTINGS_TAB_LEFT_SIDE
			strAux = nParamsInitSucceed? "" : _L("Error during compilation for parameters init.");
			if( !nParamsInitSucceed )
				return false;
		}
	}
	///End NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
	
	///Joseph 06/21/07 v8.0645 NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
	///Cheney 2007-8-27 IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
	//if(GETNE_ON_VALUE_CHANGE == nEvent || GETNE_ON_INIT == nEvent)
	if(GETNE_ON_VALUE_CHANGE == nEvent || GETNE_ON_INIT == nEvent || GETNE_ON_CUSTOM_BUTTON1 == nEvent)	
	///end IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
	{
		int nUseValue;
	///End NLF_SHOULD_SUPPORT_CUSTOM_BUTTON_EVENT
		//Waring message section
		///Joseph 06/07/07 v8.0635 NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		//if(trInput.GetAttribute(STR_USE_ATTRIB, nUseValue) && _is_multi_dataset(tr) && _is_independent_mode(nUseValue))
		///Cheney 2007-8-27 IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
		//if(trInput && trInput.GetAttribute(STR_USE_ATTRIB, nUseValue) && _is_multi_dataset(tr, bIsOnChanged) && _is_independent_mode(nUseValue))
		if(trInput && trInput.GetAttribute(STR_USE_ATTRIB, nUseValue) && _is_multi_dataset(tr, bIsOnChanged || GETNE_ON_CUSTOM_BUTTON1 == nEvent) && _is_independent_mode(nUseValue))
		///end IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
		///End NLF_DIFF_EVENT_SHOULD_USE_DIFF_TREE
		{
			//load hints from "Indepedent" section in the file
			///Cheney 2007-9-11 LARRY_CHANGE_INDEPDENT_TO_MULTIDATA_MODE_IN_HINT_TXT
			//tr.SetAttribute(STR_HINT_SECTION_ATTRIB, "Independent");
			/// AW 10/26/07 WRONG_LOCALIZE_MACRO
			//tr.SetAttribute(STR_HINT_SECTION_ATTRIB, "Multi-Data Fit Mode");
			//tr.SetAttribute(STR_HINT_SECTION_ATTRIB, "Multi-Data Fit Mode");
			tr.SetAttribute(STR_HINT_SECTION_ATTRIB, WKSH_OPERATION_INFO_DATA_MODE);//Jasmine 10/27/07 NLFIT_HINTS_LOCALIZATION
			/// END WRONG_LOCALIZE_MACRO
			///end LARRY_CHANGE_INDEPDENT_TO_MULTIDATA_MODE_IN_HINT_TXT
			///Cheney 2007-8-27 IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
			//strAux = _L("The Fit and 1-Iter buttons are disabled. See more info in Hints tab."); 
			ocu_load_msg_str(HINTS_NLFIT_FIT_AND_ITER_BUTTON_DISABLED, &strAux);
			///end IF_MULTI_DATASET_SHOULD_ALWAYS_SHOW_HITS
		}
		else
		{
			string strHint;
			if(tr.GetAttribute(STR_HINT_SECTION_ATTRIB, strHint))
				tr.RemoveAttribute(STR_HINT_SECTION_ATTRIB);
		}
		///End SHOW_ERR_MSG_ON_NLSF_INIT
	}
			
	return true;
}
///End ADD_NLSF_ERR_MSG_EVENT

///Arvin 05/15/07 SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
static bool _add_y_datatype_branch_for_surface_and_matrix_fitting(TreeNode& trOp)
{
	TreeNode trFittedCurve = trOp.GUI.Graph1;
	if(!trFittedCurve.IsValid())
		return false;
	
	if(trFittedCurve.YDataType)
		trFittedCurve.YDataType.Remove();
	
	TreeNode trXDataType = trFittedCurve.XDataType;	
	//construct Fitted Curve options of Y input data for xyz data
	TreeNode trYDataType = trFittedCurve.InsertNode(trFittedCurve.ConfBands, "YDataType", TRGP_BRANCH);
	TreeNode trYTemp = trXDataType.Clone();
	trYTemp.SetAttribute(STR_LABEL_ATTRIB, _L("Y Data Type"));			
	trYTemp.DataID = IDE_FIT_Y_DATA_TYPE_BRANCH;
	trYTemp.N.DataID =IDE_FIT_Y_POINTS;
	trYTemp.Range.DataID =IDE_FIT_Y_RANGE_BRANCH;
	trYTemp.Min.DataID = IDE_FIT_Y_MIN;
	trYTemp.Max.DataID = IDE_FIT_Y_MAX;
	TreeNode trMin = trYTemp.Min;
	TreeNode trMax = trYTemp.Max;
	octree_set_auto_support(&trMin);
	octree_set_auto_support(&trMax);
	trYTemp.RangeMargin.DataID = IDE_FIT_Y_RANGE_MARGIN; 
	trYDataType.Replace(trYTemp, true, true);
	
	return true;
}
///end SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE

///Cheney 2007-8-21 QA70-10256-P7 ADD_GLOBAL_FUC_FOR_UPDATE_CONTOUR_LEVEL
bool NLFitUpdateContourLevels()
{
	GraphLayer gl = Project.ActiveLayer();
	if(!gl)
		return false;
	
	DataPlot dp = gl.DataPlots();
	if(!dp)
		return false;
	
	DataRange dr;
	dp.GetDataRange(dr);
	
	MatrixLayer ml;
	dr.GetParent(ml);
	
	vector vz;
	if(!ml)
	{	
		vector vx, vy;
		DWORD dwPlotUID;
		int nRet = dr.GetData(DRR_GET_Z_DEPENDENT, 0, &dwPlotUID, NULL, &vz, &vx, NULL, NULL, NULL, NULL, NULL, NULL, &vy);
	}
	else
	{
		matrixbase& mat = ml.MatrixObjects(0).GetDataObject();
		mat.GetAsVector(vz, FALSE);
	}
	
	return nlsf_update_residual_contour_levels(gl, dp, vz);
}
///end ADD_GLOBAL_FUC_FOR_UPDATE_CONTOUR_LEVEL

///////////////////////////////////////////////
//	class FitNL
///////////////////////////////////////////////
FitNL::FitNL()
{
	_DBSTR("++++++++ FitNL::FitNL()");
	/// ML 11/10/2006 NLFIT_ALWAYS_MODAL
	//m_bUseFitSession = false;//---- CPY 4/23/05 OK_ON_BAD_FIT_DO_NOT_CLOSE_DIALOG
	/// end NLFIT_ALWAYS_MODAL

	/// Iris 01/30/2007 IMPROVE_NLSF_SPEED
	m_nNumberIndepVariables = -1;
	m_nNumberDepVariables = -1;
	///END IMPROVE_NLSF_SPEED
	
	m_pNLFCurves = NULL; /// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	m_bUseFitSession = false; ///Sophy 9/24/2008 NEW_PA default : create session in operation
}

FitNL::~FitNL()
{
	/// ML 11/10/2006 NLFIT_MODAL_CLEANUP
	//if(m_pFitSession)
	//{
	//	delete m_pFitSession;
	//	m_pFitSession = NULL;
	//}
	CleanupFitSession("~FitNL");
	/// end NLFIT_MODAL_CLEANUP
	///Sophy 10/14/2008 QA80-12370 FIX_RUNTIME_IN_2ND_TIME_RECALCULATE_MATRIX_FIT_ANALYSIS_TEMPLATE
	/*
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	CleanupNLFitCurve("~FitNL");
	/// end FITNL_USING_NEW_NLFSESSION
	*/
	///end FIX_RUNTIME_IN_2ND_TIME_RECALCULATE_MATRIX_FIT_ANALYSIS_TEMPLATE
	_DBSTR("-------- FitNL::~FitNL()");
}

//----CPY 11/10/06 NLFIT_NEW_CODE_RUNTIME_ERR_ON_CANCEL_BUTTON
//virtual
///------ Folger 07/31/09 QA80-13998 DESTROY_OPERATION_AND_ALL_RELATED_OUTPUTS
//void	FitNL::DestroyInternal()
void	FitNL::DestroyInternal(BOOL bDeleteOutputs/* = FALSE*/)
///------ End DESTROY_OPERATION_AND_ALL_RELATED_OUTPUTS
{
	//----CPY 11/10/06 NLFIT_NEW_CODE_RUNTIME_ERR_ON_CANCEL_BUTTON
	_DBSTR("FitNL::DestroyInternal");
	//----
	CleanupFitSession("DestroyInternal");
	///------ Folger 07/31/09 QA80-13998 DESTROY_OPERATION_AND_ALL_RELATED_OUTPUTS
	//FitterOperation::DestroyInternal();
	FitterOperation::DestroyInternal(bDeleteOutputs);
	///------ End DESTROY_OPERATION_AND_ALL_RELATED_OUTPUTS
}
//virtual
BOOL	FitNL::OnKeepOpAfterExecute()
{
	//----CPY 11/10/06 NLFIT_NEW_CODE_RUNTIME_ERR_ON_CANCEL_BUTTON
	_DBSTR("FitNL::OnKeepOpAfterExecute");
	//----
	CleanupFitSession("OnKeepOpAfterExecute");
	return FitterOperation::OnKeepOpAfterExecute();
}
//----

/// ML 11/10/2006 NLFIT_MODAL_CLEANUP
///Sophy 11/4/2008 RESET_FDF_ON_INIT_SESSION_LEAD_TO_RESET_AUTORUNINITPARAMS
//void	FitNL::CleanupFitSession(LPCSTR lpcszMsg)
void	FitNL::CleanupFitSession(LPCSTR lpcszMsg, bool bResetFDF ) //default : true
///end RESET_FDF_ON_INIT_SESSION_LEAD_TO_RESET_AUTORUNINITPARAMS
{
	///Sophy 10/14/2008 QA80-12370 FIX_RUNTIME_IN_2ND_TIME_RECALCULATE_MATRIX_FIT_ANALYSIS_TEMPLATE
	CleanupNLFitCurve("CleanupFitSession"); ///Sophy, Clean NLFSession should delete NLFCurves at the same time, for it's based on session
	///end FIX_RUNTIME_IN_2ND_TIME_RECALCULATE_MATRIX_FIT_ANALYSIS_TEMPLATE
	if(m_pFitSession)
	{
		//----CPY 11/10/06 NLFIT_NEW_CODE_RUNTIME_ERR_ON_CANCEL_BUTTON
		_DBPRINTF("**** m_pFitSession not NULL when %s, deleting...\n", lpcszMsg);
		//----
		///Sophy 9/24/2008 NEW_PA if not created in operation, shall not destroy it
		//delete m_pFitSession;
		if( !m_bUseFitSession )
			delete m_pFitSession;
		else
		{
			Tree trOp;
			GetTree( trOp );
			if( trOp.FitWorkArea )
			{
				TreeNode trFitPointer = trOp.FitWorkArea.FitPointer;
				if( trFitPointer )
					trFitPointer.Reset();
				SetTree( trOp );
			}
		}
		///end NEW_PA
		m_pFitSession = NULL;
	}
	else
	{
		//----CPY 11/10/06 NLFIT_NEW_CODE_RUNTIME_ERR_ON_CANCEL_BUTTON
		_DBPRINTF("**** m_pFitSession is NULL when %s\n", lpcszMsg);
		//----
	}
	/// Hong 11/01/08 QA80-12465 FIX_ASSAYS_OGW_FAIL_RECALCULATE_WITH_FUNCTION_CHANGED_TWICE
	///Sophy 11/4/2008 RESET_FDF_ON_INIT_SESSION_LEAD_TO_RESET_AUTORUNINITPARAMS
	//m_trFDF.Reset();
	if( bResetFDF )
		m_trFDF.Reset();
	///end RESET_FDF_ON_INIT_SESSION_LEAD_TO_RESET_AUTORUNINITPARAMS
	/// end FIX_ASSAYS_OGW_FAIL_RECALCULATE_WITH_FUNCTION_CHANGED_TWICE
}

// virtual
BOOL	FitNL::PostExecute(int nExeMode, BOOL bExeRet)
{
	CleanupFitSession("PostExecute");
	return FitterOperation::PostExecute(nExeMode, bExeRet);
}
/// end NLFIT_MODAL_CLEANUP




/// ML 1/26/2005 CUSTOM_TABLE_TO_GRAPH
/*
// virtual
BOOL	FitNL::getCustomTableThemeName(string &strThemeName, TreeNode &trOp, int nCustomIndex)
{
	if ( 0 == nCustomIndex )
	{
		strThemeName = "Fit";
		return TRUE;
	}
	
	return FALSE;
}
*/

/// ML 4/28/2006 FRIENDLY_CUSTOM_TABLE_THEME_GENERATION
/*
// virtual
int		FitNL::getTableIdForGraph(string *pstr, TreeNode& trOp)
{
	/// ML 12/22/2004 temp until Roman is done with the label work
	//return 0;
	// Custom for now:
	TreeNode		tr = getOrCreateCustomTable(trOp);
	if( !tr.IsValid() )
		return 0;

	int				nID = tr.ID;
	/// 
	if ( pstr )
	{
		*pstr = "RegrTable";
	}
	return nID;
}
/// end PROGRAMMATICALLY_PUTTING_A_REPORT_TABLE_INTO_A_GRAPH
*/
/// end FRIENDLY_CUSTOM_TABLE_THEME_GENERATION

/// YuI 11/09/06 SOME_REDESIGN_OF_NLFIT_FOR_MODAL
/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
/*
bool	FitNL::Edit(bool bChangeParams, int& nAutoUpdate, LPCSTR lpcszTheme, bool bInitFromSel)
{
	return FitterOperation::Edit(bChangeParams, nAutoUpdate, lpcszTheme, bInitFromSel);	
}
*/
/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
/// SOME_REDESIGN_OF_NLFIT_FOR_MODAL

//------- CPY 9/14/04 CONSOLIDATE_OP_BRANCH_AND_AUTOUPDATE
// if return false, indicate Category cannot be changed by user
/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
////virtual 
//bool FitNL::GetCategoryFuncNames(TreeNode& trOperation, string& strCategory, string& strFunction, vector<string>& vsFilterList)
bool FitNL::getCategoryFuncNamesAll(TreeNode& trOperation, string& strCategory, string& strFunction, vector<string>& vsFilterList)
/// end INVOKING_OPERATION_FROM_XFUNCTION
{
	NLFitSelFunction	mySelFunc(trOperation.GUI.FunctionSelection);
	mySelFunc.GetCategoryAndFunction(strCategory, strFunction);	
	return true;// indicate category can be changed
}

///Jasmine 04/16/08 MOVE_UPDATE_MODEL_CODES_IN_FITNL_CLASS
bool FitNL::UpdateModelNote(TreeNode& trTable, const TreeNode& trOperation)
{
	if(!trOperation || !trTable || !trTable.Model)
		return false;
	
	//Model note only needed in NL Fit
	trTable.Model.strVal = GetResultModel(trOperation);
	trTable.Model.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_MODEL);
	
	return true;
}
///End MOVE_UPDATE_MODEL_CODES_IN_FITNL_CLASS

/// Iris 8/14/2008 QA80-12017-S2 ADD_PARAM_NUM_DATA_NUM_TO_NOTE_TABLE
//virtual 
bool FitNL::UpdateNumParamsDatasetsNote(TreeNode& trTable, int nTotalNumData, const TreeNode& trOperation)
{
	if( !trTable )
		return false;
	
	if( trTable.NumFuncParams )
	{
		trTable.NumFuncParams.nVal = m_pFitSession->GetNumParameter();
		trTable.NumFuncParams.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_NUM_PARAMS);
	}
	
	if( trTable.NumDerivParams )
	{
		trTable.NumDerivParams.nVal = m_pFitSession->GetDerivedParamNum();
		trTable.NumDerivParams.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_NUM_DERIVED_PARAMS);
	}
		
	if( trTable.NumDataSets )
	{
		trTable.NumDataSets.nVal = nTotalNumData;
		trTable.NumDataSets.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_NUM_DATASETS);
	}
	
	return true;
}
///end ADD_PARAM_NUM_DATA_NUM_TO_NOTE_TABLE

///Arvin 10/27/06 FITTING_FUNCTION_MODEL_IN_REPORT
string FitNL::GetResultModel(const TreeNode& trOperation)
{
	string strCate, strFunc;
	NLFitSelFunction	mySelFunc(trOperation.GUI.FunctionSelection);
	if(mySelFunc.GetCategoryAndFunction(strCate, strFunc))
		return strFunc;
}
///end FITTING_FUNCTION_MODEL_IN_REPORT

//virtual 
string FitNL::GetResultDescription(const TreeNode& trOperation, bool bLong)// = true)
{
	string str = _LR("Nonlinear Curve Fit");
	///Cheney IF_3D_FITTING_GIVE_PROPER_DESCRIPTION
	int nFitType = GetFitType(trOperation);
	if(nFitType == NLFIT_XYZ_FITTING)
		str = _LR("Nonlinear Surface Fit");
	else if(nFitType == NLFIT_MATRIX_FITTING)
		str = _LR("Nonlinear Matrix Fit");
	///end IF_3D_FITTING_GIVE_PROPER_DESCRIPTION
	if(bLong)
	{
		string strCate, strFunc;
		NLFitSelFunction	mySelFunc(trOperation.GUI.FunctionSelection);
		if(mySelFunc.GetCategoryAndFunction(strCate, strFunc))
			str += " (" + strFunc + ")";
	}
	return str;
}

/// Iris 11/16/06 ADD_PARAMETER_SETTING_TO_THEME
//virtual
bool		FitNL::ParamsFromGUItoOperation(TreeNode& trOperation)
{
	TreeNode	trFitParams = trOperation.FitWorkArea.Parameters;
	/// ML 12/15/2006 CALLING_NLFIT_FROM_OC_LT
	if (!trFitParams)
		return false;
	/// end CALLING_NLFIT_FROM_OC_LT
	TreeNode	trParamNames = trFitParams.Names;
	if( !trParamNames )
	{
		ASSERT(FALSE); // Hong, why silence
		return false;
	}
	int		nNumParams = trParamNames.strVals.GetSize();
	if( nNumParams <= 0)
	{
		ASSERT(FALSE); // Hong, why silence
		return false;
	}
	
	/// Hong 11/17/07 QA80-10499 FIX_NLFIT_LAST_USED_THEME_MISSING_SOMESETTINGS	
	bool bAutoParamsInit = false, bLinearConstraints = false;
	int nAutoParamsInit, nLinearConstraints;
	/// end FIX_NLFIT_LAST_USED_THEME_MISSING_SOMESETTINGS
	/// RVD 10/4/2007 v8.0715 qa7-10463 FIX_NLFIT_LIMIT_20_PARAMETERS
	TreeNode trTempParams = trOperation.GUI.Parameters;
	if( trTempParams )
	{
		/// Hong 11/17/07 QA80-10499 FIX_NLFIT_LAST_USED_THEME_MISSING_SOMESETTINGS	
		if ( trTempParams.AutoParamsInit )
		{
			nAutoParamsInit = trTempParams.AutoParamsInit.nVal;
			bAutoParamsInit = true;
		}
		if ( trTempParams.LinearConstraints )
		{
			nLinearConstraints = trTempParams.LinearConstraints.nVal;
			bLinearConstraints = true;
		}
		
		/// end FIX_NLFIT_LAST_USED_THEME_MISSING_SOMESETTINGS	
#ifndef SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION ///---Sim 10-20-2008 FIX_NLFIT_LAST_USED_THEME_FAILED_TO_SAVE_FIXED_VALUE
		trTempParams.Remove(); //remove Parameters to reconstruct		
#endif //SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION ///---Sim 10-20-2008 FIX_NLFIT_LAST_USED_THEME_FAILED_TO_SAVE_FIXED_VALUE
	}
	/// end FIX_NLFIT_LIMIT_20_PARAMETERS

	//construct parameters node in GUI
	TreeNode 	trParams = nlsf_check_get_GUI_params_with_ID(trOperation.GUI, nNumParams);
	if( !trFitParams || !trParams)
		return false;
	
	/// Hong 11/17/07 QA80-10499 FIX_NLFIT_LAST_USED_THEME_MISSING_SOMESETTINGS
	if ( trParams.AutoParamsInit && bAutoParamsInit )
		trParams.AutoParamsInit.nVal = nAutoParamsInit;
	if ( trParams.LinearConstraints && bLinearConstraints )
		trParams.LinearConstraints.nVal = nLinearConstraints;
	/// end FIX_NLFIT_LAST_USED_THEME_MISSING_SOMESETTINGS
	
	//put parameter values from FitWorkArea to GUI.Parameters node
	foreach(TreeNode trParam in trParams.Children)
	{
		TreeNode trOneFitParam = trFitParams.GetNode(trParam.tagName);
		if( trOneFitParam )
		{
			_convert_tree_vals_to_tree_val(trOneFitParam, trParam);				
		}
	}
	return true;
			
}

/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
//// move to NLFSessionn.h
//static void  _convert_tree_vals_to_tree_val(const TreeNode& trSource, TreeNode& trDest)
//{
	//switch(trSource.TypeID)
	//{
	//case TNVAL_TYPE_INT_VECTOR:
		//vector<int> vn;
		//vn = trSource.nVals;
		////------ Folger 08/15/08 QA80-12034 FIX_PARAMETER_FIXED_MISSING_IN_RECALCULATION
		///*
		////---- CPY 11/19/2007 QA70-10708 PROPER_VECTOR_OF_DOUBLES_TO_SUBNODES_CODE
		////_convert_numeric_vec_to_tree_val(vn, trDest);
		//_convert_int_vec_to_tree_val(vn, trDest);
		////----
		//*/
		//octree_value_from_vec_int_to_tree_sub_nodes(&vn, &trDest);
		////------ End FIX_PARAMETER_FIXED_MISSING_IN_RECALCULATION
		//break;
	//case TNVAL_TYPE_DOUBLE_VECTOR:
		//vector<double> vd;
		//vd = trSource.dVals;
		///// ML 11/16/2007 QA70-10708 PROPER_VECTOR_OF_DOUBLES_TO_SUBNODES_CODE
		////_convert_numeric_vec_to_tree_val(vd, trDest);
		//octree_value_from_vec_double_to_tree_sub_nodes(&vd, &trDest);
		///// end PROPER_VECTOR_OF_DOUBLES_TO_SUBNODES_CODE
		//break;
	//case TNVAL_TYPE_CSTRING_VECTOR:
		//vector<string> vstr;
		//vstr = trSource.strVals;
		//_convert_str_vec_to_tree_val(vstr, trDest);
		//break;
	//default:
		//break;		
	//}
//}
//
//
////---- CPY 11/19/2007 QA70-10708 PROPER_VECTOR_OF_DOUBLES_TO_SUBNODES_CODE
///*
//static void _convert_numeric_vec_to_tree_val(const vectorbase& vValues, TreeNode& trDest)
//{
	//TreeNodeCollection trRows(trDest, "Value");
	//if(trRows.Count() != vValues.GetSize())
		//return;
	//
	//for(int ii=0; ii<vValues.GetSize(); ii++)
	//{
		//TreeNode trRow  = trRows.Item(ii);
		//if(trRow)
		//{
			//string str = vValues[ii];
			//trRow.strVal  = str;
		//}
	//}	
//}
//*/
//static void _convert_int_vec_to_tree_val(const vectorbase& vValues, TreeNode& trDest)
//{
	//TreeNodeCollection trRows(trDest, "Value");
	//if(trRows.Count() != vValues.GetSize())
		//return;
	//
	//for(int ii=0; ii<vValues.GetSize(); ii++)
	//{
		//TreeNode trRow  = trRows.Item(ii);
		//if(trRow)
		//{
			//trRow.nVal  = vValues[ii];
		//}
	//}	
//}
////---- end QA70-10708 PROPER_VECTOR_OF_DOUBLES_TO_SUBNODES_CODE
//
//static void _convert_str_vec_to_tree_val(const vector<string>& vValues, TreeNode& trDest)
//{
	//TreeNodeCollection trRows(trDest, "Value");
	//for(int ii=0; ii<vValues.GetSize(); ii++)
	//{
		//TreeNode trRow  = trRows.Item(ii);
		//if(trRow)
		//{
			//string str = vValues[ii];
			//trRow.strVal  = str;
		//}
	//}	
//}
/////end ADD_PARAMETER_SETTING_TO_THEME
/// end FITNL_USING_NEW_NLFSESSION

///Arvin 01/09/06 FIND_Z_FROM_XY by Iris' suggestion
static bool _change_calibration_branch_for_surface_fit(TreeNode& trOperation)
{
	TreeNode trCalibration = trOperation.GUI.Calibration;
	if(trCalibration)
	{
		TreeNode trGUI = trOperation.GUI;
		TreeNode trTemp = trGUI.InsertNode(trCalibration, "Temp");
		trCalibration.Remove();
		int nCols = 1;
		Tree tr;
		GETN_USE(tr)	
		GETN_BEGIN_BRANCH(Calibration, _L("Find Specific Z")) GETN_ID_BRANCH(IDST_REPORT_CUSTOM_TABLE3_BEGIN) GETN_CHECKBOX_BRANCH(0) GETN_ID_REPEAT_BRANCH(3) GETN_OPTION_EVENT(on_check_calibration_branch_event)
		GETN_COMBO(Cols, _L("Number of Z Columns"), nCols, "1|2|3|4|5|6|7|8|9") GETN_ID(IDE_REPORT_CUSTOM_TABLE_COLS) GETN_OPTION_NUM_FORMAT( "%d" )
		GETN_END_BRANCH(Calibration)
		TreeNode trCal = tr.Calibration;
		trTemp.Replace(trCal.Clone());
		return true;
	}
	
	return false;
}

static bool _change_output_find_xy_branch_for_surface_fit(TreeNode& trOperation, int nFinXYBranchID)
{
	TreeNode trOut = trOperation.GUI.Output;
	TreeNode trFindXY = trOperation.GUI.Output.FindXY;
	if(trFindXY)
	{
		TreeNode trTemp = trOut.InsertNode(trFindXY, "Temp");
		trFindXY.Remove();
		Tree tr;
		GETN_USE(tr)
		///Arvin 12/25/07 MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL as cp said
		//GETN_BEGIN_BRANCH(FindXY, _L("Output Find Specific Z Table")) GETN_ID_BRANCH(nFinXYBranchID)
		GETN_BEGIN_BRANCH(FindXY, _L("Output Find Specific Z Table")) GETN_ID_BRANCH(nFinXYBranchID) GETN_OPTION_EVENT(operation_output_findxy_branch_event)
		///end MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL
			GETN_STRLIST(Book, _L("Book"), STR_NEW, STR_SOURCE_BOOK + STR_TOKEN_SEP + STR_REPORT + STR_TOKEN_SEP + STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS) GETN_ID(IDE_FIND_XY_BOOK) GETN_OPTION_EVENT(operation_output_findxy_book_event)
			GETN_STR(BookName, _L("BookName"), _L("")) GETN_ID(IDE_FIND_XY_BOOK_NAME) GETN_OPTION_EVENT_EX(operation_output_book_sheet_name_changed)/// Iris 3/28/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME_AFTER_CLEAN_OUTPUT_GUI_CODES
			///Sophy 5/28/2008 QA80-10934-P8 FIX_GIVE_DEFAULT_BOOK_SHEET_NAME_TO_PARTIAL_LEVERAGE_VALUES_NODE
			//GETN_STRLIST(Sheet, _L("Sheet"), STR_NEW, STR_SOURCE_BOOK + STR_TOKEN_SEP + STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS) GETN_ID(IDE_FIND_XY_SHEET) GETN_OPTION_EVENT(operation_output_sheet_event)
			GETN_STRLIST(Sheet, _L("Sheet"), STR_NEW, STR_SOURCE_BOOK + STR_TOKEN_SEP + STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS) GETN_ID(IDE_FIND_XY_SHEET) GETN_OPTION_EVENT(operation_output_findxy_sheet_event)
			///end FIX_GIVE_DEFAULT_BOOK_SHEET_NAME_TO_PARTIAL_LEVERAGE_VALUES_NODE
			GETN_READ_ONLY
			GETN_STR(SheetName, _L("SheetName"), _L("")) GETN_ID(IDE_FIND_XY_SHEET_NAME) GETN_OPTION_EVENT_EX(operation_output_book_sheet_name_changed)/// Iris 3/28/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME_AFTER_CLEAN_OUTPUT_GUI_CODES
		GETN_END_BRANCH(FindXY)
		trFindXY = tr.FindXY;
		trTemp.Replace(trFindXY.Clone());
		return true;
	}
	
	return false;
}
///end FIND_Z_FROM_XY

//----- CPY 10/12/07 10522-P3 CLEANUP_IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE
/*
///Arvin 04/27/07 v8.0609 UPDATE_OUTPUT_DESTINATION_FOR_SURFACE_FITTING as max's suggestion
///Cheney 2007-8-30 QA70-10290-sug4 FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
//static bool _update_output_book_sheet_destination(TreeNode& trOutput, LPCSTR lpcszBookList, LPCSTR lpcszBookDefault, LPCSTR lpcszSheetList, LPCSTR lpcszSheetDefault = NULL)
static bool _update_output_book_sheet_destination(TreeNode& trOutput, LPCSTR lpcszBookList = NULL, LPCSTR lpcszBookDefault = NULL, LPCSTR lpcszSheetList = NULL, LPCSTR lpcszSheetDefault = NULL)
///end FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
{
	if(!trOutput)
		return false;
	
	if(trOutput.Book)
	{
		///Cheney 2007-8-30 QA70-10290-sug4 FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
		//trOutput.Book.RemoveAttribute(STR_COMBO_ATTRIB);
		//trOutput.Book.SetAttribute(STR_COMBO_ATTRIB, lpcszBookList);
		if(lpcszBookList)
		{
			trOutput.Book.RemoveAttribute(STR_COMBO_ATTRIB);
			trOutput.Book.SetAttribute(STR_COMBO_ATTRIB, lpcszBookList);
		}
		if(lpcszBookDefault)
		///end FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
		trOutput.Book.strVal = lpcszBookDefault;
	}
	
	if(trOutput.Sheet)
	{
		///Cheney 2007-8-30 QA70-10290-sug4 FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
		//trOutput.Sheet.RemoveAttribute(STR_COMBO_ATTRIB);
		//trOutput.Sheet.SetAttribute(STR_COMBO_ATTRIB, lpcszSheetList);
		if(lpcszSheetList)
		{
			trOutput.Sheet.RemoveAttribute(STR_COMBO_ATTRIB);
			trOutput.Sheet.SetAttribute(STR_COMBO_ATTRIB, lpcszSheetList);
		}
		if(lpcszSheetDefault)
		///end FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
		trOutput.Sheet.strVal = lpcszSheetDefault;
	}
	return true;
}
///end UPDATE_OUTPUT_DESTINATION_FOR_SURFACE_FITTING
*/
//---- end CLEANUP_IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE

///Arvin 11/20/07 QA70-10708 CHECK_AND_CONVERT_DOUBLE_VALUES_FROM_GERMAN_TO_ENGLISH
static bool _check_and_convert_tree_sub_nodes_values(TreeNode& trN)
{
	if(!trN.IsValid())
		return false;
	
	bool 		bConverted = false;
	int 		index = 0;
	foreach(TreeNode trSub in trN.Children)
	{
		if(trSub.IsEmpty())
			continue;
		
		string 	strVal = trSub.strVal;
		int nFind = strVal.Find(CHAR_GERMAN_RADIX_POINT);
		if(nFind >= 0 && nFind < strVal.GetLength())
		{
			strVal.Replace(CHAR_GERMAN_RADIX_POINT, CHAR_ENGLISH_RADIX_POINT);
			trSub.strVal = strVal;
			bConverted = true;
		}
	}
	
	return bConverted;
}

static bool _check_and_covert_german_params_double_values(TreeNode& trParams)
{
	if(_check_and_convert_tree_sub_nodes_values(trParams.Values))
	{
		_check_and_convert_tree_sub_nodes_values(trParams.LowerBounds);
		_check_and_convert_tree_sub_nodes_values(trParams.UpperBounds);
		return true;
	}
	return false;
}

bool FitNL::CheckLoadOperation(TreeNode& trOperation, int nCurrentOperationVersion)
{
	TreeNode trParams = trOperation.GUI.Parameters;
	if(nCurrentOperationVersion != CURRENT_OPERATION_VERSION && trParams)
	{
		_check_and_covert_german_params_double_values(trParams);
		trOperation.SetAttribute(STR_OP_VERSION, CURRENT_OPERATION_VERSION);
		return true;
	}
	return false;
}
///end CHECK_AND_CONVERT_DOUBLE_VALUES_FROM_GERMAN_TO_ENGLISH
	
///Cheney 2007-7-17 SHOULD_UPDATE_SPECI_INFO_WHEN_THEME_LOAD_OR_FUNC_CHANGE_IF_IS_SPECI_FIT
bool	FitNL::updateSepcInfo(TreeNode& trOp)
{
	TreeNode	trSpec = trOp.SpecInfo;
	if (!trSpec)
		return false;
	
	TreeNode trFuncList = trOp.GUI.FunctionSelection.FunctionList;
	if( !trFuncList)
		return false;
	
	string strFuncList; 
	if(!trFuncList.GetAttribute( STR_COMBO_ATTRIB, strFuncList ))
		return false;
	
	StringArray saOptions;
	if( strFuncList.GetTokens( saOptions, '|' ) < 1)
		return false;
	
	string strFunc = trFuncList.strVal;
	int nOption = saOptions.Find( strFunc );
	if(nOption < 0)
		return false;
	
	trSpec.Options.strVals = saOptions;
	trSpec.Names.strVals = saOptions;
	trSpec.Option.nVal = nOption;
	
	return true;
}
///end SHOULD_UPDATE_SPECI_INFO_WHEN_THEME_LOAD_OR_FUNC_CHANGE_IF_IS_SPECI_FIT

///Arvin 04/24/07 v8.0607 SURFACE_FIT_NEED_UPDATE_TROPERATION_BEFORE_RUNNING_CHANGE_PARAM_AND_RECALCULATE
void	FitNL::OnBeforeCalculations(TreeNode& trOperation, int nExeMode)
{
	Operation::OnBeforeCalculations(trOperation, nExeMode);
	//Update calibration branch for recalculate, and because other execution modes need open dialog,
	//so we update this branch in OperationtoGUI for them.
	if (OEXEM_ON_AUTOUPDATE_MANUAL == nExeMode || OEXEM_ON_AUTOUPDATE_TASK == nExeMode)
	{
		//Update calibration branch for surface fitting before running 
		///Arvin 11/19/07 SURFACE_FIT_RECALCULATION_DESTROY_CALIBRATION_TABLE
		//Has done this in updateTreeBeforeRunning
		//if(HasZ(trOperation))
		//{
			//_change_calibration_branch_for_surface_fit(trOperation);
			//int  nFinXYBranchID = GetFindXYID();
			//_change_output_find_xy_branch_for_surface_fit(trOperation, nFinXYBranchID);
			/////Arvin 05/15/07 SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
			//_add_y_datatype_branch_for_surface_and_matrix_fitting(trOperation);
			/////end SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
		//}
		///END SURFACE_FIT_RECALCULATION_DESTROY_CALIBRATION_TABLE
		
		//Should set attribute STR_REPORT_MATRIX_DATA for surface fitting in all executing modes
		TreeNode trData = trOperation.GUI.Output.Data;
		TreeNode trRes = trOperation.GUI.Output.Residual;
		int nFitType = GetFitType(trOperation);
		if(nFitType == NLFIT_XYZ_FITTING)
		{
			if(trData)
				///Cheney 2007-10-16 QA70-10536 CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
				//trData.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
				///Sophy 9/3/2008 CLEAN_OUTPUT_WND_TYPE_CODE
				//trData.SetAttribute(STR_OPERATION_OUTPUT_TYPE, OPERATION_OUTPUT_XYZ_FITTING);
				trData.SetAttribute(STR_OPERATION_OUTPUT_WND_TYPE, EXIST_WKS );
				///end CLEAN_OUTPUT_WND_TYPE_CODE
				///end CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
		}
		
		if(nFitType == NLFIT_MATRIX_FITTING)
		{
			if(trData)
				///Cheney 2007-10-16 QA70-10536 CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
				//trData.SetAttribute(STR_REPORT_MATRIX_DATA, 2);
				///Sophy 9/3/2008 CLEAN_OUTPUT_WND_TYPE_CODE
				//trData.SetAttribute(STR_OPERATION_OUTPUT_TYPE, OPERATION_OUTPUT_MAT_FITTING);
				trData.SetAttribute( STR_OPERATION_OUTPUT_WND_TYPE, EXIST_MATRIX );
				///end CLEAN_OUTPUT_WND_TYPE_CODE
				///end CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
			if(trRes)
				///Cheney 2007-10-16 QA70-10536 CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
				//trRes.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
				///Sophy 9/3/2008 CLEAN_OUTPUT_WND_TYPE_CODE
				//trRes.SetAttribute(STR_OPERATION_OUTPUT_TYPE, OPERATION_OUTPUT_MAT_FITTING);
				trRes.SetAttribute( STR_OPERATION_OUTPUT_WND_TYPE, EXIST_MATRIX );
				///end CLEAN_OUTPUT_WND_TYPE_CODE
				///end CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
		}
	}
	
	///Cheney 2007-7-17 SHOULD_UPDATE_SPECI_INFO_WHEN_THEME_LOAD_OR_FUNC_CHANGE_IF_IS_SPECI_FIT
	if( IsSpecFit(trOperation) )
		updateSepcInfo(trOperation);
	///end SHOULD_UPDATE_SPECI_INFO_WHEN_THEME_LOAD_OR_FUNC_CHANGE_IF_IS_SPECI_FIT
}
///end SURFACE_FIT_NEED_UPDATE_TROPERATION_BEFORE_RUNNING_CHANGE_PARAM_AND_RECALCULATE
//----- CPY 10/12/07 10522-P3 CLEANUP_IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE
/*		
///Cheney 2007-8-30 QA70-10290-sug4 FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
void	FitNL::updateOutputSettingFor3DFitting(TreeNode& trOperation)
{
	TreeNode trData = trOperation.GUI.Output.Data;
	TreeNode trRes = trOperation.GUI.Output.Residual;
	int nFitType = GetFitType(trOperation);
	
	TreeNode trFittedOut = trOperation.GUI.Output.Data; 
	TreeNode trResidualOut = trOperation.GUI.Output.Residual;
	TreeNode trFindXYOut = trOperation.GUI.Output.FindXY;
	TreeNode trReportOut = trOperation.GUI.Output.Report;
	
	///Cheney 2007-10-12 IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE
#ifdef NLFIT_CHECK_LOOSE_DATASET
	//check if 1st data range is loose data set
	bool bLooseDataset = false;
	FUNC_IS_LOOSE_DATASET pfn = Project.FindFunction("is_loose_dataset", "OriginLab\\Event_utils", true);
	if(pfn)
		bLooseDataset = pfn(trOperation.GUI.InputData.Range1); 
	
	if(bLooseDataset && nFitType == NLFIT_GENERAL_XY_FITTING)
	{
		if(trReportOut)
			_update_output_book_sheet_destination(trReportOut, STR_LOOSEDATASET_XYFITTING_REPORTOUT_BOOK_COMBO, STR_NEW, NULL, NULL);
	}
#endif //NLFIT_CHECK_LOOSE_DATASET
	///end IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE
	if(!is_range_from_normal_book(trOperation.GUI.InputData) && trReportOut) // reset to basic new report type of combo
		_update_output_book_sheet_destination(trReportOut, STR_OUTPUT_REPORT_BOOK_COMBO, STR_NEW, NULL, NULL);
//----- end CLEANUP_IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE
	
	if(nFitType == NLFIT_XYZ_FITTING)
	{
		if(trData)
			trData.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
		
		if(trResidualOut)
			_update_output_book_sheet_destination(trResidualOut, STR_XYZFITTING_RESIDUALOUT_BOOK_COMBO, STR_REPORT, STR_XYZFITTING_RESIDUALOUT_SHEET_COMBO, STR_NEW);
		
		if(trFindXYOut)
			_update_output_book_sheet_destination(trFindXYOut, STR_XYZFITTING_FINDZOUT_BOOK_COMBO, STR_REPORT, STR_XYZFITTING_FINDZOUT_SHEET_COMBO, STR_NEW);
	
		if(trFittedOut)
			_update_output_book_sheet_destination(trFittedOut, STR_XYZFITTING_FITTEDCURVE_BOOK_COMBO, STR_NEW, NULL, STR_NEW);
		///Cheney 2007-10-12 IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE
#ifdef NLFIT_CHECK_LOOSE_DATASET
		//check if 1st data range is loose data set
		if(bLooseDataset && trReportOut)
			_update_output_book_sheet_destination(trReportOut, STR_LOOSEDATASET_XYZFITTING_REPORTOUT_BOOK_COMBO, STR_NEW, NULL, NULL);
#endif //NLFIT_CHECK_LOOSE_DATASET
		///end IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE
	}
		
	if(nFitType == NLFIT_MATRIX_FITTING)
	{
		if(trData)
			trData.SetAttribute(STR_REPORT_MATRIX_DATA, 2);
		if(trRes)
			trRes.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
		
		if(trResidualOut)
			///Cheney 2007-9-26 QA70-10388 FIX_BUG_OF_REPORT_RESULT_WHEN_FIT_MATRIX
			//_update_output_book_sheet_destination(trResidualOut, STR_MATFITTING_RESIDUALOUT_BOOK_COMBO, STR_FIT_CURVE, STR_MATFITTING_RESIDUALOUT_SHEET_COMBO, STR_FIT_CURVE);
			_update_output_book_sheet_destination(trResidualOut, STR_MATFITTING_RESIDUALOUT_BOOK_COMBO, STR_FIT_CURVE, STR_MATFITTING_RESIDUALOUT_SHEET_COMBO, STR_NEW);
			///end FIX_BUG_OF_REPORT_RESULT_WHEN_FIT_MATRIX
		
		if(trFindXYOut)
			_update_output_book_sheet_destination(trFindXYOut, STR_MATFITTING_FINDZOUT_BOOK_COMBO, STR_REPORT, STR_MATFITTING_FINDZOUT_SHEET_COMBO, STR_NEW);
		
		if(trReportOut)
			_update_output_book_sheet_destination(trReportOut, STR_MATFITTING_REPORTOUT_BOOK_COMBO, STR_NEW, STR_MATFITTING_REPORTOUT_SHEET_COMBO, STR_NEW);
		
		if(trFittedOut)
		{
			string strBookCombo;
			trFittedOut.Book.GetAttribute(STR_COMBO_ATTRIB, strBookCombo);
			StringArray saTokens;
			strBookCombo.GetTokens( saTokens, '|');
			if(saTokens.GetSize() == 0)
				return;
			_update_output_book_sheet_destination(trFittedOut, NULL, saTokens[0], NULL, STR_NEW);
		}
	}
}
*/
void	FitNL::updateOutputSettingFor3DFitting(TreeNode& trOperation)
{
	int nFitType = GetFitType(trOperation);
	
	/// Iris 3/26/2008 v8.0832 CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS
	/*
	///Cheney 2007-10-16 QA70-10536 CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
	//check_update_fit_output_book_sheet_GUI(trOperation.GUI, nFitType);
	check_update_fit_output_book_sheet_GUI(trOperation.GUI, trOperation.GUI.InputData, nFitType, true, GetSourcePageName(trOperation));
	///end CLEAN_CODE_AND_FIX_BUG_OF_ADD_AUTO_FOR_OUTPUT_SETTING
	*/
	//FitOutputGUIManager	outputManager;
	m_pOutputManager->CheckUpdateFitOutputBookSheetGUI(trOperation.GUI, trOperation.GUI.InputData, nFitType, true, GetSourcePageName(trOperation));
	///end CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS
	
}
//----- end CLEANUP_IF_LOOSE_DATASET_SHOULD_NOT_PUT_REPORT_SHEET_TO_SOURCE

///Cheney 2007-9-6 FINDZ_NODE_SHOULD_PREPARED_WHEN_CHANGE_PARAM	
BOOL	FitNL::UpdateCalibrationBranch(TreeNode& trOperation)
{
	if(!trOperation)
		return false;
	
	_change_calibration_branch_for_surface_fit(trOperation);
	int  nFinXYBranchID = GetFindXYID();
	_change_output_find_xy_branch_for_surface_fit(trOperation, nFinXYBranchID);
		
	///Jasmine 05/28/08 QA80-11234 v8.0872 GRID_XY_AFTER_GENERATE_XY_FOR_XYZ_FIT
	ASSERT( trOperation.GUI.Graph1.XDataType.N.IsValid() );
	TreeNode trN = trOperation.GUI.Graph1.XDataType.N;
	if(trN)
		trN.nVal = XYZ_FIT_DEFAULT_POINTS;
	///End GRID_XY_AFTER_GENERATE_XY_FOR_XYZ_FIT
	_add_y_datatype_branch_for_surface_and_matrix_fitting(trOperation);
	return true;
}
///end FINDZ_NODE_SHOULD_PREPARED_WHEN_CHANGE_PARAM
///Jasmine 09/30/07 QA70-10462 CHECK_REPLACE_USER_FITTING_FUNCTION_TO_GROUP_ONE
// virtual
/// YuI 06/06/08 QA70-11619 MORE_CLEAR_WORKSHEET_PROBLEM
//	void	FitNL::GUIOnUpdateTreeBeforeRunning(TreeNode &trGUINew, TreeNode &trGUIOriginal)
///---Sim 04-02-2009 QA80-13403 ADD_INDIVIDUAL_OP_VERSION_FOR_CONVERT_GUI_TREE
//void	FitNL::GUIOnUpdateTreeBeforeRunning(TreeNode &trGUINew, TreeNode &trGUIOriginal, TreeNode& trOperation)
void	FitNL::GUIOnUpdateTreeBeforeRunning(const MultipleVersion& mvOld, TreeNode &trGUINew, TreeNode &trGUIOriginal, TreeNode& trOperation)
///---END QA80-13403 ADD_INDIVIDUAL_OP_VERSION_FOR_CONVERT_GUI_TREE
/// end MORE_CLEAR_WORKSHEET_PROBLEM
{
	/// YuI 06/06/08 QA70-11619 MORE_CLEAR_WORKSHEET_PROBLEM
	//	StatsOpBase::GUIOnUpdateTreeBeforeRunning(trGUINew, trGUIOriginal);
	///---Sim 04-02-2009 QA80-13403 ADD_INDIVIDUAL_OP_VERSION_FOR_CONVERT_GUI_TREE
	//StatsOpBase::GUIOnUpdateTreeBeforeRunning(trGUINew, trGUIOriginal, trOperation);
	/// Iris 4/29/2009 QA80-12017 NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ
//#ifdef INSERT_NEW_REPORT_ENTRY_IN_OLD_OPJ_WHEN_RECALCULATE
	FitterOperation::GUIOnUpdateTreeBeforeRunning(mvOld, trGUINew, trGUIOriginal, trOperation);	
//#else
//	StatsOpBase::GUIOnUpdateTreeBeforeRunning(mvOld, trGUINew, trGUIOriginal, trOperation);
//	#endif 	
	///end NEED_ADD_NEW_REPORT_ITEM_WHEN_RECALCULATE_ON_OLD_OPJ	
	///---END QA80-13403 ADD_INDIVIDUAL_OP_VERSION_FOR_CONVERT_GUI_TREE
	/// end MORE_CLEAR_WORKSHEET_PROBLEM
	
	int nPathType;
	TreeNode trFunctionSelection = trGUINew.FunctionSelection;
	string strCategory = trFunctionSelection.CategoryList.strVal;
	string strFunction = trFunctionSelection.FunctionList.strVal;
	string strFuncName = okutil_separate_composite_name(strFunction, &nPathType);
	string strGroup = okutil_get_origin_path(ORIGIN_PATH_GROUP, NULL, TRUE);
	if(USER_FOLDER == nPathType && !strGroup.IsEmpty())
	{
		int nFolder;
		string strFile;
		nlf_get_fdf_filename(strFunction, &strCategory, &nFolder, &strFile);
		if(strFile.IsFile() && nFolder != nPathType)
			trFunctionSelection.FunctionList.strVal = okutil_composite_name_from_components(nFolder, NULL, strFuncName);
	}
	/// YuI 06/06/08 QA70-11619 MORE_CLEAR_WORKSHEET_PROBLEM
	// it turns out that some things in the GUI tree that get initialized in OperationtoGUI
	// are used for decision making during executeWithRange - some values (visibility, enable etc.) has implications
	// that go beyond GUI
	// one of them is PlotFit node. Depending on its visibility the decision is made whether to put fit curve into source layer (see IsPlotOnSourceGraph)
	if( HasZ(trOperation) )
	{
		TreeNode trGraph = GetGUIGraphNodesEx(trGUINew, GRAPH_FIT_CURVE);
		if( trGraph )
		{
			trGraph.PlotFit.Show = false;
		}
	}
	/// end MORE_CLEAR_WORKSHEET_PROBLEM
}
///End CHECK_REPLACE_USER_FITTING_FUNCTION_TO_GROUP_ONE

///Arvin 03/10/08 QA70-11234 REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
//Hide node of residual type and all other plots except "Residual vs. Independent Plot" nodes. 
//Hide all nodes except "Plot in Report Table" node under fitted curves branch 
static bool  _hide_children_nodes_for_branch(TreeNode& trBranch, int nExceptNodeIndex = 1)
{
	if(!trBranch)
		return false;
		
	int ii = 0;
	foreach(TreeNode trChild in trBranch.Children)
	{
		//For ii == 0, the node is residual type node
		
		if(ii != nExceptNodeIndex)
			trChild.Show = false;
		ii++;
	}
	return true;
}
///end REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT

///------ Folger 03/19/10 QA81-15218 ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
/// move to FitterOperation.h
/*
/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
typedef	int (*FUNC_CHECK_GET_QUICK_FIT_RESULT)(GraphLayer& gl, QuickFitPlotInfo& stPlotInfo, string& strFunc, vector& vParams, string* pstrCateg = NULL, vector<string>* pvstrParamNames = NULL, bool bNLFitOnly = true);
bool	nlsf_check_get_quick_fit_result(QuickFitPlotInfo& stPlotInfo, string& strFunc, string& strCateg, vector& vParams, vector<string>& vstrParamNames)
{
	GraphLayer		gl = Project.ActiveLayer();
	if ( !gl )
		return false;
	FUNC_CHECK_GET_QUICK_FIT_RESULT		pFunc = Project.FindFunction("check_get_quick_fit_result", "OriginLab\\QuickFit.c", TRUE);
	if ( !pFunc )
		return false;
	return (0 == pFunc(gl, stPlotInfo, strFunc, vParams, &strCateg, &vstrParamNames));
}
/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME

///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
/// Iris 2/05/2010 FIX_SWITCH_TO_NLFIT_ALWAYS_USE_PARAM_INIT_VALUES
//typedef bool (*FUNC_CHECK_GET_QUICKFIT_SETTINGS)(DWORD dwQuickFitToolPtr, string& strFunc, string& strCateg, QuickFitPlotInfo& qfInfo);
//bool	nlsf_check_get_quick_fit_settings(DWORD dwQuickFitToolPtr, string& strFunc, string& strCateg, QuickFitPlotInfo& qfInfo)
typedef bool (*FUNC_CHECK_GET_QUICKFIT_SETTINGS)(DWORD dwQuickFitToolPtr, QuickFitPlotInfo& qfInfo, string& strFunc, string& strCateg, vector& vParams, vector<string>& vstrParamNames);
bool	nlsf_check_get_quick_fit_settings(DWORD dwQuickFitToolPtr, QuickFitPlotInfo& qfInfo, string& strFunc, string& strCateg, vector& vParams, vector<string>& vstrParamNames)
///End FIX_SWITCH_TO_NLFIT_ALWAYS_USE_PARAM_INIT_VALUES
{
	FUNC_CHECK_GET_QUICKFIT_SETTINGS pfn = Project.FindFunction("check_get_quick_fit_settings", "Originlab\\QuickFit.c", TRUE);
	if ( !pfn )
		return false;
	
	/// Iris 2/05/2010 FIX_SWITCH_TO_NLFIT_ALWAYS_USE_PARAM_INIT_VALUES
	//return pfn(dwQuickFitToolPtr, strFunc, strCateg, qfInfo);
	return pfn(dwQuickFitToolPtr, qfInfo, strFunc, strCateg, vParams, vstrParamNames);
	///End FIX_SWITCH_TO_NLFIT_ALWAYS_USE_PARAM_INIT_VALUES
}
///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
*/

class FitNLUpdateFromQuickfitHelper : public FitterOperationUpdateFromQuickfitHelper
{
public:
	FitNLUpdateFromQuickfitHelper(TreeNode&				trGUI
								, DWORD					dwParam
								, DWORD&				dwExeCtrl
								) :
	FitterOperationUpdateFromQuickfitHelper(trGUI
										, dwParam
										, dwExeCtrl
										)
	{
	}

	BOOL	UpdateFunction()
	{
		TreeNode 	trFuncSel = m_trGUI.FunctionSelection;
		m_trGUI.SetAttribute(STR_QUICK_FIT_ATTRIB, "");
		
		trFuncSel.CategoryList.strVal = m_strCateg;
		trFuncSel.FunctionList.strVal = m_strFunc;

		return TRUE;
	}

	BOOL	UpdateParameters()
	{
		nlsf_check_get_GUI_params_with_ID(m_trGUI, m_vstrParamNames.GetSize());

		TreeNode	trValues = m_trGUI.Parameters.Values;
		int			index = 0;
		foreach ( TreeNode trNode in trValues.Children )
		{
			if ( index >= m_vParams.GetSize() )
				break;
			trNode.dVal = m_vParams[index++];
		}
		m_trGUI.Parameters.AutoParamsInit.nVal = 0;

		return TRUE;
	}
	
private:
	virtual	void	GetIndepsAndDeps(vector<string>& vsIndeps, vector<string>& vsDeps)
	{
		nlf_get_independent_variables(m_strFunc, &vsIndeps);
		nlf_get_dependent_variables(m_strFunc, &vsDeps);
	}

	///------ Folger 03/24/10 QA81-15218-P2 SHOULD_TAKE_CARE_OF_ERROR_WHEN_SWITCH_TO_LINEAR_FIT
	virtual	int		GetDataNodeID()			{ return ONODETYPE_FITTER_DATA; }
	///------ End SHOULD_TAKE_CARE_OF_ERROR_WHEN_SWITCH_TO_LINEAR_FIT
};
///------ End ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU

//virtual 
/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
//BOOL	FitNL::OperationtoGUI(TreeNode& trOperation, bool bInit, string* pstrSelTheme, bool bSetDefaultInputOnInit) //=NULL, = true
///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
//BOOL	FitNL::OperationtoGUI(TreeNode& trOperation, bool bInit, string* pstrSelTheme, bool bSetDefaultInputOnInit, bool bFromHotkey/* = false*/) //=NULL, = true
BOOL	FitNL::OperationtoGUI(TreeNode& trOperation, bool bInit, string* pstrSelTheme, bool bSetDefaultInputOnInit, DWORD dwExeCtrl/* = 0*/, DWORD dwParam/* = 0*/) //=NULL, = true
///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
{
	//--- CPY 8/5/05 FITNL_LAST_USED should be responsibility of caller to set bSetDefaultInputOnInit
	//bSetDefaultInputOnInit = false;   /// Iris 6/10/05 NLSF_SUPPORT_XYZ_DATA, no need construct input data here, it has been constructed in InitFitSession in NLFitSplitter class and will be rebuild while function changed.
	//---
	
	///Cheney 2007-5-5 FUNC_DESCRIPTION_NOT_WORK
	TreeNode trFunctionSelection = trOperation.GUI.FunctionSelection;
	if(trFunctionSelection)
	{
		TreeNode trFuncPath = tree_check_get_node( trFunctionSelection, "SelFuncPath", 0, STR_LABEL_ATTRIB, _L("File Name(.FDF)") );
		trFuncPath.Enable = ENABLE_READ_ONLY;
	}
	///end FUNC_DESCRIPTION_NOT_WORK
		
	/// Iris 11/16/06 ADD_PARAMETER_SETTING_TO_THEME
	///Arvin 02/25/08 QA70-11151 SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION
	//nlsf_check_get_GUI_params_with_ID(trOperation.GUI);
#ifndef SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION
	nlsf_check_get_GUI_params_with_ID(trOperation.GUI);
#endif 	SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION
	///end SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION
	///end ADD_PARAMETER_SETTING_TO_THEME

	///Arvin 01/09/06 FIND_Z_FROM_XY
	///Cheney 2007-9-6 FINDZ_NODE_SHOULD_PREPARED_WHEN_CHANGE_PARAM
	//if(HasZ(trOperation))	
	//{
		//_change_calibration_branch_for_surface_fit(trOperation);
		//int  nFinXYBranchID = GetFindXYID();
		//_change_output_find_xy_branch_for_surface_fit(trOperation, nFinXYBranchID);
		/////Arvin 05/15/07 SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
		//_add_y_datatype_branch_for_surface_and_matrix_fitting(trOperation);
		/////end SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
	//}
	
	/// Iris 6/04/2008 v8.0877 FIX_XYZFIT_POINT_OF_X_DATA_TYPEIS_100
	//if(HasZ(trOperation) && bInit)
	//	UpdateCalibrationBranch(trOperation);
	///end FIX_XYZFIT_POINT_OF_X_DATA_TYPEIS_100
	
	///end FINDZ_NODE_SHOULD_PREPARED_WHEN_CHANGE_PARAM
	///end FIND_Z_FROM_XY
	///Cheney 2007-8-30 QA70-10290-sug4 FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
	///Arvin 04/27/07 v8.0609 UPDATE_OUTPUT_DESTINATION_FOR_SURFACE_FITTING as max's suggestion
	//TreeNode trData = trOperation.GUI.Output.Data;
	//TreeNode trRes = trOperation.GUI.Output.Residual;
	//int nFitType = GetFitType(trOperation);
	
	//TreeNode trResidualOut = trOperation.GUI.Output.Residual;
	//TreeNode trFindXYOut = trOperation.GUI.Output.FindXY;
	//TreeNode trReportOut = trOperation.GUI.Output.Report;
	//string strBookList, strBookDefault, strSheetList, strSheetDefault;
	//if(nFitType == NLFIT_XYZ_FITTING)
	//{
		//if(trData)
			//trData.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
		//
		//if(trResidualOut)
		//{
			//strBookList = STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS;
			//strBookDefault = STR_NEW;
			//strSheetList = STR_NEW + STR_TOKEN_SEP;
			//strSheetDefault = STR_NEW;
			//_update_output_book_sheet_destination(trResidualOut, strBookList, strBookDefault, strSheetList, strSheetDefault);
		//}
	//}
		//
	//if(nFitType == NLFIT_MATRIX_FITTING)
	//{
		//if(trData)
			//trData.SetAttribute(STR_REPORT_MATRIX_DATA, 2);
		//if(trRes)
			//trRes.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
		//
		//if(trResidualOut)
		//{
			//strBookList = STR_FIT_CURVE + STR_TOKEN_SEP + STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS;
			//strBookDefault = STR_FIT_CURVE;
			//strSheetList = STR_NEW + STR_TOKEN_SEP;
			//strSheetDefault = STR_NEW;
			//_update_output_book_sheet_destination(trResidualOut, strBookList, strBookDefault, strSheetList, strSheetDefault);
		//}
		//
		//if(trFindXYOut)
		//{
			//strBookList = STR_REPORT + STR_TOKEN_SEP + STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS;
			//strBookDefault = STR_REPORT;
			//strSheetList = STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS;
			//strSheetDefault = STR_NEW;
			//_update_output_book_sheet_destination(trFindXYOut, strBookList, strBookDefault, strSheetList, strSheetDefault);
		//}
		//
		//if(trReportOut)
		//{
			//strBookList = STR_NONE + STR_TOKEN_SEP + STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS;
			//strBookDefault = STR_NEW;
			//strSheetList = STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS;
			//strSheetDefault = STR_NEW;
			//_update_output_book_sheet_destination(trReportOut, strBookList, strBookDefault, strSheetList, strSheetDefault);
		//}
	//}
	/////end 	UPDATE_OUTPUT_DESTINATION_FOR_SURFACE_FITTING
	int nFitType = GetFitType(trOperation);
	///end FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
	
	/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
	//if(!FitterOperation::OperationtoGUI(trOperation, bInit, pstrSelTheme, bSetDefaultInputOnInit))
	///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	//if ( bFromHotkey && bInit )
	if ( (dwExeCtrl & LTXF_FROM_HOTKEY || dwExeCtrl & LTXF_FROM_CONTEXT_MENU) && bInit )
	///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	{
		///------ Folger 03/19/10 QA81-15218 ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
		/*
		string			strFunc, strCateg;
		vector			vParams;
		vector<string>	vstrParamNames;
		QuickFitPlotInfo	stPlotInfo;
		
		bool bRet = false;
		if ( dwExeCtrl & LTXF_FROM_HOTKEY )
			bRet = nlsf_check_get_quick_fit_result(stPlotInfo, strFunc, strCateg, vParams, vstrParamNames);
		else if ( dwExeCtrl & LTXF_FROM_CONTEXT_MENU )
		{
			/// Iris 2/05/2010 FIX_SWITCH_TO_NLFIT_ALWAYS_USE_PARAM_INIT_VALUES
			//bRet = nlsf_check_get_quick_fit_settings(dwParam, strFunc, strCateg, stPlotInfo);
			bRet = nlsf_check_get_quick_fit_settings(dwParam, stPlotInfo, strFunc, strCateg, vParams, vstrParamNames);
			///End FIX_SWITCH_TO_NLFIT_ALWAYS_USE_PARAM_INIT_VALUES
			///Sophy 1/15/2010 QA80-14832 QUICKFIT_SWITCH_TO_NLFIT_SHOULD_USE_EXISTING_DATAMARKER_WHEN_SELECT_RANGE
			//the following code avoid reseting inputdata to active dataplot when there is not data marker(No range selected)
			if ( (0 == stPlotInfo.nFrom) && (-1 == stPlotInfo.nTo) )
				dwExeCtrl &= ~LTXF_FROM_CONTEXT_MENU;
			///end QUICKFIT_SWITCH_TO_NLFIT_SHOULD_USE_EXISTING_DATAMARKER_WHEN_SELECT_RANGE
		}
			
		if ( bRet )
		{
			DataPlot	dp;
			dp = Project.GetObject(stPlotInfo.nUID);
			if ( dp )
			{
				if ( pstrSelTheme )
				{
					pstrSelTheme->Empty();
					pstrSelTheme = NULL;
				}
				bSetDefaultInputOnInit = false;
				
				XYRange		dr;
				dp.GetDataRange(dr, stPlotInfo.nFrom, stPlotInfo.nTo);
				Tree		trRange;
				dr.GetTree(trRange);
				vector<string>	vsIndep, vsDep;
				nlf_get_independent_variables(strFunc, &vsIndep);
				nlf_get_dependent_variables(strFunc, &vsDep);
				okutil_create_fitter_data_node_ex(&trRange, NULL, STR_INPUT_RANGE_NAME, STR_INPUT_RANGE_LABEL, &vsIndep, &vsDep, WEIGHT_NONE);
				
				TreeNode	trGUI = trOperation.GUI;
				TreeNode 	trFuncSel = trGUI.FunctionSelection;
				trGUI.SetAttribute(STR_QUICK_FIT_ATTRIB, "");
				trGUI.InputData.Replace(trRange, TRUE, TRUE, TRUE);
				trGUI.InputData.ID = ONODETYPE_FITTER_DATA;
				///Sophy 2/22/2010 QA80-14832 QUICKFIT_SWITCH_TO_NLFIT_SHOULD_USE_EXISTING_DATAMARKER_WHEN_SELECT_RANGE
				if ( (LTXF_FROM_CONTEXT_MENU & dwExeCtrl) && trGUI.InputData.FirstNode )
				{
					vector<int> vBegins, vEnds;
					vector<uint> vIDs;
					dp.GetDataMarkers(vBegins, vEnds, vIDs);
					int nMarkerIndex = vIDs.GetSize() - 1;
					if ( nMarkerIndex >= 0 )
						trGUI.InputData.FirstNode.SetAttribute(STR_DATA_MARKER_ID_ATTRIB, vIDs[nMarkerIndex]);
				}
				///end QUICKFIT_SWITCH_TO_NLFIT_SHOULD_USE_EXISTING_DATAMARKER_WHEN_SELECT_RANGE
			
				TreeNode 	trFuncSel = trGUI.FunctionSelection;
				trGUI.SetAttribute(STR_QUICK_FIT_ATTRIB, "");
				
				trFuncSel.CategoryList.strVal = strCateg;
				trFuncSel.FunctionList.strVal = strFunc;
				
				nlsf_check_get_GUI_params_with_ID(trGUI, vstrParamNames.GetSize());
				TreeNode	trValues = trGUI.Parameters.Values;
				int			index = 0;
				foreach ( TreeNode trNode in trValues.Children )
				{
					if ( index >= vParams.GetSize() )
						break;
					trNode.dVal = vParams[index++];
				}
				trGUI.Parameters.AutoParamsInit.nVal = 0;
			}
		}
		*/
		FitNLUpdateFromQuickfitHelper		clHelper(trOperation.GUI, dwParam, dwExeCtrl);
		
		if ( clHelper.UpdateData() )
		{
			clHelper.UpdateConditions(pstrSelTheme, bSetDefaultInputOnInit);
			
			clHelper.UpdateFunction();
			clHelper.UpdateParameters();
		}
		///------ End ADD_LINEAR_FIT_AND_POLYNOMIAL_FIT_TO_QUICKFIT_CONTEXT_MENU
	}
	///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	//if(!FitterOperation::OperationtoGUI(trOperation, bInit, pstrSelTheme, bSetDefaultInputOnInit, bFromHotkey))
	if(!FitterOperation::OperationtoGUI(trOperation, bInit, pstrSelTheme, bSetDefaultInputOnInit, dwExeCtrl, dwParam))
	///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
		return error_report("FitterOperation::OperationtoGUI failed");
	
	if ( GetFitType(trOperation) != NLFIT_GENERAL_XY_FITTING ) ///Sophy 1/19/2009 v8.0960 NOT_ALWAYS_NEED_TO_CHECK_SETTTING_FOR_3D_FITTING
		updateOutputSettingFor3DFitting(trOperation); ///Cheney 2007-8-30 QA70-10290-sug4 FIX_STH_ABOUT_OUTPUT_SETTING_FOR_3D_FIT
	
	string strCategory, strFunc;
	vector<string> vsFuncFilterList;
	bool bIsCategoryAllowedChange = GetCategoryFuncNames(trOperation, strCategory, strFunc, vsFuncFilterList);
	/// ML 11/7/2005 QA70-8135 SURFACE_FITTING_VIA_XFUNC_NEW_WAY
	// It seems logical to me that if category cannot be changed, then this should be the only category. So here I provide
	// the category filter for that case:
	vector<string> vsCatsFilterList;
	if (!bIsCategoryAllowedChange && !strCategory.IsEmpty())
		vsCatsFilterList.Add(strCategory);
	/// end SURFACE_FITTING_VIA_XFUNC_NEW_WAY

	TreeNode trFuncSel = trOperation.GUI.FunctionSelection;
	trFuncSel.CategoryList.Enable = bIsCategoryAllowedChange;
	bool bUseFuncInTree = false;
	if(bIsCategoryAllowedChange && !trFuncSel.CategoryList.strVal.IsEmpty() && !trFuncSel.FunctionList.strVal.IsEmpty())
	{
		// already have selection, do not need to init
		bUseFuncInTree = true;
	} 
	else if(!bIsCategoryAllowedChange && !strCategory.IsEmpty() && strCategory.CompareNoCase(trFuncSel.CategoryList.strVal) == 0 &&
		(vsFuncFilterList.GetSize()==0 || is_in_list(trFuncSel.FunctionList.strVal, vsFuncFilterList)))
	{
		bUseFuncInTree = true;
	}
	if(bUseFuncInTree)
	{
		strCategory = trFuncSel.CategoryList.strVal;
		strFunc = trFuncSel.FunctionList.strVal;
	}
	NLFitSelFunction	mySelFunc(trOperation.GUI.FunctionSelection);
	///------ Folger 11/05/09 QA81-14595-P1 NLFIT_SHOULD_NOT_LOAD_GAUSS_WHEN_DO_ANALYSIS_WITH_THEME_WHICH_HAS_NO_FUNCTION
	mySelFunc.SetInitFromNLFit(TRUE);
	///------ End NLFIT_SHOULD_NOT_LOAD_GAUSS_WHEN_DO_ANALYSIS_WITH_THEME_WHICH_HAS_NO_FUNCTION
	/// ML 11/7/2005 QA70-8135 SURFACE_FITTING_VIA_XFUNC_NEW_WAY
	//bool bOK = mySelFunc.Init(strCategory, strFunc, &vsFuncFilterList);
	//bool bOK = mySelFunc.Init(strCategory, strFunc, &vsFuncFilterList, vsCatsFilterList.GetSize() > 0 ? &vsCatsFilterList : NULL);///Jasmine 03/13/06 REPLACE_VECTOR_POINTER_WITH_VECTOR, the pointer leads to strange crash
	bool bOK = mySelFunc.Init(strCategory, strFunc, vsFuncFilterList, vsCatsFilterList);
	/// end SURFACE_FITTING_VIA_XFUNC_NEW_WAY
	
	///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
	//1.if from GUI or Change Parametert, will load FDF tree in OperationtoGUI,
	//  then pass it into NLFitSplitter in ShowDlg.
	//2.if from theme, will load FDF tree in UpdateInputBranch.
	//  then set it to NLFitSession when CalMultiData, because here will init pFitSession 
	//3.if auto update, will get FDF tree from NLFitSession after call initfromOperationTree
	//4.if open Dlg and sel func change, 
	//  should reload FDF tree in SelFuncchange in NLFitSplitter.h
	//  will get FDF tree from NLFitSession when call CalcMultiData after Click OK
	if(!isFDFTreeValid())//if(m_trFDF.Children.Count() == 0)//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
	{
		///Cheney 2007-7-30 ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
		//string strFilenameTemp;
		//nlf_get_fdf_filename(trFuncSel.FunctionList.strVal, NULL, NULL, &strFilenameTemp);
		/////Cheney 2007-6-8 ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC
		////if(!nlsf_FDF_to_tree(strFilenameTemp, &m_trFDF, FDFT_CONVERT_BOOL_TO_01))
		//if(!nlsf_load_FDF_to_tree(strFilenameTemp, &m_trFDF, FDFT_CONVERT_BOOL_TO_01, true))
		/////end ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC
			//return false;
		if(!LoadFDFtoTree(trFuncSel.FunctionList.strVal))
			return false;
		///end ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
	}
	///end CLEAN_UP_FDF_TREE_LOAD
	
	//---- CPY 12/13/04 KEEP_SESSION_TEMP_GRAPH_WHEN_FIT_FROM_WKS
	// this is a better place to init this, but still not the best, can 
	TreeNode trKeepSessionGraph = trOperation.GUI.Output.KeepSessionGraph;
	if(trKeepSessionGraph)
	{
		Worksheet wks  = Project.ActiveLayer();
		if(wks)
			trKeepSessionGraph.Show = true;
		else
		{
			trKeepSessionGraph.Show = false;
			trKeepSessionGraph.nVal = false;
		}
	}
	//----	
	
	///Cheney 2007-5-29 SHOULD_HIDE_RES_ANALYSIS_IF_MULTI_XY_FITTING
	if(GetNumX(trOperation) > 1 || GetNumY(trOperation) > 1)
	{
		trOperation.GUI.ResAnalysis.Show = false;
		trOperation.GUI.Residuals.ResType.Show = false;
	}
	///end SHOULD_HIDE_RES_ANALYSIS_IF_MULTI_XY_FITTING
	
	//--- Iris 10/17/06 NOT_SUPPORT_FINDXY_FOR_SURFACE_AND_MR
	//
	if(HasZ(trOperation))
	{	
		///Cheney 2007-5-29 SHOULD_HIDE_RES_ANALYSIS_IF_MULTI_XY_FITTING
		/////Arvin 12/09/06 HIDE_RESIDUAL_ANALYSIS_FOR_SURFACE_FIT
		//trOperation.GUI.ResAnalysis.Show = false;
		//trOperation.GUI.Residuals.ResType.Show = false;
		/////END HIDE_RESIDUAL_ANALYSIS_FOR_SURFACE_FIT
		///end SHOULD_HIDE_RES_ANALYSIS_IF_MULTI_XY_FITTING
		
		///Arvin 12/08/06 HIDE_CONF_PRED_CONV_AND_CORR_FOR_SURFACE_FIT
		///Arvin 05/08/07 QA70-9498 SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
		//trOperation.GUI.Quantities.mCov.Show = false;
		//trOperation.GUI.Quantities.mCor.Show = false;
		///end SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
		TreeNode trGraph = GetGUIGraphNodes(trOperation, GRAPH_FIT_CURVE);
		if(trGraph)
		{
			trGraph.ConfBands.Show = false;
			trGraph.PredBands.Show = false;
			trGraph.Confidence.Show = false;
		}
		///end HIDE_CONF_PRED_CONV_AND_CORR_FOR_SURFACE_FIT
		
		//------ Folger 05/30/08 QA80-11632 HIDE_SOURCE_PLOT_RELATED_NODE_FOR_3D_FITTING
		trGraph.PlotFit.Show = false;
		#ifdef	MARKER_VISIBILITY_OPTIONS
		trGraph.ShowMarker.Show = false;
		#endif//	MARKER_VISIBILITY_OPTIONS
		trGraph.UpdateLegend.Show = false;
		//------
		
		///Arvin 11/22/07 ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
		//As max's suggestion, hide set color node
		trGraph.SetColor.Show = false;
		trGraph.SetColor.nVal = 0;
		///end ADD_CHECKBOX_USE_SOURCE_GRAPH_COLOR_TO_SET_FITCURVES_COLOR
		///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode trPlotInOneGraph = trOperation.GUI.Output.PlotSettings.PlotInOneGraph;
		TreeNode trPlotInOneGraph = OP_GUI_GRAPH_ARRANGEMENT_NODE(trOperation.GUI).PlotInOneGraph;
		///end OP_DLG_NEW_STRUCTURE
		if(trPlotInOneGraph)
		{
			trPlotInOneGraph.Show = false;
			trPlotInOneGraph.nVal = 0;
		}
		///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
	}
	//---
	
	/// Iris 11/14/06 v8.0510 REMOVE_FITCURVE_OPTION_FROM_RESIDUAL_BOOK_SHEET_FOR_2D_FIT
	///Arvin 04/27/07 v8.0609 UPDATE_OUTPUT_DESTINATION_FOR_SURFACE_FITTING as max's suggestion
	//if(HasZ(trOperation))
	//{
		//TreeNode trResidualOut = trOperation.GUI.Output.Residual;
		//trResidualOut.Book.SetAttribute(STR_COMBO_ATTRIB, STR_NEW + STR_TOKEN_SEP + STR_CUSTOM + STR_THREE_DOTS);
		//trResidualOut.Book.strVal = STR_NEW;
		//trResidualOut.Sheet.SetAttribute(STR_COMBO_ATTRIB, STR_NEW);
		//trResidualOut.Sheet.strVal = STR_NEW		
	//}
	///end UPDATE_OUTPUT_DESTINATION_FOR_SURFACE_FITTING
	///end REMOVE_FITCURVE_OPTION_FROM_RESIDUAL_BOOK_SHEET_FOR_2D_FIT
	
	/// Iris 04/03/2007 v8.0595 REMOVE_DATA_MODE_ATTRI_FOR_SURFACE_FIT
	//From CP, Surface Fit should not show Data mode
	if( HasZ(trOperation) )
	{
		trOperation.GUI.InputData.RemoveAttribute(STR_ATTRIB_BRANCH_COMBO);
		///Arvin 04/05/07 v8.0596 SHOULD_REMOVE_USE_ATTRIBUTE_AND_HIDE_X_Y_DATA_FOR_MATRIX_FIT
		trOperation.GUI.InputData.RemoveAttribute(STR_USE_ATTRIB);
		int nFitType = GetFitType(trOperation);
		if(nFitType == NLFIT_MATRIX_FITTING)
		{
			trOperation.GUI.InputData.Range1.X.Show = false;
			trOperation.GUI.InputData.Range1.Y.Show = false;
			///Arvin 04/17/07 v8.0602 FIT_MATRIX_ONLY_NEED_THREE_GRAPH
			///Arvin 03/10/08 QA70-11234 REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
			//TreeNode trResiduals = trOperation.GUI.Residuals;
			//if(trResiduals)
			//{
			//
				//trResiduals.Graph4.nVal = 0;
				//trResiduals.Graph4.Show = false;
				//trResiduals.Graph5.nVal = 0;
				//trResiduals.Graph5.Show = false;
				//trResiduals.Graph6.nVal = 0;
				//trResiduals.Graph6.Show = false;
			//}
			///end REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
			///end FIT_MATRIX_ONLY_NEED_THREE_GRAPH
		}
		///Arvin 03/10/08 QA70-11234 REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
		//Hide node of residual type and all other plots except "Residual vs. Independent Plot" nodes. 
		TreeNode trResiduals = trOperation.GUI.Residuals;
		if(trResiduals)
			_hide_children_nodes_for_branch(trResiduals, 1);
		//Hide all nodes except "Plot in Report Table" node under fitted curves branch 
		/// Iris 5/5/2008 QA80-11234 HIDE_X_DATA_TYPE_FOR_3DIT_AND_MATFIT_IS_WRONG
		/*
		TreeNode trFittedCurves = trOperation.GUI.Graph1;
		if(trFittedCurves)
			_hide_children_nodes_for_branch(trFittedCurves, 0);
		*/
		///end HIDE_X_DATA_TYPE_FOR_3DIT_AND_MATFIT_IS_WRONG
		///end REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
		///end SHOULD_REMOVE_USE_ATTRIBUTE_AND_HIDE_X_Y_DATA_FOR_MATRIX_FIT
	}
	///Arvin 03/12/08 REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT as CP said
	if(bInit && HasZ(trOperation))
	{
		///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
		//TreeNode trInitMethod = trOperation.GUI.Fit.Replica.ReplicaInitParam.InitMethod;
///Arvin 03/28/08 HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT
		//TreeNode trMinHeight = trOperation.GUI.Replica.ReplicaInitParam.MinHeight;
		TreeNode trReplica = trOperation.GUI.Replica;
#ifdef 	HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT
		if(trReplica)
		{
			trReplica.Show = false;
			trReplica.Number.nVal = 0;
		}
#endif  //HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT
		TreeNode trMinHeight = trReplica.ReplicaInitParam.MinHeight;
///end 	HIDE_REPLICA_BRANCH_FOR_SURFACE_FIT	
		if(trMinHeight)
			trMinHeight.SetAttribute(STR_LABEL_ATTRIB, STR_MIN_HEIGHT_SURFACE_LABEL);
		TreeNode trInitMethod = trOperation.GUI.Replica.ReplicaInitParam.InitMethod;
		///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		if(trInitMethod)
		{
			trInitMethod.SetAttribute(STR_ATTRIB_BRANCH_COMBO, STR_SURFACEFIT_LIST_REPLICA_FINDING_PEAK_METHODS);
			trInitMethod.Use = 0; //default method is local maximum
		}
	}
	///end REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT
	///end REMOVE_DATA_MODE_ATTRI_FOR_SURFACE_FIT
	/// Arvin 04/06/07 v8.0596 REMOVE_DATA_MODE_ATTRI_FOR_MULTI_X_AND_MULTI_Y by max's suggestion
	///------ Folger 04/03/09 OPEN_NLFIT_WITH_MULTI_SETS_PLUS_MULTI_INDEPS_DEPS_FROM_THEME_MISSING_ERROR_MSG
	//if(GetNumX(trOperation) > 1 || GetNumY(trOperation) > 1)
	if( NLFIT_GENERAL_XY_FITTING != nFitType && (GetNumX(trOperation) > 1 || GetNumY(trOperation) > 1) )
	///------ End OPEN_NLFIT_WITH_MULTI_SETS_PLUS_MULTI_INDEPS_DEPS_FROM_THEME_MISSING_ERROR_MSG
	{
		trOperation.GUI.InputData.RemoveAttribute(STR_ATTRIB_BRANCH_COMBO);
		trOperation.GUI.InputData.RemoveAttribute(STR_USE_ATTRIB);
	}
	///end REMOVE_DATA_MODE_ATTRI_FOR_MULTI_X_AND_MULTI_Y
	///Cheney 2007-8-20 v8.0685 QA70-10256-P12 SHOUDL_HIDE_MASKED_DATA_CHECK_BOX_IF_MATRIX_FIT
	if(nFitType == NLFIT_MATRIX_FITTING)
		trOperation.GUI.OutPut.Create.MaskedData.Show = false;
	///end SHOUDL_HIDE_MASKED_DATA_CHECK_BOX_IF_MATRIX_FIT
	///Cheney 2007-11-16 ONLY_NLFIT_XYFITTING_SHOW_REPLICA_RELATED_CHECK_BOX
	if( HasZ(trOperation) )
		hideReplicaRelatedNode(trOperation.GUI.Quantities.Statistics);
	///end ONLY_NLFIT_XYFITTING_SHOW_REPLICA_RELATED_CHECK_BOX

	return bOK;
}

/// Iris 3/12/2009 CLEANUP_UpdateDataModeNode_CODES
/*
///Arvin 01/03/08 SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS as cp said
void FitNL::UpdateDataModeNode(TreeNode& trOp, int nDataMode, int nTotalNumData)
{
	if(nTotalNumData > 1 || MDINPUT_CMBND_SIMPLE == nDataMode)
	{
		TreeNode		trTable = GetTreeNode_Notes(trOp);
		if( trTable )
		{
			string		strCombo;
			if(!trOp.GUI.InputData.GetAttribute(STR_ATTRIB_BRANCH_COMBO, strCombo))
				 strCombo = L_STR_FIT_MODES_COMBO;
			
			string		str = strCombo.GetToken(nDataMode, '|');
			if( !str.IsEmpty() )
			{
				trTable.DataMode.strVal = str;
				trTable.DataMode.ID = IDE_NOTES_DATA_MODE;
				trTable.DataMode.SetAttribute(STR_LABEL_ATTRIB, WKSH_OPERATION_INFO_DATA_MODE);
			}
		}
	}		
}
///end SHOULD_ALWAYS_SHOW_DATA_MODE_WHEN_FIT_MULTI_DATASETS
*/
string FitNL::GetFitModeCombo()
{
	return L_STR_FIT_MODES_COMBO;
}
///end CLEANUP_UpdateDataModeNode_CODES

	
///Arvin 10/25/06 ORIGINAL_DATA_SCATTER_UNSHOW
int 	FitNL::GetNumY(TreeNode& trOp) 
{ 
	///Cheney 2007-4-13 CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
	//if change func, m_nNumberDepVariables maybe change
	if(NULL != m_pFitSession)
		m_pFitSession->GetNumVars(&m_nNumberDepVariables, NULL);
	
	if(m_nNumberDepVariables <= 0)
	//if(m_nNumberDepVariables < 0)
	///end CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
	{
		TreeNode 	trFuncNode = trOp.GUI.FunctionSelection.FunctionList;
		if(trFuncNode)
		{	
			//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
			checkUpdateFDFTree(trFuncNode.strVal);
			//------
			
			///Cheney 2007-4-9 CORRECT_LOGIC_OF_CALLING_INIT_BRANCH
			//m_nNumberDepVariables = nlf_get_dependent_variable_number(trFuncNode.strVal);
			///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
			//m_nNumberDepVariables = nlf_get_dependent_variables(trFuncNode.strVal);
			m_nNumberDepVariables = nlf_get_dependent_variables(m_trFDF);
			///end CLEAN_UP_FDF_TREE_LOAD
			///end CORRECT_LOGIC_OF_CALLING_INIT_BRANCH
		}
	}
	return m_nNumberDepVariables;
}
///end ORIGINAL_DATA_SCATTER_UNSHOW

///Iris 9/21/06 MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
//virtual 
int 	FitNL::GetNumX(TreeNode& trOp) 
{ 
	///Cheney 2007-4-13 CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
	//GetNumX will always return indepedent var's num
	//if change func, m_nNumberIndepVariables maybe change
	if(NULL != m_pFitSession)
		m_pFitSession->GetNumVars(NULL, &m_nNumberIndepVariables);
	
	if(m_nNumberIndepVariables <= 0)
	//if(m_nNumberIndepVariables < 0)
	{
		TreeNode 	trFuncNode = trOp.GUI.FunctionSelection.FunctionList;
		if(trFuncNode)
		{
			//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
			checkUpdateFDFTree(trFuncNode.strVal);
			//------
			
			///Cheney 2007-4-9 CORRECT_LOGIC_OF_CALLING_INIT_BRANCH
			//m_nNumberIndepVariables = nlf_get_independent_variable_number(trFuncNode.strVal);
			///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
			//m_nNumberIndepVariables = nlf_get_independent_variables(trFuncNode.strVal);
			m_nNumberIndepVariables = nlf_get_independent_variables(m_trFDF);
			///end CLEAN_UP_FDF_TREE_LOAD
			///end CORRECT_LOGIC_OF_CALLING_INIT_BRANCH
			
			///Cheney 2007-4-13 CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
			//if(2 == m_nNumberIndepVariables && HasZ(trOp))
				//m_nNumberIndepVariables = 1;
			///end CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
		}
	}
	return m_nNumberIndepVariables;
}	

//virtual 
int 	FitNL::GetReportGraphTableColNum(TreeNode& trOp, int nGraphIndex, bool bSkipPlotInOneGraphNode) 
{ 
	/// Iris 02/27/2007 FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC
	//if(nGraphIndex == GRAPH_FIT_CURVE) //temp for fit curve, residual later
	if( GetNumX(trOp) > 1 || GetNumY(trOp) > 1)
	{
		if(GRAPH_RESIDUALS_HISTOGRAM != nGraphIndex)
		///end FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC
		{
			///Cheney 2007-4-13 CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
			//int 	nXs = GetNumX(trOp);
			int nFitType = GetFitType(trOp);
			int nXs = nFitType == NLFIT_MATRIX_FITTING || nFitType == NLFIT_XYZ_FITTING ?
									1 : GetNumX(trOp);
			//if(nXs > 1)
			///end CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
				return nXs;		
		}
	}
	return FitterOperation::GetReportGraphTableColNum(trOp, nGraphIndex, bSkipPlotInOneGraphNode);	
}

int    	FitNL::GetReportGraphTableRowNum(TreeNode& trOp, int nGraphIndex, bool bSkipPlotInOneGraphNode)
{
	/// Iris 02/27/2007 FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC
	//if(nGraphIndex == GRAPH_FIT_CURVE) //temp for fit curve, residual later
	if( GetNumX(trOp) > 1 || GetNumY(trOp) > 1)
	{
		if(GRAPH_RESIDUALS_HISTOGRAM != nGraphIndex)
		///end FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC
		{
			///Cheney 2007-4-13 CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
			//int 	nYs = GetNumY(trOp);
			int nFitType = GetFitType(trOp);
			///Sophy 12/24/2008 v8.0990 QA80-12832 SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
			int nYs = nFitType == NLFIT_MATRIX_FITTING || nFitType == NLFIT_XYZ_FITTING ?
									1 : GetNumY(trOp);
			///------ Folger 01/19/09 SUPPORT_MULTI_SETS_FOR_MULTI_DEPS_INDEPS_MAKE_RESET_ALL_GRAPHS_BROKEN
			//nYs = nYs * m_pFitSession->GetNumDataset();
			nYs = nYs * GetTotalNumData(trOp);
			///------ End SUPPORT_MULTI_SETS_FOR_MULTI_DEPS_INDEPS_MAKE_RESET_ALL_GRAPHS_BROKEN
			///end SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
			//if(nYs > 1)
			///end CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
				return nYs;
		}
	}
	return FitterOperation::GetReportGraphTableRowNum(trOp, nGraphIndex, bSkipPlotInOneGraphNode);
}
///end MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH

///Jasmine 05/18/07 ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO
//bool nlf_on_change_category(TreeNode& trGUI, int nRow, int nType, Dialog& Dlg)
bool nlf_on_change_category(TreeNode& trGUI, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& Dlg)
{	
	string strCategory = trNode.strVal;
	if(!strCategory.Compare(STR_NEW_DOT_DOT_DOT))
		return nlf_on_fo(trGUI, nRow, nCol, trNode, dwCntrl, nType, Dlg);
	
	/// TD 5-5-06
	//NLFitSelFunction funcSel(trGUI.FunctionSelection);
	NLFitSelFunction funcSel(trGUI);
	//------
	funcSel.OnChangeCategoryUpdateFunctionList();
	return true;
}
	
bool nlf_on_change_function(TreeNode& trGUI, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& Dlg)
{
	if(!trNode.strVal.Compare(STR_NEW_DOT_DOT_DOT))
		return nlf_on_fo(trGUI, nRow, nCol, trNode, dwCntrl, nType, Dlg);
	return true;
}
///End ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO
bool nlf_on_weighting_method_update(TreeNode& trGUI, int nRow, int nType, Dialog& Dlg)
{
	//TreeNode trWtMethod = trGUI.Fit.Weighting;
	TreeNode trWTMethod = tree_get_node(trGUI, nRow);
	TreeNode trWT;
	trWT = trWTMethod.Parent();
	if( !trWTMethod || !trWT )
		return false;	
	
	int 	nWT = trWTMethod.nVal;
	int 	nShowA, nShowB, nShowC;
	
	switch(nWT)
	{
	case WEIGHT_INVERSE_DATA_VALUE_A_B:
	case WEIGHT_IRWLS_INVERSE_FUNC_VALUE_A_B:
		nShowA = nShowB = 1;
		nShowC = 0;
		break;
	case WEIGHT_INVERSE_DATA_VALUE_A_B_WITH_ASSAY_SENSITIVITY_TERM:
	case WEIGHT_INVERSE_DATA_VALUE_A_B_C_WITH_TIME_INFORMATION:
	case WEIGHT_IRWLS_INVERSE_FUNC_VALUE_A_B_WITH_ASSAY_SENSITIVITY_TERM:
	case WEIGHT_IRWLS_INVERSE_FUNC_VALUE_A_B_C_WITH_TIME_INFORMATION:
		nShowA = nShowB = nShowC = 1;
		break;		
	default:
		nShowA = nShowB = nShowC = 0;
		break;
	}
	
	trWT.a.Show = nShowA;
	trWT.b.Show = nShowB;
	trWT.c.Show = nShowC;

	return true;
}

bool nlf_on_change_replica_number(TreeNode& trGUI, int nRow, int nType, Dialog& Dlg)
{
	TreeNode 	trNumber = tree_get_node(trGUI, nRow);
	string		strNum = trNumber.strVal;
	int			nNum = atoi(strNum);
	if(nNum < 0)
	{
		MessageBox(NULL, _L("The number of Replica must be larger than or equal to 0!"), _L("Error"), MB_OK | MB_ICONSTOP);
		trNumber.strVal = "1";
	}
	return true;	
}

bool nlf_on_change_delta_fixed(TreeNode& trGUI, int nRow, int nType, Dialog& Dlg)
{
	TreeNode 	trFixed = tree_get_node(trGUI, nRow);
	if(trFixed && trFixed.Enable)
	{
		bool 		bChecked = trFixed.nVal;
		
		//the Minimum and Maximum text box should be inactive when the Fixed box is check
		TreeNode 	trDelta = trFixed.Parent();
		TreeNode 	trMin = trDelta.Minimum;
		TreeNode 	trMax = trDelta.Maximum;
		trMin.Enable = !bChecked;
		trMax.Enable = !bChecked;
		return true;	
	}
	return false;
}
///Jasmine 05/18/07 ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO, uncomment 
///Joseph	12/11/06	ADD_OPEN_FO_BITMAPBUTTON
//typedef BOOL (*_FUNC_STR) (string& strSel);
///// TD 5-5-06
bool nlf_on_fo(TreeNode& trGUI, int nRow, int nCol, TreeNode& trNode, DWORD dwCntrl, int nType, WndContainer& theDlg)
{
   if(!(dwCntrl & GETNEVENT_ON_INIT))
   {
   		///Jasmine 06/08/07 INTERACTIVE_CHANGE_SAVING_BETWEEN_FO_AND_NLFIT
   		///Jasmine 05/18/06 RETURN_SEL_FUNCTION
   		//BOOL_FUNC _pfn = Project.FindFunction("Foopen", "OriginLab\\FunctionOrganizerDlg.cpp", TRUE);
   		//_FUNC_STR _pfn = Project.FindFunction("OpenFO", "OriginLab\\FunctionOrganizerDlg.cpp", TRUE);
   		//FUNC_STR_DWORD_HWND _pfn = Project.FindFunction("OpenFO", "OriginLab\\FunctionOrganizerDlg.cpp", TRUE);
		FUNC_STR_DWORD_HWND_TREENODE _pfn = Project.FindFunction("OpenFO", "OriginLab\\FunctionOrganizerDlg.cpp", TRUE);
		if(_pfn)	
   		{
   			string str;
   			///Jasmine 11/24/06 SEL_FUNC_AFTER_OPEN
   			TreeNode trCate = tree_get_node_by_id(trGUI, IDE_NLSF_CATEGORY), trFunc = tree_get_node_by_id(trGUI, IDE_NLSF_FUNCTION);
   			if(!trCate.IsValid() || !trFunc.IsValid())
   				return false;
   			str = trCate.strVal +"|"+ trFunc.strVal;
   			///Jasmine 05/29/07 ONLY_SHOW_SPECIFIED_CATEGORY_FOR_SPECIAL_FIT
			DWORD dw;
			if(false == trCate.Enable)
				dw = 1;//temp
			TreeNode trChangedFDFs;//doing
   			if(_pfn(str, dw, theDlg.GetSafeHwnd(), trChangedFDFs))
   		///End INTERACTIVE_CHANGE_SAVING_BETWEEN_FO_AND_NLFIT
   			///End ONLY_SHOW_SPECIFIED_CATEGORY_FOR_SPECIAL_FIT
   			{
   				/*
			 	TreeNode tr;
			 	vector<int> nIDs = {IDE_NLSF_CATEGORY, IDE_NLSF_FUNCTION};
			 	for(int ii = 0; ii < nIDs.GetSize(); ii++)
			 	{
			 		tr = tree_get_node_by_id(trGUI, nIDs[ii]);
			 		if(tr.IsValid())
			 			tr.strVal = str.GetToken(ii,'|');
			 	}
			 	*/
			 	trCate.strVal = str.GetToken(0,'|');
			 	trFunc.strVal = str.GetToken(1,'|');
			///End SEL_FUNC_AFTER_OPEN			 	
   				//trGUI
   				NLFitSelFunction funcSel(trGUI);
   				///Jasmine 05/18/07 ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO 
   				// trGUI also need update for category change only
			 	//string strCat, strName;
			 	//if(funcSel.GetCategoryAndFunction(strCat, strName))
			 	//{
			 		funcSel.Init(trCate.strVal, trFunc.strVal);
			 	//}
			 	///End ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO
		///End RETURN_SEL_FUNCTION
				return true;///Jasmine 08/06/08 RETURN_TRUE_WHEN_CLICK_OK_TO_INDICATE_FUNCTION_CHANGE
  			}
   		}
   }
	return false;
}
///End	ADD_OPEN_FO_BITMAPBUTTON
///End ADD_NEW_AT_LIST_BOTTOM_TO_OPEN_FO
/// TD 9-2-06 QA70-9012 DYNACONTROL_MULTILINEEDIT_BUTTON
#define ADD_CODEBUILDER_BUTTON_FIT_FUNCTION  	 _tmpSubNode.SetAttribute(STR_MULTILINE_BUTTON_ID_ATTRIB, IDC_OPEN_IN_CODE_BUILDER_BUTTON_FIT_FUNCTION);
#define ADD_CODEBUILDER_BUTTON_PARA_INIT  	 	_tmpSubNode.SetAttribute(STR_MULTILINE_BUTTON_ID_ATTRIB, IDC_OPEN_IN_CODE_BUILDER_BUTTON_PARA_INIT);
/// end DYNACONTROL_MULTILINEEDIT_BUTTON
//-----------

//virtual
void FitNL::ConstructAddBeforeQuantitiesToCompute(TreeNode& trGUI)
{
	GETN_USE(trGUI)
	GETN_BEGIN_BRANCH(FunctionSelection, _L("Function Selection")) GETN_ID_BRANCH(IDST_NLSF_FUNC_SEL_OPTIONS) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		/// ML 11/6/2006 SELECT_FITTING_FUNCTION_PANEL_CHANGES
		//GETN_STR(Info," ",_L("To add new function, you need to open the Fitting Function Organizer")) GETN_READ_ONLY_COLOR	   
		//GETN_BUTTON_GROUP(Button, "Button", 0, "Open...")  GETN_OPTION_EVENT_EX(nlf_on_fo) GETN_OPTION_DISPLAY_FORMAT(DISPLAY_EDITOR_RIGHT)
		//GETN_STR(Info1," ",_L("Select fitting function from the lists below")) GETN_READ_ONLY_COLOR
		/// end SELECT_FITTING_FUNCTION_PANEL_CHANGES
		GETN_STR(CategoryList, _L("Category"), "") GETN_ID(IDE_NLSF_CATEGORY) //GETN_OPTION_EVENT_EX(nlf_on_change_category)//GETN_OPTION_EVENT(nlf_on_change_category)
		GETN_STR(FunctionList, _L("Function"), "") GETN_ID(IDE_NLSF_FUNCTION) //GETN_OPTION_EVENT_EX(nlf_on_change_function)
		//GETN_STR(SelFuncFile, "FDF", "") GETN_READ_ONLY_COLOR
		GETN_STR(SelFuncDesc, _L("Description"), "") GETN_READ_ONLY_COLOR	///Jasmine 01/27/07 SHOW_FUNC_DESCRIPTION_INSTEAD_OF_FDF_PATH
		///Joseph	12/11/06	ADD_OPEN_FO_BITMAPBUTTON
		///// ML 11/6/2006 SELECT_FITTING_FUNCTION_PANEL_CHANGES
		//GETN_STR(Info," ",_L("To add new function, you need to open the Fitting Function Organizer")) GETN_READ_ONLY_COLOR GETN_OPTION_COLOR_READONLY(0)	   
		//GETN_BUTTON_GROUP(Button, "", 0, "Organizer...")  GETN_OPTION_EVENT_EX(nlf_on_fo) GETN_OPTION_DISPLAY_FORMAT(DISPLAY_EDITOR_RIGHT)
		///// end SELECT_FITTING_FUNCTION_PANEL_CHANGES
		///End	ADD_OPEN_FO_BITMAPBUTTON
	GETN_END_BRANCH(FunctionSelection)

	///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
	/// Max 6/4/08 v8.0877 THIS_BRANCH_SHOULD_CLOSE_BY_DEFAULT
	//GETN_BEGIN_BRANCH(Replica, _L("Replica")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
	GETN_BEGIN_BRANCH(Replica, _L("Replica"))
	/// END THIS_BRANCH_SHOULD_CLOSE_BY_DEFAULT
		///Arvin 03/17/08 REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT as CP said
		//GETN_COMBO(Number, _L("Number of Replicas"), 0, "0|1|2|3|4|5|6|7|8|9|10") GETN_ID(IDE_NL_REPLICA_NUMBER)	//GETN_OPTION_EVENT(nlf_on_change_replica_number)
		GETN_COMBO(Number, _L("Number of Replicas"), 0, "|0|1|2|3|4|5|6|7|8|9|10") GETN_ID(IDE_NL_REPLICA_NUMBER)	//GETN_OPTION_EVENT(nlf_on_change_replica_number)
		///end REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT
		GETN_NUM(Offset, _L("Replicate From nth Parameter"), 0)	GETN_READ_ONLY_COLOR
		GETN_NUM(NumParam, _L("Number of Parameters in Replicas"), 0) GETN_READ_ONLY_COLOR
		///Cheney 2006-1-1 ADD_ONE_MORE_CHECK_BOX_FOR_REPLICA_CONTROL
		//GETN_CHECK(PeakCurve, "Plot Each Peak Curve", 1)	GETN_ID(IDE_NL_REPLICA_PEAK_CURVE)			
		GETN_CHECK(PeakCurve, _L("Plot Individual Peak Curve"), 0)	GETN_ID(IDE_NL_REPLICA_INDIVIDUAL_PEAK_CURVE)			
		GETN_CHECK(CumulativeCurve, _L("Plot Cumulative Fitted Curve"), 1)	GETN_ID(IDE_NL_REPLICA_CUMULATIVE_FITTED_CURVE)			
		///end ADD_ONE_MORE_CHECK_BOX_FOR_REPLICA_CONTROL
		//GETN_CHECK(BaseLine, "Plot Baseline", 0)	GETN_ID(IDE_NL_REPLICA_BASE_LINE) /// Iris 04/27/06 remove this by design
	GETN_END_BRANCH(Replica)
	///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		
	GETN_BEGIN_BRANCH(Fit, _L("Fit Control")) GETN_ID_BRANCH(IDST_NLSF_OPTIONS) //GETN_OPTION_BRANCH(GETNBRANCH_OPEN)		
		GETN_BEGIN_BRANCH(Weighting, _L("Weighting")) /*GETN_COMBO_BRANCH(0, "No Weighting|Instrumental|Statistical|Arbitrary Dataset|Direct Weighting|Variance ~ y^2|Variance = a*y^b|Variance = c^b+a*y^b|Variance = a*y^b*c^(tlast-t)|Variance ~ yfit|Variance ~ yfit^2|Variance = a*yfit^b|Variance = c^b+a*yfit^b|Variance = a*yfit^b*c^(tlast-t)")*/
			GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			GETN_LIST(Methods, _L("Methods"), 0, _L("No Weighting|Instrumental|Statistical|Arbitrary Dataset|Direct Weighting|Variance ~ y^2|Variance = a*y^b|Variance = c^b+a*y^b|Variance = a*y^b*c^(tlast-t)|Variance ~ yfit|Variance ~ yfit^2|Variance = a*yfit^b|Variance = c^b+a*yfit^b|Variance = a*yfit^b*c^(tlast-t)"))  GETN_ID(IDE_NLSF_WEIGHTING_METHOD)
			GETN_OPTION_EVENT(nlf_on_weighting_method_update)
				GETN_NUM(a, _L("a"), 0)  GETN_ID(IDE_NLSF_WEIGHTING_A)
				GETN_NUM(b, _L("b"), 0)  GETN_ID(IDE_NLSF_WEIGHTING_B)
				GETN_NUM(c, _L("c"), 0)  GETN_ID(IDE_NLSF_WEIGHTING_C)
		GETN_END_BRANCH(Weighting)
		
		/// Iris 02/04/06 QA70-8461 ADD_REPLICA_OPTIONS
		///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
		//GETN_BEGIN_BRANCH(Replica, _L("Replica")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		//	///Arvin 03/17/08 REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT as CP said
		//	//GETN_COMBO(Number, _L("Number of Replicas"), 0, "0|1|2|3|4|5|6|7|8|9|10") GETN_ID(IDE_NL_REPLICA_NUMBER)	//GETN_OPTION_EVENT(nlf_on_change_replica_number)
		//	GETN_COMBO(Number, _L("Number of Replicas"), 0, "|0|1|2|3|4|5|6|7|8|9|10") GETN_ID(IDE_NL_REPLICA_NUMBER)	//GETN_OPTION_EVENT(nlf_on_change_replica_number)
		//	///end REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT
		//	GETN_NUM(Offset, _L("Replicate From nth Parameter"), 0)	GETN_READ_ONLY_COLOR
		//	GETN_NUM(NumParam, _L("Number of Parameters Used in Replicas"), 0) GETN_READ_ONLY_COLOR
		//	///Cheney 2006-1-1 ADD_ONE_MORE_CHECK_BOX_FOR_REPLICA_CONTROL
		//	//GETN_CHECK(PeakCurve, "Plot Each Peak Curve", 1)	GETN_ID(IDE_NL_REPLICA_PEAK_CURVE)			
		//	GETN_CHECK(PeakCurve, _L("Plot Individual Peak Curve"), 1)	GETN_ID(IDE_NL_REPLICA_INDIVIDUAL_PEAK_CURVE)			
		//	GETN_CHECK(CumulativeCurve, _L("Plot Cumulative Fitted Curve"), 0)	GETN_ID(IDE_NL_REPLICA_CUMULATIVE_FITTED_CURVE)			
		//	///end ADD_ONE_MORE_CHECK_BOX_FOR_REPLICA_CONTROL
		//	//GETN_CHECK(BaseLine, "Plot Baseline", 0)	GETN_ID(IDE_NL_REPLICA_BASE_LINE) /// Iris 04/27/06 remove this by design
		//GETN_END_BRANCH(Replica)
		///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		///End ADD_REPLICA_OPTIONS
		
		//GETN_STR(temp, "Temp", "Just used to avoid one bug temporarily") //When Replica branch is disable,the other two branch also are disable too, need wait for fix the bug. 
		
		GETN_BEGIN_BRANCH(Iterations, _L("Iterations")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
			GETN_COMBO(MaxNum, _L("Max. Number of Iterations"), 400, "|2|5|10|20|30|50|100|200|300|400|500") GETN_ID(IDE_NLSF_MAX_ITERATIONS)
			GETN_COMBO(Tolerance, _L("Tolerance"), 1e-9, "|1e-15|1e-14|1e-12|1e-10|1e-9|1e-6") GETN_ID(IDE_NLSF_TOLERANCE)
		GETN_END_BRANCH(Iterations)
		
		//value read from function tree
		GETN_BEGIN_BRANCH(DerivativeDelta, _L("Derivative Delta")) GETN_ID_BRANCH(IDST_NLSF_DERIV_OPTIONS)
			GETN_NUM(Delta, _L("Delta"), 0.005) GETN_ID(IDE_NLSF_DERIV_DELTA)
			GETN_NUM(Minimum, _L("Minimum"), 5E-30) GETN_ID(IDE_NLSF_DERIV_DELTA_MIN)
			GETN_NUM(Maximum, _L("Maximum"), 5E30) GETN_ID(IDE_NLSF_DERIV_DELTA_MAX)
			GETN_CHECK(Fixed, _L("Fixed"), 0) GETN_ID(IDE_NLSF_DERIV_DELTA_FIXED)  GETN_OPTION_EVENT(nlf_on_change_delta_fixed)
		GETN_END_BRANCH(DerivativeDelta)
		///Kevin 09/02/05 ADD_CL_COMPUTATION_METHOD_GETNLIST
		GETN_LIST(CIMethod, _L("Parameters' CI Computation Method"), 0, _L("Asymptotic-Symmetry based|Model-Comparison based")) GETN_ID(IDE_NLSF_COMP_METHOD)
		//GETN_NUM(Confidence, _L("Confidence Level for Parameters(%)"), 95) 		GETN_ID(IDE_FIT_CONF_PERCENT)   
		//GETN_OPTION_EVENT_EX(Project.FindFunction("fit_conf_level_event", "stats_guis.C"))/// TD 5-12-06 CL_CHANGE_UPDATE CL change will not update report title
		///End ADD_CL_COMPUTATION_METHOD_GETNLIST
		///Arvin 05/08/07 QA70-9498 SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
		///Cheney 2007-5-14 RENAME_FIT_TOOL_CHECK_BOX_NAME
		//GETN_CHECK(ScaleError, "Scale Errors with Sqrt(Reduced Chi^2)", 1)	GETN_ID(IDE_NL_SCALE_ERROR_WITH_CHISQR)	
		GETN_CHECK(ScaleError, STR_FITTING_CHECKBOX_USE_RED_CHI_SQR, 1)	GETN_ID(IDE_NL_SCALE_ERROR_WITH_CHISQR)	
		///end RENAME_FIT_TOOL_CHECK_BOX_NAME
		///end RENAME_FIT_TOOL_CHECK_BOX_NAME
		///END SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
		/// Iris 02/04/06 QA70-8461 ADD_REPLICA_OPTIONS
		///// Iris 10/13/05 QA70-8015-P16 ADD_REPLICA_NUM_OPTION_FOR_PEAK_FUNC
		//GETN_NUM(ReplicaNum, _L("Number of Replica"), 0) GETN_ID(IDE_NLSF_REPLICA_NUM)
		/////End ADD_REPLICA_NUM_OPTION_FOR_PEAK_FUNC
		///End ADD_REPLICA_OPTIONS
		
	GETN_END_BRANCH(Fit)
	
	/// TD 9-2-06 QA70-9012 DYNACONTROL_MULTILINEEDIT_BUTTON
	//GETN_BEGIN_BRANCH(Codes, "Fitting Codes") GETN_ID_BRANCH(IDST_NLSF_CODES) //GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
	//	GETN_MULTILINE_TEXT(FunctionCode, "Function", "")			GETN_ID(IDE_NLSF_CODES_FUNC) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
	//	GETN_MULTILINE_TEXT(ParaInitCode, "Parameter Init", "")	GETN_ID(IDE_NLSF_CODES_PARAINIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
	//	GETN_MULTILINE_TEXT(BeforeFit, "Before Fit Code", "")			GETN_ID(IDE_NLSF_CODES_BEFOREFIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
	//	GETN_MULTILINE_TEXT(AfterFit, "After Fit Code", "")				GETN_ID(IDE_NLSF_CODES_AFTERFIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
	//	GETN_MULTILINE_TEXT(Constraints, "Constraints", "")				GETN_ID(IDE_NLSF_CONSTRAINTS) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)	///Jasmine 05/08/06
	//GETN_END_BRANCH(Codes)
	GETN_BEGIN_BRANCH(Codes, _L("Fitting Codes")) GETN_ID_BRANCH(IDST_NLSF_CODES) //GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		/// Hong 03/19/08 8.0827 NLFIT_REMOVE_SETTINGS_ALLREADY_IN_FDF_FILE_FROM_THEME		
		#ifdef NLFIT_FDF_SETTINGS_SKIP_APPLY_THEME
			GETN_BRANCH_THEME_APPLICAPABILITY(XVTA_DO_NOT_APPLY_VALUE|XVTA_DO_NOT_APPLY_ATTRIBUTES)
		#endif //NLFIT_FDF_SETTINGS_SKIP_APPLY_THEME
		/// end NLFIT_REMOVE_SETTINGS_ALLREADY_IN_FDF_FILE_FROM_THEME
		GETN_MULTILINE_TEXT(FunctionCode, _L("Function"), "")			GETN_ID(IDE_NLSF_CODES_FUNC) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX) //ADD_CODEBUILDER_BUTTON_FIT_FUNCTION   /// Iris 06/19/2007 v8.0643 REMOVE_CB_BUTTON_SINCE_ALWAYS_DISABLE
		///Cheney 2007-8-29 FIX_STH_ABOUT_NLFIT_INIT_CODE	
		//GETN_MULTILINE_TEXT(ParaInitCode, "Parameter Init", "")		GETN_ID(IDE_NLSF_CODES_PARAINIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX) //ADD_CODEBUILDER_BUTTON_PARA_INIT  /// Iris 06/19/2007 v8.0643 REMOVE_CB_BUTTON_SINCE_ALWAYS_DISABLE
		//let it has code builder
		GETN_MULTILINE_TEXT(ParaInitCode, _L("Parameter Init"), "")		GETN_ID(IDE_NLSF_CODES_PARAINIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX) ADD_CODEBUILDER_BUTTON_PARA_INIT  				
		///end FIX_STH_ABOUT_NLFIT_INIT_CODE

		//----- Iris 02/28/2007 Change id for Constrains nodes to keep the ids of nodes in Code tab is continuous to check if selected row is in Code Tab
		//GETN_MULTILINE_TEXT(Constraints, "Constraints", "")			GETN_ID(IDE_NLSF_CONSTRAINTS) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
#ifdef ALLOW_LINEAR_CONSTRAINT_WHEN_FITTING  //Cheney 2007-5-28 TEMP_HIDE_LINEAR_CONSTRAIN_TAB_AND_CHECK_BOX
		GETN_MULTILINE_TEXT(Constraints, _L("Constraints"), "")			GETN_ID(IDE_NLSF_CODES_CONSTRAINTS) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
#endif //ALLOW_LINEAR_CONSTRAINT_WHEN_FITTING  //Cheney 2007-5-28 TEMP_HIDE_LINEAR_CONSTRAIN_TAB_AND_CHECK_BOX
		//-----
		
#ifdef ALLOW_SCRIPT_BEFORE_AFTER_FITTING	///Jasmine 03/24/07 REMOVE_SCRIPT_BEFORE_AFTER_FITTING

		///Jasmine 11/16/06 INITIALIZATION_SCRIPT_TO_SCRIPT_BEFORE_FITTING
		//GETN_MULTILINE_TEXT(BeforeFit, "Before Fit Code", "")		GETN_ID(IDE_NLSF_CODES_BEFOREFIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
		//GETN_MULTILINE_TEXT(AfterFit, "After Fit Code", "")			GETN_ID(IDE_NLSF_CODES_AFTERFIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
		GETN_MULTILINE_TEXT(BeforeFit, GetLocalized(STR_FUNC_SCRIPT_BEFORE_FITTING), "")		GETN_ID(IDE_NLSF_CODES_BEFOREFIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
		GETN_MULTILINE_TEXT(AfterFit, GetLocalized(STR_FUNC_SCRIPT_AFTER_FITTING), "")			GETN_ID(IDE_NLSF_CODES_AFTERFIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)

/// Hong 01/04/10 QA80-14907-P1 TAKE_BACK_SCRIPT_BEFORE_FITTING		
//#endif //ALLOW_SCRIPT_BEFORE_AFTER_FITTING	///Jasmine 03/24/07 REMOVE_SCRIPT_BEFORE_AFTER_FITTING	
#else //ALLOW_SCRIPT_BEFORE_AFTER_FITTING
/// end TAKE_BACK_SCRIPT_BEFORE_FITTING		 
		//------ Folger QA70-10890 01/02/08 ADD_SCRIPT_AFTER_FITTING
		//only add after fitting script, no before fitting script, see ALLOW_SCRIPT_BEFORE_AFTER_FITTING
		GETN_MULTILINE_TEXT(AfterFit, _L(STR_FUNC_SCRIPT_AFTER_FITTING), "")			GETN_ID(IDE_NLSF_CODES_AFTERFIT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
		//------
#endif //ALLOW_SCRIPT_BEFORE_AFTER_FITTING /// Hong 01/04/10 QA80-14907-P1 TAKE_BACK_SCRIPT_BEFORE_FITTING
		///Sophy 10/20/2008 QA80-12406 ADD_DERIVATIVE_PARAM_PAGE_IN_CODE_TAB_OF_NLFIT_DLG
		GETN_MULTILINE_TEXT( DerivParam, _L("Derived Parameters"), "" ) GETN_ID(IDE_NLSF_CODES_DERIVATIVE) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE(NLF_CODES_ROW_MINMAX)
		///end ADD_DERIVATIVE_PARAM_PAGE_IN_CODE_TAB_OF_NLFIT_DLG
		
	GETN_END_BRANCH(Codes)
	/// end DYNACONTROL_MULTILINEEDIT_BUTTON
	trGUI.Codes.Show = false;// this branch will be shown in separate tab
	//trGUI.FunctionSelection.SelFuncFile.Show = false;//---- CPY 1/13/04 NLFIT_GETTING_WRONG_FDF_FILE
	
	///---Sim 04-07-2008 QA80-11371 THEME_SAVING_OPTIONS
	GETN_BEGIN_BRANCH(DialogSettings, "") // hard code for tagname
		GETN_BEGIN_BRANCH(ThemeFilter, "") GETN_ID_BRANCH(IDE_DS_THEME_FILTER)
		/*
			GETN_CHECK(FunctionList, _L("Function Type"), 1)	GETN_ID(IDE_NL_THEME_FILTER_FUNC)
			GETN_CHECK(AutoParamsInit, _L("Auto Parameter Initialization"), 0)	GETN_ID(IDE_NL_THEME_FILTER_AUTO_PARAM_INIT)
			GETN_CHECK(Values, _L("Parameter Values"), 0)	GETN_ID(IDE_NL_THEME_FILTER_PARAMS)
			GETN_CHECK(Fixed, _L("Fixed Status"), 0)	GETN_ID(IDE_NL_THEME_FILTER_FIXED)
			GETN_CHECK(Share, _L("Share Status"), 1)	GETN_ID(IDE_NL_THEME_FILTER_SHARE)
			GETN_CHECK(UpperLowerBounds, _L("Upper and Lower Bounds"), 0)	GETN_ID(IDE_NL_THEME_FILTER_ULB)
			GETN_CHECK(LinearConstraints, _L("Enable Linear Constraints"), 0)	GETN_ID(IDE_NL_THEME_FILTER_ENABLE_LINEAR_CONSTRAINTS)
			GETN_CHECK(Constraints, _L("Constraints"), 0)	GETN_ID(IDE_NL_THEME_FILTER_CONSTRAINTS)
			GETN_CHECK(AfterFit, _L("Script after Fitting"), 0)	GETN_ID(IDE_NL_THEME_FILTER_SCRIPT)
			GETN_CHECK(Other, _L("Other Settings"), 1)	GETN_ID(IDE_NL_THEME_FILTER_OTHER)
		*/
		nlsf_construct_theme_filter(trGUI.DialogSettings.ThemeFilter);
		//------ Folger 08/25/08 ADD_CONTEXT_HELP_FOR_NLFIT_THEME_SETTINGS_DIALOG
		trGUI.DialogSettings.ThemeFilter.SetAttribute(STR_HELPID_ATTRIB, IDD_FITTING_WITH_THEMES);
		//------
		GETN_END_BRANCH(ThemeFilter) 
	GETN_END_BRANCH(DialogSettings) // hard code for tagname
	trGUI.DialogSettings.Show = false;
	///---END QA80-11371 THEME_SAVING_OPTIONS
}

//virtual 
void FitNL::ConstructAddCommonBottom(TreeNode& trGUI)
{
	TreeNode trGraph = GetGUIGraphNodes(trGUI.Parent(), 0);
	if(!trGraph)
	{
		error_report("Fit Curve option not in the right place");
		return;
	}
}

//------- end


//virtual
void 	FitNL::FilterStatsReport(TreeNode& trOp)
{	
	FitterOperation::FilterStatsReport(trOp);
	
	/// Iris 01/17/2007 v8.0543 IMPROVE_NLFIT_SPEED
	//vector<int> vnNodesToHide = {IDE_FIT_CORRELATION, IDE_FIT_NORM_REDIDUALS};
	//tree_set_attributes(trOp.Calculation, vnNodesToHide, "0");
	TreeNode trStarts = trOp.Calculation.RegStats;
	if(trStarts)
	{
		foreach(TreeNode trOneSet in trStarts.Children)
		{
			///Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION
			//If node Correlation and NormResiduals are not exist, this code will add them
			//trOneSet.Correlation.Show = 0;
			//trOneSet.NormResiduals.Show = 0;
			TreeNode trCorr = trOneSet.Correlation;
			if(trCorr)
				trCorr.Show = 0;
			TreeNode trNormRes = trOneSet.NormResiduals;
			if(trNormRes)
				trNormRes.Show = 0;
			///end XOP_NEED_SUPPORT_CHANGE_FUNCTION
		}
	}
	///end IMPROVE_NLFIT_SPEED
	//octree_delete_nodes_by_attribute(&trRow, STR_SHOW_ATTRIB, false);
}

/// Iris 6/04/05 ADD_FILTER_FITTING_GUI
//virtual
void    FitNL::FilterFittingGUI(TreeNode& trOp)
{
	FitterOperation::FilterFittingGUI(trOp);
	
	vector<int> vnNodesToHide = {
		IDE_FIT_CORRELATION, IDE_FIT_NORM_REDIDUALS};
	tree_set_attributes(trOp.GUI, vnNodesToHide, "0");
	

	///Iris 7/27/05 UPDATE_FITTED_CURVE_OPTIONS
	TreeNode trFitCurves = trOp.GUI.Graph1;
	if(trFitCurves)
		trFitCurves.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);	
	///end UPDATE_FITTED_CURVE_OPTIONS	
	
}
///----

///Arvin 03/11/08  QA70-11234 REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
/*
bool residual_limit_event(TreeNode& tr, int nRow, int nType, Dialog& Dlg)
{
	TreeNode trCurrentNode = tree_get_node(tr, nRow);
	if( !trCurrentNode )
		return false;
	TreeNode trIrl = trCurrentNode.Irl;
	TreeNode trOrl = trCurrentNode.Orl;
	if(trCurrentNode.Use)
	{
		if(trIrl)
			trIrl.Show = true;
		if(trOrl)
			trOrl.Show = true;
	}
	else
	{
		if(trIrl)
			trIrl.Show = false;
		if(trOrl)
			trOrl.Show = false;
	}
	return true;
}
*/
static bool _add_irl_and_orl_nodes_under_residual_plot_for_surface_fit(TreeNode& trResiduals)
{
	TreeNode trResVsIndepPlot = trResiduals.Graph2;
	if(!trResVsIndepPlot)
		return false;
	int nDataID = 0;
	string strLabel = "";
	trResVsIndepPlot.GetAttribute(STR_DATAID_ATTRIB, nDataID);
	trResVsIndepPlot.GetAttribute(STR_LABEL_ATTRIB, strLabel);
	TreeNode trTemp = trResiduals.InsertNode(trResVsIndepPlot, "Temp");
	trResVsIndepPlot.Remove();
	Tree tr;
	GETN_USE(tr)
	GETN_BEGIN_BRANCH(Graph2, strLabel) GETN_ID_BRANCH(nDataID) GETN_CHECKBOX_BRANCH(1) //GETN_OPTION_EVENT(residual_limit_event)
	GETN_NUM(Irl, _L("Inner Residual Limit(%)"), 5)     GETN_ID(IDE_FIT_INNER_RESIDUAL_LIMIT)
	GETN_NUM(Orl, _L("Outer Residual Limit(%)"), 30) 	GETN_ID(IDE_FIT_OUTER_RESIDUAL_LIMIT)
	GETN_END_BRANCH(Graph2)
	TreeNode trGraph2 = tr.Graph2;
	trTemp.Replace(trGraph2);
	return true;
}
///end REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT

BOOL 	FitNL::Construct(TreeNode& trOp, int nOption)
{	
	//nOption = 1; //1, need include 3D options, else 0 //Iris 9/06/06 it is unuseful now
	if( FitterOperation::Construct(trOp, nOption) )
	{
		/// Iris 8/15/2008 QA80-12025 TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL 
		trOp.FitType.nVal = nOption;
		///end TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
		
		/// Iris 01/19/2007 v8.0544 IMPROVE_NLFIT_SPEED
		// The speed is too slow to create, so not show these tables to improve speed temporarily, will move some codes to vc later
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//TreeNode trCreate = trOp.GUI.Output.Create;
		TreeNode trCreate = OP_GUI_OUTPUT_TABLES_BRANCH(trOp.GUI);
		///end OP_DLG_NEW_STRUCTURE
		if(trCreate)
		{
			/// Iris 03/29/2007 v8.0591 SHOW_INPUT_TABLE_AS_NEEDED
			/*
			trCreate.InputData.nVal = 0;
			*/
			///end SHOW_INPUT_TABLE_AS_NEEDED
			trCreate.MaskedData.nVal = 0;
			trCreate.MissingData.nVal = 0;
		}
		///end IMPROVE_NLFIT_SPEED
		
		///Cheney 2007-4-11 ONLY_FIT_NL_NEED_LB_UB	
		TreeNode trParams = trOp.GUI.Quantities.Parameters;
		if(trParams)
		{
			GETN_USE(trParams);
			GETN_CHECK(LowerBound, _L("Lower Bound"), false) 	GETN_ID(IDE_PARAM_LOWER_BOUND)
			GETN_CHECK(UpperBound, _L("Upper Bound"), false) 	GETN_ID(IDE_PARAM_UPPER_BOUND)
			
			///Kyle 09/03/2009 QA80-14077-P1 Unit_IS_ONLY_NEEDED_FOR_NLSF
			TreeNode trUnit = trParams.InsertNode(trParams.FirstNode, "Unit", TRGP_CHECK);
			if(trUnit)
			{
				trUnit.DataID = IDE_PARAM_UNIT;
				trUnit.SetAttribute(STR_LABEL_ATTRIB, _L("Unit"));
				trUnit.SetAttribute(STR_DELAY_DATAID_ASSIGN_ATTRIB, PA_DELAY_DATAID_ASSIGN_VER4);
				trUnit.nVal = 0;
			}
			///End Unit_IS_ONLY_NEEDED_FOR_NLSF
		}
		///end ONLY_FIT_NL_NEED_LB_UB
		
		///Sophy 11/28/2008 v8.0980d QA80-12591-P5 ADD_AUTO_SUPPORT_FOR_LR_AND_PR_FITCURVE_XDATATYPE
		//moved to stats_guis.c, shared with LR & LP
		/////Arvin 05/15/07 SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
		//TreeNode trXDataType = trOp.GUI.Graph1.XDataType;
		//if(trXDataType)
		//{
			//TreeNode trMin = trXDataType.Min;
			//TreeNode trMax = trXDataType.Max;
			//octree_set_auto_support(&trMin);
			//octree_set_auto_support(&trMax);
		//}
		/////end SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
		///end ADD_AUTO_SUPPORT_FOR_LR_AND_PR_FITCURVE_XDATATYPE
		
		///Arvin 12/25/07 MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL as cp said
		//Open output branch by default
		trOp.GUI.Output.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
		///end MOVE_OUTPUT_RESULTS_BRANCH_TO_LEFT_PANEL 		
		
		/// Hong 01/23/08 QA80-10969 MOVE_PREVIEW_TO_HIGHER_LEVEL_IN_GUI
		TreeNode trGUI = trOp.GUI;
		GETN_USE(trGUI)
		GETN_CHECK(Preview, _L("Show Preview on Source Graph"), 1) GETN_ID(IDE_FIT_PREV) /// Hong 01/23/08 QA80-10969 DEFAULT_PREVIEW_IN_SOURCE_GRAPHPAGE
		/// end MOVE_PREVIEW_TO_HIGHER_LEVEL_IN_GUI
		///Arvin 03/12/08 REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT
		///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
		//TreeNode trReplica = trGUI.Fit.Replica;
		//_add_auto_init_params_branch_under_replica(trReplica);
		TreeNode trReplica = trGUI.Replica;
		TreeNode trOffset = trReplica.Offset;
		TreeNode trTemp = trReplica.InsertNode(trOffset, "Temp");
		///Sophy 6/5/2009 MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
		//_add_auto_init_params_branch_under_replica(trTemp);
		add_auto_init_params_branch_under_replica(trTemp);
		///end MORE_SUPPORT_ON_NLFITSESSION_CUSTOMIZATION
		///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		
		///Arvin 03/11/08  QA70-11234 REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
		//------ Folger 06/20/08 QA80-11749 REMOVE_UNWANTED_SUBNODES_FOR_GENERAL_XY_FITTING
		//if( NLFIT_GENERAL_XY_FITTING != nOption ) /// Iris 4/24/2008 HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA		
		// nOption is not always means fitting type, for example,
		// when comes from change parameter, nOption will store some magic number, which will be larger than fitting type
		// so something is done below to fix that, need to be cleaned up later
		/// Iris 8/15/2008 QA80-12025 TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
		//int		nFitOption = nOption <= NLFIT_MATRIX_FITTING ? nOption : GetFitType(trOp);
		//if( NLFIT_XYZ_FITTING == nFitOption || NLFIT_MATRIX_FITTING == nFitOption )
		// For Folger's change, when comes from change parameter, nOption will store some magic number, this number is the index of selected function in current funciton list, see Cheney's codes by SHOULD_UPDATE_SPECI_INFO_WHEN_THEME_LOAD_OR_FUNC_CHANGE_IF_IS_SPECI_FIT
		// So must store fit type to other treenode, so introduce trOp.FitType.
		int		nFitOption = GetFitType(trOp);
		if( !isNormalFit(nFitOption ) )
		///end TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
		//------
		{
			TreeNode trResiduals = trGUI.Residuals;
			_add_irl_and_orl_nodes_under_residual_plot_for_surface_fit(trResiduals);
		}
		///end REORGNIZE_FITTED_CURVE_AND_RESIDUAL_PLOTS_BRANCH_FOR_NLFIT
		
		/// Iris 6/04/2008 v8.0877 FIX_XYZFIT_POINT_OF_X_DATA_TYPEIS_100
		/// Iris 6/06/2008 FAIL_IN_RECALCULATE_FOR_FIT_EXPONENTIAL, nOption is 20 not 0 for Fit Expoenntial.
		//if( NLFIT_GENERAL_XY_FITTING == nOption )
		/// Iris 8/15/2008 QA80-12025 TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
		//if( NLFIT_XYZ_FITTING == nOption || NLFIT_MATRIX_FITTING == nOption)
		if( !isNormalFit(nFitOption ) )
		///end TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
		///end FAIL_IN_RECALCULATE_FOR_FIT_EXPONENTIAL
			UpdateCalibrationBranch(trOp);
		///end FIX_XYZFIT_POINT_OF_X_DATA_TYPEIS_100
		
		return TRUE;
	}
	return FALSE;
}

/// Iris 8/15/2008 QA80-12025 TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
bool	FitNL::isNormalFit(int nFitOption)
{
	return NLFIT_GENERAL_XY_FITTING == nFitOption;
}
///end TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL

/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
void	FitNL::CleanupNLFitCurve(LPCSTR lpcszMsg)
{
	if(	m_pNLFCurves )
	{
		_DBPRINTF("**** m_pNLFCurves not NULL when %s, deleting...\n", lpcszMsg);
		delete m_pNLFCurves;
		m_pNLFCurves = NULL;
	}
	else
	{
		_DBPRINTF("**** m_pNLFCurves is NULL when %s\n", lpcszMsg);
	}	
}

DWORD	FitNL::getPlotUID(TreeNode& trOp, int nDataset/* = 0*/)
{
	DWORD	dwPlotUID = m_pFitSession->GetSourcePlotUID(nDataset);
	
	int 	nDataMode;
	if(trOp.GUI.InputData.GetAttribute( STR_USE_ATTRIB, nDataMode) && nDataMode == DATA_MODE_CONCATENATE)
		dwPlotUID = m_pFitSession->GetSrcPlotUIDConcatenate();
	
	return dwPlotUID;	
}
/// end FITNL_USING_NEW_NLFSESSION

//------ Folger 10/14/08 WRONG_NLF_CURVES_CLASS_IN_PA_MAKES_WRONG_REPORT
/// virtual
NLFCurvesBase*	FitNL::createNLFCurvePointer(TreeNode& trOp)
{
	int nFitType = GetFitType(trOp);
	ASSERT( m_pFitSession );///Sophy 10/14/2008 QA80-12370 FIX_RUNTIME_IN_2ND_TIME_RECALCULATE_MATRIX_FIT_ANALYSIS_TEMPLATE
	switch(nFitType)
	{
	case NLFIT_XYZ_FITTING:
		return new SurfaceFitCurves(m_pFitSession);

	case NLFIT_MATRIX_FITTING:
		return new MatrixFitCurves(m_pFitSession);

	case NLFIT_GENERAL_XY_FITTING:
	default:
		break;
	}
	return new NLFCurves(m_pFitSession);
}
//------ End WRONG_NLF_CURVES_CLASS_IN_PA_MAKES_WRONG_REPORT

//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
bool	FitNL::checkUpdateFDFTree(LPCSTR lpcszFunc)
{
	if(!isFDFTreeValid())//if(m_trFDF.Children.Count() == 0)//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
	{
		if(!LoadFDFtoTree(lpcszFunc))
			return false;
	}
	return true;
}
//------ End SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET

//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
bool FitNL::isFDFTreeValid()
{
	if(m_trFDF && m_trFDF.IsValid() && m_trFDF.Children.Count() > 0)
		return true;
	
	return false;
}
//---

/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
//virtual 
string	FitNL::GetAnalysisName(int nOption)
{
	/*
	string str = _L("Fit Exponential");
	if(nOption < 0)
		return str;
	
	string strTemp;
	strTemp.Format(_L("(Terms = %d)"), nOption + 1);
	
	return str + " " + strTemp;
	*/
	Tree			trOp;
	GetTree(trOp);
	string			strOption;
	if (!IsSpecFit(trOp, NULL, &strOption))
		//return "NL Fit";
	{
		string 	strCategory, strFunc;
		vector<string> vsFuncFilterList;
		if( GetCategoryFuncNames(trOp, strCategory, strFunc, vsFuncFilterList) )
			return strFunc + " " + _LR("Fit");
		return _LR("Nonlinear Curve Fit");
	}

	/// make consistent with SepcFit above
	//return strOption;
	return strOption + " " + _L("Fit");
}

//virtual 
string	FitNL::GetClassName() 
{
	Tree			trOp;
	GetTree(trOp);
	string			strClassName;
	///Sophy 5/30/2008 FIX_SURFACE_FIT_CURVE_SHEETNAME_ERROR_ON_SCRIPT_COMMAND_CASE
	//if (!IsSpecFit(trOp, &strClassName))
		//return "FitNL";
	///Sophy 6/4/2008 RESTORE_OLD_LOGIC
	//strClassName = "FitNL";
	if( !IsSpecFit( trOp, &strClassName ) )
		strClassName = STR_FITTEROPERATION_CLASS_FITNL;
	///end RESTORE_OLD_LOGIC
	///Sophy 6/3/2008 FIX_GET_OPERATION_TREE_FAILURE
	/*
	IsSpecFit(trOp, &strClassName);//check specical type class name
	///end FIX_SURFACE_FIT_CURVE_SHEETNAME_ERROR_ON_SCRIPT_COMMAND_CASE
	/// Sophy 5/06/2008 QA80-10934-P7 MAKE_OUTPUT_SHEETNAME_CONSISTENT
	if(0 == strClassName.Compare("fitmatrix"))
		strClassName = "FitMatrix";
	if(0 == strClassName.Compare("fitsurface"))
		strClassName = "FitSurface";
	/// End MAKE_OUTPUT_SHEETNAME_CONSISTENT
	*/
	///end FIX_GET_OPERATION_TREE_FAILURE
	return strClassName;
}

// virtual
int		FitNL::GetOptionIndex(const TreeNode& trGUI)
{
	TreeNode		trOp = trGUI.Parent();
	int				nOption = 0;
	if (!IsSpecFit(trOp, NULL, NULL, NULL, NULL, &nOption))
		return FitterOperation::GetOptionIndex(trGUI);
	
	return nOption;
}

/// Iris 10/28/2009 QA81-14546 CHANGE_GUI_REPORT_TABLE_LABEL
/*
/// Iris 4/17/2008 SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
//virtual	
string	FitNL::GetReportTableGUIName(TreeNode& trGUI)
{ 
	Tree 	trOp;
	GetTree(trOp);
	int 	nFitType = GetFitType(trOp);
	
	string 	str;
	switch(nFitType)
	{
	case NLFIT_GENERAL_XY_FITTING:
		str = STR_OUTPUT_NL_FIT_REPORT_TABLE;
		break;
	case NLFIT_XYZ_FITTING:
		str = STR_OUTPUT_XYZ_FIT_REPORT_TABLE;
		break;
	case NLFIT_MATRIX_FITTING:
		str = STR_OUTPUT_MATRIX_FIT_REPORT_TABLE;
		break;
	}

	ASSERT(!str.IsEmpty());
	return str;
}
///end SPECIAL_REPORT_TABLE_NAME_FOR_DIFF_TOOLS
*/
///end CHANGE_GUI_REPORT_TABLE_LABEL

//virtual
string FitNL::GetGraphTemplate(int nGraphIndex)
{
	Tree		trOp;
	GetTree(trOp);
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	int nFitType = GetFitType(trOp);
	if(nFitType != NLFIT_GENERAL_XY_FITTING)
	//if( HasZ(trOp))
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	{
		switch(nGraphIndex)
		{
		case GRAPH_FIT_CURVE:
			//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
			//return "XYZ2MAT3D"; //"wirefrm"; ///Arvin CHANGE_TEMPLATE_FOR_SURFACE_FIT
			
			//------ Folger 03/18/08 QA80-11260 FIX_RUNTIME_ERROR_IN_MATRIX_FITTING_PREVIEW_AND_REPORT_GRAPH
			//return "TRICONTOUR";
			return nFitType == NLFIT_XYZ_FITTING? "TRICONTOUR" : "CONTOUR";
			//------
			
			//------			
			break;
		case GRAPH_RESIDUALS_SCATTER:
			///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
			//return "Report3DResidual";	
			
			//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
			//string strTemplate = nFitType == NLFIT_XYZ_FITTING? "Report3DResidual" : "ReportMatResidual";
			///Sophy 2/16/2009 v8.0979b QA80-13121 CUSTOM_LEGEND_NEED_SIMPLER_LINE_SUPPORT
			//string strTemplate = nFitType == NLFIT_XYZ_FITTING? "TRICONTOUR" : "CONTOUR";
			string strTemplate = nFitType == NLFIT_XYZ_FITTING? "ReportTricontourRes" : "ReportContourRes";
			///end CUSTOM_LEGEND_NEED_SIMPLER_LINE_SUPPORT
			//------
			
			return strTemplate;
			///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
			break;
		default:
			break;
		}
	}	
	return FitterOperation::GetGraphTemplate(nGraphIndex);	
}


//virtual 
bool	FitNL::GetCategoryFuncNames(TreeNode& trOp, string& strCategory, string& strFunction, vector<string>& vsFilterList)
{
	string			strCat, strName;
	bool			bSpecFit = IsSpecFit(trOp, NULL, NULL, &strName, &strCat);
	if (!bSpecFit)
		return getCategoryFuncNamesAll(trOp, strCategory, strFunction, vsFilterList);
	
	/// ML 11/7/2005 QA70-8135 SURFACE_FITTING_VIA_XFUNC_NEW_WAY
	strCategory = strCat;
	if (strName.IsEmpty())		// like for surface fit
		return false;	// indicate Category cannot be changed	
		//return getCategoryFuncNamesAll(trOp, strCategory, strFunction, vsFilterList);
	/// end SURFACE_FITTING_VIA_XFUNC_NEW_WAY
	
	strFunction = strName;
	
	/// Iris 12/02/06 QA70-8757-P1 v8.0518 CORRECT_CATE_FUNC_OPTIONS
	//vsFilterList.SetSize(1);
	//vsFilterList[0] = strName;
	///end CORRECT_CATE_FUNC_OPTIONS
	
	return false;// indicate Category cannot be changed
}


bool	FitNL::IsSpecFit(const TreeNode& trOp, string *pstrClassName, string *pstrOption, string *pstrName, string *pstrCat, int *pnOption)
{
	TreeNode		trSpec = trOp.SpecInfo;
	if (!trSpec)
		return false;
	///Sophy 5/30/2008 FIX_SURFACE_FIT_CURVE_SHEETNAME_ERROR_ON_SCRIPT_COMMAND_CASE
	if( trSpec.FitType )
	{
		if( NLFIT_XYZ_FITTING == trSpec.FitType.nVal )
		{
			if( pstrClassName )
				*pstrClassName = "fitsurface";
		}
		if( NLFIT_MATRIX_FITTING == trSpec.FitType.nVal )
		{
			if( pstrClassName )
				*pstrClassName = "fitmatrix";
		}
	}
	///end FIX_SURFACE_FIT_CURVE_SHEETNAME_ERROR_ON_SCRIPT_COMMAND_CASE
	///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
	if(!trSpec.ClassName)
		return false;
	///end CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
	if (pstrClassName)
		*pstrClassName = trSpec.ClassName.strVal;

	int				nOption = trSpec.Option.nVal;
	
	if (pstrOption)
	{
		StringArray		saOptions;
		saOptions = trSpec.Options.strVals;
		if (saOptions.GetSize() <= nOption)
		{
			ASSERT(FALSE);
			return false;
		}
		
		*pstrOption = saOptions[nOption];
	}
	
	if (pstrName)
	{
		StringArray		saNames;
		if (trSpec.Names.IsValid())
		{
			saNames = trSpec.Names.strVals;
			if (saNames.GetSize() <= nOption)
			{
				ASSERT(FALSE);
				return false;
			}
			
			*pstrName = saNames[nOption];
		}
		else
		{
			pstrName->Empty();
			nOption = 0;			// always only 0 if no names (like for surface fitting)
		}
	}
	else if (!trSpec.Names)
		nOption = 0;			// always only 0 if no names (like for surface fitting)
	
	if (pnOption)
		*pnOption = nOption;

	if (pstrCat)	
		*pstrCat = trSpec.Categ ? trSpec.Categ.strVal : "";
	
	return true;
}

/// Iris 4/24/2008 HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA
/*
///Cheney 2007-9-13 SUPPORT_FIT_MATRIX_FROM_GRAPH	
bool	FitNL::isDataFromMatrix(GraphLayer& gl)
{
	DataPlot dp = gl.DataPlots();
	if(!dp)
		return false;
	
	bool bFromMatrix = false;
	int nPlotType = dp.GetPlotType();
	/// ML 10/1/2007 QA70-10268 MATRIX_FIT_FROM_CONTOUR_PLOT
	//if(IDM_PLOT_3D_MESH == nPlotType)
	//	bFromMatrix = true;
	if(IDM_PLOT_3D_MESH == nPlotType || IDM_PLOT_CONTOUR == nPlotType)
		bFromMatrix = true;
	/// end MATRIX_FIT_FROM_CONTOUR_PLOT

	return bFromMatrix;
}
///end SUPPORT_FIT_MATRIX_FROM_GRAPH
*/
///end HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA

// virtual
BOOL	FitNL::SetInfoFromXF(int nOption, LPCSTR lpcszClass, StringArray &saOptions, StringArray &saNames, LPCSTR lpcszStr2)
{
	/*
	GETN_USE(trOp)
	GETN_BEGIN_BRANCH(SpecInfo, "")
		GETN_STR(Options, "", "")
		GETN_NUM(Option, "", 0)
		GETN_STR(Names, "", "")
		GETN_STR(Categ, "", "")
	GETN_END_BRANCH(SpecInfo)
	*/
	
	Tree trOp;
	GetTree(trOp);
	
	TreeNode		trSpec = tree_check_get_node(trOp, "SpecInfo");
	///Cheney 2007-9-13 SUPPORT_FIT_MATRIX_FROM_GRAPH	
	//trSpec.ClassName.strVal = lpcszClass;
	/////Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
	/////Cheney 2007-3-28 USE_FIT_TYPE_TO_GET_DATA_RULE
	//if(!lstrcmp(lpcszClass, "fitsurface"))
		//trSpec.FitType.nVal = NLFIT_XYZ_FITTING;
	//else if(!lstrcmp(lpcszClass, "fitmatrix"))
		//trSpec.FitType.nVal = NLFIT_MATRIX_FITTING;
	////if(!lstrcmp(lpcszClass, "fitsurface"))
		////trSpec.FitType.nVal = NLFIT_XYZ_FITTING;
	/////end USE_FIT_TYPE_TO_GET_DATA_RULE
	//else
		//trSpec.FitType.nVal = NLFIT_GENERAL_XY_FITTING;
	/////END CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
	
	/// Iris 4/24/2008 HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA
	/*
	trSpec.ClassName.strVal = lpcszClass;
	
	int nFitType = NLFIT_GENERAL_XY_FITTING;
	if(!lstrcmp(lpcszClass, "fitsurface"))
		nFitType = NLFIT_XYZ_FITTING;
	else if(!lstrcmp(lpcszClass, "fitmatrix")) 
		nFitType = NLFIT_MATRIX_FITTING;
	
	//if do 3d fitting from graph, lpcszClass always be "fitsurface"
	//because in the menu, if from graph, only could select surface fit
	GraphLayer gl = Project.ActiveLayer();
	if(nFitType != NLFIT_GENERAL_XY_FITTING && gl && isDataFromMatrix(gl))
	{
		nFitType = NLFIT_MATRIX_FITTING;
		trSpec.ClassName.strVal = "fitmatrix";
	}
	
	trSpec.FitType.nVal = nFitType;	
	*/	
	string		strClass(lpcszClass);
	trSpec.FitType.nVal = get_fit_type(strClass);
	trSpec.ClassName.strVal = strClass;	
	///end HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA
	
	///end SUPPORT_FIT_MATRIX_FROM_GRAPH
		
	trSpec.Options.strVals = saOptions;
	trSpec.Option.nVal = nOption;
	/// ML 11/7/2005 QA70-8135 SURFACE_FITTING_VIA_XFUNC_NEW_WAY
	//trSpec.Names.strVals = saNames;
	if (0 < saNames.GetSize())
		trSpec.Names.strVals = saNames;
	/// end SURFACE_FITTING_VIA_XFUNC_NEW_WAY
	if (lpcszStr2)
		trSpec.Categ.strVal = lpcszStr2;
	///Arvin 04/24/07 v8.0607  SURFACE_FIT_NEED_UPDATE_TROPERATION_BEFORE_RUNNING_CHANGE_PARAM_AND_RECALCULATE
	//Change parameter and recalculate don't call this function, so we should not set this attribute at here
	//I will move them to function OnBeforeCalculation
	/*
	/// Iris 9/06/06 SURFACE_FIT_REPORT_MAT_FIT_DATA
	if(HasZ(trOp))
	{
		TreeNode trData = trOp.GUI.Output.Data;
		if(trData)
			trData.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
	}
	///ENd SURFACE_FIT_REPORT_MAT_FIT_DATA
	
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	if(GetFitType(trOp) == NLFIT_MATRIX_FITTING)
	{
		TreeNode trData = trOp.GUI.Output.Residual;
		if(trData)
			trData.SetAttribute(STR_REPORT_MATRIX_DATA, 1);
	}
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	*/
	///end SURFACE_FIT_NEED_UPDATE_TROPERATION_BEFORE_RUNNING_CHANGE_PARAM_AND_RECALCULATE
	SetTree(trOp);
	return TRUE;
}
/// end INVOKING_OPERATION_FROM_XFUNCTION

			
/// Iris 12/30/2006 v8.0534 CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE
virtual bool 	FitNL::insertDerivedParamsNames(vector<string>& vstrParameterNames, vector<string>& vsDerivedParamNames, bool bIncPostfix, vector<bool>& vnTarget, int index)
{
	if(NULL == m_pFitSession)
		return error_report("found invalid m_pFitSession in insertDerivedParamsNames");
	
	int 	nMultiplicity = m_pFitSession->GetNumberMultiplicity();
	int		nOffset = m_pFitSession->GetReplicaOffsetFromFDF();
	int		nUnit = m_pFitSession->GetReplicaUnitFromFDF();
	
	if(nMultiplicity > 1)
	{
		///------ Folger 12/23/08 v8.0990 FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
		//if( !bIncPostfix )
		//{
			//for(int ii = 1; ii < nMultiplicity; ii++)
			//{
				//for(int jj = nOffset-1, nn = 0; nn < nUnit; jj++, nn++)
					//vstrParameterNames.Add(vstrParameterNames[jj]);
			//}
		//}
		///------ End FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
		
		int 	nNumDerivedParamOnePeak = vsDerivedParamNames.GetSize() / nMultiplicity;
		for(int ii = 0; ii < nMultiplicity; ii++)
		{
			for(int jj = nNumDerivedParamOnePeak * ii, nNum = 0; nNum < nNumDerivedParamOnePeak; jj++, nNum++)
			{
				if( ii > 0 && bIncPostfix)
					//vsDerivedParamNames[jj] = vsDerivedParamNames[nNum] + "__" + (string)(ii + 1);
					vsDerivedParamNames[jj] = m_pFitSession->GetReplicaParamIndexedName(vsDerivedParamNames[nNum], ii + 1);
				
				int	nInsertPlace = (nOffset - 1) + nUnit * (ii + 1) + nNum + nNumDerivedParamOnePeak * ii;
				vstrParameterNames.InsertAt(nInsertPlace, vsDerivedParamNames[jj]);	
				vnTarget.InsertAt(nInsertPlace, true);
			}
		}
		return true;
	}	

	if( bIncPostfix )
	{
		ParamsNamesAddPostfix(vsDerivedParamNames, index);
	}
	
	vstrParameterNames.Append(vsDerivedParamNames);
	
	vector<bool> vnTemp(vsDerivedParamNames.GetSize());
	vnTemp = 1;
	vnTarget.Append(vnTemp);
	
	
	return true;
}
///end CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE

///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
virtual bool FitNL::insertDerivedParamsUnits(vector<string>& vstrParameterUnits, vector<string>& vsDerivedParamUnits, vector<bool>& vnTarget, int index)
{
	if(NULL == m_pFitSession)
		return error_report("found invalid m_pFitSession in insertDerivedParamsUnits");
	
	int 	nMultiplicity = m_pFitSession->GetNumberMultiplicity();
	int		nOffset = m_pFitSession->GetReplicaOffsetFromFDF();
	int		nUnit = m_pFitSession->GetReplicaUnitFromFDF();
	
	if(nMultiplicity > 1)
	{
		int 	nNumDerivedParamOnePeak = vsDerivedParamUnits.GetSize() / nMultiplicity;
		for(int ii = 0; ii < nMultiplicity; ii++)
		{
			for(int jj = nNumDerivedParamOnePeak * ii, nNum = 0; nNum < nNumDerivedParamOnePeak; jj++, nNum++)
			{
				int	nInsertPlace = (nOffset - 1) + nUnit * (ii + 1) + nNum + nNumDerivedParamOnePeak * ii;
				vstrParameterUnits.InsertAt(nInsertPlace, vsDerivedParamUnits[jj]);	
				vnTarget.InsertAt(nInsertPlace, true);
			}
		}
		return true;
	}

	vstrParameterUnits.Append(vsDerivedParamUnits);
	
	vector<bool> vnTemp(vsDerivedParamUnits.GetSize());
	vnTemp = 1;
	vnTarget.Append(vnTemp);

	return true;
}
///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT

///------ Folger 12/23/08 v8.0990 FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
/*
///----Jasmine 10/17/07 these codes should write into a function
int		FitNL::GetParametersInFunctions(vector<string> &vstrParameterNames, int nNumberFunction, bool bIncNumPostfix)
{
	//Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
	//int		nMultiplicity = m_pFitSession->GetNumberMultiplicity();
	int 	nParamStart = 0;
	for( int nFunc = 0; nFunc < nNumberFunction; nFunc++ )
	{
		int		nMultiplicity = m_pFitSession->GetNumberMultiplicity(nFunc);
		if( nMultiplicity > 1 )		
		{	
			///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
			//int nOffset = m_pFitSession->GetReplicaOffsetFromFDF();  
			//int nUnit = m_pFitSession->GetReplicaUnitFromFDF();
			int nOffset = m_pFitSession->GetReplicaOffsetFromFDF(nFunc);  
			int nUnit = m_pFitSession->GetReplicaUnitFromFDF(nFunc);
			///end PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
			for( int ii = 1; ii < nMultiplicity; ii++ )
				for(int jj = nParamStart+nOffset-1; jj < nOffset + nUnit -1; jj++)
				{
					///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
					//vstrParameterNames[jj] = vstrParameterNames[jj] + "__" + (string)(ii+1);
					int nParam = ii*nUnit+jj;
					string strParamName = vstrParameterNames[jj];
					if(bIncNumPostfix)
						//strParamName += "__" + (string)(ii+1);
						strParamName = m_pFitSession->GetReplicaParamIndexedName(strParamName, ii+1);
					if(nParam >= vstrParameterNames.GetSize())
						vstrParameterNames.Add(strParamName);
					else
						vstrParameterNames[nParam] = strParamName;
					///end PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
				}
		}
	///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
		if(nFunc == 0)
			nParamStart--;
		vector<string> vsParams;
		nParamStart += m_pFitSession->GetParamNamesInFunction(vsParams, nFunc)
	}
	return vstrParameterNames.GetSize();
}
///----End 
*/
///------ End FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA

int		FitNL::GetParameters(TreeNode &trOp, int index, vector<string> &vstrParameterNames, bool bIncNumPostfix, bool bIncDerivedParams, vector<bool>& vbIsDerived)
{
	/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
	int		nSessionIndex = index;
	int		nResultIndex = index;
	int		nNumData = GetTotalNumData(trOp);
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/*
	if( isSepFit(trOp) )
	{
		nSessionIndex = 0;		
	}
	///end SUPPORT_INDEP_FIT_MODE
	*/
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
		
	///// Iris 2/15/06 QA70-8461 v8.0365 INCLUDE_RPLICA_FOR_FITTING, 
	////return m_pFitSession->GetNumParamsInFunction(vstrParameterNames);
	//--- Iris 8/17/06 m_pFitSession is invalid when calculation is over
	//return m_pFitSession->GetNumParamsByDataset(vstrParameterNames, index);
	if( NULL != m_pFitSession)
	{
		/// Iris 12/29/2006 v8.0534 PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
		//return m_pFitSession->GetNumParamsByDataset(vstrParameterNames, index);
		int		nNumParams;
		
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		/*
		if(bIncNumPostfix)
			nNumParams = m_pFitSession->GetNumParamsByDataset(vstrParameterNames, index);		
		else
			nNumParams = m_pFitSession->GetParamNamesInFunction(vstrParameterNames);
		*/
		/// Iris 06/28/2007 SEPARATE_PFM_OP_CLASS
		//nNumParams = m_pFitSession->GetParamNamesInFunction(vstrParameterNames);
		int 	nFunc = 0;
		int 	nNumberFunction = m_pFitSession->GetNumberFitFunctions();
		///------ Folger 12/23/08 v8.0990 FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
		//if( nNumberFunction > 1 )
		if ( nNumData <= 1 )
		///------ End FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
			nFunc = -1; //-1 means to get param names from all functions	
		///Sophy 10/17/2008 FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
		//nNumParams = m_pFitSession->GetParamNamesInFunction(vstrParameterNames, nFunc);
		nNumParams = m_pFitSession->GetParamNamesInFunction(vstrParameterNames, nFunc, !bIncNumPostfix );
		///end FIX_PA_PARAMETER_NAME_NOT_CORRECT_IN_REPORT
		///end SEPARATE_PFM_OP_CLASS
		
		if(bIncNumPostfix)
		{
			/// Iris 9/22/2008 NEW_PA, NLParametersManager::GetColumn alreay take care of name postfix for multi functions
			/*
			/// Iris 06/28/2007 SEPARATE_PFM_OP_CLASS
 			// to add postfix to avoid same parameter name
			if( nNumberFunction > 1 )		
			{
				int	nParam = 0;
				for( int ii = 0; ii < nNumberFunction; ii++ )
				{
					///Jasmine 08/13/08 QA80-12009 PARAM_HAS_SAME_NOTATION_AS_75_FOR_MULTI_DS_AND_REPLICA_AND_PEAK
					vector<string> vsParamNames;
					int nCount = m_pFitSession->GetParamNamesInFunction(vsParamNames, ii);
					int nPostfix = ii+1;//offset
					
					if( m_pFitSession->HasBaselinePeak() )
					{
						nPostfix--;//skip baseline peak
						if(0 == ii)
						{
							nParam += nCount;
							continue;
						}
					}
					
					for(int jj = 0; jj < nCount; jj++)
					{
						//vstrParameterNames[nParam++] = vsParamNames[jj] + "__" + (string)(ii+1);
						vstrParameterNames[nParam++] = m_pFitSession->GetReplicaParamIndexedName(vsParamNames[jj], nPostfix);
					}				
					///End PARAM_HAS_SAME_NOTATION_AS_75_FOR_MULTI_DS_AND_REPLICA_AND_PEAK
				}
			}
			///end SEPARATE_PFM_OP_CLASS
			*/
			///end NEW_PA
			
			/*
			///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
			//int		nMultiplicity = m_pFitSession->GetNumberMultiplicity();
			int 	nParamStart = 0;
			for( int nFunc = 0; nFunc < nNumberFunction; nFunc++ )
			{
			///end 	PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
				int		nMultiplicity = m_pFitSession->GetNumberMultiplicity(nFunc);
				if( nMultiplicity > 1 )		
				{	
					///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
					//int nOffset = m_pFitSession->GetReplicaOffsetFromFDF();  
					//int nUnit = m_pFitSession->GetReplicaUnitFromFDF();
					int nOffset = m_pFitSession->GetReplicaOffsetFromFDF(nFunc);  
					int nUnit = m_pFitSession->GetReplicaUnitFromFDF(nFunc);
					///end PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
					for( int ii = 1; ii < nMultiplicity; ii++ )
						for(int jj = nParamStart+nOffset-1; jj < nOffset + nUnit -1; jj++)
						{
							///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
							//vstrParameterNames[jj] = vstrParameterNames[jj] + "__" + (string)(ii+1);
							int nParam = ii*nUnit+jj;
							string strParamName = vstrParameterNames[jj] + "__" + (string)(ii+1);
							if(nParam >= vstrParameterNames.GetSize())
								vstrParameterNames.Add(strParamName);
							else
								vstrParameterNames[nParam] = strParamName;
							///end PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
						}
				}
			///Arvin 09/18/07 QA70-10356 PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
				if(nFunc == 0)
					nParamStart--;
				vector<string> vsParams;
				nParamStart += m_pFitSession->GetParamNamesInFunction(vsParams, nFunc)
			}
			///end PFM_SHOULD_USE_NLFIT_FDF_AND_ORIGINAL_LOGIC_WRONG
			*/
			///------ Folger 12/23/08 v8.0990 FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
			//GetParametersInFunctions(vstrParameterNames, nNumberFunction, bIncNumPostfix);
			///------ End FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
			if( nNumData > 1 )
			{
				for( int jj = 0; jj < nNumParams; jj++ )
				{
					//vstrParameterNames[jj] = vstrParameterNames[jj] + "_" + (string)(nResultIndex+1);
					vstrParameterNames[jj] = m_pFitSession->GetMultiDataParamIndexedName(vstrParameterNames[jj], nResultIndex+1);
				}
			}
			nNumParams = vstrParameterNames.GetSize();
		}
		///end SUPPORT_INDEP_FIT_MODE
				
		
		if( bIncDerivedParams )
		{
			vector<bool> 	vbIsDerivedTemp;
			vbIsDerivedTemp.SetSize(nNumParams);
			vbIsDerivedTemp = false; //non derived parameter for now
			
			vector<string> 	vsDerivedParamNames;
			/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
			//if( m_pFitSession->GetDerivedParameters(index, &vsDerivedParamNames) )
			if( m_pFitSession->GetDerivedParameters(nSessionIndex, &vsDerivedParamNames) )
			///end SUPPORT_INDEP_FIT_MODE
			{				
				insertDerivedParamsNames(vstrParameterNames, vsDerivedParamNames, bIncNumPostfix, vbIsDerivedTemp, nResultIndex);
			}
			///Jasmine 10/12/07 QA70-10522 GET_REPLICA_PARAM_IF_NO_DERIVED_PARAM
			else if( !bIncNumPostfix )
			{
				/*int 	nMultiplicity = m_pFitSession->GetNumberMultiplicity();
				int		nOffset = m_pFitSession->GetReplicaOffsetFromFDF();
				int		nUnit = m_pFitSession->GetReplicaUnitFromFDF();
				for(int ii = 1; ii < nMultiplicity; ii++)
				{
					for(int jj = nOffset-1, nn = 0; nn < nUnit; jj++, nn++)
						vstrParameterNames.Add(vstrParameterNames[jj]);
				}*/	
				///------ Folger 12/23/08 v8.0990 FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
				//GetParametersInFunctions(vstrParameterNames, nNumberFunction, bIncNumPostfix);
				///------ End FAST_ACCESS_ABOUT_GETTING_PARAMETER_NAMES_IN_NLFIT_AND_PA
				vbIsDerivedTemp.SetSize(vstrParameterNames.GetSize());
				vbIsDerivedTemp = false;
			}
			///End GET_REPLICA_PARAM_IF_NO_DERIVED_PARAM
			if(vbIsDerived)
				vbIsDerived = vbIsDerivedTemp;			
		}
		return nNumParams;
		///end PARAM_NAME_AS_TAGNAME_FOR_CELL_LINKING
	}
	
	//m_pFitSession is invalid when calculation is over, so must get parameter names from parameter tables in operation tree
	TreeNode 	trParams = tree_get_node_by_id(trOp.Calculation, IDST_FIT_PARAMETER, true);
	if( trParams )
	{
		//the total number of input data
		DataRange 	dr;
		TreeNode 	trInputData = trOp.GUI.InputData;
		dr.Create(trInputData, FALSE);
		int 		nDataset = dr.GetNumData(GetDataRules(trOp));
		if( nDataset <= 0) 
			return 0;
		
		//get the number of parameters
		int		nNumParams = trParams.Children.Count() / nDataset;
		///Joseph 9/18/06 CHANGE_FINDX_FROMY_STEP   If the parameter name is empty, then not added to vstrParameterNames
		//vstrParameterNames.SetSize(nNumParams); 
		///End CHANGE_FINDX_FROMY_STEP
		//get the name of parameters
		for(int ii=0; ii<nNumParams; ii++)			
		{
			TreeNode	trOneParam = tree_get_node_by_id(trParams,  make_one_set_ID(IDST_FIT_PARAMETER_ONE_SET + ii, index), true);
			if(trOneParam)
			{
				string 		strParamName;
				if(trOneParam.GetAttribute(STR_LABEL_ATTRIB, strParamName))
					///Joseph 9/18/06 CHANGE_FINDX_FROMY_STEP
					//vstrParameterNames[ii] = strParamName;
					if(! strParamName.IsEmpty())
						vstrParameterNames.Add(strParamName);
					///End CHANGE_FINDX_FROMY_STEP
			}
		}
		///Joseph 9/18/06 CHANGE_FINDX_FROMY_STEP
		//return nNumParams;				
		return vstrParameterNames.GetSize();
		///End CHANGE_FINDX_FROMY_STEP
	}
	return 0;
	//---
	/////End INCLUDE_RPLICA_FOR_FITTING
}

///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
// virtual
int		FitNL::GetParamUnits(TreeNode& trOp, int index, vector<string> &vstrParameterUnits, bool bIncDerivedUnits, vector<bool>& vbIsDerived)
{
	int		nSessionIndex = index;
	int		nResultIndex = index;
	int		nNumData = GetTotalNumData(trOp);
		
	if( NULL != m_pFitSession)
	{
		int		nNumParams;
		
		int 	nFunc = 0;
		int 	nNumberFunction = m_pFitSession->GetNumberFitFunctions();
		if ( nNumData <= 1 )
			nFunc = -1; //-1 means to get param names from all functions	
		nNumParams = m_pFitSession->GetParamUnitsInFunction(vstrParameterUnits, nFunc );

		if( bIncDerivedUnits )
		{
			vector<bool> 	vbIsDerivedTemp;
			vbIsDerivedTemp.SetSize(nNumParams);
			vbIsDerivedTemp = false; //non derived parameter for now
			
			vector<string> 	vsDerivedParamNames, vsDerivedParamUnits;
			if( m_pFitSession->GetDerivedParameters(nSessionIndex, &vsDerivedParamNames, NULL, &vsDerivedParamUnits) )
			{				
				insertDerivedParamsUnits(vstrParameterUnits, vsDerivedParamUnits, vbIsDerivedTemp, nResultIndex);
			}
			else
			{
				vbIsDerivedTemp.SetSize(vstrParameterUnits.GetSize());
				vbIsDerivedTemp = false;
			}
			if(vbIsDerived)
				vbIsDerived = vbIsDerivedTemp;			
		}
		return nNumParams;
	}

	//m_pFitSession is invalid when calculation is over, so must get parameter names from parameter tables in operation tree
	TreeNode 	trParams = tree_get_node_by_id(trOp.Calculation, IDST_FIT_PARAMETER, true);
	if( trParams )
	{
		//the total number of input data
		DataRange 	dr;
		TreeNode 	trInputData = trOp.GUI.InputData;
		dr.Create(trInputData, FALSE);
		int 		nDataset = dr.GetNumData(GetDataRules(trOp));
		if( nDataset <= 0) 
			return 0;
		
		//get the number of parameters
		int		nNumParams = trParams.Children.Count() / nDataset;
		//get the name of parameters
		for(int ii=0; ii<nNumParams; ii++)			
		{
			TreeNode	trOneParam = tree_get_node_by_id(trParams,  make_one_set_ID(IDST_FIT_PARAMETER_ONE_SET + ii, index), true);
			if(trOneParam && trOneParam.Unit)
				vstrParameterUnits.Add(trOneParam.Unit.strVal);
		}
		return vstrParameterUnits.GetSize();
	}
	return 0;
}
///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT

/// Iris 6/07/05 NLSF_SUPPORT_XYZ_DATA
DWORD	FitNL::GetDataRules(const TreeNode& trOperation, bool bIgnoreCombineInfo)
{
	bool 		bIsXYZData = HasZ(trOperation);
	
	DWORD	dw =  DRR_NO_FACTORS;	
	int nFitType = GetFitType(trOperation);
	switch(nFitType)
	{
	case NLFIT_XYZ_FITTING:
		dw |= DRR_GET_Z_DEPENDENT;
		break;
	case NLFIT_MATRIX_FITTING:
		dw |= DRR_MATRIX_DATA;
		break;
	case NLFIT_GENERAL_XY_FITTING:
	default: //if no spcieal info, set it as XY Fitting
		dw |= DRR_GET_DEPENDENT | DRR_RAW_ERR_WEIGHT;
	}
	if ( nFitType ==  NLFIT_GENERAL_XY_FITTING)
		dw |= DRR_NLFIT;
	if(nFitType ==  NLFIT_XYZ_FITTING)
		dw |= DRR_ONE_DATA;	
	return CheckDataRules(trOperation, dw, bIgnoreCombineInfo);
}

///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
int 	FitNL::GetFitType(TreeNode& trOp)
{
	TreeNode		trSpec = trOp.SpecInfo;
	/// Iris 8/15/2008 QA80-12025 TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
	/*
	if (!trSpec)
		///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
		//return -1;
		//default is general XY Fitting
		return NLFIT_GENERAL_XY_FITTING;
		///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	*/
	if(!trSpec)
	{		
		if(trOp.FitType && !trOp.FitType.IsEmpty())
			return trOp.FitType.nVal;
		return NLFIT_GENERAL_XY_FITTING;
	}
	///end TO_FIX_DOUBLE_MEANING_FOR_nOption_IN_FITNL
	
	return trSpec.FitType.nVal;
}
///end CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX

/// Iris 3/21/2008 v8.0829 QA80-10934 ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME
//virtual 
string 	FitNL::GetResultBookName(TreeNode& trGUI)
{
	string strName = E_STR_NL_FIT_REPORT_TABLE_BOOK_SHORT_NAME;
	TreeNode trOp = trGUI.Parent();
	if(!trOp)
		return strName;
	
	switch(GetFitType(trOp))
	{
	case NLFIT_XYZ_FITTING:
		strName = E_STR_XYZ_FIT_REPORT_TABLE_BOOK_SHORT_NAME;
		break;
	case NLFIT_MATRIX_FITTING:
		strName = E_STR_MATRIX_FIT_REPORT_TABLE_BOOK_SHORT_NAME;
		break;
	default:
		break;
	}
	
	return strName;
}
///end ADD_EDITBOX_TO_SPECIFICATION_BOOK_SHEET_NAME	

//virtual 
string 	FitNL::GetResultSheetName(TreeNode& trGUI)
{
	///Sophy 6/11/2008 QA80-10934-P14 CORRECT_REPORT_SHEETNAME_ON_NLFIT_EXP
	/*
	/// Iris 4/21/2008 SHOW_NLFIT1_AS_SHEET_NAME_IN_XYZFIT
	//string strName = STR_NL_FIT_REPORT_TABLE_SHEET_NAME;
	string	strName;
	///end SHOW_NLFIT1_AS_SHEET_NAME_IN_XYZFIT
	TreeNode trOp = trGUI.Parent();
	if(!trOp)
		return strName;	
	switch(GetFitType(trOp))
	{
	case NLFIT_XYZ_FITTING:
		strName = STR_XYZ_FIT_REPORT_TABLE_SHEET_NAME;
		break;
	case NLFIT_MATRIX_FITTING:
		strName = STR_MATRIX_FIT_REPORT_TABLE_SHEET_NAME;
		break;
	default:
		strName = STR_NL_FIT_REPORT_TABLE_SHEET_NAME;
		break;
	}
	return strName;
	*/
	string	strName = STR_FITTEROPERATION_CLASS_FITNL;
	Tree	trOp;
	GetTree( trOp );
	
	IsSpecFit( trOp, &strName );
	
	if( 0 == strName.Compare("fitmatrix") )
		strName = "FitMatrix";
	if( 0 == strName.Compare("fitsurface") )
		strName = "FitSurface";
	if( 0 == strName.Compare("fitsigmoidal") )
		strName = "FitSigmoidal";
	if( 0 == strName.Compare("fitexp") )
		strName = "FitExp";
	
	return (strName + "1");
	///end CORRECT_REPORT_SHEETNAME_ON_NLFIT_EXP
}
/// Sophy 5/07/2008 QA80-10934-P5 v8.0857 FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME//virtual
//virtual
TreeNode FitNL::GetSheetNameNode( TreeNode& trBookSheetBranch, int nIndex)
{
	Tree trOp;
	GetTree( trOp );
	int nType = GetFitType( trOp );
	if( NLFIT_MATRIX_FITTING == nType || NLFIT_XYZ_FITTING == nType )
		return trBookSheetBranch.SheetName;
	return FitterOperation::GetSheetNameNode( trBookSheetBranch, nIndex);
}
//virtual
void FitNL::SetFindXYOutputSheetDefaultName( TreeNode& trGUI)
{
	TreeNode trOperation = trGUI.Parent();

	int nType = GetFitType( trOperation );
	if( NLFIT_MATRIX_FITTING == nType || NLFIT_XYZ_FITTING == nType )
	{
		SetOneOutputBookSheetDefaultName(trGUI, trGUI.Output.FindXY, false, GetResultCurveSheetFullName(trOperation, 0, OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET),0); 
	}
	else
		FitterOperation::SetFindXYOutputSheetDefaultName( trGUI );
}
/// End FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME

/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
void	FitNL::InitNLFitCurvePointer(TreeNode &trOp)
{
	CleanupNLFitCurve("InitFitSessionPointer");
	
	//------ Folger 10/14/08 WRONG_NLF_CURVES_CLASS_IN_PA_MAKES_WRONG_REPORT
	/*
	int nFitType = GetFitType(trOp);
	ASSERT( m_pFitSession );///Sophy 10/14/2008 QA80-12370 FIX_RUNTIME_IN_2ND_TIME_RECALCULATE_MATRIX_FIT_ANALYSIS_TEMPLATE
	switch(nFitType)
	{
	case NLFIT_XYZ_FITTING:
		m_pNLFCurves = new SurfaceFitCurves(m_pFitSession);
		break;
	case NLFIT_MATRIX_FITTING:
		m_pNLFCurves = new MatrixFitCurves(m_pFitSession);
		break;
	case NLFIT_GENERAL_XY_FITTING:
	default:
		m_pNLFCurves = new NLFCurves(m_pFitSession);
		break;
	}
	*/
	m_pNLFCurves = createNLFCurvePointer(trOp);
	//------ End WRONG_NLF_CURVES_CLASS_IN_PA_MAKES_WRONG_REPORT	
	
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	// curve object should only be created when doing report, in this moment, all options are ready and stable
	ASSERT(trOp.GUI.Graph1);
	GetNLFCurvePointer()->SetFitCurveOptions(trOp.GUI.Graph1); /// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
	/// end FITNL_USING_NEW_NLFSESSION
}

NLFCurvesBase* 	FitNL::GetNLFCurvePointer()
{
	if( NULL == m_pNLFCurves )
	{
		Tree trOp;
		GetTree(trOp);
		
		InitNLFitCurvePointer(trOp);
	}
	ASSERT(m_pNLFCurves);
	return m_pNLFCurves;
}
/// end FITNL_USING_NEW_NLFSESSION

///Arvin 04/17/07 v8.0602 FIT_MATRIX_HISTOGRAM_PLOT
static  bool _plot_histogram_from_matrix_range(DataRange & dr, GraphLayer& gl, int& nPlot)
{
	int nStartPlot = -1;
	for(int nRange=0; nRange < dr.GetNumRanges(); nRange++)
	{
		int c1, c2, r1, r2;
		MatrixLayer mlTemp;
		dr.GetRange(nRange, r1, c1, r2, c2, mlTemp);
		if(!mlTemp.IsValid())
			return false;
		
		if(c2 < 0)
			c2 = c1;
		
		for( int nMatrixObject = c1; nMatrixObject <= c2; nMatrixObject++ )
		{
			MatrixPage mp = mlTemp.GetPage();
			if(!mp)
				return false;
			
			int nIndex = mlTemp.GetIndex();
			mp.SetShow();
			if(!page_set_active_layer(mp, nIndex, false))
				return false;
			
			if(mlTemp.SetActive(nMatrixObject))
				LT_execute("worksheet -p 219 Hist");
			else
				return false;
			
			GraphLayer glTemp = Project.ActiveLayer();
			if(glTemp)
			{
				DataPlot dp = glTemp.DataPlots(0);
				if(dp)
					nPlot = gl.AddPlot(dp, TRUE);
				GraphPage gp = glTemp.GetPage();
				if(gp)
					gp.Destroy();
				else
					glTemp.Destroy();
			}
		}	
	}
	
	return true;	
}



///Sophy 12/29/2008 v8.0991b QA80-12832 SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS
#define	NUM_LCL_UCL_OF_ONE_DATA	2
#define	NUM_LPL_UPL_OF_ONE_DATA	2
static int	_plot_confidence_and_prediction_bands_for_one_xy(GraphLayer& gl, const DataRange& dr, int nPlotType, const int& nXIndex, const int& nYIndex, const int& nNumOfX, const int& nNumOfY, const TreeNode& trFitCurve, DWORD dwCtrl = GAP_USE_TEMPLATE, bool bCheckHasPlot = true)
{
	if ( !trFitCurve || !trFitCurve.Use || !gl || !dr )
		return -1;
	
	ASSERT( nXIndex >= 0 && nYIndex >=0 );
	ASSERT( 1 == dr.GetNumRanges() );
	
	int nC1, nC2, nR1, nR2;
	Worksheet wks;
	dr.GetRange(0, nR1, nC1, nR2, nC2, wks);
	
	int nNumCols = nC2 - nC1 + 1;
	if ( !wks || nXIndex > nC2 || nYIndex > nC2 )
		return -1;
	
	TreeNode trConfBands = trFitCurve.ConfBands;
	TreeNode trPredBands = trFitCurve.PredBands;
	int nConfOffset = (trConfBands && trConfBands.nVal) ? (nNumOfX + nNumOfY) : -1; //-1 means don't plot
	int nPredOffset = (trPredBands && trPredBands.nVal) ? ((nConfOffset < 0) ? (nNumOfX + nNumOfY) : (nConfOffset + nNumOfY * NUM_LCL_UCL_OF_ONE_DATA)) : -1; 
	ASSERT( nConfOffset < nC2 && nPredOffset < nC2 );
	
	if ( nConfOffset < 0 && nPredOffset < 0 ) //no need to plot
		return 0;
		
	
	DataRange drOneBands;
	drOneBands.Add(wks, nXIndex, "X");
	if ( nConfOffset > 0 ) //nConfOffset is of course bigger than 0, for there a fit X & fit Y before them
	{
		int nCurConfIndex = nConfOffset + nYIndex * NUM_LCL_UCL_OF_ONE_DATA;
		drOneBands.Add(wks, nCurConfIndex, "Y"); //LCL
		drOneBands.Add(wks, nCurConfIndex + 1, "Y" ); //UCL
	}
	if ( nPredOffset > 0 )
	{
		int nCurPredIndex = nPredOffset + nYIndex * NUM_LPL_UPL_OF_ONE_DATA;
		drOneBands.Add(wks, nPredOffset, "Y"); //LPL
		drOneBands.Add(wks, nPredOffset + 1, "Y"); //UPL
	}
	
	vector<int> vnPlotIndex;
	if ( bCheckHasPlot && check_has_plotted_in_graph(drOneBands, gl, vnPlotIndex) > 0 && vnPlotIndex.GetSize() > 0 )
		return vnPlotIndex[0]; //already plotted, return the first plot's index
	
	return gl.AddPlot(drOneBands, nPlotType, dwCtrl);
}
///end SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS
///Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
//int FitNL::PlotOneResultsDataRange(TreeNode& trOp, GraphLayer& gl, DataRange drTable, int nPlotType, int nGraphIndex, int nPictureIndex, int nPicColIndex)
/// Iris 08/06/2007 v8.0674 NOT_PLOT_AGAIN_IF_PLOTTED_FOR_REPORT_GRAPH
//int FitNL::PlotOneResultsDataRange(TreeNode& trOp, GraphLayer& gl, DataRange drTable, int nPlotType, int nGraphIndex, int nPictureIndex, int nPicColIndex, bool bIsSourceGraph)
///Arvin 08/15/07 QA70-10212-P3 ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
//int FitNL::PlotOneResultsDataRange(TreeNode& trOp, GraphLayer& gl, DataRange drTable, int nPlotType, int nGraphIndex, int nPictureIndex, int nPicColIndex, bool bIsSourceGraph, bool bCheckIfHasPlot)
int FitNL::PlotOneResultsDataRange(TreeNode& trOp, GraphLayer& gl, DataRange drTable, int nPlotType, int nGraphIndex, int nPictureIndex, int nPicColIndex, bool bIsSourceGraph, bool bCheckIfHasPlot, int* pStartPlotIndex)
///end ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
///end NOT_PLOT_AGAIN_IF_PLOTTED_FOR_REPORT_GRAPH
///end FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
{
	///Sophy 10/27/2008 USE_NLFCURVES_TO_PLOT_IN_REPORT_GRAPH Sophy 10/29/2008 rool back, use old logic currently
	///*
	int nPlot = -1;
	int nFitType = GetFitType(trOp); 
	if(nFitType == NLFIT_MATRIX_FITTING && nPlotType == IDM_PLOT_HISTOGRAM_TYPE)
	{
		_plot_histogram_from_matrix_range(drTable, gl, nPlot);	
		return nPlot;		
	}
	///Sophy 12/29/2008 v8.0991b QA80-12832 SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS
	//this logic only for NLFit, moved from WksReportOperation::PlotOneResultsDataRange
	else if(!HasZ(trOp) && (GetNumX(trOp) > 1 || GetNumY(trOp) > 1))
	{
		int		nXIndex = nPicColIndex;
		///Sophy 12/23/2008 v8.0990 QA80-12832 SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
		//int		nYIndex = nPictureIndex;
		int		nYIndex = (nPictureIndex / GetReportGraphTableColNum(trOp, nGraphIndex)) % GetNumY(trOp); //(nPicturedIndex/GetReportGraphTableColNum(trOp, nGraphIndex) is row_index, row_index%GetNumY(trOp) is a specified Y index in a specified dataset
		///end SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
		nPlot = plot_wks_one_xy_from_data_range(drTable, gl, nPlotType, nXIndex, nYIndex, bCheckIfHasPlot);	
		
		DWORD dwCtrl = GAP_USE_TEMPLATE | GAP_ALLOW_DUPLICATE_COL;
		dwCtrl |= GetPlotCtrl(trOp);
		_plot_confidence_and_prediction_bands_for_one_xy(gl, drTable, nPlotType, nXIndex, nYIndex, GetNumX(trOp), GetNumY(trOp), GetGUIGraphNodes(trOp, nGraphIndex), dwCtrl, bCheckIfHasPlot);
		return nPlot;
	}
	///end SUPPORT_PLOT_CONFIDENCE_AND_PREDICTION_BANDS_FOR_MULTI_INDEPS_AND_DEPS
	
	///Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
	//return WksReportOperation::PlotOneResultsDataRange(trOp, gl, drTable, nPlotType, nGraphIndex, nPictureIndex, nPicColIndex);
	/// Iris 08/06/2007 v8.0674 NOT_PLOT_AGAIN_IF_PLOTTED_FOR_REPORT_GRAPH
	//return WksReportOperation::PlotOneResultsDataRange(trOp, gl, drTable, nPlotType, nGraphIndex, nPictureIndex, nPicColIndex, bIsSourceGraph);
	///Arvin 08/15/07 QA70-10212-P3 ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
	//return WksReportOperation::PlotOneResultsDataRange(trOp, gl, drTable, nPlotType, nGraphIndex, nPictureIndex, nPicColIndex, bIsSourceGraph, bCheckIfHasPlot);
	return WksReportOperation::PlotOneResultsDataRange(trOp, gl, drTable, nPlotType, nGraphIndex, nPictureIndex, nPicColIndex, bIsSourceGraph, bCheckIfHasPlot, pStartPlotIndex);
	///end ADD_NEW_PLOT_FOR_COLUMN_TYPE_CHANGED_AND_REMOVE_REDUNDANT_PLOTS
	///end NOT_PLOT_AGAIN_IF_PLOTTED_FOR_REPORT_GRAPH
	///end FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
	//*/
	//int nPlot = -1;
	//DataRange dr;
	//convert_result_curve_range_to_one_plotted_range( drTable, dr );
	//if( GRAPH_FIT_CURVE  == nGraphIndex )
	//{
		//nPlot = GetNLFCurvePointer()->PlotFitCurve( gl, dr, GetFitSession()->GetDataObject() );
	//}
	//else if( GRAPH_RESIDUALS_SCATTER == nGraphIndex )
	//{
		//nPlot = GetNLFCurvePointer()->PlotResidual( gl, dr );
	//}
	//return nPlot;
	///end USE_NLFCURVES_TO_PLOT_IN_REPORT_GRAPH
}
///end FIT_MATRIX_HISTOGRAM_PLOT

/// ML 11/2/2005 QA70-8135 MISSING_AND_MASKED_DATA_FOR_XYZ
// virtual
///Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
//bool	FitNL::HasZ(TreeNode& trOp)
bool	FitNL::HasZ(TreeNode& trOp, bool *pbHasXIndep, bool *pbHesYIndep)
///end REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
{
	/// Iris 7/28/06 CHECK_HAS_Z_FROM_XF_INFO
	///// Iris 5/15/06 v8.0410 CLEANUP_ISXYZDATA_CODES
	////return m_pFitSession->IsXYZData();	
	//return nlf_is_3d_function(trOp);
	string 	strCalssName;
//	bool bSpac = IsSpecFit(trOp, strCalssName);CPY 10/19/06 FIT_SPECIAL_RUN_TIME_ERR
	bool bSpac = IsSpecFit(trOp, &strCalssName);
	///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
	//if(bSpac && !lstrcmp(strCalssName, "fitsurface"))
	int nFitType = GetFitType(trOp);
	///Cheney 2007-4-3 REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
	//if(nFitType == NLFIT_XYZ_FITTING || nFitType == NLFIT_MATRIX_FITTING)
	/////end CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
		//return true;
	//return false;
	//XY fitting only has X indep
	bool bHasZ = false;
	if(pbHasXIndep != NULL)
		*pbHasXIndep = true;
	if(pbHesYIndep != NULL)
		*pbHesYIndep = false;
	
	if(nFitType != NLFIT_GENERAL_XY_FITTING)
	{
		bHasZ = true;
		if(nFitType == NLFIT_XYZ_FITTING) //XYZ fitting should show both X and Y Indep 
		{
			if(pbHesYIndep != NULL)
				*pbHesYIndep = true;
		}
		else //matrix fitting not show X and Y Indep 
		{
			if(pbHasXIndep != NULL)
				*pbHasXIndep = false;
		}
	}
	return bHasZ;
	///end REMOVE_XY_IN_INPUT_TABLE_WHEN_FIT_MATRIX
	/////End CLEANUP_ISXYZDATA_CODES
	//end CHECK_HAS_Z_FROM_XF_INFO
}
/// end QA70-MISSING_AND_MASKED_DATA_FOR_XYZ

/// YuI 11/09/06 SOME_REDESIGN_OF_NLFIT_FOR_MODAL
/*
//---- CPY 4/23/05 OK_ON_BAD_FIT_DO_NOT_CLOSE_DIALOG
void FitNL::SetFitSession(NLFitSession* pFitSession)
{
	if(pFitSession)
	{
		if(m_pFitSession)
			error_report("m_pFitSession not NULL in FitNL::OnNoEdit");
		
		m_pFitSession = pFitSession;
		m_bUseFitSession = true;
		/// Iris 06/16/06 SET_BACK_FIT_POINTER_FOR_BAD_FIT
		//---- Iris 5/23/06 must remove session preview data since the fitting data will be created in operation calss again
		//if(bRemoveSessionPreview)
			//m_pFitSession->RemovePreviewData();
		//----
		///End SET_BACK_FIT_POINTER_FOR_BAD_FIT
	}
	else
		m_bUseFitSession = false;
}
//----
*/
/// SOME_REDESIGN_OF_NLFIT_FOR_MODAL
/// Iris 06/16/06 SET_BACK_FIT_POINTER_FOR_BAD_FIT

/// YuI 11/09/06 SOME_REDESIGN_OF_NLFIT_FOR_MODAL
/*
NLFitSession* FitNL::GetFitSession(bool bTransfer)
{
	if(m_pFitSession)
	{
		NLFitSession* pp;
		pp = m_pFitSession;
		if(bTransfer)
		{
			m_pFitSession = NULL;
			m_bUseFitSession = false;
		}		
		return pp;
	}
	return 0;
}
*/

NLFitSession* FitNL::GetFitSession()
{
	ASSERT( m_pFitSession );
	return m_pFitSession;
}
/// SOME_REDESIGN_OF_NLFIT_FOR_MODAL
///End SET_BACK_FIT_POINTER_FOR_BAD_FIT

///Iris 9/21/06 MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
//virtual 
bool FitNL::MakeFitX(int index, const string &strDataLabel, vector& vX, vector& vFitX, TreeNode trOp, const tagFitResultCurveDataOptions& fitOptions)
{
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/*
	/// Iris 3/01/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
	if( isSepFit(trOp) )
		index = 0;
	///end SUPPORT_INDEP_FIT_MODE
	*/
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//return m_pFitSession->GetFitX(vFitX, index);
	return GetNLFCurvePointer()->GetFitX(vFitX, GetFitSession()->GetDataObject(), index);
	/// end FITNL_USING_NEW_NLFSESSION
}

//virtual 
bool FitNL::MakeFitX(int index, const string &strDataLabel, matrix& mXs, matrix& mFitXs, TreeNode trOp, const tagFitResultCurveDataOptions& fitOptions)
{		
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//m_pFitSession->GetFitX(mFitXs, index);
	/// Hong 09/26/08 v8.0948 FIX_MULTI_DEPS_INDEPS_RUNTIME
	//GetNLFCurvePointer()->GetFitX(mFitXs, GetFitSession()->GetDataObject(), index);	
	GetNLFCurvePointer()->GetFitX(mFitXs, GetFitSession()->GetDataObject(), index, GetNumX(trOp));
	/// end FIX_MULTI_DEPS_INDEPS_RUNTIME
	/// end FITNL_USING_NEW_NLFSESSION
	int numXs = mFitXs.GetNumCols();
	
	/// ML 10/2/2006 NLFIT_CURVES_CLEANUP
	bool		bSort = HasZ(trOp) || 1 == numXs;
	/// end NLFIT_CURVES_CLEANUP
	
	//GraphLayer gl = Project.ActiveLayer(); ///Arvin 04/12/07 v8.0599 PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE by cp's suggestion	
	for(int ncol=0; ncol<numXs; ncol++)
	{
		vector vData, vFitX;
		mFitXs.GetColumn(vData, ncol);
		/// ML 10/2/2006 NLFIT_CURVES_CLEANUP
		//updateResultCurveXRangeSettings(vData, vFitX, fitOptions, gl);
		///Arvin 04/12/07 v8.0599 PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE by cp's suggestion	
		//updateResultCurveXRangeSettings(vData, vFitX, fitOptions, gl, bSort);
		updateResultCurveXRangeSettings(trOp, index, vData, vFitX, fitOptions, bSort);
		///end PREVIEW_RANGE_SHOULD_BE_SOUCE_GRAPH_OR_DATA_RANGE_WHEN_RANGE_TYPE_IS_SPAN_TO_FULL_AXIS_RANGE
		/// end NLFIT_CURVES_CLEANUP
		
		mFitXs.SetSize(vFitX.GetSize(), numXs);
		mFitXs.SetColumn(vFitX, ncol);
	}
	return true;
}
///end MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH


///Cheney/Arvin 2007-9-10 XOP_NEED_SUPPORT_PFM
BOOL	FitNL::IsXOPFuncReady(const TreeNode& tr)
{
	if(!tr)
		return false;
	
	string strFuncName = tr.strVal;
	return !strFuncName.IsEmpty();
}
///end XOP_NEED_SUPPORT_PFM

///Arvin 06/29/07 v8.652 XOP_NEED_SUPPORT_NLFIT
int 	FitNL::OnInitOperationTreeFromOCLT(TreeNode &trOp, TreeNode& trOCLT, bool bInitTree)
{
	if(bInitTree)
		return FitterOperation::OnInitOperationTreeFromOCLT(trOp, trOCLT);
	
	TreeNode trOutGUI = trOCLT.GetNode("GUI");
	string strFuncName, strCateg;
	TreeNode trFuncSel = trOutGUI.FunctionSelection;
	if(trFuncSel)
	{
		strFuncName = trFuncSel.FunctionList.strVal;
		strCateg = trFuncSel.CategoryList.strVal;
	}
	else
		return OP_NLSF_NOT_SELECT_FUNCTION; //Haven't selected function and category to fit
	
	DataRange drInputData;
	TreeNode trInputData = trOutGUI.InputData;
	if(trInputData)
	{
		trOp.GUI.InputData.Replace(trInputData.Clone()); //In order to copy all attributes of input data branch
		if(!drInputData.Create(trInputData, FALSE))
			return OP_GET_INPUT_DATARANGE_WRONG;
	}
	else
		return OP_INVALID_INPUT_DATA_NODE;
	
	///Cheney/Arvin 2007-9-10 XOP_NEED_SUPPORT_PFM
	//if(strFuncName.IsEmpty())
	if( !IsXOPFuncReady(trFuncSel.FunctionList) )
	///end XOP_NEED_SUPPORT_PFM
		return OP_NLSF_NOT_SELECT_FUNCTION; //Haven't selected function and category to fit
	
	///Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION
	//if(strCateg.IsEmpty())
	nlf_find_category(strFuncName, strCateg, -1);
	///end XOP_NEED_SUPPORT_CHANGE_FUNCTION
	
	int nRet = OnInitDataFromOCLT(trOp, trOp.GUI.InputData, drInputData, strFuncName, strCateg);
	if ( nRet != OP_NOERROR)
		return nRet;
	//Copy GUI tree from operation tree to OCLT treee 
	trOutGUI.Replace(trOp.GUI.Clone());
	TreeNode trUserSettings;
	if(trOCLT.UserSettings)
		trUserSettings = trOCLT.UserSettings;
	else
	{
		trOCLT.AddNode("UserSettings");
		trUserSettings = trOCLT.UserSettings;
	}
	
	trUserSettings.Replace(trOp.UserSettings.Clone());
	return OP_NOERROR;
}
///end XOP_NEED_SUPPORT_NLFIT

// virtual
///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
int 	FitNL::CheckMakeFitterInputDataNode(TreeNode &trOp, TreeNode &trInput, DataRange& dr, LPCSTR lpcszCateg, LPCSTR lpcszInputTagName)
{
	string strTagName = lpcszInputTagName;
	if(strTagName.IsEmpty())
		strTagName = "InputData";
	
	int nFitType = NLFIT_GENERAL_XY_FITTING;
	if(!lstrcmp(lpcszCateg, "Surface Fitting"))
		nFitType = NLFIT_XYZ_FITTING;
	
	TreeNode		trSpecInfo = tree_check_get_node(trOp, "SpecInfo");	
	TreeNode trFitType = tree_check_get_node(trSpecInfo, "FitType");
	trFitType.nVal = NLFIT_GENERAL_XY_FITTING;
	XYZRange xyz = dr;
	if(xyz && nFitType == NLFIT_XYZ_FITTING)
	{
		MatrixLayer ml;
		dr.GetParent(ml);
		if(ml.IsValid())
			trFitType.nVal = NLFIT_MATRIX_FITTING;
		else
			trFitType.nVal = NLFIT_XYZ_FITTING;			
	}
	else if(!xyz && nFitType == NLFIT_XYZ_FITTING)
	{
		MatrixLayer ml;
		dr.GetParent(ml);
		if(!ml.IsValid())
		{
			error_report("Invalid matrix or xyz range for surface fitting!");
			return OP_WRONG_TYPE_DATA_RANGE;
		}
		trFitType.nVal = NLFIT_MATRIX_FITTING;
	}
	
	XYRange xy = dr;
	if(!xy && nFitType == NLFIT_GENERAL_XY_FITTING)
	{
		error_report("Invalid xy range for non-linear curve fitting!");
		return OP_WRONG_TYPE_DATA_RANGE;
	}
	
	if(!trInput.IsValid())
		return OP_INVALID_INPUT_DATA_NODE;
	
	trInput.AddNode(strTagName);
	TreeNode trTemp = trInput.GetNode(strTagName);
	if(!dr.GetTree(trTemp, FALSE))
		return OP_FAILED_GET_TREE_FROM_DATA_RANGE;
	
	return OP_NOERROR;
}
///END CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX

/// Hong 02/01/08 v8.0798 FIX_CONTANTENATE_FIT_FAIL_WORK
// virtual 
bool 	FitNL::PrepareFitTypeFromInput(TreeNode& trOp, DataRange& dr, LPCSTR lpcszCateg)
{
	Tree trInput;	
	if ( OP_NOERROR != CheckMakeFitterInputDataNode(trOp, trInput, dr, lpcszCateg, STR_INPUT_RANGE_NAME) )
		return false;
	return true;
}
/// end FIX_CONTANTENATE_FIT_FAIL_WORK

///Cheney 2007-7-16 SHOULD_SHARE_CODE_BETWEEN_NLFITSPLITTER_AND_FITNL_ABOUT_AUTOINIT_AND_LINEAR_CONSTRAINT
bool 	FitNL::setAutoInitAndLinearConstrtoOperationTree(TreeNode& trOp)
{
	TreeNode trAutoParamsInit = trOp.GUI.Parameters.AutoParamsInit;
	trAutoParamsInit.nVal = GetFitSession()->IsEnableAutoParamsInitFromOperation(trAutoParamsInit);
	TreeNode trLinearConstraints = trOp.GUI.Parameters.LinearConstraints;
	trLinearConstraints.nVal = GetFitSession()->IsEnableConstraintsFromOperation( trLinearConstraints);
	return true;

}
///end SHOULD_SHARE_CODE_BETWEEN_NLFITSPLITTER_AND_FITNL_ABOUT_AUTOINIT_AND_LINEAR_CONSTRAINT

///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
//BOOL	FitNL::OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, XYRange &xyrng, LPCSTR lpcszStr1, LPCSTR lpcszStr2)
///Arvin 01/29/08 SHOULD_NOT_ADD_USER_PARAM_SETTING_TREE_IN_CLASS_LT_NLFit
//int	FitNL::OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, DataRange &dr, LPCSTR lpcszStr1, LPCSTR lpcszStr2)
///------- Folger 07/01/09 QA80-13774-P1 COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
//int	FitNL::OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, DataRange &dr, LPCSTR lpcszStr1, LPCSTR lpcszStr2, bool bNeedUserParamSetting)
int	FitNL::OnInitDataFromOCLT(TreeNode &trOp, TreeNode& trInputData, DataRange &dr, LPCSTR lpcszStr1, LPCSTR lpcszStr2, bool bNeedUserParamSetting, TreeNode& trOriginalInput/* = NULL*/)
///------- End COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
///end SHOULD_NOT_ADD_USER_PARAM_SETTING_TREE_IN_CLASS_LT_NLFit
/// end CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
{
	///------- Folger 07/01/09 QA80-13774-P1 COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
	#ifdef		__FIT_COMPARE_MODEL_IMPROVEMENT__
	if ( trOriginalInput )
	{
		trInputData.Replace(trOriginalInput, TRUE, TRUE, TRUE);
	}
	else
	{
	#endif		/// __FIT_COMPARE_MODEL_IMPROVEMENT__
	///------- End COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
		Tree			trInput;
		TreeNode		trInputDataTemp;
		string			strInputDataTagName = "InputData"; 
		///Arvin 03/27/07 QA70-9532 CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
		//if ( !xyrng.MakeFitterInputDataNode(trInput, strInputDataTagName) )
		//	return FALSE;
		int nRet = CheckMakeFitterInputDataNode(trOp, trInput, dr, lpcszStr2, strInputDataTagName);
		if(nRet != OP_NOERROR)
			return nRet;
		///end CALLING_SURFACE_FIT_FROM_OC_LT_AND_SUPPORT_MATRIX
		
		trInputDataTemp = trInput.GetNode(strInputDataTagName);
		if (!trInputDataTemp.IsValid())
			return OP_INVALID_INPUT_DATA_NODE;
	
		///Arvin/Cheney 03/26/07 QA70-9527 SUPPORT_SETTING_PARAMS_FROM_OC_LT
		//trInputData.Replace(trInputDataTemp, TRUE, TRUE);
		//if user set replica or data mode, should call OnInitDataFromOCLT again,
		//reconstruct user setting tree
		trInputData.Replace(trInputDataTemp, TRUE, TRUE, TRUE);
		///end SUPPORT_SETTING_PARAMS_FROM_OC_LT
	///------- Folger 07/01/09 QA80-13774-P1 COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
	#ifdef		__FIT_COMPARE_MODEL_IMPROVEMENT__
	}
	#endif		/// __FIT_COMPARE_MODEL_IMPROVEMENT__
	///------- End COMPARE_MODELS_FOR_FITTING_WITH_WEIGHT_FAILS_WHEN_NOT_OUTPUT_FIT_STATISTICS_TABLE
	trOp.GUI.FunctionSelection.FunctionList.strVal = lpcszStr1;	// function name
	trOp.GUI.FunctionSelection.CategoryList.strVal = lpcszStr2;	// category name
	
	///Arvin 05/16/07 SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
	if(GetFitType(trOp) != NLFIT_GENERAL_XY_FITTING)
		_add_y_datatype_branch_for_surface_and_matrix_fitting(trOp);
	///end SET_CUSTOM_RANGE_DEFAULT_AS_INPUT_DATA_RANGE
	if(NULL == m_pFitSession)
	{
		InitFitSessionPointer(trOp);  /// Iris 4/14/06 NLFITSESSION_POINTER_FOR_NORMAL_FIT_OR_PFM	
	
	}
	GetFitSession()->SetInitData(FALSE);
	
	///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
	///Arvin 11/10/07 XOP_NEED_SUPPORT_CHANGE_FUNCTION
	//if(m_trFDF.Children.Count() == 0)
	bool bNeedLoadFDF = true;
	if(isFDFTreeValid())//if(m_trFDF.Children.Count() > 0)//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
	{
		string strOldFuncName, strOldCateg;
		strOldFuncName = GetFitSession()->GetFunctionName(&strOldCateg);
		if(strOldFuncName.Compare(lpcszStr1) == 0 && strOldCateg.Compare(lpcszStr2) == 0 )
			bNeedLoadFDF = false;
	}
	
	if(bNeedLoadFDF)
	///end 	XOP_NEED_SUPPORT_CHANGE_FUNCTION
	{
		///Cheney 2007-7-30 ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF	
		//string strFilenameTemp;
		//nlf_get_fdf_filename(lpcszStr1, NULL, NULL, &strFilenameTemp);
		/////Cheney 2007-6-8 ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC
		////if(!nlsf_FDF_to_tree(strFilenameTemp, &m_trFDF, FDFT_CONVERT_BOOL_TO_01))
		//if(!nlsf_load_FDF_to_tree(strFilenameTemp, &m_trFDF, FDFT_CONVERT_BOOL_TO_01, true))
		/////end ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC
			//return false;
		if(!LoadFDFtoTree(lpcszStr1))
			//return false;
			return OP_FAIL_LOAD_FDF_TO_TREE; /// Hong 01/31/08 QA80-10929 LTNLFIT_MORE_DETAILS_ERROR_MSG
		///end ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
	}
	GetFitSession()->SetTreeFDF(m_trFDF);
	///end CLEAN_UP_FDF_TREE_LOAD
	
	///Cheney 2007-4-25 CALL_NLFIT_FROM_OC_ALSO_NEED_GET_FUNC_CODE
	GetFitSession()->GetFittingCodes(trOp.GUI.Codes);
	///end CALL_NLFIT_FROM_OC_ALSO_NEED_GET_FUNC_CODE
	
	///Arvin/Cheney 03/26/07 QA70-9527 SUPPORT_SETTING_PARAMS_FROM_OC_LT
	//if this function no replica, but Replica set more then 0
	///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
	//if( m_pFitSession->GetReplicaOffsetFromFDF() < 1 && trOp.GUI.Fit.Replica.Number.nVal > 0)
	//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
	//if( GetFitSession()->GetReplicaOffsetFromFDF() < 1 && trOp.GUI.Replica.Number.nVal > 0)
	if( GetFitSession()->GetReplicaOffsetFromFDF() < 1 && get_gui_replica_node(trOp.GUI).Number.nVal > 0)
	//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
	///end 	MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		return OP_FUNCTION_NOT_SUPPORT_REPLICA;
	
	nlsf_check_get_GUI_params_with_ID(trOp.GUI); 	///Cheney 2007-6-22 SHOULD_ADD_AUTOINIT_AND_LINEARCONSTRA_FOR_OCCODE_CALL_NLFIT
	
	setAutoInitAndLinearConstrtoOperationTree(trOp); ///Cheney 2007-7-16 SHOULD_SHARE_CODE_BETWEEN_NLFITSPLITTER_AND_FITNL_ABOUT_AUTOINIT_AND_LINEAR_CONSTRAINT
	
	bool bParamsReady, bHasFitGood;
	///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD	
	//if( !m_pFitSession->InitFromOperationTree(trOp, bHasFitGood, bParamsReady) )
	///Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
	//if( !m_pFitSession->InitFromOperationTree(trOp, bHasFitGood, bParamsReady, false, false, false, false) ) //bDoFitAnyWay, bAutoInitParams, bInitData, bLoadFDF
	if( !GetFitSession()->InitFromOperationTree(trOp, bHasFitGood, bParamsReady, false, 0, false, false) ) //bDoFitAnyWay, dwInitParams, bInitData, bLoadFDF
	///end CLEAN_UP_FDF_TREE_LOAD
		return OP_FAILED_INIT_FROM_OPERATION_TREE;
	
	//if multi data set, not support replica
	///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
	//if( m_pFitSession->GetNumDataset() > 1 && trOp.GUI.Fit.Replica.Number.nVal > 0)
	//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
	//if( GetFitSession()->GetNumDataset() > 1 && trOp.GUI.Replica.Number.nVal > 0)
	if( GetFitSession()->GetNumDataset() > 1 && get_gui_replica_node(trOp.GUI).Number.nVal > 0)
	//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
	///end 	MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		return OP_MULTI_DATA_SET_NOT_SUPPORT_REPLICA;

	///Arvin 01/29/08 SHOULD_NOT_ADD_USER_PARAM_SETTING_TREE_IN_CLASS_LT_NLFit
	//AddParamsInfoToOperationTree(trOp, lpcszStr1, lpcszStr2);
	if(	bNeedUserParamSetting)
		AddParamsInfoToOperationTree(trOp, lpcszStr1, lpcszStr2);
	///end SHOULD_NOT_ADD_USER_PARAM_SETTING_TREE_IN_CLASS_LT_NLFit
	///end SUPPORT_SETTING_PARAMS_FROM_OC_LT
	return OP_NOERROR;
}

///Arvin/Cheney 03/26/07 QA70-9527 SUPPORT_SETTING_PARAMS_FROM_OC_LT
static bool _values_from_vector_to_tree_sub_nodes(TreeNode& trParams, const vectorbase& vec, const vector<string>& vsParamNames, LPCSTR lpcszTagName, bool bFloat = false)
{
	int nSize = vec.GetSize();
	TreeNode trVals = tree_check_get_node(trParams, lpcszTagName);
	for(int ii = 0; ii < nSize; ii++)
	{
		//should assume vsParamNames[ii] is valid tag name
		string strTagName  = vsParamNames[ii];
		//string strTagName  = cvt_str_to_tag_name( vsParamNames[ii] );
		TreeNode trTemp = tree_check_get_node(trVals, strTagName);
		if(!trTemp.IsValid())
			return false;
		
		if(bFloat)
			trTemp.dVal = vec[ii];
		else
			trTemp.nVal = vec[ii];	
	}
	
	//remove redudent node
	int nChildren = trVals.Children.Count();
	for(int jj = ii; jj < nChildren; jj++)
	{
		TreeNode trTemp = trVals.Children.Item(ii);
		trTemp.Remove();
	}
	
	return true;
}

bool 	FitNL::AddParamsInfoToOperationTree(TreeNode &trOp, LPCSTR lpcszFunName, LPCSTR lpcszCateg, string strTagName)
{
	/* Hong, to do, comment out for compile
	TreeNode trSpecInfo = tree_check_get_node(trOp, "UserSettings");
	TreeNode trParams = tree_check_get_node(trSpecInfo, strTagName);
	
	//get Params name
	vector<string> vsParamNames;
	if(!m_pFitSession->GetParamsSettingStringVector(vsParamNames, PARMAS_SETTING_NAMES))
		return false;

	//get other settings, set to user params tree
	///Jasmine 10/24/07 CHANGE_SHARE_VECTOR_TO_INT
	vector<int> vnShared;
	if(!m_pFitSession->GetParamsSettingIntVector(vnShared, PARMAS_SETTING_SHARE))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vnShared, vsParamNames, "Share");
	///End CHANGE_SHARE_VECTOR_TO_INT
	vector<bool> vbFixed;
	if(!m_pFitSession->GetParamsSettingIntVector(vbFixed, PARMAS_SETTING_FIXED))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vbFixed, vsParamNames, "Fixed");
	
	vector vValues;
	if(!m_pFitSession->GetParamsSettingDoubleVector(vValues, PARMAS_SETTING_VALUES))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vValues, vsParamNames, "Values", true);
	
	/// Iris 5/20/2008 QA80-11371 SAVE_FIX_VALUE_WITH_TOGETHER_WITH_FIX_STATUS
	vector vFixedValues;
	if(!m_pFitSession->GetParamsSettingDoubleVector(vFixedValues, PARMAS_SETTING_FIXED_PARAM_VALUE))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vFixedValues, vsParamNames, "FixedValues", true);
	///end SAVE_FIX_VALUE_WITH_TOGETHER_WITH_FIX_STATUS
	
	vector vParaLowerBounds;
	if(!m_pFitSession->GetParamsSettingDoubleVector(vParaLowerBounds, PARMAS_SETTING_LOWERBOUNDS))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vParaLowerBounds, vsParamNames, "LowerBounds", true);
	
	vector vParaUpperBounds;
	if(!m_pFitSession->GetParamsSettingDoubleVector(vParaUpperBounds, PARMAS_SETTING_UPPERBOUNDS))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vParaUpperBounds, vsParamNames, "UpperBounds", true);
	
	vector<bool> vbpbExclusiveLower;
	if(!m_pFitSession->GetParamsSettingIntVector(vbpbExclusiveLower, PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vbpbExclusiveLower, vsParamNames, "LowerBoundsExclusive");
	
	vector<bool> vbpbExclusiveUpper;
	if(!m_pFitSession->GetParamsSettingIntVector(vbpbExclusiveUpper, PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vbpbExclusiveUpper, vsParamNames, "UpperBoundsExclusive");
	
	vector<bool> vbOnLowerBounds;
	if(!m_pFitSession->GetParamsSettingIntVector(vbOnLowerBounds, PARMAS_SETTING_LOWERBOUNDSENABLE))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vbOnLowerBounds, vsParamNames, "LowerBoundsEnable");
	
	vector<bool> vbOnUpperBounds;
	if(!m_pFitSession->GetParamsSettingIntVector(vbOnUpperBounds, PARMAS_SETTING_UPPERBOUNDSENABLE))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vbOnUpperBounds, vsParamNames, "UpperBoundsEnable");

	///Jasmine 10/17/07 MISSING_SIGN_DIGITES, sign
	vector<int> vnSignDigit;
	if(!m_pFitSession->GetParamsSettingIntVector(vnSignDigit, PARMAS_SETTING_SIGN_DIGITES))
		return false;
	_values_from_vector_to_tree_sub_nodes(trParams, vnSignDigit, vsParamNames, "SignificantDigit");
	///End MISSING_SIGN_DIGITES
	*/
	return true;			
}
///end SUPPORT_SETTING_PARAMS_FROM_OC_LT

/// Iris 5/19/2008 RENAME_OLD_FUNCTION_AND_MOVE_TO_SUIT_PLACE
//void 	FitNL::OnAfterAddOneDataStatsResultsToReportTree(TreeNode& trOp, int index)
void 	FitNL::OnAfterAddParamtersSummaryTable(TreeNode& trOp, int index)
///end RENAME_OLD_FUNCTION_AND_MOVE_TO_SUIT_PLACE
{
	//---- Iris 3/28/2007 v8.0591 From Max, when fit mode is Global fit, remove Reduced ChiSqr and Adjust R Square columns from Summary table
	TreeNode trOutSummary = trOp.Calculation.Summary;
	if(DATA_MODE_GLOBAL == trOp.GUI.InputData.Use && trOutSummary)
	{
		string		strTagName = "R" + (index+1);
		TreeNode 	trOneSet = trOutSummary.GetNode(strTagName);
		if(trOneSet)
		{
			strTagName = "Stats_ReducedChiSqr";
			TreeNode 	trN = trOneSet.GetNode(strTagName);
			if(trN)
				trN.Remove();
			
			strTagName = "Stats_AdjRSquare";
			trN = trOneSet.GetNode(strTagName);
			if(trN)
				trN.Remove();			
		}		
	}
	//----
}

/// Iris 03/02/2007 v8.0573 GLOBAL_FIT_NEED_OUTPUT_STATS_INC_FOR_EACH_DATA_AND_FOR_ALL_DATA
/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
//bool 	FitNL::AddRegStatsToReportTree(TreeNode& trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, const RegStats &sRegStats)
bool 	FitNL::AddRegStatsToReportTree(TreeNode& trOp, int index, const string &strDataLabel, int nTotalNumData, const vector<string> &vstrFactors, const RegStats &sRegStats, int* pnSetIndex/* = NULL*/)
/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
{
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//if(FitterOperation::AddRegStatsToReportTree(trOp, index, strDataLabel, nTotalNumData, vstrFactors, sRegStats))
	if(FitterOperation::AddRegStatsToReportTree(trOp, index, strDataLabel, nTotalNumData, vstrFactors, sRegStats, pnSetIndex))
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	{
		string 		str = CALCULATION_REPORT_TABLE_COL_PREFIX + (index+1);
		TreeNode	trStatsTable = trOp.Calculation.RegStats;
		TreeNode 	trCol = trStatsTable.GetNode(str);
		if(trCol)
		{
			bool 	bGlobalFit = DATA_MODE_GLOBAL == trOp.GUI.InputData.Use? true : false;
			bool	bStatsPreOneData = index < nTotalNumData? true : false;
			if(bGlobalFit && bStatsPreOneData)
			{				
				trCol.N.Reset(true);
				trCol.DOF.Reset(true);
				trCol.ReducedChiSq.Reset(true);
				trCol.AdjRSq.Reset(true);
				trCol.RMSESD.Reset(true);
				
			}
			
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			int		nSetIndex = 0;
			if ( pnSetIndex )
				nSetIndex = *pnSetIndex;
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			//Add "Number of Iterationss" and "Fit Status" Columns
			//------ Folger 01/31/08 QA80-10929 CENTRALIZE_CODE_TO_GENERATE_NUMBER_OF_ITERATION
			//if(trOp.GUI.Quantities.Statistics.NumIter.nVal)
			//{
				//TreeNode trN = tree_check_get_node(trCol, "NumIter", 1, STR_LABEL_ATTRIB, _L("Number of Iterations"));
				//trN.nVal = m_pFitSession->GetNumberItersPerformed();
				//trN.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
			//}
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			//TreeNode trN = m_pFitSession->CheckAddNumIterNode(trCol);
			TreeNode trN = GetFitSession()->CheckAddNumIterNode(trCol, nSetIndex);
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			trN.SetAttribute(STR_SHOW_ATTRIB, trOp.GUI.Quantities.Statistics.NumIter.nVal);
			//------
			
			//------ Folger 02/13/08 QA80-10929 ACCESS_FIT_STATUS_FROM_LT_TREE
			//if(trOp.GUI.Quantities.Statistics.FitStatus.nVal)
			//{
				//TreeNode trN = tree_check_get_node(trCol, "FitStatus", 2, STR_LABEL_ATTRIB, _L("Fit Status"));
				/////Cheney 2007-4-2 USE_SHORT_STRING_IN_STATISTIC_COLUMN
				////trN.strVal = m_pFitSession->GetFitOutCome(false);
				//string strMsg;
				//m_pFitSession->GetShortFitOutCome(strMsg);
				//trN.strVal = strMsg;
				/////end USE_SHORT_STRING_IN_STATISTIC_COLUMN
			//}
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			//TreeNode trFitStatus = m_pFitSession->CheckAddFitStatusNode(trCol);
			TreeNode trFitStatus = GetFitSession()->CheckAddFitStatusNode(trCol, nSetIndex);
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			
			trFitStatus.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);///Sophy 3/30/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES

			trFitStatus.SetAttribute(STR_SHOW_ATTRIB, trOp.GUI.Quantities.Statistics.FitStatus.nVal);
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			//TreeNode trFitStatusErr = m_pFitSession->CheckAddFitStatusErrorCode(trCol);
			TreeNode trFitStatusErr = GetFitSession()->CheckAddFitStatusErrorCode(trCol, nSetIndex);
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			
			trFitStatusErr.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);///Sophy 3/30/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES

			trFitStatusErr.SetAttribute(STR_SHOW_ATTRIB, 0);		//always hide
			//------
			return true;
		}
		
	}
	return false;
}
///end GLOBAL_FIT_NEED_OUTPUT_STATS_INC_FOR_EACH_DATA_AND_FOR_ALL_DATA

bool	FitNL::isSepFit(TreeNode& trOp)
{
	int		nNumData = GetTotalNumData(trOp);
	/// Iris 02/27/2007 v8.0570 RENAME_DATA_MODE_TO_AVOID_CONFUSE
	//if( nNumData > 1 && DATA_MODE_INDEP_FIT == trOp.GUI.InputData.Use)
	//------ Folger 08/19/08 QA80-12042 FIX_PARAMETERS_VALUES_AND_BOUNDS_WRONG_FOR_INDEPENDENT_FIT_CONSOLIDATED_REPORT
	/// need to roll back for #12077, additional datasets value need to do duplication
	if( nNumData > 1 && DATA_MODE_INDEP_CONSOLID == trOp.GUI.InputData.Use)
	//if( nNumData > 1 && DATA_MODE_INDEP_SEP == trOp.GUI.InputData.Use)
	//------ End FIX_PARAMETERS_VALUES_AND_BOUNDS_WRONG_FOR_INDEPENDENT_FIT_CONSOLIDATED_REPORT
	///end RENAME_DATA_MODE_TO_AVOID_CONFUSE
		return true;
	return false;
}

///Cheney 2007-4-4 SHOW_LB_UB_IN_REPORT_SHEET
//------ Folger 08/18/08 QA80-12036 FIX_BOUNDS_MISSING_IN_REPORT_SHEET_FOR_REPLICA_FIT
//bool	FitNL::addOneDataLBUBToParametersTable(TreeNode& trOp, vector<string>& vstrFactors, vector<string>& vsParamNames, vector<string>& vsParamNamesPostfix, int nDataFrom)
bool	FitNL::addOneDataLBUBToParametersTable(TreeNode& trOp, vector<string>& vstrFactors, vector<string>& vsParamNames, vector<string>& vsParamNamesPostfix, int nDataFrom/* = 0*/, int nNumMultiplicity/* = 0*/)
//------
{
	TreeNode trParams = trOp.Calculation.Parameters;
	//------ Folger 08/18/08 QA80-12036 FIX_BOUNDS_MISSING_IN_REPORT_SHEET_FOR_REPLICA_FIT
	//if(!trParams)
	if ( !trParams || trParams.IsEmpty() )
	//------
		return false;
	
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	/*
	vector vParamLowerBounds;
	m_pFitSession->GetParamsSettingDoubleVector(vParamLowerBounds, PARMAS_SETTING_LOWERBOUNDS);
	
	vector<bool> vbParamLowerBoundsEnable;
	m_pFitSession->GetParamsSettingIntVector(vbParamLowerBoundsEnable, PARMAS_SETTING_LOWERBOUNDSENABLE);
	
	vector vParamUpperBounds;
	m_pFitSession->GetParamsSettingDoubleVector(vParamUpperBounds, PARMAS_SETTING_UPPERBOUNDS);
	
	vector<bool> vbParamUpperBoundsEnable;
	m_pFitSession->GetParamsSettingIntVector(vbParamUpperBoundsEnable, PARMAS_SETTING_UPPERBOUNDSENABLE);
	*/
	vector vParamLowerBounds;
	GetFitSession()->GetParamNumericValues(vParamLowerBounds, PARMAS_SETTING_LOWERBOUNDS);
	
	vector<bool> vbParamLowerBoundsEnable;
	GetFitSession()->GetParamNumericValues(vbParamLowerBoundsEnable, PARMAS_SETTING_LOWERBOUNDSENABLE);
	
	vector vParamUpperBounds;
	GetFitSession()->GetParamNumericValues(vParamUpperBounds, PARMAS_SETTING_UPPERBOUNDS);
	
	vector<bool> vbParamUpperBoundsEnable;
	GetFitSession()->GetParamNumericValues(vbParamUpperBoundsEnable, PARMAS_SETTING_UPPERBOUNDSENABLE);
	/// end FITNL_USING_NEW_NLFSESSION
	int nParams = GetFitSession()->GetNumParameter();	
	
	//------ Folger 08/18/08 QA80-12036 FIX_BOUNDS_MISSING_IN_REPORT_SHEET_FOR_REPLICA_FIT
	
	vector<int>		vnShared;
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//m_pFitSession->GetParamsSettingIntVector(vnShared, PARMAS_SETTING_SHARE);
	GetFitSession()->GetParamNumericValues(vnShared, PARMAS_SETTING_SHARE);
	/// end FITNL_USING_NEW_NLFSESSION
	int	nNumSharedParams = nParams - GetFitSession()->GeNumtNonSharedParams(nParams);
	
	/// since not to break the original code for SR3, just separate replica fit from general one
	if ( nNumMultiplicity > 1 )
	{
		ASSERT(nDataFrom == 0);
		
		int		nReplicaOffset = GetFitSession()->GetReplicaOffsetFromFDF() - 1;
		int		nReplicaUnit = GetFitSession()->GetReplicaUnitFromFDF();
		
		int		nNumDerivedParams;
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		//m_pFitSession->GetNumParamsInFunc(0, &nNumDerivedParams);
		nNumDerivedParams = GetFitSession()->GetDerivedParamNum();
		/// end FITNL_USING_NEW_NLFSESSION
		
		for ( int ii=0; ii<nNumMultiplicity; ++ii )
		{
			//------ Folger 11/05/08 QA80-12525 v8.0965 PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
			//int		nShared = 0;
			//------
			for ( int jj=0; jj<nParams; ++jj )
			{
				int			nRow = (nParams + nNumDerivedParams) * ii + jj;
				
				#ifdef	_DEBUG
				
				if ( nRow >= trParams.Children.Count() )
				{
					ASSERT(false);
					return false;
				}
					
				#endif	//_DEBUG
				
				TreeNode	trRow = trParams.Children.Item(nRow);
				
				int			nIndex = jj;
				if ( ii > 0 )
				{
					if ( jj>=nReplicaOffset )
					{
						//------ Folger 11/05/08 QA80-12525 v8.0965 PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
						//if ( vnShared[jj] > 0 )
						//{
							//++nShared;
						//}
						//else
						//{
							//nIndex = nParams + (ii - 1) * (nReplicaUnit - nNumSharedParams) + (jj - nReplicaOffset - nShared);
						//}
						nIndex = nParams + (ii - 1) * (nReplicaUnit - nNumSharedParams) + (jj - nReplicaOffset);
						//------ End PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
					}
				}
				
				TreeNode trLB = tree_check_get_node( trRow, "LowerBound", 0, STR_DATAID_ATTRIB, (string)IDE_PARAM_LOWER_BOUND );
				trLB.dVal = vbParamLowerBoundsEnable[nIndex]? vParamLowerBounds[nIndex] : NANUM;
				
				TreeNode trUB = tree_check_get_node( trRow, "UpperBound", 0, STR_DATAID_ATTRIB, (string)IDE_PARAM_UPPER_BOUND );
				trUB.dVal = vbParamUpperBoundsEnable[nIndex]? vParamUpperBounds[nIndex] : NANUM;
			}
		}
		
		return true;
	}
	//------ End FIX_BOUNDS_MISSING_IN_REPORT_SHEET_FOR_REPLICA_FIT
	
	//------ Folger 11/05/08 QA80-12525 v8.0965 PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
	////------ Folger 08/18/08 QA80-12040 FIX_BOUNDS_OUPUT_FOR_MULTIPLE_SETS_FIT
	//int		nShared = 0;
	////------
	//------ End PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
	
	for(int ii = 0, jj = nParams * nDataFrom; ii < nParams; ii++, jj++)
	{
		//Derived params should always behand func params
		TreeNode trRow = trParams.GetNode( vsParamNamesPostfix[ii]);	
		if(trRow)/// Iris 4/23/2008 v8.0848 FIX_GET_RUNTIME_ERR_WHEN_NOT_REPORT_PARAMS_TABLE
		{
			//------ Folger 08/18/08 QA80-12040 FIX_BOUNDS_OUPUT_FOR_MULTIPLE_SETS_FIT
			int		nIndex = jj;
			if ( nDataFrom > 0 )
			{
				//------ Folger 11/05/08 QA80-12525 v8.0965 PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
				/*
				if ( vnShared[ii] > 0 )
				{
					nIndex = ii;
					++nShared;
				}
				else
				{
					nIndex -= (nDataFrom - 1) * nNumSharedParams + nShared;
				}
				*/
				nIndex -= (nDataFrom - 1) * nNumSharedParams;
				//------ End PARAMETER_BOUNDS_VECTOR_INDEX_BOUNDARY_ERROR_CAUSE_REPLICA_REPORT_FAIL
			}
			//------ End FIX_BOUNDS_OUPUT_FOR_MULTIPLE_SETS_FIT
			
			TreeNode trLB = tree_check_get_node( trRow, "LowerBound", 0, STR_DATAID_ATTRIB, (string)IDE_PARAM_LOWER_BOUND );
			trLB.dVal = vbParamLowerBoundsEnable[nIndex]? vParamLowerBounds[nIndex] : NANUM;
			
			TreeNode trUB = tree_check_get_node( trRow, "UpperBound", 0, STR_DATAID_ATTRIB, (string)IDE_PARAM_UPPER_BOUND );
			trUB.dVal = vbParamUpperBoundsEnable[nIndex]? vParamUpperBounds[nIndex] : NANUM;
		}
	}
	
	return true;
}
///end SHOW_LB_UB_IN_REPORT_SHEET

///Arvin 05/08/07 QA70-9498 SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
BOOL	FitNL::isVarCovarMatrixNeedScale(const TreeNode& trOp, int nSetIndex)
{
	TreeNode trSCaleError = trOp.GUI.Fit.ScaleError;
	BOOL bScale = FALSE;
	if(trSCaleError)
	{
		bScale = trSCaleError.nVal;
	}
	
	if(GetFitSession()->IsNoneWeight(nSetIndex))
		bScale = TRUE;
	
	return bScale; 
}
/*
BOOL 	FitNL::isParamErrorNeedScale(const TreeNode& trOp, int nSetIndex)
{
	BOOL bScale = isVarCovarMatrixNeedScale(trOp, nSetIndex);
	if(m_pFitSession->IsNoneWeight(nSetIndex))
		bScale = FALSE;
	
	return bScale;
}
*/
void 	FitNL::getCovAndCorrMatrix(const TreeNode& trOp, matrix& matCov, matrix& matCorr)
{
	BOOL bScaleCovMatWithChiSq = isVarCovarMatrixNeedScale(trOp);
	if(matCov)
	{
		if(!GetFitSession()->GetVarCovarMatrix(matCov, bScaleCovMatWithChiSq))
			error_report("GetVarCovarMatrix failed!");
	}
	
	if(matCorr)
	{
		if(!GetFitSession()->GetVarCorrMatrix(matCorr, bScaleCovMatWithChiSq))
			error_report("GetVarCorrMatrix failed!");
	}
}
//------ Folger 04/22/08 CLEAN_UP_MEMORY_ALLOCATION_IN_FIT_SESSION

//move to NLFitSession.h
/*
//------ Folger 04/17/08 QA80-11434 TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
class PointerManager
{
public:
	PointerManager(void **pv, int nSize)
	{
		m_pv = malloc(nSize);
		*pv = m_pv;
	}
	
	~PointerManager()
	{
		free(m_pv);
	}
	
private:
	void *m_pv;
};
//------ End TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
*/

//------ End CLEAN_UP_MEMORY_ALLOCATION_IN_FIT_SESSION

/// Iris 4/25/2008 NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
bool	FitNL::IsReportComplexInputDataTable(TreeNode& trOp)
{
	if(GetFitType(trOp) == NLFIT_GENERAL_XY_FITTING)
		return true;	
	
	return false;
}
///end NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO

///end SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
bool	FitNL::doOneFit(TreeNode& trOp, DataRange& dr, bool bIsXYZData, int nExeMode, DWORD dwExecCntrl, int nNumData, int numSubRanges, int nNumDataToFit, int nDataFrom, bool bSepFit)
{	
	DWORD		dwRules = GetDataRules(trOp);		
	
	/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
	//Independent fit must do parameter init and fit here even though has click Fit button and fit converge
	bool	bDoFitAnyWay = false;
	if(bSepFit)
	{
		bDoFitAnyWay = true;
	}
	///end SUPPORT_INDEP_FIT_MODE
	int		nFitMode = trOp.GUI.InputData.Use;
	bool	bGlobalFit = DATA_MODE_GLOBAL == nFitMode;
	
	bool 	bParamsReady = false;
	bool 	bHasFitGood = false; /// Iris 9/18/06 CLICK_OK_SET_FUNC_DATA_AGAIN_EVEN_CLICK_FIT_OK
	
	/// Iris 2/27/2007 v8.0571 SUPPORT_INDEP_FIT_MODE
	// For other data mode, no need to init parameteters here since in dialog already init parameters and show in Parameter Tab. 
	// But for Indep fit - Consolidate report mode, need to do init separately pre each dataset here again, so introduce variable "bAutoInitParams".
	//if( !m_pFitSession->InitFromOperationTree(trOp, bHasFitGood, bParamsReady) )	
	///Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
	//bool	bAutoInitParams = bSepFit;
	DWORD	dwInitParams = NLFIT_INIT_PARMAS_AUTO;
	TreeNode trAutoInit = trOp.GUI.Parameters.AutoParamsInit;
	if(trAutoInit)
		///Cheney 2007-8-1 CORRECT_LOGIC_OF_LOADING_THEME
		//dwInitParams = trAutoInit.nVal == false? NLFIT_INIT_PARMAS_LOAD_FDF : NLFIT_INIT_PARMAS_AUTO;
	{
		if(trAutoInit.IsEmpty())
			/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
			//m_pFitSession->LoadAutoParamsInitSetting(m_trFDF);
			GetFitSession()->IsFDFEnableAutoParamsInit(); // Hong, to do, m_trFDF should be the same as the one in NLFSession, otherwise, bug
			/// end FITNL_USING_NEW_NLFSESSION
		else
			dwInitParams = trAutoInit.nVal == false? NLFIT_INIT_PARMAS_LOAD_FDF : NLFIT_INIT_PARMAS_AUTO;
	}
		///end CORRECT_LOGIC_OF_LOADING_THEME
	///end SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
	bool	bOpenDlg = (OEXEM_ON_CREATE_OPEN_GUI == nExeMode || OEXEM_ON_CHANGEPARAM == nExeMode)? true : false;
	/// Iris 02/06/2007 v8.0575b CORRECT_SETINITDATA_LOGIC
	///From Marko, m_bInitData should be TRUE in the following circumstances: 
	// 1) When doing fitting for the first time, whether using the dlg or without the dialog.	 
	// 2) Whenever user changes the fitting function. 
	//bool	bInitData = !bOpenDlg || bSepFit;
	//bool	bInitData = (bSepFit && bOpenDlg)? true : false;
	bool	bInitData = false;
	if(DATA_MODE_INDEP_SEP == nFitMode && !bOpenDlg)
		bInitData = true;
	
	///Jasmine 06/10/08 QA80-10666 SHOULD_ENABLE_FIT_AFTER_CONF_PERCENT_OR_REDUCE_CHISQR_CHANGE
	/*
	///Cheney 2007-11-12 QA70-10666 LCL_AND_UCL_WERE_WRONG_IN_NLFIT_IN_SOME_CASE
	if(m_pFitSession->IsFitConverged() && m_pFitSession->IsLCLUCLParamsChangeAfterFitConverge(trOp.GUI) ) 
		trOp.FitWorkArea.Parameters.SetAttribute(STR_FIT_OUTCOME_ATTRIB, FITITER_NO_ITERATE);
	///end LCL_AND_UCL_WERE_WRONG_IN_NLFIT_IN_SOME_CASE
	*/
	///End SHOULD_ENABLE_FIT_AFTER_CONF_PERCENT_OR_REDUCE_CHISQR_CHANGE
	///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
	//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
	//bool bLoadFDF = m_trFDF.Children.Count() == 0? true : false;
	bool bLoadFDF = !isFDFTreeValid();
	//---
	///end CLEAN_UP_FDF_TREE_LOAD
	///Arvin/Cheney 03/26/07 QA70-9527 SUPPORT_SETTING_PARAMS_FROM_OC_LT
	TreeNode trUserParamsSetting = trOp.UserSettings.Parameters;
	///Arvin 01/29/08 GENERATE_REPORT_FOR_LT_NLFit
	//if(bSepFit || !trUserParamsSetting)
	if((bSepFit || !trUserParamsSetting) && !(dwExecCntrl & OPEXEC_NO_INIT_FROM_OP_AGAIN))
	///end 	GENERATE_REPORT_FOR_LT_NLFit
	///end SUPPORT_SETTING_PARAMS_FROM_OC_LT
		///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
		//if( !m_pFitSession->InitFromOperationTree(trOp, bHasFitGood, bParamsReady, bDoFitAnyWay, bAutoInitParams, bInitData) )	
		///Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
		//if( !m_pFitSession->InitFromOperationTree(trOp, bHasFitGood, bParamsReady, bDoFitAnyWay, bAutoInitParams, bInitData, bLoadFDF) )	
		if( !GetFitSession()->InitFromOperationTree(trOp, bHasFitGood, bParamsReady, bDoFitAnyWay, bSepFit? dwInitParams : 0, bInitData, bLoadFDF) )	
		///end SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
		///end CLEAN_UP_FDF_TREE_LOAD
	///end CORRECT_SETINITDATA_LOGIC
	///end SUPPORT_INDEP_FIT_MODE
			return error_report("Err, failed from InitFromOperationTree on FitNL::doOneFit");
	
	if( dwExecCntrl & OPEXEC_NO_INIT_FROM_OP_AGAIN )
		bHasFitGood = GetFitSession()->IsFitConverged();
			
	///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
	if(!isFDFTreeValid())//if(m_trFDF.Children.Count() == 0)//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
		m_trFDF = GetFitSession()->GetTreeFDF();
	///end CLEAN_UP_FDF_TREE_LOAD
	
	///Arvin/Cheney 03/26/07 QA70-9527 SUPPORT_SETTING_PARAMS_FROM_OC_LT	
	//if(!(dwExecCntrl & OPEXEC_NO_PARAM_INIT))
	//if do NLfit from OC, TrUserParamSetting should be valid 
	if(trUserParamsSetting)
	{
		//Notes:if user set all params value already. no need to init
		//otherwise init params, then set value from user setting tree if
		//any node value is not NANUM. 
		//and if replica > 0, init will not init each peak center, should
		//always set by user
		bool bGlobalFit = trOp.GUI.InputData.Use == DATA_MODE_GLOBAL? true : false;
		if(!GetFitSession()->SetParamVectorsFromUserParamsSetting(trUserParamsSetting, nDataFrom < 0? 0 : nDataFrom, bGlobalFit) )
			return false;
		
		int nParamsValid = GetFitSession()->CheckIfParamValuesValid(nNumDataToFit);
		if(nParamsValid != PARAMS_VALID_ALL)
			///Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
			//m_pFitSession->ParamsInitValues(false, true);
			/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
			//m_pFitSession->ParamsInitValues(false, true, false, dwInitParams & NLFIT_INIT_PARMAS_AUTO);					
			GetFitSession()->ParamsInitValues(dwInitParams & NLFIT_INIT_PARMAS_AUTO, NLF_RESET_SHARE_FIX);		
			/// end FITNL_USING_NEW_NLFSESSION
			///end SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
		///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
		//if(nParamsValid == PARAMS_VALID_PART || trOp.GUI.Fit.Replica.Number.nVal > 0)
		//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		//if(nParamsValid == PARAMS_VALID_PART || trOp.GUI.Replica.Number.nVal > 0)
		if(nParamsValid == PARAMS_VALID_PART || get_gui_replica_node(trOp.GUI).Number.nVal > 0)
		//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH	
		{
			/// Hong, to do, comment out for compile
			/*
			vector vParamValues;
			if(!m_pFitSession->GetParamsSettingDoubleVector(vParamValues, PARMAS_SETTING_VALUES))
				return false;
			
			if(!nlf_set_double_param_from_user_params_setting(trUserParamsSetting.Values, vParamValues, nDataFrom < 0? 0 : nDataFrom))
				return false;
			
			if(!m_pFitSession->SetParamsSettingDoubleVector(vParamValues, PARMAS_SETTING_VALUES))
				return false;
			*/
			///
		}
		
		//Set params to NLFit
		///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
		//if(nParamsValid != PARAMS_VALID_NONE || trOp.GUI.Fit.Replica.Number.nVal > 0)
		//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		//if(nParamsValid != PARAMS_VALID_NONE || trOp.GUI.Replica.Number.nVal > 0)
		if(nParamsValid != PARAMS_VALID_NONE || get_gui_replica_node(trOp.GUI).Number.nVal > 0)
		//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		///end 	MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
			GetFitSession()->UpdateParamsFromUserSetting();
	}
	else if(!(dwExecCntrl & OPEXEC_NO_PARAM_INIT))
	///end SUPPORT_SETTING_PARAMS_FROM_OC_LT
	{
		if(!bParamsReady)
		{
			///Cheney 2007-7-23 QA80-10090 MODIFY_STH_ABOUT_FDF_SAVING_AND_THEME_APPLY	
			/////Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
			////m_pFitSession->ParamsInitValues();
			//m_pFitSession->ParamsInitValues(false, false, false, dwInitParams & NLFIT_INIT_PARMAS_AUTO);
			/////end SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
			///// Iris 02/24/2007 v8.0569 FAIL_APPLY_PARAM_FROM_THEME_WHEN_CHOOSE_THEME_FROM_MENU
			/////Cheney 2007-4-29 SEPRATE_BOUND_SETTING_FROM_PARAMS_SETTING_CEHCK_BOX
			////m_pFitSession->OperationGUIToParams(trOp.GUI.Parameters, true);
			//TreeNode trParamsSetting = trOp.GUI.Parameters;
			//DWORD dwCopySetting = 0;
			//if(trParamsSetting.ApplyParamsTheme && trParamsSetting.ApplyParamsTheme.nVal == 1)
				//dwCopySetting |= NLFIT_COPY_GUI_SETTING_PARAMS;
			//if(trParamsSetting.ApplyBoundTheme && trParamsSetting.ApplyBoundTheme.nVal == 1)
				//dwCopySetting |= NLFIT_COPY_GUI_SETTING_BOUND;
			//m_pFitSession->OperationGUIToParams(trOp.GUI.Parameters, true, true, dwCopySetting);
			/////end SEPRATE_BOUND_SETTING_FROM_PARAMS_SETTING_CEHCK_BOX
			/////end FAIL_APPLY_PARAM_FROM_THEME_WHEN_CHOOSE_THEME_FROM_MENU
			/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
			/*
			m_pFitSession->OperationGUIToParams(trOp.GUI.Parameters, true, true, NLFIT_COPY_GUI_SETTING_PARAMS | NLFIT_COPY_GUI_SETTING_BOUND);
			if ( dwInitParams & NLFIT_INIT_PARMAS_AUTO ) /// Hong 12/26/07 QA80-10499 FIX_LOST_THEME_VALUES_WHEN_FROM_MRU_NOT_AUTO_INIT
			m_pFitSession->ParamsInitValues(false, false, false, dwInitParams & NLFIT_INIT_PARMAS_AUTO);
			///end MODIFY_STH_ABOUT_FDF_SAVING_AND_THEME_APPLY
			m_pFitSession->ParamsToOperationGUI(trOp.GUI.Parameters); ///Cheney 2007-8-22 SHOULD_ADD_PARAMS_TO_TREE_WHEN_SEP_FIT
			*/
			GetFitSession()->OperationGUIToParams(trOp.GUI.Parameters);
			if ( dwInitParams & NLFIT_INIT_PARMAS_AUTO ) /// Hong 12/26/07 QA80-10499 FIX_LOST_THEME_VALUES_WHEN_FROM_MRU_NOT_AUTO_INIT
				m_pFitSession->ParamsInitValues(dwInitParams & NLFIT_INIT_PARMAS_AUTO);
			///end MODIFY_STH_ABOUT_FDF_SAVING_AND_THEME_APPLY
			GetFitSession()->ParamsToOperationGUI(trOp.GUI.Parameters); ///Cheney 2007-8-22 SHOULD_ADD_PARAMS_TO_TREE_WHEN_SEP_FIT
			/// end FITNL_USING_NEW_NLFSESSION
		}
		else 
		{		
			if(IS_EXE_ON_AUTO_UPDATE(nExeMode))
			{
				///Cheney 2007-7-12 SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
				//m_pFitSession->ParamsInitValues();
				if ( dwInitParams & NLFIT_INIT_PARMAS_AUTO ) /// Hong 12/26/07 QA80-10499 FIX_LOST_THEME_VALUES_WHEN_FROM_MRU_NOT_AUTO_INIT					
					//m_pFitSession->ParamsInitValues(false, false, false, dwInitParams & NLFIT_INIT_PARMAS_AUTO);
					GetFitSession()->ParamsInitValues(dwInitParams & NLFIT_INIT_PARMAS_AUTO); /// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
				///end SHOULD_LOAD_FROM_FDF_IF_NOT_AUTO_INIT_AND_NOT_OPEN_DLG
			}
		}
	}
	
	///Cheney 2007-4-10 IF_SEP_FIT_SHOULD_DISABLE_FIT_AND_ITER_BUTTON
	if(bOpenDlg && bSepFit)
		getUserSettingFromGUI(nDataFrom);
	///end IF_SEP_FIT_SHOULD_DISABLE_FIT_AND_ITER_BUTTON
	
	int nFitOutcome;
	///Arvin 01/29/08 GENERATE_REPORT_FOR_LT_NLFit
	//if( !bHasFitGood ) 
	/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	/*
	if( !bHasFitGood && !(dwExecCntrl & OPEXEC_NO_FIT_AGAIN))
	///end GENERATE_REPORT_FOR_LT_NLFit
		GetFitSession()->Fit(&nFitOutcome);
	*/
	if ( !bHasFitGood )
	{
		if ( !(dwExecCntrl & OPEXEC_NO_FIT_AGAIN) )
			GetFitSession()->Fit(&nFitOutcome);
		else if ( OPEXEC_FORCE_CALCUTE_OUTPUT & dwExecCntrl )
			GetFitSession()->GetChiSqr(NULL, true);
	}
	/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	
	vector vY, vX, vWeights, vZ;
	matrix mXs, mYs;
	vector<string> vstrFactors;
	DWORD dwPlotUID;
	Worksheet wksData;	

	//------ Folger 04/17/08 QA80-11434 TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
	//FitParameter	arrstFitParameter[MAX_MR_PARAMS];		// max num parameters (100)
	//FitDerivedParameter		arrstDerivedParams[MAX_MR_PARAMS];
	FitParameter			*arrstFitParameter = NULL;
	FitDerivedParameter		*arrstDerivedParams = NULL;
	//------
	
	RegStats		sRegStats;
	RegStats		sRegStatsGlobal;
	NLSFFitInfo		sFitInfo;	
	RegANOVA		stANOVA;
	RegANOVARow 	stCorrTotal; ///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
	
	GetFitSession()->ParamsToOperation(trOp);
	//m_pFitSession->ComputeParamsUpperLowerBounds();/// Iris 11/02/06 v8.0502e COMMENT_IT_AS_IT_CAUSE_LOTS_TIME_TO_CALC
	//bool	bShared = m_pFitSession->IsSharedParameters();
	bool	bShared = GetFitSession()->HasSharedParameters(); /// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	
	/// ML 9/5/2006 MASKED_MISSING_NLFIT_TABLES
	int	nDeps, nIndeps;
	StringArray	vstrDepVarNames, vstrIndepVarNames;
	if ( !GetFitSession()->GetNumVars(&nDeps, &nIndeps, &vstrDepVarNames, &vstrIndepVarNames) )
		return false;
	/// end MASKED_MISSING_NLFIT_TABLES	
	
	vector vAveErr;
	string strDataLabel;
	double	dTempGlobalSST = .0;
	///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
	double	dCRowGlobalSST = .0; 
	double	dCRowGloablDOF = .0;
	///end ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
	///Arvin 06/11/07 OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT
	vector<string> 	vsGlobalParamNames;
	///END OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT
	
	///Sophy 10/17/2008 QA80-12000 SHOULD_UPDATE_MASKED_AND_MISSING_DATA_STATS_ON_RECALCULATE
	SetHasMissingData( false ); //reset status before detecting missing and masked data
	SetHasMaskedData( false );
	///end SHOULD_UPDATE_MASKED_AND_MISSING_DATA_STATS_ON_RECALCULATE
	

	//for( int ii = 0; ii < nNumData; ii++ )
	for( int ii = 0; ii < nNumDataToFit; ii++, nDataFrom++ )		
	{		
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		if(nDataFrom < 0)
			nDataFrom = ii;
		///end SUPPORT_INDEP_FIT_MODE
		
//			printf("\n\n-----Data %d------\n", ii+1); CPY 2/15/07, when trying Easwar OGW, see this should be removed
		/// Iris 9/28/06 need to get input data from m_pFitSession
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		//if( HasZ(trOp) )
		//{
			//m_pFitSession->GetInputData(vX, vY, vZ, ii);
		//}
		//else if(nDeps > 1 || nIndeps > 1)
		//{
			//m_pFitSession->GetInputData(mXs, mYs, ii);
		//}
		//else
		//{
			////----- Iris 11/02/06 GET_WEIGHT_TO_DO_CONFIDENCE_PREDICTION_BANDS
			////m_pFitSession->GetInputData(vX, vY, NULL, ii);
			//m_pFitSession->GetInputData(vX, vY, NULL, ii, &vWeights);
			////-----
		//}
		bool bGetInput = false;
		if( HasZ(trOp) )
			bGetInput = GetFitSession()->GetInputData(vX, vY, vZ, ii);
		else if(nDeps > 1 || nIndeps > 1)
			bGetInput = GetFitSession()->GetInputData(mXs, mYs, ii);
		else
			bGetInput = GetFitSession()->GetInputData(vX, vY, NULL, ii, &vWeights);
		if(!bGetInput)
			return error_report("failed to get input data in doonefit");
		///end CLEAN_UP_ERR_HANDLING
		
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		//GetEscapedMainDataString(trOp, strDataLabel, ii + 1);
		GetEscapedMainDataString(trOp, strDataLabel, nDataFrom + 1);
		///end SUPPORT_INDEP_FIT_MODE
		
		///Arvin 02/21/08 QA70-10929 NLEND_NEED_OUTPUT_REPORT_TABLES_TO_NOTES_WINDOW
		//As Marko said, Translating Peak1(?$OP:F=1) is now not supported. 
		//So, we have to use translated string, like Peak1(B) instead.
		
		//------ Folger 11/28/08 v8.0980 USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
		/// General speaking, this code is for Statistics table column labels to keep quoted when
		/// column long name is used, use converted label as old code will make double quotes missing.
		string		strDataLabelUnconverted = strDataLabel;
		//------ End USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
		
		if(isReplicaFit(trOp))
			ConvertEscapedString(strDataLabel);
		///end NLEND_NEED_OUTPUT_REPORT_TABLES_TO_NOTES_WINDOW
		
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		/*
		///Iris 9/21/06 MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH, not vX, vY and dwPlotUID for multiple indep func fitting, so just save empty data here
		/// ML 9/29/2006 GETTING_PLOUID_FROM_SESSION_OBJ
		//dr.GetNLFitData(dwRules, ii, &dwPlotUID, 0, NULL, 0, NULL, NULL);
		///Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
		//dwPlotUID = m_pFitSession->GetPlotUID(ii);
		int nDataMode;
		if(trOp.GUI.InputData.GetAttribute( STR_USE_ATTRIB, nDataMode))
			dwPlotUID = nDataMode == DATA_MODE_CONCATENATE? m_pFitSession->GetSrcPlotUIDConcatenate() : m_pFitSession->GetPlotUID(ii);
		else
			dwPlotUID = m_pFitSession->GetPlotUID(ii);
		///end FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
		/// end GETTING_PLOUID_FROM_SESSION_OBJ
		
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		//SetSourceDataPlot(trOp, vY, vX, ii, nNumData, dwPlotUID); 
		SetSourceDataPlot(trOp, vY, vX, nDataFrom, nNumData, dwPlotUID); 
		///end SUPPORT_INDEP_FIT_MODE
		*/
		int 	nDataMode = DATA_MODE_INDEP_CONSOLID;
		bool	bRet = trOp.GUI.InputData.GetAttribute( STR_USE_ATTRIB, nDataMode);		
		ASSERT(bRet);
		SetSourceDataPlot(trOp, vY, vX, nDataFrom, nNumData, getPlotUID(trOp, ii));
		/// end FITNL_USING_NEW_NLFSESSION
		
		///end MULTI_INDEP_PLOTS_NEED_OUT_MATRIX_GRAPH
			
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		//int		nSetIndex = bShared? -1 : ii;
		//int		nResultIndex = bShared? 0 : ii;
		int		nSetIndex = ii;
		int		nResultIndex = nDataFrom;
		///end SUPPORT_INDEP_FIT_MODE
		
		///------ Folger 02/24/09 ALWAYS_GET_FIT_RESULT_STATS_REGARDLESS_OF_OUTPUT_OF_STATS_TABLE
		bool	bStatsPreDataset = bGlobalFit? true : false;
		bool	bGetFitResultsStatsOK = GetFitSession()->GetFitResultsStats(&sRegStats, &sFitInfo, bStatsPreDataset, nSetIndex);
		if ( !bGetFitResultsStatsOK )
			error_report("failed to get fit result stats");	///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		///------ End ALWAYS_GET_FIT_RESULT_STATS_REGARDLESS_OF_OUTPUT_OF_STATS_TABLE
		
		/// Iris 4/23/2008 NOT_GENERAGE_TABLE_IF_NOT_REPORT_TO_IMPROVE_NLSF_SPEED
		bool	bReportStats = !tree_GUI_are_all_uncheck(trOp.GUI.Quantities.Statistics);
		if(bReportStats)
		///end NOT_GENERAGE_TABLE_IF_NOT_REPORT_TO_IMPROVE_NLSF_SPEED
		{
			///------ Folger 02/24/09 ALWAYS_GET_FIT_RESULT_STATS_REGARDLESS_OF_OUTPUT_OF_STATS_TABLE
			//bool	bStatsPreDataset = bGlobalFit? true : false;
			///// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
			////if( m_pFitSession->GetFitResultsStats(&sRegStats, &sFitInfo, nSetIndex) )				
			//if( GetFitSession()->GetFitResultsStats(&sRegStats, &sFitInfo, bStatsPreDataset, nSetIndex) )
			/////end SUPPORT_INDEP_FIT_MODE
			//{
				////----- Iris 10/23/06 ONLY_UPDATE_DATA_LABEL_FOR_STATS_REPORT
				////only report one stats result when parameters shared, for this case, the data label should be empty
				////AddRegStatsToReportTree(trOp, nResultIndex, strDataLabel, nNumData, vstrFactors, sRegStats); 
				///// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
				////AddRegStatsToReportTree(trOp, nResultIndex, strDataLabel, nNumData, vstrFactors, sRegStats);
				////------ Folger 11/28/08 v8.0980 USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
				////AddRegStatsToReportTree(trOp, nResultIndex, strDataLabel, nNumData, vstrFactors, sRegStats, &nSetIndex);
				//AddRegStatsToReportTree(trOp, nResultIndex, strDataLabelUnconverted, nNumData, vstrFactors, sRegStats, &nSetIndex);
				////------
				///// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
				////-----
			//}
			//else error_report("failed to get fit result stats");	///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
			if ( bGetFitResultsStatsOK )
				AddRegStatsToReportTree(trOp, nResultIndex, strDataLabelUnconverted, nNumData, vstrFactors, sRegStats, &nSetIndex);
			///------ End ALWAYS_GET_FIT_RESULT_STATS_REGARDLESS_OF_OUTPUT_OF_STATS_TABLE
	
			///Cheney 2007-11-2 QA70-10626 ADD_REPLICA_INFO_IN_REPORT_TABLE
			///------ Folger 02/26/09 QA80-10626 FAILS_TO_SHOW_REPLICA_INFO_IN_STATS_TABLE_WHEN_REPLICA_NUMBER_IS_ZERO
			//if(isReplicaFit(trOp))
			if ( isReplicaFitSupported(trOp) )
			///------ End FAILS_TO_SHOW_REPLICA_INFO_IN_STATS_TABLE_WHEN_REPLICA_NUMBER_IS_ZERO
				//------ Folger 11/28/08 v8.0980 USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
				//if( !addReplicaInfoOnStatsTable(trOp, nResultIndex, strDataLabel, nNumData) )
				if( !addReplicaInfoOnStatsTable(trOp, nResultIndex, strDataLabelUnconverted, nNumData) )
				//------
					error_report("failed to add replica info");
			///end ADD_REPLICA_INFO_IN_REPORT_TABLE
			
			/// Iris 03/02/2007 v8.0573 GLOBAL_FIT_NEED_OUTPUT_STATS_INC_FOR_EACH_DATA_AND_FOR_ALL_DATA
			///Arvin 06/12/07 USE_WRONG_REG_STATS_RESULT_FOR_GLOBAL_FIT
			//if( ii == nNumDataToFit -1 && DATA_MODE_GLOBAL == nFitMode )
			//{
			//	if( m_pFitSession->GetFitResultsStats(&sRegStatsGlobal, &sFitInfo, false) )
			/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			// Should NOT call if NOT global fit
			//bool bGlobalFitResults = m_pFitSession->GetFitResultsStats(&sRegStatsGlobal, &sFitInfo, false);
			/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
			if( bGlobalFit )
			{
				/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
				bool bGlobalFitResults = GetFitSession()->GetFitResultsStats(&sRegStatsGlobal, &sFitInfo, false);
				/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
				//sRegStats = sRegStatsGlobal;
				if( ii == nNumDataToFit -1 && bGlobalFitResults)
				{
			///end USE_WRONG_REG_STATS_RESULT_FOR_GLOBAL_FIT
					nResultIndex++;
					string	strLabel = "Global";
					AddRegStatsToReportTree(trOp, nResultIndex, strLabel, nNumData, vstrFactors, sRegStatsGlobal);
				}
			}	
			///end GLOBAL_FIT_NEED_OUTPUT_STATS_INC_FOR_EACH_DATA_AND_FOR_ALL_DATA
		}		
		
		/// Iris 12/30/2006 v8.0534 CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE
		//int nNumParaInFunc = m_pFitSession->GetFitResultsParams(arrstFitParameter, ii);
		//vector<string> vsDPnames;
		//vector<double> vdDPvals;
		//m_pFitSession->GetDerivedParameters(vsDPnames, vdDPvals, ii);
		//int 	nNumDerivedParams = m_pFitSession->GetDerivedParameters(ii, arrstDerivedParams);	//------ Folger 04/17/08 QA80-11434 TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
		/// Iris 02/06/2007 v8.0556 OUTPUT_T_P_VALUES_IN_PARAMS_TABLE
		//int 	nNumParaInFunc = m_pFitSession->GetFitResultsParams(arrstFitParameter, ii, true);
		//int 	nNumParaInFunc = m_pFitSession->GetFitResultsParams(arrstFitParameter, &sRegStats, ii, true);	//------ Folger 04/17/08 QA80-11434 TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
		///end OUTPUT_T_P_VALUES_IN_PARAMS_TABLE
		///end CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE
		/// Arvin 03/30/07 GET_ANOVA_RESULT_WITH_DIFF_WEIGHT_METHOD
		//m_pFitSession->GetANOVAResult(stANOVA, sRegStats, ii);  ///Iris 5/22/06 ADD_ANOVA_TABLE_FOR_NLSF
		///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		//m_pFitSession->GetANOVAResult(stANOVA, ii);
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		//m_pFitSession->GetANOVAResult(stANOVA, stCorrTotal, ii);
		if( !GetFitSession()->GetANOVAResult(stANOVA, stCorrTotal, ii) )
			error_report("failed to get Anova result");
		///end CLEAN_UP_ERR_HANDLING
		dCRowGloablDOF += stCorrTotal.DOF;
		dCRowGlobalSST += stCorrTotal.SSq;
		///END ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		///end GET_ANOVA_RESULT_WITH_DIFF_WEIGHT_METHOD
		dTempGlobalSST += stANOVA.AnovaTable[ANOVA_TOTAL].SSq;	/// Max
		
		/// Iris 12/30/2006 v8.0534 CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE			
		//AddOneDataStatsResultsToReportTree(trOp, ii, strDataLabel, nNumData, vstrFactors, NULL, NULL, NULL, arrstFitParameter, stANOVA, NULL, NULL, NULL, vsDPnames, vdDPvals);				
		vector<string> 	vsParamNames, vsParamNamesPostfix;
		vector<string> vsParamUnits;							///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
		vector<bool>	vbIsDerived;
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		//int				nParams = GetParameters(trOp, ii, vsParamNames, false, true, vbIsDerived);						
		//GetParameters(trOp, ii, vsParamNamesPostfix, true, true, vbIsDerived);						
		int				nParams = GetParameters(trOp, nDataFrom, vsParamNames, false, true, vbIsDerived);
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		//GetParameters(trOp, nDataFrom, vsParamNamesPostfix, true, true, vbIsDerived);
		if(nParams < 1)
			return false;
		if(GetParameters(trOp, nDataFrom, vsParamNamesPostfix, true, true, vbIsDerived) < 1)
			return false;
		///end CLEAN_UP_ERR_HANDLING
		///end SUPPORT_INDEP_FIT_MODE
		ASSERT(vsParamNames.GetSize() == vsParamNamesPostfix.GetSize());	///Jasmine 10/12/07 QA70-10522 GET_REPLICA_PARAM_IF_NO_DERIVED_PARAM
		
		///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
		if(GetParamUnits(trOp, nDataFrom, vsParamUnits, true) < 1)
			return false;
		///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
		
		//------ Folger 04/17/08 QA80-11434 TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
		//allocate memory for both parameters and derived parameters for fixed size
		vector<string>	vsDerivedParamNames;
		GetFitSession()->GetDerivedParameters(ii, &vsDerivedParamNames);
		void *pvParams, *pvDerivedParams;
		///------ Folger 05/27/09 QA80-13669 FIT_COMPARE_MODELS_CAUSE_ORIGIN_CRASH_UNDER_SPECIFIC_CIRCUMSTANCES
		//PointerManager	pmParams(&pvParams, sizeof(FitParameter) * vsParamNames.GetSize());
		//PointerManager	pmDerivedParams(&pvDerivedParams, sizeof(FitDerivedParameter) * vsDerivedParamNames.GetSize());
		const	int		nNiceSafeExtraFitParameters = 5;
		PointerManager	pmParams(&pvParams, sizeof(FitParameter) * (vsParamNames.GetSize() + nNiceSafeExtraFitParameters));
		PointerManager	pmDerivedParams(&pvDerivedParams, sizeof(FitDerivedParameter) * (vsDerivedParamNames.GetSize() + nNiceSafeExtraFitParameters));
		///------ End FIT_COMPARE_MODELS_CAUSE_ORIGIN_CRASH_UNDER_SPECIFIC_CIRCUMSTANCES
		arrstFitParameter = (FitParameter*)pvParams;
		arrstDerivedParams = (FitDerivedParameter*)pvDerivedParams;
		
		int 	nNumParaInFunc = GetFitSession()->GetFitResultsParams(arrstFitParameter, &sRegStats, ii, true);
		
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		//int 	nNumDerivedParams = m_pFitSession->GetDerivedParameters(ii, arrstDerivedParams);
		int 	nNumDerivedParams = GetFitSession()->GetDerivedParameters(ii, arrstDerivedParams, vsDerivedParamNames.GetSize());
		/// end FITNL_USING_NEW_NLFSESSION
		//------ End TEMPORARY_FIX_ORIGIN_CRASH_AFTER_CLICK_FINISH_IN_PA
		
		///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
		FITPARAMSINFO stParamInfo;
		stParamInfo.pvsParamNames = &vsParamNames;
		stParamInfo.pvsParamNamesPostfix = &vsParamNamesPostfix;
		stParamInfo.pvsParamUnits = &vsParamUnits;
		///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
		
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		//AddOneDataStatsResultsToReportTree(trOp, ii, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, NULL, NULL, NULL, arrstDerivedParams, nNumDerivedParams, vbIsDerived);
		//bool	bReportANOVA = DATA_MODE_GLOBAL == nFitMode? false : true;
		/// Iris 10/11/2009 FIX_NLFIT_STILL_REPORT_EMPTY_ANOVA_TABLE_IF_NOT_CHECKED_ON_GUI
		//bool 	bReportInidividualANOVA = !bGlobalFit; // will report global ANOVA table for Global Fit
		TreeNode	trGUIANOVA = trOp.GUI.Quantities.ANOVAtable;
		bool 	bReportInidividualANOVA = !bGlobalFit && trGUIANOVA && trGUIANOVA.Show && trGUIANOVA.nVal; // will report global ANOVA table for Global Fit
		///end FIX_NLFIT_STILL_REPORT_EMPTY_ANOVA_TABLE_IF_NOT_CHECKED_ON_GUI
		bool 	bReportInidividualCovAndCorrMatrix = !bGlobalFit;		
		bReportStats = false; //already report stats table above since want to do diff report on Global Fit or not
		///Arvin 05/08/07 QA70-9498 SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
		//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, NULL, NULL, arrstDerivedParams, nNumDerivedParams, vbIsDerived, false, bReportANOVA);
		///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, mVarCovar, mVarCorr, arrstDerivedParams, nNumDerivedParams, vbIsDerived, false, bReportANOVA);
		///Arvin 06/12/07 OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT
		//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, mVarCovar, mVarCorr, arrstDerivedParams, nNumDerivedParams, vbIsDerived, false, bReportANOVA, stCorrTotal);
		
		///Arvin 08/03/07 WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
		int 	nMultiplicity = GetFitSession()->GetNumberMultiplicity();
		int		nDupUnit = GetFitSession()->GetReplicaUnitFromFDF();
		///end WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
		
		///Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said
		vector<bool> vbShared;
		GetFitSession()->GetSharedVector(vbShared);
		vector<bool> vbTemp(vbIsDerived.GetSize() - vbShared.GetSize());
		if ( vbTemp.GetSize() > 0 )		/// if vbTemp.GetSize() == 0, after assignment, vbTemp's size becomes 1 ...
			vbTemp = false;
		vbShared.Append(vbTemp);
		///end ADD_STAR_MARK_FOR_SHARED_PARAMS
		if(bReportInidividualCovAndCorrMatrix)
		{
			matrix mVarCovar, mVarCorr;
			getCovAndCorrMatrix(trOp, mVarCovar, mVarCorr);
			///Arvin 08/03/07 WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, mVarCovar, mVarCorr, arrstDerivedParams, nNumDerivedParams, vbIsDerived, false, bReportANOVA, stCorrTotal);
			///Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, mVarCovar, mVarCorr, arrstDerivedParams, nNumDerivedParams, vbIsDerived, false, bReportANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit);
			//------ Folger 12/01/08 v8.0981 MORE_ON_USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, mVarCovar, mVarCorr, arrstDerivedParams, nNumDerivedParams, vbIsDerived, bReportStats, bReportInidividualANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit, vbShared);
			///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, mVarCovar, mVarCorr, arrstDerivedParams, nNumDerivedParams, vbIsDerived, bReportStats, bReportInidividualANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit, vbShared, &strDataLabelUnconverted);
			AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, stParamInfo, stANOVA, sRegStats, mVarCovar, mVarCorr, arrstDerivedParams, nNumDerivedParams, vbIsDerived, bReportStats, bReportInidividualANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit, vbShared, &strDataLabelUnconverted);
			///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
			//------
			///end ADD_STAR_MARK_FOR_SHARED_PARAMS
			///end WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
		}
		else
		{
			///Arvin 08/03/07 WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, NULL, NULL, arrstDerivedParams, nNumDerivedParams, vbIsDerived, false, bReportANOVA, stCorrTotal);
			///Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, NULL, NULL, arrstDerivedParams, nNumDerivedParams, vbIsDerived, false, bReportANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit);
			//------ Folger 12/01/08 v8.0981 MORE_ON_USE_UNCONVERTED_DATA_LABEL_FOR_REGSTATS_TABLE_COLUMNS
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, NULL, NULL, arrstDerivedParams, nNumDerivedParams, vbIsDerived, bReportStats, bReportInidividualANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit, vbShared);
			///Kyle 08/10/2009 QA80-14077 ADD_PARAMETER_UNIT_TO_FITTING_REPORT
			//AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, vsParamNames, vsParamNamesPostfix, stANOVA, sRegStats, NULL, NULL, arrstDerivedParams, nNumDerivedParams, vbIsDerived, bReportStats, bReportInidividualANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit, vbShared, &strDataLabelUnconverted);
			AddOneDataStatsResultsToReportTree(trOp, nDataFrom, strDataLabel, nNumData, vstrFactors, vY, vX, mXs, arrstFitParameter, stParamInfo, stANOVA, sRegStats, NULL, NULL, arrstDerivedParams, nNumDerivedParams, vbIsDerived, bReportStats, bReportInidividualANOVA, stCorrTotal, nMultiplicity, nNumParaInFunc, nDupUnit, vbShared, &strDataLabelUnconverted);
			///End ADD_PARAMETER_UNIT_TO_FITTING_REPORT
			//------
			///end ADD_STAR_MARK_FOR_SHARED_PARAMS
			///end WRONG_PARAMETER_SUMARY_TABLE_WHILE_FIT_REPLICA
			vector<string> vsParamTemp;
			vsParamTemp = vsParamNames;
			RemoveUnusedParams(vsParamTemp, vbIsDerived);
			if(ii > 0)
			{
				vector<bool> vbIsShared;
				GetFitSession()->GetSharedVector(vbIsShared);
				RemoveUnusedParams(vsParamTemp, vbIsShared);
			}
			vsGlobalParamNames.Append(vsParamTemp);
		}
		///end OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT
		///END ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		///end	SCALE_PARAMETER_ERRORS_WITH_CHI_SQR
		///end SUPPORT_INDEP_FIT_MODE
		///Cheney 2007-4-4 SHOW_LB_UB_IN_REPORT_SHEET
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		//addOneDataLBUBToReportTree(trOp, vstrFactors, vsParamNames, vsParamNamesPostfix, bSepFit || nDataFrom < 0? 0 : nDataFrom);
		//------ Folger 08/18/08 QA80-12036 FIX_BOUNDS_MISSING_IN_REPORT_SHEET_FOR_REPLICA_FIT
		//if(!addOneDataLBUBToParametersTable(trOp, vstrFactors, vsParamNames, vsParamNamesPostfix, bSepFit || nDataFrom < 0? 0 : nDataFrom))
		if(!addOneDataLBUBToParametersTable(trOp, vstrFactors, vsParamNames, vsParamNamesPostfix, bSepFit || nDataFrom < 0? 0 : nDataFrom, nMultiplicity))
		//------
			error_report("failed to add LB and UB to report tree in doonefit");
		///end SHOW_LB_UB_IN_REPORT_SHEET
		///end CORRECT_DERIVED_PARAMS_ORDER_FOR_REPLICA_CASE
		
		appendFitFootnoteToParamTable(trOp, nDataFrom, nNumData);
		///Cheney 2007-4-4 ADD_FOOTNOTE_FOR_FIT_STATUS_AS_LARRY_SUGGEST
		TreeNode trFitStatus = trOp.GUI.Quantities.Statistics.FitStatus;
		if(trFitStatus && trFitStatus.nVal)
			appendFitFootnoteToStatsTable(trOp, nDataFrom, nNumData);
		///end ADD_FOOTNOTE_FOR_FIT_STATUS_AS_LARRY_SUGGEST

		///Iris 4/18/05 FIX_NLSF_CONF_PREDI_BAND_NOT_WORK
		RegCalcInternal	sInternal;
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		/*
		if( STATS_NO_ERROR == stats_calc_internal(vX, vY, sInternal, vWeights))
			ConstructCurvesAndGraphs(trOp, ii, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, &sInternal, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs);
		else
			ConstructCurvesAndGraphs(trOp, ii, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, NULL, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs);
		*/
		/// ML 6/1/2007 LEGEND_INCORRECT_FIX
		//if( STATS_NO_ERROR == stats_calc_internal(vX, vY, sInternal, vWeights))
		//	ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, &sInternal, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs);
		//else
		//	ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, NULL, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs);
		//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		/*
		string			strDataLabelCurves = _L("Fit Curve");
		strDataLabelCurves += " ";
		strDataLabelCurves += nDataFrom + 1;		
		*/
		string strDataLabelCurves = GetResultCurveMainTableLabel(trOp, nNumData, strDataLabel);
		//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		
		///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
		//if( STATS_NO_ERROR == stats_calc_internal(vX, vY, sInternal, vWeights))
			//ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabelCurves, vX, vY, mXs, arrstFitParameter, &sRegStats, &sInternal, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs);
		//else
			//ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabelCurves, vX, vY, mXs, arrstFitParameter, &sRegStats, NULL, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs);
		bool bConstructCurvesAndGraphs = false;		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		///Arvin 11/06/07 USE_WRONG_REG_STATS_RESULT_TO_CAL_CONF_PRED_BANDS_FOR_GLOBAL_FIT
		if( bGlobalFit )
			sRegStats = sRegStatsGlobal;
		///END USE_WRONG_REG_STATS_RESULT_TO_CAL_CONF_PRED_BANDS_FOR_GLOBAL_FIT
		if( STATS_NO_ERROR == stats_calc_internal(vX, vY, sInternal, vWeights))
		{
			/// Iris 06/28/2007 SEPARATE_PFM_OP_CLASS, should get number of peaks here, number of Multiplicity != number of peaks in PFM, nMultiplicity always be 1 in PFM.
			//ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, &sInternal, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs, NULL, NULL, strDataLabelCurves);
			///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
			//ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, &sInternal, dwPlotUID, m_pFitSession->GetNumPeaks(), mYs, NULL, NULL, strDataLabelCurves);
			bConstructCurvesAndGraphs = ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, &sInternal, dwPlotUID, GetFitSession()->GetNumPeaks(), mYs, NULL, NULL, strDataLabelCurves);
			///end CLEAN_UP_ERR_HANDLING
			///end SEPARATE_PFM_OP_CLASS
		}
		else
		{
			/// Iris 06/28/2007 SEPARATE_PFM_OP_CLASS, should get number of peaks here, number of Multiplicity != number of peaks in PFM, nMultiplicity always be 1 in PFM.
			//ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, NULL, dwPlotUID, m_pFitSession->GetNumberMultiplicity(), mYs, NULL, NULL, strDataLabelCurves);
			///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
			//ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, NULL, dwPlotUID, m_pFitSession->GetNumPeaks(), mYs, NULL, NULL, strDataLabelCurves);
			bConstructCurvesAndGraphs = ConstructCurvesAndGraphs(trOp, nDataFrom, nNumData, strDataLabel, vX, vY, mXs, arrstFitParameter, &sRegStats, NULL, dwPlotUID, GetFitSession()->GetNumPeaks(), mYs, NULL, NULL, strDataLabelCurves);
			///end CLEAN_UP_ERR_HANDLING
			///end SEPARATE_PFM_OP_CLASS
		}
		///end CENTRALIZE_FITTING_RESULT_LABELS
		/// end LEGEND_INCORRECT_FIX
		///end SUPPORT_INDEP_FIT_MODE
		/// end FIX_NLSF_CONF_PREDI_BAND_NOT_WORK
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		if(!bConstructCurvesAndGraphs)
			error_report("failed to construct curves and graphs in do oen fit");
		///end CLEAN_UP_ERR_HANDLING
		
		/// ML 9/1/2006 NLFIT_MULTIDEPS_INDEPS_INPUT_DATA_TBL
		//UpdateDataSourceInReportingHeader(trOp, vstrFactors, wksData, ii);
		
		/// Iris 4/25/2008 NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
		//if ( bIsXYZData )
		if( !IsReportComplexInputDataTable(trOp) )
		///end NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
		{
			UpdateDataSourceInReportingHeader(trOp, vstrFactors, wksData, ii);
			///Cheney 2007-4-2 ADD_HINTS_IN_FOOTNOTE_WHEN_EXISTS_MISSING_OR_MASKED_DATA
			//UpdateMaskedOrMissingDataTables(trOp, dr, vstrFactors, ii, nNumData, numSubRanges, dwRules, strDataLabel, false);
			//UpdateMaskedOrMissingDataTables(trOp, dr, vstrFactors, ii, nNumData, numSubRanges, dwRules, strDataLabel, true);
			bool bHas = false;
			UpdateMaskedOrMissingDataTables(trOp, dr, vstrFactors, ii, nNumData, numSubRanges, dwRules, strDataLabel, false, bHas);
			if(bHas)
				///Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
				//m_bHasMasked = true;
				SetHasMaskedData(true);
				///end ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
			UpdateMaskedOrMissingDataTables(trOp, dr, vstrFactors, ii, nNumData, numSubRanges, dwRules, strDataLabel, true, bHas);
			if(bHas)
				///Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
				//m_bHasMissing = true;
				SetHasMissingData(true);
				///end ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
			///end ADD_HINTS_IN_FOOTNOTE_WHEN_EXISTS_MISSING_OR_MASKED_DATA
		}
		else
		{
			///Arvin 01/23/06 INPUT_MASKED_AND_MISSING_DATA_TABLE_INCOMPLETE_CONCATENATE
			/*
			updateInputDataTable(trOp.Calculation.Input, ii, nNumData, dwRules);
			updateMaskedOrMissingDataTables(trOp, dr, ii, vstrDepVarNames, vstrIndepVarNames, nNumData, 0, dwRules, strDataLabel, false);
			updateMaskedOrMissingDataTables(trOp, dr, ii, vstrDepVarNames, vstrIndepVarNames, nNumData, 0, dwRules, strDataLabel, true);
			*/
			///Cheney 2007-4-13 FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
			//int nDataMode = trOp.GUI.InputData.Use;
			///end FIX_BUG_OF_CUSTOM_TABLE_DISAPPEAR_WHEN_CONCATENATE
			if(nDataMode == DATA_MODE_CONCATENATE)
			{
				for(int jj = 0; jj < numSubRanges; jj++)
				{
					/// Iris 4/28/2008 NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
					//updateInputDataTable(trOp.Calculation.Input, jj, numSubRanges, dwRules);
					updateInputDataTable(trOp.Calculation.Input, jj, numSubRanges, dwRules, bIsXYZData);
					///end NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
					string strLabel;
					GetEscapedMainDataString(trOp, strLabel, jj + 1);
					updateMaskedOrMissingDataTables(trOp, dr, jj, vstrDepVarNames, vstrIndepVarNames, numSubRanges, 0, dwRules, strLabel, false);
					updateMaskedOrMissingDataTables(trOp, dr, jj, vstrDepVarNames, vstrIndepVarNames, numSubRanges, 0, dwRules, strLabel, true);
				}
			}
			else
			{
				/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
				//updateInputDataTable(trOp.Calculation.Input, ii, nNumData, dwRules);
				/// Iris 4/28/2008 NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
				//updateInputDataTable(trOp.Calculation.Input, nDataFrom, nNumData, dwRules);
				updateInputDataTable(trOp.Calculation.Input, nDataFrom, nNumData, dwRules, bIsXYZData);
				///end NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
				///end SUPPORT_INDEP_FIT_MODE					
				updateMaskedOrMissingDataTables(trOp, dr, ii, vstrDepVarNames, vstrIndepVarNames, nNumData, 0, dwRules, strDataLabel, false);
				updateMaskedOrMissingDataTables(trOp, dr, ii, vstrDepVarNames, vstrIndepVarNames, nNumData, 0, dwRules, strDataLabel, true);		
			}
			///end INPUT_MASKED_AND_MISSING_DATA_TABLE_INCOMPLETE_CONCATENATE
			/// Joesph/Iris 9/26/06 QA70-7120 MOVE_CUSTOM_TABLE_TO_SEPARATE_SHEET
			//surface fitting and mr not support FindXY temp as methmetic not ready, can be later.
			//addAdditionalCustomTables(trOp, ii, nNumData); ///Arvin 01/09/06 FIND_Z_FROM_XY
			///end MOVE_CUSTOM_TABLE_TO_SEPARATE_SHEET

		}
		
		/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
		/*
		///Arvin 01/09/06 FIND_Z_FROM_XY
		addAdditionalCustomTables(trOp, ii, nNumData);
		///end FIND_Z_FROM_XY
		*/
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		//addAdditionalCustomTables(trOp, nDataFrom, nNumData);
		if( !addAdditionalCustomTables(trOp, nDataFrom, nNumData))
			error_report("failed to add additional custom table");
		///end CLEAN_UP_ERR_HANDLING
		///end SUPPORT_INDEP_FIT_MODE
		
		///Arvin 10/23/06 FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED
		//--- Arvin 10/27/06 GET_RUNTIME_ERROR_IN_SURFACE_FIT
		//if(nDeps > 1 || nIndeps > 1)
		if( !HasZ(trOp) && (nDeps > 1 || nIndeps > 1) )
		//---
		{
			/// ML 6/1/2007 LEGEND_INCORRECT_FIX
			///// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
			////if(!CalcAddStatsHistPlotData(trOp, ii, arrstFitParameter, mYs, mXs, vstrFactors, vWeights, strDataLabel))
			//if(!CalcAddStatsHistPlotData(trOp, nDataFrom, arrstFitParameter, mYs, mXs, vstrFactors, vWeights, strDataLabel))
			/////end SUPPORT_INDEP_FIT_MODE
			if(!CalcAddStatsHistPlotData(trOp, nDataFrom, arrstFitParameter, mYs, mXs, vstrFactors, vWeights, strDataLabelCurves))
			/// end LEGEND_INCORRECT_FIX
				//--- Arvin 10/27/06 GET_RUNTIME_ERROR_IN_SURFACE_FIT. no need to directly return here
				//return false;
				error_report("CalcAddStatsHistPlotData returns false ");
				//---
		}
		///Arvin 10/30/06 NLFIT_SURFACE_HISTOGRAM_PLOT
		//else
	   	else if(!HasZ(trOp))
	   	///----
	   	{
			/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
			/*
	   		///Arvin 01/17/06 CALC_RESIDUAL_WITH_REPLICA
	   		//if(!CalcAddStatsHistPlotData(trOp, ii, arrstFitParameter, vY, vX, vstrFactors, mXs, vWeights, strDataLabel, dwPlotUID))
	   		if(!CalcAddStatsHistPlotData(trOp, ii, arrstFitParameter, vY, vX, vstrFactors, mXs, vWeights, strDataLabel, dwPlotUID,m_pFitSession->GetNumberMultiplicity()))
	   		///end CALC_RESIDUAL_WITH_REPLICA
	   		*/
			/// ML 6/1/2007 LEGEND_INCORRECT_FIX
	   		//if(!CalcAddStatsHistPlotData(trOp, nDataFrom, arrstFitParameter, vY, vX, vstrFactors, mXs, vWeights, strDataLabel, dwPlotUID,m_pFitSession->GetNumberMultiplicity()))
	   		/// Iris 06/28/2007 SEPARATE_PFM_OP_CLASS, should get number of peaks here, number of Multiplicity != number of peaks in PFM, nMultiplicity always be 1 in PFM.
	   		//if(!CalcAddStatsHistPlotData(trOp, nDataFrom, arrstFitParameter, vY, vX, vstrFactors, mXs, vWeights, strDataLabelCurves, dwPlotUID, m_pFitSession->GetNumberMultiplicity()))
	   		if(!CalcAddStatsHistPlotData(trOp, nDataFrom, arrstFitParameter, vY, vX, vstrFactors, mXs, vWeights, strDataLabelCurves, dwPlotUID, GetFitSession()->GetNumPeaks()))
	   		///end SEPARATE_PFM_OP_CLASS
			/// end LEGEND_INCORRECT_FIX
	   		///end SUPPORT_INDEP_FIT_MODE
	   			error_report("CalcAddStatsHistPlotData returns false ");
	   	}
	   	///Arvin 10/30/06 NLFIT_SURFACE_HISTOGRAM_PLOT
	   	else
	   	{
			/// ML 6/1/2007 LEGEND_INCORRECT_FIX
			///// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
	   		////if(!CalcAddStatsHistPlotData(trOp, ii, vstrFactors, vWeights, strDataLabel))		   		  
	   		//if(!CalcAddStatsHistPlotData(trOp, nDataFrom, vstrFactors, vWeights, strDataLabel))
	   		/////end SUPPORT_INDEP_FIT_MODE
	   		if(!CalcAddStatsHistPlotData(trOp, nDataFrom, vstrFactors, vWeights, strDataLabelCurves))
			/// end LEGEND_INCORRECT_FIX
				error_report("CalcAddStatsHistPlotData failed ");
	   	}
	   	///END NLFIT_SURFACE_HISTOGRAM_PLOT
		///end FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED

	}
	/// end NLFIT_MULTIDEPS_INDEPS_INPUT_DATA_TBL	
	
	if(	DATA_MODE_GLOBAL == trOp.GUI.InputData.Use)
	{
		RegANOVA stANOVAGlobal;
		stANOVAGlobal.AnovaTable[ANOVA_TOTAL].SSq = dTempGlobalSST;
		stANOVAGlobal.AnovaTable[ANOVA_ERR].SSq = sRegStatsGlobal.SSR;
		stANOVAGlobal.AnovaTable[ANOVA_MODEL].SSq = dTempGlobalSST - sRegStatsGlobal.SSR;
		///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		//stANOVAGlobal.AnovaTable[ANOVA_TOTAL].DOF = sRegStatsGlobal.N - 1;
		stANOVAGlobal.AnovaTable[ANOVA_TOTAL].DOF = sRegStatsGlobal.N;
		///end ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		stANOVAGlobal.AnovaTable[ANOVA_ERR].DOF = sRegStatsGlobal.DOF;
		///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		//stANOVAGlobal.AnovaTable[ANOVA_MODEL].DOF = sRegStatsGlobal.N - sRegStatsGlobal.DOF - 1;
		stANOVAGlobal.AnovaTable[ANOVA_MODEL].DOF = sRegStatsGlobal.N - sRegStatsGlobal.DOF;
		///end ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		stANOVAGlobal.AnovaTable[ANOVA_ERR].MeanSq = (0 == sRegStatsGlobal.DOF) ? NANUM : sRegStatsGlobal.SSR / sRegStatsGlobal.DOF;
		///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		//stANOVAGlobal.AnovaTable[ANOVA_MODEL].MeanSq = (0 == sRegStatsGlobal.N - sRegStatsGlobal.DOF - 1) ? NANUM : (dTempGlobalSST - sRegStatsGlobal.SSR) / (sRegStatsGlobal.N - sRegStatsGlobal.DOF - 1);
		stANOVAGlobal.AnovaTable[ANOVA_MODEL].MeanSq = (0 == sRegStatsGlobal.N - sRegStatsGlobal.DOF) ? NANUM : (dTempGlobalSST - sRegStatsGlobal.SSR) / (sRegStatsGlobal.N - sRegStatsGlobal.DOF);
		///end ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		stANOVAGlobal.Fvalue = (0 == stANOVAGlobal.AnovaTable[ANOVA_ERR].MeanSq) ? NANUM : stANOVAGlobal.AnovaTable[ANOVA_MODEL].MeanSq / stANOVAGlobal.AnovaTable[ANOVA_ERR].MeanSq;
		stANOVAGlobal.Pvalue = (NANUM == stANOVAGlobal.Fvalue) ? NANUM : 1 - invf( stANOVAGlobal.Fvalue, stANOVAGlobal.AnovaTable[ANOVA_MODEL].DOF, stANOVAGlobal.AnovaTable[ANOVA_ERR].DOF);
		
		string	strLable = _L("Global");
		///Arvin 05/25/07 ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
		//if(!stats_tree_add_ANOVA_table(trOp, strLable, 0, nNumData, stANOVAGlobal, vstrFactors))
		RegANOVARow 	stCorrTotalGlobal;
		stCorrTotalGlobal.SSq = dCRowGlobalSST;
		stCorrTotalGlobal.DOF = dCRowGloablDOF;
		if(!stats_tree_add_ANOVA_table(trOp, strLable, 0, nNumData, stANOVAGlobal, vstrFactors, stCorrTotalGlobal))
		///end ADD_CORRECTED_TOTAL_ROW_FOR_ANOVA_TABLE_FOR_FITNL
			return error_report("error adding ANOVA table");
		
		///Arvin 06/12/07 OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT
		TreeNode		trCal = trOp.Calculation;
		matrix mVarCovar, mVarCorr;
		getCovAndCorrMatrix(trOp, mVarCovar, mVarCorr);
		if(mVarCovar.GetNumRows() > 0 && mVarCovar.GetNumCols() > 0)
		{
			if(!AddCovOrCorrMatrixToReportTree(trOp, strLable, 0, nNumData, IDST_REG_COV_TABLE, mVarCovar, vsGlobalParamNames))
				error_report("error adding Covariance table");
		}
		else
			trCal.RemoveChild(IDST_REG_COV_TABLE);
	
		if(mVarCorr.GetNumRows() > 0 && mVarCorr.GetNumCols() > 0)
		{
			if(!AddCovOrCorrMatrixToReportTree(trOp, strLable, 0, nNumData, IDST_REG_CORR_TABLE, mVarCorr, vsGlobalParamNames))
				error_report("error adding Correlation table");
		}
		else
			trCal.RemoveChild(IDST_REG_CORR_TABLE);	
		///end OUTPUT_COV_AND_COR_MATRIX_FOR_GLOBAL_FIT

	}
	
	
	return TRUE;
}

//Cheney 2007-4-2 IF_SHARE_PARAMETERS_ADD_HINTS_IN_FOOTNOTE
bool	FitNL::addHintOnFootnoteForShareParams(TreeNode& trFootNote)
{
	///Arvin 01/03/08 ADD_STAR_MARK_FOR_SHARED_PARAMS as cp said
	//vector<bool> vbParamShare;
	//if(!m_pFitSession->GetParamsSettingIntVector(vbParamShare, PARMAS_SETTING_SHARE))
		//return false;
	//
	//vector<string> vsParamNames;
	//if(!m_pFitSession->GetParamsSettingStringVector(vsParamNames, PARMAS_SETTING_NAMES))
		//return false;
	//
	//int nNumParaInFunc = m_pFitSession->GetNumParameter();
	//string strHint = _L("\r\nShared Parameters:") + " ";
	//bool bExistShareParam = false;
	//for(int ii = 0; ii < nNumParaInFunc; ii++)
	//{
		//if(vbParamShare[ii])
		//{
			//strHint += ii == nNumParaInFunc - 1? vsParamNames[ii] : vsParamNames[ii] + "," + " ";
			//bExistShareParam = true;
		//}
	//}
	//if(bExistShareParam)
	//	trFootNote.strVal += strHint;	
	//if(m_pFitSession->IsSharedParameters())
	if ( GetFitSession()->HasSharedParameters() ) /// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	///------ Folger 03/03/09 PARAMETER_STATS_INFO_MISSING_IN_FOOTNOTE_WHEN_SHARING
		//trFootNote.strVal = "*: " + _L("Shared Parameter");
	{
		string	strFootNote = "*: " + _L("Shared Parameter");
		trFootNote.strVal += trFootNote.strVal.IsEmpty()? strFootNote : "\r\n" + strFootNote;
	}
	///------ End PARAMETER_STATS_INFO_MISSING_IN_FOOTNOTE_WHEN_SHARING
	///end ADD_STAR_MARK_FOR_SHARED_PARAMS
	return true;
}
///end IF_SHARE_PARAMETERS_ADD_HINTS_IN_FOOTNOTE

/// Iris 06/15/2007 v8.0642 FIX_NOT_SET_FIT_SETTINGS_FROM_GUI_TO_NLFIT_WHEN_SEL_MENU_THEME
/// virtual		///------ Folger 09/25/09 LINEAR_CONSTRAINTS_NOT_WORK_WHEN_RUN_PA_IN_SCRIPT_MODE
bool	FitNL::setNLFitSettings(TreeNode& trOp)
{
	if(m_pFitSession)
	{
		TreeNode trLinearConstraints = trOp.GUI.Parameters.LinearConstraints;
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		//m_pFitSession->SetLinearConstraints(trOp.GUI.Codes.Constraints, trLinearConstraints.nVal);
		GetFitSession()->SetEnableLinearConstraints(trOp.GUI.Codes.Constraints, trLinearConstraints.nVal);		
		/// end FITNL_USING_NEW_NLFSESSION
		
		GetFitSession()->SetTolerance(trOp.GUI.Fit.Iterations.Tolerance.dVal);
		GetFitSession()->SetDerivsSettings(trOp.GUI.Fit.DerivativeDelta);
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		//m_pFitSession->IsScaleParamError(trOp.GUI.Fit);
		//m_pFitSession->IsGetParamsConf(trOp.GUI.Quantities.Parameters, trOp.GUI.Quantities.SummaryTable, trOp.GUI.Fit.CIMethod);	
		ASSERT(trOp.GUI.Fit);
		GetFitSession()->SetScaleParamError(trOp.GUI.Fit.ScaleError.nVal);
		GetFitSession()->SetIsGetParamsConf(trOp.GUI.Quantities.Parameters, trOp.GUI.Quantities.SummaryTable, trOp.GUI.Fit.CIMethod);
		/// end FITNL_USING_NEW_NLFSESSION
		return true;
	}
	return false;
}
///end FIX_NOT_SET_FIT_SETTINGS_FROM_GUI_TO_NLFIT_WHEN_SEL_MENU_THEME

///Cheney 2007-11-6 QA70-10659 ADD_LCL_UCL_FOR_DERIVED_PARAMS
bool	FitNL::addDerivedParamsInfoOnFootnote(TreeNode trFootNote)
{
	/// Iris 4/15/2009 FIX_NO_DERIVED_PARAM_INFO_IN_PARAM_TABLE_FOOTNOTE_IN_PA
	//if(!trFootNote || !m_trFDF)
	//	return false;
	
	//TreeNode trDerivedParams = m_trFDF.DerivedParameters;
	if( !trFootNote )
		return false;
	
	int nFuncIndex = m_pFitSession->GetBaselineFitMode()? 1 : 0;
	ASSERT( nFuncIndex < m_pFitSession->GetNumberFitFunctions() );
	TreeNode trFDF = m_pFitSession->GetTreeFDF(nFuncIndex);	
	
	TreeNode trDerivedParams = trFDF.DerivedParameters;
	///end FIX_NO_DERIVED_PARAM_INFO_IN_PARAM_TABLE_FOOTNOTE_IN_PA
	if(!trDerivedParams)
		return false;
	
	string strDerivedParams;
	string strSep = "," + " ";
	foreach(TreeNode trChild in trDerivedParams.Children)
	{
		///Cheney 2007-11-19 COMMA_SHOULD_BE_LOCALIZED
		//strDerivedParams += trChild.tagName + ", ";
		strDerivedParams += trChild.tagName + strSep;
		///end COMMA_SHOULD_BE_LOCALIZED
	}
	if(strDerivedParams.IsEmpty())
		return false;
	
	///Cheney 2007-11-19 COMMA_SHOULD_BE_LOCALIZED
	//strDerivedParams.TrimRight(", ");
	strDerivedParams.TrimRight(strSep);
	///end COMMA_SHOULD_BE_LOCALIZED
	string strFootNote;
	if( !ocu_load_msg_str(FOOTNOTE_NLFIT_DERIVED_PARAMS, &strFootNote, strDerivedParams) )
		return false;
	
	trFootNote.strVal += trFootNote.strVal.IsEmpty()? strFootNote : "\r\n" + strFootNote;
	return true;
}
///end ADD_LCL_UCL_FOR_DERIVED_PARAMS
/// Hong 12/26/07 QA80-10499 FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
static bool _remove_redundant_params_node(TreeNode& trNode, int nDataset, int nNumParams)
{
	if ( !trNode || nDataset < 0 || nNumParams < 0 )
		return false;

	int nCount = trNode.GetNodeCount();
	if ( nCount <= (nDataset+1) * nNumParams )
		return false;
	
	TreeNode trSubNode = trNode.Children.Item(nDataset * nNumParams);
	if ( trSubNode.IsEmpty() )
		return false;
	
	int ii = nDataset * nNumParams;
	while (ii-- > 0)
	{
		trSubNode = trNode.FirstNode;
		trNode.RemoveChild(trSubNode);
	}		
	
	return true;
}

static bool _remove_redundant_params_setting(TreeNode& trParams, int nDataset, int nNumParams)
{
	if ( !trParams || nDataset < 0 || nNumParams < 0 )
		return false;
	
	_remove_redundant_params_node(trParams.Share, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.Fixed, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.LowerBounds, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.LowerBoundsExclusive, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.LowerBoundsEnable, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.UpperBounds, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.UpperBoundsExclusive, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.UpperBoundsEnable, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.Values, nDataset, nNumParams);
	_remove_redundant_params_node(trParams.SignificantDigit, nDataset, nNumParams);
	return true;
}
/// end FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
bool	FitNL::CalcMultiData(TreeNode& trOp, DataRange& dr, int &nNumData, int nExeMode, DWORD dwExecCntrl)
{
	vector<int>	vFactorSizes;
	TreeNode	trAdditionalData = tree_check_get_node(trOp, TREE_INPUTRANGE_ADDITIONAL_DATA_NODE_NAME); 
	DWORD		dwRules = GetDataRules(trOp);
	int			numSubRanges = 0;
	nNumData = dr.GetNumData(dwRules, trAdditionalData, NULL, NULL, &numSubRanges);
	//if(!OnBeforeCalcMultiDataLoop(trOp, dr, nNumData, vFactorSizes))
	if(nNumData <= 0)
		return error_report("No data!");

	bool 		bIsXYZData = HasZ(trOp);
	SetTree(trOp);
	
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	/*
	/// Hong 05/30/08 v8.0874 FIX_FIT_CONVERGE_FAIL_CORRECTLY_RESTORE_SRC_GRAPH_LEGEND
	if ( NULL != m_pFitSession )
		m_pFitSession->CheckRemoveSrcPreviewFitCurves();
	/// end FIX_FIT_CONVERGE_FAIL_CORRECTLY_RESTORE_SRC_GRAPH_LEGEND
	*/
	/// end FITNL_USING_NEW_NLFSESSION
	/// ML 11/10/2006 NLFIT_ALWAYS_MODAL
	//if(!m_bUseFitSession) //---- CPY 4/23/05 OK_ON_BAD_FIT_DO_NOT_CLOSE_DIALOG
	if(NULL == m_pFitSession)
	/// end NLFIT_ALWAYS_MODAL
	{
		InitFitSessionPointer(trOp);  /// Iris 4/14/06 NLFITSESSION_POINTER_FOR_NORMAL_FIT_OR_PFM	
	}	
	
	m_strFitStatus = ""; /// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	
	///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
	//if open Dlg, may be will change func
	//should reload it.
	//if from theme, should set it to Fitsession
	bool bOpenDlg = OEXEM_ON_CREATE_OPEN_GUI == nExeMode || OEXEM_ON_CHANGEPARAM == nExeMode? true : false;
	///Cheney 2007-7-30 ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
	//bool bEmptyTreeFDF = m_trFDF.Children.Count() == 0? true : false;
	//if( bOpenDlg )
		//m_trFDF = m_pFitSession->GetTreeFDF();
	//else if(!bEmptyTreeFDF)
		//m_pFitSession->SetTreeFDF(m_trFDF);		
	if( !(dwExecCntrl & OPEXEC_NO_INIT_FROM_OP_AGAIN) )		///Jasmine 04/11/08 NLFITSESSION_IS_NO_INIT_FROM_OP_AGAIN
		UpdateFDFTreeFromThemeOrChangeFunc(bOpenDlg);
	///end ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
	///end CLEAN_UP_FDF_TREE_LOAD
	
	/// Iris 06/15/2007 v8.0642 FIX_NOT_SET_FIT_SETTINGS_FROM_GUI_TO_NLFIT_WHEN_SEL_MENU_THEME
	/*
	///Cheney 2007-6-6 SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT
	TreeNode trLinearConstraints = trOp.GUI.Parameters.LinearConstraints;
	if( !bOpenDlg && trLinearConstraints)
		m_pFitSession->SetLinearConstraints(trLinearConstraints.nVal);	
	///end SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT
	*/
	if(!bOpenDlg)
	{
		// set fit settings from GUI to NLFit object
		if( !setNLFitSettings(trOp) )
			error_report("Get error in setNLFitSettings");
	}
	///end FIX_NOT_SET_FIT_SETTINGS_FROM_GUI_TO_NLFIT_WHEN_SEL_MENU_THEME
	
	///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
	//bool	bRet = false; 
	bool	bRet = true; 
	///end CLEAN_UP_ERR_HANDLING
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	//if( isSepFit(trOp) )
	//{	
		/////Cheney 2007-4-10 IF_SEP_FIT_SHOULD_DISABLE_FIT_AND_ITER_BUTTON
		////when do sep fit from dlg, save current user setting, after init, get back
		//if(OEXEM_ON_CREATE_OPEN_GUI == nExeMode || OEXEM_ON_CHANGEPARAM == nExeMode) //open Dlg
			//setUserSettingFromGUI();
		/////end IF_SEP_FIT_SHOULD_DISABLE_FIT_AND_ITER_BUTTON
		//
		//for(int ii=0; ii<nNumData; ii++)
		//{
			/////Cheney 2007-5-22 SHOULD_RESET_FITSESSION_OBJ_IF_SEP_FIT	
			////as preview not support sep fit, so here should reset m_NLFit,
			////but many things not reset, such as fitResult, regStats,...
			////best resolved method is to support sep fit in preview
			////so now, just temp fix it
			////after rewite NLFitSession.h, should be removed
			//if(m_pFitSession != NULL)
				//delete m_pFitSession;
			//InitFitSessionPointer(trOp);
			//m_pFitSession->SetTreeFDF(m_trFDF);
			//
			///// Iris 06/15/2007 v8.0642 FIX_NOT_SET_FIT_SETTINGS_FROM_GUI_TO_NLFIT_WHEN_SEL_MENU_THEME
			///*
			/////Cheney 2007-6-6 SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT
			////as m_pFitSession reset, should set it again
			//TreeNode trLinearConstraints = trOp.GUI.Parameters.LinearConstraints;
			//if( !bOpenDlg && trLinearConstraints)
				//m_pFitSession->SetLinearConstraints(trLinearConstraints.nVal);
			/////end SUPPORT_LINEAR_CONSTRAINT_IN_NLFIT
			//*/
			///// Iris 06/25/2007 v8.0648 SHOULD_ALWASY_SET_NLFIT_SETTINGS_AGAIN_AFTER_DEL_FIT_SESSION_POINTER
			//// Discussed with Cheney, always del fit session pointer for Sep Fit above, so should always set nlfit settings again. 
			///*
			//if(!bOpenDlg)
			//{
				//// set fit settings from GUI to NLFit object
				//if( !setNLFitSettings(trOp) )
					//error_report("Get error in setNLFitSettings");
			//}	
			//*/
			//// set fit settings from GUI to NLFit object
			//if( !setNLFitSettings(trOp) )
				//error_report("Get error in setNLFitSettings");
			/////end SHOULD_ALWASY_SET_NLFIT_SETTINGS_AGAIN_AFTER_DEL_FIT_SESSION_POINTER
			/////end FIX_NOT_SET_FIT_SETTINGS_FROM_GUI_TO_NLFIT_WHEN_SEL_MENU_THEME
			//
			/////end SHOULD_RESET_FITSESSION_OBJ_IF_SEP_FIT
			//TreeNode	trSepOp = trOp.Clone();
			//TreeNode 	trOut = trSepOp.Calculation;
			//
			////Reset Input, MaskedData, MissingData, Parameters, Summary, RegStats, ANOVAs tables
			/////Arvin 05/23/07 v8.0624 COV_AND_CORR_TABLE_CHAOS_WHILE_CHANGE_PARAMETER
			////int			nNumTables = 7; 
			//int			nNumTables = 9;
			/////end COV_AND_CORR_TABLE_CHAOS_WHILE_CHANGE_PARAMETER
			//TreeNode 	trTable = trOut.Input;
			//for(int nn = 0; nn < nNumTables && trTable; nn++, trTable = trTable.NextNode)			
			//{
				//trTable.Reset(true);
			//}			
			//
			////Reset ResultCurves, ResidualCurves, Calibration1, Calibration2 
			//nNumTables = 4; 			
			//trTable = trSepOp.ResultCurves;
			//for(nn = 0; nn < nNumTables && trTable; nn++, trTable = trTable.NextNode)			
			//{
				///// Iris 03/01/2007 v8.0572 FIX_INDEP_FIT_MULTI_DATA_REPORT_FAIL_TO_DO_AU
				//// need to keep TREE_UID attribute, this attribute used to remember the report id of the range of result curves
				//// when do AU, we will put the new result into the original place to replace the old result curves .
				////trTable.Reset(true);
				//foreach(TreeNode trSub in trTable.Children) //trSub here is Data1, Data2 nodes...
				//{
					//trSub.Reset(true);
				//}
				/////end FIX_INDEP_FIT_MULTI_DATA_REPORT_FAIL_TO_DO_AU
			//}
			//
			//
			//// Need to remove all the children except the ii'th one:
			//TreeNode	trInputData = trSepOp.GUI.InputData;
			//TreeNode	trChild = trInputData.FirstNode;
			//int			jj = 0;
			//while( trChild.IsValid() )
			//{
				//if (jj == ii)
					//trChild = trChild.NextNode;	// skip
				//else
				//{
					//TreeNode	trDestroy = trChild;
					//trChild = trChild.NextNode;
					//trInputData.RemoveChild(trDestroy);
				//}
				//
				//jj++;
			//}
			//
			//DataRange drSep;
			//drSep.Create();
			//drSep.SetTree(trInputData);
			//
			///// Hong 12/26/07 QA80-10499 FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
			//if ( !isReplicaFit(trOp, true) )
			//{	// for do one fit, only first set of parameter values will be used, so remove other values NOT used for current dataset
				//vector<string> vstrParameterNames;
				//TreeNode trFunc = trOp.GUI.FunctionSelection.FunctionList;
				//TreeNode trCate = trOp.GUI.FunctionSelection.CategoryList;
				//if ( trFunc && trCate )
				//{
					//// fail to use m_pFitSession->GetNumTotalParams() here as seem something not ready
					//if(!nlsf_get_param_names(trFunc.strVal, vstrParameterNames, trCate.strVal))
						//error_report("FitNL.cpp: error in get nlsf parameters!");//Sandy 2008-5-26 add
					//_remove_redundant_params_setting(trSepOp.GUI.Parameters, ii, vstrParameterNames.GetSize()); 
				//}
			//}
			///// end FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
			//
			//_DBPRINTF("\n----------Indep Fit %d----------\n", ii+1);
			//if( doOneFit(trSepOp, drSep, bIsXYZData, nExeMode, dwExecCntrl, nNumData, numSubRanges, 1, ii, true) )
			//{
				////Copy results from trSepOp Input, MaskedData, MissingData, Parameters, Summary, RegStats, ANOVAs tables back to trOp
				/////Arvin 05/11/07 v8.0616 NEED_COPY_COVARIANCE_AND_CORRELATION_MATRIX
				////_tree_copy_nodes(trOp.Calculation, trOut.Input, 7, "Parameters.Footnote");
				//_tree_copy_nodes(trOp.Calculation, trOut.Input, 9, "Parameters.Footnote");
				/////END NEED_COPY_COVARIANCE_AND_CORRELATION_MATRIX
 				//_append_parameter_footnote(trOp, trSepOp);
				//
				////Copy results from trSepOp ResultCurves, ResidualCurves, Calibration1, Calibration2 nodes back to trOp
				//_tree_copy_nodes(trOp, trSepOp.ResultCurves, 4);
				//
				////Clone trOp.Temp node
				//TreeNode 	trTemp = tree_check_get_node(trOp, "Temp", 1);
				//trTemp.Replace(trSepOp.Temp.Clone());
				//
				///// Iris 02/27/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
				////.GUI.InputData will be changed in NLFitSessionBase::SetFunction, so need to copy back to trOp
				//_tree_copy_nodes(trOp.GUI, trSepOp.GUI.InputData, 1);
				/////end CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY	
				//
				/////Cheney 2007-10-8 QA70-10463 FIX_AUTOFIT_OGW_LAST_TWO_DATASET_CAN_NOT_WORK_WHEN_CHANGE_PARAM
				////_copy_params_setting(trOp.GUI.Parameters, trSepOp.GUI.Parameters, (nNumData-1)*m_pFitSession->GetNumTotalParams()); ///Cheney 2007-8-22 SHOULD_ADD_PARAMS_TO_TREE_WHEN_SEP_FIT
				//_copy_params_setting(trOp.GUI.Parameters, trSepOp.GUI.Parameters, ii*m_pFitSession->GetNumTotalParams()); 
				/////end FIX_AUTOFIT_OGW_LAST_TWO_DATASET_CAN_NOT_WORK_WHEN_CHANGE_PARAM
			//}
			//else
			//{
				//bRet = false;
				//break;
			//}
		//}
		//
		////bRet = true;///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
	//}
	//else
	//{
		//bRet = doOneFit(trOp, dr, bIsXYZData, nExeMode, dwExecCntrl, nNumData, numSubRanges, nNumData);
	//}
	bRet = doOneFit(trOp, dr, bIsXYZData, nExeMode, dwExecCntrl, nNumData, numSubRanges, nNumData);
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/// Hong 10/10/08 QA80-11014 FIX_AFTER_FIT_NOT_USED_IF_SAVE_IN_FALY_OUT_THEME
	// This change dependent on the change of Folger 04/11/08 APPLY_FDF_ORIGINAL_SETTING_AFTER_APPLY_THEME which will apply FDF settting into operation
	/////Jasmine 09/30/07 QA70-10462 CHECK_REPLACE_USER_FITTING_FUNCTION_TO_GROUP_ONE
	/// Hong 03/11/09 FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO
	//if(m_pFitSession)
		//GetFitSession()->GetFittingCodes(trOp.GUI.Codes);
	if(m_pFitSession)
		GetFitSession()->GetFittingCodes(trOp.GUI.Codes, true);
	/// end FIX_RECACULATE_FAIL_UPDATE_EQAUTION_AFTER_CHANGED_IN_FO
	/////End CHECK_REPLACE_USER_FITTING_FUNCTION_TO_GROUP_ONE
	/// end FIX_AFTER_FIT_NOT_USED_IF_SAVE_IN_FALY_OUT_THEME
	///Cheney 2007-4-2 ADD_HINTS_IN_FOOTNOTE_WHEN_EXISTS_MISSING_OR_MASKED_DATA
	TreeNode trFootNote = trOp.Calculation.Parameters.Footnote;
	if(trFootNote)
	{
		///Cheney 2007-4-2 IF_SHARE_PARAMETERS_ADD_HINTS_IN_FOOTNOTE
		//------ Folger 04/01/08 QA80-11304 SHOW_SHARED_SIGN_IN_REPORT_SHEET_FOR_REPLICA_FITTING
		//if(DATA_MODE_GLOBAL == trOp.GUI.InputData.Use)	//always need to check shared status, exp: replica fit
		//------
			///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
			//addHintOnFootnoteForShareParams(trFootNote);
			if(!addHintOnFootnoteForShareParams(trFootNote))
				error_report("failed to add hint on foot note for share params"); 
			///end CLEAN_UP_ERR_HANDLING
		///end IF_SHARE_PARAMETERS_ADD_HINTS_IN_FOOTNOTE
		
		///Cheney 2007-11-6 QA70-10659 ADD_LCL_UCL_FOR_DERIVED_PARAMS
		if( !addDerivedParamsInfoOnFootnote(trFootNote) )
			error_report("failed to add derived params info on foot note"); 
		///end ADD_LCL_UCL_FOR_DERIVED_PARAMS
		///Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
		//if(m_bHasMasked)
			//trFootNote.strVal += "\r\nSome input data points are masked.";
		//if(m_bHasMissing)
			//trFootNote.strVal += "\r\nSome input data points are missing.";
		///end ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
	}
	///end ADD_HINTS_IN_FOOTNOTE_WHEN_EXISTS_MISSING_OR_MASKED_DATA
	
	///Cheney 2007-5-11 RESET_FIXED_LABEL_AS_MAX_SUGGEST
	TreeNode trFixed = trOp.GUI.Quantities.Parameters.Fix;
	if(trFixed)
		trFixed.SetAttribute(STR_LABEL_ATTRIB, _L("Fixed"));
	///end RESET_FIXED_LABEL_AS_MAX_SUGGEST
	
	/// Iris 11/03/2009 QA81-14576 OUTPUT_FIT_NOT_CONVERGED_INFO_TO_SCRIPT_WND
	int nFitMode = trOp.GUI.InputData.Use;
	if( DATA_MODE_INDEP_SEP != nFitMode ) // if sep report with multi dataset, not output anything to SC wnd.
	{
		string strFitCome;
		if( DATA_MODE_INDEP_CONSOLID == nFitMode && nNumData > 1 )
		{
			int nSummaryOutType = -1;
			strFitCome = GetFitSession()->GetSummaryIterateOutCome(&nSummaryOutType, false);
			if( !strFitCome.IsEmpty() && (-1 == nSummaryOutType || SUMMARY_FIT_OUT_ALL_SUCCESS == nSummaryOutType)) 
			{
				strFitCome.Empty();// if all successfully, no need output
			}
		}
		else
		{
			int nLastOutcome = GetFitSession()->GetLastIterateOutCome();
			if( !GetFitSession()->IsLastFitOutComeGoodFit(nLastOutcome) )
			{
				strFitCome = GetFitSession()->GetFitOutCome(nLastOutcome);
			}
		}
		
		if( !strFitCome.IsEmpty() )
		{
			/// Iris 12/08/2009 FIX_GIBBERISH_MESSAGE_IN_SCRIPT_WND_IN_J_BUILD
			// strFitCome already is localized, no need localize again, or lese cause gibberish.
			//strFitCome = GetLocalized(strFitCome);
			///end FIX_GIBBERISH_MESSAGE_IN_SCRIPT_WND_IN_J_BUILD
			warning_msg_box(strFitCome, false, 'I');
		}
	}
	///end OUTPUT_FIT_NOT_CONVERGED_INFO_TO_SCRIPT_WND
	
	return bRet;
}

static void test_fit_curve(TreeNode &trRC, int ii)
{
	string str = "Data" + (ii+1);
	TreeNode trFitCurve = trRC.GetNode(str);
	if(!trFitCurve)
		error_report("fail in test_fit_curve");
	
	WorksheetPage wksPage("Test");
	if(!wksPage)
	{
		wksPage.Create();
		wksPage.Rename("Test");
	}
	
	
	Worksheet wks;
	wks = wksPage.Layers();
	int nCol = wks.GetNumCols();
	
	Column colX(wks, nCol);
	if(!colX)
	{
		colX.Attach(wks, wks.AddCol());
	}
	nCol++;
	
	Column colY(wks, nCol);
	if(!colY)
	{
		colY.Attach(wks, wks.AddCol());
	}
	
	vector vX, vY;
	vX = trFitCurve.FitCurves.FitX.dVals;
	vY = trFitCurve.FitCurves.FitY.dVals;
	
	Dataset dsX(colX);
	dsX = vX;
	Dataset dsY(colY);
	dsY = vY;
	
}

static void _append_parameter_footnote(TreeNode &trOp, TreeNode &trSepOp)
{
	TreeNode	trFootNote = trOp.Calculation.Parameters.Footnote;
	if(!trFootNote)
	{
		trFootNote = trOp.Calculation.Parameters.AddNode("junk");
		trFootNote.Replace(trSepOp.Calculation.Parameters.Footnote.Clone());
		return;
	}
	
	string 	strSep = "\n-----------------------------------\n";
	trFootNote.strVal = trFootNote.strVal + strSep + trSepOp.Calculation.Parameters.Footnote.strVal;	
}

static void _tree_copy_nodes(TreeNode &trDest, TreeNode &trFrom, int nNumNodes, LPCSTR lpcszSkipNode = NULL, bool bCopyAttrib = true)
{
	TreeNode 	trNode = trFrom;
	for(int nn = 0; nn < nNumNodes && trNode; nn++, trNode = trNode.NextNode)
	{
		foreach(TreeNode trSub in trNode.Children)
		{	
			bool		bSkipThisSubNode = false;
			if(NULL != lpcszSkipNode)
			{
				string	strSkipNode(lpcszSkipNode);				
				if(0 == lstrcmpi(trNode.tagName, strSkipNode.GetToken(0, '.')) && 0 == lstrcmpi(trSub.tagName, strSkipNode.GetToken(1, '.')) )
				{
					bSkipThisSubNode = true;
				}
			}
			
			if( !bSkipThisSubNode )
			{
				/// Iris 02/27/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
				//TreeNode tr = trDest.GetNode(trNode.tagName).AddNode("jusk");
				if(!trSub.IsEmpty())/// Iris 03/01/2007 v8.0572 FIX_INDEP_FIT_MULTI_DATA_REPORT_FAIL_TO_DO_AU
				{
					TreeNode tr = trDest.GetNode(trNode.tagName).GetNode(trSub.tagName);
					///Cheney 2007-4-2 FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
					//if(!tr)
						//tr = trDest.GetNode(trNode.tagName).AddNode("jusk");
					/////end CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
					//tr.Replace(trSub.Clone());
					bool bReplace = true;	///Arvin 11/27/07 WRONG_MASKED_AND_MISSING_TABLE_FOR_MULTI_DATASET
					if(!tr)
					{
						tr = trDest.GetNode(trNode.tagName).AddNode("jusk");
					}
					else if(trNode.tagName.Compare("MissingData") == 0 || trNode.tagName.Compare("MaskedData") == 0)
					{
						///Arvin 11/27/07 WRONG_MASKED_AND_MISSING_TABLE_FOR_MULTI_DATASET
						//TreeNode trTemp = trSub.Children.Item(0);
						//tr = tr.GetNode(trTemp.tagName);
						//if(!tr)
							//tr = trDest.GetNode(trNode.tagName).GetNode(trSub.tagName).AddNode("jusk");
						//trSub = trTemp;
						bReplace = false;
						foreach(TreeNode trTemp in trSub.Children)
						{
							tr = tr.GetNode(trTemp.tagName);
							if(!tr)
								tr = trDest.GetNode(trNode.tagName).GetNode(trSub.tagName).AddNode("jusk");
							tr.Replace(trTemp.Clone());
						}
						///end WRONG_MASKED_AND_MISSING_TABLE_FOR_MULTI_DATASET
					}
					///Arvin 11/27/07 WRONG_MASKED_AND_MISSING_TABLE_FOR_MULTI_DATASET
					//tr.Replace(trSub.Clone());
					if(bReplace)
						tr.Replace(trSub.Clone());
					///end WRONG_MASKED_AND_MISSING_TABLE_FOR_MULTI_DATASET
					///end FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
				}
			}			
		}
		
		if(bCopyAttrib)
		{
			tree_node_copy_attribute(trNode, trDest.GetNode(trNode.tagName), STR_LABEL_ATTRIB);
			tree_node_copy_attribute(trNode, trDest.GetNode(trNode.tagName), TREE_Table);
			tree_node_copy_attribute(trNode, trDest.GetNode(trNode.tagName), STR_SHOW_ATTRIB);
			/// Iris 03/12/2007 v8.0579 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
			// should copy back correct NodeID attribute for InputData node
			tree_node_copy_attribute(trNode, trDest.GetNode(trNode.tagName), STR_ID_ATTRIB);
			///end CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
		}
	}
	
}

///Cheney 2007-8-22 SHOULD_ADD_PARAMS_TO_TREE_WHEN_SEP_FIT
static bool _copy_params_node(TreeNode& trDest, const TreeNode& trSrc, int nNodeIndex)
{
	if(!trDest || !trSrc || nNodeIndex < 0)
		return false;
	
	///Cheney 2007-10-8 QA70-10463 FIX_AUTOFIT_OGW_LAST_TWO_DATASET_CAN_NOT_WORK_WHEN_CHANGE_PARAM
	//int nDestNodeCount = 0;
	//int nSrcNodeCount = 0;
	//
	//foreach(TreeNode trDestSub in trDest.Children)
	//{
		//if(nDestNodeCount < nNodeIndex)
		//{
			//nDestNodeCount++;
			//continue;
		//}
		//
		//TreeNode trSrcSub;
		//trSrcSub = trSrc.Children.Item(nSrcNodeCount);
		//
		//trDestSub.strVal = trSrcSub.strVal;
		//nSrcNodeCount++;
		//nDestNodeCount++;
	//}
	int nSrcNodeCount = trSrc.GetNodeCount();
	int nSrcNodeIndex = 0;
	for(int ii = 0; ii < nSrcNodeCount; ii++)
	{
		TreeNode trDestSub = tree_get_node(trDest, nNodeIndex + ii);
		if(!trDestSub)
		{
			trDestSub = trDest.AddNode("Value" + (nNodeIndex + ii + 1));
			trDestSub.DataID = trDestSub.PrevNode.DataID + 1;
		}
		
		TreeNode trSrcSub = trSrc.Children.Item(nSrcNodeIndex);
		if(!trSrcSub)
			return false;
		
		trDestSub.strVal = trSrcSub.strVal;
		nSrcNodeIndex++;
	}
	///end FIX_AUTOFIT_OGW_LAST_TWO_DATASET_CAN_NOT_WORK_WHEN_CHANGE_PARAM
	
	return true;
}

static bool _copy_params_setting(TreeNode& trParamsDest, const TreeNode& trParamsSrc, int nNodeIndex)
{
	if(!trParamsDest || !trParamsSrc || nNodeIndex < 0)
		return false;
	
	_copy_params_node(trParamsDest.Share, trParamsSrc.Share, nNodeIndex);
	_copy_params_node(trParamsDest.Fixed, trParamsSrc.Fixed, nNodeIndex);
	_copy_params_node(trParamsDest.LowerBounds, trParamsSrc.LowerBounds, nNodeIndex);
	_copy_params_node(trParamsDest.LowerBoundsExclusive, trParamsSrc.LowerBoundsExclusive, nNodeIndex);
	_copy_params_node(trParamsDest.LowerBoundsEnable, trParamsSrc.LowerBoundsEnable, nNodeIndex);
	_copy_params_node(trParamsDest.UpperBounds, trParamsSrc.UpperBounds, nNodeIndex);
	_copy_params_node(trParamsDest.UpperBoundsExclusive, trParamsSrc.UpperBoundsExclusive, nNodeIndex);
	_copy_params_node(trParamsDest.UpperBoundsEnable, trParamsSrc.UpperBoundsEnable, nNodeIndex);
	_copy_params_node(trParamsDest.Values, trParamsSrc.Values, nNodeIndex);
	_copy_params_node(trParamsDest.SignificantDigit, trParamsSrc.SignificantDigit, nNodeIndex);
	return true;
}
///end SHOULD_ADD_PARAMS_TO_TREE_WHEN_SEP_FIT



/// ML 9/1/2006 NLFIT_MULTIDEPS_INDEPS_INPUT_DATA_TBL
// virtual
/// Iris 4/28/2008 NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
//void	FitNL::updateInputDataTable(TreeNode &trInputTable, int index, int numData, DWORD dwRules)
void	FitNL::updateInputDataTable(TreeNode &trInputTable, int index, int numData, DWORD dwRules, bool bIsXYZData)
///end NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
{
	int	nDeps, nIndeps;
	StringArray	vstrDepVarNames, vstrIndepVarNames;
	GetFitSession()->GetNumVars(&nDeps, &nIndeps, &vstrDepVarNames, &vstrIndepVarNames);
	///Sophy 1/19/2009 v8.0960 FIX_USE_SAME_WEIGHT_METHOD_FOR_ALL_DATASETS
	/*
	int	nTotalPerSet = nDeps + nIndeps;
	
	int	nNumDataSet = GetFitSession()->GetNumDataset();
	
	///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
	//for (int indexSet = 0; indexSet < numData; indexSet++)
	//{
		//for (int iindep = 0; iindep < nIndeps; iindep++)
		//{
			//TreeNode	trRow = makeInputDataTableVarRow(trInputTable, index, iindep, iindep, false, vstrIndepVarNames[iindep], numData, nTotalPerSet);
		//}
		//
		//for (int idep = 0; idep < nDeps; idep++)
		//{
			//TreeNode	trRow = makeInputDataTableVarRow(trInputTable, index, nIndeps + idep, idep, true, vstrDepVarNames[idep], numData, nTotalPerSet);
		//}
	//}
	int nWeightMethod;
	Tree trrABC;
	/// Iris 2/25/2007 v8.0570 SUPPORT_INDEP_FIT_MODE, for indep fit consolide report case, only one input data in m_pFitSession
	//for(int indexSet = 0; indexSet < numData; indexSet++)
	for(int indexSet = 0; indexSet < nNumDataSet; indexSet++)
	///end SUPPORT_INDEP_FIT_MODE
	{
		for (int idep = 0; idep < nDeps; idep++)
		{
			/// Iris 4/22/2008 ALWAYS_SHOW_0_FOR_WEIGHT_ARGUMENTS
			//string strZero = ftoa(0);
			//TreeNode trrABC1 = trrABC.AddTextNode(strZero);
			//TreeNode trrABC2 = trrABC.AddTextNode(strZero);
			//TreeNode trrABC3 = trrABC.AddTextNode(strZero);
			//m_pFitSession->GetOneWeight(indexSet, idep, nWeightMethod, trrABC1.dVal, trrABC2.dVal, trrABC3.dVal);
			double 	dA = 0.0, dB = 0.0, dC = 0.0;
			GetFitSession()->GetOneWeight(indexSet, idep, nWeightMethod, dA, dB, dC);
			TreeNode trrABC1 = trrABC.AddNumericNode(dA);
			TreeNode trrABC2 = trrABC.AddNumericNode(dB);
			TreeNode trrABC3 = trrABC.AddNumericNode(dC);
			///end ALWAYS_SHOW_0_FOR_WEIGHT_ARGUMENTS
		}
	}
	/// Iris 4/28/2008 NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
	//report_update_input_data_table(&trInputTable, index, numData, nDeps, nIndeps, &vstrDepVarNames, &vstrIndepVarNames, nNumDataSet, nWeightMethod, &trrABC);
	report_update_input_data_table(&trInputTable, index, numData, nDeps, nIndeps, &vstrDepVarNames, &vstrIndepVarNames, nNumDataSet, nWeightMethod, &trrABC, bIsXYZData);
	///end NANOSIZER_REPORT_COMPLEX_INPUT_DATA_WITH_WEIGHT_INFO
	///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
	*/
	int nWeightMethod;
	Tree trABC;
	double dA = 0, dB = 0, dC = 0;
	const int nNumDataset = 1;
	///------ Folger 08/17/10 ORG-824-P1 WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
	vector<int>		vnWeights;
	vnWeights.SetSize(nDeps);
	///------ End WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
	for ( int iDep = 0; iDep < nDeps; iDep++ )
	{
		///------ Folger 08/17/10 ORG-824-P1 WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
		//GetFitSession()->GetOneWeight(index, iDep, nWeightMethod, dA, dB, dC);
		GetFitSession()->GetOneWeight(index, iDep, vnWeights[iDep], dA, dB, dC);
		///------ End WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
		trABC.AddNumericNode(dA);
		trABC.AddNumericNode(dB);
		trABC.AddNumericNode(dC);
	}
	///------ Folger 08/17/10 ORG-824-P1 WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
	//report_update_input_data_table(&trInputTable, index, numData, nDeps, nIndeps, &vstrDepVarNames, &vstrIndepVarNames, nNumDataset, nWeightMethod, &trABC, bIsXYZData);
	report_update_input_data_table(&trInputTable, index, 1, nDeps, nIndeps, &vstrDepVarNames, &vstrIndepVarNames, nNumDataset, &vnWeights, &trABC, bIsXYZData);
	///------ End WEIGHTING_BROKEN_FOR_MULTIPLE_DEPS_FITTING
	///end FIX_USE_SAME_WEIGHT_METHOD_FOR_ALL_DATASETS
}

// virtual
void	FitNL::GetEscapedMainDataString(TreeNode &trOp, string &str, int indexLT, bool bInputTable, char cType, char cXYW)// = false  = 0  = 0
{
	DWORD			dwRules = GetDataRules(trOp);
	if (DRR_COMBINED_MASK & dwRules)
		FitterOperation::GetEscapedMainDataString(trOp, str, indexLT, bInputTable, cType, cXYW);
	
	///Arvin 01/23/06 INPUT_MASKED_AND_MISSING_DATA_TABLE_INCOMPLETE_CONCATENATE
	//getSetDataString(str, indexLT - 1);
	int nDataMode = trOp.GUI.InputData.Use;
	if(nDataMode != DATA_MODE_CONCATENATE)
	/// ML 4/2/2007 INCORRECT_MAIN_DATA_STRING_NLFIT
	//	///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
	//	//getSetDataString(str, indexLT - 1);
	//	report_get_set_data_string(str, indexLT - 1, m_pFitSession->GetNumDataset());
	//	///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
	{
		report_get_escaped_data_string(&str, indexLT, false, 'F', 0);
	}
	/// end INCORRECT_MAIN_DATA_STRING_NLFIT
	///end INPUT_MASKED_AND_MISSING_DATA_TABLE_INCOMPLETE_CONCATENATE
}

//----Iris 9/26/06 no need overload here
//// virtual
//bool 	FitNL::IsOutputSeparateResidualCurveSheet()
//{
	//return false;		// temp
//}
//----

#define	CALC_INPUT_DATA_NLFIT_ROW_PREFIX	"R"
#define	CALC_INPUT_DATA_NLFIT_COL_PREFIX	"C"
///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
//bool		FitNL::getSetDataString(string &str, int indexSet)
//{
	//int				numSets = m_pFitSession->GetNumDataset();
	//int				nAdditional = ESC_LABEL_ADD_NONE;
	///// Iris 01/09/2007 v8.0539 REMOVE_INDEX_FOR_DATA_LABEL, from Easwar's requirement
	////if (1 < numSets)
	////	nAdditional = MAKELONG(ESC_LABEL_ADD_INDEX, indexSet + 1);
	/////end REMOVE_INDEX_FOR_DATA_LABEL
	//
	//// For 'F' see CONVERT_DATA_ESC_COMBINE_ALL_CHAR in okIrange.cpp.
	//getEscapedDataString(str, indexSet + 1, FALSE, 'F', 'Y', nAdditional);
	//return true;
//}
///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC

#define	STR_INPDTBL_NLFIT_COL_DEP_INDEP	_L("Dep/Indep")
#define	STR_INPDTBL_NLFIT_INDEP			_L("Indep")
#define	STR_INPDTBL_NLFIT_DEP			_L("Dep")
#define	STR_INPDTBL_NLFIT_WEIGHT_TYPE	_L("Weight Type")
#define	STR_INPDTBL_NLFIT_WEIGHT_DATA	_L("Weight Data")
///Cheney 2007-1-30 MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC
//// Each row is one variable, times the total number of sets.
//TreeNode	FitNL::makeInputDataTableVarRow(TreeNode &trInputTable, int indexSet, int iWithinSet, int iWithinDepOrIndep, bool bDep, LPCSTR lpcszVarName, int numData, int nTotalPerSet)
//{
	//
	//int			id = make_one_set_ID(IDST_REPORT_INPUT_DATA_NLFIT_VAR_BEG + iWithinSet, indexSet);
	//
	//TreeNode	trRow = check_add_enumerated_node(trInputTable, CALC_INPUT_DATA_NLFIT_ROW_PREFIX, indexSet * nTotalPerSet + iWithinSet + 1, id);
	///////////////
	//// Row labels:
	//// The var name is either the only column of row labels (if numData <= 1), or the second column of row labels (if 1 < numData).
	//int			nVarNameLabel = numData <= 1 ? -1 : 0;
	//if (1 < numData)
	//{
		//string		strSet;
		//getSetDataString(strSet, indexSet);
		//tree_add_one_label(trRow, strSet);
	//}
	//tree_add_one_label(trRow, lpcszVarName, nVarNameLabel);
//
	//int			indexCol = 0;
	//// Dep or indep col:
	//TreeNode	trCol = check_add_enumerated_node(trRow, CALC_INPUT_DATA_NLFIT_COL_PREFIX, ++indexCol, IDE_INPUT_NLFIT_DEP_INDEP);
	//tree_add_one_label(trCol, STR_INPDTBL_NLFIT_COL_DEP_INDEP);
	//if ( bDep )
		//trCol.strVal = STR_INPDTBL_NLFIT_DEP;
	//else
		//trCol.strVal = STR_INPDTBL_NLFIT_INDEP;
	//
	//// 'P' string: (like [Book1]Sheet!LongOrShortColName) col:
	//trCol = check_add_enumerated_node(trRow, CALC_INPUT_DATA_NLFIT_COL_PREFIX, ++indexCol, IDE_INPUT_NLFIT_DATA);
	//tree_add_one_label(trCol, _L("Data"));
	//string		str;
	//char		cXYW = bDep ? 'Y' : 'X';
	//getEscapedDataString(str, indexSet + 1, FALSE, 'P', cXYW, ESC_LABEL_ADD_NONE, 0, iWithinDepOrIndep + 1);
	//trCol.strVal = str;
	//
//
	//// Row range string:
	//trCol = check_add_enumerated_node(trRow, CALC_INPUT_DATA_NLFIT_COL_PREFIX, ++indexCol, IDE_INPUT_RANGE);
	//tree_add_one_label(trCol, WKSH_OPERATION_INFO_DATA_SOURCE_RANGE);
	//getEscapedDataString(str, indexSet + 1, FALSE, 'G', cXYW, ESC_LABEL_ADD_NONE, 0, iWithinDepOrIndep + 1);
	//trCol.strVal = str;
	//
	//if (bDep)		// Weight columns:
	//{
		//int				nWeightMethod;
		//double			rABC[3];
		//m_pFitSession->GetOneWeight(indexSet, iWithinDepOrIndep, nWeightMethod, rABC[0], rABC[1], rABC[2]);
		//
		//string			strDisplay;
		//BOOL			bData, bWParams[3];
		//octree_fitter_get_weight_mth_info(nWeightMethod, &strDisplay, &bData, &bWParams[0], &bWParams[1], &bWParams[2]);
		//// Weight type:
		//trCol = check_add_enumerated_node(trRow, CALC_INPUT_DATA_NLFIT_COL_PREFIX, ++indexCol, IDE_INPUT_NLFIT_WEIGHT_TYPE);
		//tree_add_one_label(trCol, STR_INPDTBL_NLFIT_WEIGHT_TYPE);
		//trCol.strVal = strDisplay;
		//
		//// Weight Data:
		//++indexCol;
		//if (bData)
		//{
			//trCol = check_add_enumerated_node(trRow, CALC_INPUT_DATA_NLFIT_COL_PREFIX, indexCol, IDE_INPUT_NLFIT_WEIGHT_DATA);
			//tree_add_one_label(trCol, STR_INPDTBL_NLFIT_WEIGHT_DATA);
			//getEscapedDataString(str, indexSet + 1, FALSE, 'P', 'W', ESC_LABEL_ADD_NONE, 0, iWithinDepOrIndep + 1);
			//trCol.strVal = str;
		//}
		//
		//// Weight a, b, c params:
		//for (int jj = 0; jj < 3; jj++)
		//{
			//++indexCol;
			//if (bWParams[jj])
			//{
				//char	ch = 'a' + jj;
				//string	strWParamLabel = ch;
				//trCol = check_add_enumerated_node(trRow, CALC_INPUT_DATA_NLFIT_COL_PREFIX, indexCol, IDE_INPUT_NLFIT_WEIGHT_A + jj);
				//tree_add_one_label(trCol, strWParamLabel);
				//trCol.dVal = rABC[jj];
			//}
		//}
	//}
	//
	//return trRow;
//}
///end MOVE_SOME_FUNCTION_FOR_NLFIT_REPORT_TO_VC

/// ML 9/5/2006 MASKED_MISSING_NLFIT_TABLES
bool	FitNL::updateMaskedOrMissingDataTables(TreeNode& trOp, DataRange& dr, int index, StringArray &vstrDepVarNames, StringArray &vstrIndepVarNames,
													int nNumData, int numSubRanges, DWORD dwRules, LPCSTR lpcszDataLabel, bool bMissingData)
{
	/// Iris 01/15/2007 v8.0541 REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
	//int			numTotal = 0 < numSubRanges ? numSubRanges : nNumData;
	//bool			bUseSubLevels = 1 < numTotal;
	//TreeNode		trTable;
	///end REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
	TreeNode		trCalc = trOp.Calculation;
	TreeNode		trTheTable;
	int				idOneSet;
	bool			bCreateTable; /// Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
	if ( bMissingData )
	{
		idOneSet = IDST_REPORT_MISSING_DATA_TABLES;
		trTheTable = trCalc.MissingData;
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//bCreateTable = trOp.GUI.Output.Create.MissingData.nVal;  /// Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
		bCreateTable = OP_GUI_OUTPUT_TABLES_BRANCH(trOp.GUI).MissingData.nVal;
		///end OP_DLG_NEW_STRUCTURE
	}
	else
	{
		idOneSet = IDST_REPORT_MASKED_DATA_TABLES;
		trTheTable = trCalc.MaskedData;
		/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
		//bCreateTable = trOp.GUI.Output.Create.MaskedData.nVal; /// Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
		bCreateTable = OP_GUI_OUTPUT_TABLES_BRANCH(trOp.GUI).MaskedData.nVal;
		///end OP_DLG_NEW_STRUCTURE
	}
	
	if( !trTheTable )
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		//return false;
		error_report("no table for adding missing or masked data");
		///end CLEAN_UP_ERR_HANDLING

	/// Iris 01/15/2007 v8.0541 REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
	/*
	if ( bUseSubLevels )
	{
		trTheTable.SetAttribute(TREE_Table, GetTableStringMaskedOrMissingData(true));	
		int			nID = make_one_set_ID(idOneSet, index);
		string		strTableLabel;
		getSetDataString(strTableLabel, index);
		trTable = check_add_enumerated_node(trTheTable, "M", index + 1, nID, STR_LABEL_ATTRIB, strTableLabel);
		trTable.SetAttribute(TREE_Table, GetTableStringSupport());	// must be transposed
	}
	else
	{
		trTable = trTheTable;
		trTable.SetAttribute(TREE_Table, GetTableStringMaskedOrMissingData(false));
	}
	bool		bHas = setOneMaskedOrMissingTable(dr, trTable, index, vstrDepVarNames, vstrIndepVarNames, dwRules, bMissingData);
	*/
	trTheTable.SetAttribute(TREE_Table, GetTableStringMaskedOrMissingData(false));
	bool		bHas = setOneMaskedOrMissingTable(dr, trTheTable, index, vstrDepVarNames, vstrIndepVarNames, dwRules, lpcszDataLabel, bMissingData, bCreateTable);
	///end REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
	
	///Cheney 2007-4-2 ADD_HINTS_IN_FOOTNOTE_WHEN_EXISTS_MISSING_OR_MASKED_DATA
	if(bHas)
	{
		if(bMissingData)
			///Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
			//m_bHasMissing = true;
			SetHasMissingData(true);
			///end ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
		else
			///Cheney 2007-4-12 ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
			//m_bHasMasked = true;
			SetHasMaskedData(true);
			///end ALL_FITTING_TOOLS_NEED_FOOTNOTE_FOR_MISSING_AND_MASKED_DATA
	}
	///end ADD_HINTS_IN_FOOTNOTE_WHEN_EXISTS_MISSING_OR_MASKED_DATA
	
	/// Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
	if( bCreateTable )
	{
		UpdateNotesTextOnEmptyMaskedOrMissingDataTable(trTheTable, bMissingData, index, nNumData, bHas);
	}
	///end ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE	
	
	octree_set_attribute_bit_if_not_empty(&trTheTable, TREE_Table, GETNBRANCH_OPEN);
	return bHas;
}

// Returns true if any data found.
bool	FitNL::setOneMaskedOrMissingTable(DataRange& dr, TreeNode &trTable, int index, StringArray &vstrDepVarNames, StringArray &vstrIndepVarNames,
											DWORD dwRules, LPCSTR lpcszDataLabel, bool bMissingData, bool bCreateTable)
{
	/// Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
	if( !bCreateTable )
		return false;
	///end ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
	
	int				idRows, idRow;
	if ( bMissingData )
	{
		idRows = IDE_MISSING_ROWS;
		idRow = IDE_MISSING_ROW;
	}
	else
	{
		idRows = IDE_MASKED_ROWS;
		idRow = IDE_MASKED_ROW;
	}
	int				numDeps = vstrDepVarNames.GetSize();
	int				numIndeps = vstrIndepVarNames.GetSize();
	vector			vDeps[MAX_DATASET_NUMBER], vIndeps[MAX_INDEP_DATASET_NUMBER], vWeights[MAX_DATASET_NUMBER];
	vector<int>		vintRows;
	int				nn = dr.GetMaskedOrMissingNLFitData(dwRules, index, !bMissingData, &vintRows, numDeps, vDeps, numIndeps, vIndeps, vWeights);

	bool			bReturn = true;
	if ( nn < 0 )
	{
		ASSERT(FALSE);		// failed		
		bReturn = false;
	}
	else if ( vintRows.GetSize() <= 0 )
		bReturn = false;		// to indicate that there are no pts
	
	/// Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
	//if (!bReturn)
	//	return false;		// no masked or missing pts
	///end ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE

	/// Iris 01/15/2007 v8.0541 REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
	//TreeNode		trRows = tree_check_get_node(trTable, "MRows", idRows, STR_LABEL_ATTRIB, _L("Rows"));
	//trRows.nVals = vintRows;
	TreeNode		trRows = tree_check_get_node(trTable, "Rows", idRows, STR_LABEL_ATTRIB, _L("Rows")); //changed the tagname to same as the missing/masked table in basic class
	
	///Cheney 2007-4-2 FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
	TreeNode trOp;
	GetTree(trOp);
	int nDataMode = trOp.GUI.InputData.Use;
 	int nRowStart = getRowStartForMaskedOrMissingData();
	AddRowsToMaskedOrMissingDataTable(trRows, vintRows, idRow, lpcszDataLabel, nDataMode==DATA_MODE_INDEP_CONSOLID? &nRowStart : NULL);
	/// Iris 9/14/2009 QA80-14279 ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
	// if not missing or masked data return from here
	if( !bReturn )
		return false; 
	///end ADD_NOTES_TEXT_FOR_EMPTY_MISSING_MASKED_DATA_TABLE
		
	int nRowStartCurrent = getRowStartForMaskedOrMissingData();
	//AddRowsToMaskedOrMissingDataTable(trRows, vintRows, idRow, lpcszDataLabel);
	///end FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
	///end REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
	
	string			strTag;
	// Indeps:
	for (int iindep = 0; iindep < numIndeps; iindep++)
	{
		// One vector node:
		strTag.Format("I%d", iindep + 1);
		TreeNode	trVec = tree_check_get_node(trTable, strTag, IDST_REPORT_MASKED_MISSING_NLFIT_INDEP_BEG + iindep, STR_LABEL_ATTRIB, vstrIndepVarNames[iindep]);
		/// Hong 06/07/09 QA80-13865 FIX_INDPES_DEPS_FUNC_CONTAIN_REDUNDENT_MISSING_ROW_IN_REPORT_TABLE
#ifdef			__FIX_INDPES_DEPS_FUNC_REDUNDENT_MISSING_ROW_IN_REPORT_TABLE__
		nRowStartCurrent = getRowStartForMaskedOrMissingData();
#endif			//__FIX_INDPES_DEPS_FUNC_REDUNDENT_MISSING_ROW_IN_REPORT_TABLE__
		/// end FIX_INDPES_DEPS_FUNC_REDUNDENT_MISSING_ROW_IN_REPORT_TABLE
		/// Iris 01/15/2007 v8.0541 REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
		//trVec.dVals = vIndeps[iindep];
		///Cheney 2007-4-2 FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
		//AddRowsToMaskedOrMissingDataTable(trVec, vIndeps[iindep], idRow, lpcszDataLabel);
		AddRowsToMaskedOrMissingDataTable(trVec, vIndeps[iindep], idRow, lpcszDataLabel, nDataMode==DATA_MODE_INDEP_CONSOLID? &nRowStartCurrent : NULL);
		///end FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
		///end REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
	}
	
	// Deps and weight datasets (if any):
	for (int idep = 0; idep < numDeps; idep++)
	{
		// One vector node for dep:
		strTag.Format("D%d", idep + 1);
		TreeNode	trVec = tree_check_get_node(trTable, strTag, IDST_REPORT_MASKED_MISSING_NLFIT_DEP_BEG + idep, STR_LABEL_ATTRIB, vstrDepVarNames[idep]);
		/// Iris 01/15/2007 v8.0541 REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
		//trVec.dVals = vDeps[idep];
		///Cheney 2007-4-2 FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
		//AddRowsToMaskedOrMissingDataTable(trVec, vDeps[idep], idRow, lpcszDataLabel);
		nRowStartCurrent = getRowStartForMaskedOrMissingData();
		AddRowsToMaskedOrMissingDataTable(trVec, vDeps[idep], idRow, lpcszDataLabel, nDataMode==DATA_MODE_INDEP_CONSOLID? &nRowStartCurrent : NULL);
		///end FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
		///end REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
		
		// One vector node for weight ds:
		vector		*pW = &vWeights[idep]; 
		if ( pW->GetSize() > 0 )
		{
			strTag.Format("W%d", idep + 1);
			TreeNode	trVec = tree_check_get_node(trTable, strTag, IDST_REPORT_MASKED_MISSING_NLFIT_WEIGHT_BEG + idep, STR_LABEL_ATTRIB, STR_INPDTBL_NLFIT_WEIGHT_DATA);
			/// Iris 01/15/2007 v8.0541 REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE
			//trVec.dVals = vWeights[idep];
			///Cheney 2007-4-2 FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
			//AddRowsToMaskedOrMissingDataTable(trVec, vWeights[idep], idRow, lpcszDataLabel);
			nRowStartCurrent = getRowStartForMaskedOrMissingData();
			AddRowsToMaskedOrMissingDataTable(trVec, vWeights[idep], idRow, lpcszDataLabel, nDataMode==DATA_MODE_INDEP_CONSOLID? &nRowStartCurrent : NULL);
			///end FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
			///end REMOVE_SUB_TABLE_FROM_ANOVE_MISS_MASK_DATA_TABLE

		}
	}
	///Cheney 2007-4-2 FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
	setRowStartForMaskedOrMissingData(nRowStart);
	///end FIX_ALWAYS_SHOW_LAST_DATASET_MISSING_MASKED_DATA_WHEN_MULTI_DATASET_FITTING
	return bReturn;
}
/// end MASKED_MISSING_NLFIT_TABLES
/// end NLFIT_MULTIDEPS_INDEPS_INPUT_DATA_TBL

///Arvin 12/29/06 MOVE_TO_ANALYSIS_UTILS
/*
///Arvin 11/03/06 SET_W_AS_ED_OF_DATARANGE_AND_PLOT_ERROR_BAR
int FitNL::plotInputDataWithErrorBar(DataRange& dr, GraphLayer& gl, int nPlotType, uint nCntrl)
{
	if(!gl || !dr)
		return -1;
	
	DataRange drSubRange;
	int nStartPlot = -1;
	for(int nRange=0; nRange < dr.GetNumRanges(); nRange++)
	{
		int c1, c2, r1, r2;
		Worksheet wksTemp;
		dr.GetRange(nRange, r1, c1, r2, c2, wksTemp);
		
		//create a new data range with range name "X", "Y", "Err" and so on according to col type
		for( int nCol = c1; nCol <= c2; nCol++ )
		{
			Column col(wksTemp, nCol);
			if( col )
			{
				string strRange;
				switch( col.GetType() )
				{
				case OKDATAOBJ_DESIGNATION_X:
					strRange = "X";
					break;
					
				case OKDATAOBJ_DESIGNATION_Y:				
					strRange = "Y";
					break;
					
				case OKDATAOBJ_DESIGNATION_ERROR:				
					strRange = "ED";				
					break;
					
				case OKDATAOBJ_DESIGNATION_Z:
					strRange = "Z";
					break;
				case OKDATAOBJ_DESIGNATION_WEIGHT:
					strRange = "W";
				default:
					break;
				}
			
				if( !strRange.IsEmpty() )
				{
					if("X" == strRange && drSubRange)
						drSubRange.Add(); //add separator
					
					drSubRange.Add(wksTemp, nCol, strRange);
				}
			}
		}
	}
	
	int nPlot = gl.AddPlot(drSubRange, nPlotType, nCntrl);
	return nPlot;
}
///end SET_W_AS_ED_OF_DATARANGE_AND_PLOT_ERROR_BAR
*/
///END MOVE_TO_ANALYSIS_UTILS

/// ML 10/2/2006 NLFIT_CURVES_CLEANUP
// virtual
int		FitNL::PlotInputData(DataRange &rngInput, const TreeNode& trOp, GraphLayer& gl, int index, int nPlotType, int iIndep, int iDep)
{
	DataRange	dpRange;
	///Arvin 10/25/06 ORIGINAL_DATA_SCATTER_UNSHOW
	int nNumX = GetNumX(trOp);
	int nNumY = GetNumY(trOp);
	if(nNumX == 1 && nNumY == 1)
	{
		iDep = 0;
		iIndep = 0;
	}
	///end ORIGINAL_DATA_SCATTER_UNSHOW
	///Arvin 11/20/06 SURFACE_FIT_SOURCE_DATA_PLOT
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
	//if(!HasZ(trOp))
	if(GetFitType(trOp) == NLFIT_GENERAL_XY_FITTING)
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	{
	///-----
		if ( !rngInput.GetNLFitSubRange(dpRange, DRR_NLFIT, index, iDep, iIndep) || !dpRange )
		{
			error_report("Error in adding Input data to report graph");
			return -1;
		
		}
	///Arvin 11/20/06 SURFACE_FIT_SOURCE_DATA_PLOT
	}
	else
	{
		DWORD dwRules = DRR_GET_Z_DEPENDENT | DRR_GET_DEPENDENT | DRR_NO_FACTORS; 
		//Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
		DataRange drSrcRange;
		drSrcRange = rngInput;
		//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
		//if(GetFitType(trOp) == NLFIT_MATRIX_FITTING)
		if ( m_pFitSession && GetFitType(trOp) == NLFIT_MATRIX_FITTING )
		//------
			drSrcRange = GetFitSession()->GetSrcDataRange();
		
		if(!drSrcRange.GetSubRange(dpRange, dwRules, index) || !dpRange)
		//if(!rngInput.GetSubRange(dpRange, dwRules, index) || !dpRange)
		///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
		{
			error_report("Error in adding Input data to report graph");
			return -1;
		}
		//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
		//nPlotType = ID_3D_GRAPH_SCATTER;
		//------
		
		//uint nCntrl = GAP_USE_TEMPLATE;
	}
	///end SURFACE_FIT_SOURCE_DATA_PLOT
	
	///Arvin 11/03/06 SET_W_AS_ED_OF_DATARANGE_AND_PLOT_ERROR_BAR
	//int			nPlot = gl.AddPlot(dpRange, nPlotType);
	//return nPlot;
	
	//Plot Input data with error bar
	//return plotDataRange(dpRange, gl, nPlotType);
	/// Iris 07/31/2007 FIX_DUPLICATE_PLOTS_IN_FITCURVE_REPORT_GRAPH_AFTER_CHANGE_PARAM
	uint nCntrl = GAP_GROUP_PLOTS | GAP_USE_TEMPLATE;
	/// Hong 03/25/09 QA80-12551 RESET_PLOT_ROW_RANGE_IF_USER_UPDATE_INPUT_DATARANGE_WHEN_CHANGE_PARAMETER
	//return plotDataRange(dpRange, gl, nPlotType, nCntrl);
	return plotDataRange(dpRange, gl, nPlotType, nCntrl, true, NULL, true);
	/// end RESET_PLOT_ROW_RANGE_IF_USER_UPDATE_INPUT_DATARANGE_WHEN_CHANGE_PARAMETER
	///end FIX_DUPLICATE_PLOTS_IN_FITCURVE_REPORT_GRAPH_AFTER_CHANGE_PARAM
	///end SET_W_AS_ED_OF_DATARANGE_AND_PLOT_ERROR_BAR
		
	
}
/// end NLFIT_CURVES_CLEANUP

///Iris 4/21/05 MAKEFITY_SUPPORT_MULTI_REGRESSION
//bool	FitNL::MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* psFitParameter)
bool	FitNL::MakeFitY(int index, TreeNode &trOp, const vector& vFitX, vector& vFitY, FitParameter* psFitParameter, const matrix& mMultiIndep, int nPeak)
{
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/*
	/// Iris 2/27/2007 v8.0570 SUPPORT_INDEP_FIT_MODE
	if( isSepFit(trOp) )
		index = 0;
	///end SUPPORT_INDEP_FIT_MODE
	*/
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//return m_pFitSession->GetFitY(vFitX, vFitY, index, nPeak);	
	return GetNLFCurvePointer()->GetFitY(vFitX, vFitY, GetFitSession()->GetNLParamsMngr(), index, nPeak);
	/// end FITNL_USING_NEW_NLFSESSION
}

//virtual 
bool 	FitNL::MakeFitY(TreeNode &trOp, const matrix& mFitXs, matrix& mFitYs, int index)
{
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//return m_pFitSession->GetFitY(mFitXs, mFitYs, index);	
	/// Hong 09/26/08 v8.0948 FIX_MULTI_DEPS_INDEPS_RUNTIME
	//return GetNLFCurvePointer()->GetFitY(mFitXs, mFitYs, GetFitSession()->GetNLParamsMngr(), index);
	return GetNLFCurvePointer()->GetFitY(mFitXs, mFitYs, GetFitSession()->GetNLParamsMngr(), index, GetNumY(trOp));
	/// end FIX_MULTI_DEPS_INDEPS_RUNTIME
	/// end FITNL_USING_NEW_NLFSESSION
}


//virtual
bool	FitNL::ShowDlg(TreeNode& trOperation, BOOL bChangeParams)
{	
	string strNLFitFile = "Originlab\\NLFitting";	
	///Jasmine 11/07/06 CHANGE_NLFIT_MODAL
	/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
	//if(bChangeParams)
	//bool			bModal = bChangeParams || IsSpecFit(trOperation);
	bool			bModal = true;
	
	/// YuI 11/09/06 SOME_REDESIGN_OF_NLFIT_FOR_MODAL
	InitFitSessionPointer(trOperation);
	/// SOME_REDESIGN_OF_NLFIT_FOR_MODAL
	
	///Cheney 2007-6-15 IF_CHANGE_PARAM_AND_XY_FITTING_NO_NEED_TO_DO_IT
	//move from constructGetOperationTreeBranches in NLFitSplitter
	GetFitSession()->SetFitType(trOperation.SpecInfo);
	///end IF_CHANGE_PARAM_AND_XY_FITTING_NO_NEED_TO_DO_IT
	
#ifdef NLFIT_MODLESS
	bModal = bChangeParams || IsSpecFit(trOperation);
#endif
	///End CHANGE_NLFIT_MODAL
	if(bModal)
	/// end INVOKING_OPERATION_FROM_XFUNCTION
	{
		PEVENT_GETN pfnGetN = GetNewEventFunction(); ///Joseph 01/30/06	ADD_OPERATION_ERRMSG_LINE
		
		NLFDLG_FUNC pfn = Project.FindFunction("NLFitBox", strNLFitFile);
		if( pfn )
		{
			//------Joseph 01/30/06	ADD_OPERATION_ERRMSG_LINE
			/*
			/// YuI 11/09/06 SOME_REDESIGN_OF_NLFIT_FOR_MODAL
			//	return pfn(trOperation, GetWindow(), NULL);
			return pfn(trOperation, GetFitSession(), GetWindow(), NULL);
			/// SOME_REDESIGN_OF_NLFIT_FOR_MODAL
			*/
			///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
			//return pfn(trOperation, GetFitSession(), GetWindow(), NULL, pfnGetN);
			return pfn(trOperation, m_trFDF, GetFitSession(), GetWindow(), NULL, pfnGetN);
			///end CLEAN_UP_FDF_TREE_LOAD
			//------End ADD_OPERATION_ERRMSG_LINE
		}
		
		return error_report("Failed to load NLFitBox");
	}
	//---- CPY 8/15/05 NLFIT_USE_MODLESS_DIALOG
	// create dialog and then return false, so framework can detroy temp op and return
	else
	{
		FUNC_INT_DWORD_LPVOID pfn = Project.FindFunction("NLFitting");
		if(pfn)
		{
			pfn(0,0,NULL);
		}
	}
	return false;// indicate modless dialog
	//-----
}

/// Iris 1/17/06 CLEANUP_NLFITSESSION_STRUCT
//virtual 
//bool FitNL::MakeFitXY(const TreeNode& trOp, const vector& vX, const vector& vY, int& nRow, int& nCol, vector& vFitX, vector& vFitY)
//{
	//vFitX = vX;
	//vFitY = vY;
	//return m_pFitSession->GetFitXY(vFitX, vFitY, nRow, nCol);	
//}
//
//bool	FitNL::MakeFitZ(const TreeNode &trOp, const vector& vFitX, const vector& vFitY, matrix& mat, int index)
//{
	//return m_pFitSession->GetFitZ(vFitX, vFitY, mat, index);
//}
///End CLEANUP_NLFITSESSION_STRUCT

void    FitNL::createSetupResultMatrix(matrix& matFit, const vector& vFitX, const vector& vFitY)
{
	string 		strPageName = _L("FittedResult");
	string 		strFittedSheet = _L("FittedData");
	//create matrx window
	MatrixPage 	mp;
	mp.Create(NLSF_3D_FITTING_GRAPH_TEMPLATE);
	mp.Rename(strPageName);
	
	//get and setup matrix layer
	MatrixLayer ml = mp.Layers(0);	
	if(!ml)
	{
		int nLayer = mp.AddLayer();
		ml = mp.Layers(nLayer);
		ml.SetName(strFittedSheet);
	}
	
	
	MatrixObject 	moFit;
	moFit = ml.MatrixObjects(0);
	//set size
	moFit.SetNumRows(matFit.GetNumRows());
	moFit.SetNumCols(matFit.GetNumCols());
	//set dimension for fitted data matrix object
	double 			dXMin, dYMin, dXMax, dYMax;	
	vFitX.GetMinMax(dXMin, dXMax);
	vFitY.GetMinMax(dYMin, dYMax);
	moFit.SetXY(dXMin, dYMin, dXMax, dYMax);
	
	//assign fit data
	Matrix& mat = moFit.GetDataObject();
	mat = matFit;
	
}
///Arvin 04/17/07 v8.0602 FIT_MATRIX_HISTOGRAM_PLOT
string	FitNL::GetOneResultCurvesTableTagName(int nGraphIndex)
{
	if(nGraphIndex == GRAPH_RESIDUALS_HISTOGRAM)
	{
		TreeNode trOp;
		GetTree(trOp);
		int nFitType = GetFitType(trOp);
		if(nFitType == NLFIT_MATRIX_FITTING)
			return STR_RESIDUALS_DATA_TABLE;
	}
	
	return FitterOperation::GetOneResultCurvesTableTagName(nGraphIndex);

}
///end FIT_MATRIX_HISTOGRAM_PLOT
///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
///Arvin 04/17/07 v8.0602 FIT_MATRIX_HISTOGRAM_PLOT
//bool 	FitNL::reportMATResidualData(TreeNode& trOp)
bool 	FitNL::reportMATResidualData(TreeNode& trOp, int index, int nTotalNumData)
///END FIT_MATRIX_HISTOGRAM_PLOT
{
	matrix matResidual;
	int nRows, nCols;
	double dXmin, dYmin, dXmax, dYmax;
	///Sophy 10/13/2008 QA80-12365 FIX_FAIL_TO_REPORT_RESIDUAL_IN_MATRIX_FIT
	//if(!GetFitSession()->GetMatResidualData(matResidual, nRows, nCols, dXmin, dYmin, dXmax, dYmax))
	///Sophy 3/3/2009 v8.0990 FIX_RUNTIME_ERROR_WHEN_USE_CHEBYSHEV2D_AS_FUNCTION_IN_MATRIX_FITTING
	//if(!GetNLFCurvePointer()->GetMatResidualData(matResidual, nRows, nCols, dXmin, dYmin, dXmax, dYmax))
	if(!GetNLFCurvePointer()->GetResidualData(matResidual, GetFitSession()->GetDataObject(), GetFitSession()->GetNLParamsMngr(), nRows, nCols, dXmin, dYmin, dXmax, dYmax))
	///end FIX_RUNTIME_ERROR_WHEN_USE_CHEBYSHEV2D_AS_FUNCTION_IN_MATRIX_FITTING
	///end FIX_FAIL_TO_REPORT_RESIDUAL_IN_MATRIX_FIT
		return false;
	
	string strDataLabel;
	//int index = 0; ///Arvin 04/17/07 v8.0602 FIT_MATRIX_HISTOGRAM_PLOT
	GetEscapedMainDataString(trOp, strDataLabel, index + 1);
	
	TreeNode	trRC =
		CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_RESIDUALS_SCATTER, GetOneResultCurvesTableTagName(GRAPH_RESIDUALS_SCATTER), IDST_FIT_RESIDUALS_SCATTER, "Residuals", strDataLabel);
	
	trRC.dVals2 = matResidual;
	string strXY;
	strXY.Format("Row=%d;Col=%d;XMin=%f;XMax=%f;YMin=%f;YMax=%f;", nRows, nCols, dXmin, dXmax, dYmin, dYmax);
	trRC.SetAttribute(STR_XYMAP_ATTRIB, strXY);

	return true;
}
///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG

/// Iris 11/17/05 REPORT_FITTED_MATRIX_DATA_TO_EACH_MATRIXOBJECT
///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
//bool 	FitNL::reportResidualData(TreeNode& trOp, int index, int nTotalNumData)
bool 	FitNL::reportXYZResidualData(TreeNode& trOp, int index, int nTotalNumData)
///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
{	
	vector 	vX, vY, vZ, vFitZ, vResidual;
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//if( !m_pFitSession->GetResidualData(vResidual, index, vX, vY, vZ, vFitZ))
	if( !GetNLFCurvePointer()->GetResidualData(vResidual, GetFitSession()->GetDataObject(), GetFitSession()->GetNLParamsMngr(), index, vX, vY, vZ, vFitZ))
	/// end FITNL_USING_NEW_NLFSESSION
		return false;
	
	string strDataLabel;	
	GetEscapedMainDataString(trOp, strDataLabel, index + 1);
	
	string	strReportColLabel(strDataLabel);
	///------ Folger 03/24/09 QA80-13331-P1 CUSTOMIZED_OUTPUT_COLUMN_LONGNAME_FORMAT_SUPPORT
	//ConvertEscapedString(strReportColLabel);
	MakeFullRangeEscapeString(strReportColLabel);
	///------ End CUSTOMIZED_OUTPUT_COLUMN_LONGNAME_FORMAT_SUPPORT
	/// Iris 3/23/2009 QA80-13331-P1 CENTRILIZE_REPORT_COL_LABEL_CODES
	//strReportColLabel = _L("Residual of") + " " + strReportColLabel;
	strReportColLabel = ConstructReportDataColLabel(_L("Residual"), strReportColLabel);
	///end CENTRILIZE_REPORT_COL_LABEL_CODES
	
	//add X, Y columns into report table
	int			nSubTableID = IDST_REPORT_RESIDUAL_FIT_ONE_SET;
	string		strMainTableLabel = GetResultCurveMainTableLabel(trOp, index, strDataLabel);
	//--- Iris 3/27/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	//AddGraphDataOneTable(trOp, index, nTotalNumData, strMainTableLabel, GetOneResultCurvesTableTagName(GRAPH_RESIDUALS_SCATTER), _L("Residuals"), _L("Residual"), IDST_FIT_RESIDUALS_SCATTER/*IDST_FIT_RESIDUALS_DATA*/, nSubTableID, vX, "X", vY, "Y", GRAPH_RESIDUALS_SCATTER);///Arvin 10/30/06 NLFIT_SURFACE_HISTOGRAM_PLOT
	string		strTableLabel = GetResidualDataTableLabel();
	int 		nGraphIndex = GRAPH_RESIDUALS_SCATTER;
	/// Iris 6/16/2009 QA80-13776-P2 FIX_FAIL_CREATE_X_Y_COL_IN_RESIDUAL_DATA_TABLE
	//AddGraphDataOneTable(trOp, index, nTotalNumData, strMainTableLabel, GetOneResultCurvesTableTagName(nGraphIndex), strTableLabel, GetResidualDataTableYDataSubLabel(), IDST_FIT_RESIDUALS_SCATTER/*IDST_FIT_RESIDUALS_DATA*/, nSubTableID, vX, "X", vY, "Y", GRAPH_RESIDUALS_SCATTER);///Arvin 10/30/06 NLFIT_SURFACE_HISTOGRAM_PLOT
	///end FIX_FAIL_CREATE_X_Y_COL_IN_RESIDUAL_DATA_TABLE
	//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	
	//add Z, FitZ, Residual into report table
	string strTableSubLabel;
	GetCustomGraphTypeName(strTableSubLabel, nGraphIndex);
	
	TreeNode	trTable = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_RESIDUALS_SCATTER, GetOneResultCurvesTableTagName(GRAPH_RESIDUALS_SCATTER), /*IDST_FIT_RESIDUALS_DATA*/IDST_FIT_RESIDUALS_SCATTER);///Arvin 10/30/06 NLFIT_SURFACE_HISTOGRAM_PLOT
	if(trTable)
	{
		//--- Iris 3/27/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
		/*
		TreeNode  	trRow;
		trRow = tree_check_get_node(trTable, "Z", IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, "Z");
		trRow.dVals = vZ;
		trRow.ID = make_one_set_ID(nSubTableID+3, index);
		//trRow.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Z);
		
		trRow = tree_check_get_node(trTable, "FitZ", IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, _L("Fit Z"));
		trRow.dVals = vFitZ;
		trRow.ID = make_one_set_ID(nSubTableID+4, index);	
		//trRow.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Z);
		
		trRow = tree_check_get_node(trTable, "Residual", IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, strReportColLabel);
		trRow.dVals = vResidual;
		trRow.ID = make_one_set_ID(nSubTableID+5, index);	
		trRow.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Z);
		*/
		/// Iris 6/11/2009 QA80-13776 FIX_XYZFIT_APPEND_RESIDUAL_DATA_AFTER_RECALCULATE
		/*
		AddOneColToResultCurveTable(trTable, vZ, strTableSubLabel, _L("Z"), nSubTableID, trTable.GetNodeCount(), OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vFitZ, strTableSubLabel, _L("Fit Z"), nSubTableID, trTable.GetNodeCount(), OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vResidual, strTableSubLabel, strReportColLabel, nSubTableID, trTable.GetNodeCount(), OKDATAOBJ_DESIGNATION_Z);
		*/
		/// Iris 6/16/2009 QA80-13776-P2 FIX_FAIL_CREATE_X_Y_COL_IN_RESIDUAL_DATA_TABLE
		/*
		AddOneColToResultCurveTable(trTable, vZ, strTableSubLabel, _L("Z"), nSubTableID, 0, OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vFitZ, strTableSubLabel, _L("Fit Z"), nSubTableID, 1, OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vResidual, strTableSubLabel, strReportColLabel, nSubTableID, 2, OKDATAOBJ_DESIGNATION_Z);	
		*/
		///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
#ifndef	__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__
		///end FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
		int index=0;
		AddOneColToResultCurveTable(trTable, vX, strTableSubLabel, _L("X"), nSubTableID, index++, OKDATAOBJ_DESIGNATION_X);
		AddOneColToResultCurveTable(trTable, vY, strTableSubLabel, _L("Y"), nSubTableID, index++, OKDATAOBJ_DESIGNATION_Y);	
		AddOneColToResultCurveTable(trTable, vZ, strTableSubLabel, _L("Z"), nSubTableID, index++, OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vFitZ, strTableSubLabel, _L("Fit Z"), nSubTableID, index++, OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vResidual, strTableSubLabel, strReportColLabel, nSubTableID, index++, OKDATAOBJ_DESIGNATION_Z);	
		///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING		
#else
		int nColIndex = 0;
		TreeNode trColX = AddOneColToResultCurveTable(trTable, vX, strTableSubLabel, _L("X"), nSubTableID, nColIndex++, OKDATAOBJ_DESIGNATION_X);
		UpdateOneXColumnFormat(trColX, index);
		
		TreeNode trColY = AddOneColToResultCurveTable(trTable, vY, strTableSubLabel, _L("Y"), nSubTableID, nColIndex++, OKDATAOBJ_DESIGNATION_Y);	
		UpdateOneYColumnFormat(trColY, index);
		
		AddOneColToResultCurveTable(trTable, vZ, strTableSubLabel, _L("Z"), nSubTableID, nColIndex++, OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vFitZ, strTableSubLabel, _L("Fit Z"), nSubTableID, nColIndex++, OKDATAOBJ_DESIGNATION_NONE);
		AddOneColToResultCurveTable(trTable, vResidual, strTableSubLabel, strReportColLabel, nSubTableID, nColIndex++, OKDATAOBJ_DESIGNATION_Z);	
#endif	//__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__
		///end FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
		///end FIX_FAIL_CREATE_X_Y_COL_IN_RESIDUAL_DATA_TABLE
		///end FIX_XYZFIT_APPEND_RESIDUAL_DATA_AFTER_RECALCULATE
		//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	}
	
	//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	// The following codes existed duplicate logic with FitterOperation::AddResidualTables, and now not support these residual plots in XYZ fit, so comment out.
	/*
	///Arvin 04/24/07 v8.0607 SURFACE_FIT_RESIDUAL_DATA_PLOTS
	bool		bResHist = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_HISTOGRAM);
	bool		bResFit = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_VERSUS_FITS_PLOT);
	bool		bResOrder = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_VERSUS_ORDER_PLOT);
	bool		bResLag = GUIHasResidualTable(trOp, GRAPH_RESIDUALS_LAG_PLOT);
	
	if (bResHist)
		AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_HISTOGRAM_TABLE, _L("Residuals"),
				_L("Histogram of the Residual"), IDST_FIT_RESIDUALS_DATA, IDST_REPORT_RESIDUAL_HISTOGRAM_ONE_SET, NULL, NULL, vResidual, strReportColLabel, GRAPH_RESIDUALS_HISTOGRAM, false);
	
	if (bResFit)
		AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_FIT_GRAPH_TABLE, _L("Residuals"), _L("Residuals vs. Predicted Values"), IDST_FIT_RESIDUALS_VERSUS_FITS_DATA,
			IDST_REPORT_RESIDUAL_FIT_ONE_SET, vFitZ, _L("Fitted Z"), vResidual, strReportColLabel, GRAPH_RESIDUALS_VERSUS_FITS_PLOT, false);
				
	if (bResOrder)
	{
		vector vRowNum;
		vRowNum.Data(1, vResidual.GetSize(), 1);
		AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_ORDER_GRAPH_TABLE, _L("Residuals"), _L("Residuals vs. the Order of the Data"), IDST_FIT_RESIDUALS_VERSUS_ORDER_DATA,
			IDST_REPORT_RESIDUAL_ORDER_ONE_SET, vRowNum, _L("Order"), vResidual, strReportColLabel, GRAPH_RESIDUALS_VERSUS_ORDER_PLOT, false);
	}
	
	if (bResLag)
	{
		vector 	vReX;
		vReX = vResidual;
		vReX.RemoveAt(vReX.GetSize()-1);
		vResidual.RemoveAt(0);
			
		AddGraphDataOneTable(trOp, index, nTotalNumData, strDataLabel, STR_RESIDUALS_LAG_GRAPH_TABLE, _L("Residuals"), _L("Residuals Lag Plot"), IDST_FIT_RESIDUALS_LAG_DATA,
			IDST_REPORT_RESIDUAL_LAG_ONE_SET, vReX, _L("Residual(I-1)"), vResidual, strReportColLabel, GRAPH_RESIDUALS_LAG_PLOT, false);
	}
	///end SURFACE_FIT_RESIDUAL_DATA_PLOTS
	*/
	//---end SURFACE_FIT_RESIDUAL_DATA_PLOTS
	
	return true;
}
///End REPORT_FITTED_MATRIX_DATA_TO_EACH_MATRIXOBJECT
///Arvin 12/07/06 IMPROVE_SURFACE_FIT_RESIDUAL_CONTOUR
bool FitNL::UpdateResidualContourLevels(GraphLayer& gl, int index)
{
	if( !GetFitSession()->UpdateResidualContourLevels(gl)) //only one dataset for surface fitting
		return false;
	
	gl.Rescale();
	return true;
}

bool FitNL::SetupPlotDetails(const TreeNode& trOp, GraphLayer& gl, int nFittedPlot, int nNumPlots, int nGraphIndex, int nDataIndex, bool bIsSourceGraph, bool bUpdateExistedReportGraph) 
{
	if(!FitterOperation::SetupPlotDetails(trOp, gl, nFittedPlot, nNumPlots, nGraphIndex, nDataIndex, bIsSourceGraph, bUpdateExistedReportGraph)) 
		return false;
	//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
	/*
	/// Iris 08/10/2007 QA70-10073 TO_KEEP_CUSTOMIC_SETTINGS_IN_REPORT_GRAPH
	//if(HasZ(trOp) && nGraphIndex == GRAPH_RESIDUALS_SCATTER)
	if(HasZ(trOp) && nGraphIndex == GRAPH_RESIDUALS_SCATTER && !bUpdateExistedReportGraph)
	///end TO_KEEP_CUSTOMIC_SETTINGS_IN_REPORT_GRAPH
		return UpdateResidualContourLevels(gl);
	*/
	//------
	return true;
}

int	FitNL::ReportGraphGetRescaleOption(TreeNode& trOp, int nGraphIndex)
{
	//We should rescale residual contour plot in the function SetupPlotDetails
	//so, we needn't rescale it there. 
	if(HasZ(trOp) && nGraphIndex == GRAPH_RESIDUALS_SCATTER)
		return -1;
	
	return FitterOperation::ReportGraphGetRescaleOption(trOp, nGraphIndex);
}
///end IMPROVE_SURFACE_FIT_RESIDUAL_CONTOUR

string  FitNL::getXYMapInfo(const vector& vFitX, const vector& vFitY, int nRow, int nCol)
{
	string strXY;
	double Xmin, Xmax, Ymin, Ymax;
	vFitX.GetMinMax(Xmin, Xmax);
	vFitY.GetMinMax(Ymin, Ymax);
	strXY.Format("Row=%d;Col=%d;XMin=%f;XMax=%f;YMin=%f;YMax=%f;", nRow, nCol, Xmin, Xmax, Ymin, Ymax);
	
	return strXY;
}

///Arvin 12/11/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
bool FitNL::GetAllTypeResidualData(const TreeNode &trOp, const vector& vX, const vector& vRegularRes, vector& vStand, vector& vStud, vector& vStudDel, int index, int nPeak, vector &vY, vector &vWeights, matrix &mXs)
{
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/*
	/// Iris 3/08/2007 v8.0577 SUPPORT_INDEP_FIT_MODE
	if( isSepFit(trOp) )
		index = 0;
	///end SUPPORT_INDEP_FIT_MODE
	*/
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT

	if(m_pFitSession && m_pFitSession->GetDifferentTypeResidualDatas(trOp, vX, vRegularRes, vStand, vStud, vStudDel, index, nPeak))
		return true;
	
	return false;
}
///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING

/// Hong 01/24/08 QA80-10929 LT_NLFIT_SUPPORT_SOUURCE_GRAPHPAGE_PREVIEW
// virtual
bool FitNL::EnableSourceGraphPreview()
{
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	/*
	if ( !m_pFitSession )
		return false;
	
	Tree trOp;
	GetTree(trOp);	
	TreeNode trPreview = trOp.GUI.Preview;
	if ( !trPreview || 0 == trOp.GUI.Preview.nVal || !m_pFitSession->IsAllSrcDataFromGraph() )
		return false;
		
	GraphPage gp = m_pFitSession->GetSrcGraphPage();
	if ( !gp )
		return false;
	
	m_pFitSession->SetFitPreviewGraph(gp, PREVIEW_EXTERNAL_DATA_FIT);
	m_pFitSession->UpdateFitSessionPreviewData();
	m_pFitSession->UpdatePreviewGraph(FITPREVIEW_INIT);
	return true;
	*/
	return false; // should NOT be used any more
	/// end FITNL_USING_NEW_NLFSESSION
}
/// end LT_NLFIT_SUPPORT_SOUURCE_GRAPHPAGE_PREVIEW

///Arvin 12/04/06 ADD_CONF_PRED_BANDS_FOR_MR
//bool	FitNL::ConstructCurvesAndGraphs(TreeNode &trOp, int index, int nTotalNumData,LPCSTR strDataLabel, vector &vX, vector & vY, matrix &mXs, FitParameter *psFitParameter, RegStats *psRegStats, RegCalcInternal *psReg, DWORD dwPlotObjUID, int nMultiplicity, matrix& mYs)
///Arvin 12/12/06 ADD_RESIDUAL_ANALYSIS_FOR_FITTING
//bool	FitNL::ConstructCurvesAndGraphs(TreeNode &trOp, int index, int nTotalNumData,LPCSTR strDataLabel, vector &vX, vector & vY, matrix &mXs, FitParameter *psFitParameter, RegStats *psRegStats, RegCalcInternal *psReg, DWORD dwPlotObjUID, int nMultiplicity, matrix& mYs, vector& vSerr)
///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
//bool	FitNL::ConstructCurvesAndGraphs(TreeNode &trOp, int index, int nTotalNumData,LPCSTR strDataLabel, vector &vX, vector & vY, matrix &mXs, FitParameter *psFitParameter, RegStats *psRegStats, RegCalcInternal *psReg, DWORD dwPlotObjUID, int nMultiplicity, matrix& mYs, vector& vSerr, vector& vWeights)
bool	FitNL::ConstructCurvesAndGraphs(TreeNode &trOp, int index, int nTotalNumData,LPCSTR strDataLabel, vector &vX, vector & vY, matrix &mXs, FitParameter *psFitParameter, RegStats *psRegStats, RegCalcInternal *psReg, DWORD dwPlotObjUID, int nMultiplicity, matrix& mYs, vector& vSerr, vector& vWeights, LPCSTR lpcsDataLabelCurves)
///end CENTRALIZE_FITTING_RESULT_LABELS
///end ADD_RESIDUAL_ANALYSIS_FOR_FITTING
///end ADD_CONF_PRED_BANDS_FOR_MR
{
	/// Iris 5/15/06 v8.0410 CLEANUP_ISXYZDATA_CODES
	/////Iris 12/12/05 MOVE_NLF_TO_UTILS_FILE
	////bool 	bIsXYZData = op_is_3d_function(trOp);
	//bool 	bIsXYZData = nlf_is_3d_function(trOp);
	/////End MOVE_NLF_TO_UTILS_FILE
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
	//bool 	bIsXYZData = HasZ(trOp);
	int nFitType = GetFitType(trOp);
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	///End CLEANUP_ISXYZDATA_CODES	
	
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
	//if( !bIsXYZData )
	if(nFitType == NLFIT_GENERAL_XY_FITTING)
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
		//return FitterOperation::ConstructCurvesAndGraphs(trOp, index, nTotalNumData, strDataLabel, vX, vY, mXs, psFitParameter, psRegStats, psReg, dwPlotObjUID, nMultiplicity, mYs);
		return FitterOperation::ConstructCurvesAndGraphs(trOp, index, nTotalNumData, strDataLabel, vX, vY, mXs, psFitParameter, psRegStats, psReg, dwPlotObjUID, nMultiplicity, mYs, NULL, NULL, lpcsDataLabelCurves);
	///end CENTRALIZE_FITTING_RESULT_LABELS
	
	/// Iris 1/17/06 CLEANUP_NLFITSESSION_STRUCT
	////get X and Y for fitting
	//int 	nRow, nCol;
	//vector 	vFitX, vFitY;
	//MakeFitXY(trOp, vX, vY, nRow, nCol, vFitX, vFitY);	
	//
	////Do fitting
	//matrix 	matFit(nRow, nCol);
	//MakeFitZ(trOp, vFitX, vFitY, matFit, index);	
	vector	vFitX, vFitY;
	vFitX = vX;
	vFitY = vY;	
	matrix	matFit;
	int		nRows, nCols;
	
	//------ Folger 03/12/08 QA80-11244 SHOULD_NOT_OUTPUT_DATA_TO_MATRIX_FOR_XYZ_FITTING
	vector	vFitZ;
	
	if ( nFitType == NLFIT_MATRIX_FITTING )
	{
	//------
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		/* copy code from new FitNL, Hong, to do, check if should only call GetFit
		if( !m_pFitSession->GetFit(vFitX, vFitY, matFit, nRows, nCols))
			return error_report("Fail to do fitting for xyz data in FitNL::ConstructCurvesAndGraphs\n");
		*/
		/// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
		//if( !m_pFitSession->GetFitZ(vFitX, vFitY, matFit, nRows, nCols))
		if( GetNLFCurvePointer()->GetFitXY(vFitX, vFitY, true, true, &nRows, &nCols) ) 	
		{
			matFit.SetSize(nRows, nCols);
			if( !GetNLFCurvePointer()->GetFitZ(vFitX, vFitY, matFit, GetFitSession()->GetNLParamsMngr(), index) )		
		///end REMOVE_NLFCURVE_FROM_NLSESSION
				return error_report("Fail to do fitting for xyz data in FitNL::ConstructCurvesAndGraphs\n");
		}
		/// end FITNL_USING_NEW_NLFSESSION
	//------ Folger 03/12/08 QA80-11244 SHOULD_NOT_OUTPUT_DATA_TO_MATRIX_FOR_XYZ_FITTING
	}
	else
	{
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		/* copy code from new FitNL, Hong, to do, check if should only call GetFit
		//if( !m_pFitSession->GetFitZ(vFitX, vFitY, vFitZ))		///Jasmine 05/27/08 QA80-11234 v8.0871 USE_GETFIT_TO_GENERATE_XY_ACCORDING_NUM_OF_POINT
		if( !m_pFitSession->GetFit(vFitX, vFitY, vFitZ))
			return error_report("Fail to do fitting for xyz data in FitNL::ConstructCurvesAndGraphs\n");
		*/
		/// Iris NLF_81, REMOVE_NLFCURVE_FROM_NLSESSION
		//if( !m_pFitSession->GetFitZ(vFitX, vFitY, vFitZ))
		///Sophy 11/19/2008 v8.975b QA80-12613-P1 KEEP_OLD_LOGIC_SHOULD_FIT_XY_BEFORE_FIT_Z
		if( !GetNLFCurvePointer()->GetFitXY(vFitX, vFitY, true, true))
			return error_report("Fail to do fitting for xyz data in FitNL::ConstructCurvesAndGraphs\n");
		///end KEEP_OLD_LOGIC_SHOULD_FIT_XY_BEFORE_FIT_Z
		if( !GetNLFCurvePointer()->GetFitZ(vFitX, vFitY, vFitZ, GetFitSession()->GetNLParamsMngr(), index) )
		///end REMOVE_NLFCURVE_FROM_NLSESSION
			return error_report("Fail to do fitting for xyz data in FitNL::ConstructCurvesAndGraphs\n");
		/// end FITNL_USING_NEW_NLFSESSION
	}
	//------
	
	///End CLEANUP_NLFITSESSION_STRUCT

	//Calculate LCL, UCL
	//...
	
	//Calculate LPI, UPI
	//...
	
	//Generate fitted result output tree
	//---- CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET	
	/*
	TreeNode	trOut = trOp.Calculation;	
	string 		strPrefix = nTotalNumData > 1? CALCULATION_FIT_CURVES_PREFIX : "";
	int 		nSingleTable = GetTableStringDatasets();
	
	TreeNode	trFC = GetSubReportNode(FIT_CURVES_BRANCH(trOut), index, IDST_REPORT_FITDATA_ONE_SET, strDataLabel, strPrefix, nSingleTable);	
	*/
	
	//--- Iris 3/16/2009 QA80-13285-P2 CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	/*
	string 		strTableLabel;
	GetCustomGraphTypeName(strTableLabel, GRAPH_FIT_CURVE);
	///Arvin 06/07/07 CENTRALIZE_FITTING_RESULT_LABELS as max's suggestion
	//TreeNode	trFC = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_FIT_CURVE, STR_FIT_CURVES_TABLE, IDST_FIT_CURVES, strTableLabel, strDataLabel);
	TreeNode	trFC = CheckCreateOneResultCurvesTable(trOp, index, nTotalNumData, GRAPH_FIT_CURVE, STR_FIT_CURVES_TABLE, IDST_FIT_CURVES, strTableLabel, lpcsDataLabelCurves);
	///end CENTRALIZE_FITTING_RESULT_LABELS
	//-----
	*/
	TreeNode	trFC = CheckCreateOneFitCurvesTable(trOp, index, nTotalNumData);
	//---end CLEANUP_FIT_TOOLS_REPORT_DATA_COLUMN_LABELS
	
	//TreeNode 	trFittedData = tree_check_get_node(trFC, "FittedData", make_one_set_ID(IDST_REPORT_MATRIX_FITDATA, index), STR_LABEL_ATTRIB, "Fitted Data");
	/// Iris 9/06/06 SURFACE_FIT_REPORT_MAT_FIT_DATA
	//*****keep fitting data treenode empty temporary since will set columns to XY format for this matrix now******
	
	//------ Folger 03/12/08 QA80-11244 SHOULD_NOT_OUTPUT_DATA_TO_MATRIX_FOR_XYZ_FITTING
	/*
	trFC.dVals2 = matFit;
	trFC.SetAttribute(STR_XYMAP_ATTRIB, getXYMapInfo(vFitX, vFitY, nRows, nCols));
		
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
	if(nFitType == NLFIT_MATRIX_FITTING)
		///Arvin 04/17/07 v8.0602 FIT_MATRIX_HISTOGRAM_PLOT
		//reportMATResidualData(trOp);
		reportMATResidualData(trOp, index, nTotalNumData);
		///END FIT_MATRIX_HISTOGRAM_PLOT
	else
		reportXYZResidualData(trOp, index, nTotalNumData);
		//reportResidualData(trOp, index, nTotalNumData);
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	
	///Cheney 2007-9-7 SHOULD_JUST_SET_SHOW_AS_FALSE_IF_NOT_CHECK_PLOT_FIT_CURVE
	int nReportFitCurve = 0;
	TreeNode trFittedCurve = GetGUIGraphNodes(trOp);
	trFittedCurve.GetAttribute( STR_USE_ATTRIB, nReportFitCurve);
	if(!nReportFitCurve)
		trFC.Show = false;
	///end SHOULD_JUST_SET_SHOW_AS_FALSE_IF_NOT_CHECK_PLOT_FIT_CURVE
	*/
	
	if(nFitType == NLFIT_MATRIX_FITTING)
	{
		trFC.dVals2 = matFit;
		trFC.SetAttribute(STR_XYMAP_ATTRIB, getXYMapInfo(vFitX, vFitY, nRows, nCols));
		//reportMATResidualData(trOp, index, nTotalNumData); 	/// Iris 7/23/2009 QA80-14000-P1 2D_FIT_NOT_PLOT_RESIDUAL_CAUSE_FIT_DATA_ERROR
	}
	else
	{
		TreeNode	trFitX = tree_check_get_node(trFC, "FitX", IDST_FIT_X, STR_LABEL_ATTRIB, "FitX");
#ifdef	__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__
			UpdateOneXColumnFormat(trFitX, index);	///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
#endif	//__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__
			TreeNode	trFitY = tree_check_get_node(trFC, "FitY", IDST_FIT_Y, STR_LABEL_ATTRIB, "FitY");
#ifdef	__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__
			UpdateOneYColumnFormat(trFitY, index);	///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
#endif	//__UPDATE_REPORT_COLUMN_FORMAT_IN_3D_FITTING__
		
		TreeNode	trFitZ = tree_check_get_node(trFC, "FitZ", IDST_FIT_Z, STR_LABEL_ATTRIB, "FitZ");
		
		trFitX.dVals = vFitX;
		trFitY.dVals = vFitY;
		trFitZ.dVals = vFitZ;
		/// Iris 1/07/2010 FIX_NO_FIT_CURVE_PLOT_IN_FIT_CURVE_GRAPH_IN_SURFACE_REPORT
		trFitX.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_X);		
		trFitY.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
		///End FIX_NO_FIT_CURVE_PLOT_IN_FIT_CURVE_GRAPH_IN_SURFACE_REPORT
		trFitZ.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Z);		
		//reportXYZResidualData(trOp, index, nTotalNumData); /// Iris 7/23/2009 QA80-14000-P1 2D_FIT_NOT_PLOT_RESIDUAL_CAUSE_FIT_DATA_ERROR
	}	
	//------ End SHOULD_NOT_OUTPUT_DATA_TO_MATRIX_FOR_XYZ_FITTING
		
	/// Iris 7/23/2009 QA80-14000-P2 2D_FIT_FITTED_DATA_ALWAYS_REPORT_EVEN_UNCHECKED
	TreeNode trFitCurveGraph = GetGUIGraphNodes(trOp, GRAPH_FIT_CURVE);
	ASSERT( trFitCurveGraph );
	if( trFitCurveGraph )
	{
		trFC.Show = tree_is_true(trFitCurveGraph);
	}
	///end 2D_FIT_FITTED_DATA_ALWAYS_REPORT_EVEN_UNCHECKED

	
	/// Iris 7/23/2009 QA80-14000-P1 2D_FIT_NOT_PLOT_RESIDUAL_CAUSE_FIT_DATA_ERROR
	if( IsOutputAnyTypeResidualGraph(trOp) )
	{
		if(nFitType == NLFIT_MATRIX_FITTING)
			reportMATResidualData(trOp, index, nTotalNumData);
		else
			reportXYZResidualData(trOp, index, nTotalNumData);
	}
	///END 2D_FIT_NOT_PLOT_RESIDUAL_CAUSE_FIT_DATA_ERROR
	
	////*****put fitted data into matrix window to check result temporary!******
	///// Iris 11/02/05 QA70-8135-P6 NOT_SHOW_SURFACE_FITTED_DATA
	///// Iris 11/17/05 REPORT_FITTED_MATRIX_DATA_TO_EACH_MATRIXOBJECT
	//vector	vx, vy, xz;
	//try
	//{
		//createSetupResultMatrix(matFit, vFitX, vFitY);
		//reportResidualData(trOp, index, nTotalNumData);		
	//}
	//catch(int nErr)
	//{
		//return false;
	//}
	/////End REPORT_FITTED_MATRIX_DATA_TO_EACH_MATRIXOBJECT
	/////End NOT_SHOW_SURFACE_FITTED_DATA
	
	///end SURFACE_FIT_REPORT_MAT_FIT_DATA
	
	/// Iris 01/08/2007 v8.0538 REPORT_GRAPHS_ARRANGEMENT, moved it to WksOpeatioin.c
	//PrepareGraphNodes(trOp, GetNumGraphs(), index, strDataLabel); 
	///end REPORT_GRAPHS_ARRANGEMENT

	/// Iris 9/06/06 SURFACE_FIT_REPORT_MAT_FIT_DATA
	///// Iris 7/25/05 GRAPH_TABLE_TEMP_SOLUTION_FOR_XYZ_DATA
	////hide all graphs table for XYZ input data
	//TreeNodeCollection trColl(trOp.Calculation, "Graph");
	//foreach(TreeNode trN in trColl)
		//trN.Show = 0;
	/////end GRAPH_TABLE_TEMP_SOLUTION_FOR_XYZ_DATA
	///end SURFACE_FIT_REPORT_MAT_FIT_DATA
	
	return true;
}

/// Iris 9/11/06 SURFACE_FIT_REPORT_MAT_FIT_DATA
//virtual 
bool 	FitNL::IsSourceDataPlotInReport(int nGraphIndex)  
{
	TreeNode 	trOp;
	GetTree(trOp);
	///Arvin 11/20/06 SURFACE_FIT_SOURCE_DATA_PLOT
	//if( HasZ(trOp) )
	//	return true;
	//else
	///end SURFACE_FIT_SOURCE_DATA_PLOT
	///Arvin 04/17/07 v8.0602 FIT_MATRIX_DOES_NOT_PLOT_SOURCE_DATA
	int nFitType = GetFitType(trOp);
	if(nFitType == NLFIT_MATRIX_FITTING)
		return true;
	///end FIT_MATRIX_DOES_NOT_PLOT_SOURCE_DATA
	
	//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
	if ( nFitType == NLFIT_XYZ_FITTING )
		return true;
	//------
	
	return FitterOperation::IsSourceDataPlotInReport(nGraphIndex);
}


int 	FitNL::ReportGetPlotTypeFromGraphIndex(int nGraphIndex)
{
	/// Iris 5/15/06 v8.0410 CLEANUP_ISXYZDATA_CODES, m_pFitSession is NULL when double click report graph, this will cause crash.
	//bool 		bIsXYZData = m_pFitSession->IsXYZData(); 
	TreeNode 	trOp;
	GetTree(trOp);
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
	//bool 		bIsXYZData = HasZ(trOp);
	int nFitType = GetFitType(trOp);
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	///End CLEANUP_ISXYZDATA_CODES
	///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
	//if(bIsXYZData)
	if(nFitType != NLFIT_GENERAL_XY_FITTING)
	///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
	{
		switch(nGraphIndex)
		{
		case GRAPH_FIT_CURVE:
			//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
			//return IDM_PLOT_SURFACE_WIREFRAME;
			
			//------ Folger 03/18/08 QA80-11260 FIX_RUNTIME_ERROR_IN_MATRIX_FITTING_PREVIEW_AND_REPORT_GRAPH
			//return IDM_PLOT_TRI_CONTOUR;
			return nFitType == NLFIT_XYZ_FITTING? IDM_PLOT_TRI_CONTOUR : IDM_PLOT_CONTOUR;
			//------
			
			//------
			break;
		case GRAPH_RESIDUALS_SCATTER:
			///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG	
			//return IDM_PLOT_TRI_CONTOUR;
			int nPlotType = nFitType == NLFIT_XYZ_FITTING? IDM_PLOT_TRI_CONTOUR : IDM_PLOT_CONTOUR;
			return nPlotType;
			///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
			break;
		default:
			break;			
		}
	}
	return FitterOperation::ReportGetPlotTypeFromGraphIndex(nGraphIndex);
}

//------ Folger 03/12/08 QA80-11244 SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS
//virtual
int	FitNL::GetDataSourcePlotType(int nGraphIndex)
{
	//------ Folger 03/18/08 QA80-11260 FIX_RUNTIME_ERROR_IN_MATRIX_FITTING_PREVIEW_AND_REPORT_GRAPH
	//return IDM_PLOT_TRI_CONTOUR;
	TreeNode 	trOp;
	GetTree(trOp);
	int nFitType = GetFitType(trOp);
	
	//------ Folger 03/19/08 QA80-11281 FIX_XY_FIT_CURVE_NOT_SHOW_SOURCE_PLOTS
	//return nFitType == NLFIT_XYZ_FITTING? IDM_PLOT_TRI_CONTOUR : IDM_PLOT_CONTOUR;
	switch ( nFitType )
	{
	case NLFIT_XYZ_FITTING:
		return IDM_PLOT_TRI_CONTOUR;
	case NLFIT_MATRIX_FITTING:
		return IDM_PLOT_CONTOUR;
	default:break;
	}
	return WksReportOperation::GetDataSourcePlotType(nGraphIndex);
	//------ End FIX_XY_FIT_CURVE_NOT_SHOW_SOURCE_PLOTS
	
	//------
}

bool	FitNL::SetupSourceDataPlot(BOOL bResiduleGraph, DataPlot &dp, vector *pZ, int nSteps)
{
	BOOL bGrayScaleSrcDataContour = bResiduleGraph;
	//------ CPY 3/31/08 ZERO_INC_FOUND_DURING_DEBUG_WITHOUT_BREAK_POINTS
	//return rescale_init_colormap(dp, &m_vContourLevelInfo, nSteps, bGrayScaleSrcDataContour);
	if(!rescale_init_colormap(dp, &m_vContourLevelInfo, nSteps, bGrayScaleSrcDataContour))
	{
		/// YuI 01/26/09 QA70-13023 MATRIX_FIT_IN_IMAGE_FORM_PROBLEMS
		//	ASSERT(m_vContourLevelInfo.GetSize()==3); // this should still be true regardless
		if( m_vContourLevelInfo.GetSize() < 3 )
		{
			ASSERT(FALSE);
			return false;
		}
		/// end MATRIX_FIT_IN_IMAGE_FORM_PROBLEMS
		// temp code to make some valid increment
		double dz = m_vContourLevelInfo[1] - m_vContourLevelInfo[0];
		if(100* m_vContourLevelInfo[2] < fabs(dz))
		{
			m_vContourLevelInfo[2] = dz/20;
			printf("Z inc is reset to %g\n", m_vContourLevelInfo[2]);
		}
	}
	return true;
	//-----
}

bool	FitNL::SetupFitCurvesPlot(DataPlot &dp, vector &vZ)
{
	///------ Folger 09/16/2010 ORG-1057-P1 MATRIX_FITTING_FAILED_TO_CLOSE_DIALOG_AFTER_FIT_WITH_EMPTY_DATA
	if ( m_vContourLevelInfo.GetSize() == 0 )
		return false;
	///------ End MATRIX_FITTING_FAILED_TO_CLOSE_DIALOG_AFTER_FIT_WITH_EMPTY_DATA
	
	m_vContourLevelInfo[2] *= FIT_CONTOUR_LEVEL_REDUCTION_FROM_DATA_LEVELS;
	return setup_fit_contour(dp, m_vContourLevelInfo);
}

bool	FitNL::SetupResidualPlot(DataPlot& dp, vector& zz, double irl, double orl, int nInnersteps, int nOutSteps)
{
	return setup_residual_contour(dp, m_vContourLevelInfo, irl, orl, nInnersteps, nOutSteps);
}

//virtual
bool	FitNL::SetupPlotsAfterRescale(GraphLayer &gl, int nGraphIndex)
{
	TreeNode trOp;
	GetTree(trOp);
	BOOL bFitCurveGraph = nGraphIndex == GRAPH_FIT_CURVE? true:false;
	if ( GetFitType(trOp) == NLFIT_XYZ_FITTING || GetFitType(trOp) == NLFIT_MATRIX_FITTING )
	{
		for ( int ii=0; ii<gl.DataPlots.Count(); ++ii )
		{
			DataPlot dp = gl.DataPlots(ii);
			if ( ii == NLFIT_XYZ_SOURCE_PLOT )
			{
				SetupSourceDataPlot(!bFitCurveGraph, dp);
			}
			else if ( ii == NLFIT_XYZ_RESULT_PLOT )
			{
				if ( bFitCurveGraph )
					SetupFitCurvesPlot(dp, NULL);
				else
				{
					ASSERT( nGraphIndex == GRAPH_RESIDUALS_SCATTER );
					
					/// Iris 7/29/2009 QA80-14029 FAIL_CHANGE_INNER_OUTTER_RESIDUAL_LIMIT_ON_CHANGE_PARAM
					/*
					TreeNode trGraph = GetGUIGraphNodes(trOp, nGraphIndex);
					double	dIrl = 5, dOrl = 30;		//hard code default value, need to define later, see SurfaceFitPreviewCtrl.h
					if ( trGraph )
					{
						if ( trGraph.Irl )
							dIrl = trGraph.Irl.dVal;
						if ( trGraph.Orl )
							dOrl = trGraph.Orl.dVal;
					}						
					SetupResidualPlot(dp, NULL, dIrl, dOrl);
					*/
					setupResidualLimit(gl);
					///end FAIL_CHANGE_INNER_OUTTER_RESIDUAL_LIMIT_ON_CHANGE_PARAM
				}
			}
		}
	}
	
	return true;
}
//------ End SURFACE_FIT_REPORT_SHOULD_USE_CONTOUR_PLOTS

/// Iris 7/29/2009 QA80-14029 FAIL_CHANGE_INNER_OUTTER_RESIDUAL_LIMIT_ON_CHANGE_PARAM
//virtual 
void	FitNL::SetupPlotsOnRecalculate(GraphLayer& gl, int nGraphIndex)
{
	if( nGraphIndex == GRAPH_RESIDUALS_SCATTER )
	{
		TreeNode trOp;
		GetTree(trOp);
		if ( GetFitType(trOp) == NLFIT_XYZ_FITTING || GetFitType(trOp) == NLFIT_MATRIX_FITTING )
		{
			setupResidualLimit( gl );
		}
	}
}

void 	FitNL::setupResidualLimit(GraphLayer& gl)
{
	DataPlot dpResultResidual = gl.DataPlots(NLFIT_XYZ_RESULT_PLOT);
	
	ASSERT( dpResultResidual );
	if( dpResultResidual )
	{	
		TreeNode trOp;
		GetTree(trOp);
		
		TreeNode trGraph = GetGUIGraphNodes(trOp, GRAPH_RESIDUALS_SCATTER);
		double	dIrl = 5, dOrl = 30;		//hard code default value, need to define later, see SurfaceFitPreviewCtrl.h
		if ( trGraph )
		{
			if ( trGraph.Irl )
				dIrl = trGraph.Irl.dVal;
			if ( trGraph.Orl )
				dOrl = trGraph.Orl.dVal;
		}	
		
		if( m_vContourLevelInfo.GetSize() < 3 ) // when change parameter, m_vContourLevelInfo is empty since will not call FitNL::SetupSourceDataPlot to init it at this time
		{
			//get_contour_level_info(dpSource, z1, z2, zInc, &m_vContourLevelInfo, vz.GetSize());
			DataPlot 	dpSource = gl.DataPlots(NLFIT_XYZ_SOURCE_PLOT);
			ASSERT(dpSource);
			
			vector		vz;
			BOOL 		bLogScale;
			if( dpSource && dpSource.GetColormap(vz, bLogScale) )
			{			
				m_vContourLevelInfo.SetSize(3);
				vz.GetMinMax(m_vContourLevelInfo[0], m_vContourLevelInfo[1]);				
				RoundLimits(&m_vContourLevelInfo[0], &m_vContourLevelInfo[1], &m_vContourLevelInfo[2], vz.GetSize());
			}			
		}
		
		SetupResidualPlot(dpResultResidual, NULL, dIrl, dOrl);
	}
}
///end FAIL_CHANGE_INNER_OUTTER_RESIDUAL_LIMIT_ON_CHANGE_PARAM


/// Iris 8/09/06 FIND_XY_FOR_PR
///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
//bool 	FitNL::GetYFromX(const vector& vx, vector& vy, int nOuputIndex, TreeNode& trOp, const matrix& mXs)
bool 	FitNL::GetYFromX(const vector& vx, vector& vy, int nOuputIndex, TreeNode& trOp, const matrix& mXs, int nPeaks, vector& vParams)
///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
{
	if(NULL == trOp)
		GetTree(trOp);	
		
	///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	if(nPeaks < 1)
		return false;
	///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	
	string 	strFunctionName = trOp.GUI.FunctionSelection.FunctionList.strVal;
	string 	strCategory = trOp.GUI.FunctionSelection.CategoryList.strVal;
	
	///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
	//vector 	vParams;
	/////Cheney 2007-3-24 SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	////int 	nParams = GetFitParams(vParams, nOuputIndex, trOp);
	//int 	nParams = GetFitParams(vParams, nOuputIndex, trOp, false);
	/////end SHOULD_NOT_PASS_DERIVED_PARAMS_WHEN_FIND_X_FROM_Y
	//if( nParams < 0)
		//return false;
	//return nlsf_evaluate(strFunctionName, strCategory, vx, vy, vParams);
	vector vParamstemp;
	
	//if no replica
	if(nPeaks == 1)
	{
		int 	nParams = GetFitParams(vParamstemp, nOuputIndex, trOp, false);
		if( nParams < 0)
			return false;
		
		if(vParams)
			vParams = vParamstemp;
		return nlsf_evaluate(strFunctionName, strCategory, vx, vy, vParamstemp);
	}
		
	//if multi peaks, should loop to get each peak's fit curve, then got cumulative curve
	Tree	trParams;
	if(!GetFitParameters(trOp, trParams, false))
		return false;
	
	TreeNode trParamsVal = trParams.Children.Item(0);
	int nTotalParams = trParamsVal.Children.Count();
	///Cheney 2007-10-9 FINDX_IN_REPLICA_FITTING_NOT_WORK
	//as somebody modified trParamsVal, now first param is not sharing
	//int nParamInFunc = (nTotalParams - 1) / nPeaks; //first param is sharing
	int nParamInFunc = nTotalParams / nPeaks; 
	///end FINDX_IN_REPLICA_FITTING_NOT_WORK
	vy.SetSize(vx.GetSize());
	
	for(int ii = 0; ii < nPeaks; ii++)
	{
		int nParamBegin = 1 + ii * nParamInFunc;
		///Cheney 2007-10-9 FINDX_IN_REPLICA_FITTING_NOT_WORK
		//int nParamEnd = nParamBegin + nParamInFunc;
		int nParamEnd = nParamBegin + nParamInFunc - 1;
		///end FINDX_IN_REPLICA_FITTING_NOT_WORK
		vector vtemp; //for each peak
		int nParams = getFitParamsMultiPeaks(vtemp, vParamstemp, nParamBegin, nParamEnd, trParamsVal);
		if( nParams < 0)
			return false;
		
		vector vytemp(vx.GetSize());
		if(!nlsf_evaluate(strFunctionName, strCategory, vx, vytemp, vtemp))
			return false;
		
		vy += vytemp;
	}
	
	//subtract baseline
	double dBaseLine = vParamstemp[0];
	vy -= dBaseLine * ( nPeaks - 1);
	
	if(vParams)
		vParams = vParamstemp;
	return true;
	///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
}
//end FIND_XY_FOR_PR

///Cheney 2007-6-19 ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT
int		FitNL::getFitParamsMultiPeaks(vector& vParamsCurrentPeak, vector& vParams, int nParamBegin, int nParamEnd, TreeNode& trParams)
{
	if(!trParams)
		return -1;
	
	vParamsCurrentPeak.SetSize(0);
	
	//get shareing parameter at first
	double dVal = trParams.Children.Item(0).Value.dVal;
	vParamsCurrentPeak.Add( dVal );
	if(nParamBegin == 1) //means first peak
		vParams.Add( dVal );
	
	//get other by begin and end index
	for(int ii = nParamBegin; ii < nParamEnd; ii++)
	{
		dVal = trParams.Children.Item(ii).Value.dVal;
		vParamsCurrentPeak.Add( dVal );
		vParams.Add(dVal)
	}
	
	return vParamsCurrentPeak.GetSize();
}

bool 	FitNL::GetFitCurve(TreeNode& trOp, vector& vx, vector& vy, int& nPeaks, int nIndex)
{
	TreeNode	trFit = GetOneResultCurvesTable(trOp, nIndex, 0, GRAPH_FIT_CURVE); //getFitCuvesTable(trOp, nIndex);
	if(!trFit)
		return false;
	
	TreeNodeCollection trColl(trFit, "FitX");
	TreeNode trX = trColl.Item(0); //only one X for this method	
	TreeNodeCollection trCol2(trFit, "FitY");
	
	if(trX)
		vx = trX.dVals;
	else
		return false;

	int nCount = trCol2.Count();
	if( nCount < 0)
		return false;
	
	//get number of replica
	///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
	//TreeNode trReplica = trOp.GUI.Fit.Replica;
	//------ 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
	///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
	/// Hong 06/10/08 v8.0881 FIX_FLAYOUT_THEME_LOSE_RESULT_FOR_FIND_X_FROM_Y
	//int nReplicaEnable = 0;
	int nReplicaEnable = ENABLE;
	/// end FIX_FLAYOUT_THEME_LOSE_RESULT_FOR_FIND_X_FROM_Y
	trReplica.GetAttribute( STR_ENABLE_ATTRIB, nReplicaEnable );
	nPeaks = nReplicaEnable && trReplica.Number.nVal > 0? trReplica.Number.nVal + 1 : 1;
	
	if(nPeaks == 1) //no replica
	{
		vy = trCol2.Item(0).dVals;
		return true;
	}
	
	//if multi peaks need check if exist cumulative fit curve
	TreeNode trtemp = trCol2.Item(0); //cumulative fit curve will be first if exists in trCol2
	string strLabel;
	trtemp.GetAttribute( STR_LABEL_ATTRIB, strLabel);
	bool bCumulative = strLabel.Compare(STR_LABEL_CUMULATIVE_FIT_CURVE)? false : true;
	
	//get cumulative fit curve
	if(bCumulative)
	{
		vy = trtemp.dVals;
		return true;
	}
	
	//bCumulative = false, should compute it by each peaks
	TreeNode trBaseLine = trOp.Calculation.Parameters.Children.Item(0);
	if(!trBaseLine)
		return false;
	
	double dBaseLine = trBaseLine.Value.dVal; 
	
	for(int ii = 0; ii < nPeaks; ii++)
	{
		TreeNode trY = trCol2.Item(ii);
		
		vector vtemp;
		vtemp = trY.dVals;
		
		if(ii == 0)
			vy = vtemp;
		else
		{
			vy += vtemp;
			vy -= dBaseLine;
		}
	}
	
	return true;
}
///end ALWAYS_FIND_XY_FROM_CUMULATIVE_FIT_CURVE_IF_PEAK_FIT

///Arvin 1/04/06 FIND_Z_FROM_XY
bool 	FitNL::GetZFromXY(const vector& vx, const vector& vy, vector& vz, int nOuputIndex, TreeNode& trOp, const matrix& mXs)
{
	if(NULL == trOp)
		GetTree(trOp);	
	
	string 	strFunctionName = trOp.GUI.FunctionSelection.FunctionList.strVal;
	string 	strCategory = trOp.GUI.FunctionSelection.CategoryList.strVal;
	
	vector 	vParams;
	/// Hong 09/28/08 QA80-12305 v8.0949 FIX_FIND_Z_FROM_XY_FAIL_IF_HAVE_DERIVED_PARAMS
	//int 	nParams = GetFitParams(vParams, nOuputIndex, trOp);
	int 	nParams = GetFitParams(vParams, nOuputIndex, trOp, false);
	/// end FIX_FIND_Z_FROM_XY_FAIL_IF_HAVE_DERIVED_PARAMS
	if( nParams < 0)
		return false;
	return nlsf_evaluate(strFunctionName, strCategory, vx, vy, vParams, vz);
}

///Sophy 7/9/2008 CLEAN_CODE_FIX_FAIL_TO_GET_INPUT_OUT_DATA_NODE_IN_OUTPUTGUIMANAGER
//virtual
TreeNode	FitNL::GetInputDataNode( const TreeNode& trGUI )
{
	TreeNode trInput = FitterOperation::GetInputDataNode( trGUI );
	if( !trInput )
		trInput = trGUI.Parent().DataSelection.InputData;//in nlfit GUI tree structure is different from normal fit
	
	return trInput;
}
//virtual
TreeNode	FitNL::GetOutputNode( const TreeNode& trGUI )
{
	TreeNode trOutput = FitterOperation::GetOutputNode( trGUI );
	if( !trOutput )
		trOutput = trGUI.Parent().OutputResults.Output;
	
	return trOutput;
}
///end CLEAN_CODE_FIX_FAIL_TO_GET_INPUT_OUT_DATA_NODE_IN_OUTPUTGUIMANAGER
string	FitNL::GetResultCurveSheetName(TreeNode& trOperation, int nIndex, int nOption)
{
	/// Sophy 5/07/2008 QA80-10934-P5 v8.0857 FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME
	//if(HasZ(trOperation) && nOption == OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET)
	if(HasZ(trOperation) && nOption == OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET)
	/// End FIX_BUG_SURFACE_AND_MATRIX_FIT_WRONG_DEFAULT_SHEETNAME
	{
		string strSheetName = _LE(E_STR_FINDZ_CURVE_SHEET_NAME);
		return strSheetName;
	}
	return WksReportOperation::GetResultCurveSheetName(trOperation, nIndex, nOption);
}
///Sophy 6/3/2008 FIX_GET_OPERATION_TREE_FAILURE
string	FitNL::GetResultCurveSheetFullName(TreeNode& trOperation, int nIndex, int nOption )
{
	string strClassName = STR_FITTEROPERATION_CLASS_FITNL;
	IsSpecFit( trOperation, &strClassName);
	
	if( 0 == strClassName.Compare("fitmatrix") )
		strClassName = "FitMatrix";
	if( 0 == strClassName.Compare("fitsurface") )
		strClassName = "FitSurface";
	if( 0 == strClassName.Compare("fitsigmoidal") )
		strClassName = "FitSigmoidal";
	if( 0 == strClassName.Compare("fitexp") )
		strClassName = "FitExp";
	
	return strClassName + GetResultCurveSheetName( trOperation, nIndex, nOption) + "1";
}
///end FIX_GET_OPERATION_TREE_FAILURE
string FitNL::GetResultCurveBookName(TreeNode& trOperation, int nDataIndex, int nOption, bool bSeparateSheetForDataset)
{
	if(HasZ(trOperation) && nOption == OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET)
	{
		string strSheetName = STR_FINDZ_CURVE_BOOK_LONG_NAME;
		return strSheetName;
	}
	
	return FitterOperation::GetResultCurveBookName(trOperation, nDataIndex, nOption, bSeparateSheetForDataset);
}

/// Iris 4/11/2008 SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK
string FitNL::GetResultCurveBookShortName(TreeNode& trOperation, int nIndex, int nOption)
{
	if(HasZ(trOperation) && nOption == OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET)
	{
		return _LE(E_STR_FIND_Z_CURVE_BOOK_SHORT_NAME);
	}	
	return FitterOperation::GetResultCurveBookShortName(trOperation, nIndex, nOption);
}
///end SET_BOTH_LONG_NAME_AND_SHORT_NAME_FOR_REPORT_BOOK


bool	FitNL::addAdditionalCustomTables(TreeNode &trOp, int index, int nNumData)
{
	if(HasZ(trOp))
	{
		bool		bb = addFindZTable(trOp, true, index, nNumData);
		return bb;
	}
	
	return FitterOperation::addAdditionalCustomTables(trOp, index, nNumData);
}

bool FitNL::setFindZTable(TreeNode &trCustom, string &strInputXColLabel, int nInputXColType, string &strInputYColLabel, int nInputYColType, string &strOutColLabel, int nOutputColType, string &strValueToStore)
{
	TreeNode		trRow = trCustom.FirstNode;
	if ( !trRow.IsValid() )
		return error_report("addFindXYorYXTable trCustom invalid");

	TreeNode		trInputXCol = trRow.FirstNode;		// the input will be the first column
	if ( !trInputXCol.IsValid() )
		return false;
	trInputXCol.SetAttribute(STR_LABEL_ATTRIB, strInputXColLabel);
	trInputXCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nInputXColType);
	
	TreeNode		trInputYCol = trRow.Children.Item(1);
	if ( !trInputYCol.IsValid() )
		return false;
	
	trInputYCol.SetAttribute(STR_LABEL_ATTRIB, strInputYColLabel);
	trInputYCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nInputYColType);
	
	// We want the second column to have the formula:
	TreeNode		trCol = trRow.Children.Item(2);
	if ( !trCol.IsValid() )
		return false;
		
	trCol.SetAttribute(STR_LABEL_ATTRIB, strOutColLabel);
	trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nOutputColType);			
	trCol.SetAttribute(STR_ATT_COLUMN_FORMULA, strValueToStore);
		
	// If there are any more output columns, set the labels to them:
	int				nCountOutputCols = trRow.Children.Count() - 1;
	for (int kk = 2; kk < nCountOutputCols; kk++)
	{
		trCol = trRow.Children.Item(kk + 1);
		string		strMoreOutLabel;
		strMoreOutLabel.Format("%s %d", strOutColLabel, kk);  
		trCol.SetAttribute(STR_COL_DESIGNATION_ATTRIB, nOutputColType);
		trCol.SetAttribute(STR_LABEL_ATTRIB, strMoreOutLabel);
	}
	return true;
}

bool	FitNL::addFindZTable(TreeNode &trOp, bool bYfromX, int index, int nNumData)
{
	string		strSection = "FitterOp_ZfromXY";
		
	string			strInputXColLabel; 
	string			strInputYColLabel; 
	string			strOutColLabel;
		
	strInputXColLabel = _L("Enter X values:");
	strInputYColLabel = _L("Enter Y values:");
	strOutColLabel = _L("Z Value");
				
	string		strValueToStore = "RegrFindXYorYX.txt|" + strSection;
	int			indexTbl = bYfromX ? 2 : 1;		
		
	string		strDataLabel;
	GetEscapedMainDataString(trOp, strDataLabel, index + 1);
	ConvertEscapedString(strDataLabel);

	int nOption = bYfromX? OUTPUT_RESULT_CURVE_CALIBRATION_FIND_Y_SHEET : OUTPUT_RESULT_CURVE_CALIBRATION_FIND_X_SHEET;
	TreeNode 	trCustomTable = GetResultCurvesBranch(trOp, index, nNumData, nOption, strDataLabel);
	if(!trCustomTable)
		return error_report("Fail to create Calibration table");

	string		strTblLabel;
	bool		bEnabled = false;
	if ( !GetCustomTableProps(&strTblLabel, trOp, indexTbl, -1, &bEnabled, strDataLabel) )
		return error_report("addFindXYorYXTable failed GetCustomTableProps");
	if( !bEnabled )
		return true;
		
	string		strTagName =  "ZfromXY";
		
	int 		nIDTable = GetCustomTableID(indexTbl, index);
	TreeNode 	trCustom = tree_check_get_node(trCustomTable, strTagName, nIDTable, STR_LABEL_ATTRIB, strTblLabel);
		
	int			nInputXColType = OKDATAOBJ_DESIGNATION_X;
	int			nInputYColType = OKDATAOBJ_DESIGNATION_Y;
	int			nOutputColType = OKDATAOBJ_DESIGNATION_Z;
	if( !AddCustomTableToReport(trOp, trCustom, indexTbl) )
		return error_report("AddFindXYorYXTable failed addCustomTableToReport");
		
	setFindZTable(trCustom,strInputXColLabel,nInputXColType,strInputYColLabel,nInputYColType,strOutColLabel,nOutputColType,strValueToStore);
	DWORD		dwGetNBranchBits = GETNBRANCH_HIDE_ROW_HEADINGS | GETNBRANCH_WRITABLE | GETNBRANCH_HIDE_ROW_LABELS | GETNBRANCH_CHANGE_LABEL_TYPES_IN_FLAT;
	trCustom.SetAttribute(TREE_Table, GetTableStringSupport(false, true, true, dwGetNBranchBits));		
		
	return true;
}

bool FitNL::IsOutputSeparateCalibrationSheet(const TreeNode& trOp, int nXfromY) 
{
	if(HasZ(trOp))
	{
		TreeNode 	trCalibration = trOp.GUI.Calibration;
		if(!trCalibration)
			return false;
		
		bool	bOutputXfromY = false;
		bool	bOutputYfromX = trCalibration.Use ? true : false;		
		if(1 == nXfromY)		
			return bOutputXfromY;
		else if(0 == nXfromY)
			return bOutputYfromX;
		else
			return bOutputXfromY || bOutputYfromX;
	}
	
	return FitterOperation::IsOutputSeparateCalibrationSheet(trOp, nXfromY); 	
}
///END FIND_Z_FROM_XY

/// Iris 9/05/06 ADD_FIT_FOOTNOTE_TO_PARAM_RESULT_TABLE
void 	FitNL::appendFitFootnoteToParamTable(TreeNode& trOp, int index, int nTotalNumData)
{
	TreeNode 	trParams = tree_get_node_by_id(trOp.Calculation, IDST_FIT_PARAMETER, true);
	if(!trParams || NULL == m_pFitSession)
		return;
	
	/// Iris 4/16/2008 REMOVE_PARAM_TABLE_IF_IT_IS_EMPTY
	if( !IsAppendParamFootnote(trOp) )
		return;
	///end REMOVE_PARAM_TABLE_IF_IT_IS_EMPTY
	
	string		strMessage;
	/// Hong 09/03/08 QA80-12130 NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/*
	if( isSepFit(trOp) )
	{
		m_vbFitConverged.Add( m_pFitSession->IsFitConverged() );
		/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION	
		// Hong, to do, what is the purpose of m_vbShared, check if can remove it
		//m_vbShared.Add( m_pFitSession->IsSharedParameters() );
		//m_vbFixed.Add( m_pFitSession->IsFixedParameters() );
		m_vbShared.Add( m_pFitSession->HasSharedParameters() );
		m_vbFixed.Add( m_pFitSession->HasFixedParameters() );
		/// end FITNL_USING_NEW_NLFSESSION
		
		if(index == nTotalNumData - 1)
		{
			int	num=0;
			for(int ii=0; ii<m_vbFitConverged.GetSize(); ii++)
			{
				if(m_vbFitConverged[ii])
					num++;
			}
			if(0 == num)
				strMessage = _L("Fitting failed on all datasets.");
			else if(num == m_vbFitConverged.GetSize())
				strMessage = _L("All datasets were fitted successfully.");
			else
				strMessage = _L("Fitting failed on some of the datasets.");
			
			num=0;
			for(ii=0; ii<m_vbShared.GetSize(); ii++)
			{
				if(m_vbShared[ii])
					num++;
			}
			if(num>0)
				///Cheney 2007-4-17 FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED
				//strMessage += "Some parameter values were shared.";
				strMessage += _L("\r\nSome parameter values were shared.");
				///end FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED
			
			num=0;
			for(ii=0; ii<m_vbFixed.GetSize(); ii++)
			{
				if(m_vbFixed[ii])
					num++;
			}
			if(num>0)
				///Cheney 2007-4-17 FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED
				//strMessage += "Some parameter values were fixed.";	
				strMessage += STR_FOOTNOTE_SOME_PARAMS_FIXED;	
				///end FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED	
		}
	}
	else
	{
		strMessage = m_pFitSession->GetFitMessage();
		///Cheney 2007-4-17 FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED
		if(m_pFitSession->HasFixedParameters() )	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
			strMessage += STR_FOOTNOTE_SOME_PARAMS_FIXED;
		///end FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED
	}
	*/
	// Hong, to do, may need more check
	/// Iris 11/03/2009 QA81-14576 SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE
	// to fix footnote always only display fit out come for first dataset
	//strMessage = GetFitSession()->GetFitMessage();
	strMessage = GetFitSession()->GetFitMessage(index, NULL, true);
	if( strMessage.IsEmpty() )
		return;
	///end SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE
	///Cheney 2007-4-17 FIX_BUG_OF_WHEN_SEP_REPORT_NO_FOOT_NOTES_FOR_IF_FIXED
	if(GetFitSession()->HasFixedParameters() )	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
		strMessage += STR_FOOTNOTE_SOME_PARAMS_FIXED;
	/// end NLFIT_SESSION_SUPPORT_SEPARATE_FIT
	/// Hong 13/05/08 QA80-11541 ADD_FOOTNODE_IF_UNCHECK_USE_REDUCED_CHISQR
	TreeNode 	trScaleError = tree_get_node_by_id(trOp.GUI, IDE_NL_SCALE_ERROR_WITH_CHISQR, true);
	if ( trScaleError && 0 == trScaleError.nVal )
	{
		string	strFootNoteScale;
		ocu_load_msg_str(FOOTNOTE_NOT_SCALED_BY_REDUCED_CHISQR, &strFootNoteScale);
		strMessage += strFootNoteScale;
	}
	/// end ADD_FOOTNODE_IF_UNCHECK_USE_REDUCED_CHISQR
	if(strMessage.IsEmpty())
		return;
	
	TreeNode 	trFooter = tree_check_get_node(trParams, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); // just need the TREE_Footnote attribute, value does not matter, so 1 is good
	trFooter.strVal = strMessage;
	
}
///end ADD_FIT_FOOTNOTE_TO_PARAM_RESULT_TABLE

///Cheney 2007-4-4 ADD_FOOTNOTE_FOR_FIT_STATUS_AS_LARRY_SUGGEST
void FitNL::appendFitFootnoteToStatsTable(TreeNode& trOp, int index, int nTotalNumData)
{
	TreeNode 	trRegStats = tree_get_node_by_id(trOp.Calculation, IDST_REG_STATS_RESULTS, true);
	if(!trRegStats || NULL == m_pFitSession)
		///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
		//return;
	{
		error_report("failed to append fit foot note to stats table");
		return;
	}
		///end CLEAN_UP_ERR_HANDLING
	
	string strItersPerformed;
	/// Iris 11/03/2009 QA81-14576 SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE
	// to fix footnote always only display fit out come for first dataset
	//strItersPerformed.Format("%d : %s", GetFitSession()->GetLastIterateOutCome(), GetFitSession()->GetFitOutCome(false));
	strItersPerformed.Format("%d : %s", GetFitSession()->GetLastIterateOutCome(index), GetFitSession()->GetFitOutCome(false, index));
	///end SET_BLUE_COLOR_FOR_FIT_CONVERGE_INFO_IN_FOOTNOTE
	if(m_strFitStatus.Find(strItersPerformed) < 0)	
		//the last line not need has "\r\n"
		m_strFitStatus += index == 0? strItersPerformed : "\r\n" + strItersPerformed;
	
	if(index == nTotalNumData - 1)
	{
		TreeNode 	trFooter = tree_check_get_node(trRegStats, "Footnote", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); // just need the TREE_Footnote attribute, value does not matter, so 1 is good
		if(trFooter)
			//------ Folger 11/15/07 FIT_REPORT_TABLE_LOCALIZATION
			//trFooter.strVal = "Fit Status Code : \r\n" + m_strFitStatus;
		{
			string strLabel = _L("Fit Status Code");
			trFooter.strVal = strLabel + " " + ": \r\n" + m_strFitStatus;
		}
			//------ End FIT_REPORT_TABLE_LOCALIZATION
	}
	
}
///end ADD_FOOTNOTE_FOR_FIT_STATUS_AS_LARRY_SUGGEST

///Arvin 10/31/06 FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED
bool FitNL::CalcAddStatsHistPlotData(TreeNode& trOp, int index, FitParameter* psFitParameter, matrix &mYs, matrix &mXs, const vector<string> &vstrFactors, const vector &vWeights, string& strDataLabel)
{
	matrix mFitYs, mResiduals;
	if(!FitterOperation::getResidualData(trOp, index, psFitParameter, mXs, mYs, mFitYs, mResiduals))
		return false;
		
	for(int ii = 0; ii < mResiduals.GetNumCols(); ii++)
	{
		vector vRe;
		
		if(mResiduals.GetNumRows() > 0)///Cheney 2007-5-28 IF_EMPTY_DATA_SET_SHOULD_SET_MISSING_AS_RESULT
			mResiduals.GetColumn(vRe, ii);
		/*
		double dMin, dMax;
		vRe.GetMinMax(dMin, dMax);
		if((is_double_legal(&dMin) && is_double_legal(&dMax)) || (is_missing_value(dMin) && is_missing_value(dMax)))
		{
			AddBinDataTableAndGraphNodes(trOp, index+ii, vRe, vstrFactors, strDataLabel);
		}
		*/
		if(!calcStatsData(trOp, index+ii, vRe, vWeights))
		return false;
	}
		
	return true;
}

/// Iris 02/27/2007 FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC
bool FitNL::CalcAddStatsHistPlotData(TreeNode& trOp, int index, const vector<string> &vstrFactors, const vector &vWeights, string& strDataLabel)
{
	///Kyle 01/24/2009 NO_NEED_TO_CALC_HIST_PLOT_DATA_IF_CREATE_REPORT_GRAPH_FALSE
	if( !IsCreateReportGraph(trOp, GRAPH_RESIDUALS_HISTOGRAM) )
		return true;
	///End NO_NEED_TO_CALC_HIST_PLOT_DATA_IF_CREATE_REPORT_GRAPH_FALSE

	vector 	vX, vY, vZ, vFitZ, vResidual;
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	//if( !m_pFitSession->GetResidualData(vResidual, index, vX, vY, vZ, vFitZ))
	if( !GetNLFCurvePointer()->GetResidualData(vResidual, GetFitSession()->GetDataObject(), GetFitSession()->GetNLParamsMngr(), index, vX, vY, vZ, vFitZ))
	/// end FITNL_USING_NEW_NLFSESSION
		return false;
	double dMin, dMax;
	vResidual.GetMinMax(dMin, dMax);
	if((is_double_legal(&dMin) && is_double_legal(&dMax)) || (is_missing_value(dMin) && is_missing_value(dMax)))
	{
		AddBinDataTableAndGraphNodes(trOp, index, vResidual, vstrFactors, strDataLabel);
	}
	if(!calcStatsData(trOp, index, vResidual, vWeights))
		return false;
	
	return true;
}
///end FITTING_RESIDUALS_HISTOGRAM_PLOT_CENTRALIZED

//virtual 
string FitNL::GetReportGraphLabel(TreeNode& trOp, int nGraphIndex, int nPicRow, int nPicCol)
{
	string		strLabel;
	int			nPicIndex = nPicRow * GetReportGraphTableColNum(trOp, nGraphIndex) + nPicCol;
	if(nPicIndex >= GetTotalNumPictureForOneGraphType(trOp, nGraphIndex))
		return strLabel; //return error
		
	if( GetNumX(trOp) > 1 || GetNumY(trOp) > 1 )
	{
		DataRange 	dr;
		GetInput(dr);	
		
		string		strIndep, strDep;
		strDep = get_column_name(dr, "Y", nPicRow);
		///Sophy 12/23/2008 v8.0990 QA80-12832 SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
		//strIndep = get_column_name(dr, "X", nPicCol);
		strIndep = get_column_name(dr, "X", nPicCol + (nPicRow/GetNumY(trOp)) * GetNumX(trOp)); //nPicCol-th X of the (nPicRow/GetNumY(trOp))-th dataseet
		///end SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
		strLabel = strDep + " " + "vs." + " " + strIndep;	
		return strLabel;
	}
	
	return FitterOperation::GetReportGraphLabel(trOp, nGraphIndex, nPicRow, nPicCol);
	
}

//virtual 
int    	FitNL::GetTotalNumPictureForOneGraphType(TreeNode& trOp, int nGraphIndex)
{
	if(-1 == nGraphIndex)
	{
		//if for multi dep or multi indep, there is only dataset
		if( GetNumX(trOp) > 1 || GetNumY(trOp) > 1 )
			return 1;
		else
		{		
			if( trOp.GUI.Graph1.Use || //Fitted Curve
				trOp.GUI.Residuals.Graph2.nVal || //Resiudl Scatter
				trOp.GUI.Residuals.Graph4.nVal || //Residual vs. Fit Curve
				trOp.GUI.Residuals.Graph5.nVal || //Residual vs. Order
				trOp.GUI.Residuals.Graph6.nVal)   //Residual vs. Lag
				return GetTotalNumData(trOp);
			
			if( trOp.GUI.Residuals.Graph3.nVal )
				return 1;
		}
	}
	else
	{
		switch(nGraphIndex)
		{
		case GRAPH_RESIDUALS_HISTOGRAM:
			//return 1; ///Arvin 03/29/07 v8.0592 CAN_NOT_PLOT_MULTI_HISTOGRAMS_FOR_MULTI_DATASET
			
		case GRAPH_FIT_CURVE:
		case GRAPH_RESIDUALS_SCATTER:
		case GRAPH_RESIDUALS_VERSUS_FITS_PLOT:
		case GRAPH_RESIDUALS_VERSUS_ORDER_PLOT:
		case GRAPH_RESIDUALS_LAG_PLOT:
			///Cheney 2007-4-13 CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
			//return (GetNumX(trOp) > 1 || GetNumY(trOp) > 1)? GetNumX(trOp) * GetNumY(trOp) : GetTotalNumData(trOp);
			if(GetNumX(trOp) > 1 || GetNumY(trOp) > 1)
			{
				int nFitType = GetFitType(trOp);
				if(nFitType == NLFIT_MATRIX_FITTING || nFitType == NLFIT_XYZ_FITTING)
					return 1;
				else
					///Sophy 12/23/2008 v8.0990 QA80-12832 SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
					//return GetNumX(trOp) * GetNumY(trOp);
					///------ Folger 01/19/09 SUPPORT_MULTI_SETS_FOR_MULTI_DEPS_INDEPS_MAKE_RESET_ALL_GRAPHS_BROKEN
					//return GetNumX(trOp) * GetNumY(trOp) * m_pFitSession->GetNumDataset();
					return GetNumX(trOp) * GetNumY(trOp) * GetTotalNumData(trOp);
					///------ End SUPPORT_MULTI_SETS_FOR_MULTI_DEPS_INDEPS_MAKE_RESET_ALL_GRAPHS_BROKEN
					///end SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING
			}
			else
				return GetTotalNumData(trOp);
			///end CORRECT_RESIDUAL_COMPUTING_WHEN_MULTI_INDEP_AND_DEP
		}
	
	}
	return GetNumY(trOp);//error	
}

void	FitNL::UpdateImageNodePlottingInfo(TreeNode& trOp, TreeNode& trPlotInfo, int nGraphIndex, int nDataIndex, int nPicIndex)
{
	FitterOperation::UpdateImageNodePlottingInfo(trOp, trPlotInfo, nGraphIndex, nDataIndex, nPicIndex);
	
	if( GetNumX(trOp) > 1 || GetNumY(trOp) > 1 )
	{
		trPlotInfo.TableID.nVal = GetResultCurveTableID(trOp, nDataIndex, -1, nGraphIndex);
			
		/// Iris 03/01/2007 FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC
		trPlotInfo.DataIndex.From.nVal = nDataIndex;
		trPlotInfo.DataIndex.To.nVal = nDataIndex;
		///end FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC

	}
}
///end FIX_ONLY_SHOW_ONE_GRAPH_FOR_MULTI_DEP_FUNC

///Cheney 2007-3-29 SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG
bool	FitNL::IsAddMaskedOrMissingDataTableForMultiIndep(vector& vX, matrix& mMultiIndep)
{
	bool bRet = WksReportOperation::IsAddMaskedOrMissingDataTableForMultiIndep(vX, mMultiIndep);

	TreeNode trOp;
	GetTree(trOp);
	//when matrix fit, mMultiIndep will also be n*m, not 0*0
	return bRet && !trOp.SpecInfo;		
}
///end SUPPORT_MATRIX_FIT_WHEN_USE_DIALOG

///Cheney 2007-4-9 CORRECT_LOGIC_OF_CALLING_INIT_BRANCH
bool 	FitNL::UpdateInputBranch(TreeNode& trOp)
{
	if(!trOp.IsValid())
		return false;
	
	TreeNode trInputData = trOp.GUI.InputData;
	if(!trInputData)
		return false;
	
	TreeNode trFunc = trOp.GUI.FunctionSelection.FunctionList;
	if(!trFunc)
		return false;
	
	StringArray		vstrIndepVars, vstrDepVars;
	///Cheney 2007-4-24 CLEAN_UP_FDF_TREE_LOAD
	if(!isFDFTreeValid())//if(m_trFDF.Children.Count() == 0)//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
	{
		///Cheney 2007-7-30 ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
		//string strFilenameTemp;
		//nlf_get_fdf_filename(trFunc.strVal, NULL, NULL, &strFilenameTemp);
		/////Cheney 2007-6-8 ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC
		////if(!nlsf_FDF_to_tree(strFilenameTemp, &m_trFDF, FDFT_CONVERT_BOOL_TO_01))
		//if(!nlsf_load_FDF_to_tree(strFilenameTemp, &m_trFDF, FDFT_CONVERT_BOOL_TO_01, true))
		/////end ALLOW_USER_EDIT_LINEAR_CONSTRINTS_WHEN_USE_BUILDIN_FUNC
			//return false;
		if(!LoadFDFtoTree(trFunc.strVal))
			return false;
		///end ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
	}
	//----- CPY 7/17/2007 QA70-10010-P3 LAST_USED_THEME_WHEN_NOT_FOUND_BREAK_UPDATE_INPUT_TREE
	/*
	if(nlf_get_dependent_variables(m_trFDF, &vstrDepVars) < 0)
		return false;
  	if(nlf_get_dependent_variables(m_trFDF, &vstrDepVars) < 0)
  		return false;
  	*/
  	int nDepVars = nlf_get_dependent_variables(m_trFDF, &vstrDepVars);
  	if(nDepVars <= 0)
  	///------ Folger 01/06/09 QA80-12878-P1 v8.0993e NLFIT_FAILS_TO_GET_ALL_DATAPLOTS_FROM_GRAPH
  		//return error_report("error getting dependent vars");
	{
		vstrDepVars.Add("Y");
  	}
  	///------ End NLFIT_FAILS_TO_GET_ALL_DATAPLOTS_FROM_GRAPH
  	///Cheney 2007-7-18 USE_WRONG_FUNC_TO_GET_INDEP
  	//int nIndepVars = nlf_get_dependent_variables(m_trFDF, &vstrDepVars);
  	int nIndepVars = nlf_get_independent_variables(m_trFDF, &vstrIndepVars);
  	///end USE_WRONG_FUNC_TO_GET_INDEP
  	if(nIndepVars <= 0)
  	///------ Folger 01/06/09 QA80-12878-P1 v8.0993e NLFIT_FAILS_TO_GET_ALL_DATAPLOTS_FROM_GRAPH
  		//return error_report("error getting independent vars");
	{
		vstrIndepVars.Add("X");
	}
  	///------ End NLFIT_FAILS_TO_GET_ALL_DATAPLOTS_FROM_GRAPH
  	//----- end LAST_USED_THEME_WHEN_NOT_FOUND_BREAK_UPDATE_INPUT_TREE
  	
	//if(nlf_get_dependent_variables(trFunc.strVal, &vstrDepVars) < 0)
		//return false;
  	//if(nlf_get_independent_variables(trFunc.strVal, &vstrIndepVars) < 0)
  		//return false;
  	///end CLEAN_UP_FDF_TREE_LOAD
  	
  	Tree trtemp;
  	trtemp.AddNode(trInputData);		
	TreeNode	trInput;
	///Cheney 2007-7-18 CLEAN_UP_ERR_HANDLING
	//okutil_create_fitter_data_node_ex(&trInput, &trtemp, STR_INPUT_RANGE_NAME, STR_INPUT_RANGE_LABEL, &vstrIndepVars, &vstrDepVars, WEIGHT_NONE, true);
	if(!okutil_create_fitter_data_node_ex(&trInput, &trtemp, STR_INPUT_RANGE_NAME, STR_INPUT_RANGE_LABEL, &vstrIndepVars, &vstrDepVars, WEIGHT_NONE, true))
		return error_report("failed to create fitter data node");
	///end CLEAN_UP_ERR_HANDLING
	
	trOp.GUI.InputData.Replace(trInput);	
	return true;
}
///end CORRECT_LOGIC_OF_CALLING_INIT_BRANCH

///Cheney 2007-4-10 IF_SEP_FIT_SHOULD_DISABLE_FIT_AND_ITER_BUTTON
//after rewrite NLFitsession, should remove
bool 	FitNL::getUserSettingFromGUI(int nDataIndex)
{
	if(nDataIndex < 0)
		return false;
	/* Hong, to do, comment out for compile, need clean interface
	int nParamsInFunc = m_pFitSession->GetNumParameter();
	
	int nBegin	= nDataIndex*nParamsInFunc;
	int nEnd	= nBegin + nParamsInFunc - 1;
	
	vector<bool> vbFixed;
	m_vbFixed.GetSubVector( vbFixed, nBegin, nEnd);
	m_pFitSession->SetParamsSettingIntVector(vbFixed, PARMAS_SETTING_FIXED);
	
	vector vValues;
	m_vParamValues.GetSubVector( vValues, nBegin, nEnd);
	m_pFitSession->SetParamsSettingDoubleVector(vValues, PARMAS_SETTING_VALUES);
	
	vector vParaLowerBounds;
	m_vParaLowerBounds.GetSubVector( vParaLowerBounds, nBegin, nEnd);
	m_pFitSession->SetParamsSettingDoubleVector(vParaLowerBounds, PARMAS_SETTING_LOWERBOUNDS);
	
	vector vParaUpperBounds;
	m_vParaUpperBounds.GetSubVector( vParaUpperBounds, nBegin, nEnd);
	m_pFitSession->SetParamsSettingDoubleVector(vParaUpperBounds, PARMAS_SETTING_UPPERBOUNDS);
	
	vector<bool> vbpbExclusiveLower;
	m_vbpbExclusiveLower.GetSubVector( vbpbExclusiveLower, nBegin, nEnd);
	m_pFitSession->SetParamsSettingIntVector(vbpbExclusiveLower, PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE);
	
	vector<bool> vbpbExclusiveUpper;
	m_vbpbExclusiveUpper.GetSubVector( vbpbExclusiveUpper, nBegin, nEnd);
	m_pFitSession->SetParamsSettingIntVector(vbpbExclusiveUpper, PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE);
	
	vector<bool> vbOnLowerBounds;
	m_vbOnLowerBounds.GetSubVector( vbOnLowerBounds, nBegin, nEnd);
	m_pFitSession->SetParamsSettingIntVector(vbOnLowerBounds, PARMAS_SETTING_LOWERBOUNDSENABLE);
	
	vector<bool> vbOnUpperBounds;
	m_vbOnUpperBounds.GetSubVector( vbOnUpperBounds, nBegin, nEnd);
	m_pFitSession->SetParamsSettingIntVector(vbOnUpperBounds, PARMAS_SETTING_UPPERBOUNDSENABLE);
	
	///Jasmine 10/17/07 MISSING_SIGN_DIGITES, sign
	vector<int> vnSignDigit;
	m_vnSignDigit.GetSubVector( vnSignDigit, nBegin, nEnd);
	m_pFitSession->SetParamsSettingIntVector(vnSignDigit, PARMAS_SETTING_SIGN_DIGITES);
	///End MISSING_SIGN_DIGITES
	
	m_pFitSession->UpdateParamsFromUserSetting();
	*/
	return true;
}

bool 	FitNL::setUserSettingFromGUI()
{
	//get user settings
	/* Hong, to do, comment out for compile, UserSetting is old mechanism which is NOT used amnymore, so can remove all code relative
	vector<bool> vbFixed;
	m_pFitSession->GetParamsSettingIntVector(vbFixed, PARMAS_SETTING_FIXED);
	m_vbFixed = vbFixed;
	
	vector vValues;
	m_pFitSession->GetParamsSettingDoubleVector(vValues, PARMAS_SETTING_VALUES);
	m_vParamValues = vValues;
	
	vector vParaLowerBounds;
	m_pFitSession->GetParamsSettingDoubleVector(vParaLowerBounds, PARMAS_SETTING_LOWERBOUNDS);
	m_vParaLowerBounds = vParaLowerBounds;
	
	vector vParaUpperBounds;
	m_pFitSession->GetParamsSettingDoubleVector(vParaUpperBounds, PARMAS_SETTING_UPPERBOUNDS);
	m_vParaUpperBounds = vParaUpperBounds;
	
	vector<bool> vbpbExclusiveLower;
	m_pFitSession->GetParamsSettingIntVector(vbpbExclusiveLower, PARMAS_SETTING_LOWERBOUNDSEXCLUSIVE);
	m_vbpbExclusiveLower = vbpbExclusiveLower;
	
	vector<bool> vbpbExclusiveUpper;
	m_pFitSession->GetParamsSettingIntVector(vbpbExclusiveUpper, PARMAS_SETTING_UPPERBOUNDSEXCLUSIVE);
	m_vbpbExclusiveUpper = vbpbExclusiveUpper;
	
	vector<bool> vbOnLowerBounds;
	m_pFitSession->GetParamsSettingIntVector(vbOnLowerBounds, PARMAS_SETTING_LOWERBOUNDSENABLE);
	m_vbOnLowerBounds = vbOnLowerBounds;
	
	vector<bool> vbOnUpperBounds;
	m_pFitSession->GetParamsSettingIntVector(vbOnUpperBounds, PARMAS_SETTING_UPPERBOUNDSENABLE);
	m_vbOnUpperBounds = vbOnUpperBounds;
	
	///Jasmine 10/17/07 MISSING_SIGN_DIGITES
	vector<int> vnSignDigit;
	m_pFitSession->GetParamsSettingIntVector(vnSignDigit, PARMAS_SETTING_SIGN_DIGITES);
	m_vnSignDigit = vnSignDigit;
	///End MISSING_SIGN_DIGITES
	*/
	return true;
}
///end IF_SEP_FIT_SHOULD_DISABLE_FIT_AND_ITER_BUTTON

///Cheney 2007-7-30 ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
bool 	FitNL::LoadFDFtoTree(LPCSTR lpcszFuncName)
{
	//------ Folger 04/07/08 CENTRALIZE_CODE_OF_LOADING_FDF_FILE
	//restore the old mechanism
	string strFilenameTemp;
	if ( lstrlen(lpcszFuncName) > 0 )
		nlf_get_fdf_filename(lpcszFuncName, NULL, NULL, &strFilenameTemp);
	///Jasmine 10/08/07 QA70-10490 RUNTIME_ERR_IF_INVALID_FUNC_SEL_IN_THEME
	if(strFilenameTemp.IsFile())
		return nlsf_load_FDF_to_tree(strFilenameTemp, &m_trFDF, FDFT_CONVERT_BOOL_TO_01, true);
	return true;
	///End RUNTIME_ERR_IF_INVALID_FUNC_SEL_IN_THEME
	//return nlsf_load_fdf_tree(m_trFDF, lpcszFuncName);
	//------
}

void	FitNL::UpdateFDFTreeFromThemeOrChangeFunc(bool bOpenDlg)
{
	bool bEmptyTreeFDF = !isFDFTreeValid();//m_trFDF.Children.Count() == 0? true : false;//--- CPY 2/16/10 QA81-15106 CHANGE_PARAM_BY_SCRIPT
	if( bOpenDlg )
		m_trFDF = GetFitSession()->GetTreeFDF();
	else if(!bEmptyTreeFDF)
		GetFitSession()->SetTreeFDF(m_trFDF);
}	
///end ADD_NEW_FUNC_TO_SUPPORT_PFM_LOAD_FDF
	
///Joseph 04/02/07 ADD_NLSF_ERR_MSG_EVENT
PEVENT_GETN	FitNL::GetNewEventFunction()
{
	return _nlsf_event1;
}
///End ADD_NLSF_ERR_MSG_EVENT

//virtual 
void	FitNL::InitFitSessionPointer(TreeNode &trOp)
{
	/// ML 11/10/2006 NLFIT_MODAL_CLEANUP
	//if(m_pFitSession)
	//{
	//	delete m_pFitSession;
	//	m_pFitSession = NULL;
	//}
	///Sophy 11/4/2008 RESET_FDF_ON_INIT_SESSION_LEAD_TO_RESET_AUTORUNINITPARAMS
	//CleanupFitSession("InitFitSessionPointer");
	CleanupFitSession("InitFitSessionPointer", false); //Sophy, oninit, should not reset fdf tree
	///end RESET_FDF_ON_INIT_SESSION_LEAD_TO_RESET_AUTORUNINITPARAMS
	/// end NLFIT_MODAL_CLEANUP
	///Arvin 03/03/08 QA-11206 CLEAN_PREVIEW_CTRL_CLASSES
	/*
	bool		bIsPFM = false;
	/// ML 12/18/2006 FITWORKAREA_MISSING_ERROR
	//TreeNode 	trPFM = trOp.FitWorkArea.PFM.Peaks;
	//if(trPFM && trPFM.FirstNode)
	//	bIsPFM = true;
	if (trOp.FitWorkArea)
	{
		TreeNode 	trPFM = trOp.FitWorkArea.PFM.Peaks;
		if(trPFM && trPFM.FirstNode)
			bIsPFM = true;
	}
	/// end FITWORKAREA_MISSING_ERROR
	if(bIsPFM)
	{
		///Jasmine 11/07/07 MOVE_MULFUNC_FITSESSION_TO_SEPARATE_FILE
		//m_pFitSession = new MulFuncsFitSession(false);
		error_report("PFM should use FitPeak not FitNL");
		///End MOVE_MULFUNC_FITSESSION_TO_SEPARATE_FILE
	}
	else
	{
		m_pFitSession = new NLFitSession(false, true); //bool bDeleteFitCurvesOnFinish, bool bPreview 
	}
	*/
		//get FitSession pointer from trOp
	
	///Jasmine 03/08/08 REUSE_FITSESSION_IN_PAW_OR_SPFW
	bool bUseExisting = false;
	DWORD dwFitSession;
	
	if(trOp.FitWorkArea && trOp.FitWorkArea.FitPointer)
	{
		TreeNode trFitPointer = trOp.FitWorkArea.FitPointer;
		dwFitSession = trFitPointer.nVal;
		bUseExisting = true;
	}
	
	if(bUseExisting)
	{
		/// Folger, 11/25/08, better try/catch to avoid casting runtime error
		try
		{
			m_pFitSession = (NLFitSession*)dwFitSession;
		}
		catch ( int nErr )
		{
			ASSERT(false);
			return;
		}
		if(m_pFitSession)
		///Sophy 9/24/2008 NEW_PA use existing session, not allow to destroy it in operation
			//return;
		{
			m_bUseFitSession = true;
			return;
				
		}
		///end NEW_PA
	}
	///End REUSE_FITSESSION_IN_PAW_OR_SPFW

	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	/*
	int nFitType = GetFitType(trOp);
	switch(nFitType)
	{
	case NLFIT_GENERAL_XY_FITTING:
		m_pFitSession = new NLFitSession(false, true); //bool bDeleteFitCurvesOnFinish, bool bPreview
		break;
	case NLFIT_XYZ_FITTING:
		m_pFitSession = new XYZSurfaceFitSession(false, true); //bool bDeleteFitCurvesOnFinish, bool bPreview
		break;
	case NLFIT_MATRIX_FITTING:
		m_pFitSession = new MatSurfaceFitSession(false, true); //bool bDeleteFitCurvesOnFinish, bool bPreview
		break;
	default:
		break;
	}
	*/
	m_pFitSession = new NLFitSession();
	/// end FITNL_USING_NEW_NLFSESSION
	///end CLEAN_PREVIEW_CTRL_CLASSES
}

///Cheney 2007-8-1 CORRECT_LOGIC_OF_LOADING_THEME	
//virtual
void	FitNL::ThemeUpdateLastUsed(LPCSTR lpcszClassName, TreeNode& tr, bool bThemesTree)
{
	/// Iris 4/30/2008 QA80-10442 WANT_REMEMBER_X_DATA_TYPE_IN_THEME
	/*
	///Arvin 09/29/07 SHOULD_NOT_REMOVE_XDATATYPE_TREE_NODE_FROM_OPERATION_TREE
	///Cheney 2007-9-28 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_INTO_THEME_AS_MAX_SAID	
	//TreeNode trXDataType = tr.Graph1.XDataType;
	//if(trXDataType)
		//trXDataType.Remove();
	//TreeNode trYDataType = tr.Graph1.YDataType;
	//if(trYDataType)
		//trYDataType.Remove();
	/////end XDATATYPE_SHOULD_NOT_SAVE_INTO_THEME_AS_MAX_SAID			
	///Arvin 12/24/07 QA70-10442 XDATATYPE_SHOULD_NOT_SAVE_DATATYPE_ATTRIB_INTO_THEME
	//TreeNode trGUI = tr.Clone();
	//TreeNode trXDataType = trGUI.Graph1.XDataType;
	//if(trXDataType)
		//trXDataType.Remove();
	//TreeNode trYDataType = trGUI.Graph1.YDataType;
	//if(trYDataType)
		//trYDataType.Remove();
	TreeNode trGUI = tr.Clone();
	remove_datatype_attrib_from_theme(trGUI);
	///end XDATATYPE_SHOULD_NOT_SAVE_DATATYPE_ATTRIB_INTO_THEME		
	///end SHOULD_NOT_REMOVE_XDATATYPE_TREE_NODE_FROM_OPERATION_TREE
	
	/// Hong 10/17/07 QA80-10499 NLFIT_LAST_USED_THEME_SHOULD_SAVE_ALL_SETTING
	//TreeNode trSrc;
	//trSrc = m_pFitSession->GetOriginalSettingTree();
	//theme_update_last_used(lpcszClassName, trGUI, bThemesTree, trSrc);
	theme_update_last_used(lpcszClassName, trGUI, bThemesTree);
	/// end NLFIT_LAST_USED_THEME_SHOULD_SAVE_ALL_SETTING
	*/
	theme_update_last_used(lpcszClassName, tr, bThemesTree);
	///end WANT_REMEMBER_X_DATA_TYPE_IN_THEME
}
///end CORRECT_LOGIC_OF_LOADING_THEME
///Sophy 6/23/2008 FIX_MATRIX_FIT_RUNTIME_WHEN_ACTIVE_OUTPUT_PANEL
string	FitNL::getSourcePageName( TreeNode trOp, TreeNode trInput,  int nFitType )
{
	DataRange	dr, drSub;
	string		strBook;
	if( NLFIT_GENERAL_XY_FITTING!= nFitType )
	{
		drSub.Create( trInput, FALSE );
	}
	else
	{
		nlsf_init_datarange( dr, trInput );
		if( !dr.IsValid() )
			return strBook;
		dr.GetSubRange( drSub, GetDataRules( trOp ), 0 );
	}
	if( !drSub.IsValid() || drSub.GetNumRanges() == 0 )
		return strBook;
	
	return nlsf_get_source_page_name(drSub, nFitType);
}
///end FIX_MATRIX_FIT_RUNTIME_WHEN_ACTIVE_OUTPUT_PANEL
///Cheney 2007-8-23 QA70-10290 FITCURVE_AND_REPORT_SHOULD_BE_SAME_BOOK_IF_SRC_DATA_FROM_DIFF_BOOK
//virtual 
string	FitNL::GetSourcePageName(TreeNode& trOp, Datasheet& ds)
{
	///Sophy 6/23/2008 FIX_MATRIX_FIT_RUNTIME_WHEN_ACTIVE_OUTPUT_PANEL
	/*
	TreeNode trInput = trOp.GUI.InputData;
	DataRange dr, drSub;
	string strBook;
	
	int nFitType = GetFitType(trOp);
	if(nFitType != NLFIT_GENERAL_XY_FITTING)
	{
		drSub.Create(trInput, FALSE);
	}
	else
	{
		nlsf_init_datarange(dr, trInput);
		if( !dr.IsValid() )
			return strBook;
		
		dr.GetSubRange(drSub, GetDataRules(trOp), 0);
	}
	if( !drSub.IsValid() || drSub.GetNumRanges() == 0)
		return strBook;
	
	///Cheney 2007-10-15 QA70-10522-P4 CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING 
	//Datasheet dstemp;
	//if(NLFIT_MATRIX_FITTING == nFitType)
	//{
		//MatrixLayer ml;
		//drSub.GetParent(ml);
		//if(!ml)
			//return strBook;
		//dstemp = ml;
		//return 	dstemp.GetName(); 
	//}
	//else
	//{
		//Worksheet wks;
		//drSub.GetParent(wks);
		//if(!wks)
			//return strBook;
		//dstemp = wks;
	//}
	//strBook = WksReportOperation::GetSourcePageName(trOp, dstemp);
	//return strBook;
	return nlsf_get_source_page_name(drSub, nFitType);
	///end CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING
	*/
	TreeNode	trInputData = trOp.GUI.InputData;
	int			nFitType = GetFitType(trOp);
	
	return getSourcePageName(trOp,trInputData, nFitType );
	///end FIX_MATRIX_FIT_RUNTIME_WHEN_ACTIVE_OUTPUT_PANEL
}
///end FITCURVE_AND_REPORT_SHOULD_BE_SAME_BOOK_IF_SRC_DATA_FROM_DIFF_BOOK

///Cheney 2007-9-21 QA70-10376 MATRIX_FTTING_SUPPORT_GET_MISSING_DATA_IN_REPORT
//virtual  
void	FitNL::PrepareMissingOrMaskedTable(TreeNode& trTable, TreeNode& trRows, 
			LPCSTR lpcszTagRows, int idRows, TreeNode& trMain, LPCSTR lpcszTagMain, int idMain,
			LPCSTR lpcszTableLabel, TreeNode& trCols, LPCSTR lpcszTagCols, int idCols)
{
	Tree trOp;
	GetTree(trOp);
	
	if(NLFIT_MATRIX_FITTING != GetFitType(trOp))
	{
		WksReportOperation::PrepareMissingOrMaskedTable(trTable, trRows, lpcszTagRows, idRows, trMain, lpcszTagMain, idMain,
			lpcszTableLabel, trCols, lpcszTagCols, idCols);
		return;		
	}
			
	trRows = tree_check_get_node(trTable, lpcszTagRows, idRows, STR_LABEL_ATTRIB, _L("Rows"));
	trCols = tree_check_get_node(trTable, lpcszTagCols, idCols, STR_LABEL_ATTRIB, _L("Cols"));
	trMain = tree_check_get_node(trTable, lpcszTagMain, idMain, STR_LABEL_ATTRIB, lpcszTableLabel);
}

//virtual  
int	FitNL::GetMissingDataAndIndex(const DataRange& dr, LPCSTR lpcszXDataLabel, DWORD dwRules, int index,
			vector<int>& vintRows, vector& vMain, vector& vX, matrix& mMultiIndep, vector& vWeight, 
			vector& vYIndep, vector<int>& vintCols)
{
	Tree trOp;
	GetTree(trOp);
	
	if(NLFIT_MATRIX_FITTING != GetFitType(trOp))
		return WksReportOperation::GetMissingDataAndIndex(dr, lpcszXDataLabel, dwRules, index,
					vintRows, vMain, vX, mMultiIndep, vWeight, vYIndep, vintCols);
	
	int nRet = -1;
	MatrixLayer ml;
	dr.GetParent(ml);
	if(!ml)	
		return nRet;
	
	MatrixObject mo(ml, 0);
	double dXMin, dYMin, dXMax, dYMax;
	mo.GetXY( dXMin, dYMin, dXMax, dYMax);
	
	matrixbase& mat = mo.GetDataObject();
	int nRows = mat.GetNumRows();
	int nCols = mat.GetNumCols();
	double dXInc = (dXMax - dXMin) / (nCols - 1);
	double dYInc = (dYMax - dYMin) / (nRows - 1);
	
  	nRet = dr.GetMissingData(dwRules, index, &vintRows, NULL, NULL, NULL, NULL, NULL, &vintCols);  
	if(nRet < 0)
		return nRet;
  	
	int nSize = vintRows.GetSize();
	for(int ii = 0; ii < nSize; ii++)
	{
		int nRowIndex = vintRows[ii];
		int nColIndex = vintCols[ii];
		vX.Add(dXMin + (nColIndex - 1)*dXInc );
		vYIndep.Add(dYMin + (nRowIndex - 1)*dYInc );
	}
	vMain.SetSize(nSize);
	vMain = NANUM;
	
  	return nRet;
}

//virtual
bool FitNL::AddColsIndexToMissingDataTable(TreeNode& trCol, const vectorbase& vData, int nBaseID, LPCSTR lpcszRowLabel, int* pRowStart)
{
	Tree trOp;
	GetTree(trOp);
	
	if(NLFIT_MATRIX_FITTING != GetFitType(trOp))
		return WksReportOperation::AddColsIndexToMissingDataTable(trCol, vData, nBaseID, lpcszRowLabel);

	return 	AddRowsToMaskedOrMissingDataTable(trCol, vData, nBaseID, lpcszRowLabel);
}
///end MATRIX_FTTING_SUPPORT_GET_MISSING_DATA_IN_REPORT

///Cheney 2007-10-15 QA70-10522-P4 CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING 
//virtual
int		FitNL::GetReportOutPutDestination(const TreeNode& trInput)
{
	Tree trOp;
	GetTree(trOp);
	if(NLFIT_MATRIX_FITTING == GetFitType(trOp))
		return PDS_NEW;
	return WksReportOperation::GetReportOutPutDestination(trInput);
}

//virtual
/// Hong 04/15/08 v8.0843 FITTED_DATA_AUTO_SHOULD_TRY_SOURCE_BEFORE_USING_NEW
//int		FitNL::GetDataOutPutDestination(const TreeNode& trOutput, string& strReportBook, Worksheet* pwksReport)
///Sophy 6/2/2008 ADD_SOURCE_BOOK_FOR_PLOT_DATA_REDISUAL_ON_MATRIX_FIT
//int		FitNL::GetDataOutPutDestination(const TreeNode& trOutput, const TreeNode& trInput, string& strReportBook, Worksheet* pwksReport)
int		FitNL::GetDataOutPutDestination( TreeNode& trOp, const TreeNode& trOutput, const TreeNode& trInput, string& strReportBook, Worksheet* pwksReport)
///end ADD_SOURCE_BOOK_FOR_PLOT_DATA_REDISUAL_ON_MATRIX_FIT
/// end FITTED_DATA_AUTO_SHOULD_TRY_SOURCE_BEFORE_USING_NEW
{
	///Sophy 6/2/2008 ADD_SOURCE_BOOK_FOR_PLOT_DATA_REDISUAL_ON_MATRIX_FIT
	//Tree trOp;
	//GetTree(trOp);
	///end ADD_SOURCE_BOOK_FOR_PLOT_DATA_REDISUAL_ON_MATRIX_FIT
	strReportBook.Empty();
	/// Hong 06/23/08 QA80-10536 FIX_ABNORMAL_BOOK_SHOULD_NOT_OUTPUT_TO_SOURCE
	/*
	///Sophy 6/3/2008 FIX_GET_OPERATION_TREE_FAILURE
	if( !trOp )
		return PDS_SOURCE;
	///end FIX_GET_OPERATION_TREE_FAILURE
	///Cheney 2007-10-19 QA70-10536 FIX_EIGHT_PROBLEMS_REPORT_BY_MAX
	//----- CPY 10/15/07 XYZ_FITTING_CREATED_WKS_INSTEAD_OF_MAT_BOOK
	//if(NLFIT_XYZ_FITTING == GetFitType(trOp))
	//int nn;
	//if((nn = GetFitType(trOp)) == NLFIT_XYZ_FITTING || NLFIT_MATRIX_FITTING == nn)
	//int nFitType = GetFitType(trOp); ///Sophy 6/3/2008 useless code
	if( GetFitType(trOp) == NLFIT_MATRIX_FITTING )
	{
		strReportBook = GetSourcePageName(trOp);
		return strReportBook.IsEmpty()? PDS_NEW : PDS_SOURCE;
	}
	*/
	// the operation tree is not correct when come from event of GUI from outputmanager, it must be fixed but too later for SR2
	// so i temp fix it by get from session which may still have problem but better than before
	int		nFitType;
	if ( m_pFitSession )
		nFitType = GetFitSession()->GetFitType();
	else if ( trOp )
		nFitType = GetFitType(trOp);
	else
		return PDS_SOURCE;
	
	if ( NLFIT_MATRIX_FITTING == nFitType )
	{
		///Sophy 6/23/2008 FIX_MATRIX_FIT_RUNTIME_WHEN_ACTIVE_OUTPUT_PANEL
		//strReportBook = GetSourcePageName(trOp);
		if( trOp )
			strReportBook = GetSourcePageName( trOp );
		else
		{
			GetTree( trOp );
			strReportBook = getSourcePageName( trOp, trInput,  nFitType );
		}
		///end FIX_MATRIX_FIT_RUNTIME_WHEN_ACTIVE_OUTPUT_PANEL
		return strReportBook.IsEmpty()? PDS_NEW : PDS_SOURCE;
	}
	/// end FIX_ABNORMAL_BOOK_SHOULD_NOT_OUTPUT_TO_SOURCE
	/// Iris 3/15/2008 QA80-11244 SHOULD_NOT_OUTPUT_DATA_TO_MATRIX_FOR_XYZ_FITTING, report xyz fitted curve to worksheet replace of matrix, so the settings here same as normal xy fitting
	/*
	else if( GetFitType(trOp) == NLFIT_XYZ_FITTING )
	///end FIX_EIGHT_PROBLEMS_REPORT_BY_MAX
	//-----
		return PDS_NEW;
	*/
	///end SHOULD_NOT_OUTPUT_DATA_TO_MATRIX_FOR_XYZ_FITTING
	/// Hong 04/15/08 v8.0843 FITTED_DATA_AUTO_SHOULD_TRY_SOURCE_BEFORE_USING_NEW
	//return WksReportOperation::GetDataOutPutDestination(trOutput, strReportBook, pwksReport);
	///Sophy 6/2/2008 ADD_SOURCE_BOOK_FOR_PLOT_DATA_REDISUAL_ON_MATRIX_FIT
	//return WksReportOperation::GetDataOutPutDestination(trOutput, trInput, strReportBook, pwksReport);
	return WksReportOperation::GetDataOutPutDestination( trOp, trOutput, trInput, strReportBook, pwksReport);	
	///end ADD_SOURCE_BOOK_FOR_PLOT_DATA_REDISUAL_ON_MATRIX_FIT
	/// end FITTED_DATA_AUTO_SHOULD_TRY_SOURCE_BEFORE_USING_NEW
}
///end CLEAN_CODE_AND_ADD_AUTO_FOR_OUTPUT_SETTING

///Cheney 2007-11-2 QA70-10626 ADD_REPLICA_INFO_IN_REPORT_TABLE

//------ Folger 11/28/08 v8.0980 CLEAN_UP_REPLICA_FITTING_JUDGEMENT
/*
/// Hong 12/26/07 QA80-10499 FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
//bool		FitNL::isReplicaFit(const TreeNode& trOp)
bool		FitNL::isReplicaFit(const TreeNode& trOp, bool bCheckHasReplica) // true
/// end FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
{
	///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
	//TreeNode trReplica = trOp.GUI.Fit.Replica;
	//------ 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
	///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
	if(!trReplica)
		return false;
	
	TreeNode trReplicaNum = trReplica.Number;
	if(!trReplicaNum)
		return false;
	///Cheney 2007-11-9 QA70-10626 FIX_SOME_BUGS_OF_ADD_REPLICA_INFO_IN_REPORT_TABLE
	//return trReplica.Enable && trReplicaNum.nVal > 0;	
	/// Hong 12/26/07 QA80-10499 FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
	//return trReplica.Enable;	
	/// Hong 04/21/08 v8.0846c FIX_REPLICA_FIT_REPORT_FAIL_GET_CORRECT_DATASET_NAME
	//bool bRet = trReplica.Enable == 1;	
	bool	bRet = true;
	int		nEnable;
	if ( trReplica.GetAttribute(STR_ENABLE_ATTRIB, nEnable) && (DISABLE == nEnable) )
		bRet = false;
	/// end FIX_REPLICA_FIT_REPORT_FAIL_GET_CORRECT_DATASET_NAME	
	if (bCheckHasReplica)
		bRet = bRet && trReplicaNum.nVal > 0;
	return bRet;
	/// end FIX_MULTIDATASET_LOST_THEME_VALUE_WHEN_FROM_MRU_WITHOUT_DIALOG_EXCEPT_FIRST_ONE
	///end FIX_SOME_BUGS_OF_ADD_REPLICA_INFO_IN_REPORT_TABLE
}
*/
bool		FitNL::isReplicaFitSupported(const TreeNode& trOp)
{
	TreeNode trReplica = get_gui_replica_node(trOp.GUI);
	if(!trReplica)
		return false;
	
	return trReplica.Enable == DISABLE ? false : true;
}

virtual bool		FitNL::isReplicaFit(const TreeNode& trOp)
{
	if ( !isReplicaFitSupported(trOp) )
		return false;
	
	TreeNode trReplica = get_gui_replica_node(trOp.GUI);
	ASSERT(trReplica);
	
	TreeNode trReplicaNum = trReplica.Number;
	if(!trReplicaNum)
		return false;
	
	return trReplicaNum.nVal > 0 ? true : false;
}

//------ End CLEAN_UP_REPLICA_FITTING_JUDGEMENT

bool		FitNL::addReplicaInfoOnStatsTable(TreeNode& trOp, int nIndex, const string& strDataLabel, int nNumData)
{
	TreeNode		trCal = trOp.Calculation;
	TreeNode		trTable = tree_check_get_node(trCal, "RegStats", IDST_REG_STATS_RESULTS);
	TreeNode		trRow = check_add_enumerated_node(trTable, CALCULATION_REPORT_TABLE_COL_PREFIX, nIndex + 1, IDST_TEMP_ONE_SET, STR_LABEL_ATTRIB, strDataLabel);

	TreeNode trStatistics = trOp.GUI.Quantities.Statistics;
	if(!trStatistics)
		return false;
	
	TreeNode trFitStatus = trRow.FitStatus;
	if(!trFitStatus)
		return false;	
	int nID = trFitStatus.ID;			
		
	TreeNode trReplicaNum = trStatistics.ReplicaNum;	
	if(trReplicaNum && trReplicaNum.nVal)
	{
		TreeNode tr = tree_check_get_node( trRow, "ReplicaNum", ++nID, STR_LABEL_ATTRIB, STR_NUMBER_OF_REPLICA );
		//tr.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
		///Cheney 2007-11-9 QA70-10626 FIX_SOME_BUGS_OF_ADD_REPLICA_INFO_IN_REPORT_TABLE
		//tr.nVal = trReplicaNum.nVal;
		///Arvin 03/25/08 MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH as CP said
		//TreeNode trTemp = trOp.GUI.Fit.Replica.Number;
		//------ Folger 11/06/08 QA80-12538 v0.966 CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		//TreeNode trTemp = trOp.GUI.Replica.Number;
		TreeNode trTemp = get_gui_replica_node(trOp.GUI).Number;
		//------ End CENTRALIZE_CODE_ABOUT_GETTING_GUI_REPLICA_NODE
		///end MOVE_REPLICA_BARANCH_OUT_OF_FIT_CONTROL_BRANCH
		if(!trTemp)
			return false;
		tr.nVal = trTemp.nVal;
		///end FIX_SOME_BUGS_OF_ADD_REPLICA_INFO_IN_REPORT_TABLE
		tr.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);///Sophy 3/30/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
	}
	
	TreeNode trParamsFromNum = trStatistics.ParamsFromNum;
	if(trParamsFromNum && trParamsFromNum.nVal)
	{
		TreeNode tr = tree_check_get_node( trRow, "ParamsFromNum", ++nID, STR_LABEL_ATTRIB, STR_REPLICATE_FROM_NTH_PARAMS );
		//tr.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
		TreeNode trDuplicateOffset = m_trFDF.Controls.DuplicateOffset;
		if(!trDuplicateOffset)
			return false;
		tr.nVal = trDuplicateOffset.nVal;
		tr.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);///Sophy 3/30/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
	}
	
	TreeNode trParamsUsed = trStatistics.ParamsUsed;
	if(trParamsUsed && trParamsUsed.nVal)
	{
		TreeNode tr = tree_check_get_node( trRow, "ParamsUsed", ++nID, STR_LABEL_ATTRIB, STR_NUM_OF_PARAMS_USED_IN_REPLICA );
		//tr.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);
		TreeNode trDuplicateUnit = m_trFDF.Controls.DuplicateUnit;
		if(!trDuplicateUnit)
			return false;
		tr.nVal = trDuplicateUnit.nVal;
		tr.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_Y);///Sophy 3/30/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
	}
	
	return true; 
}
///end ADD_REPLICA_INFO_IN_REPORT_TABLE

///Cheney 2007-11-16 ONLY_NLFIT_XYFITTING_SHOW_REPLICA_RELATED_CHECK_BOX
bool		FitNL::hideReplicaRelatedNode(TreeNode& trStatistics)
{
	if(!trStatistics)
		return false;
	
	if(trStatistics.ReplicaNum)
		trStatistics.ReplicaNum.Show = false;
	
	if(trStatistics.ParamsFromNum)
		trStatistics.ParamsFromNum.Show = false;
	
	if(trStatistics.ParamsUsed)
		trStatistics.ParamsUsed.Show = false;
	
	return true;
}	
///end ONLY_NLFIT_XYFITTING_SHOW_REPLICA_RELATED_CHECK_BOX

/// Hong 05/30/08 QA80-11632 FIX_SURFACE_FIT_REPORT_FIT_CURVE_FAIL_CORRECT_RESCALE
// virtual
bool 		FitNL::IsFitCurveFollowSourcePlotType()
{
	TreeNode 	trOp;
	GetTree(trOp);	
	int 		nFitType = GetFitType(trOp);
	if ( NLFIT_XYZ_FITTING == nFitType || NLFIT_MATRIX_FITTING == nFitType )
		return false;
	
	return true;
}
/// end FIX_SURFACE_FIT_REPORT_FIT_CURVE_FAIL_CORRECT_RESCALE

/// Jack 12/19/2008 QA80-12329 MULTI_INDEP_DEPS_BAND_CALCULATION
bool FitNL::CalcConfOrPredBounds(TreeNode &trOp, bool bConf, double dBoundLevel, vector& vLower, vector& vUpper, matrix& mIndeps, vector &vFitY, GraphLayer& grLayAppar, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, vector& vSE, int index, int iDep)
{
		return m_pFitSession->CalcConfAndPredBands(mIndeps, dBoundLevel/100.0, vLower, vUpper, bConf, iDep, index);
}
/// End MULTI_INDEP_DEPS_BAND_CALCULATION

///Arvin 01/11/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS
bool FitNL::CalcConfOrPredBounds(TreeNode &trOp, bool bConf, double dBoundLevel, vector& vLower, vector& vUpper, vector& vIndep1, vector &vFitY, GraphLayer& grLayAppar, FitParameter* psFitParameter, RegStats &stRegStats, RegCalcInternal* pstReg, vector& vSE, vector& vIndep2, int index)
{
	/// Hong 09/05/08 v8.093cc FITNL_USING_NEW_NLFSESSION
	/*
	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;
	}
	return m_pFitSession->CalcConfAndPredBands(vMultiIndeps, nNumIndep, dBoundLevel/100.0, vLower, vUpper, bConf, 0);
	*/
	/// Jack 10/20/08 QA70-10923 CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
	//return m_pFitSession->CalcConfAndPredBands(vIndep1, dBoundLevel/100.0, vLower, vUpper, bConf, 0, vIndep2);
	return m_pFitSession->CalcConfAndPredBands(vIndep1, dBoundLevel/100.0, vLower, vUpper, bConf, 0, vIndep2, index);
	/// End CALC_CONFIDENCE_AND_PREDICTION_BANDS_FOR_GLOBAL_FIT
	/// end FITNL_USING_NEW_NLFSESSION
}
///end CALC_CONFIDENCE_AND_PREDICTION_BANDS

/// Hong 09/04/09 QA80-14258 HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING
//virtual 
int		FitNL::InitFromSelection(TreeNode &trOperation)
{
	GraphLayer		gl = Project.ActiveLayer();
	if ( gl )
	{
		DataPlot	dp = gl.DataPlots();
		if ( dp && IDM_PLOT_HISTOGRAM_TYPE == dp.GetPlotType() )
		{
			OptionalMessage("NLFitHistogramHint", MB_OK);
			return -1;
		}
	}
	return FitterOperation::InitFromSelection(trOperation);
}
/// end HISTOGRAM_NEED_SPECIAL_HINT_FOR_DOING_NLFITTING

//------ Folger 12/11/08 QA80-12766 v8.0985 SIGNIFICANT_DIGITS_FAILS_TO_APPLY_TO_NLSF_FITTING_REPORT
/// virtual
///------ Folger 12/22/08 QA80-12766-P2 v8.0990 SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
//int		FitNL::GetSignDigitsArray(vector<int>& vnSignDigits)
int		FitNL::GetSignDigitsArray(vector<int>& vnSignDigits, int nDataIndex/* = 0*/)
///------ End SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
{
	GetFitSession()->GetParamNumericValues(vnSignDigits, PARMAS_SETTING_SIGN_DIGITES);
	///------ Folger 12/22/08 QA80-12766-P2 v8.0990 SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
	if ( nDataIndex > 0 )		/// multiple datasets
	{
		vnSignDigits.GetSubVector(vnSignDigits, GetFitSession()->GetNumParameter() * nDataIndex);
	}
	///------ End SIGNIFICANT_DIGITS_NOT_WORKING_FOR_MULTIPLE_DATASETS_REPORT
	return vnSignDigits.GetSize();
}
//------ End SIGNIFICANT_DIGITS_FAILS_TO_APPLY_TO_NLSF_FITTING_REPORT

///Arvin 01/29/08 GENERATE_REPORT_FOR_LT_NLFit
/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
//BOOL 	FitNL::GetExecuteCtrl(const TreeNode& trFitWorkArea, DWORD& dwExecCntrl)
//virtual
BOOL 	FitNL::GetExecuteCtrl(const TreeNode& trOperation, DWORD& dwExecCntrl)
/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
{
	/// Hong 01/12/10 QA80-14948 NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	//if(!trFitWorkArea)
	//	return FALSE;
	if ( !trOperation )
		return FALSE;
	
	TreeNode		trGUI = trOperation.GUI;
	int				nForceCalculatingOutput = 0;
	if ( trGUI.GetAttribute(STR_FITTING_NO_FIT_AGAIN, nForceCalculatingOutput) )
	{
		dwExecCntrl |= OPEXEC_NO_FIT_AGAIN;
		/// Hong 01/12/10 QA80-14948-P2 FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT
		dwExecCntrl |= OPEXEC_NO_INIT_FROM_OP_AGAIN;
		dwExecCntrl |= OPEXEC_NO_PARAM_INIT;
		/// end FIX_NLFIT_OK_DTN_FAIL_KEEP_LAST_ITERATE_COUNT
		if ( 1 == nForceCalculatingOutput )
			dwExecCntrl |= OPEXEC_FORCE_CALCUTE_OUTPUT;
		trGUI.RemoveAttribute(STR_FITTING_NO_FIT_AGAIN);
	}
	
	TreeNode		trFitWorkArea = trOperation.FitWorkArea;
	if ( !trFitWorkArea )
		return TRUE;
	/// end NLFIT_SUPPORT_OK_BTN_WHICH_DONOT_FIT_AGAIN
	int nFromLTNLFIT = 0;
	if(trFitWorkArea.GetAttribute(STR_LT_NLFIT_CLASS_ATTRIB, nFromLTNLFIT) && nFromLTNLFIT)
		dwExecCntrl |= OPEXEC_NO_PARAM_INIT | OPEXEC_NO_FIT_AGAIN;
	
	int nNoInitAgain = 0;
	if(trFitWorkArea.GetAttribute(STR_NO_INIT_FROM_OP_ATTRIB, nNoInitAgain) && nNoInitAgain)
		dwExecCntrl |= OPEXEC_NO_INIT_FROM_OP_AGAIN;
	
	return TRUE;
}
///end GENERATE_REPORT_FOR_LT_NLFit

///Arvin 02/14/08 QA70-11094 SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL
DWORD FitNL::GetOutputOptions(const TreeNode& trOp)
{
	DWORD dwOptions = FitterOperation::GetOutputOptions(trOp);
	dwOptions |= REPORT_PLOT_ALL_PLOTS_IN_ONE_GRAPH; 
	return dwOptions;
}
///end SUPPORT_PLOT_MULTI_FITTED_CURVES_IN_ONE_GRAPH_IN_LR_PR_AND_FITNL

///Arvin 02/22/08 QA70-11151 SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION	
#ifdef SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION
///---Sim 04-07-2008 QA80-11371 THEME_SAVING_OPTIONS
//bool   FitNL::ConstructParamBranchByThemeTree(const TreeNode& trTheme, TreeNode& trOp, string* pstrSelectedTheme)
//{
	//return nlsf_construct_parameter_branch_by_theme_Tree(trTheme, trOp.GUI);
//}
/*
bool   FitNL::ConstructParamBranchByThemeTree(const TreeNode& trTheme, TreeNode& trGUI)
{
	return nlsf_construct_parameter_branch_by_theme_Tree(trTheme, trGUI);
}
*/
///---END QA80-11371 THEME_SAVING_OPTIONS

#endif
///end SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION

/// Iris 3/26/2008 v8.0832 CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS
bool	FitNL::InitOutputGUIManagerPointer(const TreeNode& trGUI)
{
	if(m_pOutputManager)//already init
		return true;	

	Tree trOp;
	GetTree(trOp);	
	int 	nFitType = GetFitType(trOp);	
	switch(nFitType)
	{
	case NLFIT_GENERAL_XY_FITTING:
		m_pOutputManager = new NLFitOutputGUIManager;
		break;
	case NLFIT_XYZ_FITTING:
		m_pOutputManager = new SurfaceFitOutputGUIManager;
		break;
	case NLFIT_MATRIX_FITTING:
		m_pOutputManager = new MatrixFitOutputGUIManager;
		break;
	default:
		break;
	}
	if(NULL == m_pOutputManager)
		return false;
	
	return true;
}
///END CLEANUP_OUTPUT_BOOK_SHEET_AREA_TO_CLASS

///---Sim 04-07-2008 QA80-11371 THEME_SAVING_OPTIONS
#ifdef SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION
/*
static void _go_through_parent_to_allow_apply(TreeNode& tr, const TreeNode& trRoot)
{
	TreeNode trParent = tr;
	while( trParent.tagName != trRoot.tagName )
	{
		trParent = trParent.Parent();
		if ( !trParent )
			return;
		trParent.SetAttribute(STR_XVARIABLE_THEME_APPLICABILITY_ATTRIB, 0); // allow apply
	}
}

static void _set_apply_attribute(TreeNode& trRoot, int nDestNodeID, bool bApply)
{
	TreeNode trDest;
	if ( nDestNodeID < 0 )
		trDest = trRoot;
	else
		trDest = tree_get_node_by_id(trRoot, nDestNodeID, true);
	if ( !trDest )
		return;
	
	int n = (bApply) ? 0 : XVTA_DO_NOT_APPLY_VALUE|XVTA_DO_NOT_APPLY_ATTRIBUTES;
	string str = n;

	tree_set_attribute_to_all_nodes(trDest, STR_XVARIABLE_THEME_APPLICABILITY_ATTRIB, str);
	
	if ( bApply )
		_go_through_parent_to_allow_apply(trDest, trRoot);
}

static void _set_apply_attribute(TreeNode& trRoot, int nDestNodeID, const TreeNode& trThemeFilter, int nSettingNodeID)
{
	if ( !trThemeFilter || !trRoot )
		return;
	
	TreeNode trSetting = tree_get_node_by_id(trThemeFilter, nSettingNodeID, true);
	if ( !trSetting )
		return;
	
	bool bApply = trSetting.nVal;
	
	_set_apply_attribute(trRoot, nDestNodeID, bApply);
}

//virtual
bool FitNL::ApplyThemeFilterSetting(TreeNode& trGUI, const TreeNode& trThemeFilter)
{
	TreeNode tr;
	
	// other options must be dealt first
	_set_apply_attribute(trGUI, -1, 						trThemeFilter, IDE_NL_THEME_FILTER_OTHER);
	
	// separater options will overwirte trGUI again
	_set_apply_attribute(trGUI, IDE_NLSF_FUNCTION,			trThemeFilter, IDE_NL_THEME_FILTER_FUNC);
	_set_apply_attribute(trGUI, IDE_NL_PARAMS_VALUE_BASE,	trThemeFilter, IDE_NL_THEME_FILTER_PARAMS);
	_set_apply_attribute(trGUI, IDE_NL_PARAMS_FIXED_BASE,	trThemeFilter, IDE_NL_THEME_FILTER_FIXED);
	_set_apply_attribute(trGUI, IDE_NL_PARAMS_SHARE_BASE,	trThemeFilter, IDE_NL_THEME_FILTER_SHARE);
	_set_apply_attribute(trGUI, IDE_NL_PARAMS_LOWER_BOUNDS_BASE,	trThemeFilter, IDE_NL_THEME_FILTER_ULB);
	_set_apply_attribute(trGUI, IDE_NL_PARAMS_UPPER_BOUNDS_BASE,	trThemeFilter, IDE_NL_THEME_FILTER_ULB);
	_set_apply_attribute(trGUI, IDE_NLSF_CODES_CONSTRAINTS,	trThemeFilter, IDE_NL_THEME_FILTER_CONSTRAINTS);
	_set_apply_attribute(trGUI, IDE_NLSF_CODES_AFTERFIT,	trThemeFilter, IDE_NL_THEME_FILTER_SCRIPT);
	_set_apply_attribute(trGUI, IDE_NL_PARAMS_AUTO_INIT,	trThemeFilter, IDE_NL_THEME_FILTER_AUTO_PARAM_INIT);
	_set_apply_attribute(trGUI, IDE_NL_LINEAR_CONSTRAINTS,	trThemeFilter, IDE_NL_THEME_FILTER_ENABLE_LINEAR_CONSTRAINTS);
	
	_set_apply_attribute(trGUI, IDE_DS_THEME_FILTER, true); // theme setting should always been kept
	return true;
}

// virtual
bool FitNL::ApplyTheme(LPCSTR lpcszClassName, TreeNode& trGUI, LPCSTR lpcszThemeName, bool bLoadFactDefault) // = true
{
	if ( !FitterOperation::ApplyTheme(lpcszClassName, trGUI, lpcszThemeName, bLoadFactDefault) )
		return false;
	
	ApplyFDF(trGUI);

	Tree trTheme;
	if ( IsParamInThemeFilter(trGUI) )
	{
		Tree trTmp;
		theme_apply_analysis_theme(lpcszClassName, trTmp, lpcszThemeName, bLoadFactDefault, trTheme);
	}
	ConstructParamBranchByThemeTree(trTheme, trGUI);
	
	return true;
}

bool FitNL::ApplyFDF(TreeNode& trGUI)
{
	// need to do
	return false;
}

bool FitNL::IsParamInThemeFilter(TreeNode& trGUI)
{
	TreeNode trDS = get_external_settings_branch(trGUI);
	
	TreeNode trThemeFilter = tree_get_node_by_id(trDS, IDE_DS_THEME_FILTER, true);
	if ( trThemeFilter )
	{
		TreeNode tr = tree_get_node_by_id(trThemeFilter, IDE_NL_THEME_FILTER_PARAMS, true);
		if ( tr )
		{
			return (tr.nVal);
		}
	}
	
	return true; // default parameters in theme
}
*/
bool FitNL::ApplyTheme(LPCSTR lpcszClassName, TreeNode& trGUI, LPCSTR lpcszThemeName, bool bLoadFactDefault) // = true
{
	///---Sim 09-05-2008 QA80-12151 NLFIT_TOO_SLOW_TO_OPEN
	Tree trJunk;
	nlsf_construct_parameter_branch_by_theme_Tree(trJunk, trGUI); // init parameter
	if ( theme_is_factory_default(lpcszThemeName) )
		return true;
	///---END QA80-12151 NLFIT_TOO_SLOW_TO_OPEN
	return nlsf_apply_theme(lpcszClassName, trGUI, lpcszThemeName, bLoadFactDefault);
}
#endif // SUPPORT_PARAMETERS_BRANCH_DYNAMICAL_ALLOCATION
///---END QA80-11371 THEME_SAVING_OPTIONS

///---Sim 09-10-2008 NLFIT_LABTALK_TREE_ACCESS
void FitNL::SetLTTreeSetting(DWORD dwOption)
{
	m_dwOption = dwOption;
}
virtual	BOOL	FitNL::LabTalkTreeAccess(LPSTR lpVar, LPSTR lpArg, LPVOID lpValue, WORD msg)
{
	/// Hong 09/27/08 FIX_LT_TREE_FAIL_GET_SESSION_PTR
	Tree			trOp;
	GetTree(trOp);
	if ( NULL == m_pFitSession )
		InitFitSessionPointer(trOp);
	/// end FIX_LT_TREE_FAIL_GET_SESSION_PTR
	//out_str("LabTalkTreeAccess");
	NLParametersManager *pNLParamsMngr = GetFitSession()->GetNLParamsMngr();
	ASSERT(pNLParamsMngr);
	if ( pNLParamsMngr->LabTalkTreeAccess(lpVar, lpArg, lpValue, msg, m_dwOption) )
		return TRUE;	
		
	int		nRet = okutil_operation_tree_access(&trOp, lpVar, lpArg, lpValue, msg, m_dwOption|NLFIT_DISPLAY_NO_PARAMS);
	if ( nRet >= 0 )
	{
		if ( 1 == nRet )
			SetTree(trOp);
		return TRUE;
	}
	
	return FALSE;
}
virtual	BOOL	FitNL::MakeLabTalkTree(TreeNode& trLT)
{
	//out_str("MakeLabTalkTree");
	if ( !trLT )
		return FALSE;
	//trLT.Reset();
	//Tree tree;		///------- Folger 03/10/09 INCORRECT_INPUT_DATA_DISPLAY_IN_NLFIT_LT_TREE
	/// Hong 09/27/08 FIX_LT_TREE_FAIL_GET_SESSION_PTR
	Tree			trOp;
	GetTree(trOp);
	if ( NULL == m_pFitSession )
		InitFitSessionPointer(trOp);
	/// end FIX_LT_TREE_FAIL_GET_SESSION_PTR
	
	NLParametersManager *pNLParamsMngr = GetFitSession()->GetNLParamsMngr();
	ASSERT(pNLParamsMngr);
	///------- Folger 03/10/09 INCORRECT_INPUT_DATA_DISPLAY_IN_NLFIT_LT_TREE
	//if ( pNLParamsMngr->MakeLabTalkTree(tree, m_dwOption) )
		//tree_append_children(trLT, tree, ""); // can't pass NULL, will cause runtime error
	
	//tree.Reset();
	//if ( okutil_operation_tree_to_labtalk_tree(&trOp, &tree, m_dwOption|NLFIT_DISPLAY_NO_PARAMS, GetUID()) )
		//tree_append_children(trLT, tree, ""); // can't pass NULL, will cause runtime error
	trLT.Reset();
	
	Tree	trParams;
	bool	bGetParamsOK = pNLParamsMngr->MakeLabTalkTree(trParams, m_dwOption);	
	
	Tree	trStats;
	bool	bGetStatsOK = false;
	if ( (bGetStatsOK = okutil_operation_tree_to_labtalk_tree(&trOp, &trStats, m_dwOption|NLFIT_DISPLAY_NO_PARAMS, GetUID())) )
	{
		TreeNode trNode = trStats.FirstNode;
		while ( trNode.tagName.Match("Data*") )
		{
			trLT.AddNode(trNode);
			TreeNode	trTmp = trNode;
			trNode = trNode.NextNode;
			trTmp.Remove();
		}
	}
	
	if ( bGetParamsOK )
		tree_append_children(trLT, trParams, "");
	if ( bGetStatsOK )
		tree_append_children(trLT, trStats, "");
	///------- End INCORRECT_INPUT_DATA_DISPLAY_IN_NLFIT_LT_TREE
	
	return TRUE;
}
///---END NLFIT_LABTALK_TREE_ACCESS

/// Hong 10/17/08 QA80-10624 NLFIT_SUPPORT_FIT_SWAPPED_POLAR_PLOT
// virtual 
//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
/*
uint		FitNL::GetPlotCtrl()
{
	return GetNLFCurvePointer()->GetFitCurvePlotCtrl( GetFitSession()->GetDataObject() );
}
*/
uint		FitNL::GetPlotCtrl(TreeNode& trOp)
{
	TreeNode	trPlotCntrl = trOp.GetNode("SpecPlotCntrl");
	
	if ( m_pFitSession )
	{
		uint		nPlotCntrl = GetNLFCurvePointer()->GetFitCurvePlotCtrl( GetFitSession()->GetDataObject() );
		if ( !trPlotCntrl )
		{
			trOp.SpecPlotCntrl.nVal = nPlotCntrl;
		}
		return nPlotCntrl;
	}
	
	return trPlotCntrl ? trPlotCntrl.nVal : 0;
}
//------ End SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET

/// end NLFIT_SUPPORT_FIT_SWAPPED_POLAR_PLOT

///Sophy 12/23/2008 v8.0990 QA80-12832 SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING when check whether plot is in datarange, number of ranges in datarange should depend on number of depends
//virtual
void	FitNL::FilterDataRulesForPlot(DWORD& dwDataRules)
{
	dwDataRules &= ~DRR_NLFIT;
	return;
}
///end SUPPORT_MULTI_DATASET_FOR_MULTI_INDEPS_AND_DEPS_FITTING


///Sophy 7/7/2009 v8.1058 QA80-12613-P6 FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING
bool	FitNL::UpdateOneYColumnFormat(TreeNode& trCol, int nIndex)
{
	XYRange xyRange;
	GetInput(xyRange);
	if ( !trCol || !xyRange )
		return false;
	
	Column colY;
	if ( xyRange.GetYColumn(colY, nIndex) )
		return trCol.SetAttribute(STR_COL_FORMAT_ATTRIB, colY.GetFormat());
}
///end FITCURVE_Y_COLUMN_FORMAT_MUST_BE_CONSISTENT_WITH_SOURCE_DATA_IN_3D_FITTING


///Sophy 10/27/2008 USE_NLFCURVES_TO_PLOT_IN_REPORT_GRAPH
//bool		FitNL::PlotSourceDataInLayer(int nDataIndex, TreeNode& trPlotInfo, TreeNode& trOp, GraphLayer& gl, int nGraphIndex, int nXIndex, int nYIndex)
/////end ONLY_RECALCULATE_TIME_NEED_CHECK_RESCALE_IF_DATA_OUTSIDE
//{
	//int nPlot;
	//GetNLFCurvePointer()->PlotSourceCurve( gl, nDataIndex );
	//return ( nPlot >= 0 );
//}
///end USE_NLFCURVES_TO_PLOT_IN_REPORT_GRAPH


//----------- Iris 11/20/2008 v8.0975d QA80-12591-P4 REMOVE_LOG_DATA_TYPE_WHEN_DATA_FROM_MATRIX
//virtual
void 		FitNL::FilterTreeForGUI(TreeNode& trOp)
{
	///Sophy 7/8/2009 v8.1060 CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
	/*
	change_indep_data_type_combo_on_source_page_type(trOp.GUI);
	///Sophy 11/24/2008 v8.978c CHECK_SET_XDATATYPE_VALUE_ON_APPLY_THEME
	check_set_xdatatype_value(trOp.GUI);
	///end CHECK_SET_XDATATYPE_VALUE_ON_APPLY_THEME
	///Sophy 12/11/2008 v8.984d NLFIT_XDATATYPE_SHOULD_BE_SOURCE_GRAPH_SCALE_TYPE_AS_LR_WHEN_DATA_FROM_GRAPH
	check_set_xdatatype_on_source_graph(trOp.GUI);
	///end NLFIT_XDATATYPE_SHOULD_BE_SOURCE_GRAPH_SCALE_TYPE_AS_LR_WHEN_DATA_FROM_GRAPH
	*/
	///Sophy 7/22/2009 v8.1073 NANOSIZER_NEED_TO_GET_ORIGINAL_INPUTDATA
	//check_set_datatype(trOp.GUI, true);
	//check_set_datatype(trOp.GUI, false);
	///Jasmine 05/24/10 SRVC-12 ALLOW_SAME_AS_INPUT_FOR_ALL_SURFACE_FIT
	//check_set_datatype(trOp.GUI, GetInputDataNode(trOp.GUI), true);
	//check_set_datatype(trOp.GUI, GetInputDataNode(trOp.GUI), false);
	check_set_datatype(trOp.GUI, GetInputDataNode(trOp.GUI), GetFitType(trOp), true);
	check_set_datatype(trOp.GUI, GetInputDataNode(trOp.GUI), GetFitType(trOp), false);
	///End ALLOW_SAME_AS_INPUT_FOR_ALL_SURFACE_FIT
	///end NANOSIZER_NEED_TO_GET_ORIGINAL_INPUTDATA
	///end CLEAN_CODE_SUPPORT_UPDATE_Y_DATATYPE_BRANCH
}
//-----------
