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