11.3.3 How to Create a Wizard

Summary

A wizard is a graphical user interface that includes a series of dialogs to direct a user to complete a mission step by step. A wizard makes a complex task easier to perform. Origin provides several classes in Origin C for users to develop a wizard. The dialog for each step in the wizard can be created using an X-Function.

In this example, the wizard will perform a normality test and then a one-sample t-test for data in a column. The normality test's result can be shared in one-sample t-test.

Note: This tutorial requires the Develop Kit.

Minimum Origin Version Required: Origin 8.1SR0

What you will learn

  • How to create an X-Function.
  • How to share a variable or a DataRange in different steps.
  • How to call an X-Function in OriginC.
  • How to create a wizard.

Create four X-Functions

  1. Select Tools: X-Function Builder or press F10 to open X-Function Builder dialog
  2. Add the variables as follows and save the X-Function as "StatTest" in the User Files folder, User Files\X-Functions\Statistics\Hypothesis Testing.
    How to Create a Wizard xf1.png
  3. Click the New X-Function Wizard button. Add the variables as follows and save the X-Function as "StatTestWizGoal" in the User Files folder, User Files\X-Functions\Statistics\Hypothesis Testing.
    How to Create a Wizard xf2.png
  4. Click the New X-Function Wizard button. Add the variables as follows and save the X-Function as "NormalityTest" in the User Files folder, User Files\X-Functions\Statistics\Hypothesis Testing.
    How to Create a Wizard xf3.png
  5. Click the New X-Function Wizard button. Add the variables as follows and save the X-Function as "OnetTest" in the User Files folder, User Files\X-Functions\Statistics\Hypothesis Testing.
    How to Create a Wizard xf4.png

Note that the X-Functions NormalityTest and OnetTest have the same variable "prob", which is a shared variable and will be declared in the source file.

Update X-Function's Property in Tree View

  1. Open the X-Function StatTest. Click the TreeView button TreeView.png to open the Tree View. Make the following settings in the Tree View.
    How to Create a Wizard xf1s.png
  2. Click the Save OXF file button to save the X-Function.
  3. Open the X-Function StatTestWizGoal, NormalityTest and OnetTest respectively in X-Function Builder. Click the TreeView button TreeView.png and type "Select Wizard Goal", "Normality Test" and "One-Sample t-test" in the Description edit box of each X-Function's Tree View, which will be shown in the dialogs.

Create Files for the Wizard

  • Click the Code Builder button on the Standard toolbar. In Code Builder, click the New button. In the New File dialog, select H File, click the Browse button, and select the User Files folder, User Files\OriginC as the new header file's Location. Then type StatTestWiz in the File Name edit box. Click OK to close the dialog.

Add the following script to StatTestWiz.h file.

#ifndef __STAT_TEST_WIZ_H__
#define __STAT_TEST_WIZ_H__

#include <..\OriginLab\XFWiz.h>
#include <..\OriginLab\XFCore.h>
#include <..\OriginLab\XFWizard_utils.h>

class StatTestWizCore : public XFCore
{
public:
   StatTestWizCore();

public:	
   void ChangeGoal(int nGoal);
   DataRange GetRange();	
	
   int nStep;
protected:

};

int stat_test_run_wiz_nodlg(LPCSTR lpcszThemeName = NULL, const XFWizTheme *pXFWizTheme 
= NULL, const XFWizInputOutputRange *pXFWizIO = NULL, DWORD dwOPUID = 0);

int stat_test_open_wiz_dlg(LPCSTR lpcszThemeName = NULL, const XFWizTheme *pXFWizTheme 
= NULL, const XFWizInputOutputRange *pXFWizIO = NULL, DWORD dwOPUID = 0);

#endif	//__STAT_TEST_WIZ_H__

Click the Save button to save StatTestWiz.h file.

  • Repeat the same operation to create a new C File, StatTestWiz.c .

Add the following script to StatTestWiz.c file.

///////////////////////////////////////////////////////////////////////////////////
#include <..\OriginLab\XFWizManager.h>

#include <..\OriginLab\WizOperation.h>
#include <..\OriginLab\XFWizNavigation.h>

