unit baselineset; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, CustomDrawnControls; type { Tbaseline } Tbaseline = class(TForm) curvedBaselinebutton: TCDButton; StraightBaselinebutton: TCDButton; procedure curvedBaselinebuttonClick(Sender: TObject); procedure StraightBaselinebuttonClick(Sender: TObject); private public end; var baseline: Tbaseline; procedure baselineindexes; procedure straightbaseline; procedure curvedbaseline; procedure baselineredraw; procedure drawcurvedbaseline; procedure courveline(x0,x1:longint; y0,y1,y14,y12,y34:double); procedure clearbaselineset; procedure curvedbaselinefinish; procedure Differencep; procedure arearesult; procedure markersdraw; procedure onsetresult; procedure tmaxresult; procedure linesdraw; procedure singletextdraw(texti,i:longint); procedure onetextdraw(texti,i:longint); procedure textredraw; implementation {$R *.lfm} uses variables, main, loadunit,fit; procedure onetextdraw(texti,i:longint); var index:longint; s:string; y:double; begin if not texts[texti].b[i] then exit; s:=texts[texti].str[i]; index:=texts[texti].index[i]; y:=texts[texti].y[i]; if xaxispointer=1 then mainform.Text2LineSeries.AddxY(time2_01(t1[index]),q2_01(y),s,clblack) else mainform.Text2LineSeries.AddxY(temp2_01(temp2[index]),q2_01(y),s,clblack); end; procedure textredraw; var i,j:longint; begin mainform.Text2LineSeries.clear; for j:=1 to textsp do for i:=1 to 4 do onetextdraw(j,i); end; procedure singletextdraw(texti,i:longint); var index:longint; s:string; y:double; begin mainform.Text1LineSeries.clear; s:=texts[texti].str[i]; index:=texts[texti].index[i]; y:=texts[texti].y[i]; if xaxispointer=1 then mainform.Text1LineSeries.AddxY(time2_01(t1[index]),q2_01(y),s,clred) else mainform.Text1LineSeries.AddxY(temp2_01(temp2[index]),q2_01(y),s,clred); end; procedure linesdraw; var slope,x,y,diff:double; j,i:longint; begin mainform.onsetLineSeries.Clear; if linesp=0 then exit; for i:=1 to linesp do begin slope:=(lines[i].a1-lines[i].a0)/500; if xaxispointer=1 then diff:=(lines[i].t1-lines[i].t0)/500 else diff:=(lines[i].temp1-lines[i].temp0)/500; if xaxispointer=1 then x:=lines[i].t0 else x:=lines[i].temp0; y:=lines[i].a0; for j:=1 to 499 do begin x:=x+diff; y:=y+slope; if xaxispointer=1 then mainform.onsetLineSeries.AddXY(time2_01(x),q2_01(y)) else mainform.onsetLineSeries.AddXY(temp2_01(x),q2_01(y)) end; end; end; procedure markersdraw; var i,j:longint; begin mainform.markersLineSeries.Clear; if markersp=0 then exit; for j:=1 to markersp do begin i:=markers[j]; if xaxispointer=1 then mainform.markerslineseries.addxy(time2_01(t1[i]),q2_01(a1[i])) else mainform.markerslineseries.addxy(temp2_01(temp2[i]),q2_01(a1[i])); end; end; procedure drawcurvedbaseline; var i:longint; begin Mainform.curvedbaselineLineseries.clear; if mainform.Curvedbaselinelineseries.active then begin for i:=bindex1 to bindex2 do begin if xaxispointer=1 then mainform.Curvedbaselinelineseries.addxy(time2_01(t1[i]),q2_01(by[i])) else mainform.Curvedbaselinelineseries.addxy(temp2_01(temp2[i]),q2_01(by[i])); end; end; end; procedure baselineredraw; var i:longint; begin Mainform.curvedbaselinedirectionLineseries1.clear; Mainform.curvedbaselinedirectionLineseries2.clear; Mainform.curvedbaselinedraggLineseries.clear; Mainform.curvedbaselinemarkerLineseries.clear; drawcurvedbaseline; if mainform.Curvedbaselinedragglineseries.active then begin mainform.CurvedbaselinedirectionLineSeries1.active:=true; mainform.CurvedbaselinedirectionLineSeries2.active:=true; if xaxispointer=1 then begin mainform.Curvedbaselinedragglineseries.Addxy(time2_01(t1[x0drag]),q2_01(y0drag)); mainform.Curvedbaselinedragglineseries.Addxy(time2_01(t1[x1drag]),q2_01(y1drag)); mainform.Curvedbaselinedragglineseries.Addxy(time2_01(t1[x2drag]),q2_01(y2drag)); mainform.CurvedbaselinedirectionLineSeries1.AddXY(time2_01(t1[bindex1]),q2_01(a1[bindex1])); mainform.CurvedbaselinedirectionLineSeries1.Addxy(time2_01(t1[x0drag]),q2_01(y0drag)); mainform.CurvedbaselinedirectionLineSeries2.AddXY(time2_01(t1[bindex2]),q2_01(a1[bindex2])); mainform.CurvedbaselinedirectionLineSeries2.Addxy(time2_01(t1[x2drag]),q2_01(y2drag)); end else begin mainform.Curvedbaselinedragglineseries.Addxy(temp2_01(temp2[x0drag]),q2_01(y0drag)); mainform.Curvedbaselinedragglineseries.Addxy(temp2_01(temp2[x1drag]),q2_01(y1drag)); mainform.Curvedbaselinedragglineseries.Addxy(temp2_01(temp2[x2drag]),q2_01(y2drag)); mainform.CurvedbaselinedirectionLineSeries1.AddXY(temp2_01(temp2[bindex1]),q2_01(a1[bindex1])); mainform.CurvedbaselinedirectionLineSeries1.Addxy(temp2_01(temp2[x0drag]),q2_01(y0drag)); mainform.CurvedbaselinedirectionLineSeries2.AddXY(temp2_01(temp2[bindex2]),q2_01(a1[bindex2])); mainform.CurvedbaselinedirectionLineSeries2.Addxy(temp2_01(temp2[x2drag]),q2_01(y2drag)); end; end; end; procedure baselineindexes; begin index1:=index2+10; mainform.marker1constantline.Active:=true; mainform.marker1datapointdragtool.Enabled:=true; if xaxispointer=1 then mainform.marker1constantline.position:=time2_01(t1[index1]) else mainform.marker1constantline.position:=temp2_01(temp2[index1]); baselineindex1b:=true; resultout('Set lower baseline point by dragging the line'); upallowed:=false; end; procedure straightbaseline; var i:longint; slopeb,zerob:double; begin if index1=index2 then exit; if index1>index2 then begin i:=index2; index2:=index1; index1:=i; end; slopeb:=(a1[index2]-a1[index1])/(t1[index2]-t1[index1]); zerob:=a1[index1]; for i:=index1 to index2 do a2[i]:=zerob+slopeb*(t1[i]-t1[index1]); redraw; end; procedure courveline_0(x0,x1:longint; y0,y1,y14,y12,y34:double); var i:longint; diff,d1,ri,xx:double; begin diff:=x1-x0; d1:=diff/4; ba[0]:=y0; ba[1]:=y0; ba[round(diff)]:=y1; ba[round(diff+1)]:=y1; ba[1+trunc(d1)]:=y14; ba[1+trunc(3*d1)]:=y34; d1:=d1+d1; ba[1+trunc(d1)]:=y12; d1:=d1/2; while d1>1 do begin for i:=1 to trunc((diff+1)/d1) do begin ri:=i*d1; ba[1+trunc(ri-d1/2)]:=(ba[1+trunc(ri-d1)]+ba[1+trunc(ri)])/2; end; for i:=1 to trunc((diff+1)/d1)-1 do begin ri:=i*d1; ba[1+trunc(ri)]:=ba[1+trunc(ri)]/2+(ba[1+trunc(ri-d1/2)]+ ba[1+trunc(ri+d1/2)])/4; end; d1:=d1/2; end; mainform.Curvedbaselinelineseries.active:=true; for i:=0 to x1-x0 do begin by[i+x0]:=ba[i]; end; bindex1:=x0; bindex2:=x1; end; procedure courveline(x0,x1:longint; y0,y1,y14,y12,y34:double); var i:longint; y12_iter,y12_s:double; begin y12_iter:=y12; for i:=1 to 20 do begin courveline_0(x0,x1,y0,y1,y14,y12_iter,y34); y12_s:=by[(x0+x1) div 2]; if abs(y12-y12_s)<0.01 then exit; y12_iter:=y12_iter+0.2*(y12-y12_s); end; end; procedure curvedbaseline; var aa:x_vector; j,i:longint; m1,m2,cy14,cy12,cy34:double; begin if index2index2 then begin i:=index2; index2:=index1; index1:=i; end; j:=index1-10; if j<0 then j:=index1+10; m1:=(a1[index1]-a1[j])/(t1[index1]-t1[j]); j:=index2+10; if j>datanum1 then j:=index2-10; m2:=(a1[index2]-a1[j])/(t1[index2]-t1[j]); j:=index1+((index2-index1) div 4); cy14:=a1[index1]-m1*(t1[index1]-t1[j]); j:=index1+((index2-index1) div 8); y0drag:=a1[index1]-m1*(t1[index1]-t1[j]); x0drag:=j; j:=index2-((index2-index1) div 4); cy34:=a1[index2]-m2*(t1[index2]-t1[j]); j:=index2-((index2-index1) div 8); y2drag:=a1[index2]-m2*(t1[index2]-t1[j]); x2drag:=j; j:=index1+((index2-index1) div 2); cy12:=a1[index1]-m1*(t1[index1]-t1[j])+a1[index2]-m2*(t1[index2]-t1[j]); cy12:=cy12/2; x1drag:=j; y1drag:=cy12; courveline_0(index1,index2, a1[index1],a1[index2],cy14,cy12,cy34); y1drag:=by[(index1+index2) div 2]; mainform.Curvedbaselinedragglineseries.active:=true; mainform.CurvedbaselinedataPointdragtool.enabled:=true; redraw; end; procedure curvedbaselinefinish; var i:longint; begin for i:=bindex1+1 to bindex2 do a2[i]:=by[i]; redraw; end; { Tbaseline } procedure startbaselineset; begin baseline.Visible:=false; mainform.baselinebutton.visible:=false; mainform.setbaselinebutton.visible:=true; mainform.escbaselinebutton.visible:=true; end; procedure clearbaselineset; begin mainform.baselinebutton.visible:=true; mainform.setbaselinebutton.visible:=false; mainform.escbaselinebutton.visible:=false; mainform.marker1datapointdragtool.Enabled:=false; mainform.marker2datapointdragtool.Enabled:=false; mainform.CurvedbaselineDataPointDragTool.Enabled:=false; mainform.Curvedbaselinedragglineseries.active:=false; mainform.Curvedbaselinelineseries.active:=false; mainform.CurvedbaselinedirectionLineSeries1.active:=false; mainform.CurvedbaselinedirectionLineSeries2.active:=false; mainform.marker1ConstantLine.active:=false; mainform.marker2ConstantLine.active:=false; baselineindex1b:=false; baselineindex2b:=false; curvedbaselineb:=false; straightbaselineb:=false; resultout(''); end; procedure Tbaseline.curvedBaselinebuttonClick(Sender: TObject); begin startbaselineset; curvedbaselineb:=true; baselineindexes; end; procedure Tbaseline.StraightBaselinebuttonClick(Sender: TObject); begin startbaselineset; straightbaselineb:=true; baselineindexes; end; procedure Differencep; var i:longint; begin if baselineb then exit; for i:=1 to datanum1 do begin a1[i]:=(a1[i]-a2[i])/mass1; a2[i]:=0; end; baselineb:=true; setaxislabels; minmax; index1:=bimin; index2:=index1; minmax; redraw; end; procedure arearesult; var i:longint; summ:double; gunit,s:string; begin if index1>index2 then begin index1:=i; index1:=index2; index2:=i; end; inc(markersp); markers[markersp]:=index1; inc(markersp); markers[markersp]:=index2; summ:=0; for i:=index1 to index2-1 do begin summ:=summ+a1[i]*(t1[i+1]-t1[i]); end; gunit:='°Cs/mg'; inc(textsp); texts[textsp].head[1]:='From '; texts[textsp].head[2]:='to '; texts[textsp].head[3]:='int dT/m='; texts[textsp].head[4]:='t='; texts[textsp].str[1]:=numconv(temp2[index1],2)+' '+tempunit; texts[textsp].str[2]:=numconv(temp2[index2],2)+' '+tempunit; texts[textsp].str[3]:=numconv(summ,2)+gunit; texts[textsp].str[4]:=numconv(t1[index2]-t1[index1],2)+' '+'s'; texts[textsp].index[1]:=index1; texts[textsp].y[1]:=a2[index1]; texts[textsp].index[2]:=index2; texts[textsp].y[2]:=a2[index2]; texts[textsp].index[3]:=(index1+index2) div 2; texts[textsp].y[3]:=a1[(index1+index2) div 2]; texts[textsp].index[4]:=(index1+index2) div 2; texts[textsp].y[4]:=a2[(index1+index2) div 2]; s:=''; for i:=1 to 4 do begin texts[textsp].b[i]:=false; s:=s+texts[textsp].head[i]+texts[textsp].str[i]+' '; end; resultout(s); areaprocb:=false; mainform.marker1ConstantLine.Active:=false; mainform.marker2ConstantLine.Active:=false; integrationindex2b:=false; redraw; end; procedure onsetresult; var xx,yy,sigma:x_vector; ndata,i,j:longint; aa:paramtype; s:string; begin if index1>index2 then begin index1:=i; index1:=index2; index2:=i; end; inc(markersp); markers[markersp]:=index1; inc(markersp); markers[markersp]:=index2; ndata:=index2-index1-1; mfit:=2; for j:=1 to ndata do begin xx[j]:=t1[j+index1-1]; yy[j]:=a1[j+index1-1]; sigma[j]:=1; end; linearcombination:=true; for j:=1 to 10 do aa[j]:=0; polifit(xx,yy,sigma,ndata,0,aa); j:=1; inc(linesp); lines[linesp].t0:=-aa[1]/aa[2]; while (t1[j]< lines[linesp].t0) do inc(j); lines[linesp].temp0:=temp1[j]; lines[linesp].a0:=0; lines[linesp].t1:=t1[index2]; lines[linesp].temp1:=temp2[index2]; lines[linesp].a1:=aa[1]+aa[2]*t1[index2]; if abs(aa[1]+aa[2]*t1[index2])