unit Unit1;
// Calculation of the pI of proteins according to Skoog and Wichman
// https://forum.lazarus.freepascal.org/index.php/topic,45188.0.html
// Book:
// TRAC: Trends in Analytical Chemistry, Volume 5
// edited by C. J. W. Brooks, A. F. Fell, R. W. Frei
// https://books.google.com.br/books?id=vIPNCgAAQBAJ&pg=PA83&lpg=PA83&dq=%22Isoelectric+point+determination+of+polypeptides%22&source=bl&ots=P6U2JITr8G&sig=ACfU3U1_--_v_3rglRuY7k93XmUXRNOqOg&hl=pt-BR&sa=X&ved=2ahUKEwiFmoer7uzhAhVBLLkGHRffBakQ6AEwAHoECAAQAQ#v=onepage&q=%22Isoelectric%20point%20determination%20of%20polypeptides%22&f=false
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
const
pKa3_arg = 12.5;
pKa3_asp = 3.9;
pKa3_cys = 8.3;
pKa3_glu = 4.3;
pKa3_his = 6.0;
pKa3_lys = 10.5;
pKa3_tyr = 10.1;
Max_chains = 5;
Max_iterations = 100;
pH1 = 1;
pH2 = 14;
Accuracy = 0.0005;
All = 'alaargasnaspcysglngluglyhisileleulysmetpheproserthrtrptyrval';
type
Str3 = String[3];
Str80 = String[80];
Aminoacid = ARRAY [1..Max_chains] OF Double;
Turn = ARRAY [1..Max_iterations] OF Double;
N_values = ARRAY [1..20] OF Double;
C_values = ARRAY [1..20] OF Double;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit10: TEdit;
Edit11: TEdit;
Edit12: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Label1: TLabel;
Label10: TLabel;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
Label14: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
Name: Str80;
Test: Str3;
Num_arg,
Num_asp,
Num_cys,
Num_glu,
Num_his,
Num_lys,
Num_tyr,
Num_chains: Integer;
N_term, C_term: Aminoacid;
Test_pH, Charge: Turn;
TermN, TermC: Double;
Number, N: Integer;
NtermpK: N_values;
CtermpK: C_values;
Sum, Temp: Double;
implementation
{$R *.lfm}
function Neg_charge (pK_value: Double; pH: Turn): Double;
begin
Neg_charge:=(exp(2.3026*((pH[N])-(pK_value))))/(1+exp(2.3026*((pH[N])-(pK_value))));
end; {Neg_charge}
function Pos_charge (pK_value: Double; pH: Turn): Double;
begin
Pos_charge := (1/(exp(2.3026*(((pH[N])-(pK_value))))+1));
end; {Pos_charge}
procedure Findend;
begin
NtermpK[01] := 9.9;
NtermpK[02] := 9.0;
NtermpK[03] := 8.8;
NtermpK[04] := 9.8;
NtermpK[05] := 10.8;
NtermpK[06] := 9.1;
NtermpK[07] := 9.7;
NtermpK[08] := 9.8;
NtermpK[09] := 9.2;
NtermpK[10] := 9.8;
NtermpK[11] := 9.7;
NtermpK[12] := 9.0;
NtermpK[13] := 9.3;
NtermpK[14] := 9.2;
NtermpK[15] := 10.6;
NtermpK[16] := 9.2;
NtermpK[17] := 9.1;
NtermpK[18] := 9.4;
NtermpK[19] := 9.1;
NtermpK[20] := 9.7;
CtermpK[01] := 2.4;
CtermpK[02] := 2.2;
CtermpK[03] := 2.1;
CtermpK[04] := 2.1;
CtermpK[05] := 1.7;
CtermpK[06] := 2.2;
CtermpK[07] := 2.2;
CtermpK[08] := 2.4;
CtermpK[09] := 1.8;
CtermpK[10] := 2.3;
CtermpK[11] := 2.3;
CtermpK[12] := 2.2;
CtermpK[13] := 2.1;
CtermpK[14] := 2.2;
CtermpK[15] := 2.0;
CtermpK[16] := 2.2;
CtermpK[17] := 2.1;
CtermpK[18] := 2.4;
CtermpK[19] := 2.2;
CtermpK[20] := 2.3;
Number := Pos(Test, All);
Number := (Number+2) DIV 3;
TermN := NtermpK[Number];
TermC := CtermpK[Number];
end; {Findend}
PROCEDURE Check (VAR Instr : Str3);
var
Count: Integer;
begin
FOR Count := 1 TO 3 DO
IF Instr[Count] IN ['A'..'Z'] THEN
Instr[Count] := CHR(ORD(Instr[Count])+32);
end; {Check}
procedure Input;
var
n : 1..Max_chains;
BEGIN
// Write('Name of protein/peptide: ');
// Readln(Name);
Name := Form1.Edit1.Text;
// Writeln;
// Writeln('Please, enter the number of charged amino acids');
// Write('arg: '); Readln(Num_arg);
Num_arg := StrToInt(Form1.Edit2.Text);
// Write('asp: '); Readln(Num_asp);
Num_asp := StrToInt(Form1.Edit3.Text);
// Write('cys: '); Readln(Num_cys);
Num_cys := StrToInt(Form1.Edit4.Text);
// Write('glu: '); Readln(Num_glu);
Num_glu := StrToInt(Form1.Edit5.Text);
// Write('his: '); Readln(Num_his);
Num_his := StrToInt(Form1.Edit6.Text);
// Write('lys: '); Readln(Num_lys);
Num_lys := StrToInt(Form1.Edit7.Text);
// Write('tyr: '); Readln(Num_tyr);
Num_tyr := StrToInt(Form1.Edit8.Text);
// Writeln;
// Write('Number of polypeptide chains: ');
// Readln(Num_chains);
Num_chains := StrToInt(Form1.Edit9.Text);
FOR n := 1 TO Num_chains DO
begin
// Write('Chain',n:2,' N-terminal amino acid: ');
// Readln(Test);
Test := InputBox('Inform Chain ', 'Chain ' + RightStr('0' + IntToStr(n),2) + ' N-terminal amino acid:', 'abc');
Check(Test);
Findend;
C_term[n] := TermC;
N_term[n] := TermN;
// Write('Chain',n:2,' C-terminal amino acid: ');
// Readln(Test);
Test := InputBox('Inform Chain ', 'Chain ' + RightStr('0' + IntToStr(n),2) + ' C-terminal amino acid:', 'abc');
Check(Test);
Findend;
C_term[n] := TermC;
// ***************************************
end;
end; {Input}
procedure Find_charge;
var
i: 1..Max_chains;
begin
Sum := 0;
Sum := Sum - (Num_asp)*(Neg_charge(pKa3_asp,Test_pH));
Sum := Sum - (Num_glu)*(Neg_charge(pKa3_glu,Test_pH));
Sum := Sum - (Num_cys)*(Neg_charge(pKa3_cys,Test_pH));
Sum := Sum - (Num_tyr)*(Neg_charge(pKa3_tyr,Test_pH));
Sum := Sum + (Num_his)*(Pos_charge(pKa3_his,Test_pH));
Sum := Sum + (Num_lys)*(Pos_charge(pKa3_lys,Test_pH));
Sum := Sum + (Num_arg)*(Pos_charge(pKa3_arg,Test_pH));
FOR i := 1 to Num_chains DO
begin
Temp :=(Pos_charge(N_term[i], Test_pH));
Sum := Sum +Temp;
Temp := (Neg_charge(C_term[i], Test_pH));
Sum := Sum - Temp;
Temp := Sum;
end;
Charge[N] := Temp;
end; {find_charge}
procedure Iterate;
var
Factor, Diff: Double;
BEGIN
N := 1;
Test_pH[N] := pH1;
Find_charge;
N := 2;
Test_pH[N] := pH2;
Find_charge;
REPEAT
N := N+ 1;
begin
Factor := ((Test_pH[N-1])-(Test_pH[N-2]))/((Charge[N-1])-(Charge[N-2]));
Test_pH[N] := (Test_pH[N-1])-(Charge[N-1]*Factor);
Find_charge;
Temp := (Charge[N])-(Charge[N-1]);
Diff := ABS(Temp);
end;
UNTIL (Diff)<=(Accuracy);
// Writeln;
// Writeln('Isoelectric point calculated to pH = ', Test_pH[N]:5:3);
Form1.Edit10.Text := FormatFloat('00000.000', Test_pH[N]);
// Writeln;
// Writeln('Accuracy = ', Accuracy:7:5, ' pH units');
Form1.Edit11.Text := FormatFloat('0000000.00000', Accuracy);
// Writeln('Number of iterations = ', N);
Form1.Edit12.Text := IntToStr(N);
end; {Iterate}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
Input;
Iterate;
end;
end.