#include <..\OriginLab\XFWizScript.h>
#include <..\OriginLab\XFWizDlg.h>

///////////////////////////////////////////////////////////////////////////////////
// Include your own header files here.
#include "StatTestWiz.h"

enum
{
	GOAL_ALL = 0,
	GOAL_SIMPLE,
};

//Names of three X-Functions
#define STR_STEP_GOAL	"StatTestWizGoal"
#define STR_STEP_Normal	"NormalityTest"
#define STR_STEP_TTest "OnetTest"

//Names of steps shown in the wizard.
#define STR_LABEL_STEP_GOAL	"Goal"
#define STR_LABEL_STEP_Normal	"Normality Test"
#define STR_LABEL_STEP_TTest	"One-Sample t-test"

///////////////////////////////////////////////////////////////////////////////////
//Class StatTestWizTheme
class StatTestWizTheme : public XFWizTheme
{
public:
   StatTestWizTheme();
};

//Name of the variable prob shared by X-Functions NormalityTest and OnetTest
#define STR_GETN_VAR_SHARED_NProb "prob"

StatTestWizTheme::StatTestWizTheme()
:XFWizTheme()
{
   m_saSharedList.Add(STR_GETN_VAR_SHARED_NProb); //Add the shared variable
}

///////////////////////////////////////////////////////////////////////////////////
class StatTestWizInputOutputRange : public XFWizInputOutputRange
{
};

///////////////////////////////////////////////////////////////////////////////////
//Class StatTestWizManager

#define STR_CLASS_NAME_TEST	"StatTestWiz"
#define TEST_VERSION_NUMBER	1.0

class StatTestWizManager : public XFWizManager
{
public:
   StatTestWizManager(LPCSTR lpcszThemeName = NULL, const XFWizTheme *pXFWizTheme 
= NULL, const XFWizInputOutputRange *pXFWizIO = NULL, DWORD dwUIDOp = 0);

protected:
   virtual double GetVersion() { return TEST_VERSION_NUMBER; }	
   virtual XFCore* CreateXFCore() { return new StatTestWizCore; }
   virtual XFWizTheme*	CreateXFWizTheme() { return new StatTestWizTheme; }
   virtual XFWizInputOutputRange* CreateXFWizInputOutputRange()
             { return new StatTestWizInputOutputRange; }
   virtual string GetClassName() { return STR_CLASS_NAME_TEST; }
};

StatTestWizManager::StatTestWizManager(LPCSTR lpcszThemeName, const XFWizTheme 
*pXFWizTheme, const XFWizInputOutputRange *pXFWizIO, DWORD dwUIDOp) 
: XFWizManager(lpcszThemeName, pXFWizTheme, pXFWizIO, dwUIDOp)
{
   StringArray saMapXFNames = {STR_STEP_GOAL, STR_STEP_Normal, STR_STEP_TTest};
   StringArray saMapXFLabels = {STR_LABEL_STEP_GOAL, STR_LABEL_STEP_Normal, 
                                 STR_LABEL_STEP_TTest};
   m_saMapXFNames = saMapXFNames;
   m_saMapXFLabels = saMapXFLabels;
   ASSERT( m_saMapXFNames.GetSize() == m_saMapXFLabels.GetSize() );

   StringArray saDefaultXFNames = {STR_STEP_GOAL, STR_STEP_Normal, STR_STEP_TTest};
   m_saDefaultXFNames = saDefaultXFNames;

   m_strRunDlgName = _L("Stat Test");
}

///////////////////////////////////////////////////////////////////////////////////
//Class StatTestWizCore

StatTestWizCore::StatTestWizCore()
:XFCore()
{
   StringArray vsXFsRecalculateShown = {STR_STEP_GOAL};
   m_vsXFsRecalculateShown = vsXFsRecalculateShown;
   nStep = GOAL_ALL;
}

