write_atom_itp.m

Contents

Version

2.11

Contact

Please report problems/bugs to michael.holmboe@umu.se

Examples

  1. write_atom_itp(atom,Box_dim,filename) % Basic input arguments
  2. write_atom_itp(atom,Box_dim,filename,1.25,1.25) % Default forcefield is clayff_2004
  3. write_atom_itp(atom,Box_dim,filename,1.25,2.25,'clayff','spc/e')
  4. write_atom_itp(atom,Box_dim,filename,1.25,2.25,'interface','tip3p')
  5. write_atom_itp(atom,Box_dim,filename,1.25,2.25,'interface','tip3p',1)
function write_atom_itp(atom,Box_dim,filename,varargin)
format long
nAtoms=size(atom,2);

if regexp(filename,'.itp') ~= false
    filename = filename;
else
    filename = strcat(filename,'.itp');
end

if nargin > 3
    maxrshort=varargin{1}
    maxrlong=varargin{2}
else
    maxrshort=1.25;
    maxrlong=1.25; % long=short since clayff
end

if nargin > 7
    MolId=varargin{5};
    if ~ischar(MolId)
        MolId=strcat('_',num2str(MolId));
    end
else
    MolId=[];
end

if nargin>5
    ffname=varargin{3}
    if nargin>6
        watermodel=varargin{4}
    else
        disp('Unknown watermodel, will try SPC/E')
        watermodel='SPC/E'
    end

    if strcmpi(ffname,'clayff')
        clayff_param(sort(unique([atom.type])),watermodel);
        if ~isfield(atom,'charge')
            atom = charge_atom(atom,Box_dim,'clayff',watermodel,'adjust');
        end
        Total_charge=sum([atom.charge])
        round(Total_charge,5)
        %         pause
        nrexcl=1; % See the gromacs manual
        explicit_bonds = 0
        explicit_angles = 1
    elseif strncmpi(ffname,'clayff_2004',5)
        clayff_2004_param(sort(unique([atom.type])),watermodel);
        if ~isfield(atom,'charge')
            atom = charge_atom(atom,Box_dim,'clayff_2004',watermodel,'adjust');
        end
        Total_charge=sum([atom.charge])
        round(Total_charge,5)
        %         pause
        nrexcl=1; % See the gromacs manual
        explicit_bonds = 0
        explicit_angles = 1
    elseif strcmpi(ffname,'interface')
        interface_param(sort(unique([atom.type])),watermodel);
        if ~isfield(atom,'charge')
            atom = charge_atom(atom,Box_dim,'interface',watermodel,'adjust');
        end
        Total_charge=sum([atom.charge])
        nrexcl=2; % See the gromacs manual
        explicit_bonds = 1;
        explicit_angles = 1;

    elseif strcmpi(ffname,'interface15')
        atom = mass_atom(atom);
        nrexcl=2; % See the gromacs manual
        %         interface15_param(sort(unique([atom.type])),watermodel);
        %         atom = charge_atom(atom,Box_dim,'interface15',watermodel,'adjust');
        if nargin > 7
            model_database=varargin{5}
        else
            model_database='CLAY_MINERALS'
        end
        atom = check_interface15_charge(atom,model_database);
        Total_charge
        nrexcl=2; % See the gromacs manual
        explicit_bonds = 0 % 0 currently does not work, because no default bond types
        explicit_angles = 0% 0 currently does not work, because no default angle types
    elseif strcmpi(ffname,'interface_car')
        % Experimental!!!
        atom = mass_atom(atom);
        nrexcl=2; % See the gromacs manual
        explicit_bonds = 1
        explicit_angles = 1
        %     elseif strcmpi(ffname,'oplsaa_go');
        %         % This is not for you...
        %         oplsaa_go_param(sort(unique([atom.type])),watermodel);
        %         atom = charge_opls_go_atom(atom,Box_dim,{'H' 'Oe' 'Oh'},[0.418 -0.4 -0.683])
        %         Total_charge
        %         nrexcl=3; % See the gromacs manual
        %         explicit_bonds = 0;
        %         explicit_angles = 0;
    end
