1 /* Copyright (C) 2000-2002 Damir Zucic */
2 
3 /*=============================================================================
4 
5 				sequence_from.c
6 
7 Purpose:
8 	Copy the sequence  from the specified macromolecular complex to
9 	the sequence buffer. Only the sequence for selected range(s) is
10 	copied.  A residue is treated as selected  if the first atom of
11 	this residue is selected.  For proteins,  this is typically  N.
12 	The original  residue  sequence  indices are copyed.  Insertion
13 	codes are, however, ignored,  so it is possible  that some res.
14 	serial indices appear more than once in the buffer.
15 
16 Input:
17 	(1) Pointer to MolComplexS structure, with macromol. complexes.
18 	(2) The number of macromolecular complexes.
19 	(3) Pointer to RuntimeS structure.
20 	(4) Pointer to the string which contains  the macromol. complex
21 	    identifier.
22 
23 Output:
24 	(1) Sequence from the specified complex  copied to the sequence
25 	    buffer.
26 	(2) Return value.
27 
28 Return value:
29 	(1) Positive (command) code on success.
30 	(2) Negative (error) code on failure.
31 
32 ========includes:============================================================*/
33 
34 #include <stdio.h>
35 
36 #include <string.h>
37 
38 #include <X11/Xlib.h>
39 #include <X11/Xutil.h>
40 #include <X11/Xos.h>
41 #include <X11/Xatom.h>
42 
43 #include "defines.h"
44 #include "commands.h"
45 #include "typedefs.h"
46 
47 /*======function prototypes:=================================================*/
48 
49 char		*ExtractToken_ (char *, int, char *, char *);
50 void		InitHyphob_ (RuntimeS *);
51 
52 /*======copy sequence from complex to sequence buffer:=======================*/
53 
SequenceFrom_(MolComplexS * mol_complexSP,int mol_complexesN,RuntimeS * runtimeSP,char * stringP)54 int SequenceFrom_ (MolComplexS *mol_complexSP, int mol_complexesN,
55 		   RuntimeS *runtimeSP, char *stringP)
56 {
57 int			max_length;
58 char			*remainderP;
59 char			tokenA[SHORTSTRINGSIZE];
60 int			complexID;
61 int			mol_complexI;
62 static MolComplexS	*curr_mol_complexSP;
63 int			job_doneF = 0;
64 size_t			residue1I, residues1N;
65 ResidueS		*curr_residueSP;
66 AtomS			*first_atomSP;
67 AtomS			*last_atomSP;
68 AtomS			*curr_atomSP;
69 size_t			offset;
70 char			*sourceP, *destP;
71 size_t			residue2I = 0;
72 int			bondsN, bondI;
73 TrueBondS		*curr_bondSP;
74 int			disulfideF;
75 int			*curr_disulfideFP;
76 
77 /* The maximal residue name length: */
78 max_length = RESNAMESIZE - 1;
79 
80 /* At least one macromolecular complex should be available: */
81 if (mol_complexesN == 0)
82 	{
83 	strcpy (runtimeSP->messageA, "No structure loaded!");
84 	runtimeSP->message_length = strlen (runtimeSP->messageA);
85 	return -1;
86 	}
87 
88 /* Take the first token; it should be present: */
89 remainderP = ExtractToken_ (tokenA, SHORTSTRINGSIZE, stringP, " \t\n");
90 if (!remainderP)
91 	{
92 	strcpy (runtimeSP->messageA, "Complex identifier missing!");
93 	runtimeSP->message_length = strlen (runtimeSP->messageA);
94 	return -2;
95 	}
96 
97 /* Extract the macromolecular complex identifier: */
98 if (sscanf (tokenA, "%d", &complexID) != 1)
99 	{
100 	strcpy (runtimeSP->messageA, "Bad macromolecular complex identifier!");
101 	runtimeSP->message_length = strlen (runtimeSP->messageA);
102 	return -3;
103 	}
104 
105 /* Check is the requested complex available at all: */
106 for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
107 	{
108 	/** Prepare the pointer to the current macromolecular complex: **/
109 	curr_mol_complexSP = mol_complexSP + mol_complexI;
110 
111 	/* Check the number of atoms;  for bad */
112 	/* and discarded complexes it is zero: */
113 	if (curr_mol_complexSP->atomsN == 0) continue;
114 
115 	/* If macromol. complex is recognized, set the catch flag to one: */
116 	if (curr_mol_complexSP->mol_complexID == complexID)
117 		{
118 		job_doneF = 1;
119 		break;
120 		}
121 	}
122 
123 /* If the requested complex is not available, return negative value: */
124 if (job_doneF == 0)
125 	{
126 	strcpy (runtimeSP->messageA,
127 		"The requested complex is not available!");
128 	runtimeSP->message_length = strlen (runtimeSP->messageA);
129 	return -4;
130 	}
131 
132 /* Copy the sequence: */
133 residues1N = curr_mol_complexSP->residuesN;
134 for (residue1I = 0; residue1I < residues1N; residue1I++)
135 	{
136 	/* Pointer to the current residue: */
137 	curr_residueSP = curr_mol_complexSP->residueSP + residue1I;
138 
139 	/* Pointer to the first atom: */
140 	first_atomSP = curr_mol_complexSP->atomSP +
141 		       curr_residueSP->residue_startI;
142 
143 	/* Pointer to the last atom: */
144 	last_atomSP = curr_mol_complexSP->atomSP +
145 		      curr_residueSP->residue_endI;
146 
147 	/* If this atom is not selected, do not copy the residue name: */
148 	if (first_atomSP->selectedF == 0) continue;
149 
150 	/* Pointer to the residue name associated with this atom: */
151 	sourceP = first_atomSP->raw_atomS.pure_residue_nameA;
152 
153 	/* Prepare and check the position in seq. */
154 	/* buffer where this name will be copied: */
155 	offset = max_length * residue2I;
156 	if (offset > runtimeSP->sequence_buffer_size - 10 * max_length)
157 		{
158 		strcpy (runtimeSP->messageA, "Sequence too long!");
159 		runtimeSP->message_length = strlen (runtimeSP->messageA);
160 		return -5;
161 		}
162 
163 	/* Copy the residue name: */
164 	destP = runtimeSP->sequenceP + offset;
165 	strncpy (destP, sourceP, max_length);
166 
167 	/* Copy the residue serial index: */
168 	*(runtimeSP->serialIP + residue2I) =
169 				first_atomSP->raw_atomS.residue_sequenceI;
170 
171 	/* Now it is time to set disulfide flag for the current residue. */
172 
173 	/* Pointer to disulfide flag for the current residue: */
174 	curr_disulfideFP = runtimeSP->disulfideFP + residue2I;
175 
176 	/* Reset disulfide flag: */
177 	*curr_disulfideFP = 0;
178 
179 	/* Reset the flag: */
180 	disulfideF = 0;
181 
182 	/* Check is this residue involved in disulfide bond: */
183 	for (curr_atomSP = first_atomSP;
184 	     curr_atomSP <= last_atomSP;
185 	     curr_atomSP++)
186 		{
187 		/* The number of bonds: */
188 		bondsN = curr_atomSP->bondsN;
189 
190 		/* Check is disulfide bond present: */
191 		for (bondI = 0; bondI < bondsN; bondI++)
192 			{
193 			/* Pointer to the current bond: */
194 			curr_bondSP = curr_atomSP->true_bondSA + bondI;
195 
196 			/* If this bond is disulfide */
197 			/* bond, set flag and break: */
198 			if (curr_bondSP->bond_typeI == 2)
199 				{
200 				disulfideF = 1;
201 				break;
202 				}
203 			}
204 
205 		/* If at least one disulfide bond is found, break from loop: */
206 		if (disulfideF != 0) break;
207 		}
208 
209 	/* Update disulfide flag: */
210 	if (disulfideF) *curr_disulfideFP = 1;
211 
212 	/* Update the output residue index: */
213 	residue2I++;
214 	}
215 
216 /* Set the number of residues: */
217 runtimeSP->residuesN = residue2I;
218 
219 /* Initialize hydrophobicity values: */
220 InitHyphob_ (runtimeSP);
221 
222 /* Return positive value on success: */
223 return 1;
224 }
225 
226 /*===========================================================================*/
227 
228 
229