//Select steps in the Goal Step
void StatTestWizCore::ChangeGoal(int nGoal)
{
   XFWizNavigation *pXFWizNavg = (XFWizNavigation *)GetXFWizNavigation();
   ASSERT(pXFWizNavg);
	
   nStep = nGoal;
   
   if ( pXFWizNavg )
   {
      StringArray saXFNames;
      saXFNames.Add(STR_STEP_GOAL);
      switch (nGoal)
      {
      case GOAL_ALL:
	 saXFNames.Add(STR_STEP_Normal);
	 saXFNames.Add(STR_STEP_TTest);
	 break;
      case GOAL_SIMPLE:
	 saXFNames.Add(STR_STEP_TTest);
	 break;
      }

      pXFWizNavg->SetSteps(saXFNames);
		
   }
}

//Get input DataRange in the Goal Step.
DataRange StatTestWizCore::GetRange()
{
   XFWizNavigation *pXFWizNavg = (XFWizNavigation*)GetXFWizNavigation();
   XFWizInputOutputRange* pIORange = pXFWizNavg->GetXFWizInputOutputRange();

   DataRange drInput;
   if(!pIORange)
   {
      error_report("Fail to get io ranges!");
      return drInput;
   }
	
   Array<DataRange&> drs;
   //Get input DataRange.
   if(!pIORange->Get(&drs, STR_STEP_GOAL, true))
   {
      error_report("Fail to get range from WizCore!");
      return drInput;
   }
	
   drInput = drs.GetAt(0);
   
   return drInput;
}

///////////////////////////////////////////////////////////////////////////////////

int stat_test_run_wiz_nodlg(LPCSTR lpcszThemeName, const XFWizTheme *pXFWizTheme, const 
XFWizInputOutputRange *pXFWizIO, DWORD dwOPUID)
{
   TEMPLATE_run_wiz_nodlg(StatTestWizManager, lpcszThemeName, pXFWizTheme, pXFWizIO, dwOPUID)
}

int stat_test_open_wiz_dlg(LPCSTR lpcszThemeName, const XFWizTheme *pXFWizTheme, const 
XFWizInputOutputRange *pXFWizIO, DWORD dwOPUID)
{
   TEMPLATE_open_wiz_dlg(StatTestWizManager, lpcszThemeName, pXFWizTheme, pXFWizIO, dwOPUID)
}

int stat_test_run_wiz(UINT msg, const XFWizTheme *pXFWizTheme, const 
XFWizInputOutputRange *pXFWizIO, DWORD dwOPUID, int nExeMode)
{
   TEMPLATE_run_wiz(StatTestWizManager, msg, pXFWizTheme, pXFWizIO, dwOPUID, nExeMode)
}

Click the Save button to save StatTestWiz.c file.

Note that StatTestWiz.c should be compiled after the X-Function StatTest is compiled, since the included files in StatTestWiz.c are not yet in the workspace until the X-Function StatTest is compiled. In fact StatTestWiz.h is included in X-Function StatTest, so StatTestWiz.c will be compiled automatically when X-Function StatTest is compiled.

Add Script for X-Functions

Script for X-Function StatTest

In the X-Function Builder, click the Open button and open the X-Function StatTest. Click the Edit X-Function in Code Builder and add the following script.

  • Include header files
#include <..\OriginLab\XFWiz.h>
#include <..\OriginLab\WizOperation.h>
#include <..\OriginLab\XFCore.h>
#include <..\OriginLab\XFWizNavigation.h>
#include <..\OriginLab\XFWizManager.h>
#include <..\OriginLab\XFWizScript.h>
#include <..\OriginLab\XFWizDlg.h>

#include <..\OriginLab\XFWizard_utils.h>

#include <..\OriginLab\WksOperation.h>

#include <event_utils.h>

#include "StatTestWiz.h"
  • StatTest()

Add the function body, which specifies the dialog mode.

if( script )
   stat_test_run_wiz_nodlg(tn);
else
   stat_test_open_wiz_dlg(tn);
  • StatTest_before_execute()

Add the function body, which determines not to show this dialog before the wizard is opened.

   nRet = XFEVT_PROCEED_NO_DLG;

Click Compile button to compile the file. Then click Return to Dialog button to return to X-Function Builder. In the X-Function Builder, click Save OXF file button to save the X-Function.

Script for X-Function StatTestWizGoal

Open the X-Function StatTestWizGoal. Click Edit X-Function in Code Builder button, add the following script.

  • Include header files
#include "StatTestWiz.h"
  • Add a static function _check_input()

This function is used to check whether the input DataRange is a single column.