else
    disp('Forcefield not stated, will make some assumptions then...')
    pause(2)
    ffname='clayff'
    watermodel='SPC/E'
    pause(2)
    atom = mass_atom(atom);
    element=element_atom(atom);
    [atom.element]=element.type;
    if ~isfield(atom,'charge')
        atom = charge_atom(atom,Box_dim,ffname,watermodel);
    end
    nrexcl=1; % See the gromacs manual
    explicit_bonds = 0
    explicit_angles = 0
end

Find atomtype specific indexes

ind_Hneighbours = find(~cellfun(@isempty,regexpi([atom.type],'h')));
ind_H=find(strncmpi([atom.type],{'H'},1));
ind_O=find(strncmpi([atom.type],{'O'},1));
ind_Osih=find(strncmpi([atom.type],{'Osih'},4));
ind_Alhh=find(strncmpi([atom.type],{'Oalhh'},5));
ind_Oh=intersect(ind_O,ind_Hneighbours);
ind_Al=find(strncmpi([atom.type],'Al',2));
ind_Mgo=find(ismember([atom.type],{'Mgo' 'Mgh'}));
ind_Si=find(strncmpi([atom.type],{'Si'},2));
ind_Oct=sort([ind_Al ind_Mgo]);
ind_Edge=unique([ind_H ind_Alhh ind_Osih]);

atom = bond_angle_atom(atom,Box_dim,maxrshort,maxrlong);
if strncmpi(ffname,'clayff',5)
    %     %% To only keep bonds to atoms also bonded to H's, uncomment the next four lines
    %     disp('Keeping only bonds with H')
    %     [h_row,h_col]=ind2sub(size(Bond_index),find(ismember(Bond_index,ind_Hneighbours)));
    %     Bond_index=Bond_index(h_row,:);
    %     nBonds=size(Bond_index,1);

To only keep bonds to H's, uncomment the next three lines

   [H_row,H_col]=ind2sub(size(Bond_index),find(ismember(Bond_index,ind_H)));
   Bond_index=Bond_index(H_row,:);
   nBonds=size(Bond_index,1);
    %     %% To only keep edge bonds (and all O-H), uncomment the next four lines
        disp('Keeping only bonds with H or edge-O ')
        [h_row,h_col]=ind2sub(size(Bond_index),find(ismember(Bond_index,ind_Edge)));
        Bond_index=Bond_index(h_row,:);

To only keep bonds between Osih - H, uncomment the next four lines

   disp('Keeping only bonds with H')
   [h_row,h_col]=ind2sub(size(Bond_index),find(ismember(Bond_index,ind_Osih)));
   Bond_index=Bond_index(h_row,:);
   nBonds=size(Bond_index,1);
    %     %% To remove bonds with 'Al'
    %     [Al_row,Al_col]=ind2sub(size(Bond_index),find(ismember(Bond_index,ind_Al)));
    %     Bond_index(Al_row,:)=[];
    %     nBonds=size(Bond_index,1);

    %     %% To remove bonds with 'Si'
    %     [Si_row,Si_col]=ind2sub(size(Bond_index),find(ismember(Bond_index(:,2),ind_Si)));
    %     Bond_index(Si_row,:)=[];
    %     nBonds=size(Bond_index,1);

    %    %% To remove bonds larger than certain rmin, uncomment next two lines
    %     rm_ind=find(Bond_index(:,3)>1.25);
    %     Bond_index(rm_ind,:)=[];
    %     nBonds=size(Bond_index,1);
end

[Y,I]=sort(Bond_index(:,1));
Bond_index=Bond_index(I,:);
Bond_index = unique(Bond_index,'rows','stable');

% if strncmpi(ffname,'clayff',5)
%     disp('What to do with edge angles with Al')
%     disp('Removing angles with Al')
%     [Al_row,Al_col]=ind2sub(size(Angle_index),find(ismember(Angle_index,ind_Al)));
%     Angle_index(Al_row,:)=[];
%     % To remove angles with 'Si'
%     Si_ind=find(strcmp(XYZ_labels(:,1),'Si'));
%     [Si_row,Si_col]=ind2sub(size(Angle_index),find(ismember(Angle_index(:,2),Si_ind)));
%     Angle_index(Si_row,:)=[];
% %% Extra stuff
%     Angle_index
%     rm_ind=find(Angle_index(:,4)>150|Angle_index(:,4)<60);
%     Angle_index(rm_ind,:)=[];
%     [Y,I]=sort(Angle_index(:,2));
%     Angle_index=Angle_index(I,:);
%     Angle_index = unique(Angle_index,'rows','stable');
% end

