/src/inchi/INCHI-1-SRC/INCHI_BASE/src/runichi.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * International Chemical Identifier (InChI) |
3 | | * Version 1 |
4 | | * Software version 1.07 |
5 | | * 20/11/2023 |
6 | | * |
7 | | * The InChI library and programs are free software developed under the |
8 | | * auspices of the International Union of Pure and Applied Chemistry (IUPAC). |
9 | | * Originally developed at NIST. |
10 | | * Modifications and additions by IUPAC and the InChI Trust. |
11 | | * Some portions of code were developed/changed by external contributors |
12 | | * (either contractor or volunteer) which are listed in the file |
13 | | * 'External-contributors' included in this distribution. |
14 | | * |
15 | | * IUPAC/InChI-Trust Licence No.1.0 for the |
16 | | * International Chemical Identifier (InChI) |
17 | | * Copyright (C) IUPAC and InChI Trust |
18 | | * |
19 | | * This library is free software; you can redistribute it and/or modify it |
20 | | * under the terms of the IUPAC/InChI Trust InChI Licence No.1.0, |
21 | | * or any later version. |
22 | | * |
23 | | * Please note that this library is distributed WITHOUT ANY WARRANTIES |
24 | | * whatsoever, whether expressed or implied. |
25 | | * See the IUPAC/InChI-Trust InChI Licence No.1.0 for more details. |
26 | | * |
27 | | * You should have received a copy of the IUPAC/InChI Trust InChI |
28 | | * Licence No. 1.0 with this library; if not, please e-mail: |
29 | | * |
30 | | * info@inchi-trust.org |
31 | | * |
32 | | */ |
33 | | |
34 | | |
35 | | /* |
36 | | General processing procedures |
37 | | |
38 | | */ |
39 | | |
40 | | #include <stdlib.h> |
41 | | #include <string.h> |
42 | | #include <stdarg.h> |
43 | | #include <errno.h> |
44 | | #include <limits.h> |
45 | | #include <math.h> |
46 | | #include <ctype.h> |
47 | | |
48 | | #include "mode.h" |
49 | | #include "ichitime.h" |
50 | | #ifndef COMPILE_ANSI_ONLY |
51 | | #include <conio.h> |
52 | | #endif |
53 | | |
54 | | #include "ichimain.h" |
55 | | #include "ichi_io.h" |
56 | | #include "mol_fmt.h" |
57 | | #include "inchi_api.h" |
58 | | #include "readinch.h" |
59 | | #include "ichicant.h" |
60 | | #ifdef TARGET_LIB_FOR_WINCHI |
61 | | #include "../../../IChI_lib/src/ichi_lib.h" |
62 | | #include "inchi_api.h" |
63 | | #endif |
64 | | #include "inchi_gui.h" |
65 | | #include "readinch.h" |
66 | | #include "ichirvrs.h" |
67 | | |
68 | | #include "bcf_s.h" |
69 | | |
70 | | extern int DisplayTheWholeStructure( struct tagCANON_GLOBALS *pCG, |
71 | | struct tagINCHI_CLOCK *ic, |
72 | | struct tagStructData *sd, |
73 | | INPUT_PARMS *ip, |
74 | | char *szTitle, |
75 | | INCHI_IOSTREAM *inp_file, |
76 | | INCHI_IOSTREAM *log_file, |
77 | | ORIG_ATOM_DATA *orig_inp_data, |
78 | | long num_inp, |
79 | | int iINChI, |
80 | | int bShowStruct, |
81 | | int bINCHI_LIB_Flag ); |
82 | | |
83 | | extern int DisplayStructure( struct tagCANON_GLOBALS *pCG, |
84 | | inp_ATOM *at, |
85 | | int num_at, |
86 | | OAD_Polymer *polymer, |
87 | | int num_removed_H, |
88 | | int bAdd_DT_to_num_H, |
89 | | int nNumRemovedProtons, |
90 | | NUM_H *nNumRemovedProtonsIsotopic, |
91 | | int bIsotopic, |
92 | | int j /*bTautomeric*/, |
93 | | INChI **cur_INChI, |
94 | | INChI_Aux **cur_INChI_Aux, |
95 | | int bAbcNumbers, |
96 | | DRAW_PARMS *dp, |
97 | | INCHI_MODE nMode, |
98 | | char *szTitle ); |
99 | | |
100 | | extern int ReadInChICoord( INCHI_IOSTREAM *pInp, |
101 | | SEGM_LINE *pLine, |
102 | | int *pState, |
103 | | INChI *pInpInChI[INCHI_NUM][TAUT_NUM], |
104 | | int nNumComponents[INCHI_NUM][TAUT_NUM] ); |
105 | | |
106 | | |
107 | | /* Local functions */ |
108 | | static int DoOneStructureEarlyPreprocessing( INCHI_CLOCK *ic, |
109 | | CANON_GLOBALS *pCG, |
110 | | long num_inp, |
111 | | STRUCT_DATA *sd, |
112 | | INPUT_PARMS *ip, |
113 | | INCHI_IOSTREAM *inp_file, |
114 | | INCHI_IOSTREAM *log_file, |
115 | | INCHI_IOSTREAM *out_file, |
116 | | INCHI_IOSTREAM *prb_file, |
117 | | ORIG_ATOM_DATA *orig_inp_data, |
118 | | ORIG_ATOM_DATA *prep_inp_data ); |
119 | | |
120 | | /* Actual worker sitting under ProcessOneStructureEx */ |
121 | | int ProcessOneStructureExCore( struct tagINCHI_CLOCK *ic, |
122 | | struct tagCANON_GLOBALS *CG, |
123 | | STRUCT_DATA *sd, |
124 | | INPUT_PARMS *ip, |
125 | | char *szTitle, |
126 | | PINChI2 *pINChI2[INCHI_NUM], |
127 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
128 | | INCHI_IOSTREAM *inp_file, |
129 | | INCHI_IOSTREAM *log_file, |
130 | | INCHI_IOSTREAM *out_file, |
131 | | INCHI_IOSTREAM *prb_file, |
132 | | ORIG_ATOM_DATA *orig_inp_data, |
133 | | ORIG_ATOM_DATA *prep_inp_data, |
134 | | long num_inp, |
135 | | INCHI_IOS_STRING *strbuf, |
136 | | unsigned char save_opt_bits ); |
137 | | |
138 | | |
139 | | |
140 | | static ORIG_STRUCT* |
141 | | OrigAtData_StoreNativeInput( CANON_GLOBALS *pCG, |
142 | | int *nRet, |
143 | | STRUCT_DATA *sd, |
144 | | INPUT_PARMS *ip, |
145 | | ORIG_ATOM_DATA *orig_inp_data, |
146 | | ORIG_STRUCT *pOrigStruct ); |
147 | | static void PrepareSaveOptBits( unsigned char *save_opt_bits, |
148 | | INPUT_PARMS *ip ); |
149 | | |
150 | | static void DisplayOrigAndResultStructuresAndComponents( int nRet, |
151 | | INCHI_CLOCK *ic, |
152 | | CANON_GLOBALS *pCG, |
153 | | STRUCT_DATA *sd, |
154 | | INPUT_PARMS *ip, |
155 | | char *szTitle, |
156 | | PINChI2 *pINChI[INCHI_NUM], |
157 | | PINChI_Aux2 *pINChI_Aux[INCHI_NUM], |
158 | | INCHI_IOSTREAM *inp_file, INCHI_IOSTREAM *log_file, |
159 | | INCHI_IOSTREAM *out_file, |
160 | | ORIG_ATOM_DATA *orig_inp_data, |
161 | | ORIG_ATOM_DATA *prep_inp_data, |
162 | | long num_inp, |
163 | | int maxINChI, |
164 | | COMP_ATOM_DATA composite_norm_data[INCHI_NUM][TAUT_NUM + 1] ); |
165 | | static void SaveOkProcessedMolfile( int nRet, |
166 | | STRUCT_DATA *sd, |
167 | | INPUT_PARMS *ip, |
168 | | INCHI_IOSTREAM *prb_file, |
169 | | INCHI_IOSTREAM *inp_file ); |
170 | | |
171 | | static int mark_atoms_to_delete_or_renumber( ORIG_ATOM_DATA *orig_at_data, |
172 | | OAD_StructureEdits *ed, |
173 | | int *at_renum); |
174 | | static int set_renumbered_or_delete( int *number, |
175 | | int *buf, |
176 | | int nelems, |
177 | | int *renum, |
178 | | int base ); |
179 | | |
180 | | static void swap_atoms_xyz( ORIG_ATOM_DATA *orig_at_data, int ia1, int ia2 ); |
181 | | |
182 | | /* Callbacks */ |
183 | | |
184 | | /* Console user issued CTRL+C etc. */ |
185 | | int( *ConsoleQuit )( void ) = NULL; |
186 | | int( *UserAction ) ( void ) = NULL; |
187 | | |
188 | | #if (BUILD_WITH_ENG_OPTIONS==1) |
189 | | #if ALLOW_SUBSTRUCTURE_FILTERING==1 |
190 | | static int OrigAtData_CheckForSubstructure(ORIG_ATOM_DATA *orig_inp_data); |
191 | | #endif |
192 | | #endif |
193 | | |
194 | | |
195 | | /********************************************** |
196 | | * output " L=V" or " L missing" or "" |
197 | | * The fprintf format string must contain %s%s%s%s |
198 | | */ |
199 | | const char gsMissing[] = "is missing"; |
200 | | const char gsEmpty[] = ""; |
201 | | const char gsSpace[] = " "; |
202 | | const char gsEqual[] = "="; |
203 | | |
204 | | |
205 | | |
206 | | /**************************************************************************** |
207 | | Process a portion of input data (molecule, InChI string, ...) |
208 | | in a relevant way (generate InChI, restore molecule by InChI ) |
209 | | ****************************************************************************/ |
210 | | int ProcessOneStructure( INCHI_CLOCK *ic, |
211 | | CANON_GLOBALS *pCG, |
212 | | STRUCT_DATA *sd, |
213 | | INPUT_PARMS *ip, |
214 | | char *szTitle, |
215 | | PINChI2 *pINChI[INCHI_NUM], |
216 | | PINChI_Aux2 *pINChI_Aux[INCHI_NUM], |
217 | | INCHI_IOSTREAM *inp_file, |
218 | | INCHI_IOSTREAM *log_file, |
219 | | INCHI_IOSTREAM *out_file, |
220 | | INCHI_IOSTREAM *prb_file, |
221 | | ORIG_ATOM_DATA *orig_inp_data, |
222 | | ORIG_ATOM_DATA *prep_inp_data, |
223 | | long num_inp, |
224 | | INCHI_IOS_STRING *strbuf, |
225 | | unsigned char save_opt_bits ) |
226 | 41.6k | { |
227 | 41.6k | int nRet = 0, |
228 | 41.6k | nRet1, i, k, |
229 | 41.6k | maxINChI = 0, |
230 | 41.6k | bSortPrintINChIFlags = 0; |
231 | 41.6k | COMP_ATOM_DATA |
232 | 41.6k | composite_norm_data[INCHI_NUM][TAUT_NUM + 1]; /* [0]:non-taut, |
233 | | [1]:taut, |
234 | | [2]:intermediate taut struct */ |
235 | 41.6k | NORM_CANON_FLAGS ncFlags; |
236 | 41.6k | NORM_CANON_FLAGS *pncFlags = &ncFlags; |
237 | 41.6k | ORIG_STRUCT OrigStruct; |
238 | 41.6k | ORIG_STRUCT *pOrigStruct = NULL; |
239 | 41.6k | int err, ret1 = 0; |
240 | | |
241 | | /* djb-rwth: removing redundant code */ |
242 | | |
243 | | /* 1. Preliminary work */ |
244 | | |
245 | 41.6k | int is_polymer = orig_inp_data |
246 | 41.6k | && orig_inp_data->valid_polymer |
247 | 41.6k | && orig_inp_data->polymer |
248 | 41.6k | && orig_inp_data->polymer->n ; |
249 | | |
250 | 41.6k | int is_polymer2inchi = is_polymer && ( ip->nInputType == INPUT_MOLFILE || ip->nInputType == INPUT_SDFILE ); |
251 | | |
252 | 41.6k | sd->bUserQuitComponent = 0; |
253 | 41.6k | sd->bUserQuitComponentDisplay = 0; |
254 | 41.6k | memset( composite_norm_data, 0, sizeof( composite_norm_data ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
255 | 41.6k | memset( pncFlags, 0, sizeof( *pncFlags ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
256 | | |
257 | | |
258 | | /* For experimental purposes only */ |
259 | | /*ret1 = DoOneStructureEarlyPreprocessing( num_inp, sd, ip, inp_file, |
260 | | log_file, out_file, prb_file, |
261 | | orig_inp_data, prep_inp_data ); |
262 | | */ |
263 | 41.6k | ret1 = DoOneStructureEarlyPreprocessing( ic, pCG, num_inp, sd, ip, |
264 | 41.6k | inp_file, log_file, out_file, prb_file, |
265 | 41.6k | orig_inp_data, prep_inp_data ); |
266 | 41.6k | switch (ret1) |
267 | 41.6k | { |
268 | 0 | case _IS_SKIP: |
269 | 0 | case _IS_ERROR: |
270 | 0 | case _IS_FATAL: |
271 | 0 | nRet = ret1; |
272 | 41.6k | } |
273 | | |
274 | 41.6k | if (ret1) |
275 | 0 | { |
276 | 0 | goto exit_function; |
277 | 0 | } |
278 | | |
279 | | |
280 | 41.6k | if (is_polymer) |
281 | 0 | { |
282 | | /* Polymer house-keeping related to possible CRU frame shift(s) */ |
283 | |
|
284 | 0 | orig_inp_data->polymer->frame_shift_scheme = ip->bFrameShiftScheme; |
285 | 0 | orig_inp_data->polymer->treat = ip->bPolymers; |
286 | |
|
287 | 0 | if (!is_polymer2inchi) |
288 | 0 | { |
289 | | /* Polymer structure is being restored from InChI string */ |
290 | | /* If CRUs were pre-cyclized, re-open them in preferred forms here */ |
291 | 0 | if (orig_inp_data->polymer->frame_shift_scheme == FSS_STARS_CYCLED) |
292 | 0 | { |
293 | 0 | OAD_Polymer_SmartReopenCyclizedUnits( orig_inp_data->polymer, |
294 | 0 | orig_inp_data->at, |
295 | 0 | orig_inp_data->num_inp_atoms, |
296 | 0 | &orig_inp_data->num_inp_bonds ); |
297 | 0 | } |
298 | 0 | } |
299 | 0 | } |
300 | | |
301 | | |
302 | 41.6k | ret1 = OrigAtData_SaveMolfile( orig_inp_data, sd, ip, num_inp, out_file ); |
303 | 41.6k | if (ret1) |
304 | 0 | { |
305 | 0 | goto exit_function; |
306 | 0 | } |
307 | | |
308 | | |
309 | 41.6k | pOrigStruct = &OrigStruct; |
310 | 41.6k | memset( pOrigStruct, 0, sizeof( *pOrigStruct ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
311 | | |
312 | 41.6k | OrigAtData_StoreNativeInput( pCG, &nRet, sd, ip, orig_inp_data, pOrigStruct ); |
313 | | |
314 | | /* 2. Create INChI for the whole disconnected or original structure */ |
315 | | |
316 | 41.6k | if (nRet != _IS_FATAL && nRet != _IS_ERROR) |
317 | 41.6k | { |
318 | 41.6k | nRet1 = CreateOneStructureINChI( pCG, ic, sd, ip, szTitle, |
319 | 41.6k | pINChI, pINChI_Aux, INCHI_BAS, |
320 | 41.6k | inp_file, log_file, out_file, prb_file, |
321 | 41.6k | orig_inp_data, prep_inp_data, |
322 | 41.6k | composite_norm_data, |
323 | 41.6k | num_inp, strbuf, pncFlags ); |
324 | 41.6k | nRet = inchi_max( nRet, nRet1 ); |
325 | | |
326 | | /* If we create InChI from polymer-containing structure */ |
327 | 41.6k | if (is_polymer2inchi) |
328 | 0 | { |
329 | 0 | int polymer_repr_type = OAD_Polymer_GetRepresentation( orig_inp_data->polymer ); |
330 | |
|
331 | 0 | #ifdef ALLOW_MIXED_SRU_AND_MON |
332 | 0 | if (polymer_repr_type == POLYMER_REPRESENTATION_STRUCTURE_BASED || |
333 | 0 | polymer_repr_type == POLYMER_REPRESENTATION_MIXED) |
334 | | #else |
335 | | if (polymer_repr_type == POLYMER_REPRESENTATION_STRUCTURE_BASED) |
336 | | #endif |
337 | 0 | { |
338 | | /* Temporarily copy ptr to polymer data to prep_inp_data */ |
339 | 0 | OAD_Polymer *prep_polymer = prep_inp_data->polymer; /* may be NULL */ |
340 | 0 | prep_inp_data->polymer = orig_inp_data->polymer; |
341 | |
|
342 | 0 | OAD_Polymer_FindBackbones( prep_inp_data, /* NB: not orig_inp_data! */ |
343 | 0 | &( composite_norm_data[INCHI_BAS][TAUT_YES] ), |
344 | 0 | &err, sd->pStrErrStruct ); |
345 | 0 | if (err) |
346 | 0 | { |
347 | 0 | ret1 = _IS_ERROR; |
348 | 0 | } |
349 | 0 | nRet = inchi_max( nRet, ret1 ); |
350 | 0 | prep_inp_data->polymer = prep_polymer; /* restore temp copied*/ |
351 | 0 | } |
352 | 0 | } |
353 | 41.6k | } |
354 | | |
355 | 41.6k | if (nRet != _IS_FATAL && nRet != _IS_ERROR) |
356 | 41.5k | { |
357 | 41.5k | maxINChI = 1; |
358 | 41.5k | } |
359 | | |
360 | | |
361 | | /* 3. Create INChI for the whole metal-reconnected structure */ |
362 | | |
363 | 41.6k | if (nRet != _IS_FATAL && |
364 | 41.6k | nRet != _IS_ERROR && |
365 | 41.6k | ( sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE ) && |
366 | 41.6k | ( ip->bTautFlags & TG_FLAG_RECONNECT_COORD )) |
367 | 233 | { |
368 | | |
369 | 233 | nRet1 = CreateOneStructureINChI( pCG, ic, sd, ip, szTitle, |
370 | 233 | pINChI, pINChI_Aux, INCHI_REC, inp_file, |
371 | 233 | log_file, out_file, prb_file, |
372 | 233 | orig_inp_data, prep_inp_data, |
373 | 233 | composite_norm_data, |
374 | 233 | num_inp, strbuf, pncFlags ); |
375 | 233 | nRet = inchi_max( nRet, nRet1 ); |
376 | | |
377 | 233 | if (is_polymer2inchi) |
378 | 0 | { |
379 | 0 | ret1 = 0; |
380 | | /* temporarily copy ptr to polymer data to prep_inp_data */ |
381 | 0 | prep_inp_data->polymer = orig_inp_data->polymer; |
382 | |
|
383 | 0 | OAD_Polymer_FindBackbones( prep_inp_data, /* NB: not orig_inp_data! */ |
384 | 0 | &( composite_norm_data[INCHI_REC][TAUT_YES] ), |
385 | 0 | &err, sd->pStrErrStruct ); |
386 | 0 | if (err) |
387 | 0 | { |
388 | 0 | ret1 = _IS_ERROR; |
389 | 0 | } |
390 | 0 | nRet = inchi_max( nRet, ret1 ); |
391 | 0 | prep_inp_data->polymer = NULL; /* remove temp copied */ |
392 | 0 | } |
393 | 233 | if (nRet != _IS_FATAL && nRet != _IS_ERROR) |
394 | 233 | { |
395 | 233 | maxINChI = 2; |
396 | 233 | } |
397 | 233 | } |
398 | | |
399 | 41.6k | if (nRet != _IS_FATAL && nRet != _IS_ERROR) |
400 | 41.5k | { |
401 | 41.5k | if (( sd->bChiralFlag & FLAG_INP_AT_CHIRAL ) && |
402 | 41.5k | ( ip->nMode & REQ_MODE_STEREO ) && |
403 | 41.5k | !( ip->nMode & ( REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ) ) && |
404 | 41.5k | !bIsStructChiral( pINChI, sd->num_components )) |
405 | 0 | { |
406 | 0 | if (!ip->bNoWarnings) |
407 | 0 | { |
408 | 0 | WarningMessage( sd->pStrErrStruct, "Not chiral" ); |
409 | 0 | } |
410 | 0 | } |
411 | 41.5k | if (!sd->bUserQuitComponent && !sd->bUserQuit) |
412 | 41.5k | { |
413 | 41.5k | nRet1 = TreatCreateINChIWarning( sd, ip, prep_inp_data, num_inp, |
414 | 41.5k | inp_file, log_file, out_file, prb_file ); |
415 | 41.5k | nRet = inchi_max( nRet, nRet1 ); |
416 | 41.5k | } |
417 | 41.5k | } |
418 | | |
419 | | |
420 | | /* 4. Sort and print INChI for the whole structure */ |
421 | | |
422 | 41.6k | PrepareSaveOptBits( &save_opt_bits, ip ); |
423 | 41.6k | if (nRet != _IS_FATAL && nRet != _IS_ERROR) |
424 | 41.5k | { |
425 | 41.5k | nRet1 = SortAndPrintINChI( pCG, out_file, strbuf, log_file, ip, |
426 | 41.5k | orig_inp_data, prep_inp_data, |
427 | 41.5k | composite_norm_data, |
428 | 41.5k | pOrigStruct, sd->num_components, |
429 | 41.5k | sd->num_non_taut, sd->num_taut, |
430 | 41.5k | sd->bTautFlags, sd->bTautFlagsDone, |
431 | 41.5k | pncFlags, num_inp, |
432 | 41.5k | pINChI, pINChI_Aux, |
433 | 41.5k | &bSortPrintINChIFlags, save_opt_bits ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ |
434 | 41.5k | } |
435 | | |
436 | | |
437 | | /* 5. Post-process */ |
438 | | |
439 | 41.6k | DisplayOrigAndResultStructuresAndComponents( nRet, ic, pCG, sd, ip, szTitle, |
440 | 41.6k | pINChI, pINChI_Aux, |
441 | 41.6k | inp_file, log_file, out_file, |
442 | 41.6k | orig_inp_data, prep_inp_data, |
443 | 41.6k | num_inp, maxINChI, |
444 | 41.6k | composite_norm_data ); |
445 | | |
446 | | |
447 | 41.6k | SaveOkProcessedMolfile( nRet, sd, ip, prb_file, inp_file ); |
448 | | |
449 | | |
450 | | /* Cleanup */ |
451 | | |
452 | 124k | for (i = 0; i < INCHI_NUM; i++) |
453 | 83.2k | { |
454 | 332k | for (k = 0; k < TAUT_NUM + 1; k++) |
455 | 249k | { |
456 | 249k | FreeCompAtomData( &composite_norm_data[i][k] ); |
457 | 249k | } |
458 | 83.2k | } |
459 | | |
460 | 41.6k | OrigStruct_Free( pOrigStruct ); |
461 | | |
462 | 41.6k | exit_function: |
463 | | |
464 | 41.6k | return nRet; |
465 | 41.6k | } |
466 | | |
467 | | |
468 | | |
469 | | /**************************************************************************** |
470 | | Early preprocessing: used if defined |
471 | | REMOVE_ION_PAIRS_ORIG_STRU or UNDERIVATIZE or RING2CHAIN |
472 | | ****************************************************************************/ |
473 | | |
474 | | |
475 | | int DoOneStructureEarlyPreprocessing( INCHI_CLOCK *ic, |
476 | | CANON_GLOBALS *pCG, |
477 | | long num_inp, |
478 | | STRUCT_DATA *sd, |
479 | | INPUT_PARMS *ip, |
480 | | INCHI_IOSTREAM *inp_file, |
481 | | INCHI_IOSTREAM *log_file, |
482 | | INCHI_IOSTREAM *out_file, |
483 | | INCHI_IOSTREAM *prb_file, |
484 | | ORIG_ATOM_DATA *orig_inp_data, |
485 | | ORIG_ATOM_DATA *prep_inp_data ) |
486 | 41.6k | { |
487 | | |
488 | 41.6k | #if ( RING2CHAIN == 1 || UNDERIVATIZE == 1 ) |
489 | 41.6k | int ret1 = 0, ret2 = 0; /* djb-rwth: removing redundant variables */ |
490 | 41.6k | #endif |
491 | | |
492 | | #if ( REMOVE_ION_PAIRS_ORIG_STRU == 1 ) |
493 | | fix_odd_things( orig_inp_data->num_inp_atoms, orig_inp_data->at, 0, ip->bFixNonUniformDraw ); |
494 | | #endif |
495 | | |
496 | 41.6k | #if ( UNDERIVATIZE == 1 ) |
497 | 41.6k | if (ip->bUnderivatize) |
498 | 0 | { |
499 | 0 | if (0 > ( ret2 = OAD_Edit_Underivatize( ic, pCG, orig_inp_data, ( ip->bINChIOutputOptions & INCHI_OUT_SDFILE_ONLY ), ip->bUnderivatize & 2, ip->pSdfValue ) )) |
500 | 0 | { |
501 | 0 | long num_inp2 = num_inp; |
502 | 0 | AddErrorMessage( sd->pStrErrStruct, "Underivatization error" ); |
503 | 0 | sd->nStructReadError = 99; |
504 | 0 | sd->nErrorType = _IS_ERROR; |
505 | 0 | TreatErrorsInReadTheStructure( sd, ip, LOG_MASK_ALL, inp_file, log_file, out_file, prb_file, |
506 | 0 | prep_inp_data, &num_inp2 ); |
507 | 0 | return _IS_ERROR; /* output only if derivatives found */ |
508 | 0 | } |
509 | 0 | else if (0 < ret2) |
510 | 0 | { |
511 | 0 | if (!ip->bNoWarnings) |
512 | 0 | { |
513 | 0 | WarningMessage( sd->pStrErrStruct, "Input structure underivatized" ); |
514 | 0 | } |
515 | 0 | } |
516 | 0 | } |
517 | 41.6k | #endif /* UNDERIVATIZE == 1 */ |
518 | | |
519 | 41.6k | #if ( RING2CHAIN == 1 ) |
520 | 41.6k | if (ip->bRing2Chain && 0 > ( ret1 = Ring2Chain( ic, pCG, orig_inp_data ) )) |
521 | 0 | { |
522 | 0 | long num_inp2 = num_inp; |
523 | 0 | AddErrorMessage( sd->pStrErrStruct, "Ring to chain error" ); |
524 | 0 | sd->nStructReadError = 99; |
525 | 0 | sd->nErrorType = _IS_ERROR; |
526 | | /* djb-rwth: removing redundant code */ |
527 | 0 | TreatErrorsInReadTheStructure( sd, ip, LOG_MASK_ALL, |
528 | 0 | inp_file, log_file, |
529 | 0 | out_file, prb_file, |
530 | 0 | prep_inp_data, &num_inp2 ); |
531 | 0 | return _IS_ERROR; /* output only if derivatives found */ |
532 | 0 | } |
533 | 41.6k | #endif /* RING2CHAIN == 1 */ |
534 | 41.6k | #if ( RING2CHAIN == 1 || UNDERIVATIZE == 1 ) /***** post v.1 feature *****/ |
535 | 41.6k | if (ip->bIgnoreUnchanged && !ret1 && !ret2) |
536 | 0 | { |
537 | 0 | return _IS_SKIP; /* output only if derivatives or ring/chain found */ |
538 | 0 | } |
539 | 41.6k | #endif /* RING2CHAIN == 1 || UNDERIVATIZE == 1 */ |
540 | 41.6k | return 0; |
541 | 41.6k | } |
542 | | |
543 | | |
544 | | /* If requested, save input data to a Molfile instead of creating INChI */ |
545 | | /* Also used for output in case of combination of options 'InChI2Struct' and 'OutputSDF' */ |
546 | | int OrigAtData_SaveMolfile( ORIG_ATOM_DATA *orig_inp_data, |
547 | | STRUCT_DATA *sd, |
548 | | INPUT_PARMS *ip, |
549 | | long num_inp, |
550 | | INCHI_IOSTREAM *out_file ) |
551 | 41.6k | { |
552 | 41.6k | int ret = 0; |
553 | | |
554 | 41.6k | if (!( ip->bINChIOutputOptions & INCHI_OUT_SDFILE_ONLY )) |
555 | 41.6k | { |
556 | 41.6k | return _IS_OKAY; |
557 | 41.6k | } |
558 | 0 | else |
559 | 0 | { |
560 | 0 | char szNumber[256]; |
561 | 0 | sprintf(szNumber, "Structure #%ld. %s%s%s%s", num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue)); |
562 | 0 | ret = OrigAtData_WriteToSDfile( orig_inp_data, out_file, szNumber, NULL, |
563 | 0 | ( sd->bChiralFlag&FLAG_INP_AT_CHIRAL ) ? 1 : 0, |
564 | 0 | ( ip->bINChIOutputOptions&INCHI_OUT_SDFILE_ATOMS_DT ) ? 1 : 0, |
565 | 0 | ip->pSdfLabel, ip->pSdfValue ); |
566 | 0 | } |
567 | | |
568 | 0 | return ret; |
569 | 41.6k | } |
570 | | |
571 | | |
572 | | /**************************************************************************** |
573 | | Optionally save native input data as 'OrigStruct' data package |
574 | | ****************************************************************************/ |
575 | | ORIG_STRUCT * OrigAtData_StoreNativeInput( CANON_GLOBALS *pCG, |
576 | | int *nRet, |
577 | | STRUCT_DATA *sd, |
578 | | INPUT_PARMS *ip, |
579 | | ORIG_ATOM_DATA *orig_inp_data, |
580 | | ORIG_STRUCT *pOrigStruct ) |
581 | 41.6k | { |
582 | | |
583 | | /* v. 1.05 always create and fill OrigStruc as it may be used to store e.g. polymer info */ |
584 | | /* If normal AuxInfo is requested, create full reversibility information from native inp data |
585 | | if ( ip->bINChIOutputOptions & (INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO)) |
586 | | return NULL; */ |
587 | | |
588 | 41.6k | if (OrigStruct_FillOut( pCG, orig_inp_data, pOrigStruct, sd )) |
589 | 0 | { |
590 | 0 | AddErrorMessage( sd->pStrErrStruct, "Cannot interpret reversibility information" ); |
591 | 0 | sd->nStructReadError = 99; |
592 | 0 | sd->nErrorType = _IS_ERROR; |
593 | 0 | *nRet = _IS_ERROR; |
594 | 0 | } |
595 | | |
596 | 41.6k | return pOrigStruct; |
597 | 41.6k | } |
598 | | |
599 | | |
600 | | /**************************************************************************** |
601 | | Prepare SaveOpt bits |
602 | | ****************************************************************************/ |
603 | | void PrepareSaveOptBits( unsigned char *save_opt_bits, INPUT_PARMS *ip ) |
604 | 41.6k | { |
605 | 41.6k | if (ip->nInputType != INPUT_INCHI) |
606 | 0 | { |
607 | 0 | *save_opt_bits = 0; |
608 | 0 | if (ip->bINChIOutputOptions & INCHI_OUT_SAVEOPT) |
609 | 0 | { |
610 | 0 | if (0 != ( ip->bTautFlags & TG_FLAG_RECONNECT_COORD )) |
611 | 0 | { |
612 | 0 | ( *save_opt_bits ) |= SAVE_OPT_RECMET; |
613 | 0 | } |
614 | 0 | if (0 != ( ip->nMode & REQ_MODE_BASIC )) |
615 | 0 | { |
616 | 0 | ( *save_opt_bits ) |= SAVE_OPT_FIXEDH; |
617 | 0 | } |
618 | 0 | if (0 != ( ip->nMode & REQ_MODE_DIFF_UU_STEREO )) |
619 | 0 | { |
620 | 0 | ( *save_opt_bits ) |= SAVE_OPT_SLUUD; |
621 | 0 | } |
622 | 0 | if (0 == ( ip->nMode & ( REQ_MODE_SB_IGN_ALL_UU | REQ_MODE_SC_IGN_ALL_UU ) )) |
623 | 0 | { |
624 | 0 | ( *save_opt_bits ) |= SAVE_OPT_SUU; |
625 | 0 | } |
626 | 0 | if (0 != ( ip->bTautFlags & TG_FLAG_KETO_ENOL_TAUT )) |
627 | 0 | { |
628 | 0 | ( *save_opt_bits ) |= SAVE_OPT_KET; |
629 | 0 | } |
630 | 0 | if (0 != ( ip->bTautFlags & TG_FLAG_1_5_TAUT )) |
631 | 0 | { |
632 | 0 | ( *save_opt_bits ) |= SAVE_OPT_15T; |
633 | 0 | } |
634 | 0 | if (0 != (ip->bTautFlags & TG_FLAG_PT_22_00)) |
635 | 0 | (*save_opt_bits) |= SAVE_OPT_PT_22_00; |
636 | 0 | if (0 != (ip->bTautFlags & TG_FLAG_PT_16_00)) |
637 | 0 | (*save_opt_bits) |= SAVE_OPT_PT_16_00; |
638 | 0 | if (0 != (ip->bTautFlags & TG_FLAG_PT_06_00)) |
639 | 0 | (*save_opt_bits) |= SAVE_OPT_PT_06_00; |
640 | 0 | if (0 != (ip->bTautFlags & TG_FLAG_PT_39_00)) |
641 | 0 | (*save_opt_bits) |= SAVE_OPT_PT_39_00; |
642 | 0 | if (0 != (ip->bTautFlags & TG_FLAG_PT_13_00)) |
643 | 0 | (*save_opt_bits) |= SAVE_OPT_PT_13_00; |
644 | 0 | if (0 != (ip->bTautFlags & TG_FLAG_PT_18_00)) |
645 | 0 | (*save_opt_bits) |= SAVE_OPT_PT_18_00; |
646 | | /* Check if /SNon requested and turn OFF stereo bits if so */ |
647 | 0 | if (!( ip->nMode & REQ_MODE_STEREO )) |
648 | 0 | { |
649 | 0 | ( *save_opt_bits ) &= ~SAVE_OPT_SUU; |
650 | 0 | ( *save_opt_bits ) &= ~SAVE_OPT_SLUUD; |
651 | 0 | } |
652 | 0 | } |
653 | 0 | } |
654 | 41.6k | } |
655 | | |
656 | | |
657 | | /**************************************************************************** |
658 | | Display structures/components on screen |
659 | | ****************************************************************************/ |
660 | | void DisplayOrigAndResultStructuresAndComponents( int nRet, |
661 | | INCHI_CLOCK *ic, |
662 | | CANON_GLOBALS *pCG, |
663 | | STRUCT_DATA *sd, |
664 | | INPUT_PARMS *ip, |
665 | | char *szTitle, |
666 | | PINChI2 *pINChI[INCHI_NUM], |
667 | | PINChI_Aux2 *pINChI_Aux[INCHI_NUM], |
668 | | INCHI_IOSTREAM *inp_file, |
669 | | INCHI_IOSTREAM *log_file, |
670 | | INCHI_IOSTREAM *out_file, |
671 | | ORIG_ATOM_DATA *orig_inp_data, |
672 | | ORIG_ATOM_DATA *prep_inp_data, |
673 | | long num_inp, |
674 | | int maxINChI, |
675 | | COMP_ATOM_DATA composite_norm_data[INCHI_NUM][TAUT_NUM + 1] ) |
676 | 41.6k | { |
677 | | |
678 | | |
679 | 41.6k | if (ip->bDisplay) ip->bDisplayCompositeResults = 1; /* v. 1.05 */ |
680 | | |
681 | | #ifndef COMPILE_ANSI_ONLY /* { */ |
682 | | |
683 | | /* Display equivalent components on original or preprocessed structure(s) */ |
684 | | #ifndef TARGET_LIB_FOR_WINCHI |
685 | | if (nRet != _IS_FATAL && nRet != _IS_ERROR && /*ip->bDisplay &&*/ |
686 | | ( ip->bCompareComponents & CMP_COMPONENTS ) && !sd->bUserQuit && !sd->bUserQuitComponent) |
687 | | { |
688 | | int j, ret, ord; |
689 | | int bDisplaySaved = ip->bDisplay; |
690 | | ORIG_ATOM_DATA *inp_data; |
691 | | AT_NUMB nEquSet; |
692 | | for (ord = -1; ord < INCHI_NUM; ord++) |
693 | | { |
694 | | switch (ord) |
695 | | { |
696 | | case -1: |
697 | | j = INCHI_BAS; /* preprocessed non-tautomeric */ |
698 | | break; |
699 | | case 0: |
700 | | j = INCHI_REC; /* preprocessed tautomeric */ |
701 | | break; |
702 | | case 1: |
703 | | j = -1; /* original input */ |
704 | | break; |
705 | | default: |
706 | | continue; |
707 | | } |
708 | | inp_data = j < 0 ? orig_inp_data : prep_inp_data + j; |
709 | | if (inp_data && inp_data->num_inp_atoms && inp_data->at && |
710 | | inp_data->nEquLabels && |
711 | | inp_data->nNumEquSets) |
712 | | { |
713 | | for (nEquSet = 1; nEquSet <= inp_data->nNumEquSets; nEquSet++) |
714 | | { |
715 | | ip->dp.nEquLabels = inp_data->nEquLabels; |
716 | | ip->dp.nCurEquLabel = nEquSet; |
717 | | ip->dp.nNumEquSets = inp_data->nNumEquSets; |
718 | | ip->bDisplay = 1; /* force display if it was not requested */ |
719 | | ret = DisplayTheWholeStructure( pCG, ic, sd, ip, szTitle, |
720 | | inp_file, log_file, inp_data, |
721 | | num_inp, j, 1 /*bShowStructure*/, 0 ); |
722 | | ip->dp.nEquLabels = NULL; |
723 | | ip->dp.nCurEquLabel = 0; |
724 | | ip->dp.nNumEquSets = 0; |
725 | | ip->bDisplay = bDisplaySaved; /* restore display option */ |
726 | | if (ret) |
727 | | { |
728 | | /* user pressed Esc */ |
729 | | goto exit_loop; |
730 | | } |
731 | | } |
732 | | } |
733 | | } |
734 | | exit_loop:; |
735 | | } |
736 | | #endif |
737 | | |
738 | | /* Display composite results and equivalent components on composite results */ |
739 | | if (nRet != _IS_FATAL && nRet != _IS_ERROR && /*ip->bDisplay &&*/ ip->bDisplayCompositeResults) |
740 | | { |
741 | | int iINChI; |
742 | | for (iINChI = 0; iINChI < maxINChI && !sd->bUserQuitComponentDisplay; iINChI++) |
743 | | { |
744 | | DisplayTheWholeCompositeStructure( pCG, ic, ip, sd, num_inp, |
745 | | iINChI, pINChI[iINChI], pINChI_Aux[iINChI], |
746 | | orig_inp_data, prep_inp_data, composite_norm_data[iINChI] ); |
747 | | } |
748 | | #ifndef TARGET_LIB_FOR_WINCHI |
749 | | if (!ip->bDisplay && sd->bUserQuitComponentDisplay) |
750 | | { |
751 | | sd->bUserQuit = 1; |
752 | | } |
753 | | #endif |
754 | | } |
755 | | |
756 | | #endif /* } COMPILE_ANSI_ONLY */ |
757 | | |
758 | 41.6k | return; |
759 | 41.6k | } |
760 | | |
761 | | |
762 | | /**************************************************************************** |
763 | | Special mode (option /PGO) : extract all good MOLfiles into the problem file; |
764 | | do not extract any MOLfile that could not be processed. |
765 | | ****************************************************************************/ |
766 | | void SaveOkProcessedMolfile( int nRet, |
767 | | STRUCT_DATA *sd, |
768 | | INPUT_PARMS *ip, |
769 | | INCHI_IOSTREAM *prb_file, |
770 | | INCHI_IOSTREAM *inp_file ) |
771 | 41.6k | { |
772 | 41.6k | if (ip->bSaveAllGoodStructsAsProblem && |
773 | 41.6k | nRet != _IS_FATAL && |
774 | 41.6k | nRet != _IS_ERROR && |
775 | 41.6k | prb_file && |
776 | 41.6k | prb_file->f && |
777 | 41.6k | 0L <= sd->fPtrStart && |
778 | 41.6k | sd->fPtrStart < sd->fPtrEnd) |
779 | 0 | { |
780 | 0 | MolfileSaveCopy( inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file->f, 0 ); |
781 | 0 | } |
782 | | |
783 | 41.6k | return; |
784 | 41.6k | } |
785 | | |
786 | | |
787 | | /**************************************************************************** |
788 | | Generate InChI for the whole (multi-component) structure |
789 | | ****************************************************************************/ |
790 | | int CreateOneStructureINChI( CANON_GLOBALS *pCG, |
791 | | INCHI_CLOCK *ic, |
792 | | STRUCT_DATA *sd, |
793 | | INPUT_PARMS *ip, |
794 | | char *szTitle, |
795 | | PINChI2 *pINChI2[INCHI_NUM], |
796 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
797 | | int iINChI, |
798 | | INCHI_IOSTREAM *inp_file, |
799 | | INCHI_IOSTREAM *log_file, |
800 | | INCHI_IOSTREAM *out_file, |
801 | | INCHI_IOSTREAM *prb_file, |
802 | | ORIG_ATOM_DATA *orig_inp_data, |
803 | | ORIG_ATOM_DATA *prep_inp_data, |
804 | | COMP_ATOM_DATA composite_norm_data2[][TAUT_NUM + 1], |
805 | | long num_inp, |
806 | | INCHI_IOS_STRING *strbuf, |
807 | | NORM_CANON_FLAGS *pncFlags ) |
808 | 41.8k | { |
809 | 41.8k | int i, j, k, nRet = 0, n = 0l; |
810 | | #if defined (TARGET_EXE_STANDALONE) && defined(_WIN32) |
811 | | int err_display; |
812 | | #endif |
813 | | |
814 | 41.8k | PINChI2 *pINChI = NULL; |
815 | 41.8k | PINChI_Aux2 *pINChI_Aux = NULL; |
816 | | |
817 | 41.8k | INP_ATOM_DATA InpCurAtData; |
818 | 41.8k | INP_ATOM_DATA *inp_cur_data; |
819 | | |
820 | 41.8k | INP_ATOM_DATA InpNormAtData, InpNormTautData; |
821 | 41.8k | INP_ATOM_DATA *inp_norm_data[TAUT_NUM]; /* = { &InpNormAtData, &InpNormTautData }; */ |
822 | 41.8k | ORIG_ATOM_DATA *cur_prep_inp_data = prep_inp_data + iINChI; |
823 | 41.8k | inchiTime ulTStart; |
824 | | |
825 | | /* Always create info data structures (but do not display them always ) |
826 | | #ifndef COMPILE_ANSI_ONLY |
827 | | */ |
828 | 41.8k | int bShowStructure = 0; |
829 | 41.8k | int bStructurePreprocessed = 0; /* All changes except disconnection */ |
830 | 41.8k | int bStructureDisconnected = 0; |
831 | 41.8k | int bAlsoOutputReconnected = 0, bINCHI_LIB_Flag = 0; |
832 | 41.8k | COMP_ATOM_DATA *composite_norm_data = composite_norm_data2[iINChI]; |
833 | 41.8k | INP_ATOM_DATA2 *all_inp_norm_data = NULL; |
834 | | /*#endif*/ |
835 | | |
836 | | /* Order of actions: |
837 | | |
838 | | if ( orig_inp_data is NOT empty AND |
839 | | prep_inp_data[0] IS empty ) then do |
840 | | in PreprocessOneStructure() : |
841 | | |
842 | | 1. copy orig_inp_data --> prep_inp_data[0] |
843 | | 2. fix odd things in prep_inp_data[0] |
844 | | 3. if( orig_inp_data->bDisconnectSalts ) then |
845 | | -- disconnect salts in prep_inp_data[0] |
846 | | 4. move protons to neutralize charges on heteroatoms |
847 | | 5. if( orig_inp_data->bDisconnectCoord ) then |
848 | | -- copy prep_inp_data[0] --> prep_inp_data[1] |
849 | | -- disconnect metals in prep_inp_data[0] |
850 | | |
851 | | iINChI = 0 |
852 | | ========= |
853 | | (normal/disconnected layer) |
854 | | |
855 | | 1. normalize prep_inp_data[0] in inp_norm_data[0,1] |
856 | | 2. create INChI[ iINChI ] out of inp_norm_data[0,1] |
857 | | |
858 | | |
859 | | iINChI = 1 AND orig_inp_data->bDisconnectCoord > 0 |
860 | | ================================================= |
861 | | (reconnected layer) |
862 | | |
863 | | 1. normalize prep_inp_data[1] in inp_norm_data[0,1] |
864 | | 2. create INChI[ iINChI ] out of inp_norm_data[0,1] |
865 | | |
866 | | */ |
867 | | |
868 | 41.8k | ip->msec_LeftTime = ip->msec_MaxTime; /* start timeout countdown for each component */ |
869 | | |
870 | 41.8k | inp_cur_data = &InpCurAtData; |
871 | 41.8k | inp_norm_data[TAUT_NON] = &InpNormAtData; |
872 | 41.8k | inp_norm_data[TAUT_YES] = &InpNormTautData; |
873 | | |
874 | 41.8k | memset( inp_cur_data, 0, sizeof( *inp_cur_data ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
875 | 41.8k | memset( inp_norm_data[TAUT_NON], 0, sizeof( *inp_norm_data[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
876 | 41.8k | memset( inp_norm_data[TAUT_YES], 0, sizeof( *inp_norm_data[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
877 | | |
878 | 41.8k | { |
879 | | /*#ifndef COMPILE_ANSI_ONLY*/ |
880 | 41.8k | memset( composite_norm_data + TAUT_NON, 0, sizeof( composite_norm_data[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
881 | 41.8k | memset( composite_norm_data + TAUT_YES, 0, sizeof( composite_norm_data[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
882 | 41.8k | memset( composite_norm_data + TAUT_INI, 0, sizeof( composite_norm_data[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
883 | 41.8k | } /*#endif*/ |
884 | | |
885 | 41.8k | if (ip->bAllowEmptyStructure && !orig_inp_data->at && !orig_inp_data->num_inp_atoms) |
886 | 0 | { |
887 | 0 | ; |
888 | 0 | } |
889 | 41.8k | else if (!orig_inp_data->at || !orig_inp_data->num_inp_atoms) |
890 | 0 | { |
891 | 0 | return 0; /* nothing to do */ |
892 | 0 | } |
893 | 41.8k | if (iINChI == 1 && orig_inp_data->bDisconnectCoord <= 0) |
894 | 0 | { |
895 | 0 | return 0; |
896 | 0 | } |
897 | | |
898 | | /* m = iINChI; */ /* orig_inp_data index */ |
899 | 41.8k | if (iINChI != INCHI_BAS && iINChI != INCHI_REC) |
900 | 0 | { |
901 | 0 | AddErrorMessage( sd->pStrErrStruct, "Fatal undetermined program error" ); |
902 | 0 | sd->nStructReadError = 97; |
903 | 0 | nRet = sd->nErrorType = _IS_FATAL; |
904 | 0 | inchi_free(all_inp_norm_data); /* djb-rwth: avoiding memory leak */ |
905 | 0 | goto exit_function; |
906 | 0 | } |
907 | | |
908 | | /******************************************************************* |
909 | | * * |
910 | | * * |
911 | | * Whole structure preprocessing: 1st step of the normalization * |
912 | | * * |
913 | | * Happen only on the first call to CreateOneStructureINChI() * |
914 | | * * |
915 | | * * |
916 | | *******************************************************************/ |
917 | | |
918 | 41.8k | if (( !prep_inp_data->at || !prep_inp_data->num_inp_atoms ) && |
919 | 41.8k | orig_inp_data->num_inp_atoms > 0) |
920 | 41.6k | { |
921 | | /* The structure has not been preprocessed */ |
922 | 41.6k | if (ip->msec_MaxTime) |
923 | 0 | { |
924 | 0 | InchiTimeGet( &ulTStart ); |
925 | 0 | } |
926 | | |
927 | 41.6k | PreprocessOneStructure( ic, sd, ip, orig_inp_data, prep_inp_data ); |
928 | | |
929 | 41.6k | pncFlags->bTautFlags[iINChI][TAUT_YES] = |
930 | 41.6k | pncFlags->bTautFlags[iINChI][TAUT_NON] = |
931 | 41.6k | sd->bTautFlags[INCHI_BAS] | ip->bTautFlags; |
932 | | |
933 | 41.6k | pncFlags->bTautFlagsDone[iINChI][TAUT_YES] = |
934 | 41.6k | pncFlags->bTautFlagsDone[iINChI][TAUT_NON] = |
935 | 41.6k | sd->bTautFlagsDone[INCHI_BAS] | ip->bTautFlagsDone; |
936 | | |
937 | 41.6k | { |
938 | | /*#ifndef COMPILE_ANSI_ONLY*/ |
939 | | /* in this location the call happens once for each input structure, before preprocessing */ |
940 | 41.6k | bStructurePreprocessed = ( 0 != ( sd->bTautFlagsDone[INCHI_BAS] & ( |
941 | 41.6k | TG_FLAG_MOVE_HPLUS2NEUTR_DONE | |
942 | 41.6k | TG_FLAG_DISCONNECT_SALTS_DONE | |
943 | 41.6k | TG_FLAG_MOVE_POS_CHARGES_DONE | |
944 | 41.6k | TG_FLAG_FIX_ODD_THINGS_DONE ) ) ); |
945 | | |
946 | 41.6k | bStructureDisconnected = ( 0 != ( sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE ) ); |
947 | | |
948 | 41.6k | bShowStructure = ( bStructurePreprocessed || |
949 | 41.6k | bStructureDisconnected || |
950 | 41.6k | prep_inp_data[0].num_components > 1 ); |
951 | | |
952 | | /* sd->bTautFlags[] contains output flags |
953 | | ip->bTautFlags contains input flags |
954 | | */ |
955 | 41.6k | bAlsoOutputReconnected = ( sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE ) && |
956 | 41.6k | ( ip->bTautFlags & TG_FLAG_RECONNECT_COORD ); |
957 | 41.6k | bINCHI_LIB_Flag = 0; |
958 | | |
959 | | /*************** output structures to TARGET_LIB_FOR_WINCHI conditions ********************* |
960 | | * |
961 | | * Send to TARGET_LIB_FOR_WINCHI: |
962 | | * |
963 | | * type component conditions |
964 | | * |
965 | | * COMPONENT_ORIGINAL #0: (num_components > 1) |
966 | | * COMPONENT_ORIGINAL_PREPROCESSED #0: (num_components > 1) && (preprocessed) |
967 | | * COMPONENT_ORIGINAL #1: (num_components = 1) && (preprocessed) |
968 | | * |
969 | | * Flags explanation: |
970 | | * MAIN => iINChI=0, RECN => iINChI=1 (Reconnected) |
971 | | * ORIG => Original, PREP => Preprocessed |
972 | | * |
973 | | * Possible flags: k |
974 | | * |
975 | | * COMP_ORIG_0_MAIN 0x0001 0 COMPONENT_ORIGINAL, bMain, component #0 |
976 | | * COMP_ORIG_0_RECN 0x0002 1 COMPONENT_ORIGINAL, bRecn, component #0 |
977 | | * |
978 | | * COMP_PREP_0_MAIN 0x0004 2 COMPONENT_ORIGINAL_PREPROCESSED, bMain, component #0 |
979 | | * COMP_PREP_0_RECN 0x0008 3 COMPONENT_ORIGINAL_PREPROCESSED, bRecn, component #0 |
980 | | * |
981 | | * COMP_ORIG_1_MAIN 0x0010 4 COMPONENT_ORIGINAL, bMain, component #1 |
982 | | * COMP_ORIG_1_RECN 0x0020 5 COMPONENT_ORIGINAL, bRecn, component #1 |
983 | | * |
984 | | * bReconnected = k%2 (0 or 1) |
985 | | * nComponent = k/4 (0 or 1) |
986 | | * bPreprocessed = (k/2)%2 (0 or 1) |
987 | | * |
988 | | ******************************************************************************/ |
989 | | |
990 | | /* Original -> Main, component #0, Original */ |
991 | 41.6k | if (prep_inp_data[INCHI_BAS].num_components > 1) |
992 | 238 | { |
993 | 238 | bINCHI_LIB_Flag |= COMP_ORIG_0_MAIN; |
994 | 238 | } |
995 | 41.3k | else |
996 | 41.3k | { |
997 | | /* Original -> Main, component #1, Original */ |
998 | 41.3k | if (prep_inp_data[INCHI_BAS].num_components == 1 && bStructurePreprocessed) |
999 | 49 | { |
1000 | 49 | bINCHI_LIB_Flag |= COMP_ORIG_1_MAIN; |
1001 | | /* preprocessed will be added when output canonicalization results */ |
1002 | 49 | } |
1003 | 41.3k | } |
1004 | | |
1005 | 41.6k | if (bAlsoOutputReconnected) |
1006 | 234 | { |
1007 | | /* Original -> Reconnected, component #0, Original */ |
1008 | 234 | if (prep_inp_data[INCHI_REC].num_components > 1) |
1009 | 0 | { |
1010 | 0 | bINCHI_LIB_Flag |= COMP_ORIG_0_RECN; |
1011 | 0 | } |
1012 | 234 | else if (prep_inp_data[INCHI_BAS].num_components == 1 && bStructurePreprocessed) |
1013 | 0 | { |
1014 | | /* Original -> Reconnected, component #1, Original */ |
1015 | 0 | bINCHI_LIB_Flag |= COMP_ORIG_1_RECN; |
1016 | | /* preprocessed will be added when output canonicalization results */ |
1017 | 0 | } |
1018 | 234 | } |
1019 | 41.6k | if (ip->msec_MaxTime) |
1020 | 0 | { |
1021 | 0 | ip->msec_LeftTime -= InchiTimeElapsed( ic, &ulTStart ); |
1022 | 0 | } |
1023 | | |
1024 | | /* display the ORIGINAL, UN-PREPROCESSED structure */ |
1025 | | |
1026 | 41.6k | if (ip->bDisplay) |
1027 | 0 | { |
1028 | 0 | if (DisplayTheWholeStructure( pCG, ic, sd, ip, szTitle, |
1029 | 0 | inp_file, log_file, orig_inp_data, num_inp, |
1030 | 0 | -1, bShowStructure, bINCHI_LIB_Flag )) |
1031 | 0 | { |
1032 | 0 | inchi_free(all_inp_norm_data); /* djb-rwth: avoiding memory leak */ |
1033 | 0 | goto exit_function; |
1034 | 0 | } |
1035 | 0 | } |
1036 | 41.6k | } /*#endif */ |
1037 | | |
1038 | 41.6k | switch (sd->nErrorType) |
1039 | 41.6k | { |
1040 | 0 | case _IS_ERROR: |
1041 | 0 | case _IS_FATAL: |
1042 | | /* error message */ |
1043 | 0 | nRet = TreatErrorsInReadTheStructure( sd, ip, |
1044 | 0 | LOG_MASK_ALL, |
1045 | 0 | inp_file, log_file, out_file, prb_file, |
1046 | 0 | prep_inp_data, &num_inp ); |
1047 | 0 | goto exit_cycle; |
1048 | 41.6k | } |
1049 | 41.6k | } |
1050 | | /* tranfer flags from INChI_Aux to sd */ |
1051 | | |
1052 | | |
1053 | 41.8k | { |
1054 | | /*#ifndef COMPILE_ANSI_ONLY */ /* { */ |
1055 | | |
1056 | | /******************************************/ |
1057 | | /* Displaying the structures */ |
1058 | | /* Only under WIN32 */ |
1059 | | /******************************************/ |
1060 | 41.8k | if ( /* ip->bDisplayCompositeResults && !sd->bUserQuitComponentDisplay && */ |
1061 | 41.8k | prep_inp_data[iINChI].num_components > 1 |
1062 | 41.8k | ) |
1063 | 238 | { |
1064 | 238 | all_inp_norm_data = (INP_ATOM_DATA2 *) inchi_calloc( prep_inp_data[iINChI].num_components, sizeof( all_inp_norm_data[0] ) ); |
1065 | 238 | } |
1066 | | |
1067 | | /* Display the input structure AFTER PREPROCESSING */ |
1068 | 41.8k | switch (iINChI) |
1069 | 41.8k | { |
1070 | 41.6k | case INCHI_BAS: |
1071 | | /*------------ Possibly disconnected structure -------------------*/ |
1072 | 41.6k | bStructurePreprocessed = 0 != ( sd->bTautFlagsDone[iINChI] & ( |
1073 | 41.6k | TG_FLAG_MOVE_HPLUS2NEUTR_DONE | |
1074 | 41.6k | TG_FLAG_DISCONNECT_SALTS_DONE | |
1075 | 41.6k | TG_FLAG_MOVE_POS_CHARGES_DONE | |
1076 | 41.6k | TG_FLAG_MOVE_CHARGE_COORD_DONE | |
1077 | 41.6k | TG_FLAG_DISCONNECT_COORD_DONE | |
1078 | 41.6k | TG_FLAG_FIX_ODD_THINGS_DONE ) ); |
1079 | 41.6k | bINCHI_LIB_Flag = 0; |
1080 | | /* Preprocessed/Main -> Main, component #0, Preprocessed */ |
1081 | 41.6k | if (prep_inp_data[iINChI].num_components > 1 && |
1082 | 41.6k | bStructurePreprocessed) |
1083 | 234 | { |
1084 | 234 | bINCHI_LIB_Flag |= COMP_PREP_0_MAIN; |
1085 | 234 | } |
1086 | 41.6k | bShowStructure = ( bStructurePreprocessed && |
1087 | 41.6k | prep_inp_data[iINChI].num_components > 1 ); |
1088 | 41.6k | break; |
1089 | | |
1090 | 233 | case INCHI_REC: |
1091 | | /*------------ Reconnected structure ------------------------------*/ |
1092 | 233 | bAlsoOutputReconnected = |
1093 | 233 | ( sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE ) && |
1094 | 233 | ( ip->bTautFlags & TG_FLAG_RECONNECT_COORD ); |
1095 | | |
1096 | 233 | if (!bAlsoOutputReconnected) |
1097 | 0 | { |
1098 | 0 | break; |
1099 | 0 | } |
1100 | | |
1101 | 233 | bStructurePreprocessed = 0 != ( sd->bTautFlagsDone[iINChI] & ( |
1102 | 233 | TG_FLAG_MOVE_HPLUS2NEUTR_DONE | |
1103 | 233 | TG_FLAG_DISCONNECT_SALTS_DONE | |
1104 | 233 | TG_FLAG_MOVE_POS_CHARGES_DONE | |
1105 | 233 | TG_FLAG_FIX_ODD_THINGS_DONE ) ); |
1106 | 233 | bINCHI_LIB_Flag = 0; |
1107 | | /* Preprocessed/Reconnected -> Reconnected, component #0, Preprocessed */ |
1108 | 233 | if (prep_inp_data[iINChI].num_components > 1 && bStructurePreprocessed) |
1109 | 0 | { |
1110 | 0 | bINCHI_LIB_Flag |= COMP_PREP_0_RECN; |
1111 | 0 | } |
1112 | 233 | bShowStructure = ( bStructurePreprocessed && |
1113 | 233 | prep_inp_data[iINChI].num_components > 1 ); |
1114 | 233 | break; |
1115 | | |
1116 | 0 | default: |
1117 | 0 | bShowStructure = 0; |
1118 | 41.8k | } |
1119 | | |
1120 | | |
1121 | 41.8k | if (ip->bDisplay && prep_inp_data[iINChI].num_inp_atoms > 0) |
1122 | 0 | { |
1123 | 0 | if (DisplayTheWholeStructure( pCG, ic, sd, ip, szTitle, |
1124 | 0 | inp_file, log_file, |
1125 | 0 | prep_inp_data + iINChI, |
1126 | 0 | num_inp, |
1127 | 0 | iINChI, |
1128 | 0 | bShowStructure, |
1129 | 0 | bINCHI_LIB_Flag )) |
1130 | 0 | { |
1131 | 0 | inchi_free(all_inp_norm_data); /* djb-rwth: avoiding memory leak */ |
1132 | 0 | goto exit_function; |
1133 | 0 | } |
1134 | 0 | } |
1135 | 41.8k | } /* #endif */ /* } ifndef COMPILE_ANSI_ONLY */ |
1136 | | |
1137 | | |
1138 | | /* allocate pINChI[iINChI] and pINChI_Aux2[iINChI] -- arrays of pointers to INChI and INChI_Aux */ |
1139 | | /* assign values to sd->num_components[] */ |
1140 | | |
1141 | | /* djb-rwth: MYREALLOC2 has been replaced and the whole block rewritten to address memory leaks and reading from freed memory locations */ |
1142 | 41.8k | do { |
1143 | 41.8k | if( (sd->num_components[iINChI]) <= ((long long)cur_prep_inp_data->num_components) ) { |
1144 | 41.8k | PINChI2* newPTR1 = (PINChI2*)inchi_calloc( ((long long)cur_prep_inp_data->num_components)+1, sizeof(PINChI2) ); |
1145 | 41.8k | PINChI_Aux2* newPTR2 = (PINChI_Aux2*)inchi_calloc( ((long long)cur_prep_inp_data->num_components)+1, sizeof(PINChI_Aux2) ); |
1146 | 41.8k | if ( newPTR1 && newPTR2 ) { |
1147 | 41.8k | if ( (pINChI2[iINChI]) && (sd->num_components[iINChI]) > 0 ) |
1148 | 0 | memcpy(newPTR1, pINChI2[iINChI], (sd->num_components[iINChI]) * sizeof(PINChI2)); |
1149 | 41.8k | if ((pINChI_Aux2[iINChI]) && (sd->num_components[iINChI]) > 0) |
1150 | 0 | memcpy(newPTR2, pINChI_Aux2[iINChI], (sd->num_components[iINChI]) * sizeof(PINChI_Aux2)); |
1151 | 41.8k | if (pINChI2[iINChI]) |
1152 | 0 | inchi_free(pINChI2[iINChI]); |
1153 | 41.8k | if (pINChI_Aux2[iINChI]) |
1154 | 0 | inchi_free(pINChI_Aux2[iINChI]); |
1155 | 41.8k | pINChI2[iINChI] = newPTR1; |
1156 | 41.8k | pINChI_Aux2[iINChI] = newPTR2; |
1157 | 41.8k | sd->num_components[iINChI] = cur_prep_inp_data->num_components; |
1158 | 41.8k | k = 0; |
1159 | 41.8k | } |
1160 | 0 | else { |
1161 | 0 | inchi_free(newPTR1); |
1162 | 0 | inchi_free(newPTR2); |
1163 | 0 | k = 1; |
1164 | 0 | } |
1165 | 41.8k | } |
1166 | 0 | else { k = 0; } |
1167 | 41.8k | } while (0); |
1168 | | |
1169 | 41.8k | if (k) |
1170 | 0 | { |
1171 | 0 | AddErrorMessage( sd->pStrErrStruct, "Cannot allocate output data. Terminating" ); |
1172 | 0 | sd->nStructReadError = 99; |
1173 | 0 | sd->nErrorType = _IS_FATAL; |
1174 | 0 | inchi_free(all_inp_norm_data); /* djb-rwth: avoiding memory leak */ |
1175 | 0 | goto exit_function; |
1176 | 0 | } |
1177 | | |
1178 | 41.8k | pINChI = pINChI2[iINChI]; |
1179 | 41.8k | pINChI_Aux = pINChI_Aux2[iINChI]; |
1180 | | |
1181 | | /**************************************************************************/ |
1182 | | /* */ |
1183 | | /* */ |
1184 | | /* M A I N C Y C L E: P R O C E S S C O M P O N E N T S */ |
1185 | | /* */ |
1186 | | /* */ |
1187 | | /* O N E B Y O N E */ |
1188 | | /* */ |
1189 | | /* */ |
1190 | | /**************************************************************************/ |
1191 | | |
1192 | 41.8k | for (i = 0, nRet = 0; |
1193 | 107k | !sd->bUserQuitComponent && i < cur_prep_inp_data->num_components; |
1194 | 65.8k | i++) |
1195 | 65.8k | { |
1196 | 65.8k | if (ip->msec_MaxTime) |
1197 | 0 | { |
1198 | 0 | InchiTimeGet( &ulTStart ); |
1199 | 0 | } |
1200 | | |
1201 | 65.8k | #ifndef TARGET_LIB_FOR_WINCHI /* { */ |
1202 | 65.8k | #if ( bREUSE_INCHI == 1 ) |
1203 | | |
1204 | 65.8k | if ((iINChI == INCHI_REC && |
1205 | | /*( !ip->bDisplay && |
1206 | | !ip->bDisplayCompositeResults && */ |
1207 | 65.8k | !( ip->bCompareComponents & CMP_COMPONENTS )) || |
1208 | 65.8k | sd->bUserQuitComponentDisplay) /* djb-rwth: addressing LLVM warning */ |
1209 | 233 | { |
1210 | | /* Reconnected structure (06-20-2005: added "&& !ip->bDisplayCompositeResults" to display composite structure) */ |
1211 | 233 | int m = iINChI - 1; |
1212 | | |
1213 | | /* Find whether we have already calculated this INChI in basic (disconnected) layer */ |
1214 | 782 | for (j = n = 0; j < prep_inp_data[m].num_components; j++) |
1215 | 549 | { |
1216 | 549 | if (i + 1 == prep_inp_data[m].nOldCompNumber[j] && |
1217 | 549 | ( pINChI2[m][j][TAUT_NON] || pINChI2[m][j][TAUT_YES] )) |
1218 | 0 | { |
1219 | | /* Yes, we have already done this */ |
1220 | 0 | if (!n++) |
1221 | 0 | { |
1222 | 0 | memcpy(pINChI + i, pINChI2[m] + j, sizeof(pINChI[0])); |
1223 | 0 | memcpy(pINChI_Aux + i, pINChI_Aux2[m] + j, sizeof(pINChI_Aux[0])); |
1224 | 0 | for (k = 0; k < TAUT_NUM; k++) |
1225 | 0 | { |
1226 | 0 | if (pINChI[i][k]) |
1227 | 0 | { |
1228 | 0 | pINChI[i][k]->nRefCount++; |
1229 | 0 | if (pINChI[i][k]->nNumberOfAtoms > 0) |
1230 | 0 | { |
1231 | 0 | switch (k) |
1232 | 0 | { |
1233 | 0 | case TAUT_NON: |
1234 | 0 | sd->num_non_taut[iINChI] ++; |
1235 | 0 | break; |
1236 | 0 | case TAUT_YES: |
1237 | 0 | if (pINChI[i][k]->lenTautomer > 0) |
1238 | 0 | { |
1239 | 0 | sd->num_taut[iINChI] ++; |
1240 | 0 | } |
1241 | 0 | else |
1242 | 0 | if (!pINChI[i][TAUT_NON] || |
1243 | 0 | !pINChI[i][TAUT_NON]->nNumberOfAtoms) |
1244 | 0 | { |
1245 | 0 | sd->num_non_taut[iINChI] ++; |
1246 | 0 | } |
1247 | 0 | break; |
1248 | 0 | } |
1249 | 0 | } |
1250 | 0 | } |
1251 | 0 | if (pINChI_Aux[i][k]) |
1252 | 0 | { |
1253 | 0 | pINChI_Aux[i][k]->nRefCount++; |
1254 | 0 | } |
1255 | 0 | } |
1256 | 0 | } |
1257 | 0 | } |
1258 | 549 | } |
1259 | | |
1260 | 233 | if (n == 1) |
1261 | 0 | { |
1262 | 0 | continue; |
1263 | 0 | } |
1264 | 233 | if (n > 1) |
1265 | 0 | { |
1266 | | /* ith component is equivalent to more than one another component */ |
1267 | 0 | AddErrorMessage( sd->pStrErrStruct, "Cannot distinguish components" ); |
1268 | 0 | sd->nStructReadError = 99; |
1269 | 0 | sd->nErrorType = _IS_ERROR; |
1270 | 0 | inchi_free(all_inp_norm_data); /* djb-rwth: avoiding memory leak */ |
1271 | 0 | goto exit_function; |
1272 | 0 | } |
1273 | 233 | } |
1274 | | |
1275 | 65.8k | #endif |
1276 | 65.8k | #endif /* } TARGET_LIB_FOR_WINCHI */ |
1277 | | |
1278 | | /*****************************************************/ |
1279 | | /* a) Allocate memory and extract current component */ |
1280 | | /*****************************************************/ |
1281 | | |
1282 | 65.8k | nRet = GetOneComponent( ic, sd, ip, |
1283 | 65.8k | log_file, out_file, |
1284 | 65.8k | inp_cur_data, cur_prep_inp_data, |
1285 | 65.8k | i, num_inp ); |
1286 | | |
1287 | 65.8k | if (ip->msec_MaxTime) |
1288 | 0 | { |
1289 | 0 | ip->msec_LeftTime -= InchiTimeElapsed( ic, &ulTStart ); |
1290 | 0 | } |
1291 | | |
1292 | 65.8k | switch (nRet) |
1293 | 65.8k | { |
1294 | 0 | case _IS_ERROR: |
1295 | 0 | case _IS_FATAL: |
1296 | 0 | goto exit_cycle; |
1297 | 65.8k | } |
1298 | | |
1299 | | #if !defined(TARGET_API_LIB) && !defined(COMPILE_ANSI_ONLY) |
1300 | | /* console request: Display the component? */ |
1301 | | if (ip->bDisplay && inp_file->f != stdin) |
1302 | | { |
1303 | | if (user_quit( ic, "Enter=Display Component, Esc=Stop ?", ip->ulDisplTime )) |
1304 | | { |
1305 | | sd->bUserQuitComponent = 1; |
1306 | | break; |
1307 | | } |
1308 | | } |
1309 | | #endif |
1310 | | |
1311 | | /*#ifndef COMPILE_ANSI_ONLY |
1312 | | { */ |
1313 | | |
1314 | | /* b) Display the extracted original component structure */ |
1315 | 65.8k | if (ip->bDisplay && inp_cur_data->at && !sd->bUserQuitComponentDisplay) |
1316 | 0 | { |
1317 | 0 | if (cur_prep_inp_data->num_components == 1) |
1318 | 0 | { |
1319 | 0 | sprintf(szTitle, "%sInput Structure #%ld.%s%s%s%s%s", |
1320 | 0 | bStructurePreprocessed ? "Preprocessed " : "", |
1321 | 0 | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue), iINChI ? " (Reconnected)" : ""); |
1322 | 0 | } |
1323 | 0 | else |
1324 | 0 | { |
1325 | 0 | sprintf(szTitle, "Component #%d of %d, Input Structure #%ld.%s%s%s%s%s", |
1326 | 0 | i + 1, cur_prep_inp_data->num_components, |
1327 | 0 | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue), iINChI ? " (Reconnected)" : ""); |
1328 | 0 | } |
1329 | |
|
1330 | | #if defined (TARGET_EXE_STANDALONE) && defined(_WIN32) |
1331 | | err_display = DisplayStructure( pCG, |
1332 | | inp_cur_data->at, |
1333 | | inp_cur_data->num_at, |
1334 | | NULL, /* OAD_Polymer *polymer, */ |
1335 | | 0, |
1336 | | 1, |
1337 | | 0, |
1338 | | NULL, |
1339 | | 1 /*isotopic*/, |
1340 | | 0 /*taut*/, |
1341 | | NULL, |
1342 | | NULL, |
1343 | | ip->bAbcNumbers, |
1344 | | &ip->dp, |
1345 | | ip->nMode, |
1346 | | szTitle ); |
1347 | | |
1348 | | sd->bUserQuitComponentDisplay = (err_display == ESC_KEY ); |
1349 | | |
1350 | | if (!err_display) |
1351 | | { |
1352 | | inchi_fprintf( stderr, "Cannot display the structure\n" ); |
1353 | | } |
1354 | | #endif |
1355 | | #ifdef TARGET_LIB_FOR_WINCHI |
1356 | | if (DRAWDATA && DRAWDATA_EXISTS) |
1357 | | { |
1358 | | struct DrawData vDrawData; |
1359 | | int nType = COMPONENT_ORIGINAL; |
1360 | | vDrawData.pWindowData = CreateWinData_( pCG, |
1361 | | inp_cur_data->at, |
1362 | | inp_cur_data->num_at, |
1363 | | 0, |
1364 | | 1 /* bAdd_DT_to_num_H */, |
1365 | | 0, |
1366 | | NULL, |
1367 | | 1 /* display isotopic if present */, |
1368 | | 0, |
1369 | | NULL, |
1370 | | NULL, |
1371 | | ip->bAbcNumbers, |
1372 | | &ip->dp, |
1373 | | ip->nMode ); |
1374 | | if (vDrawData.pWindowData != NULL) |
1375 | | { |
1376 | | if (DRAWDATA_EXISTS( i + 1, nType, iINChI )) |
1377 | | { |
1378 | | /* i = component number */ |
1379 | | nType = COMPONENT_ORIGINAL_PREPROCESSED; |
1380 | | } |
1381 | | vDrawData.nComponent = i + 1; |
1382 | | vDrawData.nType = nType; |
1383 | | vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */ |
1384 | | vDrawData.szTitle = inchi__strdup( szTitle ); |
1385 | | vDrawData.pWindowData->szTitle = inchi__strdup( szTitle ); |
1386 | | DRAWDATA( &vDrawData ); |
1387 | | } |
1388 | | } |
1389 | | #endif |
1390 | 0 | } |
1391 | | /*#endif */ /* } COMPILE_ANSI_ONLY */ |
1392 | | |
1393 | | |
1394 | | /*******************************************************************************/ |
1395 | | /* */ |
1396 | | /* N O R M A L I Z A T I O N a n d C A N O N I C A L I Z A T I O N */ |
1397 | | /* */ |
1398 | | /* (both tautomeric and non-tautomeric if requested) */ |
1399 | | /* */ |
1400 | | /*******************************************************************************/ |
1401 | | /* c) Create the component's INChI ( copies ip->bTautFlags into sd->bTautFlags)*/ |
1402 | | /*******************************************************************************/ |
1403 | | |
1404 | 65.8k | nRet = CreateOneComponentINChI( pCG, ic, sd, ip, |
1405 | 65.8k | inp_cur_data, orig_inp_data, |
1406 | 65.8k | pINChI/*2[iINChI]*/, |
1407 | 65.8k | pINChI_Aux/*2[iINChI]*/, |
1408 | 65.8k | iINChI, i, num_inp, |
1409 | 65.8k | inp_norm_data, pncFlags, log_file ); |
1410 | | |
1411 | | |
1412 | | |
1413 | | /* d) Display one component structure and/or INChI results only if there was no error */ |
1414 | | |
1415 | | /* #ifndef COMPILE_ANSI_ONLY */ /* { */ |
1416 | 65.8k | if (!nRet) |
1417 | 65.8k | { |
1418 | | /* output one component INChI to the stdout if requested */ |
1419 | | /* |
1420 | | if ( ip->bDisplayEachComponentINChI ) { |
1421 | | int cur_num_non_taut = (pINChI[i][TAUT_NON] && pINChI[i][TAUT_NON]->nNumberOfAtoms>0); |
1422 | | int cur_num_taut = (pINChI[i][TAUT_YES] && pINChI[i][TAUT_YES]->nNumberOfAtoms>0); |
1423 | | if ( ip->bDisplayEachComponentINChI && cur_num_non_taut + cur_num_taut ) { |
1424 | | SortAndPrintINChI( pCG, stdout, pStr, nStrLen, NULL, |
1425 | | ip, 1, cur_num_non_taut, cur_num_taut, |
1426 | | num_inp, pINChI+i, pINChI_Aux+i, |
1427 | | save_opt_bits); |
1428 | | } |
1429 | | } |
1430 | | */ |
1431 | | /************************************************************************** |
1432 | | * display from one up to 4 structure pictures-results for each component * |
1433 | | * Enable buttons: * |
1434 | | * BN (non-tautomeric non-isotopic): inp_norm_data[0]->bExists * |
1435 | | * TN (tautomeric non-isotopic): inp_norm_data[1]->bExists * |
1436 | | * BI (non-tautomeric isotopic): inp_norm_data[0]->bExists && * |
1437 | | * inp_norm_data[0]->bHasIsotopicLayer * |
1438 | | * TI (tautomeric isotopic): inp_norm_data[1]->bExists && * |
1439 | | * inp_norm_data[1]->bHasIsotopicLayer * |
1440 | | **************************************************************************/ |
1441 | | |
1442 | 65.8k | int bIsotopic, bTautomeric, bDisplayTaut, bHasIsotopicLayer, bFixedBondsTaut, m_max, m, nNumDisplayedFixedBondTaut = 0; /* djb-rwth: ignoring LLVM warning: variable used */ |
1443 | | |
1444 | 65.8k | for ( j = 0; |
1445 | 65.8k | ip->bDisplay && !sd->bUserQuitComponentDisplay && j < TAUT_NUM; |
1446 | 65.8k | j++) |
1447 | 0 | { |
1448 | 0 | if (inp_norm_data[j]->bExists && !inp_norm_data[j]->bDeleted) |
1449 | 0 | { |
1450 | 0 | bTautomeric = ( pINChI[i][j]->lenTautomer > 0 ); |
1451 | | /* same as (inp_norm_data[j]->bTautomeric > 0) */ |
1452 | | |
1453 | | /* If requested tautomeric and no tautmerism found then do not say mobile or fixed H. 2004-10-27 */ |
1454 | 0 | bDisplayTaut = ( !( ip->nMode & REQ_MODE_BASIC ) && !bTautomeric ) ? -1 : bTautomeric; |
1455 | 0 | bHasIsotopicLayer = ( inp_norm_data[j]->bHasIsotopicLayer > 0 ); |
1456 | |
|
1457 | 0 | for (k = 0; k <= bHasIsotopicLayer; k++) |
1458 | 0 | { |
1459 | 0 | bIsotopic = ( k > 0 ); |
1460 | 0 | m_max = inp_norm_data[j]->at_fixed_bonds && inp_norm_data[j]->bTautPreprocessed ? 1 : 0; |
1461 | 0 | for (m = m_max; 0 <= m; m--) |
1462 | 0 | { |
1463 | 0 | bFixedBondsTaut = ( m > 0 ); |
1464 | 0 | nNumDisplayedFixedBondTaut += bFixedBondsTaut; |
1465 | | /* display only one time */ |
1466 | | |
1467 | | /* Added number of components, added another format for a single component case - DCh */ |
1468 | 0 | if (cur_prep_inp_data->num_components > 1) |
1469 | 0 | { |
1470 | 0 | sprintf(szTitle, "%s Component #%d of %d, Structure #%ld%s%s.%s%s%s%s%s", |
1471 | 0 | bFixedBondsTaut ? "Preprocessed" : "Result for", |
1472 | 0 | i + 1, cur_prep_inp_data->num_components, num_inp, |
1473 | 0 | bDisplayTaut == 1 ? ", mobile H" : bDisplayTaut == 0 ? ", fixed H" : "", |
1474 | 0 | bIsotopic ? ", isotopic" : "", |
1475 | 0 | SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue), iINChI ? " (Reconnected)" : ""); |
1476 | 0 | } |
1477 | 0 | else |
1478 | 0 | { |
1479 | 0 | sprintf(szTitle, "%s Structure #%ld%s%s.%s%s%s%s%s", |
1480 | 0 | bFixedBondsTaut ? "Preprocessed" : "Result for", |
1481 | 0 | num_inp, |
1482 | 0 | bDisplayTaut == 1 ? ", mobile H" : bDisplayTaut == 0 ? ", fixed H" : "", |
1483 | 0 | bIsotopic ? ", isotopic" : "", |
1484 | 0 | SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue), iINChI ? " (Reconnected)" : ""); |
1485 | 0 | } |
1486 | |
|
1487 | | #if defined (TARGET_EXE_STANDALONE) && defined(_WIN32) |
1488 | | if (bFixedBondsTaut && nNumDisplayedFixedBondTaut != 1) |
1489 | | { |
1490 | | continue; |
1491 | | } |
1492 | | if (ip->bDisplay) |
1493 | | { |
1494 | | if (bFixedBondsTaut) |
1495 | | { |
1496 | | err_display = DisplayStructure( pCG, |
1497 | | inp_norm_data[j]->at_fixed_bonds, |
1498 | | inp_norm_data[j]->num_at, |
1499 | | NULL, /* OAD_Polymer *polymer, */ |
1500 | | inp_norm_data[j]->num_removed_H, |
1501 | | 0 /*bAdd_DT_to_num_H*/, |
1502 | | inp_norm_data[j]->nNumRemovedProtons, |
1503 | | inp_norm_data[j]->nNumRemovedProtonsIsotopic, |
1504 | | bHasIsotopicLayer, |
1505 | | j, |
1506 | | NULL, |
1507 | | NULL, |
1508 | | ip->bAbcNumbers, |
1509 | | &ip->dp, |
1510 | | ip->nMode, |
1511 | | szTitle ); |
1512 | | } |
1513 | | else |
1514 | | { |
1515 | | err_display = DisplayStructure( pCG, |
1516 | | inp_norm_data[j]->at, |
1517 | | inp_norm_data[j]->num_at, |
1518 | | NULL, /* OAD_Polymer *polymer, */ |
1519 | | 0, |
1520 | | 0 /*bAdd_DT_to_num_H*/, |
1521 | | 0, |
1522 | | NULL, |
1523 | | k, |
1524 | | j, |
1525 | | pINChI[i], |
1526 | | pINChI_Aux[i], |
1527 | | ip->bAbcNumbers, |
1528 | | &ip->dp, |
1529 | | ip->nMode, szTitle ); |
1530 | | } |
1531 | | if ((sd->bUserQuitComponentDisplay = (err_display == ESC_KEY ))) /* djb-rwth: addressing LLVM warning */ |
1532 | | { |
1533 | | break; |
1534 | | } |
1535 | | } |
1536 | | #endif |
1537 | | #ifdef TARGET_LIB_FOR_WINCHI |
1538 | | |
1539 | | if (DRAWDATA && !bFixedBondsTaut) |
1540 | | { |
1541 | | struct DrawData vDrawData; |
1542 | | vDrawData.pWindowData = |
1543 | | CreateWinData_( pCG, |
1544 | | inp_norm_data[j]->at, |
1545 | | inp_norm_data[j]->num_at, |
1546 | | 0, |
1547 | | 0 /* bAdd_DT_to_num_H */, |
1548 | | 0, |
1549 | | NULL, |
1550 | | k, |
1551 | | j, |
1552 | | pINChI[i], |
1553 | | pINChI_Aux[i], |
1554 | | ip->bAbcNumbers, |
1555 | | &ip->dp, |
1556 | | ip->nMode ); |
1557 | | |
1558 | | if (vDrawData.pWindowData != NULL) |
1559 | | { |
1560 | | int nType; |
1561 | | vDrawData.nComponent = i + 1; |
1562 | | if (bTautomeric == 0) |
1563 | | nType = ( bIsotopic == 0 ) ? COMPONENT_BN |
1564 | | : COMPONENT_BI; |
1565 | | else |
1566 | | nType = ( bIsotopic == 0 ) ? COMPONENT_TN |
1567 | | : COMPONENT_TI; |
1568 | | vDrawData.nType = nType; |
1569 | | |
1570 | | vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */ |
1571 | | vDrawData.szTitle = inchi__strdup( szTitle ); |
1572 | | vDrawData.pWindowData->szTitle = inchi__strdup( szTitle ); |
1573 | | DRAWDATA( &vDrawData ); |
1574 | | } |
1575 | | } |
1576 | | else if (DRAWDATA && bFixedBondsTaut) |
1577 | | { |
1578 | | struct DrawData vDrawData; |
1579 | | if (( ip->bCompareComponents & CMP_COMPONENTS ) && |
1580 | | !( ip->bCompareComponents & CMP_COMPONENTS_NONTAUT ) && |
1581 | | !bIsotopic == !inp_norm_data[j]->bHasIsotopicLayer) |
1582 | | { |
1583 | | |
1584 | | vDrawData.pWindowData = |
1585 | | CreateWinData_( pCG, |
1586 | | inp_norm_data[j]->at_fixed_bonds, |
1587 | | inp_norm_data[j]->num_at, |
1588 | | inp_norm_data[j]->num_removed_H, |
1589 | | 0 /* bAdd_DT_to_num_H */, |
1590 | | inp_norm_data[j]->nNumRemovedProtons, |
1591 | | inp_norm_data[j]->nNumRemovedProtonsIsotopic, |
1592 | | k, |
1593 | | j, |
1594 | | NULL, |
1595 | | NULL, |
1596 | | ip->bAbcNumbers, |
1597 | | &ip->dp, |
1598 | | ip->nMode ); |
1599 | | } |
1600 | | else |
1601 | | { |
1602 | | continue; |
1603 | | } |
1604 | | if (vDrawData.pWindowData != NULL) |
1605 | | { |
1606 | | vDrawData.nComponent = i + 1; |
1607 | | vDrawData.nType = COMPONENT_ORIGINAL_PREPROCESSED; |
1608 | | vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */ |
1609 | | vDrawData.szTitle = inchi__strdup( szTitle ); |
1610 | | vDrawData.pWindowData->szTitle = inchi__strdup( szTitle ); |
1611 | | DRAWDATA( &vDrawData ); |
1612 | | } |
1613 | | } |
1614 | | #endif |
1615 | 0 | } |
1616 | 0 | } |
1617 | 0 | } |
1618 | 0 | } |
1619 | | |
1620 | | /* Save normalized components for composite display */ |
1621 | 65.8k | if ( /*ip->bDisplayCompositeResults && */ |
1622 | 65.8k | all_inp_norm_data |
1623 | 65.8k | ) |
1624 | 24.2k | { |
1625 | 72.6k | for (j = 0; j < TAUT_NUM; j++) |
1626 | 48.4k | { |
1627 | 48.4k | if (inp_norm_data[j]->bExists) |
1628 | 47.9k | { |
1629 | 47.9k | all_inp_norm_data[i][j] = *inp_norm_data[j]; |
1630 | 47.9k | memset( inp_norm_data[j], 0, sizeof( *inp_norm_data[0] ) ); /* djb-rwth: memset_s C11/Annex K variant? */ |
1631 | 47.9k | } |
1632 | 48.4k | } |
1633 | 24.2k | } |
1634 | 65.8k | } |
1635 | | |
1636 | | /* #endif */ /* } COMPILE_ANSI_ONLY */ |
1637 | | |
1638 | | |
1639 | 65.8k | if (nRet) |
1640 | 1 | { |
1641 | 1 | nRet = TreatErrorsInCreateOneComponentINChI( sd, ip, |
1642 | 1 | cur_prep_inp_data, |
1643 | 1 | i, num_inp, inp_file, |
1644 | 1 | log_file, out_file, prb_file ); |
1645 | 1 | break; |
1646 | 1 | } |
1647 | 65.8k | } |
1648 | | /**************************************************************************/ |
1649 | | /* */ |
1650 | | /* */ |
1651 | | /* E N D O F T H E M A I N C Y C L E P R O C E S S I N G */ |
1652 | | /* */ |
1653 | | /* C O M P O N E N T S O N E B Y O N E */ |
1654 | | /* */ |
1655 | | /* */ |
1656 | | /**************************************************************************/ |
1657 | | |
1658 | 41.8k | exit_cycle: |
1659 | 41.8k | switch (nRet) |
1660 | 41.8k | { |
1661 | 0 | case _IS_FATAL: |
1662 | 1 | case _IS_ERROR: |
1663 | 1 | break; |
1664 | 41.8k | default: |
1665 | | |
1666 | | /* #ifndef COMPILE_ANSI_ONLY *//* { */ |
1667 | | /* composite results picture(s) */ |
1668 | 41.8k | if (all_inp_norm_data) |
1669 | 237 | { |
1670 | 237 | CreateCompositeNormAtom( composite_norm_data, |
1671 | 237 | all_inp_norm_data, |
1672 | 237 | prep_inp_data[iINChI].num_components ); |
1673 | | /* |
1674 | | for ( i = 0; i < prep_inp_data[iINChI].num_components; i ++ ) { |
1675 | | for ( k = 0; k < TAUT_NUM; k ++ ) { |
1676 | | FreeInpAtomData( &all_inp_norm_data[i][k] ); |
1677 | | } |
1678 | | } |
1679 | | inchi_free( all_inp_norm_data ); |
1680 | | all_inp_norm_data = NULL; |
1681 | | */ |
1682 | 237 | } |
1683 | | /* #endif */ /* } COMPILE_ANSI_ONLY */ |
1684 | | |
1685 | 41.8k | break; |
1686 | 41.8k | } |
1687 | | |
1688 | | /*#ifndef COMPILE_ANSI_ONLY*/ /* { */ |
1689 | | |
1690 | | /* avoid memory leaks in case of error */ |
1691 | 41.8k | if (all_inp_norm_data) |
1692 | 238 | { |
1693 | 24.4k | for (i = 0; i < prep_inp_data[iINChI].num_components; i++) |
1694 | 24.2k | { |
1695 | 72.6k | for (k = 0; k < TAUT_NUM; k++) |
1696 | 48.4k | { |
1697 | 48.4k | FreeInpAtomData( &all_inp_norm_data[i][k] ); |
1698 | 48.4k | } |
1699 | 24.2k | } |
1700 | 238 | inchi_free( all_inp_norm_data ); |
1701 | 238 | all_inp_norm_data = NULL; |
1702 | 238 | } |
1703 | | /*#endif */ /* } COMPILE_ANSI_ONLY */ |
1704 | | |
1705 | 41.8k | FreeInpAtomData( inp_cur_data ); |
1706 | 125k | for (i = 0; i < TAUT_NUM; i++) |
1707 | 83.6k | { |
1708 | 83.6k | FreeInpAtomData( inp_norm_data[i] ); |
1709 | 83.6k | } |
1710 | | |
1711 | | |
1712 | 41.8k | exit_function: |
1713 | | |
1714 | 41.8k | return nRet; |
1715 | 41.8k | } |
1716 | | |
1717 | | |
1718 | | /**************************************************************************** |
1719 | | Generate InChI for one connected component |
1720 | | (of possibly multi-component structure) |
1721 | | ****************************************************************************/ |
1722 | | int CreateOneComponentINChI( CANON_GLOBALS *pCG, |
1723 | | INCHI_CLOCK *ic, |
1724 | | STRUCT_DATA *sd, |
1725 | | INPUT_PARMS *ip, |
1726 | | INP_ATOM_DATA *inp_cur_data, |
1727 | | ORIG_ATOM_DATA *orig_inp_data, |
1728 | | PINChI2 *pINChI, |
1729 | | PINChI_Aux2 *pINChI_Aux, |
1730 | | int iINChI, |
1731 | | int i, |
1732 | | long num_inp, |
1733 | | INP_ATOM_DATA **inp_norm_data, |
1734 | | NORM_CANON_FLAGS *pncFlags, |
1735 | | INCHI_IOSTREAM *log_file ) |
1736 | 65.8k | { |
1737 | 65.8k | inchiTime ulTStart, ulTEnd, *pulTEnd = NULL; |
1738 | 65.8k | int k, num_at, ret = 0; |
1739 | 65.8k | int bOrigCoord; |
1740 | 65.8k | INCHI_MODE bTautFlags = ip->bTautFlags; |
1741 | 65.8k | INCHI_MODE bTautFlagsDone = ( ip->bTautFlagsDone | sd->bTautFlagsDone[INCHI_BAS] ); |
1742 | 65.8k | INChI *cur_INChI[TAUT_NUM]; |
1743 | 65.8k | INChI_Aux *cur_INChI_Aux[TAUT_NUM]; |
1744 | 65.8k | long lElapsedTime; |
1745 | | |
1746 | 65.8k | InchiTimeGet( &ulTStart ); |
1747 | 65.8k | bOrigCoord = |
1748 | 65.8k | !( ip->bINChIOutputOptions & ( INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO ) ); |
1749 | | |
1750 | 197k | for (k = 0; k < TAUT_NUM; k++) |
1751 | 131k | { |
1752 | 131k | cur_INChI[k] = NULL; |
1753 | 131k | cur_INChI_Aux[k] = NULL; |
1754 | 131k | } |
1755 | | |
1756 | | /* Allocate memory for non-tautomeric (k=0) and tautomeric (k=1) results */ |
1757 | 197k | for (k = 0; k < TAUT_NUM; k++) |
1758 | 131k | { |
1759 | | /* djb-rwth: introducing variables for correct nAllocMode expression */ |
1760 | 131k | int nAM1 = 0, nAM2 = 0; |
1761 | | |
1762 | 131k | if (k == TAUT_YES) |
1763 | 65.8k | nAM1 = REQ_MODE_TAUT; |
1764 | | |
1765 | 131k | if (bTautFlagsDone & (TG_FLAG_FOUND_ISOTOPIC_H_DONE | TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE)) |
1766 | 120 | nAM2 = ip->nMode & REQ_MODE_ISO; |
1767 | | |
1768 | 131k | int nAllocMode = nAM1 | nAM2; /* djb-rwth: original sequence of bit-wise operations had to be rewritten */ |
1769 | | |
1770 | | |
1771 | 131k | if ((k == TAUT_NON && ( ip->nMode & REQ_MODE_BASIC )) || |
1772 | 131k | (k == TAUT_YES && ( ip->nMode & REQ_MODE_TAUT ))) /* djb-rwth: addressing LLVM warning */ |
1773 | 89.9k | { |
1774 | | /* alloc INChI and INChI_Aux */ |
1775 | 89.9k | cur_INChI[k] = Alloc_INChI( inp_cur_data->at, |
1776 | 89.9k | inp_cur_data->num_at, |
1777 | 89.9k | &inp_cur_data->num_bonds, |
1778 | 89.9k | &inp_cur_data->num_isotopic, |
1779 | 89.9k | nAllocMode ); |
1780 | | |
1781 | 89.9k | cur_INChI_Aux[k] = Alloc_INChI_Aux( inp_cur_data->num_at, |
1782 | 89.9k | inp_cur_data->num_isotopic, |
1783 | 89.9k | nAllocMode, |
1784 | 89.9k | bOrigCoord ); |
1785 | 89.9k | if (cur_INChI_Aux[k]) |
1786 | 89.9k | { |
1787 | 89.9k | cur_INChI_Aux[k]->bIsIsotopic = inp_cur_data->num_isotopic; |
1788 | 89.9k | } |
1789 | | /* alloc memory for the output structure: non-tautomeric and tautomeric (for displaying) */ |
1790 | | |
1791 | 89.9k | CreateInpAtomData( inp_norm_data[k], inp_cur_data->num_at, k ); |
1792 | 89.9k | } |
1793 | 41.7k | else |
1794 | 41.7k | { |
1795 | 41.7k | FreeInpAtomData( inp_norm_data[k] ); |
1796 | 41.7k | } |
1797 | 131k | } |
1798 | | |
1799 | 65.8k | lElapsedTime = InchiTimeElapsed( ic, &ulTStart ); |
1800 | 65.8k | if (ip->msec_MaxTime) |
1801 | 0 | { |
1802 | 0 | ip->msec_LeftTime -= lElapsedTime; |
1803 | 0 | } |
1804 | 65.8k | sd->ulStructTime += lElapsedTime; |
1805 | | |
1806 | | /*^^^#if ( !defined( TARGET_LIB_FOR_WINCHI ) && !defined( TARGET_API_LIB ) ) */ |
1807 | | #if ( !defined( TARGET_LIB_FOR_WINCHI ) && !defined( TARGET_API_LIB ) && !defined(TARGET_EXE_STANDALONE) ) |
1808 | | #endif |
1809 | | |
1810 | | /****************************************************** |
1811 | | * |
1812 | | * Get one component canonical numberings, etc. |
1813 | | * |
1814 | | ******************************************************/ |
1815 | | |
1816 | | /* Create_INChI() return value: |
1817 | | * num_at <= 0: error code |
1818 | | * num_at > 0: number of atoms (excluding terminal hydrogen atoms) |
1819 | | * inp_norm_data[0] => non-tautomeric, inp_norm_data[1] => tautomeric */ |
1820 | | |
1821 | 65.8k | InchiTimeGet( &ulTStart ); |
1822 | | |
1823 | 65.8k | if (ip->msec_MaxTime) |
1824 | 0 | { |
1825 | 0 | ulTEnd = ulTStart; |
1826 | 0 | pulTEnd = &ulTEnd; |
1827 | 0 | if (ip->msec_LeftTime > 0) |
1828 | 0 | { |
1829 | 0 | InchiTimeAddMsec( ic, pulTEnd, ip->msec_LeftTime ); |
1830 | 0 | } |
1831 | 0 | } |
1832 | | |
1833 | 65.8k | num_at = Create_INChI( pCG, ic, ip, |
1834 | 65.8k | cur_INChI, cur_INChI_Aux, |
1835 | 65.8k | orig_inp_data/* not used */, |
1836 | 65.8k | inp_cur_data->at, inp_norm_data, inp_cur_data->num_at, |
1837 | 65.8k | ip->nMode, |
1838 | 65.8k | &bTautFlags, &bTautFlagsDone, |
1839 | 65.8k | pulTEnd, NULL, sd->pStrErrStruct ); |
1840 | | |
1841 | 65.8k | SetConnectedComponentNumber( inp_cur_data->at, inp_cur_data->num_at, i + 1 ); |
1842 | | /* NB: normalization alters structure component number */ |
1843 | | |
1844 | 197k | for (k = 0; k < TAUT_NUM; k++) |
1845 | 131k | { |
1846 | 131k | if (cur_INChI_Aux[k] && cur_INChI_Aux[k]->nNumberOfAtoms > 0) |
1847 | 89.6k | { |
1848 | 89.6k | pncFlags->bNormalizationFlags[iINChI][k] |= |
1849 | 89.6k | cur_INChI_Aux[k]->bNormalizationFlags; |
1850 | 89.6k | pncFlags->bTautFlags[iINChI][k] |= |
1851 | 89.6k | cur_INChI_Aux[k]->bTautFlags; |
1852 | 89.6k | pncFlags->bTautFlagsDone[iINChI][k] |= |
1853 | 89.6k | cur_INChI_Aux[k]->bTautFlagsDone; |
1854 | 89.6k | pncFlags->nCanonFlags[iINChI][k] |= |
1855 | 89.6k | cur_INChI_Aux[k]->nCanonFlags; |
1856 | 89.6k | } |
1857 | 131k | } |
1858 | | |
1859 | | /* Detect errors */ |
1860 | 65.8k | if (num_at < 0) |
1861 | 1 | { |
1862 | 1 | sd->nErrorCode = num_at; |
1863 | 1 | } |
1864 | 65.8k | else if (num_at == 0) |
1865 | 0 | { |
1866 | 0 | sd->nErrorCode = -1; |
1867 | 0 | } |
1868 | 65.8k | else if (cur_INChI[TAUT_NON] && cur_INChI[TAUT_NON]->nErrorCode) |
1869 | 0 | { /* non-tautomeric error */ |
1870 | 0 | sd->nErrorCode = cur_INChI[TAUT_NON]->nErrorCode; |
1871 | 0 | } |
1872 | 65.8k | else if (cur_INChI[TAUT_YES] && cur_INChI[TAUT_YES]->nErrorCode) |
1873 | 0 | { /* tautomeric error */ |
1874 | 0 | sd->nErrorCode = cur_INChI[TAUT_YES]->nErrorCode; |
1875 | 0 | } |
1876 | | |
1877 | | |
1878 | | #if ( bRELEASE_VERSION == 0 ) |
1879 | | if (cur_INChI[TAUT_NON]) sd->bExtract |= cur_INChI[TAUT_NON]->bExtract; |
1880 | | if (cur_INChI[TAUT_YES]) sd->bExtract |= cur_INChI[TAUT_YES]->bExtract; |
1881 | | if (( TG_FLAG_TEST_TAUT3_SALTS_DONE & bTautFlagsDone )) |
1882 | | { |
1883 | | sd->bExtract |= EXTR_TEST_TAUT3_SALTS_DONE; |
1884 | | } |
1885 | | #endif |
1886 | | |
1887 | | /* Detect and store stereo warnings */ |
1888 | 65.8k | if (!sd->nErrorCode) |
1889 | 65.8k | GetProcessingWarningsOneComponentInChI( cur_INChI, inp_norm_data, sd, ip->bNoWarnings ); |
1890 | | |
1891 | 65.8k | lElapsedTime = InchiTimeElapsed( ic, &ulTStart ); |
1892 | 65.8k | if (ip->msec_MaxTime) |
1893 | 0 | { |
1894 | 0 | ip->msec_LeftTime -= lElapsedTime; |
1895 | 0 | } |
1896 | 65.8k | sd->ulStructTime += lElapsedTime; |
1897 | | |
1898 | | #if !defined(TARGET_API_LIB) && !defined(COMPILE_ANSI_ONLY) |
1899 | | /* Display the results */ |
1900 | | if (ip->bDisplay) |
1901 | | { |
1902 | | eat_keyboard_input( ); |
1903 | | } |
1904 | | #endif |
1905 | | |
1906 | | /* a) No matter what happened save the allocated INChI pointers */ |
1907 | | /* save the INChI of the current component */ |
1908 | | |
1909 | 65.8k | InchiTimeGet( &ulTStart ); |
1910 | 197k | for (k = 0; k < TAUT_NUM; k++) |
1911 | 131k | { |
1912 | 131k | pINChI[i][k] = cur_INChI[k]; |
1913 | 131k | pINChI_Aux[i][k] = cur_INChI_Aux[k]; |
1914 | 131k | cur_INChI[k] = NULL; |
1915 | 131k | cur_INChI_Aux[k] = NULL; |
1916 | 131k | } |
1917 | | |
1918 | | /* b) Count one component structure and/or INChI results only |
1919 | | if there was no error |
1920 | | Set inp_norm_data[j]->num_removed_H = number of removed explicit H |
1921 | | */ |
1922 | | |
1923 | 65.8k | if (!sd->nErrorCode) |
1924 | 65.8k | { |
1925 | | /* find where the current processed structure is located */ |
1926 | 65.8k | int cur_is_in_non_taut = ( pINChI[i][TAUT_NON] && |
1927 | 65.8k | pINChI[i][TAUT_NON]->nNumberOfAtoms > 0 ); |
1928 | 65.8k | int cur_is_in_taut = ( pINChI[i][TAUT_YES] && |
1929 | 65.8k | pINChI[i][TAUT_YES]->nNumberOfAtoms > 0 ); |
1930 | | |
1931 | 65.8k | int cur_is_non_taut = (cur_is_in_non_taut && 0 == pINChI[i][TAUT_NON]->lenTautomer) || |
1932 | 65.8k | (cur_is_in_taut && 0 == pINChI[i][TAUT_YES]->lenTautomer); /* djb-rwth: addressing LLVM warnings */ |
1933 | 65.8k | int cur_is_taut = cur_is_in_taut && 0 < pINChI[i][TAUT_YES]->lenTautomer; |
1934 | | |
1935 | | /* |
1936 | | sd->bTautFlags[iINChI] |= bTautFlags; |
1937 | | sd->bTautFlagsDone[iINChI] |= bTautFlagsDone; |
1938 | | */ |
1939 | | |
1940 | 65.8k | if (cur_is_non_taut + cur_is_taut) |
1941 | 65.8k | { |
1942 | | /* count tautomeric and non-tautomeric components of the structures */ |
1943 | 65.8k | int j1 = cur_is_in_non_taut ? TAUT_NON : TAUT_YES; |
1944 | 65.8k | int j2 = cur_is_in_taut ? TAUT_YES : TAUT_NON; |
1945 | 65.8k | int j; |
1946 | 65.8k | sd->num_non_taut[iINChI] += cur_is_non_taut; |
1947 | 65.8k | sd->num_taut[iINChI] += cur_is_taut; |
1948 | 155k | for (j = j1; j <= j2; j++) |
1949 | 89.6k | { |
1950 | 89.6k | int bIsotopic = ( pINChI[i][j]->nNumberOfIsotopicAtoms || |
1951 | 89.6k | pINChI[i][j]->nNumberOfIsotopicTGroups || |
1952 | 89.6k | (pINChI[i][j]->nPossibleLocationsOfIsotopicH && pINChI[i][j]->nPossibleLocationsOfIsotopicH[0] > 1) ); /* djb-rwth: addressing LLVM warning */ |
1953 | 89.6k | if (pINChI_Aux[i][j] && (j == TAUT_YES)) /* djb-rwth: fixing a NULL pointer dereference */ |
1954 | 65.8k | { |
1955 | 65.8k | bIsotopic |= ( 0 < pINChI_Aux[i][j]->nNumRemovedIsotopicH[0] + |
1956 | 65.8k | pINChI_Aux[i][j]->nNumRemovedIsotopicH[1] + |
1957 | 65.8k | pINChI_Aux[i][j]->nNumRemovedIsotopicH[2] ); |
1958 | 65.8k | } |
1959 | | |
1960 | 89.6k | inp_norm_data[j]->bExists = 1; /* j=0: non-taut exists, j=1: taut exists */ |
1961 | 89.6k | inp_norm_data[j]->bHasIsotopicLayer = bIsotopic; |
1962 | | /*inp_norm_data[j]->num_removed_H = inp_norm_data[j]->num_at - num_at;*/ |
1963 | 89.6k | } |
1964 | 65.8k | } |
1965 | 65.8k | } |
1966 | | |
1967 | | /* return (sd->nErrorCode==CT_OUT_OF_RAM || sd->nErrorCode==CT_USER_QUIT_ERR)? _IS_FATAL : |
1968 | | sd->nErrorCode? _IS_ERROR : 0; */ |
1969 | | |
1970 | 65.8k | if (sd->nErrorCode == CT_OUT_OF_RAM || sd->nErrorCode == CT_USER_QUIT_ERR) |
1971 | 0 | { |
1972 | 0 | ret = _IS_FATAL; |
1973 | 0 | } |
1974 | 65.8k | else if (sd->nErrorCode) |
1975 | 1 | { |
1976 | 1 | ret = _IS_ERROR; |
1977 | 1 | } |
1978 | | |
1979 | 65.8k | lElapsedTime = InchiTimeElapsed( ic, &ulTStart ); |
1980 | 65.8k | if (ip->msec_MaxTime) |
1981 | 0 | { |
1982 | 0 | ip->msec_LeftTime -= lElapsedTime; |
1983 | 0 | } |
1984 | 65.8k | sd->ulStructTime += lElapsedTime; |
1985 | | |
1986 | 65.8k | return ret; |
1987 | 65.8k | } |
1988 | | |
1989 | | |
1990 | | /**************************************************************************** |
1991 | | Extended-functionality version of ProcessOneStructure |
1992 | | |
1993 | | able to handle both polymer related and unrelated pseudoelement atoms |
1994 | | and to perform advanced polymer treatment (v. 1.06+) |
1995 | | ****************************************************************************/ |
1996 | | int ProcessOneStructureEx( struct tagINCHI_CLOCK *ic, |
1997 | | struct tagCANON_GLOBALS *CG, |
1998 | | STRUCT_DATA *sd, |
1999 | | INPUT_PARMS *ip, |
2000 | | char *szTitle, |
2001 | | PINChI2 *pINChI2[INCHI_NUM], |
2002 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
2003 | | INCHI_IOSTREAM *inp_file, |
2004 | | INCHI_IOSTREAM *log_file, |
2005 | | INCHI_IOSTREAM *out_file, |
2006 | | INCHI_IOSTREAM *prb_file, |
2007 | | ORIG_ATOM_DATA *orig_inp_data, |
2008 | | ORIG_ATOM_DATA *prep_inp_data, |
2009 | | long num_inp, |
2010 | | INCHI_IOS_STRING *strbuf, |
2011 | | unsigned char save_opt_bits ) |
2012 | 0 | { |
2013 | 0 | int ret = _IS_OKAY; |
2014 | 0 | char *sinchi_noedits=NULL, *saux_noedits=NULL; |
2015 | | |
2016 | | |
2017 | | /* PREPROCESS */ |
2018 | |
|
2019 | | #if (BUILD_WITH_ENG_OPTIONS==1) |
2020 | | #if ALLOW_SUBSTRUCTURE_FILTERING==1 |
2021 | | if (ip->bFilterSS) |
2022 | | { |
2023 | | int present, ok = 0; |
2024 | | |
2025 | | present = OrigAtData_CheckForSubstructure(orig_inp_data); |
2026 | | |
2027 | | if (ip->bFilterSS == 1 && present) ok = 1; |
2028 | | else if (ip->bFilterSS == -1 && !present) ok = 1; |
2029 | | |
2030 | | if (!ok) |
2031 | | { |
2032 | | inchi_ios_eprint(log_file, "Warning (Skip record which does not pass substructure presence/absence filter) structure #%ld.%s%s%s%s\n", |
2033 | | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue)); |
2034 | | return _IS_SKIP; |
2035 | | } |
2036 | | } |
2037 | | #endif |
2038 | | #endif |
2039 | | |
2040 | | /* Preprocess Polymer CRUs (collect frame shift info and edit the original input accordingly) */ |
2041 | 0 | ret = PreprocessPolymerCRUData( ic, CG, sd, ip, szTitle, |
2042 | 0 | pINChI2, pINChI_Aux2, |
2043 | 0 | inp_file, log_file, out_file, prb_file, |
2044 | 0 | orig_inp_data, prep_inp_data, |
2045 | 0 | num_inp, strbuf, save_opt_bits, |
2046 | 0 | &sinchi_noedits, &saux_noedits); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ |
2047 | | |
2048 | | /* CALCULATE INCHI */ |
2049 | | |
2050 | | /* Perform calculation as usual either for untouched (modes POLYMERS_LEGACY and POLYMERS_LEGACY_PLUS) |
2051 | | or just edited, probably (mode POLYMERS_MODERN) structure as passed in orig_inp_data |
2052 | | */ |
2053 | 0 | ret = ProcessOneStructureExCore( ic, CG, sd, ip, szTitle, |
2054 | 0 | pINChI2, pINChI_Aux2, |
2055 | 0 | inp_file, log_file, out_file, prb_file, |
2056 | 0 | orig_inp_data, prep_inp_data, |
2057 | 0 | num_inp, strbuf, save_opt_bits ); |
2058 | |
|
2059 | 0 | if (ip->bINChIOutputOptions2 & INCHI_OUT_INCHI_GEN_ERROR) |
2060 | 0 | { |
2061 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2062 | 0 | { |
2063 | 0 | if (ip->bINChIOutputOptions & INCHI_OUT_STDINCHI) |
2064 | 0 | { |
2065 | 0 | inchi_ios_eprint(out_file, "InChI=1S//\n"); |
2066 | 0 | } |
2067 | 0 | else |
2068 | 0 | { |
2069 | 0 | inchi_ios_eprint(out_file, "InChI=1//\n"); |
2070 | 0 | } |
2071 | 0 | } |
2072 | 0 | } |
2073 | | |
2074 | | /* Post-process: add AuxInfo for a very unedited original structure */ |
2075 | 0 | if (ret != _IS_FATAL && ret != _IS_ERROR) |
2076 | 0 | { |
2077 | 0 | if (!(ip->bINChIOutputOptions & INCHI_OUT_NO_AUX_INFO) && |
2078 | 0 | out_file->s.pStr && strstr(out_file->s.pStr, "AuxInfo=" ) && |
2079 | 0 | saux_noedits && strstr(saux_noedits, "AuxInfo=") ) |
2080 | 0 | { |
2081 | 0 | char *pp = out_file->s.pStr; |
2082 | 0 | if (saux_noedits[8]) |
2083 | 0 | { |
2084 | 0 | remove_one_lf(pp); |
2085 | 0 | out_file->s.nUsedLength = strlen(out_file->s.pStr); |
2086 | 0 | inchi_ios_eprint(out_file, "/U/%-s\n", saux_noedits +8); |
2087 | 0 | } |
2088 | 0 | } |
2089 | 0 | } |
2090 | |
|
2091 | 0 | inchi_free(sinchi_noedits); |
2092 | 0 | inchi_free(saux_noedits); |
2093 | | |
2094 | | |
2095 | | #ifdef TARGET_LIB_FOR_WINCHI |
2096 | | |
2097 | | push_to_winchi_text_window(out_file); |
2098 | | |
2099 | | if (sd->pStrErrStruct && FWPUSH) |
2100 | | { |
2101 | | FWPUSH(sd->pStrErrStruct); |
2102 | | } |
2103 | | inchi_ios_flush(out_file); |
2104 | | #endif |
2105 | |
|
2106 | 0 | return ret; |
2107 | 0 | } |
2108 | | |
2109 | | |
2110 | | /**************************************************************************** |
2111 | | Special treatment for polymers: perform CRU frame shift analysis |
2112 | | and make related edits in orig_inp_data whenever applicable |
2113 | | ****************************************************************************/ |
2114 | | int PreprocessPolymerCRUData( struct tagINCHI_CLOCK *ic, |
2115 | | struct tagCANON_GLOBALS *CG, |
2116 | | STRUCT_DATA *sd, |
2117 | | INPUT_PARMS *ip, |
2118 | | char *szTitle, |
2119 | | PINChI2 *pINChI2[INCHI_NUM], |
2120 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
2121 | | INCHI_IOSTREAM *inp_file, |
2122 | | INCHI_IOSTREAM *log_file, |
2123 | | INCHI_IOSTREAM *out_file, |
2124 | | INCHI_IOSTREAM *prb_file, |
2125 | | ORIG_ATOM_DATA *orig_inp_data, |
2126 | | ORIG_ATOM_DATA *prep_inp_data, |
2127 | | long num_inp, |
2128 | | INCHI_IOS_STRING *strbuf, |
2129 | | unsigned char save_opt_bits, |
2130 | | char **sinchi_noedits, |
2131 | | char **saux_noedits) |
2132 | 0 | { |
2133 | 0 | int ret = _IS_OKAY; |
2134 | 0 | char *sinchi_105p = NULL, *saux_105p = NULL; |
2135 | 0 | OAD_StructureEdits edits_unit_frame_shift, *ed_fs = &edits_unit_frame_shift; |
2136 | 0 | OAD_StructureEdits edits_unit_folding, *ed_fold = &edits_unit_folding; |
2137 | | |
2138 | 0 | OAD_StructureEdits_Init(ed_fold); |
2139 | 0 | OAD_StructureEdits_Init(ed_fs); |
2140 | |
|
2141 | 0 | if (orig_inp_data) |
2142 | 0 | { |
2143 | 0 | orig_inp_data->valid_polymer = 0; |
2144 | 0 | if (orig_inp_data->polymer) |
2145 | 0 | { |
2146 | 0 | orig_inp_data->polymer->treat = ip->bPolymers; |
2147 | 0 | if (orig_inp_data->polymer->treat != POLYMERS_NO) |
2148 | 0 | { |
2149 | 0 | orig_inp_data->valid_polymer = 1; |
2150 | |
|
2151 | 0 | if (orig_inp_data->polymer->treat == POLYMERS_MODERN) |
2152 | 0 | { |
2153 | 0 | int n_done, n_todo = 0, n_poly_zz = 0; /* djb-rwth: ignoring LLVM warning: variable used */ |
2154 | | |
2155 | | /* First, get InChI and AuxInfo for the unedited original input |
2156 | | (actually, we are interested in AuxInfo for original structure; |
2157 | | we then append it to the final result AuxInfo, in order to |
2158 | | preserve total reversibility (restoring the original structure ) */ |
2159 | 0 | ret = OAD_ProcessOneStructureNoEdits(ic, CG, sd, ip, szTitle, |
2160 | 0 | pINChI2, pINChI_Aux2, |
2161 | 0 | inp_file, log_file, out_file, prb_file, |
2162 | 0 | orig_inp_data, prep_inp_data, |
2163 | 0 | num_inp, strbuf, save_opt_bits, |
2164 | 0 | &n_poly_zz, |
2165 | 0 | sinchi_noedits, saux_noedits); |
2166 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2167 | 0 | { |
2168 | 0 | ret = _IS_WARNING; |
2169 | 0 | if (!ip->bNoWarnings) |
2170 | 0 | { |
2171 | 0 | AddErrorMessage(sd->pStrErrStruct, "CRU folding and frame shift analysis failed"); |
2172 | 0 | } |
2173 | 0 | goto exit_function; |
2174 | 0 | } |
2175 | 0 | if (n_poly_zz < 2) |
2176 | 0 | { |
2177 | | /* For now, CRU folding and frame shift analysis are only applicable to */ |
2178 | | /* CRU having both caps of indefinite nature, Zz */ |
2179 | 0 | goto exit_function; |
2180 | 0 | } |
2181 | | |
2182 | | |
2183 | | /* Prepare and perform CRU folding related edits */ |
2184 | 0 | if (ip->bFoldPolymerSRU != 0) |
2185 | 0 | { |
2186 | | /* Get interim 105+ flavour of InChI and AuxInfo and prepare */ |
2187 | 0 | int old_bFrameShiftScheme = ip->bFrameShiftScheme; |
2188 | 0 | ip->bFrameShiftScheme = FSS_STARS_CYCLED; |
2189 | 0 | ret = OAD_ProcessOneStructure105Plus(ic, CG, sd, ip, szTitle, |
2190 | 0 | pINChI2, pINChI_Aux2, |
2191 | 0 | inp_file, log_file, out_file, prb_file, |
2192 | 0 | orig_inp_data, prep_inp_data, |
2193 | 0 | num_inp, strbuf, save_opt_bits, |
2194 | 0 | &sinchi_105p, &saux_105p); |
2195 | 0 | ip->bFrameShiftScheme = old_bFrameShiftScheme; |
2196 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2197 | 0 | { |
2198 | 0 | ret = _IS_WARNING; |
2199 | 0 | if (!ip->bNoWarnings) |
2200 | 0 | { |
2201 | | /* AddErrorMessage(sd->pStrErrStruct, "CRU fold analysis failed");*/ |
2202 | 0 | ; |
2203 | 0 | } |
2204 | 0 | goto frame_shift; |
2205 | 0 | } |
2206 | | |
2207 | 0 | ret = OAD_Polymer_PrepareFoldCRUEdits( orig_inp_data, *sinchi_noedits, *saux_noedits, sinchi_105p, saux_105p, ed_fold); |
2208 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2209 | 0 | { |
2210 | 0 | if (!ip->bNoWarnings) |
2211 | 0 | { |
2212 | | /*AddErrorMessage(sd->pStrErrStruct, "CRU fold analysis failed");*/ |
2213 | 0 | ; |
2214 | 0 | } |
2215 | 0 | goto frame_shift; |
2216 | 0 | } |
2217 | 0 | if (ret == _IS_WARNING) |
2218 | 0 | { |
2219 | | /* inchi_ios_eprint(log_file, "Warning (CRU fold analysis failed) structure #%ld.%s%s%s%s\n", |
2220 | | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue));*/ |
2221 | 0 | ; |
2222 | 0 | } |
2223 | | /* else */ |
2224 | 0 | { |
2225 | | /* Proceed with CRU fold */ |
2226 | 0 | n_done = 0; /* djb-rwth: ignoring LLVM warning: variable used */ |
2227 | 0 | n_todo = ed_fold->del_atom->used + ed_fold->del_bond->used + ed_fold->new_bond->used + ed_fold->mod_bond->used; |
2228 | 0 | ed_fold->del_side_chains = 1; |
2229 | 0 | OAD_StructureEdits_DebugPrint(ed_fold); |
2230 | 0 | if (n_todo) |
2231 | 0 | { |
2232 | | /* Edit the original input data */ |
2233 | 0 | ed_fold->del_side_chains = 1; |
2234 | 0 | n_done = OAD_StructureEdits_Apply(sd, ip, orig_inp_data, ed_fold, &ret); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ |
2235 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2236 | 0 | { |
2237 | 0 | ret = _IS_WARNING; |
2238 | | /*inchi_ios_eprint(log_file, "Warning (CRU fold failed) structure #%ld.%s%s%s%s\n", |
2239 | | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue)); |
2240 | | */ |
2241 | 0 | if (!ip->bNoWarnings) |
2242 | 0 | { |
2243 | 0 | AddErrorMessage(sd->pStrErrStruct, "CRU folding failed"); |
2244 | 0 | } |
2245 | 0 | } |
2246 | 0 | else |
2247 | 0 | { |
2248 | 0 | if (!ip->bNoWarnings) |
2249 | 0 | { |
2250 | 0 | WarningMessage(sd->pStrErrStruct, "Atom(s) removed due to CRU folding"); |
2251 | 0 | } |
2252 | 0 | } |
2253 | 0 | } |
2254 | 0 | } |
2255 | 0 | } |
2256 | | |
2257 | 0 | frame_shift: ; |
2258 | | /* Prepare and perform frame shift related edits */ |
2259 | 0 | if (ip->bFrameShiftScheme != FSS_NONE) |
2260 | 0 | { |
2261 | | /* Clear buffers */ |
2262 | 0 | if (sinchi_105p) |
2263 | 0 | { |
2264 | 0 | inchi_free(sinchi_105p); |
2265 | 0 | } |
2266 | 0 | if (saux_105p) |
2267 | 0 | { |
2268 | 0 | inchi_free(saux_105p); |
2269 | 0 | } |
2270 | | /* Get interim 105+ flavour of InChI and AuxInfo (possibly 2nd time) */ |
2271 | 0 | ret = OAD_ProcessOneStructure105Plus(ic, CG, sd, ip, szTitle, |
2272 | 0 | pINChI2, pINChI_Aux2, |
2273 | 0 | inp_file, log_file, out_file, prb_file, |
2274 | 0 | orig_inp_data, prep_inp_data, |
2275 | 0 | num_inp, strbuf, save_opt_bits, |
2276 | 0 | &sinchi_105p, &saux_105p); |
2277 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2278 | 0 | { |
2279 | 0 | ret = _IS_WARNING; |
2280 | | /*inchi_ios_eprint(log_file, "Warning (Frame shift analysis failed) structure #%ld.%s%s%s%s\n", |
2281 | | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue));*/ |
2282 | 0 | if (!ip->bNoWarnings) |
2283 | 0 | { |
2284 | 0 | AddErrorMessage(sd->pStrErrStruct, "Frame shift analysis failed"); |
2285 | 0 | } |
2286 | 0 | goto exit_function; |
2287 | 0 | } |
2288 | | |
2289 | 0 | ret = OAD_Polymer_PrepareFrameShiftEdits( orig_inp_data, sinchi_105p, saux_105p, ed_fs); |
2290 | | |
2291 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) /* djb-rwth: logical operator corrected */ |
2292 | 0 | { |
2293 | 0 | ret = _IS_WARNING; |
2294 | | /*inchi_ios_eprint(log_file, "Warning (Frame shift analysis failed) structure #%ld.%s%s%s%s\n", |
2295 | | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue));*/ |
2296 | 0 | if (!ip->bNoWarnings) |
2297 | 0 | { |
2298 | 0 | AddErrorMessage(sd->pStrErrStruct, "Frame shift analysis failed"); |
2299 | 0 | } |
2300 | 0 | goto exit_function; |
2301 | 0 | } |
2302 | 0 | else |
2303 | 0 | { |
2304 | | /* OK, proceed with frame shift */ |
2305 | 0 | n_done = 0; /* djb-rwth: ignoring LLVM warning: variable used */ |
2306 | 0 | n_todo = ed_fs->del_atom->used + |
2307 | 0 | ed_fs->del_bond->used + ed_fs->new_bond->used + ed_fs->mod_bond->used + |
2308 | 0 | ed_fs->mod_coord->used; |
2309 | 0 | OAD_StructureEdits_DebugPrint(ed_fs); |
2310 | 0 | if (n_todo) |
2311 | 0 | { |
2312 | | /* Edit the original input data according to frame shift info */ |
2313 | 0 | n_done = OAD_StructureEdits_Apply(sd, ip, orig_inp_data, ed_fs, &ret); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ |
2314 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2315 | 0 | { |
2316 | 0 | ret = _IS_WARNING; |
2317 | | /*inchi_ios_eprint(log_file, "Warning (Frame shift failed) structure #%ld.%s%s%s%s\n", |
2318 | | num_inp, SDF_LBL_VAL(ip->pSdfLabel, ip->pSdfValue));*/ |
2319 | 0 | if (!ip->bNoWarnings) |
2320 | 0 | { |
2321 | 0 | AddErrorMessage(sd->pStrErrStruct, "Frame shift failed"); |
2322 | 0 | } |
2323 | 0 | } |
2324 | 0 | else |
2325 | 0 | { |
2326 | 0 | if (!ip->bNoWarnings) |
2327 | 0 | { |
2328 | 0 | WarningMessage(sd->pStrErrStruct, "Bond(s) rearranged due to CRU frame shift"); |
2329 | 0 | } |
2330 | 0 | } |
2331 | 0 | } |
2332 | 0 | } |
2333 | 0 | } /* if (ip->bFrameShiftScheme != FSS_NONE) */ |
2334 | | |
2335 | |
|
2336 | 0 | } /* if (orig_inp_data->polymer->treat == POLYMERS_MODERN) */ |
2337 | 0 | } |
2338 | | |
2339 | 0 | else /* orig_inp_data->polymer->treat == POLYMERS_NO) */ |
2340 | 0 | { |
2341 | | /*inchi_ios_eprint(log_file, "Ignore polymer data");*/ |
2342 | 0 | if (!ip->bNoWarnings) |
2343 | 0 | { |
2344 | 0 | AddErrorMessage(sd->pStrErrStruct, "Ignore polymer data"); |
2345 | 0 | } |
2346 | 0 | } |
2347 | 0 | } |
2348 | 0 | } |
2349 | | |
2350 | 0 | exit_function: |
2351 | 0 | if (sinchi_105p) |
2352 | 0 | { |
2353 | 0 | inchi_free(sinchi_105p); |
2354 | 0 | } |
2355 | 0 | if (saux_105p) |
2356 | 0 | { |
2357 | 0 | inchi_free(saux_105p); |
2358 | 0 | } |
2359 | 0 | OAD_StructureEdits_Clear(ed_fold); /* Clear edits collection */ |
2360 | 0 | OAD_StructureEdits_Clear(ed_fs); /* Clear edits collection */ |
2361 | | |
2362 | | |
2363 | 0 | return ret; |
2364 | 0 | } |
2365 | | |
2366 | | |
2367 | | /****************************************************************************/ |
2368 | | void swap_atoms_xyz( ORIG_ATOM_DATA *orig_at_data, int ia1, int ia2 ) |
2369 | 0 | { |
2370 | 0 | double x, y, z; |
2371 | | |
2372 | 0 | if (ia1 != ia2) |
2373 | 0 | { |
2374 | 0 | x = orig_at_data->at[ia1].x; |
2375 | 0 | y = orig_at_data->at[ia1].y; |
2376 | 0 | z = orig_at_data->at[ia1].z; |
2377 | |
|
2378 | 0 | orig_at_data->at[ia1].x = orig_at_data->at[ia2].x; |
2379 | 0 | orig_at_data->at[ia1].y = orig_at_data->at[ia2].y; |
2380 | 0 | orig_at_data->at[ia1].z = orig_at_data->at[ia2].z; |
2381 | | |
2382 | 0 | orig_at_data->at[ia2].x = x; |
2383 | 0 | orig_at_data->at[ia2].y = y; |
2384 | 0 | orig_at_data->at[ia2].z = z; |
2385 | 0 | } |
2386 | |
|
2387 | 0 | return; |
2388 | 0 | } |
2389 | | |
2390 | | |
2391 | | /**************************************************************************** |
2392 | | OAD_StructureEdits_Edit |
2393 | | ****************************************************************************/ |
2394 | | int OAD_StructureEdits_Apply( STRUCT_DATA *sd, |
2395 | | INPUT_PARMS *ip, |
2396 | | ORIG_ATOM_DATA *orig_at_data, |
2397 | | OAD_StructureEdits *ed, |
2398 | | int *ret) |
2399 | 0 | { |
2400 | 0 | int ok = 0, fail; |
2401 | 0 | int i, j, old_a1, old_a2, new_a1, new_a2, n_edits = 0; |
2402 | 0 | int n_del_atom, n_del_bond, n_new_bond, n_mod_bond, n_mod_coord; |
2403 | 0 | int a1, a2; |
2404 | 0 | int bond_type = INCHI_BOND_TYPE_NONE, bond_stereo = INCHI_BOND_STEREO_NONE; |
2405 | 0 | inp_ATOM *at = orig_at_data->at; |
2406 | 0 | OAD_Polymer *p = orig_at_data->polymer; |
2407 | 0 | int *at_renum = NULL; |
2408 | 0 | int *ibuf = NULL; |
2409 | 0 | int n_max_stored=-1; |
2410 | |
|
2411 | 0 | *ret = _IS_OKAY; |
2412 | |
|
2413 | 0 | n_del_atom = ed->del_atom->used; |
2414 | 0 | n_del_bond = ed->del_bond->used/2; |
2415 | 0 | n_new_bond = ed->new_bond->used/3; |
2416 | 0 | n_mod_bond = ed->mod_bond->used/4; |
2417 | 0 | n_mod_coord = ed->mod_coord->used/2; |
2418 | 0 | if (n_del_atom + n_del_bond + n_new_bond + n_mod_bond + n_mod_coord < 1) |
2419 | 0 | { |
2420 | 0 | return 0; |
2421 | 0 | } |
2422 | | |
2423 | 0 | n_max_stored = inchi_max(2 * (orig_at_data->num_inp_atoms + 1), 2 * (orig_at_data->num_inp_bonds + 1)); /* set all-purpose buffer */ |
2424 | |
|
2425 | 0 | ITRACE_("\n***************************\nOrig_at_data BEFORE EDITS:\n"); |
2426 | 0 | OrigAtData_DebugTrace(orig_at_data); |
2427 | 0 | OAD_Polymer_DebugTrace(orig_at_data->polymer); |
2428 | | |
2429 | | /* Delete bonds */ |
2430 | 0 | if (n_del_bond) |
2431 | 0 | { |
2432 | 0 | for (i = 0; i < 2 * n_del_bond; i += 2) |
2433 | 0 | { |
2434 | 0 | a1 = ed->del_bond->item[i] - 1; |
2435 | 0 | a2 = ed->del_bond->item[i + 1] - 1; |
2436 | 0 | ok = OrigAtData_RemoveBond(a1, a2, at, &bond_type, &bond_stereo, &orig_at_data->num_inp_bonds); |
2437 | 0 | if (!ok) |
2438 | 0 | { |
2439 | 0 | *ret = _IS_ERROR; |
2440 | 0 | goto exit_function; |
2441 | 0 | } |
2442 | 0 | n_edits++; |
2443 | 0 | } |
2444 | 0 | } |
2445 | | |
2446 | | /* Add bonds */ |
2447 | 0 | if (n_new_bond) |
2448 | 0 | { |
2449 | 0 | for (i = 0; i < 2 * n_new_bond; i += 2) |
2450 | 0 | { |
2451 | 0 | a1 = ed->new_bond->item[i] - 1; |
2452 | 0 | a2 = ed->new_bond->item[i + 1] - 1; |
2453 | | /* TODO: consider real bond_type, bond_stereo */ |
2454 | | /* OrigAtData_AddSingleStereolessBond( a1, a2, at, &dummy ); */ |
2455 | 0 | ok = OrigAtData_AddBond(a1, a2, at, bond_type, bond_stereo, &orig_at_data->num_inp_bonds); |
2456 | 0 | if (!ok) |
2457 | 0 | { |
2458 | 0 | *ret = _IS_ERROR; |
2459 | 0 | goto exit_function; |
2460 | 0 | } |
2461 | 0 | n_edits++; |
2462 | 0 | } |
2463 | 0 | } |
2464 | | |
2465 | | /* Modify bonds */ |
2466 | 0 | if (n_mod_bond) |
2467 | 0 | { |
2468 | 0 | for (j = 0; j < 4 * n_mod_bond; j += 4) |
2469 | 0 | { |
2470 | 0 | old_a1 = ed->mod_bond->item[j]; |
2471 | 0 | old_a2 = ed->mod_bond->item[j + 1]; |
2472 | 0 | new_a1 = ed->mod_bond->item[j + 2]; |
2473 | 0 | new_a2 = ed->mod_bond->item[j + 3]; |
2474 | 0 | if ((old_a1 == new_a1&&old_a2 == new_a2) || (old_a2 == new_a1&&old_a1 == new_a2)) |
2475 | 0 | { |
2476 | 0 | continue; |
2477 | 0 | } |
2478 | 0 | ok = OrigAtData_RemoveBond(old_a1 - 1, old_a2 - 1, at, &bond_type, &bond_stereo, &orig_at_data->num_inp_bonds); |
2479 | 0 | if (!ok) |
2480 | 0 | { |
2481 | 0 | *ret = _IS_ERROR; |
2482 | 0 | goto exit_function; |
2483 | 0 | } |
2484 | 0 | ok = OrigAtData_AddBond(new_a1 - 1, new_a2 - 1, at, bond_type, bond_stereo, &orig_at_data->num_inp_bonds); |
2485 | 0 | if (!ok) |
2486 | 0 | { |
2487 | 0 | *ret = _IS_ERROR; |
2488 | 0 | goto exit_function; |
2489 | 0 | } |
2490 | | /* Correct CRU blist lists */ |
2491 | 0 | for (i = 0; i < p->n; i++) |
2492 | 0 | { |
2493 | 0 | OAD_PolymerUnit *u = p->units[i]; |
2494 | 0 | if (!u->blist) |
2495 | 0 | { |
2496 | | /* No crossing bonds in the unit */ |
2497 | 0 | continue; |
2498 | 0 | } |
2499 | 0 | if ( bIsSameBond(u->blist[0], u->blist[1], old_a1, old_a2) ) |
2500 | 0 | { |
2501 | 0 | u->blist[0] = new_a1; |
2502 | 0 | u->blist[1] = new_a2; |
2503 | 0 | } |
2504 | 0 | else if ( bIsSameBond(u->blist[2], u->blist[3], old_a1, old_a2) ) |
2505 | 0 | { |
2506 | 0 | u->blist[2] = new_a1; |
2507 | 0 | u->blist[3] = new_a2; |
2508 | 0 | } |
2509 | 0 | } |
2510 | |
|
2511 | 0 | n_edits++; |
2512 | 0 | } |
2513 | 0 | } |
2514 | | |
2515 | | /* Modify coordinates */ |
2516 | 0 | if (n_mod_coord) |
2517 | 0 | { |
2518 | 0 | for (j = 0; j < 2 * n_mod_coord; j += 2) |
2519 | 0 | { |
2520 | 0 | old_a1 = ed->mod_coord->item[j]; |
2521 | 0 | new_a1 = ed->mod_bond->item[j + 1]; |
2522 | 0 | swap_atoms_xyz(orig_at_data, old_a1 - 1, new_a1 - 1); |
2523 | 0 | n_edits++; |
2524 | 0 | } |
2525 | 0 | } |
2526 | | |
2527 | | |
2528 | | /* Delete atoms */ |
2529 | 0 | if (n_del_atom) |
2530 | 0 | { |
2531 | 0 | int nat0, nat, nacc; |
2532 | 0 | inp_ATOM *new_at = NULL, *new_at0=NULL; |
2533 | |
|
2534 | 0 | at_renum = (int *)inchi_calloc(n_max_stored, sizeof(int)); |
2535 | 0 | if (!at_renum) |
2536 | 0 | { |
2537 | 0 | *ret = _IS_ERROR; |
2538 | 0 | goto exit_function; |
2539 | 0 | } |
2540 | | /* all-purpose buffer */ |
2541 | 0 | ibuf = (int *)inchi_calloc(n_max_stored, sizeof(int)); |
2542 | 0 | if (!ibuf) |
2543 | 0 | { |
2544 | 0 | *ret = _IS_ERROR; |
2545 | 0 | goto exit_function; |
2546 | 0 | } |
2547 | | |
2548 | 0 | fail = mark_atoms_to_delete_or_renumber(orig_at_data, ed, at_renum); |
2549 | 0 | if (fail) |
2550 | 0 | { |
2551 | 0 | *ret = _IS_ERROR; |
2552 | 0 | goto exit_function; |
2553 | 0 | } |
2554 | | /* Now remove atom by atom */ |
2555 | | |
2556 | 0 | nat0 = orig_at_data->num_inp_atoms; |
2557 | 0 | nat = nat0 - ed->del_atom->used; |
2558 | 0 | new_at = (inp_ATOM *)inchi_calloc(nat, sizeof(new_at[0])); |
2559 | 0 | if (!new_at) |
2560 | 0 | { |
2561 | 0 | *ret = _IS_ERROR; |
2562 | 0 | goto exit_function; |
2563 | 0 | } |
2564 | | |
2565 | 0 | for (i = 0, nacc = 0; i < nat0; i++) |
2566 | 0 | { |
2567 | 0 | AT_NUMB nbr0[MAXVAL]; |
2568 | 0 | U_CHAR btype0[MAXVAL]; |
2569 | 0 | int m, macc, valen; |
2570 | 0 | int new_num = at_renum[i]; |
2571 | 0 | if (new_num == -1) |
2572 | 0 | { |
2573 | | /* Skip removed atom */ |
2574 | 0 | continue; |
2575 | 0 | } |
2576 | | |
2577 | | /* Atom to keep; copy it */ |
2578 | 0 | new_at0 = new_at + nacc; |
2579 | 0 | ++nacc; |
2580 | 0 | memcpy(new_at0, orig_at_data->at + i, sizeof(new_at[0])); |
2581 | | /* Correct its own number(s) */ |
2582 | 0 | new_at0->orig_at_number = new_num + 1; |
2583 | | |
2584 | | /* Correct its nbr number(s) */ |
2585 | 0 | valen = new_at0->valence; |
2586 | 0 | memcpy(nbr0, new_at0->neighbor, valen * sizeof(AT_NUMB)); |
2587 | 0 | memcpy(btype0, new_at0->bond_type, valen); |
2588 | 0 | memset(new_at0->neighbor, 0, valen); /* djb-rwth: memset_s C11/Annex K variant? */ |
2589 | 0 | for (m = 0, macc=0; m < valen; m++) |
2590 | 0 | { |
2591 | 0 | int num2 = nbr0[m]; |
2592 | 0 | int renum2 = at_renum[num2]; |
2593 | 0 | if (renum2 == num2) |
2594 | 0 | { |
2595 | | /* keep old */ |
2596 | 0 | new_at0->neighbor[macc++] = num2; |
2597 | 0 | } |
2598 | 0 | else if (renum2 == -1) |
2599 | 0 | { |
2600 | | /* skip and decrement valences */ |
2601 | 0 | new_at0->chem_bonds_valence -= btype0[m]; |
2602 | 0 | new_at0->valence--; |
2603 | 0 | } |
2604 | 0 | else |
2605 | 0 | { |
2606 | | /* set renumbered */ |
2607 | 0 | new_at0->neighbor[macc++] = renum2; |
2608 | 0 | } |
2609 | 0 | } |
2610 | 0 | } |
2611 | |
|
2612 | 0 | if (new_at) |
2613 | 0 | { |
2614 | 0 | inchi_free(orig_at_data->at); |
2615 | 0 | orig_at_data->at = new_at; |
2616 | 0 | } |
2617 | |
|
2618 | 0 | orig_at_data->num_inp_atoms = nacc; |
2619 | 0 | orig_at_data->num_inp_bonds = 0; |
2620 | 0 | for (i = 0; i < nacc; i++) |
2621 | 0 | { |
2622 | 0 | orig_at_data->num_inp_bonds += new_at[i].valence; |
2623 | 0 | } |
2624 | 0 | orig_at_data->num_inp_bonds /= 2; |
2625 | | |
2626 | | /* Correct other data */ |
2627 | | |
2628 | | /* Correct polymer data */ |
2629 | 0 | if (p) |
2630 | 0 | { |
2631 | 0 | int iu; |
2632 | |
|
2633 | 0 | for (iu = 0; iu < p->n; iu++) |
2634 | 0 | { |
2635 | 0 | OAD_PolymerUnit* u = p->units[iu]; |
2636 | 0 | int new_na, new_nb, new_bb; |
2637 | 0 | memset(ibuf, 0, n_max_stored * sizeof(ibuf[0])); /* djb-rwth: memset_s C11/Annex K variant? */ |
2638 | 0 | if (u) |
2639 | 0 | { |
2640 | 0 | if (u->alist) |
2641 | 0 | { |
2642 | 0 | memcpy(ibuf, u->alist, u->na * sizeof(ibuf[0])); |
2643 | 0 | new_na = set_renumbered_or_delete(u->alist, ibuf, u->na, at_renum, 1); |
2644 | 0 | if (new_na == -1) |
2645 | 0 | { |
2646 | 0 | *ret = _IS_ERROR; |
2647 | 0 | goto exit_function; |
2648 | 0 | } |
2649 | 0 | u->na = new_na; |
2650 | 0 | } |
2651 | 0 | if (u->blist) |
2652 | 0 | { |
2653 | 0 | memcpy(ibuf, u->blist, 2 * (long long)u->nb * sizeof(int)); /* djb-rwth: cast operator added */ |
2654 | 0 | new_nb = set_renumbered_or_delete(u->blist, ibuf, 2*u->nb, at_renum, 1); |
2655 | 0 | new_nb /= 2; |
2656 | 0 | if (new_nb == -1) |
2657 | 0 | { |
2658 | 0 | *ret = _IS_ERROR; |
2659 | 0 | goto exit_function; |
2660 | 0 | } |
2661 | 0 | u->nb = new_nb; |
2662 | 0 | } |
2663 | | |
2664 | | |
2665 | 0 | if (u->bkbonds) |
2666 | 0 | { |
2667 | 0 | int b, new_nbkbonds; |
2668 | 0 | for (b = 0, new_nbkbonds = 0; b < u->nbkbonds; b++) |
2669 | 0 | { |
2670 | 0 | int bnd[2]; |
2671 | 0 | bnd[0] = u->bkbonds[b][0]; |
2672 | 0 | bnd[1] = u->bkbonds[b][1]; |
2673 | 0 | memcpy(ibuf, bnd, 2 * sizeof(ibuf[0])); |
2674 | 0 | memset(u->bkbonds[b], 0, 2 * sizeof(u->bkbonds[0][0])); /* djb-rwth: memset_s C11/Annex K variant? */ |
2675 | 0 | new_bb = set_renumbered_or_delete(bnd, ibuf, 2, at_renum, 1); |
2676 | 0 | if (new_bb == -1) |
2677 | 0 | { |
2678 | 0 | *ret = _IS_ERROR; |
2679 | 0 | goto exit_function; |
2680 | 0 | } |
2681 | 0 | else if (new_bb == 2) |
2682 | 0 | { |
2683 | 0 | u->bkbonds[new_nbkbonds][0] = bnd[0]; |
2684 | 0 | u->bkbonds[new_nbkbonds][1] = bnd[1]; |
2685 | 0 | new_nbkbonds++; |
2686 | | /* OK, settled new nums or kept old */ |
2687 | 0 | } |
2688 | 0 | else |
2689 | 0 | { |
2690 | 0 | continue; |
2691 | 0 | } |
2692 | 0 | } |
2693 | 0 | u->nbkbonds = new_nbkbonds; |
2694 | 0 | } |
2695 | | |
2696 | 0 | if (u->blist) /* djb-rwth: fixing a NULL pointer dereference */ |
2697 | 0 | { |
2698 | 0 | u->cap1 = u->blist[0]; |
2699 | 0 | u->end_atom1 = u->blist[1]; |
2700 | 0 | u->cap2 = u->blist[2]; |
2701 | 0 | u->end_atom2 = u->blist[3]; |
2702 | 0 | } |
2703 | 0 | if (u->cap1 < 1 || u->cap2 < 1 || u->end_atom1 < 1 || u->end_atom2 < 1) |
2704 | 0 | { |
2705 | 0 | *ret = _IS_ERROR; |
2706 | 0 | goto exit_function; |
2707 | 0 | } |
2708 | | |
2709 | |
|
2710 | 0 | } |
2711 | 0 | } |
2712 | 0 | } /* if (p) */ |
2713 | | |
2714 | | /* Correct V300 data */ |
2715 | 0 | if (orig_at_data->v3000) |
2716 | 0 | { |
2717 | 0 | ; |
2718 | 0 | } |
2719 | | |
2720 | |
|
2721 | 0 | } /* if (n_del_atom) */ |
2722 | | |
2723 | | |
2724 | 0 | exit_function: |
2725 | 0 | if (ibuf) |
2726 | 0 | { |
2727 | 0 | inchi_free(ibuf); |
2728 | 0 | } |
2729 | 0 | if (at_renum) |
2730 | 0 | { |
2731 | 0 | inchi_free(at_renum); |
2732 | 0 | } |
2733 | 0 | return n_edits; |
2734 | 0 | } |
2735 | | |
2736 | | |
2737 | | /**************************************************************************** |
2738 | | Set each element of number to renum[element] or delete it if renum==(base -1) |
2739 | | base is either 0 (0-started numbers) or 1 (1-started) |
2740 | | Returns new number of elements or -1 at error |
2741 | | ****************************************************************************/ |
2742 | | int set_renumbered_or_delete( int *number, /* numbers to correct */ |
2743 | | int *buf, /* must be enough size to hold nelems elements */ |
2744 | | int nelems, /* initial size of numbers */ |
2745 | | int *renum, /* new numbers in order of old numbers; always 0-based */ |
2746 | | int base) |
2747 | 0 | { |
2748 | 0 | int i, new_nelems; |
2749 | 0 | memcpy(buf, number, nelems * sizeof(int)); |
2750 | 0 | memset(number, 0, nelems * sizeof(int)); /* djb-rwth: memset_s C11/Annex K variant? */ |
2751 | 0 | for (i = 0, new_nelems = 0; i < nelems; i++) |
2752 | 0 | { |
2753 | 0 | int new_num = renum[ buf[i]-base ] + base; |
2754 | 0 | if (new_num == (base-1)) |
2755 | 0 | { |
2756 | 0 | continue; |
2757 | 0 | } |
2758 | 0 | else |
2759 | 0 | { |
2760 | 0 | number[new_nelems++] = new_num; |
2761 | 0 | } |
2762 | 0 | } |
2763 | 0 | return new_nelems; |
2764 | 0 | } |
2765 | | |
2766 | | |
2767 | | /**************************************************************************** |
2768 | | Worker placed under ProcessOneStructure wrapper (not the last nested doll) |
2769 | | ****************************************************************************/ |
2770 | | int ProcessOneStructureExCore( struct tagINCHI_CLOCK *ic, |
2771 | | struct tagCANON_GLOBALS *CG, |
2772 | | STRUCT_DATA *sd, |
2773 | | INPUT_PARMS *ip, |
2774 | | char *szTitle, |
2775 | | PINChI2 *pINChI2[INCHI_NUM], |
2776 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
2777 | | INCHI_IOSTREAM *inp_file, |
2778 | | INCHI_IOSTREAM *log_file, |
2779 | | INCHI_IOSTREAM *out_file, |
2780 | | INCHI_IOSTREAM *prb_file, |
2781 | | ORIG_ATOM_DATA *orig_inp_data, |
2782 | | ORIG_ATOM_DATA *prep_inp_data, |
2783 | | long num_inp, |
2784 | | INCHI_IOS_STRING *strbuf, |
2785 | | unsigned char save_opt_bits ) |
2786 | 0 | { |
2787 | 0 | int res = _IS_OKAY; |
2788 | 0 | int mind_polymers; |
2789 | |
|
2790 | | #ifdef TARGET_LIB_FOR_WINCHI |
2791 | | inchi_ios_free_str( out_file ); |
2792 | | inchi_ios_print(out_file, "Structure: %d\n", num_inp); |
2793 | | #endif |
2794 | | |
2795 | | /* Polymer and pseudoelement specific */ |
2796 | 0 | res = ValidateAndPreparePolymerAndPseudoatoms( ic, CG, sd, ip, szTitle, pINChI2, pINChI_Aux2, |
2797 | 0 | inp_file, log_file, out_file, prb_file, |
2798 | 0 | orig_inp_data, prep_inp_data, num_inp, strbuf, |
2799 | 0 | save_opt_bits, &mind_polymers); |
2800 | 0 | if (res== _IS_ERROR || res == _IS_FATAL ) |
2801 | 0 | { |
2802 | 0 | return res; |
2803 | 0 | } |
2804 | | |
2805 | | /* Call the very actual worker placed under this (ProcessOneStructureCore) wrapper */ |
2806 | 0 | res = ProcessOneStructure( ic, CG, sd, ip, szTitle, pINChI2, pINChI_Aux2, |
2807 | 0 | inp_file, log_file, out_file, prb_file, |
2808 | 0 | orig_inp_data, prep_inp_data, num_inp, strbuf, |
2809 | 0 | save_opt_bits); |
2810 | |
|
2811 | 0 | if ( (res == _IS_OKAY || res == _IS_WARNING ) && mind_polymers ) |
2812 | 0 | { |
2813 | | /* Post-edit the polymer layer at older polymer treatment modes (1.05, 1.05+) */ |
2814 | 0 | if (ip->bPolymers == POLYMERS_LEGACY || ip->bPolymers == POLYMERS_LEGACY_PLUS) |
2815 | 0 | { |
2816 | | /* Cut and hide "Zz" and related things in InChI (AuxInfo has a specifics). */ |
2817 | 0 | int n_pzz = 0, n_zy = orig_inp_data->n_zy; |
2818 | 0 | if (orig_inp_data->polymer) |
2819 | 0 | { |
2820 | 0 | n_pzz = orig_inp_data->polymer->n_pzz; |
2821 | 0 | } |
2822 | |
|
2823 | 0 | EditINCHI_HidePolymerZz(out_file, n_pzz, n_zy); |
2824 | |
|
2825 | 0 | } |
2826 | 0 | } |
2827 | |
|
2828 | | #ifdef TARGET_LIB_FOR_WINCHI |
2829 | | /* if ( res == _IS_ERROR || res == _IS_FATAL ) |
2830 | | { |
2831 | | inchi_ios_print(out_file, "Error %d (%s)\n", sd->nErrorCode, sd->pStrErrStruct); |
2832 | | } |
2833 | | */ |
2834 | | /*push_to_winchi_text_window(out_file); */ |
2835 | | /*inchi_ios_free_str(out_file);*/ |
2836 | | /*inchi_ios_flush(out_file);*/ |
2837 | | #endif |
2838 | |
|
2839 | 0 | return res; |
2840 | 0 | } |
2841 | | |
2842 | | |
2843 | | /**************************************************************************** |
2844 | | Treat pseudoelement and polymers: parse, validate and set details |
2845 | | ****************************************************************************/ |
2846 | | int ValidateAndPreparePolymerAndPseudoatoms( struct tagINCHI_CLOCK *ic, |
2847 | | struct tagCANON_GLOBALS *CG, |
2848 | | STRUCT_DATA *sd, |
2849 | | INPUT_PARMS *ip, |
2850 | | char *szTitle, |
2851 | | PINChI2 *pINChI2[INCHI_NUM], |
2852 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
2853 | | INCHI_IOSTREAM *inp_file, |
2854 | | INCHI_IOSTREAM *log_file, |
2855 | | INCHI_IOSTREAM *out_file, |
2856 | | INCHI_IOSTREAM *prb_file, |
2857 | | ORIG_ATOM_DATA *orig_inp_data, |
2858 | | ORIG_ATOM_DATA *prep_inp_data, |
2859 | | long num_inp, |
2860 | | INCHI_IOS_STRING *strbuf, |
2861 | | unsigned char save_opt_bits, |
2862 | | int *mind_polymers ) |
2863 | 0 | { |
2864 | 0 | int res = _IS_OKAY; |
2865 | |
|
2866 | 0 | int mind_pseudoelements = 0; |
2867 | | |
2868 | 0 | *mind_polymers = orig_inp_data && orig_inp_data->polymer && orig_inp_data->polymer->n > 0; |
2869 | 0 | *mind_polymers = *mind_polymers && orig_inp_data->valid_polymer && |
2870 | 0 | (ip->nInputType == INPUT_MOLFILE || ip->nInputType == INPUT_SDFILE); |
2871 | 0 | mind_pseudoelements = (ip->bNPZz == 1) || (ip->bPolymers != POLYMERS_NO); |
2872 | | |
2873 | | |
2874 | | /* Validate the data */ |
2875 | 0 | res = OAD_ValidatePolymerAndPseudoElementData(orig_inp_data, |
2876 | 0 | ip->bPolymers, |
2877 | 0 | ip->bNPZz, |
2878 | 0 | sd->pStrErrStruct, |
2879 | 0 | ip->bNoWarnings); |
2880 | 0 | if (res) |
2881 | 0 | { |
2882 | 0 | sd->nErrorCode = res; |
2883 | 0 | inchi_ios_eprint( log_file, "Error %d (%s) structure #%ld.%s%s%s%s\n", |
2884 | 0 | sd->nErrorCode, sd->pStrErrStruct, num_inp, |
2885 | 0 | SDF_LBL_VAL( ip->pSdfLabel, ip->pSdfValue ) ); |
2886 | 0 | res = _IS_ERROR; |
2887 | 0 | if (orig_inp_data) /* djb-rwth: fixing a NULL pointer dereference */ |
2888 | 0 | orig_inp_data->num_inp_atoms = -1; |
2889 | 0 | goto exit_function; |
2890 | 0 | } |
2891 | | |
2892 | 0 | if (*mind_polymers || mind_pseudoelements) |
2893 | 0 | { |
2894 | | /*OrigAtData_DebugTrace(orig_inp_data);*/ |
2895 | 0 | if (*mind_polymers && |
2896 | 0 | ip->bPolymers != POLYMERS_MODERN && |
2897 | 0 | (ip->bFrameShiftScheme == FSS_STARS_CYCLED || ip->bFrameShiftScheme == FSS_STARS_CYCLED_SORTED)) |
2898 | 0 | { |
2899 | | /* Analyze and cyclize frame-shift eligible CRUs using InChI canonical numbers |
2900 | | (do this only at older polymer treatment modes 1.05, 1.05+) |
2901 | | */ |
2902 | 0 | res = OAD_Polymer_CyclizeCloseableUnits( orig_inp_data, |
2903 | 0 | ip->bPolymers, |
2904 | 0 | sd->pStrErrStruct, |
2905 | 0 | ip->bNoWarnings ); |
2906 | 0 | if (res) |
2907 | 0 | { |
2908 | 0 | sd->nErrorCode = res; |
2909 | 0 | AddErrorMessage(sd->pStrErrStruct, "Error while processing polymer-related input"); |
2910 | 0 | res = _IS_ERROR; |
2911 | 0 | orig_inp_data->num_inp_atoms = -1; |
2912 | 0 | goto exit_function; |
2913 | 0 | } |
2914 | | /*OrigAtData_DebugTrace(orig_inp_data);*/ |
2915 | 0 | } |
2916 | 0 | } |
2917 | | |
2918 | 0 | exit_function: |
2919 | |
|
2920 | 0 | return res; |
2921 | 0 | } |
2922 | | |
2923 | | |
2924 | | /**************************************************************************** |
2925 | | Get InChI and AuxInfo of totally unedited original structure. |
2926 | | The intent is to preserve AuxInfo for the very original structure |
2927 | | in order to keep a final ability to restore that structure. |
2928 | | ****************************************************************************/ |
2929 | | int OAD_ProcessOneStructureNoEdits( struct tagINCHI_CLOCK *ic, |
2930 | | struct tagCANON_GLOBALS *CG, |
2931 | | STRUCT_DATA *sd, |
2932 | | INPUT_PARMS *ip, |
2933 | | char *szTitle, |
2934 | | PINChI2 *pINChI2[INCHI_NUM], |
2935 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
2936 | | INCHI_IOSTREAM *inp_file, |
2937 | | INCHI_IOSTREAM *log_file, |
2938 | | INCHI_IOSTREAM *out_file, |
2939 | | INCHI_IOSTREAM *prb_file, |
2940 | | ORIG_ATOM_DATA *orig_inp_data, |
2941 | | ORIG_ATOM_DATA *prep_inp_data, |
2942 | | long num_inp, |
2943 | | INCHI_IOS_STRING *strbuf, |
2944 | | unsigned char save_opt_bits, |
2945 | | int *n_pzz, |
2946 | | char **sinchi, |
2947 | | char **saux) |
2948 | 0 | { |
2949 | 0 | size_t slen; |
2950 | 0 | int ret = _IS_OKAY, dup_fail = 0; |
2951 | 0 | POSEContext dup_context, *dup = &dup_context; |
2952 | |
|
2953 | 0 | *n_pzz = 0; |
2954 | 0 | *sinchi = NULL; |
2955 | 0 | *saux = NULL; |
2956 | | |
2957 | | /* Make a working copy of all the native input */ |
2958 | 0 | dup_fail = POSEContext_Init(dup, sd, ip, szTitle, pINChI2, pINChI_Aux2, |
2959 | 0 | inp_file, log_file, out_file, prb_file, |
2960 | 0 | orig_inp_data, prep_inp_data, |
2961 | 0 | num_inp, strbuf, save_opt_bits); |
2962 | 0 | if (dup_fail) |
2963 | 0 | { |
2964 | 0 | ret = _IS_ERROR; |
2965 | 0 | goto exit_function; |
2966 | 0 | } |
2967 | | |
2968 | | /* Set necessary for this specific case options */ |
2969 | 0 | dup->orig_inp_data->polymer->treat = dup->ip.bPolymers = POLYMERS_MODERN; |
2970 | 0 | dup->ip.bFoldPolymerSRU = 0; |
2971 | 0 | dup->ip.bFrameShiftScheme = FSS_NONE; |
2972 | 0 | dup->ip.bINChIOutputOptions &= ~(INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO); |
2973 | 0 | dup->ip.bDisplay = dup->ip.bDisplayCompositeResults = dup->ip.bDisplayEachComponentINChI = 0; |
2974 | 0 | dup->ip.bFoldPolymerSRU = 0; |
2975 | | /*dup->ip.bTautFlags |= TG_FLAG_RECONNECT_COORD;*/ |
2976 | | |
2977 | | /* Calculate */ |
2978 | 0 | ret = ProcessOneStructureExCore( ic, CG, &dup->sd, &dup->ip, dup->szTitle, |
2979 | 0 | dup->pINChI2, dup->pINChI_Aux2, |
2980 | 0 | dup->inp_file, dup->log_file, |
2981 | 0 | dup->out_file, dup->prb_file, |
2982 | 0 | dup->orig_inp_data, dup->prep_inp_data, |
2983 | 0 | dup->num_inp, dup->strbuf, dup->save_opt_bits ); |
2984 | |
|
2985 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2986 | 0 | { |
2987 | 0 | goto exit_function; |
2988 | 0 | } |
2989 | | |
2990 | 0 | *n_pzz = dup->orig_inp_data->polymer->n_pzz; |
2991 | | /* Extract InChI */ |
2992 | 0 | slen = dup->out_file->s.nUsedLength; |
2993 | 0 | extract_inchi_substring(sinchi, dup->out_file->s.pStr, slen); |
2994 | 0 | if (!*sinchi) |
2995 | 0 | { |
2996 | 0 | ret = _IS_ERROR; |
2997 | 0 | } |
2998 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
2999 | 0 | { |
3000 | 0 | goto exit_function; |
3001 | 0 | } |
3002 | | /* Extract AuxInfo */ |
3003 | 0 | slen = dup->out_file->s.nUsedLength; |
3004 | 0 | extract_auxinfo_substring(saux, dup->out_file->s.pStr, slen); |
3005 | 0 | if (!*saux) |
3006 | 0 | { |
3007 | 0 | ret = _IS_ERROR; |
3008 | 0 | } |
3009 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
3010 | 0 | { |
3011 | 0 | goto exit_function; |
3012 | 0 | } |
3013 | | |
3014 | 0 | exit_function: |
3015 | 0 | POSEContext_Free(dup); |
3016 | |
|
3017 | 0 | return ret; |
3018 | 0 | } |
3019 | | |
3020 | | |
3021 | | /**************************************************************************** |
3022 | | Get InChI and AuxInfo of original structure using 1.05+ InChI version. |
3023 | | ****************************************************************************/ |
3024 | | int OAD_ProcessOneStructure105Plus( struct tagINCHI_CLOCK *ic, |
3025 | | struct tagCANON_GLOBALS *CG, |
3026 | | STRUCT_DATA *sd, |
3027 | | INPUT_PARMS *ip, |
3028 | | char *szTitle, |
3029 | | PINChI2 *pINChI2[INCHI_NUM], |
3030 | | PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], |
3031 | | INCHI_IOSTREAM *inp_file, |
3032 | | INCHI_IOSTREAM *log_file, |
3033 | | INCHI_IOSTREAM *out_file, |
3034 | | INCHI_IOSTREAM *prb_file, |
3035 | | ORIG_ATOM_DATA *orig_inp_data, |
3036 | | ORIG_ATOM_DATA *prep_inp_data, |
3037 | | long num_inp, |
3038 | | INCHI_IOS_STRING *strbuf, |
3039 | | unsigned char save_opt_bits, |
3040 | | char **sinchi, |
3041 | | char **saux) |
3042 | 0 | { |
3043 | 0 | size_t slen; |
3044 | 0 | int ret = _IS_OKAY, dup_fail = 0; |
3045 | 0 | POSEContext dup_context, *dup = &dup_context; |
3046 | |
|
3047 | 0 | *sinchi = NULL; |
3048 | 0 | *saux = NULL; |
3049 | | |
3050 | | /* Make a working copy of all the native input */ |
3051 | 0 | dup_fail = POSEContext_Init(dup, sd, ip, szTitle, pINChI2, pINChI_Aux2, |
3052 | 0 | inp_file, log_file, out_file, prb_file, |
3053 | 0 | orig_inp_data, prep_inp_data, |
3054 | 0 | num_inp, strbuf, save_opt_bits); |
3055 | 0 | if (dup_fail) |
3056 | 0 | { |
3057 | 0 | ret = _IS_ERROR; |
3058 | 0 | goto exit_function; |
3059 | 0 | } |
3060 | | |
3061 | | /* Set necessary for this specific case options */ |
3062 | | /* 1.05+ polymer treatment mode: hidden Zz, senior bkbond comes the first */ |
3063 | 0 | dup->orig_inp_data->polymer->treat = dup->ip.bPolymers = POLYMERS_LEGACY_PLUS; |
3064 | | /* include full aux info */ |
3065 | 0 | dup->ip.bINChIOutputOptions &= ~(INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO); |
3066 | | /* request no /D display in inchi-1 executable */ |
3067 | 0 | dup->ip.bDisplay = dup->ip.bDisplayCompositeResults = dup->ip.bDisplayEachComponentINChI = 0; |
3068 | | |
3069 | | /* Calculate */ |
3070 | 0 | ret = ProcessOneStructureExCore(ic, CG, &dup->sd, &dup->ip, dup->szTitle, |
3071 | 0 | dup->pINChI2, dup->pINChI_Aux2, |
3072 | 0 | dup->inp_file, dup->log_file, |
3073 | 0 | dup->out_file, dup->prb_file, |
3074 | 0 | dup->orig_inp_data, dup->prep_inp_data, |
3075 | 0 | dup->num_inp, dup->strbuf, dup->save_opt_bits); |
3076 | |
|
3077 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
3078 | 0 | { |
3079 | 0 | goto exit_function; |
3080 | 0 | } |
3081 | | |
3082 | | /* Extract InChI */ |
3083 | 0 | slen = dup->out_file->s.nUsedLength; |
3084 | 0 | extract_inchi_substring(sinchi, dup->out_file->s.pStr, slen); |
3085 | 0 | if (!*sinchi) |
3086 | 0 | { |
3087 | 0 | ret = _IS_ERROR; |
3088 | 0 | } |
3089 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
3090 | 0 | { |
3091 | 0 | goto exit_function; |
3092 | 0 | } |
3093 | | /* Extract AuxInfo */ |
3094 | 0 | slen = dup->out_file->s.nUsedLength; |
3095 | 0 | extract_auxinfo_substring(saux, dup->out_file->s.pStr, slen); |
3096 | 0 | if (!*saux) |
3097 | 0 | { |
3098 | 0 | ret = _IS_ERROR; |
3099 | 0 | } |
3100 | 0 | if (ret == _IS_FATAL || ret == _IS_ERROR) |
3101 | 0 | { |
3102 | 0 | goto exit_function; |
3103 | 0 | } |
3104 | | |
3105 | | |
3106 | 0 | exit_function: |
3107 | 0 | POSEContext_Free(dup); |
3108 | |
|
3109 | 0 | return ret; |
3110 | 0 | } |
3111 | | |
3112 | | |
3113 | | /**************************************************************************** |
3114 | | Mark atoms to be renumbered or removed |
3115 | | at_renum[initial number] := new_number or -1 (mark of deletion) |
3116 | | ****************************************************************************/ |
3117 | | int mark_atoms_to_delete_or_renumber( ORIG_ATOM_DATA *orig_at_data, |
3118 | | OAD_StructureEdits *ed, |
3119 | | int *at_renum) |
3120 | 0 | { |
3121 | 0 | int i, j; |
3122 | 0 | int fail=0, ret = 0; |
3123 | 0 | size_t *atnums = NULL; /* djb-rwth: needs to be size_t type */ |
3124 | 0 | size_t max_atoms = orig_at_data->num_inp_atoms; |
3125 | | |
3126 | | /* NB: new/old ORIG_ATOM_DATA atom numbers are 0-based (==orig_number-1) |
3127 | | while those in ed->... are just 1-based orig_numbers */ |
3128 | | |
3129 | 0 | for (i = 0; (size_t)i < max_atoms; i++) |
3130 | 0 | { |
3131 | 0 | at_renum[i] = i; |
3132 | 0 | } |
3133 | |
|
3134 | 0 | if (ed->del_side_chains) |
3135 | 0 | { |
3136 | | /* Extend list of atoms to be deleted with those connected to original ones |
3137 | | (i.e., delete a whole connected component(s) comprising original atoms) |
3138 | | */ |
3139 | 0 | int natnums = 0; |
3140 | 0 | atnums = (size_t *)inchi_calloc(max_atoms, sizeof(size_t)); /* djb-rwth: size_t type used for max_atoms to fit the definition of inchi_calloc */ |
3141 | 0 | if (!atnums) |
3142 | 0 | { |
3143 | 0 | return _IS_ERROR; |
3144 | 0 | } |
3145 | 0 | for (i = 0; (size_t)i < max_atoms; i++) |
3146 | 0 | { |
3147 | 0 | int iatom = ed->del_atom->item[i] - 1; |
3148 | 0 | subgraf *sg = NULL; |
3149 | 0 | subgraf_pathfinder *spf = NULL; |
3150 | 0 | if (i >= ed->del_atom->used) /* NB: ed->del_atom->used may be increased within this loop */ |
3151 | 0 | { |
3152 | 0 | break; |
3153 | 0 | } |
3154 | 0 | for (j = 0; (size_t)j < max_atoms; j++) |
3155 | 0 | { |
3156 | 0 | atnums[j] = orig_at_data->at[j].orig_at_number; /*j+1;*/ |
3157 | 0 | } |
3158 | 0 | sg = subgraf_new(orig_at_data, max_atoms, (int*)atnums); |
3159 | 0 | memset(atnums, 0, max_atoms * sizeof(int)); /* djb-rwth: memset_s C11/Annex K variant? */ |
3160 | 0 | if (!sg) |
3161 | 0 | { |
3162 | 0 | ret = _IS_ERROR; |
3163 | 0 | goto exit_function; |
3164 | 0 | } |
3165 | 0 | spf = subgraf_pathfinder_new(sg, orig_at_data, iatom, iatom); |
3166 | 0 | if (!spf) |
3167 | 0 | { |
3168 | 0 | ret = _IS_ERROR; |
3169 | 0 | goto exit_function; |
3170 | 0 | } |
3171 | 0 | spf->start = iatom; |
3172 | 0 | spf->nseen = 0; |
3173 | 0 | natnums = subgraf_pathfinder_collect_all(spf, 0, NULL, (int*)atnums); |
3174 | 0 | if (natnums) |
3175 | 0 | { |
3176 | 0 | for (j = 0; j < natnums; j++) |
3177 | 0 | { |
3178 | 0 | fail = IntArray_AppendIfAbsent(ed->del_atom, atnums[j]); /* djb-rwth: ui_rr? */ |
3179 | 0 | if (fail) |
3180 | 0 | { |
3181 | 0 | ret = _IS_ERROR; |
3182 | 0 | goto exit_function; |
3183 | 0 | } |
3184 | 0 | } |
3185 | 0 | } |
3186 | 0 | subgraf_free(sg); |
3187 | 0 | subgraf_pathfinder_free(spf); |
3188 | 0 | } |
3189 | |
|
3190 | 0 | } /* if (ed->del_side_chains) */ |
3191 | | |
3192 | 0 | for (i = max_atoms - 1; i >= 0; i--) |
3193 | 0 | { |
3194 | 0 | int orig_num = i + 1; /* NB: ed->del_atom->item contains orig# which are (OAD# + 1) */ |
3195 | 0 | if (is_in_the_ilist(ed->del_atom->item, orig_num, ed->del_atom->used)) |
3196 | 0 | { |
3197 | | /* mark as deleted atnum */ |
3198 | 0 | at_renum[i] = -1; |
3199 | | /* shift other atnums */ |
3200 | 0 | for (j = max_atoms - 1; j > i; j--) |
3201 | 0 | { |
3202 | 0 | if (at_renum[j] != -1) |
3203 | 0 | { |
3204 | 0 | at_renum[j]--; |
3205 | 0 | } |
3206 | 0 | } |
3207 | 0 | } |
3208 | 0 | } |
3209 | | |
3210 | |
|
3211 | 0 | exit_function: |
3212 | 0 | if (atnums) |
3213 | 0 | { |
3214 | 0 | inchi_free(atnums); |
3215 | 0 | } |
3216 | 0 | return ret; |
3217 | 0 | } |
3218 | | |
3219 | | |
3220 | | #if (BUILD_WITH_ENG_OPTIONS==1) |
3221 | | #if ALLOW_SUBSTRUCTURE_FILTERING==1 |
3222 | | int check_presence_of_the_encoded_substructure(ORIG_ATOM_DATA *orig_inp_data); |
3223 | | int OrigAtData_CheckForSubstructure(ORIG_ATOM_DATA *orig_inp_data) |
3224 | | { |
3225 | | int ok = 0; |
3226 | | |
3227 | | ok = check_presence_of_the_encoded_substructure(orig_inp_data); |
3228 | | |
3229 | | return ok; |
3230 | | } |
3231 | | int check_presence_of_the_encoded_substructure(ORIG_ATOM_DATA *oad) |
3232 | | { |
3233 | | int i, ok; |
3234 | | |
3235 | | /* Place sub-structure filtering code below. |
3236 | | |
3237 | | Return 1 if structure matches some hard-coded pattern |
3238 | | |
3239 | | In this example pattern is a presence of a pseudo atom. |
3240 | | */ |
3241 | | |
3242 | | ok = 0; |
3243 | | for (i = 0; i < oad->num_inp_atoms; i++) |
3244 | | { |
3245 | | if (oad->at[i].el_number == EL_NUMBER_ZZ || oad->at[i].el_number == EL_NUMBER_ZY) |
3246 | | { |
3247 | | ok = 1; |
3248 | | break; |
3249 | | } |
3250 | | } |
3251 | | return ok; |
3252 | | } |
3253 | | #endif |
3254 | | #endif |