static bool _check_input(const TreeNode trGetN, string& strErr)
{
   TreeNode trRange = trGetN.input;
   DataRange drInput;
			
   drInput.Create(trRange.strVal);	
	
   if( drInput.GetNumRanges() == 0 )
   {
      strErr = "Input can't be empty, and it should be a valid column.";
      return false;
   }
   else
   {
      if( drInput.GetNumRanges() == 1)
      {
         Worksheet wksInput;
         int nC1, nC2;
         drInput.GetRange(wksInput, nC1, nC2);
	 if( nC1 == nC2 )
	    return true;
      }

	  strErr = "Please select one column.";
	  return false;
   }	
}
  • StatTestWizGoal_event1()

Add the function body, which updates the dialog.

   StatTestWizCore* pstatwc = (StatTestWizCore*)get_xf_core_handler(trGetN);
   ASSERT(pstatwc);
   
   //Update the Wizard page.
   if ( 0 == lstrcmp(lpcszNodeName, "goal") )
      pstatwc->ChangeGoal(trGetN.goal.nVal);


   //Error message is shown at the bottom of the dialog, 
   //and OK button is disenabled for incorrect choice of DataRange.
   bOKEnable = _check_input(trGetN, strErrMsg);

   return false;

Click Compile button to compile the file. Then click Return to Dialog button to return to X-Function Builder, and click Save OXF file button to save the X-Function.

Script for X-Function NormalityTest

Open the X-Function NormalityTest. Click the Edit X-Function in Code Builder button and add the following script.

  • Include header files
#include "StatTestWiz.h"

#include <XFbase.h>
  • Add a static function _update_GUI()

This function is used to update the dialog's edit boxes for normality test result.

static void _update_GUI(TreeNode& trGetN)
{
   vector vRes;
   vRes = _norm_test(trGetN.nXFCorePointer.nVal, trGetN.type.nVal);
	
   trGetN.stat.dVal = vRes[0];
   trGetN.df.dVal = vRes[1];
   trGetN.prob.dVal = vRes[2];
}
  • Add a static function _update_strErr()

This function is used to update the string shown at the bottom of the dialog.

static void _update_strErr(const TreeNode tr, string& strErr)
{
   if(tr.prob.dVal >= 0.05 && tr.prob.dVal <= 1)
      strErr = "At the 0.05 level, the data was significantly drawn from a 
            normally distributed population.";
   else if(tr.prob.dVal < 0.05 && tr.prob.dVal >= 0)
      strErr = "At the 0.05 level, the data was not significantly drawn from a 
            normally distributed population.";
   else		
      strErr = "There is not enough information to draw a conclusion.";
}

Note that the string is divided into two lines shown in the page. It should be a command of one line in the script.

  • Add a static function _norm_test()

This function is used to perform Normality Test using related X-Functions.

static vector _norm_test(const int nXFCorePointer, const int nType)
{
   StatTestWizCore* pstatwc = (StatTestWizCore*)get_xf_core_handler(nXFCorePointer);
   ASSERT(pstatwc);
   
   vector vRes(3);
   vRes[2] = -1;
   DataRange drInput;
   drInput = pstatwc->GetRange();
   if( !drInput )
      return vRes;
      
   vector<string> vsXFName = {"swtest","kstest","lillietest"};
   XFBase xfNorm(vsXFName[nType]);
   if( !xfNorm.SetArg("irng", drInput) )
   {
      error_report("Failed to set argument image type");
      return vRes;
   }
   if( !xfNorm.SetArg("stat", vRes[0]) )
   {
      error_report("Failed to set argument image type");
      return vRes;
   }
   if( !xfNorm.SetArg("df", vRes[1]) )
   {
       error_report("Failed to set argument image type");
       return vRes;
   }
   if( !xfNorm.SetArg("prob", vRes[2]) )
   {
       error_report("Failed to set argument image type");   
       return vRes;
   }
   
   if( !xfNorm.Evaluate() )
   {
      error_report("Failed to evaluate the stats X-Function.");
      return vRes;
   }

   return vRes;
}
  • NormalityTest()

