// Filename:   	SR.OGS
// Creation:    by Joe Przechocki, 8/28/95
// Purpose:     Modularized Code for creating Sigmoidal Fits
// Modifications:
// RKM 12/10/98 v6.0141 REPORT_TO_OUTPUTLOG
// SDB 1/7/99   v6.0148 REPORT_TO_OUTPUTLOG
// RB 3/30/99 v6.0179 PASTETOLOG
// LAS 1/10/02 v6.9174 added support for FindX and FindY
// SDB 5/20/2003 QA70-4515 PARAM_INIT_FIX_VARY
// SDB 01/20/2004 QA70-5870 TEST_LOG_LINEAR_DATA
////////////////////////////////////////////////////////////////////////////////
// Main code which is called from DOSEMAIN.OGO
////////////////////////////////////////////////////////////////////////////////

[Tab.Operation.OnInit]
	SR!Tab.Operation.Upper.v1=100;
	SR!Tab.Operation.Lower.v1=0;
	SR!Tab.Operation.Center.v1=.01;
	SR!Tab.Operation.Rate.v1=1;
	
	SR!Tab.Operation.FindXedit.enable=0;
	SR!Tab.Operation.FindYedit.enable=0;
	SR!Tab.Operation.FindXButn.enable=0;
	SR!Tab.Operation.FindYButn.enable=0;


[Tab.Settings.OnInit]
	SR!Tab.Settings.Points.v1=20;
	SR!Tab.Settings.LeftMarg.v1=0;
	SR!Tab.Settings.RightMarg.v1=0;
	SR!Tab.Settings.FitIter.v1=200;
	SR!Tab.Settings.RedChi=1;
	SR!Tab.Settings.Function=2;
	SR!Tab.Settings.Weighting=1;


[Tab.Operation.Simulate.OnClick]
	if (exist(%H)==3 && Layer.is3D==1)
	{
		type -b $general.2DGraphsOnly;
		return 1;
	}
	if(SR!Tab.Operation.FixUpper==1 && SR!Tab.Operation.FixLower==1 && SR!Tab.Operation.FixCenter==1 && SR!Tab.Operation.FixRate==1)
	{	
		type -b $DoseResp.AllFixed;
		return 1;
	}

	if (run.section(,SelectionCk, 1)==0)
		run.section(,Simulate);
	return 0;

