#svl // // QuaSAR_CSA.svl // #set title 'Seelig' // QuaSAR Implementation of QuaSAR Descriptors #set class 'QuaSAR' // module class of descriptors function QuaSAR_list_Seelig [] = tr [ [ 'AA', 'Length of amphilicity axis (weigthed by TPSA and XlogP)', '2D', [] ], [ 'CSA', 'Cross-sectional area (weighted by TPSA and exp XlogP, projected)', '2D', [] ], [ 'LAA', 'Length of the molecule along the AA', '2D', [] ], [ 'NOOM', 'Number of atoms outside of the membrane', '2D', [] ], [ 'VOOM', 'Volume outside of the membrane', '3Di', [] ], [ 'LA', 'Lipoaffinity (acc. Liu 2001)', '2D', [] ] ]; // Color codes const white = 0xFFFFFF; const black = 0x000000; const yellow = 0xFFFF00; const red = 0xFF0000; const magenta = 0xFF00FF; const cyan = 0x00FFFF; const grey = 0x666666; const green = 0x33FF33; const UNK = '?'; // XlogP atoms contributions const XLOGP = tr reverse [ // phosphorus [ -0.326, '[PX3]', 'P' ], // 76: Psp3 [ -0.326, '[PX4]', 'P' ], // 76: Psp3 // sulfur [ 0.826, '[SQ1]', 'SH-' ], // 66: -SH [ 0.952, '[SQ2H0]', 'S<' ], // 67: -S- [ 0.733, 's', 'Sar' ], // 68: -S- [ 0.733, '[SQ2]1*=**=*1', 'Sar' ], // 68: -S- (ring,pi=2) [ 0.733, '[SQ2]1*:**:*1', 'Sar' ], // 68: -S- (ring,pi=2) [ 0.733, '[SQ2]1*=**:*1', 'Sar' ], // 68: -S- (ring,pi=2) [ 0.733, '[SQ2]1*=*~*~*=*1', 'Sar' ], // 68: -S- (ring,pi=2) [ 0.733, '[SQ2]1*:*~*~*:*1', 'Sar' ], // 68: -S- (ring,pi=2) [ 0.733, '[SQ2]1*=*~*~*:*1', 'Sar' ], // 68: -S- (ring,pi=2) [ -0.661, '[SX3][OX1]', 'SO' ], // 70: -SO- [ 0.306, '[SX4]([OX1])[OX1]', 'SO2' ], // 71: -SO2- [ -0.798, 'S=*', 'S=' ], // 69: S= [ 0.000, 'S=C=*', UNK ], // Hydrogen and Halogens [ 0.490, 'F', 'F' ], // 72: -F [ 0.929, '[Cl]', 'Cl' ], // 73: -Cl [ 1.135, '[Br]', 'Br' ], // 74: -Br [ 1.527, '[I]', 'I' ], // 75: -I [ 0.165, '[#1]', 'H' ], // 37: -H [ 0.000, '[#1]-S', UNK ], [ 0.000, '[#1]-O', UNK ], [ 0.000, '[#1]-N', UNK ], [ 0.000, '[#1][#6]', UNK ], [ -0.324, '[OQ1]', 'OH-X' ], // 40: OH-X #HET [ 0.029, '[OQ1][#6]', 'OH-C' ], // 39: OH-C #HET0 #PI [ -0.319, '[OQ1][#6X4]', 'OH-[CX4]'], // 38: OH-C #HET0 #PI0 [ 0.142, '[OQ2]', 'O-X' ], // 42: -O- #HET>0 [ 0.316, '[OQ2]([#6])[#6]', 'O-C2' ], // 41: C-O-C [ -0.082, 'o', 'Oar' ], // 43: O.ar [ -0.082, '[OQ2]1*=**=*1', 'Oar' ], // 43: -O- (ring,pi=2) [ -0.082, '[OQ2]1*:**:*1', 'Oar' ], // 43: -O- (ring,pi=2) [ -0.082, '[OQ2]1*=**:*1', 'Oar' ], // 43: -O- (ring,pi=2) [ -0.082, '[OQ2]1*=*~*~*=*1', 'Oar' ], // 43: -O- (ring,pi=2) [ -0.082, '[OQ2]1*:*~*~*:*1', 'Oar' ], // 43: -O- (ring,pi=2) [ -0.082, '[OQ2]1*=*~*~*:*1', 'Oar' ], // 43: -O- (ring,pi=2) [ 0.150, '[OX1]', 'Ox' ], // 0: -O [ -0.654, 'O=[#6]', 'O=C' ], // 44: O=C [ -0.374, '[OX1]-S', 'Ox-PS' ], // 45: O-{SO,SO2} !!! [ -0.374, '[OX1]-P', 'Ox-PS' ], // 45: O-Psp3 // sp3 Nitrogen [ -0.793, '[NQ1]', 'N1X' ], // 48: N #HET=1 [ -0.335, '[NQ1][#6]', 'N1C.' ], // 47: N #HET=0 #PI>1 [ -0.541, '[NQ1][#6X4]', 'N1C' ], // 46: N #HET=0 #PI=0 [ -0.103, '[NQ2]', 'N2' ], // 50: N #HET=1 [ 0.007, '[NQ2]([#6])[#6]', 'N2C2' ], // 49: N #HET=0 [ -0.429, '[NQ3]', 'N3C' ], // 52: N #HET>1 [ 0.298, '[NQ3]([#6])([#6])[#6]', 'N3C3' ], // 51: N #HET=0 // sp2 N (planar), No LP /* [ 0.000, '[N3Q2Lp0$(*(-*=*)-*=*)]', 4], // 60: Npl3 RING !!! [ 0.000, '[N3Q2Lp0$(*(-a)-a)]', 4], // 60: Npl3 RING !!! [ 0.000, '[N3Q2Lp0$(*(-*=*)-a)]', 4], // 60: Npl3 RING !!! */ [ 1.769, '[NX3Q2Lp0$(*(-*=*)-*=*)]' , 'N2pl3X' ], [ 1.769, '[NX3Q2Lp0$(*(-a)-*=*)]', 'N2pl3X' ], [ 1.769, '[NX3Q2Lp0$(*(-a)-a)]', 'N2pl3X' ], [ 0.088, '[NX3Q2Lp0$(*(-*=*)-*=*)]([#6])[#6]', 'N2pl3' ], [ 0.088, '[NX3Q2Lp0$(*(-a)-*=*)]([#6])[#6]', 'N2pl3' ], [ 0.088, '[NX3Q2Lp0$(*(-a)-a)]([#6])[#6]', 'N2pl3' ], /* [ 0.000, '[NX3Q3Lp0$(*(-*=*)-*=*)]', 'N3pl3r'], [ 0.000, '[NX3Q3Lp0$(*(-a)-*=*)]', 'N3pl3r'], [ 0.000, '[NX3Q3Lp0$(*(-a)-a)]', 'N3pl3r'], */ [ 0.444, '[NX3Q3Lp0$(*(-*=*)-*=*)]', 'N3pl3' ], // 61: Npl3 [ 0.444, '[NX3Q3Lp0$(*(-a)-a)]', 'N3pl3' ], // 61: Npl3 [ 0.444, '[NX3Q3Lp0$(*(-a)-*=*)]', 'N3pl3' ], // 61: Npl3 [ -0.028, '[NX3Lp0]=O', 'NO2' ], [ -0.411, 'n[#6]', 'NarX' ], // [ 0.430, 'n([#6])([#6])[#6]', 'Nar' ], // [ -0.328, '[nLp]', 'NarLpX2' ], // [ -0.179, '[nLp](c)', 'NarLpX1' ], // [ -0.533, '[nLp](c)c', 'NarLp' ], // [ 0.044, '[nLp]1caaaa1', 'Nar6X' ], // [ -0.478, '[nLp]1caaac1', 'Nar6' ], // [ 0.020, '[nH]', 'NarHX*' ], // [ -0.148, '[nH](c)c', 'NarH' ], // // general sp2 Nitrogen (N.2) [ -0.084, '[NLp]=C', 'N=CX' ], // 54: -N=C #HET=1 [ -0.580, '[NH0Lp](=C)[#6]', 'N=C' ], // 53: -N=C #HET=0 [ -0.580, '[NH1Lp](=C)', 'N=C' ], // 53: -N=C #HET=0 [ -1.383, '[NLp]=N', 'N=NX' ], // 56: -N=N #HET=2 [ 0.356, '[NH0Lp](=N)[#6]', 'N=N' ], // 55: -N=N #HET=1 [ 0.356, '[NH1Lp]=N', 'N=N' ], // 55: -N=N #HET=1 [ 0.809, '[NLp]=C=*', 'N=C=' ], // 78: -N=C=* [ 0.206, '[NLp]=O', 'N=O' ], // 79: -N=O // sp2 Nitrogen (Amide) [ -0.705, '[#7Q1][#6]=O', 'N1C=O' ], // 63: N.am [ -0.326, '[#7Q2][#6]=O', 'N2C=O' ], // 64: N.am [ -0.106, '[#7Q3][#6]=O', 'N3C=O' ], // 65: N.am // sp Nitrogen [ -0.168, 'N#*', 'Nsp' ], // 77: #N [ -0.168, 'N(=*)=*', 'Nsp' ], // 77: =N= new! [ 0.516, '[CQ1]=*', 'C=' ], [ 0.585, '[CQ2]=*', 'C2=X' ], [ -0.297, '[CQ2]=C', 'C2=CX' ], [ 0.322, '[CQ2](=C)[#6]', 'C2=C' ], [ 0.601, '[CQ3]=*', 'C3=X3' ], [ 0.306, '[CQ3](=*)[#6]', 'C3=X2' ], [ 0.209, '[CQ3](=*)([#6])[#6]', 'C3=X' ], [ 0.064, '[CQ3]=C', 'C3=CX' ], [ 0.129, '[CQ3]=C([#6])[#6]', 'C3=C' ], // C.ar [ -0.011, '[cQ3]', 'cX' ], [ 0.322, '[cQ3](c)(c)[#6]', 'c' ], [ 0.182, '[cQ3]:n', 'c:nX2' ], [ 0.071, '[cQ3](:n)([#6])[#6]', 'c:nX1' ], [ 0.020, '[cQ3](:n):n', 'c:n2' ], [ 0.281, 'c(:a)(:a):a', 'c:3' ], [ -0.010, '[cH]', 'C.arHX2' ], [ 0.115, '[cH][#6]', 'C.arHX1' ], [ 0.367, '[cH]([#6])[#6]', 'C.arH' ], [ 0.329, '[cH]([cH])[#6]', 'C.arH-CHC' ], [ 0.328, '[cH]([cH])[cH]', 'C.arH-CHCH' ], // sp Carbon [ -0.168, '[CQ2]#*', 'C#X' ], // UNK? [ 0.809, '[CQ2](=*)=*', 'C(=X)=*' ], [ 0.373, 'C(=C)=C', 'Csp' ], [ 0.373, 'C#C', 'Csp' ], [ 0.109, '[CH]#*', 'CH#' ], // sp3 Carbon [ -0.023, '[CX4Q1]', 'C1-X' ], [ 0.302, '[CX4Q1][#6]', 'C1.' ], [ 0.689, '[CX4Q1][CX4]', 'C1' ], [ 0.517, '[CX4Q1][CX4][#N]', 'C1-E' ], [ -0.288, '[CX4Q2]', 'C2-X2' ], [ -0.199, '[CX4Q2][#6]', 'C2-X1' ], [ 0.088, '[CX4Q2]([#6])[#6]', 'C2.' ], [ 0.442, '[CX4Q2]([#6X4])[#6X4]', 'C2' ], [ -0.376, '[CX4Q3]', 'C3-X*' ], [ -0.254, '[CX4Q3]([#6])[#6]', 'C3-X1' ], [ -0.231, '[CX4Q3]([#6])([#6])[#6]', 'C3.' ], [ 0.111, '[CX4Q3]([#6X4])([#6X4])[#6X4]', 'C3' ], [ -0.011, '[CQ4]', 'C4-X4' ], [ -0.492, '[CQ4][#6]', 'C4-X3' ], [ 0.051, '[CQ4]([#6])[#6]', 'C4-X2' ], [ -0.364, '[CQ4]([#6])([#6])[#6]', 'C4-X1' ], [ 0.086, '[CQ4]([#6])([#6])([#6])[#6]', 'C4.' ], [ -0.564, '[CQ4]([#6X4])([#6X4])([#6X4])[#6]', 'C4.1' ], [ -0.179, '[CQ4]([#6X4])([#6X4])([#6X4])[#6X4]', 'C4' ] ]; // MM: functions for correction terms eliminated // TPSA Fragments and values const TPSA = tr [ // nitrogen rules [ '[NH0Q3!ir3]', 3.01], // 6 [ '[NH0Q3!i!r3]', 3.24], // 1 [ '[NH0Q2]=*', 12.36], // 2 [ '[NH0Q1]#*', 23.79], // 3 [ '[NH0Q3+]([!#G4!i-*])=*', 11.68], // 4 [ '[NH0Q3+]=*', 3.01], // 12 [ '[NH0Q2+]([#Q-*])#[#Q!-*]', 13.60], // 5 [ '[NH0Q2+]([#Q!-*])#[#Q-*]', 4.36], // 13 [ '[NH0Q4+]', 0.00], // 11 [ '[NH1Q1+0]=*', 23.85], // 9 [ '[NH1Q2!i+0r3]', 21.94], // 8 [ '[NH1Q2!i+0!r3]', 12.03], // 7 [ '[NH1Q2+]=*', 13.97], // 15 [ '[NH1Q3!i+]', 4.44], // 14 [ '[NH2Q2+!i]', 16.61], // 16 [ '[NH2Q1+0!i]', 26.02], // 10 [ '[NH2Q1+]=*', 25.59], // 17 [ '[NH3Q1+]', 27.64], // 18 [ '[nX2Q2+0]', 12.89], // 19 [ '[nX3Q3+0](:*)(:*):*', 4.41], // 20 [ '[nX3Q3+0](-*)(:*):*', 4.93], // 21 [ '[nX3H1+0]', 15.79], // 23 [ '[nX3Q3+1]-[#Q-*]', 8.39], // 22 [ '[nX3Q3+1](:*)(:*):*', 4.10], // 24 [ '[nX3Q3+1](-*)(:*):*', 3.88], // 25 [ '[nH1Q2+1]', 14.14], // 26 // oxygen rules [ '[OX2Q2!ir3]', 12.53], // 28 [ '[OX2Q2!i]', 9.23], // 27 [ '[oX2Q2]', 13.14], // 32 [ '[OX2H1Q1!i]', 20.23], // 30 -OH [ '[OX1Q1]=*', 17.07], // 29 =O [ '[OX1Q1-]-[#Q+*]', 17.07], // 29 -O coord [ '[OX1Q1-]-[#Q!+*]', 23.06], // 31 !coord // sulfur rules [ '[SX1Q1]=*', 32.09], // 34 =S [ '[SX1Q1-]-[#Q+*]', 32.09], // 34 -S coord [ '[SX2Q1H1!i]', 38.80], // 37 -SH [ '[SX3Q3+1!i](-[#Q-*])', 19.21], // 35 sulfide [ '[sX3Q3+1]-[#Q-*]', 21.70], // 39 // phosphorus rules [ '[PX3Q3!i]', 13.59], // 40 [ '[PX2Q2i]=*', 34.14], // 41 [ '[PX4Q3H1+]-[#Q-*]', 23.47], // 43 [ '[SX2Q2!i]', 25.30], // 33 -S- [ '[sX2Q2]', 28.24], // 38 -s- aro [ '[SX4Q4+2!i](-[#Q-*])(-[#Q-*])', 8.38], // 36 sulfone [ '[PX4Q4+]-[#Q-*]', 9.81] // 42 ]; global cross_sectional_area; global hydrophilic_atom_count; global hydrophobic_atom_count; global noom; // number of atoms out of the membrane global volume_out_of_membrane; // number of atoms out of the membrane global laa; // length along the amphiphilic axis global tpsa_sum; global xlogp_sum; function v_length vector local i; local vlength = 0; for i=1, length vector, 1 loop vlength = vlength + sqr( vector[i] ); endloop vlength = sqrt( vlength ); return vlength; endfunction // other helpful functions function in_array [needle, haystack] local found=0; local i=0; for i=1, length(haystack), 1 loop if needle == haystack[i] then found=1; endif; endloop; return found; endfunction // function mean vector // brackets would only give to first value of a vector to the function // // print length( vector ); // // print add vector; // local mean = (add vector) / (length vector); // return mean; // endfunction // slide the molecule to the supplied center function recenter_molecule [ center, molecule ] aSetPos [molecule, (aPos molecule - center) ]; endfunction function generate_shape [c1, c2, spacing] // calculate number of intervals // between gridpoints in // each dimension; round upwards using ceil local num_intervals = ceil ((c2 - c1) / spacing); // number of gridpoints = number of intervals + 1 // num_gridpoints = [num_x, num_y] local num_gridpoints = inc num_intervals; // size = [size_x, size_y] // enforce a minimum of 2 gridpoints // in each dimension local size = maxE [2, num_gridpoints]; local shape = c1 + dec app igen size * spacing; return shape; endfunction function zero_out_boundary_values [size, data] // Get multiple indices for every // gridpoint in the grid. // (igen ndata generates single indices // for every grid value) local ndata = length data; local midx = grid_s2m [size, igen ndata]; // length midx === length size // Each element of midx is of // length ndata. // Generate data vector mask. local bmask = orE (midx == 1 or midx == size); // Wherever bmask has a 1, replace // corresponding element in data by a 0. data | bmask = 0; return data; endfunction function aLogP atom // returns the atomic contribution to the XlogP local i; local logP = 0; for i=1, length XLOGP(1), 1 loop if sm_Match [ XLOGP(2)(i), atom ] == 1 then ; logP = XLOGP(1)(i); endif; endloop return logP; endfunction; function xlogp atoms local i, XlogP, xlogp; for i=1, length(atoms), 1 loop xlogp(i) = [ aLogP atoms(i)]; // apply the function aLogP on selected atom endloop local xlogp_tab = [ xlogp, atoms ]; return xlogp_tab; // return the table of hydrophobic atoms and their atomic contribution to XlogP endfunction function la atoms local la = xlogp atoms; return add la(1); endfunction function tpsa atoms local tpsa; atoms = atoms | not indexof [aAtomicNumber atoms,[0,1,6,14]]; // first postition of atoms with AtomicNumber 0, 1, 6 and 14 // returns all hydrophilic atoms (1=0, 1=2, 6=C=3) each element counts local idx = sm_Indexof [ atoms, TPSA(1) ]; // match with SMILES patterns tpsa = [ TPSA(2)[ sm_Indexof [atoms, TPSA(1)] ], atoms]; // contributions of atoms to TPSA (pack removed zero values) // print tpsa(1); return tpsa; // tpsa return a 2D vector with the tpsaa contributions and the atom keys endfunction // calculate and return hydrophilic center function hydrophilic_center atoms local hydrophilic = ['N', 'O']; // define all hydrophilic atom names in a vector local hydrophilic_positions = []; local hydrophilic_center = [0, 0, 0]; local i, tpsa_weight = 0; local hydrophilic_atoms = atoms | indexof [aElement atoms,['N', 'O']]; local tpsa = tpsa(hydrophilic_atoms); // calculate the topogical polar surface area // aSetCharge [hydrophilic_atoms, tpsa(1)]; // assign tpsa contribution to the charge label // print ['TPSA: ', tpsa(1)]; tpsa_sum = add tpsa(1); // sum of all tpsa conributions hydrophilic_atom_count = add one hydrophilic_atoms; // number of hydrophilic atoms for i=1, length(hydrophilic_atoms), 1 loop // add position of the next hydrophilic atom to hydrophilic positions // print aName molecule[i]; // print the element type for each and every atom in the molecule // print tpsa(1) | indexof [tpsa(2), molecule(i)]; // get tpsa where index is molecule(i) = weighting factor for hydrophilic atoms // assign weight of 100 to a fully charged atom, else assign the tpsa contribution tpsa_weight = 100 * ( abs (aCharge hydrophilic_atoms[i]) ) + tpsa(1) * (1 - abs (aCharge hydrophilic_atoms[i]) ); // tpsa_weight = tpsa(1); // without weighting according to charge print ['Weight for:', aName hydrophilic_atoms[i], tpsa_weight[i] ]; // x-coordinates hydrophilic_positions(1) = append [ hydrophilic_positions(1), (aPos hydrophilic_atoms[i])(1) * tpsa_weight[i] / (add tpsa_weight) ]; // y-coordinates hydrophilic_positions(2) = append [ hydrophilic_positions(2), (aPos hydrophilic_atoms[i])(2) * tpsa_weight[i] / (add tpsa_weight)]; // z-coordinates hydrophilic_positions(3) = append [ hydrophilic_positions(3), (aPos hydrophilic_atoms[i])(3) * tpsa_weight[i] / (add tpsa_weight) ]; endloop; hydrophilic_center(1) = add hydrophilic_positions(1); hydrophilic_center(2) = add hydrophilic_positions(2); hydrophilic_center(3) = add hydrophilic_positions(3); return hydrophilic_center; // works MM endfunction // calculate and return hydrophobic center out of atoms function hydrophobic_center atoms local hydrophobic = ['C', 'F', 'Cl', 'I']; // define all hydrophobic atom names in a vector local hydrophobic_positions = []; local hydrophobic_center = [0, 0, 0]; local i; local hydrophobic_atoms = atoms | indexof [aElement atoms, ['C', 'F', 'Cl', 'I']]; local xlogp = xlogp(hydrophobic_atoms); // print [ 'XLogP:', xlogp(1) ]; // print the contributions to the XlogP xlogp_sum = add xlogp(1); // sum of all tpsa conributions hydrophobic_atom_count = add one hydrophobic_atoms; // number of hydrophilic atoms // label Atomcharge with the xlogp contribution // aSetCharge [hydrophobic_atoms, xlogp(1)]; for i=1, length(hydrophobic_atoms), 1 loop // x-coordinates hydrophobic_positions(1) = append [ hydrophobic_positions(1), (aPos hydrophobic_atoms[i])(1) * exp xlogp(1)[i] / (add exp xlogp(1)) ]; // y-coordinates hydrophobic_positions(2) = append [ hydrophobic_positions(2), (aPos hydrophobic_atoms[i])(2) * exp xlogp(1)[i] / (add exp xlogp(1)) ]; // z-coordinates hydrophobic_positions(3) = append [ hydrophobic_positions(3), (aPos hydrophobic_atoms[i])(3) * exp xlogp(1)[i] / (add exp xlogp(1)) ]; aSetLabelName [hydrophobic_atoms(i), xlogp(1)]; // assign contribution to XlogP to the charge label endloop; hydrophobic_center(1) = add hydrophobic_positions(1); hydrophobic_center(2) = add hydrophobic_positions(2); hydrophobic_center(3) = add hydrophobic_positions(3); return hydrophobic_center; // works MM checked MM endfunction function amphiphilic_axis centers local vector; local length; local center, center_sphere; vector = centers(2) - centers(1); // print vector; // works MM check length = sqrt( sqr vector(1)+sqr vector(2)+sqr vector(3) ); // print length; // works MM check // vector = vector / length; // normalize vector to length 1 center = centers(2) + 0.5 * vector; // print center; // works MM check return [ center, vector, length ]; // returned vector consisting of [center, vector, length] of the amphiphilic axis endfunction function mass_center molecule local i; local center, mass_center; for i=1, length(molecule), 1 loop center(1) = append [ center(1), (aPos molecule[i])(1) * aMass molecule[i] / (add aMass molecule) ]; center(2) = append [ center(2), (aPos molecule[i])(2) * aMass molecule[i] / (add aMass molecule) ]; center(3) = append [ center(3), (aPos molecule[i])(3) * aMass molecule[i] / (add aMass molecule) ]; endloop mass_center(1) = (add center(1)); mass_center(2) = (add center(2)); mass_center(3) = (add center(3)); return mass_center; endfunction // draw coordinate axis function draw_coordinate_axes [color, length] local g_x_axis = GCreate 'x-axis'; local g_y_axis = GCreate 'y-axis'; local g_z_axis = GCreate 'z-axis'; GLine [ g_x_axis, color, -length,0,0, length,0,0 ]; GLine [ g_y_axis, color, 0,-length,0, 0,length,0 ]; GLine [ g_z_axis, color, 0,0,-length, 0,0,length ]; endfunction // create a new copy of the supplied molecule function restore_molecule molecule oDestroy Atoms[]; mol_Create molecule; endfunction // draw the amphiphilic axis with the hydrophilic and hydrophobic centers function draw_aa [hydrophobic_center, hydrophilic_center] local g_hydrophilic_center = GCreate 'hydrophilic_center'; local g_hydrophobic_center = GCreate 'hydrophobic_center'; local g_amphiphilic_axis = GCreate 'amphiphilic_axis'; local center_sphere = G_Sphere[ 0xFF0000, hydrophobic_center, 0.3, 1 ]; GVertex cat [ g_hydrophobic_center, center_sphere ]; center_sphere = G_Sphere[ 0xFFFF00, hydrophilic_center, 0.3, 1 ]; GVertex cat [ g_hydrophilic_center, center_sphere ]; local line = G_Cylinder [ 0x33FF33, hydrophilic_center + (hydrophilic_center - hydrophobic_center), (hydrophobic_center-hydrophilic_center)*3, 0.05, 7 ]; // hydrophilic_center[]-2*aa(2) is center of amphphilic axis GVertex cat [g_amphiphilic_axis, line ]; endfunction; function vector_rotation [vector, transformation_matrix ] local transformed_vector = [0, 0, 0]; transformed_vector(1)=vector(1)*transformation_matrix(1)(1) + vector(2)*transformation_matrix(1)(2) + vector(3)*transformation_matrix(1)(3); transformed_vector(2)=vector(1)*transformation_matrix(2)(1) + vector(2)*transformation_matrix(2)(2) + vector(3)*transformation_matrix(2)(3); transformed_vector(3)=vector(1)*transformation_matrix(3)(1) + vector(2)*transformation_matrix(3)(2) + vector(3)*transformation_matrix(3)(3); return transformed_vector; endfunction // calculates the dimensions of a molecule, returns the lower left and the upper right corner of the surrounding box function extent atoms local lower_left, upper_right; lower_left = [ min (-(aRadius atoms) + (aPos atoms)(1)-3), min (-(aRadius atoms) + (aPos atoms)(2)-3), min (-(aRadius atoms) + (aPos atoms)(3)-3) ]; // print ['3. Coordinate: ' , (aPos atoms)(3)]; upper_right = [ max ((aRadius atoms) + (aPos atoms)(1)+3), max ((aRadius atoms) + (aPos atoms)(2)+3), max ((aRadius atoms) + (aPos atoms)(3)+3) ]; return [ lower_left, upper_right ]; endfunction function generate_grid size // calculate the maximum extent of an atom local grid_size = extent Atoms[]; print ['Grid size (for CSA) is set to: ', grid_size]; // local shape = generate_shape [ grid_size(1), grid_size(2) , 0.1]; local shape = generate_shape [ [grid_size(1)(1), 0, grid_size(1)(3) ], [grid_size(2)(1), 0, grid_size(2)(3) ] , 0.1]; // local grid_area = (grid_size(2)(1)-grid_size(1)(1)) * (grid_size(2)(2)-grid_size(1)(2) * (grid_size(2)(3)-grid_size(1)(3))); local grid_area = ( grid_size(2)(1) - grid_size(1)(1) ) * ( grid_size(2)(3) - grid_size(1)(3) ); local atoms = Atoms[]; local ndata = length shape(1) * length shape(2) * length shape(3); local coord = grid_coord [shape, igen ndata ]; // returns a grid with [ [x1, x2, ...], [y1, y2, y3, ...] ] // igen ndata sets the number of gridpoints, length of x and y local data = coord; // probe=1.4, ridge=2.5 accessible // probe=0.0, ridge=1.2 connolly // level=1 isosurface is the boundary local probe = 0.0; local ridge = 1.2; local p = aPos atoms; // atom positions local r = probe + aRadius atoms; // distance to atoms = probe + VDW radii local w = cube (sqrt(2*PI)*r/ridge) * exp (0.5 * sqr ridge); data = grid_addgauss [0, shape, 1, r/ridge, p, 4*r]; // draw a small sphere at each gridpoint function draw_grid data local g_grid = GCreate 'g_grid'; local i, gridpoints_in=0, gridpoints_out=0; local gridpoints = length data; for i=1, gridpoints, 1 loop if data[i] > 0.080 then // GPoint [g_grid, green, coord(1)(i), coord(2)(i), coord(3)(i) ]; // GPoint [g_grid, green, coord(1)(i), coord(2)(i), 0 ]; gridpoints_in = gridpoints_in + 1; elseif round(data[i]*100) === 8 then // GPoint [g_grid, yellow, coord(1)(i), coord(2)(i), coord(3)(i) ]; // GPoint [g_grid, yellow, coord(1)(i), 0, coord(3)(i) ]; else // GPoint [g_grid, red, coord(1)(i), coord(2)(i), coord(3)(i) ]; // GPoint [g_grid, red, coord(1)(i), coord(2)(i), 0 ]; gridpoints_out = gridpoints_out + 1; endif endloop cross_sectional_area = gridpoints_in / gridpoints * grid_area; return [ gridpoints, gridpoints_in ]; endfunction draw_grid data; endfunction function QuaSAR_calc_Seelig [db_mol, codes, parms] local desc = zero codes; // codes indiziert den Vektor desc mit den einzelnen Deskriptoren // load the database molecule into MOE as objects local [chains, molecule_name] = db_CreateMolecule db_mol; local atoms = cat cAtoms chains; // calculate the individual descriptors and assign // them to the corresponding positions in the return vector aSetPos [Atoms[], (aPos Atoms[] - mass_center( Atoms[] )) ]; // recenter molecule on mass center ViewSetup[ background_color:black ]; // set background color for display to black View Atoms []; // adjust view so that all atoms are visible in the window // aSetLabelCharge[Atoms[]| not indexof [aElement Atoms[],'H'], 0]; // display the aCharge for all atoms, but hydrogens // destroy all graphic elements GDestroy 'hydrophilic_center'; GDestroy 'hydrophobic_center'; GDestroy 'amphiphilic_axis'; GDestroy 'amphiphilicity_axis'; GDestroy 'projected'; GDestroy 'grid'; GDestroy 'g_grid'; // draw_coordinate_axes [white, 5]; local g_center = GCreate 'center'; // draw a small grey sphere at the mass center local g_mass_center = GCreate 'mass_center'; local masscenter = G_Sphere[ grey, mass_center( Atoms[] ), 0.2, 1 ]; GVertex cat [ g_mass_center, masscenter ]; local aa = amphiphilic_axis( [ hydrophobic_center Atoms[], hydrophilic_center Atoms[] ] ); // calculate the amphiphilic axis // length_along_aa aa; // calculate the length along the amphiphilic axis /////////////////////////////////////////////////////////////////////// // // // rotate the molecule around z and x onto y // // // /////////////////////////////////////////////////////////////////////// local normal_vector = aa(2); // create a vector in plane normal to aa normal_vector = aa(2) / sqrt add sqr aa(2); // normalize vector to length 1 print ['Normalvektor vor der 1. Transformation: ', normal_vector ]; local xy_vector = [ normal_vector(1), normal_vector(2), 0 ]; // make a vector in xy plane (z=0) xy_vector = xy_vector / v_length( xy_vector ) ; // normalize xy_normal_vector to length 1 local basis_transfer_matrix_z = [ [ xy_vector(2), -xy_vector(1), 0], [ xy_vector(1), xy_vector(2), 0], [0, 0, 1] ]; // y = cos, x = sin des Normalvektors aSetPos [ Atoms[], (vector_rotation [aPos Atoms[], basis_transfer_matrix_z ] ) ]; // move all atom positions to xy-plane normal_vector = vector_rotation [normal_vector, basis_transfer_matrix_z ]; // rotate the normal vector aa(2) = vector_rotation [aa(2), basis_transfer_matrix_z ]; // rotate the direction of aa print ['Normalvektor nach der 1. Transformation: ', normal_vector ]; // local yz_vector = [0, normal_vector(2), normal_vector(3) ]; // make a vector in yz plane (x=0) // yz_vector = yz_vector / v_length( yz_vector ); local basis_transfer_matrix_y = [ [1, 0, 0], [0, normal_vector(2), normal_vector(3)], [0, -normal_vector(3), normal_vector(2)] ]; // y = cos, z = sin aSetPos [ Atoms[], (vector_rotation [aPos Atoms[], basis_transfer_matrix_y ] ) ]; // move all atom positions to xy-plane normal_vector = vector_rotation [normal_vector, basis_transfer_matrix_y ]; aa(2) = vector_rotation [aa(2), basis_transfer_matrix_y ]; print ['Normalvektor nach der 2. Transformation: ', normal_vector ]; // should be [0, 0, 1] // draw_aa [hydrophobic_center Atoms[], hydrophilic_center Atoms[] ]; // is drawn when recentered on hydrophilic center ViewOrientation [[1,0,0],[0,0,1]]; // Set View Orientation, Z = aus der Bildebene // save molecule before changing the positions local mol_original = mol_Extract Atoms[]; // store the molecule in mol_original /////////////////////////////////////////////////////////////////////// // // // project atoms to plane normal to aphiphilic axis // // // /////////////////////////////////////////////////////////////////////// // normal vector is normalized vector along the amphiphilic axis // normal_vector = normal_vector / v_length // normalize the normal_vector // projection vecor = [1,1,1] - normal vector ONLY if normal_vector is normalized to unit length local projection_vector = [ 1, 1, 1 ] - normal_vector; // print [ 'Projectionsvektor', projection_vector ]; // build normal_vector in the form of aPos Atoms[] local normal_projection = [ rep [projection_vector(1), nAtoms[]], rep [projection_vector(2), nAtoms[]], rep [projection_vector(3), nAtoms[]] ]; aSetPos [ Atoms[], (aPos Atoms[]) * normal_projection ]; // project atoms to the xz plane (where y=0) generate_grid [10, 10, 0]; // attributes are arbitrary, because the extent of the grid is calculated oDestroy Atoms[]; // destrory projected Atoms mol_original = mol_Create mol_original; // create a new copy of the original molecule aSetPos [Atoms[], (aPos Atoms[] - hydrophilic_center Atoms[] ) ]; // recenter molecule to center of mass function extract_out_of_membrane_atoms atoms local extracted_atoms, i; for i=1, length atoms, 1 loop if (aPos atoms[i])(2) > 0 then extracted_atoms = append [ extracted_atoms, atoms[i] ]; endif endloop return extracted_atoms; endfunction local out_of_membrane_atoms = extract_out_of_membrane_atoms Atoms[]; // selects those atoms with a positive y-component // length is the maximal y-coordinate minus the minimal coordinate laa = max (aPos Atoms[])(2) - min (aPos Atoms[])(2); /////////////////////////////////////////////////////////////////////// // // // generate grid out of the membrane // // // /////////////////////////////////////////////////////////////////////// // calculate the maximum extent of an atom print ['Out of membrane Atoms: ', out_of_membrane_atoms]; local grid_size = extent out_of_membrane_atoms; print ['3D Grid size is set to: ', grid_size]; local shape = generate_shape [ [grid_size(1)(1), 0, grid_size(1)(3)], [grid_size(2)(1), grid_size(2)(2), grid_size(2)(3)], 0.15]; local grid_volume = (grid_size(2)(1)-grid_size(1)(1)) * (grid_size(2)(2)-grid_size(1)(2)) * (grid_size(2)(3)-grid_size(1)(3)); // local atoms = Atoms[]; local ndata = length shape(1) * length shape(2) * length shape(3); local coord = grid_coord [shape, igen ndata ]; // returns a grid with [ [x1, x2, ...], [y1, y2, y3, ...] ] // igen ndata sets the number of gridpoints, length of x and y local data = coord; // probe=1.4, ridge=2.5 accessible // probe=0.0, ridge=1.2 connolly // level=1 isosurface is the boundary local probe = 0.0; local ridge = 1.4; local p = aPos out_of_membrane_atoms; // atom positions local r = probe + aRadius out_of_membrane_atoms; // distance to atoms = probe + VDW radii local w = cube (sqrt(2*PI)*r/ridge) * exp (0.5 * sqr ridge); data = grid_addgauss [0, shape, 1, r/ridge, p, 4*r]; // draw a small sphere at each gridpoint function draw_grid data local g_grid = GCreate 'g_grid'; local i, gridpoints_in = 0, gridpoints_out = 0; local gridpoints = length data; for i=1, gridpoints, 1 loop // local projected = G_Sphere[ green, [position_projected(1)(i), position_projected(2)(i), position_projected(3)(i)] , 0.1, 1 ]; // GVertex cat [ g_projected, projected ]; // GPoint [g_grid, yellow, coord(1)(i), coord(2)(i), coord(3)(i) ]; if data[i] > 0.085 then GPoint [g_grid, yellow, coord(1)(i), coord(2)(i), coord(3)(i) ]; gridpoints_in = gridpoints_in + 1; else // GPoint [g_grid, grey, coord(1)(i), coord(2)(i), coord(3)(i) ]; gridpoints_out = gridpoints_out + 1; endif endloop print ['3D Gridpoints in: ', gridpoints_in]; print ['3D Gridpoints out: ', gridpoints_out]; return [ gridpoints, gridpoints_in ]; endfunction local la_atoms = Atoms[] | not indexof [aElement Atoms[],['N', 'O']]; local lipoaffinity = la la_atoms; local gridpoints = draw_grid data; volume_out_of_membrane = grid_volume * gridpoints(2) / gridpoints(1); print ['Cross-sectional-area: ', cross_sectional_area ]; print ['Amphiphilic axis: ', aa(3) ]; (desc | codes == 'AA' ) = aa(3); (desc | codes == 'CSA') = cross_sectional_area; (desc | codes == 'LAA') = laa; (desc | codes == 'NOOM') = length out_of_membrane_atoms; (desc | codes == 'VOOM') = volume_out_of_membrane; (desc | codes == 'LA') = lipoaffinity; oDestroy Atoms[]; // destrory projected Atoms return desc; endfunction