Update the function body, which exports the result into a worksheet when the Next button is pressed.

   DataRange drInput;
   StatTestWizCore* pstatwc = (StatTestWizCore*)get_xf_core_handler(nXFCorePointer);
   ASSERT(pstatwc);
   drInput = pstatwc->GetRange();

   if( !drInput )
      return;
   string strBook, strSheet;
   if(!drInput.GetBookSheet(strBook, strSheet))
   {
      error_report("Workbook and worksheet names can't be obtained.");
      return;
   }
   WorksheetPage wpData(strBook);
   
   int nLayer = wpData.AddLayer("Normality Test");
   
   if(nLayer >= 0)
   {
      Worksheet wksRes = wpData.Layers(nLayer);
      vector<string> vsTypeName = {"Shapiro-Wilk","Kolmogorov-Smirnov","Lilliefors"};
      vector<string> vsNProb = {"Prob<W", "Prob>D", "Prob>D"};
      vector<string> vsParaName = {"Statistic", "DF", ""};
      vsParaName[2] = vsNProb[type];
      
      vector vRes;
      vRes = _norm_test(nXFCorePointer, type);
      
      wksRes.Columns(1).SetLongName(vsTypeName[type]);
      for(int ii=0; ii<3; ii++)
      {
         wksRes.SetCell(ii, 0, vsParaName[ii], false);
         wksRes.SetCell(ii, 1, vRes[ii]);
      }
   }
   else
   {
      error_report("New worksheet can't be created.");
   }
  • NormalityTest_event1()

Update the function body, which will update the results in the dialog as the method of normality test changes. Strings shown at the bottom of the dialog will also be updated.

   _update_GUI(trGetN);
   _update_strErr(trGetN, strErrMsg);      
   
   return true;
  • NormalityTest_before_execute()

Update the function body, which will make the edit boxes for results grayed out, and show the result in the dialog.

   trGetN.stat.Enable = false;
   trGetN.df.Enable = false;
   trGetN.prob.Enable = false;

Click the Compile button to compile the file. Then click the Return to Dialog button to return to X-Function Builder, and click the Save OXF file button to save the X-Function.

Script for X-Function OnetTest

Open the X-Function OnetTest. Click the Edit X-Function in Code Builder button and add the following script.

  • Include header files
#include "StatTestWiz.h"

#include <XFbase.h>
  • Define strings