%
file_title = 'Gromacs awesome itp file'; % Header in output file
molecule_name = char([atom(1).resname]); % molecule name
Atom_label = unique([atom.type]);

fid = fopen(filename, 'wt'); % open a text file that we can write into

fprintf(fid, '%s % s\n',';',file_title);
fprintf(fid, '%s % s\n',';','File written by MHolmboe (michael.holmboe@umu.se)');
fprintf(fid, '\n');
fprintf(fid, '%s\n','[ moleculetype ]');
fprintf(fid, '%s % s\n',';','molname   nrexcl');
% fprintf(fid, '%s       %d\n',strrep(molecule_name(1:3),'.itp',''),nrexcl);
fprintf(fid, '%s       %d\n',strcat(molecule_name(1:3),MolId),nrexcl);
fprintf(fid, '\n');
fprintf(fid, '%s\n','[ atoms ]');
fprintf(fid, '%s\n','; id   attype  resnr resname  atname   cgnr  charge      mass');

Atom_label_ID=ones(size(atom,2),1);
for i = 1:nAtoms
    if sum(ismember(Atom_label,[atom(i).type])) > 0
        Atom_label_ID(i,1)=find(ismember(Atom_label,[atom(i).type])==1);
    end

    if isfield(atom,'mass')
        Atoms_data(i,:) = {i, char([atom(i).fftype]),[atom(i).molid],molecule_name(1:3),char([atom(i).type]),i, round([atom(i).charge],6),[atom(i).mass]};
    else exist('Masses','var');
        Atoms_data(i,:) = {i, char([atom(i).type]),[atom(i).molid],molecule_name(1:3),char([atom(i).type]),i, round([atom(i).charge],6), Masses(Atom_label_ID(i,1))};
    end
    fprintf(fid, '%-4i%6s%8i%8s%8s%8i\t% 8.6f\t% 8.6f\n', Atoms_data{i,:});
end

fprintf(fid, '\n');
fprintf(fid, '[ bonds ] \n');
fprintf(fid, '%s\n','; i    j    type');

count_b = 1;
bondtype=1; % Gromacs bond type. 1 means harmonic bond, k(r-ro)^2, see manual.
% explicit_bonds = 0;
while count_b <= size(Bond_index,1)
    if explicit_bonds == 1
        if sum(ismember(Bond_index(count_b,1:2),ind_H))>0
            if strncmpi(ffname,'interface',5)
                r=0.09290;
                kb=414216;
            else
                r=0.09789;
                kb=463700;
            end
        else
            if strncmpi(ffname,'interface',5)
                r=Bond_index(count_b,3)/10*1.05;
                kb=359824;
            else
                r=Bond_index(count_b,3)/10;
                kb=360000;
            end
        end
        % Normal
        Bond_order(count_b,:)= {Bond_index(count_b,1), Bond_index(count_b,2), bondtype, r, kb, ';',strtrim(char([atom(Bond_index(count_b,1)).fftype])), strtrim(char([atom(Bond_index(count_b,2)).fftype]))};
        fprintf(fid, '%-5i\t%-5i\t%-5i\t%-8.4f\t%-8.4f\t%s\t%s-%s\n', Bond_order{count_b,:});

        % Custom
        %                 Bond_order(count_b,:)= {Bond_index(count_b,1), Bond_index(count_b,2), 10, r*.95, r*1.05, r*1.05+.01 , kb, ';',strtrim(char([atom(Bond_index(count_b,1)).type])), strtrim(char([atom(Bond_index(count_b,2)).type]))};
        %                 fprintf(fid, '%-5i\t%-5i\t%-5i\t%-8.4f\t%-8.4f\t%-8.4f\t%-8.4f\t%s\t%s-%s\n', Bond_order{count_b,:});
        %                 fprintf(fid, '%-5i %-5i %-5i %-8.4f %-8.4f %s %s-%s\n', Bond_order{count_b,:});
        count_b = count_b + 1;
    else
        Bond_order(count_b,:)= {Bond_index(count_b,1), Bond_index(count_b,2), bondtype, ';', Bond_index(count_b,3)/10, strtrim(char([atom(Bond_index(count_b,1)).fftype])), strtrim(char([atom(Bond_index(count_b,2)).fftype]))};
        fprintf(fid, '%-5i %-5i %-5i %s %-8.4f %s-%s \n', Bond_order{count_b,:});
        count_b = count_b + 1;
    end