[Tab.Operation.Fit.OnClick]
	if (exist(%H)==3 && Layer.is3D==1)
	{
		type -b $general.2DGraphsOnly;
		return 1;
	}
	if(SR!Tab.Operation.FixUpper==1 && SR!Tab.Operation.FixLower==1 && SR!Tab.Operation.FixCenter==1 && SR!Tab.Operation.FixRate==1)
	{	
		type -b $DoseResp.AllFixed;
		return 1;
	}
	nlsf.p1=SR!Tab.Operation.Lower.v1;
	nlsf.p2=SR!Tab.Operation.Upper.v1;
	nlsf.p3=SR!Tab.Operation.Center.v1;
	nlsf.p4=SR!Tab.Operation.Rate.v1;
	if (SR!Tab.Settings.FitAll && exist(%H)==3)
	{
		count=0;%Z="";doc -e DY {%Z=%Z %C;count++;};	//Concatenate a list of Y datasets
		loop (ii,1,count)
		{
			%A=%[%Z,#ii];
			if (run.section(,SelectionCk)==0)
			{
				if (run.section(,MakeFit, %A)==0)
				{
					run.section(,Output, %A);
					nlsf.end(13);
				}
			}
			else
				return 1;
		}
	}
	else
	{
		if (run.section(,SelectionCk)==0)
		{
			if(run.section(,MakeFit, %C)==0)
			{
				run.section(,Output, %C);
				nlsf.end(13);				
			}
		}
		else
			return 1;
	}
	if (SR!Tab.Settings.FitAll==0)
	{
	
		SR!Tab.Operation.StaticText$=$Regression.ForDataSet;
		SR!Tab.Operation.FindXedit.enable=1;
		SR!Tab.Operation.FindYedit.enable=1;
		SR!Tab.Operation.FindXButn.enable=1;
		SR!Tab.Operation.FindYButn.enable=1;
		
	}
	else
	{
	
		SR!Tab.Operation.StaticText$=$Regression.Calculate;
		SR!Tab.Operation.FindXedit.enable=0;
		SR!Tab.Operation.FindYedit.enable=0;
		SR!Tab.Operation.FindXButn.enable=0;
		SR!Tab.Operation.FindYButn.enable=0;
	}
	
	return 0;


[FitMain]
	// Argument List: RawDataSetName
	if (run.section(,SelectionCk)==0 && run.section(,MakeFit, %1)==0) 
	  run.section(,Output, %1);


[Simulate]
	if (SR!Tab.Operation.Upper$=="" || SR!Tab.Operation.Lower=="" || SR!Tab.Operation.Center.v1=="" || SR!Tab.Operation.Rate.v1=="")
	{
		type -b;			//BEEP!
		return 1;			//Return ERROR - all parameters are not specified
	}

	doc -cs Dose;
	//SDB 01/20/2004 QA70-5870 TEST_LOG_LINEAR_DATA
	ii=run.section(,CheckXData);
	if (exist(%C)!=1)
	{
		if (ii==1 && SR!Tab.Settings.Function==1)
			Dose$(count+1)(x)=Boltzman(x,$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
		if (ii==1 && SR!Tab.Settings.Function==2)
			Dose$(count+1)(x)=Response1(x,$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
		if (ii==1)
			Dose$(count+1)(x)=Logistic(x,$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
	} 
	else 
	{
		limit %C;			//Look at current dataset for a clue on how to draw the sigmoid

		del dummy;/* incase it was not deleted from other parts */
		copy %C dummy;
		/* we interpolate the data with 20 points and put into	*
		 * a temporary data set called dummy			*
		 *							*/
	
		set dummy -f 0;/* this remove any possible offset in x */
		dummy-limit.ymin;	/* also remove y offset */
		dummy = ln(dummy);
		LR -N dummy;#!lr.b=;
		del dummy;

		if (ii==1 && SR!Tab.Settings.Function==1)
		{
			if (lr.b>0)
				Dose$(count+1)(x)=Boltzman(x,$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
			else
				Dose$(count+1)(x)=Boltzman(x,$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
		}
		if (ii==1 && SR!Tab.Settings.Function==2)
			Dose$(count+1)(x)=Response1(x,$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
		if (ii==0)
		{
			if (lr.b>0)
				Dose$(count+1)(x)=Logistic(x,$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
			else
				Dose$(count+1)(x)=Logistic(x,$(SR!Tab.Operation.Upper.v1),$(SR!Tab.Operation.Lower.v1),$(SR!Tab.Operation.Center.v1),$(SR!Tab.Operation.Rate.v1));
		}
	}
	set Dose$(count+1) -c color(blue);
	return 0;

[SelectionCk]
	/* check user settings                                          */
	/* -------------------------------------------------------------*/
	/* Check the users data selection                               */

	if (exist(%H)!=3 && exist(%H)!=2)
	{
		type -b $General.2DGraphsOrWks;
		return 1;
	}

	if (exist(%H)==3)
	{
		if (%1=="") 
		{
			type -b $Regression.NoData;
			return 1;
		}
	}
	
	if (exist(%H)==2 && %(%H,@Y#,2)>1)
	{
		type -b $General.Only1YColumn;
		return 1;
	}

	if (exist(%H)==2)
	{
		if ((wks.sel<=1)||((wks.col$(wks.c1).type==4)&&(wks.sel&16==16))) 
		{
			type -b $Regression.BadOptions;
			return 1;
		}
		else
		{
			switch (wks.col$(wks.c1).type)
			{
				case 1://Y column is first select
					%A=%(%H,wks.c1);        
					break;
				case 4://X column is first selected
					%A=%(%H,%(%H,@YS,1));
					break;
				default:
					type -b $Regression.BadOptions;
					return 1;
			};
			worksheet -P 201 scatter;Legend;
		}
	}

[MakeFit]
	nlsf.tolerance=0;	
	//SDB 01/20/2004 QA70-5870 TEST_LOG_LINEAR_DATA
	if (run.section(,CheckXData)) 
	{
		switch(SR!Tab.Settings.Function)
		{
			case 1:
				nlsf.func$=Boltzmann;
				break;
			case 2:
				nlsf.func$=DoseResp;
		}
	}
	else
		nlsf.func$=Logistic;

	limit %1;

	nlsf.cleanupfitdata();
	nlsf.fitdata$=%1;

	if (layer.x.space==1)
	{
		nlsf.xBegin=limit.xmin-SR!Tab.Settings.LeftMarg.v1/100*(limit.xmax-limit.xmin);
		nlsf.xEnd=limit.xmax+SR!Tab.Settings.RightMarg.v1/100*(limit.xmax-limit.xmin);
	}
	else
	{
		nlsf.xBegin=10^(log(limit.xmin)-SR!Tab.Settings.LeftMarg.v1/100*log(limit.xmax/limit.xmin));
		nlsf.xEnd=10^(log(limit.xmax)+SR!Tab.Settings.RightMarg.v1/100*log(limit.xmax/limit.xmin));
	}
	xpoints=nlsf.xPoints;		//Save the current nlsf.xPoints
	nlsf.xPoints=SR!Tab.Settings.Points.v1;
	nlsf.wType=SR!Tab.Settings.Weighting-1;
	nlsf.chisqrerr=SR!Tab.Settings.RedChi;	//Toggle on/off Scale Errors with Standard Deviation
	if (SR!Tab.Settings.Weighting==2)
	{
		%A=errof(%1)$;
		if (exist(%A)==1)
		{
			nlsf.W$=errof(%1)$;
		}
		else
		{
			type -b;			//BEEP!
			type -b $DoseResp.NoErrorBars;
			return 1;
		}

	} 
	del dummy;
	del dummy_A;
	copy -x %1 dummy;
	if (nlsf.func$=="Logistic")
		dummy_A=log(dummy_A);
	deriv dummy;
	integ -q dummy;
	if (nlsf.func$=="Logistic")
		integ.x0=10^integ.x0;
	del dummy;
	del dummy_A;

	nlsf.execute(parainit);	

	if(nlsf.p1<nlsf.p2)
	{
		nlsf.p1=SR!Tab.Operation.FixLower?SR!Tab.Operation.Lower.v1:nlsf.p1;
		nlsf.p2=SR!Tab.Operation.FixUpper?SR!Tab.Operation.Upper.v1:nlsf.p2;
		// SDB 5/20/2003 QA70-4515 PARAM_INIT_FIX_VARY
		// nlsf.p1 and nlsf.p2 set to a fix value if needed
		nlsf.v1=SR!Tab.Operation.FixLower?0:1;
		nlsf.v2=SR!Tab.Operation.FixUpper?0:1;
	}
	else
	{
		// SDB 5/20/2003 QA70-4515 PARAM_INIT_FIX_VARY
		// nlsf.p1 and nlsf.p2 set to a fix value if needed
		nlsf.p2=SR!Tab.Operation.FixLower?SR!Tab.Operation.Lower.v1:nlsf.p2;
		nlsf.p1=SR!Tab.Operation.FixUpper?SR!Tab.Operation.Upper.v1:nlsf.p1;
		nlsf.v2=SR!Tab.Operation.FixLower?0:1;
		nlsf.v1=SR!Tab.Operation.FixUpper?0:1;
	}
	nlsf.p3=SR!Tab.Operation.FixCenter?SR!Tab.Operation.Center.v1:nlsf.p3;
	nlsf.p4=SR!Tab.Operation.FixRate?SR!Tab.Operation.Rate.v1:nlsf.p4;
	nlsf.v3=SR!Tab.Operation.FixCenter?0:1;
	nlsf.v4=SR!Tab.Operation.FixRate?0:1;

	nlsf.parainit=0;
	/// SDB: Setting can no longer be read
	/// SR!PastetoPlot.v1=nlsf.PasteToPlot;			//Get current output settings
	/// RB 3/30/99 v6.0179 PASTETOLOG
	SR!PastetoLog.v1=nlsf.PasteToLog;
	/// 
	/// nlsf.PasteToPlot=0;				//Temporarily set to OFF
	/// RB 3/30/99 v6.0179 PASTETOLOG
	//nlsf.PasteToScript=0;
	nlsf.PasteToLog=0;
	nlsf.parainit=0;
	///
	#!nlsf.p1=;nlsf.p2=;nlsf.p3=;nlsf.p4=;		//DEBUG: Check parameter initialization
	nlsf.fit(SR!Tab.Settings.FitIter.v1);		//FIT

	/// nlsf.PasteToPlot=SR!PastetoPlot.v1;			//Restore to PREVIOUS STATE
	/// RB 3/30/99 v6.0179 PASTETOLOG
	nlsf.PasteToLog=SR!PastetoLog.v1;	
	///

	//Rescale the plot if user added extra fit margins
	if (SR!Tab.Settings.LeftMarg.v1 || SR!Tab.Settings.RightMarg.v1)
		layer -a;
	//Update Parameter Readout on Toolbar...
	if(SR!Tab.Operation.FixLower!=1)
		SR!Tab.Operation.Lower.v1=nlsf.p1<nlsf.p2?nlsf.p1:nlsf.p2;
	if(SR!Tab.Operation.FixUpper!=1)
		SR!Tab.Operation.Upper.v1=nlsf.p1<nlsf.p2?nlsf.p2:nlsf.p1;
	SR!Tab.Operation.Center.v1=nlsf.p3;
	SR!Tab.Operation.Rate.v1=nlsf.p4;
	nlsf.xPoints=xpoints;		//Restore nlsf.xPoints
	delete -v xpoints;
	return 0;

[Output]
	SaveRedirection=type.Redirection(16,3);	// SDB 1/7/99 v6.0148 REPORT_TO_OUTPUTLOG
	type.BeginResults();		/// RKM 12/10/98 v6.0141 REPORT_TO_OUTPUTLOG
	%A=nlsf.func$;
	type -l $DoseResp.Title;
	type " %1:";
	%B=errof(%C)$;
	if (exist(%B)==1&& (SR!Tab.Settings.Weighting.Choice==2))
		type $regression.UsingWeight;
	type;

	type -l $DoseResp.Model;
	type $DoseResp.%A;
	type;						//Blank Line
	
	type $DoseResp.ParaHeader1;
	separator 3;
	type -l $DoseResp.ChiSqr;
	type $(nlsf.chisqr);

	if ("%A"=="DoseResp")
	{
		type -l $DoseResp.Lower;
		type "$(nlsf.p1)\t$(nlsf.e1)";
		type -l $DoseResp.Upper;
		type "$(nlsf.p2)\t$(nlsf.e2)";
		if (integ.area>=0)
			type -l $DoseResp.%ALogEC50;
		else
			type -l $DoseResp.%ALogIC50;
		type "$(nlsf.p3)\t$(nlsf.e3)";
		type -l $DoseResp.%AP;
		type "$(nlsf.p4)\t$(nlsf.e4)";
		type;
		if (integ.area>=0)
			type -l $DoseResp.DoseRespEC50;
		else
			type -l $DoseResp.DoseRespIC50;	
		type "$(10^(nlsf.p3))\t$(abs((10^nlsf.p3)*ln(10))*nlsf.e3)";
	}
	else
	{
		type -l $DoseResp.Initial;
		type "$(nlsf.p1)\t$(nlsf.e1)";
		type -l $DoseResp.Final;
		type "$(nlsf.p2)\t$(nlsf.e2)";
		if (integ.area>=0)
			type -l $DoseResp.%AEC50;
		else
			type -l $DoseResp.%AIC50;
		type "$(nlsf.p3)\t$(nlsf.e3)";
		type -l $DoseResp.%AP;
		type "$(nlsf.p4)\t$(nlsf.e4)";
	}
	
	type.EndResults();
	type.Redirection=SaveRedirection; // restore previous redirection.
	delete -v SaveRedirection;
	return  0;

[Tab.Settings.Weighting.OnClick]
	SR!Tab.Settings.RedChi=SR!Tab.Settings.Weighting;

[Tab.Settings.Error.OnClick]
	SR!Tab.Settings.RedChi=0;

[Tab.Settings.Inverse.OnClick]
	SR!Tab.Settings.RedChi=0;
		
[Tab.Operation.FindXButn.Onclick]
	
	//type -b "Find X";
	
	if(run.LoadOC("OriginLab\FitToolsGetXfromY.C")!=0)
	{
		type -b "$Regression.CFileNoLoad";      
		return 1;
	}
	run.section(DBRoutines,SaveAndSetAtOC);
	
	//////////////prepare for callin functions/////////////////
	//
		%A=nlsf.funcCol$;
	//	limit %A;
		%B=nlsf.func$;
	//
	//////////////////////////////////////////////////////////
	
		
	if(SR!Tab.Operation.FindYedit.v1 == 0/0)
		run.section(,ReportError,$Regression.LRNoY);
	
	else
	{
		if(%B=="Boltzmann");
			SR!Tab.Operation.FindXedit.v1=SigmoidGetXfromY(SR!Tab.Operation.FindYedit.v1,"%A",nlsf.p1,nlsf.p2,nlsf.p3,nlsf.p4,1);
		else
		{
			if(%B=="DoseResp")
				SR!Tab.Operation.FindXedit.v1=SigmoidGetXfromY(SR!Tab.Operation.FindYedit.v1,"%A",nlsf.p1,nlsf.p2,nlsf.p3,nlsf.p4,2);
			else
				SR!Tab.Operation.FindXedit.v1=SigmoidGetXfromY(SR!Tab.Operation.FindYedit.v1,"%A",nlsf.p1,nlsf.p2,nlsf.p3,nlsf.p4,3);
		
		}
	
			
	}
	
	run.section(DBRoutines,RestoreAtOC);
	
[Tab.Operation.FindYButn.Onclick]
	
	//type -b "Find Y";
	
	if(SR!Tab.Operation.FindXedit.v1 == 0/0)
			run.section(,ReportError,$Regression.LRNoX);
	else

		SR!Tab.Operation.FindYedit.v1=fit(SR!Tab.Operation.FindXedit.v1);
	
	
[ReportError]
	
	type -b;				//BEEP!
	type -b %1;				//Type out the appropriate error message
	type -q "":				//Clear up the Status Bar
	return 0;

[CheckXData]
	//SDB 01/20/2004 QA70-5870 TEST_LOG_LINEAR_DATA
	//LR on X data to determine the X data or Log(xdata) better fit
	del dummy;/* in case it was not deleted from other parts */
	copy xof(%C) dummy;
	/* we interpolate the data with 20 points and put into	*
	 * a temporary data set called dummy			*
	 *							*/
	
	LR -N dummy;
	ii=abs(lr.r);
	dummy = log(dummy);
	LR -N dummy;
	del dummy;
	ii=ii>abs(lr.r)?1:0;
	return ii;

[OnCancel]

	SR!Tab.Operation.StaticText$=$Regression.Calculate;
	SR!Tab.Operation.FindXedit.enable=0;
	SR!Tab.Operation.FindYedit.enable=0;
	SR!Tab.Operation.FindXButn.enable=0;
	SR!Tab.Operation.FindYButn.enable=0;
	SR!TAB.OPERATION.FINDXEDIT.V1$="";
	SR!TAB.OPERATION.FINDYEDIT.V1$="";
	return 0;