const vector<string> vsNull = {"Mean = ","Mean <= ","Mean >= "};
const vector<string> vsAlter = {"Mean <> ","Mean > ","Mean < "};
const vector<string> vsAcceptNull = {"Not significantly different from","Not 
significantly greater than","Not significantly less than"};
const vector<string> vsRejectNull = {"significantly different from","significantly 
greater than","significantly less than"};
const vector<string> vsProb = {"Prob>|t|", "Prob>t", "Prob<t"};
  • Add a static function _update_null()

This function is used to update the Null edit box.

static void _update_null(TreeNode& trGetN, bool bMean = false)
{
   string strNull;

   strNull = vsNull[trGetN.tail.nVal] + ftoa(trGetN.mean.dVal);
   trGetN.null.strVal = strNull;
   
   if(bMean)
   {
      string strAlter = vsAlter[0] + ftoa(trGetN.mean.dVal) + "|";
      strAlter = strAlter + vsAlter[1] + ftoa(trGetN.mean.dVal) + "|";
      strAlter = strAlter + vsAlter[1] + ftoa(trGetN.mean.dVal);

      trGetN.tail.SetAttribute(STR_COMBO_ATTRIB, strAlter);
   }
}
  • Add a static function _check_sig_level()

This function is used to check the Significance Level edit box value.

static bool _check_sig_level(TreeNode& trGetN, string& strErr)
{
   if( trGetN.siglevel.dVal > 0 && trGetN.siglevel.dVal < 1 )
   {
      return true;
   }
   else
   {
      strErr = "Significance Level should be between 0 and 1.";
      return false;
   }
}
  • Add a static function _update_strErr()

This function is used to define the string for the conclusion of t-test at the bottom based on P-value.

static void _update_strErr(const TreeNode tr, string& strErr)
{   
   if(tr.tprob.dVal >= tr.siglevel.dVal && tr.tprob.dVal <= 1)
      strErr.Format("Null Hypothesis is %s%s.\r\nAlternative Hypothesis is %s%s.
         At the %s level, the population mean is %s the test mean(%s).",          
         vsNull[tr.tail.nVal], ftoa(tr.mean.dVal), vsAlter[tr.tail.nVal], ftoa(tr.mean.dVal),      
         ftoa(tr.siglevel.dVal), vsAcceptNull[tr.tail.nVal], ftoa(tr.mean.dVal) );
   else if(tr.tprob.dVal < tr.siglevel.dVal && tr.tprob.dVal >= 0)
      strErr.Format("Null Hypothesis is %s%s.\r\nAlternative Hypothesis is %s%s.
         At the %s level, the population mean is %s the test mean(%s).", 
         vsNull[tr.tail.nVal], ftoa(tr.mean.dVal), vsAlter[tr.tail.nVal], ftoa(tr.mean.dVal),
         ftoa(tr.siglevel.dVal), vsRejectNull[tr.tail.nVal], ftoa(tr.mean.dVal) );
   else     
      strErr = "There is not enough information to draw a conclusion.";
}

Note that the command is divided into several lines shown in the page. It should be a command of one line in the script.

  • Add a static function _update_GUI()

This function is used to update edit boxes for results in the dialog.

static void _update_GUI(TreeNode& trGetN)
{  
   vector vRes;
   vRes = _one_sample_t_test(trGetN.nXFCorePointer.nVal, trGetN.mean.dVal, trGetN.tail.dVal, trGetN.siglevel.dVal);
   
   trGetN.stat.dVal = vRes[0];
   trGetN.df.dVal = vRes[1];
   trGetN.tprob.dVal = vRes[2];
   trGetN.lcl.dVal = vRes[4];
   trGetN.ucl.dVal = vRes[5];   
}
  • Add a static function _one_sample_t_test()

This function is used to perform One-Sample t-Test using an X-Function.

static vector _one_sample_t_test(const int nXFCorePointer, const double dMean, const int nTail, const double dSiglevel)
{
   DataRange drInput;
   StatTestWizCore* pstatwc = (StatTestWizCore*)get_xf_core_handler(nXFCorePointer);
   ASSERT(pstatwc);
   
   vector vRes(6);
   vRes[2] = -1;
   drInput = pstatwc->GetRange();
   if( !drInput )
      return vRes;
         
   vRes[3] = 100 - 100*dSiglevel;
   
   XFBase xfTTest("ttest1");

   if( !xfTTest.SetArg("irng", drInput) )
   {
      error_report("Failed to set argument irng");
      return vRes;
   }
   if( !xfTTest.SetArg("mean", dMean) )
   {
      error_report("Failed to set argument mean");
      return vRes;
   }
   if( !xfTTest.SetArg("tail", nTail) )
   {
      error_report("Failed to set argument tail");
      return vRes;
   }
   if( !xfTTest.SetArg("alpha", dSiglevel) )
   {
      error_report("Failed to set argument alpha");
      return vRes;
   }
   
   if( !xfTTest.SetArg("stat", vRes[0]) )
   {
      error_report("Failed to set argument stat");
      return vRes;
   }
   if( !xfTTest.SetArg("df", vRes[1]) )
   {
       error_report("Failed to set argument df");
       return vRes;
   }
   if( !xfTTest.SetArg("prob", vRes[2]) )
   {
       error_report("Failed to set argument prob");
       return vRes;
   }
   if( !xfTTest.SetArg("lcl", vRes[4]) )
   {
       error_report("Failed to set argument lcl");
       return vRes;
   }
   if( !xfTTest.SetArg("ucl", vRes[5]) )
   {
       error_report("Failed to set argument ucl");
       return vRes;
   }
   
   if( !xfTTest.Evaluate() )
   {
      error_report("Failed to evaluate the ttest1 X-Function.");
      return vRes;
   }
   
   return vRes;
}
  • OnetTest()

Update the function body, which exports the result into a worksheet when the Finish button is pressed.

   DataRange drInput;
   StatTestWizCore* pstatwc = (StatTestWizCore*)get_xf_core_handler(nXFCorePointer);
   ASSERT(pstatwc);
   
   drInput = pstatwc->GetRange();
   if( !drInput )
      return ;
   
   string strBook, strSheet;
   if(!drInput.GetBookSheet(strBook, strSheet))
   {
      error_report("Workbook and worksheet names can't be obtained.");
      return;
   }
   WorksheetPage wpData(strBook);
   
   int nLayer = wpData.AddLayer("One-Sample t-test");
   
   if(nLayer >= 0)
   {
      Worksheet wksRes = wpData.Layers(nLayer);
   
      vector<string> vsParaName = {"t Statistic", "DF","", "Conf. Levels in %", "Lower Limits", "Lower Limits"};
      vsParaName[2] = vsProb[tail];
      
      vector vRes;
      vRes = _one_sample_t_test(nXFCorePointer, mean, tail, siglevel);
      
      wksRes.SetSize(-1, 4);
      wksRes.Columns(0).SetLongName("Test Statistics");
      string strNull = "Null Hypothesis is " + vsNull[tail] + ftoa(mean);
      wksRes.Columns(1).SetLongName(strNull);
      wksRes.Columns(3).SetLongName("Confidence Intervals for Mean");
      for(int ii=0; ii<3; ii++)
      {
         wksRes.SetCell(ii, 0, vsParaName[ii], false);
         wksRes.SetCell(ii, 1, vRes[ii]);
         
         wksRes.SetCell(ii, 2, vsParaName[ii + 3], false);
         wksRes.SetCell(ii, 3, vRes[ii + 3]);
      }     
   }
   else
   {
      error_report("New worksheet can't be created.");
   }
  • OnetTest_event1()

Update the function body, which will update results and show a conclusion at the bottom of the dialog according to the result. As settings change in the dialog, the Null edit box will be updated as the mean and hypothesis change, and the Significance Level edit box's value is checked.

   if( 0 == lstrcmp(lpcszNodeName, "mean") )
      _update_null(trGetN, true);
   if( 0 == lstrcmp(lpcszNodeName, "tail") )
      _update_null(trGetN);   
   if( 0 == lstrcmp(lpcszNodeName, "siglevel") )
      bOKEnable = _check_sig_level(trGetN, strErrMsg);
   
   _update_GUI(trGetN);
   _update_strErr(trGetN, strErrMsg);  
      
   return false;
  • OnetTest_before_execute()

Update the function body, to show/hide or disable the controls in the dialog.

   StatTestWizCore* pstatwc = (StatTestWizCore*)get_xf_core_handler(trGetN.nXFCorePointer.nVal);
   ASSERT(pstatwc);
   trGetN.prob.Show = 1 - pstatwc->nStep;
   trGetN.prob.Enable = false;
   
   trGetN.null.Enable = false;
   trGetN.stat.Enable = false;
   trGetN.df.Enable = false;
   trGetN.tprob.Enable = false;
   trGetN.lcl.Enable = false;
   trGetN.ucl.Enable = false;

Click the Compile button to compile the file. Then click the Return to Dialog button to return to the X-Function Builder. Click the Save OXF file button to save the X-Function.

Close Origin. Then start Origin and you will notice that a new item Stat Test is added to Origin's menu Statistics: Hypothesis Testing.

How to Use the Wizard

The following example shows how to use the wizard.

  1. Select a column in the worksheet.
  2. Select Statistics: Hypothesis Testing: Stat Test from the Origin menu or type the command "StatTest -d" in the command window. The Stat Test wizard dialog will open.
    How to Create a Wizard wiz1.png
  3. Click the Next button. The Normality Test dialog is opened. The result is shown in the Output branch. A conclusion is drawn at the bottom of the dialog.
    How to Create a Wizard wiz2.png
  4. Click the Next button. The One-Sample t-test dialog is opened. The result is shown in the Output branch. A conclusion is drawn at the bottom of the dialog. Previous step's result of normality test is shown at the top. You can also change the setting in the dialog, and notice the result changes.
    How to Create a Wizard wiz3.png
    How to Create a Wizard wiz3b.png
  5. Click the Finish button to end the wizard. Two worksheets for results are created.
    How to Create a Wizard wiz Res1.png
    How to Create a Wizard wiz Res2.png