end

try
    if numel(Bond_order)>0
        assignin('caller','Bond_order',Bond_order);
        disp('These atom types has bonds')
        unique(Bond_order(:,end-1:end))
    end
catch
    disp('No bonds?')
end

fprintf(fid, '\n');
fprintf(fid, '\n');
fprintf(fid, '[ angles ] \n');
fprintf(fid, '%s\n','; i    j   k   type');

count_a = 1;%explicit_angles = 0;
angletype=1; Angle_order={};
Angle_index=sortrows(Angle_index);
while count_a <= length(Angle_index) %nAngles;
    if explicit_angles == 1
        if sum(ismember(Angle_index(count_a,1:3),ind_H))==1
            if sum(ismember(Angle_index(count_a,1:3),ind_Mgo))>0 % Pouvreau,? Jeffery A. Greathouse,? Randall T. Cygan,? and Andrey G. Kalinichev 2017
                adeg=110;
                ktheta=50.208;
            elseif sum(ismember(Angle_index(count_a,1:3),ind_Al))>0 % Pouvreau,? Jeffery A. Greathouse,? Randall T. Cygan,? and Andrey G. Kalinichev 2017
                adeg=110; %
                ktheta=125.52; %
            else % Maxime Pouvreau, et al., 2019, before orig Clayff, 2004
                adeg=100; %
                ktheta=125.52; % 251.04; % since 15*4.184*2;% earlier 96.232*10; %
            end
        elseif sum(ismember(Angle_index(count_a,1:3),ind_H))==2  %             && sum(ismember(Angle_index(count_a,1:3),ind_Oh))>0 && sum(ismember(Angle_index(count_a,1:3),ind_Oct))>0
            adeg=109.47; % SPC water
            ktheta=383; % SPC water
        else % Orig Interface 2005
            adeg=Angle_index(count_a,4);
            ktheta=1422.56;
        end
        Angle_order(count_a,:)= {Angle_index(count_a,1), Angle_index(count_a,2), Angle_index(count_a,3), angletype, round(adeg,2),	ktheta, ';', strtrim(char([atom(Angle_index(count_a,1)).type])), strtrim(char([atom(Angle_index(count_a,2)).type])), strtrim(char([atom(Angle_index(count_a,3)).type]))};
        fprintf(fid, '%-5i %-5i %-5i %-5i %-6.2f %-8.4f %s %s-%s-%s\n', Angle_order{count_a,:});
        count_a = count_a + 1;
    else
        Angle_order(count_a,:)= {Angle_index(count_a,1), Angle_index(count_a,2), Angle_index(count_a,3), angletype, ';', round(Angle_index(count_a,4),2), strtrim(char([atom(Angle_index(count_a,1)).fftype])), strtrim(char([atom(Angle_index(count_a,2)).fftype])), strtrim(char([atom(Angle_index(count_a,3)).fftype]))};
        fprintf(fid, '%-5i %-5i %-5i %-5i %s %-6.2f %s-%s-%s\n', Angle_order{count_a,:});
        count_a = count_a + 1;
    end
end
fprintf(fid, '\n');
fprintf(fid, '\n');

if numel(Angle_order)>0
    assignin('caller','Angle_order',Angle_order);
    disp('These atom types has angles')
    unique(Angle_order(:,end-2:end))
end

if exist('Total_charge','var')
    disp('Total charge for the .itp file was')
    round(Total_charge,5)
end

% Defining [ exclusions ]
%     if length(Angle_index) > 0;
%
%         fprintf(fid, '\n');
%         fprintf(fid, '\n');
%         fprintf(fid, '[ exclusions ] \n');
%         fprintf(fid, '%s\n','; i    j   k   type');
%
%         count_excl = 1;
%         Excl_index=[Angle_index(:,1) Angle_index(:,2) Angle_index(:,3); Angle_index(:,2) Angle_index(:,3) Angle_index(:,1); Angle_index(:,2) Angle_index(:,3) Angle_index(:,1)];
%         while count_excl <= length(Excl_index);
%             Excl_order(count_excl,:)= {Excl_index(count_excl,1), Excl_index(count_excl,2), Excl_index(count_excl,3),';', strtrim(char(XYZ_labels(Excl_index(count_excl,1)))), strtrim(char(XYZ_labels(Excl_index(count_excl,2)))), strtrim(char(XYZ_labels(Excl_index(count_excl,3))))};
%             fprintf(fid, '%-5i %-5i %-5i %s %s-%s-%s\n', Excl_order{count_excl,:});
%             count_excl = count_excl + 1;
%         end
%
%     end

%%%%%%%%%%%%%%%%%%

fprintf(fid, '#ifdef POSRES_XY_MMT_1  \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');

for i = 1:nAtoms
    if ismember(i,ind_Oct)
        pos_res(i,:) = {num2str(i), '1', '100', '100', '10000'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');

fprintf(fid, '#ifdef POSRES_XY_MMT_2  \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
for i = 1:nAtoms
    if ismember(i,ind_Oct)
        pos_res(i,:) = {num2str(i), '1', '1000', '1000', '0'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');

%%%%%%%%%%%%


if strncmpi(ffname,'clayff',5)
    fprintf(fid, '#ifdef POSRES_Clayff \n');
    fprintf(fid, '[ position_restraints ] \n');
    fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
    for i = 1:nAtoms
        pos_res(i,:) = {num2str(i), '1', '1000', '1000', '1000'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
    fprintf(fid, '#endif \n');
else
    fprintf(fid, '#ifdef POSRES_interface \n');
    fprintf(fid, '[ position_restraints ] \n');
    fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
    for i = 1:nAtoms
        pos_res(i,:) = {num2str(i), '1', '1000', '1000', '1000'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
    fprintf(fid, '#endif \n');
end

fprintf(fid, '\n');
fprintf(fid, '\n');

fprintf(fid, '#ifdef POSRES \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
for i = 1:nAtoms
    pos_res(i,:) = {num2str(i), '1', '1000', '1000', '1000'};
    fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
    fprintf(fid, '\n');
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');

fprintf(fid, '#ifdef POSRES_noH \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
for i = 1:nAtoms
    if strncmpi([atom(i).type],'H',1)==0
        pos_res(i,:) = {num2str(i), '1', '1000', '1000', '1000'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');

fprintf(fid, '#ifdef POSRES_XYZ \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
for i = 1:nAtoms
    if strncmpi([atom(i).type],'H',1)==0
        pos_res(i,:) = {num2str(i), '1', '500', '500', '500'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');

fprintf(fid, '#ifdef POSRES_XY \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
for i = 1:nAtoms
    if strncmpi([atom(i).type],'H',1)==0
%         if strcmp([atom(i).type],'Al') > 0 || strcmp([atom(i).type],'Mgo') > 0
            pos_res(i,:) = {num2str(i), '1', '1000', '1000','0'};
            fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
            fprintf(fid, '\n');
%         end
    end
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');

fprintf(fid, '#ifdef POSRES_Oct_500 \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
for i = 1:nAtoms
    if ismember(i,ind_Oct)
        pos_res(i,:) = {num2str(i), '1', '500', '500', '500'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');

fprintf(fid, '#ifdef POSRES_Y_100 \n');
fprintf(fid, '[ position_restraints ] \n');
fprintf(fid, '%s\n','; atom  type      fx      fy      fz');
for i = 1:nAtoms
    if ismember(i,ind_Oct)
        pos_res(i,:) = {num2str(i), '1', '1000', '100', '1000'};
        fprintf(fid, '%6s\t%6s\t%6s\t%6s\t%6s%\n', pos_res{i,:});
        fprintf(fid, '\n');
    end
end
fprintf(fid, '#endif \n');

fprintf(fid, '\n');
fprintf(fid, '\n');


fclose(fid);

[atom(strcmp([atom.type],{'Ow'})).type]=deal({'OW'});
[atom(strcmp([atom.type],{'Hw'})).type]=deal({'HW'});

atom_itp=atom;
assignin('caller','atom_itp',atom_itp);
assignin('caller','Bond_index',Bond_index);
assignin('caller','Angle_index',Angle_index);
assignin('caller','nBonds',nBonds);
assignin('caller','nAngles',nAngles);
% assignin('caller','atom',atom);
% atom = charge_atom(atom,Box_dim,ffname,watermodel,'more');
% assignin('caller','Total_charge',Total_charge);
% assignin('caller','Masses',Masses);

% toc