rino 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +44 -0
- data/Rakefile +123 -0
- data/ext/extconf.rb +26 -0
- data/ext/ruby_inchi_main.so +0 -0
- data/ext/src/aux2atom.h +2786 -0
- data/ext/src/comdef.h +148 -0
- data/ext/src/e_0dstereo.c +3014 -0
- data/ext/src/e_0dstereo.h +31 -0
- data/ext/src/e_comdef.h +57 -0
- data/ext/src/e_ctl_data.h +147 -0
- data/ext/src/e_ichi_io.c +498 -0
- data/ext/src/e_ichi_io.h +40 -0
- data/ext/src/e_ichi_parms.c +37 -0
- data/ext/src/e_ichi_parms.h +41 -0
- data/ext/src/e_ichicomp.h +50 -0
- data/ext/src/e_ichierr.h +40 -0
- data/ext/src/e_ichimain.c +593 -0
- data/ext/src/e_ichisize.h +43 -0
- data/ext/src/e_inchi_atom.c +75 -0
- data/ext/src/e_inchi_atom.h +33 -0
- data/ext/src/e_inpdef.h +41 -0
- data/ext/src/e_mode.h +706 -0
- data/ext/src/e_mol2atom.c +649 -0
- data/ext/src/e_readinch.c +58 -0
- data/ext/src/e_readmol.c +54 -0
- data/ext/src/e_readmol.h +180 -0
- data/ext/src/e_readstru.c +251 -0
- data/ext/src/e_readstru.h +33 -0
- data/ext/src/e_util.c +284 -0
- data/ext/src/e_util.h +61 -0
- data/ext/src/extr_ct.h +251 -0
- data/ext/src/ichi.h +206 -0
- data/ext/src/ichi_bns.c +7999 -0
- data/ext/src/ichi_bns.h +231 -0
- data/ext/src/ichican2.c +5000 -0
- data/ext/src/ichicano.c +2195 -0
- data/ext/src/ichicano.h +49 -0
- data/ext/src/ichicans.c +1625 -0
- data/ext/src/ichicant.h +379 -0
- data/ext/src/ichicomn.h +260 -0
- data/ext/src/ichicomp.h +50 -0
- data/ext/src/ichidrp.h +119 -0
- data/ext/src/ichierr.h +124 -0
- data/ext/src/ichiisot.c +101 -0
- data/ext/src/ichilnct.c +286 -0
- data/ext/src/ichimain.h +132 -0
- data/ext/src/ichimak2.c +1189 -0
- data/ext/src/ichimake.c +3812 -0
- data/ext/src/ichimake.h +205 -0
- data/ext/src/ichimap1.c +851 -0
- data/ext/src/ichimap2.c +2856 -0
- data/ext/src/ichimap4.c +1609 -0
- data/ext/src/ichinorm.c +741 -0
- data/ext/src/ichinorm.h +67 -0
- data/ext/src/ichiparm.c +45 -0
- data/ext/src/ichiparm.h +1441 -0
- data/ext/src/ichiprt1.c +3612 -0
- data/ext/src/ichiprt2.c +1511 -0
- data/ext/src/ichiprt3.c +3011 -0
- data/ext/src/ichiqueu.c +1003 -0
- data/ext/src/ichiring.c +326 -0
- data/ext/src/ichiring.h +49 -0
- data/ext/src/ichisize.h +35 -0
- data/ext/src/ichisort.c +539 -0
- data/ext/src/ichister.c +3538 -0
- data/ext/src/ichister.h +35 -0
- data/ext/src/ichitaut.c +3843 -0
- data/ext/src/ichitaut.h +387 -0
- data/ext/src/ichitime.h +74 -0
- data/ext/src/inchi_api.h +670 -0
- data/ext/src/inchi_dll.c +1480 -0
- data/ext/src/inchi_dll.h +34 -0
- data/ext/src/inchi_dll_main.c +23 -0
- data/ext/src/inchi_dll_main.h +31 -0
- data/ext/src/inpdef.h +328 -0
- data/ext/src/lreadmol.h +1246 -0
- data/ext/src/mode.h +706 -0
- data/ext/src/ruby_inchi_main.c +558 -0
- data/ext/src/runichi.c +4179 -0
- data/ext/src/strutil.c +3861 -0
- data/ext/src/strutil.h +182 -0
- data/ext/src/util.c +1130 -0
- data/ext/src/util.h +85 -0
- data/lib/clean_tempfile.rb +220 -0
- data/lib/rino.rb +111 -0
- data/test/test.rb +386 -0
- metadata +130 -0
data/ext/src/runichi.c
ADDED
@@ -0,0 +1,4179 @@
|
|
1
|
+
/*
|
2
|
+
* International Union of Pure and Applied Chemistry (IUPAC)
|
3
|
+
* International Chemical Identifier (InChI)
|
4
|
+
* Version 1
|
5
|
+
* Software version 1.00
|
6
|
+
* April 13, 2005
|
7
|
+
* Developed at NIST
|
8
|
+
*/
|
9
|
+
|
10
|
+
#include <stdio.h>
|
11
|
+
#include <stdlib.h>
|
12
|
+
#include <string.h>
|
13
|
+
#include <ctype.h>
|
14
|
+
#include <stdarg.h>
|
15
|
+
/* #include <varargs.h> */
|
16
|
+
#include <errno.h>
|
17
|
+
#include <limits.h>
|
18
|
+
|
19
|
+
#include "mode.h" /* moved from below, suggestion by David Mosenkis */
|
20
|
+
|
21
|
+
#include "ichitime.h"
|
22
|
+
|
23
|
+
#ifndef INCHI_ANSI_ONLY
|
24
|
+
#include <conio.h>
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#include "inpdef.h"
|
28
|
+
#include "ichi.h"
|
29
|
+
#include "strutil.h"
|
30
|
+
#include "util.h"
|
31
|
+
#include "ichidrp.h"
|
32
|
+
#include "ichierr.h"
|
33
|
+
#include "ichimain.h"
|
34
|
+
#include "extr_ct.h"
|
35
|
+
|
36
|
+
#ifdef INCHI_LIB
|
37
|
+
#include "ichi_lib.h"
|
38
|
+
#endif
|
39
|
+
|
40
|
+
#include "ichicomp.h"
|
41
|
+
|
42
|
+
#if( ADD_CMLPP == 1 )
|
43
|
+
#include "readcml.hpp"
|
44
|
+
#include "debug.h"
|
45
|
+
#endif
|
46
|
+
|
47
|
+
/* for DisplayTheWholeStructure() */
|
48
|
+
|
49
|
+
#define COMP_ORIG_0_MAIN 0x0001
|
50
|
+
#define COMP_ORIG_0_RECN 0x0002
|
51
|
+
#define COMP_PREP_0_MAIN 0x0004
|
52
|
+
#define COMP_PREP_0_RECN 0x0008
|
53
|
+
#define COMP_ORIG_1_MAIN 0x0010
|
54
|
+
#define COMP_ORIG_1_RECN 0x0020
|
55
|
+
|
56
|
+
|
57
|
+
/* local prototypes */
|
58
|
+
int GetProcessingWarningsOneINChI(INChI *pINChI, INP_ATOM_DATA *inp_norm_data, char *pStrErrStruct);
|
59
|
+
int GetProcessingWarnings(INChI *cur_INChI[], INP_ATOM_DATA **inp_norm_data, STRUCT_DATA *sd);
|
60
|
+
int DisplayTheWholeStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, FILE *inp_file, INCHI_FILE *log_file,
|
61
|
+
ORIG_ATOM_DATA *orig_inp_data, int num_inp, int iINChI, int bShowStruct, int bINCHI_LIB_Flag );
|
62
|
+
int DuplicateOrigAtom( ORIG_ATOM_DATA *new_orig_atom, ORIG_ATOM_DATA *orig_atom );
|
63
|
+
int bCheckUnusualValences( ORIG_ATOM_DATA *orig_at_data, int bAddIsoH, char *pStrErrStruct );
|
64
|
+
int CreateCompositeNormAtom( COMP_ATOM_DATA *composite_norm_data, INP_ATOM_DATA2 *all_inp_norm_data,
|
65
|
+
PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int num_components, INCHI_MODE nMode );
|
66
|
+
int DetectInputINChIFileType( FILE **inp_file, INPUT_PARMS *ip, const char *fmode );
|
67
|
+
int GetMaxPrintfLength( const char *lpszFormat, va_list argList);
|
68
|
+
|
69
|
+
/* callback */
|
70
|
+
int (*ConsoleQuit)(void) = NULL; /* Console user issued CTRL+C etc. */
|
71
|
+
int (*UserAction)(void) = NULL; /* callback */
|
72
|
+
|
73
|
+
#ifdef INCHI_LIB
|
74
|
+
void (*FWPRINT) (const char * format, va_list argptr )=NULL;
|
75
|
+
void (*DRAWDATA) ( struct DrawData * pDrawData) = NULL;
|
76
|
+
int (*DRAWDATA_EXISTS) ( int nComponent, int nType, int bReconnected ) = NULL;
|
77
|
+
struct DrawData * (*GET_DRAWDATA) ( int nComponent, int nType, int bReconnected ) = NULL;
|
78
|
+
#endif
|
79
|
+
|
80
|
+
#if( TEST_RENUMB_ATOMS == 1 ) /* { */
|
81
|
+
/************************************************/
|
82
|
+
/* atoms renumbering -- for testing only */
|
83
|
+
/************************************************/
|
84
|
+
typedef struct tagRenumbData {
|
85
|
+
PINChI2 ren_INChI2[1];
|
86
|
+
PINChI_Aux2 ren_INChI_Aux[1];
|
87
|
+
INP_ATOM_DATA orig_inp_cur_data;
|
88
|
+
INP_ATOM_DATA saved_inp_cur_data;
|
89
|
+
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
|
90
|
+
INP_ATOM_DATA longest_inp_cur_data;
|
91
|
+
#endif
|
92
|
+
INP_ATOM_DATA ren_inp_norm_data1, ren_inp_norm_data2;
|
93
|
+
INP_ATOM_DATA *ren_inp_norm_data[2];
|
94
|
+
int ren_counter;
|
95
|
+
int num_taut, num_non_taut, num_taut0, num_non_taut0;
|
96
|
+
AT_RANK *new_ord;
|
97
|
+
int nRet2, c1, c2, nComp, bRenumbErr;
|
98
|
+
unsigned long ulCurTimeNorm0, ulCurTimeCanon0, ulCurTimeNorm1, ulCurTimeCanon1;
|
99
|
+
unsigned long ulCurTimeNorm, ulCurTimeCanon, ulMaxTimeNorm, ulMaxTimeCanon;
|
100
|
+
unsigned long ulMaxTime, ulCurTime, ulCurTime0, ulCurTime1;
|
101
|
+
#if ( bRELEASE_VERSION == 0 )
|
102
|
+
int bExtract;
|
103
|
+
#endif
|
104
|
+
} RENUMB_DATA;
|
105
|
+
|
106
|
+
int RenumberingTestInit( RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data );
|
107
|
+
int RenumberingTestUninit( RENUMB_DATA *pRenumbData );
|
108
|
+
int RenumberingTest( PINChI2 *pICh, PINChI_Aux2 *pINChI_Aux, ORIG_ATOM_DATA *orig_inp_data, int iINChI,
|
109
|
+
RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data, INP_ATOM_DATA **inp_norm_data,
|
110
|
+
STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, INCHI_FILE *log_file, INCHI_FILE *prb_file,
|
111
|
+
int i, int num_inp, NORM_CANON_FLAGS *pncFlags);
|
112
|
+
/*
|
113
|
+
int RenumberingTest( INChI *pINChI[][TAUT_NUM], INChI_Aux *pINChI_Aux[][TAUT_NUM], int iINChI,
|
114
|
+
RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data, INP_ATOM_DATA **inp_norm_data,
|
115
|
+
STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, INCHI_FILE *log_file, int i, int num_inp);
|
116
|
+
*/
|
117
|
+
#endif /* } TEST_RENUMB_ATOMS */
|
118
|
+
|
119
|
+
|
120
|
+
#ifdef INCHI_LIBRARY
|
121
|
+
/*****************************************************************
|
122
|
+
*
|
123
|
+
* Estimate printf string length
|
124
|
+
*
|
125
|
+
* The code is based on Microsoft Knowledge Base article Q127038:
|
126
|
+
* "FIX: CString::Format Gives Assertion Failed, Access Violation"
|
127
|
+
* (Related to Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1)
|
128
|
+
*
|
129
|
+
*****************************************************************/
|
130
|
+
|
131
|
+
#define FORCE_ANSI 0x10000
|
132
|
+
#define FORCE_UNICODE 0x20000
|
133
|
+
|
134
|
+
/* formatting (using wsprintf style formatting)*/
|
135
|
+
int GetMaxPrintfLength( const char *lpszFormat, va_list argList)
|
136
|
+
{
|
137
|
+
/*ASSERT(AfxIsValidString(lpszFormat, FALSE));*/
|
138
|
+
const char * lpsz;
|
139
|
+
int nMaxLen, nWidth, nPrecision, nModifier, nItemLen;
|
140
|
+
|
141
|
+
nMaxLen = 0;
|
142
|
+
/* make a guess at the maximum length of the resulting string */
|
143
|
+
for ( lpsz = lpszFormat; *lpsz; lpsz ++ )
|
144
|
+
{
|
145
|
+
/* handle '%' character, but watch out for '%%' */
|
146
|
+
if (*lpsz != '%' || *( ++ lpsz ) == '%')
|
147
|
+
{
|
148
|
+
nMaxLen += 1;
|
149
|
+
continue;
|
150
|
+
}
|
151
|
+
|
152
|
+
nItemLen = 0;
|
153
|
+
|
154
|
+
/* handle '%' character with format */
|
155
|
+
nWidth = 0;
|
156
|
+
for (; *lpsz; lpsz ++ )
|
157
|
+
{
|
158
|
+
/* check for valid flags */
|
159
|
+
if (*lpsz == '#')
|
160
|
+
nMaxLen += 2; /* for '0x' */
|
161
|
+
else if (*lpsz == '*')
|
162
|
+
nWidth = va_arg(argList, int);
|
163
|
+
else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0'
|
164
|
+
|| *lpsz == ' ')
|
165
|
+
;
|
166
|
+
else /* hit non-flag character */
|
167
|
+
break;
|
168
|
+
}
|
169
|
+
/* get width and skip it */
|
170
|
+
if (nWidth == 0)
|
171
|
+
{
|
172
|
+
/* width indicated by */
|
173
|
+
nWidth = atoi(lpsz);
|
174
|
+
for (; *lpsz && isdigit(*lpsz); lpsz ++ )
|
175
|
+
;
|
176
|
+
}
|
177
|
+
/*ASSERT(nWidth >= 0);*/
|
178
|
+
if ( nWidth < 0 )
|
179
|
+
goto exit_error; /* instead of exception */
|
180
|
+
|
181
|
+
nPrecision = 0;
|
182
|
+
if (*lpsz == '.')
|
183
|
+
{
|
184
|
+
/* skip past '.' separator (width.precision)*/
|
185
|
+
lpsz ++;
|
186
|
+
|
187
|
+
/* get precision and skip it*/
|
188
|
+
if (*lpsz == '*')
|
189
|
+
{
|
190
|
+
nPrecision = va_arg(argList, int);
|
191
|
+
lpsz ++;
|
192
|
+
}
|
193
|
+
else
|
194
|
+
{
|
195
|
+
nPrecision = atoi(lpsz);
|
196
|
+
for (; *lpsz && isdigit(*lpsz); lpsz ++)
|
197
|
+
;
|
198
|
+
}
|
199
|
+
if ( nPrecision < 0 )
|
200
|
+
goto exit_error; /* instead of exception */
|
201
|
+
}
|
202
|
+
|
203
|
+
/* should be on type modifier or specifier */
|
204
|
+
nModifier = 0;
|
205
|
+
switch (*lpsz)
|
206
|
+
{
|
207
|
+
/* modifiers that affect size */
|
208
|
+
case 'h':
|
209
|
+
switch ( lpsz[1] ) {
|
210
|
+
case 'd':
|
211
|
+
case 'i':
|
212
|
+
case 'o':
|
213
|
+
case 'x':
|
214
|
+
case 'X':
|
215
|
+
case 'u':
|
216
|
+
/* short unsigned, short double, etc. -- added to the original MS example */
|
217
|
+
/* ignore the fact that these modifiers do affect size */
|
218
|
+
lpsz ++;
|
219
|
+
break;
|
220
|
+
default:
|
221
|
+
nModifier = FORCE_ANSI;
|
222
|
+
lpsz ++;
|
223
|
+
break;
|
224
|
+
}
|
225
|
+
break;
|
226
|
+
case 'l':
|
227
|
+
switch ( lpsz[1] ) {
|
228
|
+
case 'd':
|
229
|
+
case 'i':
|
230
|
+
case 'o':
|
231
|
+
case 'x':
|
232
|
+
case 'X':
|
233
|
+
case 'u':
|
234
|
+
case 'f': /* long float -- post ANSI C */
|
235
|
+
/* long unsigned, long double, etc. -- added to the original MS example */
|
236
|
+
/* ignore the fact that these modifiers do affect size */
|
237
|
+
lpsz ++;
|
238
|
+
break;
|
239
|
+
default:
|
240
|
+
/*
|
241
|
+
nModifier = FORCE_UNICODE;
|
242
|
+
lpsz ++;
|
243
|
+
break;
|
244
|
+
*/
|
245
|
+
goto exit_error; /* no UNICODE, please */
|
246
|
+
}
|
247
|
+
break;
|
248
|
+
/* modifiers that do not affect size */
|
249
|
+
case 'F':
|
250
|
+
case 'N':
|
251
|
+
case 'L':
|
252
|
+
lpsz ++;
|
253
|
+
break;
|
254
|
+
}
|
255
|
+
|
256
|
+
/* now should be on specifier */
|
257
|
+
switch (*lpsz | nModifier)
|
258
|
+
{
|
259
|
+
/* single characters*/
|
260
|
+
case 'c':
|
261
|
+
case 'C':
|
262
|
+
nItemLen = 2;
|
263
|
+
va_arg(argList, int);
|
264
|
+
break;
|
265
|
+
case 'c'|FORCE_ANSI:
|
266
|
+
case 'C'|FORCE_ANSI:
|
267
|
+
nItemLen = 2;
|
268
|
+
va_arg(argList, int);
|
269
|
+
break;
|
270
|
+
case 'c'|FORCE_UNICODE:
|
271
|
+
case 'C'|FORCE_UNICODE:
|
272
|
+
goto exit_error; /* no UNICODE, please */
|
273
|
+
/*
|
274
|
+
nItemLen = 2;
|
275
|
+
va_arg(argList, wchar_t);
|
276
|
+
break;
|
277
|
+
*/
|
278
|
+
|
279
|
+
/* strings*/
|
280
|
+
case 's':
|
281
|
+
case 'S':
|
282
|
+
nItemLen = strlen(va_arg(argList, char*));
|
283
|
+
nItemLen = inchi_max(1, nItemLen);
|
284
|
+
break;
|
285
|
+
case 's'|FORCE_ANSI:
|
286
|
+
case 'S'|FORCE_ANSI:
|
287
|
+
nItemLen = strlen(va_arg(argList, char*));
|
288
|
+
nItemLen = inchi_max(1, nItemLen);
|
289
|
+
break;
|
290
|
+
|
291
|
+
case 's'|FORCE_UNICODE:
|
292
|
+
case 'S'|FORCE_UNICODE:
|
293
|
+
goto exit_error; /* no UNICODE, please */
|
294
|
+
/*
|
295
|
+
nItemLen = wcslen(va_arg(argList, wchar_t*));
|
296
|
+
nItemLen = inchi_max(1, nItemLen);
|
297
|
+
break;
|
298
|
+
*/
|
299
|
+
|
300
|
+
}
|
301
|
+
|
302
|
+
/* adjust nItemLen for strings */
|
303
|
+
if (nItemLen != 0)
|
304
|
+
{
|
305
|
+
nItemLen = inchi_max(nItemLen, nWidth);
|
306
|
+
if (nPrecision != 0)
|
307
|
+
nItemLen = inchi_min(nItemLen, nPrecision);
|
308
|
+
}
|
309
|
+
else
|
310
|
+
{
|
311
|
+
switch (*lpsz)
|
312
|
+
{
|
313
|
+
/* integers */
|
314
|
+
case 'd':
|
315
|
+
case 'i':
|
316
|
+
case 'u':
|
317
|
+
case 'x':
|
318
|
+
case 'X':
|
319
|
+
case 'o':
|
320
|
+
va_arg(argList, int);
|
321
|
+
nItemLen = 32;
|
322
|
+
nItemLen = inchi_max(nItemLen, nWidth+nPrecision);
|
323
|
+
break;
|
324
|
+
|
325
|
+
case 'e':
|
326
|
+
case 'f':
|
327
|
+
case 'g':
|
328
|
+
case 'G':
|
329
|
+
va_arg(argList, double);
|
330
|
+
nItemLen = 32;
|
331
|
+
nItemLen = inchi_max(nItemLen, nWidth+nPrecision);
|
332
|
+
break;
|
333
|
+
|
334
|
+
case 'p':
|
335
|
+
va_arg(argList, void*);
|
336
|
+
nItemLen = 32;
|
337
|
+
nItemLen = inchi_max(nItemLen, nWidth+nPrecision);
|
338
|
+
break;
|
339
|
+
|
340
|
+
/* no output */
|
341
|
+
case 'n':
|
342
|
+
va_arg(argList, int*);
|
343
|
+
break;
|
344
|
+
|
345
|
+
default:
|
346
|
+
/*ASSERT(FALSE);*/ /* unknown formatting option*/
|
347
|
+
goto exit_error; /* instead of exception */
|
348
|
+
}
|
349
|
+
}
|
350
|
+
|
351
|
+
/* adjust nMaxLen for output nItemLen */
|
352
|
+
nMaxLen += nItemLen;
|
353
|
+
}
|
354
|
+
return nMaxLen;
|
355
|
+
|
356
|
+
exit_error:
|
357
|
+
return -1; /* wrong format */
|
358
|
+
}
|
359
|
+
#define INCHI_ADD_STR_LEN 32768
|
360
|
+
#endif /* INCHI_LIBRARY */
|
361
|
+
|
362
|
+
#ifdef INCHI_LIBRARY
|
363
|
+
/*****************************************************************/
|
364
|
+
int inchi_print( INCHI_FILE* f, const char* lpszFormat, ... )
|
365
|
+
{
|
366
|
+
if ( f ) {
|
367
|
+
int ret=0, max_len;
|
368
|
+
va_list argList;
|
369
|
+
my_va_start( argList, lpszFormat );
|
370
|
+
max_len = GetMaxPrintfLength( lpszFormat, argList);
|
371
|
+
va_end( argList );
|
372
|
+
|
373
|
+
if ( max_len >= 0 ) {
|
374
|
+
if ( f->nAllocatedLength - f->nUsedLength <= max_len ) {
|
375
|
+
/* enlarge output string */
|
376
|
+
int nAddLength = inchi_max( INCHI_ADD_STR_LEN, max_len );
|
377
|
+
char *new_str = (char *)inchi_calloc( f->nAllocatedLength + nAddLength, sizeof(new_str[0]) );
|
378
|
+
if ( new_str ) {
|
379
|
+
if ( f->pStr ) {
|
380
|
+
if ( f->nUsedLength > 0 ) {
|
381
|
+
memcpy( new_str, f->pStr, sizeof(new_str[0])*f->nUsedLength );
|
382
|
+
}
|
383
|
+
inchi_free( f->pStr );
|
384
|
+
}
|
385
|
+
f->pStr = new_str;
|
386
|
+
f->nAllocatedLength += nAddLength;
|
387
|
+
} else {
|
388
|
+
return -1; /* failed */
|
389
|
+
}
|
390
|
+
}
|
391
|
+
/* output */
|
392
|
+
my_va_start( argList, lpszFormat );
|
393
|
+
ret = vsprintf( f->pStr + f->nUsedLength, lpszFormat, argList );
|
394
|
+
va_end(argList);
|
395
|
+
if ( ret >= 0 ) {
|
396
|
+
f->nUsedLength += ret;
|
397
|
+
}
|
398
|
+
return ret;
|
399
|
+
}
|
400
|
+
}
|
401
|
+
return -1;
|
402
|
+
}
|
403
|
+
#else
|
404
|
+
/*****************************************************************/
|
405
|
+
int inchi_print( INCHI_FILE* f, const char* lpszFormat, ... )
|
406
|
+
{
|
407
|
+
int ret=0, ret2=0;
|
408
|
+
/* char *p=NULL; */
|
409
|
+
|
410
|
+
va_list argList;
|
411
|
+
|
412
|
+
if ( f ) {
|
413
|
+
my_va_start( argList, lpszFormat );
|
414
|
+
ret = vfprintf( f, lpszFormat, argList );
|
415
|
+
va_end( argList );
|
416
|
+
} else {
|
417
|
+
/* printf( "\r" ); */
|
418
|
+
my_va_start( argList, lpszFormat );
|
419
|
+
//ret2 = vfprintf( stdout, lpszFormat, argList );
|
420
|
+
/* ret2 = vprintf( lpszFormat, argList ); */
|
421
|
+
va_end( argList );
|
422
|
+
}
|
423
|
+
|
424
|
+
#ifdef INCHI_LIB
|
425
|
+
if( FWPRINT )
|
426
|
+
{
|
427
|
+
my_va_start( argList, lpszFormat );
|
428
|
+
FWPRINT( lpszFormat, argList );
|
429
|
+
va_end( argList );
|
430
|
+
}
|
431
|
+
#endif
|
432
|
+
return ret? ret : ret2;
|
433
|
+
}
|
434
|
+
#endif
|
435
|
+
|
436
|
+
|
437
|
+
#ifdef INCHI_LIBRARY
|
438
|
+
/**********************************************************************/
|
439
|
+
/* This function's output should not be displayed in the output pane */
|
440
|
+
/**********************************************************************/
|
441
|
+
int inchi_print_nodisplay( INCHI_FILE* f, const char* lpszFormat, ... )
|
442
|
+
{
|
443
|
+
if ( f ) {
|
444
|
+
int ret=0, max_len;
|
445
|
+
va_list argList;
|
446
|
+
my_va_start( argList, lpszFormat );
|
447
|
+
max_len = GetMaxPrintfLength( lpszFormat, argList);
|
448
|
+
va_end( argList );
|
449
|
+
|
450
|
+
if ( max_len >= 0 ) {
|
451
|
+
if ( f->nAllocatedLength - f->nUsedLength <= max_len ) {
|
452
|
+
/* enlarge output string */
|
453
|
+
int nAddLength = inchi_max( INCHI_ADD_STR_LEN, max_len );
|
454
|
+
char *new_str = (char *)inchi_calloc( f->nAllocatedLength + nAddLength, sizeof(new_str[0]) );
|
455
|
+
if ( new_str ) {
|
456
|
+
if ( f->pStr ) {
|
457
|
+
if ( f->nUsedLength > 0 ) {
|
458
|
+
memcpy( new_str, f->pStr, sizeof(new_str[0])*f->nUsedLength );
|
459
|
+
}
|
460
|
+
inchi_free( f->pStr );
|
461
|
+
}
|
462
|
+
f->pStr = new_str;
|
463
|
+
f->nAllocatedLength += nAddLength;
|
464
|
+
} else {
|
465
|
+
return -1; /* failed */
|
466
|
+
}
|
467
|
+
}
|
468
|
+
/* output */
|
469
|
+
my_va_start( argList, lpszFormat );
|
470
|
+
ret = vsprintf( f->pStr + f->nUsedLength, lpszFormat, argList );
|
471
|
+
va_end(argList);
|
472
|
+
if ( ret >= 0 ) {
|
473
|
+
f->nUsedLength += ret;
|
474
|
+
}
|
475
|
+
return ret;
|
476
|
+
}
|
477
|
+
}
|
478
|
+
return -1;
|
479
|
+
}
|
480
|
+
#else
|
481
|
+
/**********************************************************************/
|
482
|
+
/* This function's output should not be displayed in the output pane */
|
483
|
+
/**********************************************************************/
|
484
|
+
int inchi_print_nodisplay( INCHI_FILE* f, const char* lpszFormat, ... )
|
485
|
+
{
|
486
|
+
int ret=0, ret2=0;
|
487
|
+
/* char *p=NULL; */
|
488
|
+
|
489
|
+
va_list argList;
|
490
|
+
|
491
|
+
if ( f ) {
|
492
|
+
my_va_start( argList, lpszFormat );
|
493
|
+
ret = vfprintf( f, lpszFormat, argList );
|
494
|
+
va_end( argList );
|
495
|
+
} else {
|
496
|
+
/* printf( "\r" ); */
|
497
|
+
my_va_start( argList, lpszFormat );
|
498
|
+
ret2 = vfprintf( stdout, lpszFormat, argList );
|
499
|
+
/* ret2 = vprintf( lpszFormat, argList ); */
|
500
|
+
va_end( argList );
|
501
|
+
}
|
502
|
+
|
503
|
+
return ret? ret : ret2;
|
504
|
+
}
|
505
|
+
#endif
|
506
|
+
#ifdef INCHI_LIBRARY
|
507
|
+
/*****************************************************************/
|
508
|
+
int my_fprintf( INCHI_FILE* f, const char* lpszFormat, ... )
|
509
|
+
{
|
510
|
+
if ( f ) {
|
511
|
+
int ret=0, max_len;
|
512
|
+
va_list argList;
|
513
|
+
my_va_start( argList, lpszFormat );
|
514
|
+
max_len = GetMaxPrintfLength( lpszFormat, argList);
|
515
|
+
va_end( argList );
|
516
|
+
|
517
|
+
if ( max_len >= 0 ) {
|
518
|
+
if ( f->nAllocatedLength - f->nUsedLength <= max_len ) {
|
519
|
+
/* enlarge output string */
|
520
|
+
int nAddLength = inchi_max( INCHI_ADD_STR_LEN, max_len );
|
521
|
+
char *new_str = (char *)inchi_calloc( f->nAllocatedLength + nAddLength, sizeof(new_str[0]) );
|
522
|
+
if ( new_str ) {
|
523
|
+
if ( f->pStr ) {
|
524
|
+
if ( f->nUsedLength > 0 ) {
|
525
|
+
memcpy( new_str, f->pStr, sizeof(new_str[0])*f->nUsedLength );
|
526
|
+
}
|
527
|
+
inchi_free( f->pStr );
|
528
|
+
}
|
529
|
+
f->pStr = new_str;
|
530
|
+
f->nAllocatedLength += nAddLength;
|
531
|
+
} else {
|
532
|
+
return -1; /* failed */
|
533
|
+
}
|
534
|
+
}
|
535
|
+
/* output */
|
536
|
+
my_va_start( argList, lpszFormat );
|
537
|
+
ret = vsprintf( f->pStr + f->nUsedLength, lpszFormat, argList );
|
538
|
+
va_end(argList);
|
539
|
+
if ( ret >= 0 ) {
|
540
|
+
f->nUsedLength += ret;
|
541
|
+
}
|
542
|
+
return ret;
|
543
|
+
}
|
544
|
+
}
|
545
|
+
return -1;
|
546
|
+
}
|
547
|
+
#else
|
548
|
+
/*****************************************************************/
|
549
|
+
int my_fprintf( INCHI_FILE* f, const char* lpszFormat, ... )
|
550
|
+
{
|
551
|
+
int ret=0, ret2=0;
|
552
|
+
va_list argList;
|
553
|
+
|
554
|
+
#ifndef INCHI_LIB
|
555
|
+
if ( f ) {
|
556
|
+
if ( f == stderr && lpszFormat && lpszFormat[0] && '\r' == lpszFormat[strlen(lpszFormat)-1] ) {
|
557
|
+
#define CONSOLE_LINE_LEN 80
|
558
|
+
#ifndef INCHI_ANSI_ONLY
|
559
|
+
char szLine[CONSOLE_LINE_LEN];
|
560
|
+
my_va_start( argList, lpszFormat );
|
561
|
+
ret = _vsnprintf( szLine, CONSOLE_LINE_LEN-1, lpszFormat, argList );
|
562
|
+
va_end( argList );
|
563
|
+
if ( ret < 0 ) {
|
564
|
+
/* output is longer than the console line */
|
565
|
+
strcpy(szLine+CONSOLE_LINE_LEN-4, "...\r");
|
566
|
+
}
|
567
|
+
fputs( szLine, f );
|
568
|
+
#else
|
569
|
+
my_va_start( argList, lpszFormat );
|
570
|
+
ret = vfprintf( f, lpszFormat, argList );
|
571
|
+
va_end( argList );
|
572
|
+
#endif
|
573
|
+
#undef CONSOLE_LINE_LEN
|
574
|
+
} else {
|
575
|
+
my_va_start( argList, lpszFormat );
|
576
|
+
ret = vfprintf( f, lpszFormat, argList );
|
577
|
+
va_end( argList );
|
578
|
+
}
|
579
|
+
}
|
580
|
+
if ( f != stderr ) {
|
581
|
+
my_va_start( argList, lpszFormat );
|
582
|
+
//ret2 = vfprintf( stderr, lpszFormat, argList );
|
583
|
+
va_end( argList );
|
584
|
+
}
|
585
|
+
#else
|
586
|
+
if ( f ) {
|
587
|
+
my_va_start( argList, lpszFormat );
|
588
|
+
ret = vfprintf( f, lpszFormat, argList );
|
589
|
+
va_end( argList );
|
590
|
+
}
|
591
|
+
#endif
|
592
|
+
|
593
|
+
return ret? ret : ret2;
|
594
|
+
}
|
595
|
+
#endif
|
596
|
+
#ifndef INCHI_ANSI_ONLY
|
597
|
+
/********************************************************************/
|
598
|
+
void FillTableParms( SET_DRAW_PARMS *sdp, INChI **cur_INChI, INChI_Aux **cur_INChI_Aux,
|
599
|
+
INCHI_MODE nMode, int bShowIsotopic, int indx )
|
600
|
+
{
|
601
|
+
TBL_DRAW_PARMS *tdp = sdp->tdp;
|
602
|
+
char (*ReqShownFound)[TDP_NUM_PAR] = tdp->ReqShownFound;
|
603
|
+
int i, j;
|
604
|
+
INChI_Stereo *Stereo;
|
605
|
+
int bShowTaut = (cur_INChI && cur_INChI[indx]->lenTautomer > 0)? 1 : 0;
|
606
|
+
int bRelRac = 0 != (nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ));
|
607
|
+
|
608
|
+
if ( !cur_INChI || !cur_INChI_Aux ) {
|
609
|
+
sdp->tdp->bDrawTbl = 0;
|
610
|
+
sdp->bOrigAtom = 1;
|
611
|
+
return;
|
612
|
+
}
|
613
|
+
|
614
|
+
/* Displayed */
|
615
|
+
ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'\0';
|
616
|
+
ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'\0';
|
617
|
+
/*
|
618
|
+
ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'B';
|
619
|
+
ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'N';
|
620
|
+
*/
|
621
|
+
i = indx;
|
622
|
+
if ( cur_INChI[i] ) {
|
623
|
+
Stereo = bShowIsotopic? cur_INChI[i]->StereoIsotopic : cur_INChI[i]->Stereo;
|
624
|
+
} else {
|
625
|
+
Stereo = NULL;
|
626
|
+
}
|
627
|
+
#if( REL_RAC_STEREO_IGN_1_SC == 1 )
|
628
|
+
if ( Stereo && ( 0 < Stereo->nNumberOfStereoBonds ||
|
629
|
+
0 < Stereo->nNumberOfStereoCenters-bRelRac ) ) {
|
630
|
+
ReqShownFound[ilSHOWN][itSTEREO] = 'S';
|
631
|
+
if ( Stereo->nNumberOfStereoCenters && Stereo->nCompInv2Abs == -1 &&
|
632
|
+
( nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ) ) ) {
|
633
|
+
if ( Stereo->nNumberOfStereoCenters < 2 && !Stereo->nNumberOfStereoBonds ) {
|
634
|
+
ReqShownFound[ilSHOWN][itSTEREO] = '\0';
|
635
|
+
} else
|
636
|
+
if ( Stereo->nNumberOfStereoCenters >= 2 ) {
|
637
|
+
ReqShownFound[ilSHOWN][itSTEREO] = 's'; /* shown Inverted stereo */
|
638
|
+
}
|
639
|
+
}
|
640
|
+
#else /* REL_RAC_STEREO_IGN_1_SC == 0 */
|
641
|
+
if ( Stereo && ( Stereo->nNumberOfStereoBonds || Stereo->nNumberOfStereoCenters ) ) {
|
642
|
+
ReqShownFound[ilSHOWN][itSTEREO] = 'S';
|
643
|
+
if ( Stereo->nNumberOfStereoCenters && Stereo->nCompInv2Abs == -1 &&
|
644
|
+
( nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ) ) ) {
|
645
|
+
/*
|
646
|
+
if ( Stereo->nNumberOfStereoCenters < 2 && !Stereo->nNumberOfStereoBonds ) {
|
647
|
+
ReqShownFound[ilSHOWN][itSTEREO] = '\0';
|
648
|
+
} else
|
649
|
+
if ( Stereo->nNumberOfStereoCenters >= 2 ) {
|
650
|
+
*/
|
651
|
+
ReqShownFound[ilSHOWN][itSTEREO] = 's'; /* shown Inverted stereo */
|
652
|
+
/*
|
653
|
+
}
|
654
|
+
*/
|
655
|
+
}
|
656
|
+
#endif /* REL_RAC_STEREO_IGN_1_SC */
|
657
|
+
} else {
|
658
|
+
ReqShownFound[ilSHOWN][itSTEREO] = '\0';
|
659
|
+
}
|
660
|
+
/*
|
661
|
+
ReqShownFound[ilSHOWN][itSTEREO] =
|
662
|
+
(bShowIsotopic? (cur_INChI[i] && cur_INChI[i]->StereoIsotopic &&
|
663
|
+
(cur_INChI[i]->StereoIsotopic->nNumberOfStereoBonds ||
|
664
|
+
cur_INChI[i]->StereoIsotopic->nNumberOfStereoCenters) )
|
665
|
+
:
|
666
|
+
(cur_INChI[i] && cur_INChI[i]->Stereo &&
|
667
|
+
(cur_INChI[i]->Stereo->nNumberOfStereoBonds ||
|
668
|
+
cur_INChI[i]->Stereo->nNumberOfStereoCenters) )
|
669
|
+
) ? 'S':'\0';
|
670
|
+
*/
|
671
|
+
|
672
|
+
/* remove zeroes between chars */
|
673
|
+
for ( i = j = 0; i < TDP_NUM_PAR; i ++ ) {
|
674
|
+
if ( ReqShownFound[ilSHOWN][i] >= ' ' ) {
|
675
|
+
ReqShownFound[ilSHOWN][j++] = ReqShownFound[ilSHOWN][i];
|
676
|
+
}
|
677
|
+
}
|
678
|
+
i = j;
|
679
|
+
for ( ; i < TDP_NUM_PAR; i ++ ) {
|
680
|
+
ReqShownFound[ilSHOWN][i] = '\0';
|
681
|
+
}
|
682
|
+
|
683
|
+
sdp->tdp->bDrawTbl = j? 1 : 0;
|
684
|
+
sdp->bOrigAtom = 0;
|
685
|
+
}
|
686
|
+
/********************************************************************/
|
687
|
+
void FillCompositeTableParms( SET_DRAW_PARMS *sdp, AT_NUMB StereoFlags,
|
688
|
+
INCHI_MODE nMode, int bShowIsotopic, int bShowTaut )
|
689
|
+
{
|
690
|
+
TBL_DRAW_PARMS *tdp = sdp->tdp;
|
691
|
+
char (*ReqShownFound)[TDP_NUM_PAR] = tdp->ReqShownFound;
|
692
|
+
int i, j;
|
693
|
+
|
694
|
+
/* Displayed */
|
695
|
+
ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'\0';
|
696
|
+
ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'\0';
|
697
|
+
/*
|
698
|
+
ReqShownFound[ilSHOWN][itBASIC] = bShowTaut? 'T':'B';
|
699
|
+
ReqShownFound[ilSHOWN][itISOTOPIC] = bShowIsotopic? 'I':'N';
|
700
|
+
*/
|
701
|
+
if ( StereoFlags & INF_STEREO ) {
|
702
|
+
ReqShownFound[ilSHOWN][itSTEREO] = 'S';
|
703
|
+
if ( (StereoFlags & INF_STEREO_INV) &&
|
704
|
+
( nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO ) ) ) {
|
705
|
+
if (StereoFlags & (INF_STEREO_REL | INF_STEREO_RAC) ) {
|
706
|
+
ReqShownFound[ilSHOWN][itSTEREO] = 's';
|
707
|
+
} else {
|
708
|
+
ReqShownFound[ilSHOWN][itSTEREO] = '\0'; /* shown Inverted stereo */
|
709
|
+
}
|
710
|
+
}
|
711
|
+
} else {
|
712
|
+
ReqShownFound[ilSHOWN][itSTEREO] = '\0';
|
713
|
+
}
|
714
|
+
/*
|
715
|
+
ReqShownFound[ilSHOWN][itSTEREO] =
|
716
|
+
(bShowIsotopic? (cur_INChI[i] && cur_INChI[i]->StereoIsotopic &&
|
717
|
+
(cur_INChI[i]->StereoIsotopic->nNumberOfStereoBonds ||
|
718
|
+
cur_INChI[i]->StereoIsotopic->nNumberOfStereoCenters) )
|
719
|
+
:
|
720
|
+
(cur_INChI[i] && cur_INChI[i]->Stereo &&
|
721
|
+
(cur_INChI[i]->Stereo->nNumberOfStereoBonds ||
|
722
|
+
cur_INChI[i]->Stereo->nNumberOfStereoCenters) )
|
723
|
+
) ? 'S':'\0';
|
724
|
+
*/
|
725
|
+
|
726
|
+
/* remove zeroes between chars */
|
727
|
+
for ( i = j = 0; i < TDP_NUM_PAR; i ++ ) {
|
728
|
+
if ( ReqShownFound[ilSHOWN][i] >= ' ' ) {
|
729
|
+
ReqShownFound[ilSHOWN][j++] = ReqShownFound[ilSHOWN][i];
|
730
|
+
}
|
731
|
+
}
|
732
|
+
i = j;
|
733
|
+
for ( ; i < TDP_NUM_PAR; i ++ ) {
|
734
|
+
ReqShownFound[ilSHOWN][i] = '\0';
|
735
|
+
}
|
736
|
+
|
737
|
+
sdp->tdp->bDrawTbl = j? 1 : 0;
|
738
|
+
sdp->bOrigAtom = 0;
|
739
|
+
}
|
740
|
+
#endif
|
741
|
+
/* IchiParm.c was here */
|
742
|
+
/*******************************************************************/
|
743
|
+
#ifndef INCHI_ANSI_ONLY
|
744
|
+
#ifndef INCHI_LIB
|
745
|
+
/*******************************************************************/
|
746
|
+
int DisplayStructure( inp_ATOM *at, int num_at, int num_removed_H,
|
747
|
+
int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic,
|
748
|
+
int bIsotopic, int j /*bTautomeric*/,
|
749
|
+
INChI **cur_INChI, INChI_Aux **cur_INChI_Aux,
|
750
|
+
int bAbcNumbers, DRAW_PARMS *dp, INCHI_MODE nMode, char *szTitle )
|
751
|
+
{
|
752
|
+
INF_ATOM_DATA inf_data = {NULL,};
|
753
|
+
int err = -1;
|
754
|
+
if ( CreateInfoAtomData( &inf_data, num_at, 1 ) ) {
|
755
|
+
err = 0;
|
756
|
+
FillOutInfAtom( at, &inf_data, num_at, num_removed_H, nNumRemovedProtons,
|
757
|
+
nNumRemovedProtonsIsotopic, bIsotopic,
|
758
|
+
cur_INChI?cur_INChI[j]:NULL,
|
759
|
+
cur_INChI_Aux?cur_INChI_Aux[j]:NULL, bAbcNumbers, nMode);
|
760
|
+
FillTableParms( &dp->sdp, cur_INChI, cur_INChI_Aux, nMode, bIsotopic, j );
|
761
|
+
err = DisplayInputStructure( szTitle, at, &inf_data, num_at, dp );
|
762
|
+
FreeInfoAtomData( &inf_data );
|
763
|
+
}
|
764
|
+
return err;
|
765
|
+
}
|
766
|
+
|
767
|
+
/*******************************************************************/
|
768
|
+
int DisplayCompositeStructure( COMP_ATOM_DATA *composite_norm_data, int bIsotopic, int bTautomeric,
|
769
|
+
PINChI2 *pINChI2, PINChI_Aux2 *pINChI_Aux2,
|
770
|
+
int bAbcNumbers, DRAW_PARMS *dp, INCHI_MODE nMode, char *szTitle )
|
771
|
+
{
|
772
|
+
INF_ATOM_DATA inf_data;
|
773
|
+
int err = -1, ret;
|
774
|
+
memset( &inf_data, 0, sizeof(inf_data) );
|
775
|
+
if ( CreateInfoAtomData( &inf_data, (composite_norm_data+bTautomeric)->num_at,
|
776
|
+
(composite_norm_data+bTautomeric)->num_components ) ) {
|
777
|
+
ret = FillOutCompositeCanonInfAtom(composite_norm_data, &inf_data,
|
778
|
+
bIsotopic, bTautomeric,
|
779
|
+
pINChI2, pINChI_Aux2, bAbcNumbers, nMode);
|
780
|
+
if ( !ret ) {
|
781
|
+
goto exit_function; /* error */
|
782
|
+
}
|
783
|
+
if ( bTautomeric == TAUT_INI ) {
|
784
|
+
/*
|
785
|
+
FillOutInfAtom( (composite_norm_data+bTautomeric)->at, &inf_data, (composite_norm_data+bTautomeric)->num_at,
|
786
|
+
(composite_norm_data+bTautomeric)->num_removed_H,
|
787
|
+
(composite_norm_data+bTautomeric)->nNumRemovedProtons,
|
788
|
+
(composite_norm_data+bTautomeric)->nNumRemovedProtonsIsotopic, bIsotopic,
|
789
|
+
NULL, NULL, bAbcNumbers, nMode);
|
790
|
+
*/
|
791
|
+
;
|
792
|
+
} else {
|
793
|
+
/* real check for tautomeric components 02-04-2005 */
|
794
|
+
int m, nNumTautComponents = 0;
|
795
|
+
if ( 1 == bTautomeric ) {
|
796
|
+
for ( m = 0; m < composite_norm_data[TAUT_YES].num_components; m ++ ) {
|
797
|
+
if ( !pINChI2[m][TAUT_YES] )
|
798
|
+
continue;
|
799
|
+
if ( pINChI2[m][TAUT_YES]->bDeleted || pINChI2[m][TAUT_YES]->lenTautomer > 0 )
|
800
|
+
nNumTautComponents ++;
|
801
|
+
}
|
802
|
+
}
|
803
|
+
FillCompositeTableParms( &dp->sdp, inf_data.StereoFlags, nMode, bIsotopic, nNumTautComponents );
|
804
|
+
}
|
805
|
+
err = DisplayInputStructure( szTitle, (composite_norm_data+bTautomeric)->at, &inf_data, (composite_norm_data+bTautomeric)->num_at, dp );
|
806
|
+
FreeInfoAtomData( &inf_data );
|
807
|
+
}
|
808
|
+
exit_function:
|
809
|
+
return err;
|
810
|
+
}
|
811
|
+
#endif
|
812
|
+
#endif
|
813
|
+
/************************************************/
|
814
|
+
const char *ErrMsg( int nErrorCode )
|
815
|
+
{
|
816
|
+
const char *p;
|
817
|
+
static char szErrMsg[64];
|
818
|
+
switch( nErrorCode ) {
|
819
|
+
case 0: p = ""; break;
|
820
|
+
case CT_OVERFLOW: p = "ARRAY OVERFLOW"; break;
|
821
|
+
case CT_LEN_MISMATCH: p = "LENGTH_MISMATCH"; break;
|
822
|
+
case CT_OUT_OF_RAM: p = "Out of RAM"; break;
|
823
|
+
case CT_RANKING_ERR: p = "RANKING_ERR"; break;
|
824
|
+
case CT_ISOCOUNT_ERR: p = "ISOCOUNT_ERR"; break;
|
825
|
+
case CT_TAUCOUNT_ERR: p = "TAUCOUNT_ERR"; break;
|
826
|
+
case CT_ISOTAUCOUNT_ERR: p = "ISOTAUCOUNT_ERR"; break;
|
827
|
+
case CT_MAPCOUNT_ERR: p = "MAPCOUNT_ERR"; break;
|
828
|
+
case CT_TIMEOUT_ERR: p = "Time limit exceeded"; break;
|
829
|
+
case CT_ISO_H_ERR: p = "ISO_H_ERR"; break;
|
830
|
+
case CT_STEREOCOUNT_ERR: p = "STEREOCOUNT_ERR"; break;
|
831
|
+
case CT_ATOMCOUNT_ERR: p = "ATOMCOUNT_ERR"; break;
|
832
|
+
case CT_STEREOBOND_ERROR: p = "STEREOBOND_ERR"; break;
|
833
|
+
case CT_USER_QUIT_ERR: p = "User requested termination"; break;
|
834
|
+
case CT_REMOVE_STEREO_ERR: p = "REMOVE_STEREO_ERR"; break;
|
835
|
+
case CT_CALC_STEREO_ERR: p = "CALC_STEREO_ERR"; break;
|
836
|
+
case CT_STEREO_CANON_ERR: p = "STEREO_CANON_ERR"; break;
|
837
|
+
case CT_CANON_ERR: p = "CANON_ERR"; break;
|
838
|
+
/*case CT_CANON_ERR2: p = "CT_CANON_ERR2"; break;*/
|
839
|
+
case CT_UNKNOWN_ERR: p = "UNKNOWN_ERR"; break;
|
840
|
+
case BNS_RADICAL_ERR: p = "Cannot process free radical center"; break;
|
841
|
+
|
842
|
+
default:
|
843
|
+
if ( nErrorCode > CT_UNKNOWN_ERR ) {
|
844
|
+
sprintf( szErrMsg, "No description(%d)", nErrorCode );
|
845
|
+
p = szErrMsg;
|
846
|
+
} else {
|
847
|
+
sprintf( szErrMsg, "UNKNOWN_ERR(%d)", CT_UNKNOWN_ERR - nErrorCode );
|
848
|
+
p = szErrMsg;
|
849
|
+
}
|
850
|
+
break;
|
851
|
+
}
|
852
|
+
return p;
|
853
|
+
}
|
854
|
+
/***********************************************************************************/
|
855
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
856
|
+
/***********************************************************************************/
|
857
|
+
int SaveEquComponentsInfoAndSortOrder ( int iINChI, INCHI_SORT *pINChISort[TAUT_NUM], int *num_components,
|
858
|
+
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
|
859
|
+
COMP_ATOM_DATA composite_norm_data[TAUT_NUM+1],
|
860
|
+
int bCompareComponents )
|
861
|
+
{
|
862
|
+
int nRet = 0, i, k, nNumDeleted;
|
863
|
+
/* equivalent components and sorting order */
|
864
|
+
/* bCompareComponents: bit = 1 => compare */
|
865
|
+
/* bit = 2 => compare non-isotopic */
|
866
|
+
/* bit = 4 => compare non-tautomeric */
|
867
|
+
int bCompareIsotopic, bCompareTaut, bCompareAlt;
|
868
|
+
ORIG_ATOM_DATA *inp_data = NULL;
|
869
|
+
|
870
|
+
if ( num_components[iINChI] <= 1 )
|
871
|
+
return 0;
|
872
|
+
#ifdef INCHI_LIB
|
873
|
+
if ( !DRAWDATA )
|
874
|
+
return 0;
|
875
|
+
#endif
|
876
|
+
if ( !(bCompareComponents & CMP_COMPONENTS) )
|
877
|
+
return 0;
|
878
|
+
bCompareIsotopic = !(bCompareComponents & CMP_COMPONENTS_NONISO);
|
879
|
+
bCompareTaut = (bCompareComponents & CMP_COMPONENTS_NONTAUT) ? TAUT_NON : TAUT_YES;
|
880
|
+
bCompareAlt = ALT_TAUT(bCompareTaut);
|
881
|
+
if ( num_components[iINChI] > 1 ) {
|
882
|
+
if ( prep_inp_data[iINChI].bSavedInINCHI_LIB[iINChI] && prep_inp_data[iINChI].bPreprocessed[iINChI] ) {
|
883
|
+
inp_data = prep_inp_data+iINChI;
|
884
|
+
} else
|
885
|
+
if ( orig_inp_data->bSavedInINCHI_LIB[iINChI] && !orig_inp_data->bPreprocessed[iINChI] ) {
|
886
|
+
inp_data = orig_inp_data;
|
887
|
+
} else {
|
888
|
+
inp_data = NULL;
|
889
|
+
}
|
890
|
+
if ( inp_data && !inp_data->nEquLabels && !prep_inp_data[iINChI].nSortedOrder ) {
|
891
|
+
int i1, i2, nSet;
|
892
|
+
AT_NUMB nAtNo;
|
893
|
+
AT_NUMB nNumAtoms = (AT_NUMB)inp_data->num_inp_atoms;
|
894
|
+
if ( (prep_inp_data[iINChI].nSortedOrder =
|
895
|
+
(AT_NUMB *)inchi_calloc(num_components[iINChI]+1,
|
896
|
+
sizeof(prep_inp_data[0].nSortedOrder[0])))) {
|
897
|
+
inp_data->nNumEquSets = 0;
|
898
|
+
for ( i1 = 0, nSet = 0; i1 < num_components[iINChI]; i1 = i2 ) {
|
899
|
+
nNumDeleted = (pINChISort[bCompareTaut][i1].pINChI[bCompareTaut] && pINChISort[bCompareTaut][i1].pINChI[bCompareTaut]->bDeleted);
|
900
|
+
for ( i2 = i1+1; i2 < num_components[iINChI]; i2 ++ ) {
|
901
|
+
/* isotopic/non-isotopic comparison does not separate equivalent components */
|
902
|
+
if ( CompINChI2( pINChISort[bCompareTaut]+i1, pINChISort[bCompareTaut]+i2, bCompareTaut, bCompareIsotopic ) ) {
|
903
|
+
break;
|
904
|
+
} else {
|
905
|
+
nNumDeleted += (pINChISort[bCompareTaut][i2].pINChI[bCompareTaut] && pINChISort[bCompareTaut][i2].pINChI[bCompareTaut]->bDeleted);
|
906
|
+
}
|
907
|
+
}
|
908
|
+
if ( i2 - i1 - nNumDeleted > 1 ) {
|
909
|
+
if ( inp_data->nEquLabels ||
|
910
|
+
(inp_data->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms+1,
|
911
|
+
sizeof(inp_data->nEquLabels[0]))) ) {
|
912
|
+
nSet ++; /* found i2-i1 equivalent components && memory has been allocated */
|
913
|
+
for ( i = i1; i < i2; i ++ ) {
|
914
|
+
INChI_Aux *pINChI_Aux;
|
915
|
+
if (pINChISort[bCompareTaut][i].pINChI[bCompareTaut] && pINChISort[bCompareTaut][i].pINChI[bCompareTaut]->bDeleted)
|
916
|
+
continue;
|
917
|
+
pINChI_Aux = (pINChISort[bCompareTaut][i].pINChI_Aux[bCompareTaut] &&
|
918
|
+
pINChISort[bCompareTaut][i].pINChI_Aux[bCompareTaut]->nNumberOfAtoms)?
|
919
|
+
pINChISort[bCompareTaut][i].pINChI_Aux[bCompareTaut]:
|
920
|
+
(pINChISort[bCompareTaut][i].pINChI_Aux[bCompareAlt] &&
|
921
|
+
pINChISort[bCompareTaut][i].pINChI_Aux[bCompareAlt]->nNumberOfAtoms)?
|
922
|
+
pINChISort[bCompareTaut][i].pINChI_Aux[bCompareAlt]:
|
923
|
+
(INChI_Aux *)NULL;
|
924
|
+
if ( pINChI_Aux && pINChI_Aux->nOrigAtNosInCanonOrd ) {
|
925
|
+
for ( k = 0; k < pINChI_Aux->nNumberOfAtoms; k ++ ) {
|
926
|
+
if ( (nAtNo = pINChI_Aux->nOrigAtNosInCanonOrd[k]) &&
|
927
|
+
nAtNo <= nNumAtoms ) {
|
928
|
+
inp_data->nEquLabels[nAtNo-1] = nSet;
|
929
|
+
}
|
930
|
+
}
|
931
|
+
}
|
932
|
+
}
|
933
|
+
} else {
|
934
|
+
return CT_OUT_OF_RAM;
|
935
|
+
}
|
936
|
+
}
|
937
|
+
}
|
938
|
+
nRet |= nSet? 1:0;
|
939
|
+
} else {
|
940
|
+
return CT_OUT_OF_RAM;
|
941
|
+
}
|
942
|
+
inp_data->nNumEquSets = nSet;
|
943
|
+
/* output order */
|
944
|
+
prep_inp_data[iINChI].nSortedOrder[0] = 0;
|
945
|
+
for ( i1 = 0; i1 < num_components[iINChI]; i1 ++ ) {
|
946
|
+
prep_inp_data[iINChI].nSortedOrder[i1+1] = pINChISort[TAUT_YES][i1].ord_number+1;
|
947
|
+
}
|
948
|
+
#ifdef INCHI_LIB /* { */
|
949
|
+
if ( DRAWDATA && GET_DRAWDATA && inp_data->nNumEquSets > 0 && inp_data->nEquLabels ) {
|
950
|
+
int nType = inp_data->bPreprocessed[iINChI]?
|
951
|
+
COMPONENT_ORIGINAL_PREPROCESSED :
|
952
|
+
COMPONENT_ORIGINAL;
|
953
|
+
struct DrawData *pDrawData = GET_DRAWDATA( 0, nType, iINChI);
|
954
|
+
if ( pDrawData && pDrawData->pWindowData && !pDrawData->pWindowData->nEquLabels ) {
|
955
|
+
/* copy equivalence data from inp_data to pDrawData->pWindowData */
|
956
|
+
if ( inp_data->nEquLabels &&
|
957
|
+
(pDrawData->pWindowData->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms,
|
958
|
+
sizeof(inp_data->nEquLabels[0])))) {
|
959
|
+
memcpy( pDrawData->pWindowData->nEquLabels, inp_data->nEquLabels,
|
960
|
+
inp_data->num_inp_atoms * sizeof(inp_data->nEquLabels[0]));
|
961
|
+
pDrawData->pWindowData->nNumEquSets = inp_data->nNumEquSets;
|
962
|
+
pDrawData->pWindowData->nCurEquLabel = 0;
|
963
|
+
}
|
964
|
+
}
|
965
|
+
}
|
966
|
+
#endif /* } INCHI_LIB */
|
967
|
+
}
|
968
|
+
}
|
969
|
+
return nRet;
|
970
|
+
}
|
971
|
+
|
972
|
+
/************************************************************************************************/
|
973
|
+
int DisplayTheWholeCompositeStructure( INPUT_PARMS *ip, STRUCT_DATA *sd, int num_inp, int iINChI,
|
974
|
+
PINChI2 *pINChI2, PINChI_Aux2 *pINChI_Aux2,
|
975
|
+
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
|
976
|
+
COMP_ATOM_DATA composite_norm_data[TAUT_NUM+1] )
|
977
|
+
{
|
978
|
+
ORIG_ATOM_DATA *inp_data = NULL;
|
979
|
+
int jj, j, k, err = 0, nNumIntermediateTaut = 0, bDisplayTaut;
|
980
|
+
char szTitle[256];
|
981
|
+
int nNumTautComponents, m;
|
982
|
+
|
983
|
+
int bCompareIsotopic = !(ip->bCompareComponents & CMP_COMPONENTS_NONISO);
|
984
|
+
int bCompareTaut = (ip->bCompareComponents & CMP_COMPONENTS_NONTAUT) ? TAUT_NON : TAUT_YES;
|
985
|
+
|
986
|
+
if ( ip->bCompareComponents & CMP_COMPONENTS ) {
|
987
|
+
if ( prep_inp_data[iINChI].bSavedInINCHI_LIB[iINChI] && prep_inp_data[iINChI].bPreprocessed[iINChI] ) {
|
988
|
+
inp_data = prep_inp_data+iINChI;
|
989
|
+
} else
|
990
|
+
if ( orig_inp_data->bSavedInINCHI_LIB[iINChI] && !orig_inp_data->bPreprocessed[iINChI] ) {
|
991
|
+
inp_data = orig_inp_data;
|
992
|
+
}
|
993
|
+
}
|
994
|
+
/**************************************************************************
|
995
|
+
* display from one up to 4 structure pictures-results for all components *
|
996
|
+
* Enable buttons: *
|
997
|
+
* BN (non-tautomeric non-isotopic): inp_norm_data[0]->bExists *
|
998
|
+
* TN (tautomeric non-isotopic): inp_norm_data[1]->bExists *
|
999
|
+
* BI (non-tautomeric isotopic): inp_norm_data[0]->bExists && *
|
1000
|
+
* inp_norm_data[0]->bHasIsotopicLayer *
|
1001
|
+
* TI (tautomeric isotopic): inp_norm_data[1]->bExists && *
|
1002
|
+
* inp_norm_data[1]->bHasIsotopicLayer *
|
1003
|
+
**************************************************************************/
|
1004
|
+
for ( jj = 0; ip->bDisplayCompositeResults && !sd->bUserQuitComponentDisplay && jj <= TAUT_INI; jj ++ ) {
|
1005
|
+
/*for ( j = 0; ip->bDisplayCompositeResults && !sd->bUserQuitComponentDisplay && j <= TAUT_INI; j ++ )*/
|
1006
|
+
j = (jj==0)? TAUT_NON : (jj==1)? TAUT_INI : (jj==2)? TAUT_YES : -1;
|
1007
|
+
if ( j < 0 )
|
1008
|
+
continue;
|
1009
|
+
if ( composite_norm_data[j].bExists && composite_norm_data[j].num_components > 1 ) {
|
1010
|
+
bDisplayTaut = (!(ip->nMode & REQ_MODE_BASIC) && !j)? -1 : j;
|
1011
|
+
nNumTautComponents = 0;
|
1012
|
+
if ( bDisplayTaut ) {
|
1013
|
+
/* find whether the structure is actually tautomeric */
|
1014
|
+
for ( m = 0; m < composite_norm_data[TAUT_YES].num_components; m ++ ) {
|
1015
|
+
if ( !pINChI2[m][TAUT_YES] )
|
1016
|
+
continue;
|
1017
|
+
if ( pINChI2[m][TAUT_YES]->bDeleted || pINChI2[m][TAUT_YES]->lenTautomer > 0 )
|
1018
|
+
nNumTautComponents ++;
|
1019
|
+
}
|
1020
|
+
}
|
1021
|
+
for ( k = 0; k <= composite_norm_data[j].bHasIsotopicLayer && !sd->bUserQuitComponentDisplay; k ++ ) {
|
1022
|
+
/* added number of components, added another format for a single component case - DCh */
|
1023
|
+
int bMobileH = (bDisplayTaut>0 && nNumTautComponents);
|
1024
|
+
sprintf( szTitle, "%s Structure #%d%s%s.%s%s%s%s%s",
|
1025
|
+
j == TAUT_INI? "Preprocessed":"Result for", num_inp,
|
1026
|
+
bMobileH? ", mobile H":
|
1027
|
+
bDisplayTaut==0?", fixed H":"",
|
1028
|
+
/*j? ", mobile H":", fixed H",*/
|
1029
|
+
k? ", isotopic":"",
|
1030
|
+
SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
|
1031
|
+
#ifndef INCHI_LIB
|
1032
|
+
/****** Display composite Result structure **************/
|
1033
|
+
nNumIntermediateTaut += (j == TAUT_INI ); /* display TAUT_INI (preprocessed) only once */
|
1034
|
+
if ( j != TAUT_INI || nNumIntermediateTaut == 1 ) {
|
1035
|
+
err = DisplayCompositeStructure( composite_norm_data, j==TAUT_INI? 1:k /* bIsotopic*/,
|
1036
|
+
j/*tautomeric*/,
|
1037
|
+
j==TAUT_INI? NULL:pINChI2, j==TAUT_INI? NULL:pINChI_Aux2,
|
1038
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
|
1039
|
+
}
|
1040
|
+
if ( sd->bUserQuitComponentDisplay = (err==ESC_KEY) ) {
|
1041
|
+
break;
|
1042
|
+
}
|
1043
|
+
|
1044
|
+
if ( inp_data && inp_data->nEquLabels && inp_data->nNumEquSets && !sd->bUserQuitComponentDisplay &&
|
1045
|
+
((j == bCompareTaut || bCompareTaut && j == TAUT_INI) ||
|
1046
|
+
bCompareTaut && !composite_norm_data[bCompareTaut].bExists) &&
|
1047
|
+
(k == bCompareIsotopic ||
|
1048
|
+
bCompareIsotopic && !composite_norm_data[j].bHasIsotopicLayer) ) {
|
1049
|
+
AT_NUMB nEquSet;
|
1050
|
+
int bDisplaySaved = ip->bDisplay;
|
1051
|
+
/****** Display Equ Sets of composite Result structure **************/
|
1052
|
+
for ( nEquSet = 1; nEquSet <= inp_data->nNumEquSets; nEquSet ++ ) {
|
1053
|
+
sprintf( szTitle, "Equ set %d of %d, %s Structure #%d%s%s.%s%s%s%s%s",
|
1054
|
+
nEquSet, inp_data->nNumEquSets,
|
1055
|
+
j == TAUT_INI? "Preprocessed":"Result for",
|
1056
|
+
num_inp,
|
1057
|
+
(bDisplayTaut>0 && nNumTautComponents)? ", mobile H": bDisplayTaut==0?", fixed H":"",
|
1058
|
+
/*j? ", mobile H":", fixed H",*/
|
1059
|
+
k? ", isotopic":"",
|
1060
|
+
SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
|
1061
|
+
ip->dp.nEquLabels = inp_data->nEquLabels;
|
1062
|
+
ip->dp.nCurEquLabel = nEquSet;
|
1063
|
+
ip->dp.nNumEquSets = inp_data->nNumEquSets;
|
1064
|
+
ip->bDisplay = 1; /* force display if it was not requested */
|
1065
|
+
err = DisplayCompositeStructure( composite_norm_data, k, j,
|
1066
|
+
pINChI2, pINChI_Aux2,
|
1067
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
|
1068
|
+
ip->dp.nEquLabels = NULL;
|
1069
|
+
ip->dp.nCurEquLabel = 0;
|
1070
|
+
ip->dp.nNumEquSets = 0;
|
1071
|
+
ip->bDisplay = bDisplaySaved; /* restore display option */
|
1072
|
+
|
1073
|
+
if ( sd->bUserQuitComponentDisplay = (err==ESC_KEY) ) {
|
1074
|
+
break;
|
1075
|
+
}
|
1076
|
+
}
|
1077
|
+
}
|
1078
|
+
#else
|
1079
|
+
if(DRAWDATA && j <= TAUT_YES)
|
1080
|
+
{
|
1081
|
+
struct DrawData vDrawData;
|
1082
|
+
vDrawData.pWindowData = CreateWinDataComposite_( composite_norm_data, k, j,
|
1083
|
+
pINChI2, pINChI_Aux2,
|
1084
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode);
|
1085
|
+
/* vDrawData.pWindowData = CreateWinData_( composite_norm_data[j].at, composite_norm_data[j].num_at,
|
1086
|
+
k, j, pINChI[i], pINChI_Aux[i],ip->bAbcNumbers, &ip->dp, ip->nMode ); */
|
1087
|
+
if( vDrawData.pWindowData != NULL )
|
1088
|
+
{
|
1089
|
+
int nType;
|
1090
|
+
vDrawData.nComponent = 0;
|
1091
|
+
if( j == 0 )
|
1092
|
+
nType = (k == 0) ? COMPONENT_BN: COMPONENT_BI;
|
1093
|
+
else
|
1094
|
+
nType = (k == 0) ? COMPONENT_TN: COMPONENT_TI;
|
1095
|
+
vDrawData.nType = nType;
|
1096
|
+
vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
|
1097
|
+
vDrawData.szTitle = _strdup(szTitle);
|
1098
|
+
vDrawData.pWindowData->szTitle = _strdup(szTitle);
|
1099
|
+
if ( inp_data && inp_data->nEquLabels && inp_data->nNumEquSets &&
|
1100
|
+
(j == bCompareTaut || bCompareTaut && !composite_norm_data[bCompareTaut].bExists) &&
|
1101
|
+
(k == bCompareIsotopic || bCompareIsotopic && !composite_norm_data[j].bHasIsotopicLayer) &&
|
1102
|
+
(vDrawData.pWindowData->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms,
|
1103
|
+
sizeof(inp_data->nEquLabels[0])))) {
|
1104
|
+
memcpy( vDrawData.pWindowData->nEquLabels, inp_data->nEquLabels,
|
1105
|
+
inp_data->num_inp_atoms * sizeof(inp_data->nEquLabels[0]));
|
1106
|
+
vDrawData.pWindowData->nNumEquSets = inp_data->nNumEquSets;
|
1107
|
+
vDrawData.pWindowData->nCurEquLabel = 0;
|
1108
|
+
}
|
1109
|
+
DRAWDATA(&vDrawData);
|
1110
|
+
}
|
1111
|
+
} else
|
1112
|
+
if(DRAWDATA && GET_DRAWDATA && j == TAUT_INI)
|
1113
|
+
{
|
1114
|
+
struct DrawData vDrawData;
|
1115
|
+
struct DrawData *pDrawData;
|
1116
|
+
|
1117
|
+
if ( !(ip->bCompareComponents & CMP_COMPONENTS) ||
|
1118
|
+
(ip->bCompareComponents & CMP_COMPONENTS_NONTAUT) ||
|
1119
|
+
!k != !composite_norm_data[j].bHasIsotopicLayer ) {
|
1120
|
+
|
1121
|
+
continue;
|
1122
|
+
}
|
1123
|
+
/*
|
1124
|
+
vDrawData.pWindowData = CreateWinDataComposite_( composite_norm_data, k, j,
|
1125
|
+
pINChI2, pINChI_Aux2,
|
1126
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode);
|
1127
|
+
*/
|
1128
|
+
vDrawData.pWindowData = CreateWinDataComposite_( composite_norm_data, 1 /*k*/, j,
|
1129
|
+
NULL, NULL,
|
1130
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode);
|
1131
|
+
if( vDrawData.pWindowData != NULL )
|
1132
|
+
{
|
1133
|
+
int nType = COMPONENT_ORIGINAL_PREPROCESSED;
|
1134
|
+
pDrawData = GET_DRAWDATA( 0, nType, iINChI);
|
1135
|
+
if ( pDrawData ) {
|
1136
|
+
FreeDrawData( pDrawData );
|
1137
|
+
pDrawData->pWindowData = vDrawData.pWindowData;
|
1138
|
+
vDrawData.pWindowData = NULL;
|
1139
|
+
} else {
|
1140
|
+
pDrawData = &vDrawData;
|
1141
|
+
}
|
1142
|
+
|
1143
|
+
/* vDrawData.pWindowData = CreateWinData_( composite_norm_data[j].at, composite_norm_data[j].num_at,
|
1144
|
+
k, j, pINChI[i], pINChI_Aux[i],ip->bAbcNumbers, &ip->dp, ip->nMode ); */
|
1145
|
+
pDrawData->nComponent = 0;
|
1146
|
+
pDrawData->nType = nType;
|
1147
|
+
pDrawData->bReconnected = iINChI; /* 0=>main; 1=>reconnected */
|
1148
|
+
pDrawData->szTitle = _strdup(szTitle);
|
1149
|
+
pDrawData->pWindowData->szTitle = _strdup(szTitle);
|
1150
|
+
if ( inp_data && inp_data->nEquLabels && inp_data->nNumEquSets &&
|
1151
|
+
/*(j == bCompareTaut || bCompareTaut && !composite_norm_data[bCompareTaut].bExists) &&*/
|
1152
|
+
/*(k == bCompareIsotopic || bCompareIsotopic && !composite_norm_data[j].bHasIsotopicLayer) &&*/
|
1153
|
+
(pDrawData->pWindowData->nEquLabels = (AT_NUMB *)inchi_calloc(inp_data->num_inp_atoms,
|
1154
|
+
sizeof(inp_data->nEquLabels[0])))) {
|
1155
|
+
memcpy( pDrawData->pWindowData->nEquLabels, inp_data->nEquLabels,
|
1156
|
+
inp_data->num_inp_atoms * sizeof(inp_data->nEquLabels[0]));
|
1157
|
+
pDrawData->pWindowData->nNumEquSets = inp_data->nNumEquSets;
|
1158
|
+
pDrawData->pWindowData->nCurEquLabel = 0;
|
1159
|
+
}
|
1160
|
+
if ( pDrawData == &vDrawData ) {
|
1161
|
+
DRAWDATA(pDrawData); /* there was no prepocessed structure */
|
1162
|
+
}
|
1163
|
+
}
|
1164
|
+
}
|
1165
|
+
#endif
|
1166
|
+
}
|
1167
|
+
}
|
1168
|
+
}
|
1169
|
+
return err;
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
#endif /* }INCHI_ANSI_ONLY */
|
1173
|
+
|
1174
|
+
|
1175
|
+
|
1176
|
+
/***********************************************************************************/
|
1177
|
+
/* pINChI[INCHI_BAS] refers to either disconnected or original structure; */
|
1178
|
+
/* num_components[INCHI_BAS] > 0 if there was input structure */
|
1179
|
+
/***********************************************************************************/
|
1180
|
+
/* pINChI[INCHI_REC] refers to the reconnected structure, */
|
1181
|
+
/* and only if the inpur structure has been disconnected, that is,*/
|
1182
|
+
/* num_components[INCHI_REC] > 0 */
|
1183
|
+
/***********************************************************************************/
|
1184
|
+
int SortAndPrintINChI( INCHI_FILE *output_file, char *pStr, int nStrLen, INCHI_FILE *log_file,
|
1185
|
+
INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
|
1186
|
+
COMP_ATOM_DATA composite_norm_data[INCHI_NUM][TAUT_NUM+1],
|
1187
|
+
ORIG_STRUCT *pOrigStruct, int num_components[INCHI_NUM],
|
1188
|
+
int num_non_taut[INCHI_NUM], int num_taut[INCHI_NUM],
|
1189
|
+
INCHI_MODE bTautFlags[INCHI_NUM], INCHI_MODE bTautFlagsDone[INCHI_NUM],
|
1190
|
+
NORM_CANON_FLAGS *pncFlags, int num_inp,
|
1191
|
+
PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM], int *pSortPrintINChIFlags )
|
1192
|
+
{
|
1193
|
+
INCHI_SORT *pINChISort[INCHI_NUM][TAUT_NUM];
|
1194
|
+
int j, i, k, k1, ret, iINChI, max_num_components;
|
1195
|
+
INCHI_MODE nMode;
|
1196
|
+
int bDisconnectedCoord = (0 != (bTautFlagsDone[0] & TG_FLAG_DISCONNECT_COORD_DONE));
|
1197
|
+
int bINChIOutputOptions0, bCurOption, bINChIOutputOptionsCur, bEmbedReconnected, bAnnInXmlBrackets;
|
1198
|
+
static char szAnnHdr[] = "InChI ANNOTATED CONTENTS";
|
1199
|
+
|
1200
|
+
ret = 1;
|
1201
|
+
for ( i = 0; i < INCHI_NUM; i ++ ) {
|
1202
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1203
|
+
bTautFlags[i] |= pncFlags->bTautFlags[i][k];
|
1204
|
+
bTautFlagsDone[i] |= pncFlags->bTautFlagsDone[i][k];
|
1205
|
+
}
|
1206
|
+
}
|
1207
|
+
nMode = ip->nMode;
|
1208
|
+
if ( !(nMode & (REQ_MODE_BASIC|REQ_MODE_TAUT)) ) {
|
1209
|
+
nMode |= (REQ_MODE_BASIC|REQ_MODE_TAUT);
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
max_num_components = 0;
|
1213
|
+
for ( j = 0; j < INCHI_NUM; j ++ ) {
|
1214
|
+
if ( max_num_components < num_components[j] )
|
1215
|
+
max_num_components = num_components[j];
|
1216
|
+
}
|
1217
|
+
if ( max_num_components <= 0 )
|
1218
|
+
max_num_components = 1;
|
1219
|
+
|
1220
|
+
for ( j = 0, i = 0; j < INCHI_NUM; j ++ ) {
|
1221
|
+
if ( num_components[j] ) {
|
1222
|
+
for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
|
1223
|
+
pINChISort[j][k1] = (INCHI_SORT *)inchi_calloc(max_num_components, sizeof(pINChISort[0][0][0]) );
|
1224
|
+
i += !pINChISort[j][k1]; /* number of failed allocatons */
|
1225
|
+
}
|
1226
|
+
} else {
|
1227
|
+
for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
|
1228
|
+
pINChISort[j][k1] = NULL;
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
}
|
1232
|
+
if ( i ) {
|
1233
|
+
ret = CT_OUT_OF_RAM;
|
1234
|
+
goto exit_function;
|
1235
|
+
}
|
1236
|
+
|
1237
|
+
|
1238
|
+
for ( j = 0; j < INCHI_NUM; j ++ ) {
|
1239
|
+
|
1240
|
+
if ( !num_components[j] ) {
|
1241
|
+
continue;
|
1242
|
+
}
|
1243
|
+
|
1244
|
+
iINChI = j;
|
1245
|
+
|
1246
|
+
#if( OUTPUT_CONNECTED_METAL_ONLY == 1 ) /* test: output connected as the only one INChI */
|
1247
|
+
if ( INCHI_BAS == j && num_components[INCHI_REC] ) {
|
1248
|
+
j = INCHI_REC;
|
1249
|
+
}
|
1250
|
+
#endif
|
1251
|
+
|
1252
|
+
/*j = INCHI_BAS; <- for debug only */
|
1253
|
+
/* for only normal or disconnected coord compounds */
|
1254
|
+
/* (j=0=INCHI_BAS => normal or disconnected, j=1=INCHI_REC => reconnected */
|
1255
|
+
for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
|
1256
|
+
for ( i = 0; i < num_components[j]; i ++ ) {
|
1257
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1258
|
+
pINChISort[j][k1][i].pINChI[k] = pINChI[j][i][k];
|
1259
|
+
pINChISort[j][k1][i].pINChI_Aux[k] = pINChI_Aux[j][i][k];
|
1260
|
+
}
|
1261
|
+
pINChISort[j][k1][i].ord_number = i;
|
1262
|
+
}
|
1263
|
+
}
|
1264
|
+
/* sort component INChIs */
|
1265
|
+
for ( k1 = 0; k1 < TAUT_NUM; k1 ++ ) {
|
1266
|
+
switch ( k1 ) {
|
1267
|
+
case TAUT_NON:
|
1268
|
+
qsort( pINChISort[j][k1], num_components[j], sizeof(pINChISort[0][0][0]), CompINChINonTaut2 );
|
1269
|
+
break;
|
1270
|
+
case TAUT_YES:
|
1271
|
+
qsort( pINChISort[j][k1], num_components[j], sizeof(pINChISort[0][0][0]), CompINChITaut2 );
|
1272
|
+
break;
|
1273
|
+
}
|
1274
|
+
}
|
1275
|
+
#ifndef INCHI_ANSI_ONLY
|
1276
|
+
/* find equivalent and wINChI display order; use requested in ip->bCompareComponents comparison */
|
1277
|
+
ret = SaveEquComponentsInfoAndSortOrder ( iINChI, pINChISort[j], num_components, orig_inp_data, prep_inp_data,
|
1278
|
+
composite_norm_data[j], ip->bCompareComponents );
|
1279
|
+
if ( RETURNED_ERROR( ret ) ) {
|
1280
|
+
ret = 0;
|
1281
|
+
goto exit_function;
|
1282
|
+
} else {
|
1283
|
+
ret = 1;
|
1284
|
+
}
|
1285
|
+
#endif
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
bINChIOutputOptions0 = ip->bINChIOutputOptions &
|
1289
|
+
~(INCHI_OUT_EMBED_REC |
|
1290
|
+
INCHI_OUT_XML |
|
1291
|
+
INCHI_OUT_PLAIN_TEXT |
|
1292
|
+
INCHI_OUT_PLAIN_TEXT_COMMENTS |
|
1293
|
+
INCHI_OUT_XML_TEXT_COMMENTS);
|
1294
|
+
bEmbedReconnected = ip->bINChIOutputOptions & INCHI_OUT_EMBED_REC;
|
1295
|
+
|
1296
|
+
for ( i = 0; i < 4; i ++ ) {
|
1297
|
+
switch( i ) {
|
1298
|
+
case 0:
|
1299
|
+
bCurOption = INCHI_OUT_XML;
|
1300
|
+
break;
|
1301
|
+
case 1:
|
1302
|
+
bCurOption = INCHI_OUT_PLAIN_TEXT;
|
1303
|
+
break;
|
1304
|
+
case 2:
|
1305
|
+
bCurOption = INCHI_OUT_PLAIN_TEXT_COMMENTS;
|
1306
|
+
break;
|
1307
|
+
case 3:
|
1308
|
+
bCurOption = INCHI_OUT_XML_TEXT_COMMENTS;
|
1309
|
+
break;
|
1310
|
+
default:
|
1311
|
+
continue;
|
1312
|
+
}
|
1313
|
+
if ( ip->bINChIOutputOptions & bCurOption ) {
|
1314
|
+
bAnnInXmlBrackets = 0;
|
1315
|
+
if ( i == 1 ) {
|
1316
|
+
;/*bEmbedReconnected = 0;*/
|
1317
|
+
}
|
1318
|
+
if ( i == 3 ) {
|
1319
|
+
bCurOption = INCHI_OUT_XML; /* xml output as annotation */
|
1320
|
+
}
|
1321
|
+
bINChIOutputOptionsCur = bINChIOutputOptions0 | bCurOption;
|
1322
|
+
switch ( i ) {
|
1323
|
+
case 0:
|
1324
|
+
case 1:
|
1325
|
+
/* output INChI */
|
1326
|
+
bINChIOutputOptionsCur |= bEmbedReconnected;
|
1327
|
+
break;
|
1328
|
+
case 2:
|
1329
|
+
case 3:
|
1330
|
+
/* output annotation */
|
1331
|
+
bAnnInXmlBrackets = (i == 2 && (ip->bINChIOutputOptions & INCHI_OUT_XML ));
|
1332
|
+
if ( bAnnInXmlBrackets ) {
|
1333
|
+
inchi_print( output_file, "\n<%s>\n", szAnnHdr );
|
1334
|
+
} else {
|
1335
|
+
inchi_print( output_file, "\n==== %s ====\n", szAnnHdr );
|
1336
|
+
}
|
1337
|
+
bINChIOutputOptionsCur |= bEmbedReconnected;
|
1338
|
+
bINChIOutputOptionsCur &= ~INCHI_OUT_TABBED_OUTPUT;
|
1339
|
+
break;
|
1340
|
+
default:
|
1341
|
+
continue;
|
1342
|
+
}
|
1343
|
+
|
1344
|
+
ret &= OutputINChI2( pStr, nStrLen, pINChISort, INCHI_BAS /*iINChI*/, pOrigStruct,
|
1345
|
+
bDisconnectedCoord, OUT_TN, bINChIOutputOptionsCur, 0 != (bINChIOutputOptionsCur & INCHI_OUT_XML),
|
1346
|
+
ip->bAbcNumbers, ip->bCtPredecessors, ip->bNoStructLabels,
|
1347
|
+
num_components, num_non_taut, num_taut,
|
1348
|
+
output_file, log_file, num_inp,
|
1349
|
+
ip->pSdfLabel,ip->pSdfValue, ip->lSdfId, pSortPrintINChIFlags );
|
1350
|
+
|
1351
|
+
if ( ret && !(bINChIOutputOptionsCur & INCHI_OUT_EMBED_REC) ) {
|
1352
|
+
ret &= OutputINChI2( pStr, nStrLen, pINChISort, INCHI_REC /*iINChI*/, pOrigStruct,
|
1353
|
+
bDisconnectedCoord, OUT_TN, bINChIOutputOptionsCur, 0 != (bINChIOutputOptionsCur & INCHI_OUT_XML),
|
1354
|
+
ip->bAbcNumbers, ip->bCtPredecessors, ip->bNoStructLabels,
|
1355
|
+
num_components, num_non_taut, num_taut,
|
1356
|
+
output_file, log_file, num_inp,
|
1357
|
+
ip->pSdfLabel,ip->pSdfValue, ip->lSdfId, pSortPrintINChIFlags );
|
1358
|
+
}
|
1359
|
+
if ( bAnnInXmlBrackets ) {
|
1360
|
+
inchi_print( output_file, "</%s>\n\n", szAnnHdr );
|
1361
|
+
}
|
1362
|
+
if ( !ret ) {
|
1363
|
+
break;
|
1364
|
+
}
|
1365
|
+
}
|
1366
|
+
}
|
1367
|
+
|
1368
|
+
exit_function:
|
1369
|
+
for ( j = 0; j < INCHI_NUM; j ++ ) {
|
1370
|
+
for ( k1 = 0, i = 0; k1 < TAUT_NUM; k1 ++ ) {
|
1371
|
+
if ( pINChISort[j][k1] ) {
|
1372
|
+
inchi_free( pINChISort[j][k1] );
|
1373
|
+
}
|
1374
|
+
}
|
1375
|
+
}
|
1376
|
+
ret = ret? 0 : _IS_FATAL;
|
1377
|
+
return ret;
|
1378
|
+
}
|
1379
|
+
/**********************************************************************************/
|
1380
|
+
void FreeAllINChIArrays( PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM], int num_components[INCHI_NUM] )
|
1381
|
+
{
|
1382
|
+
int k;
|
1383
|
+
for ( k = 0; k < INCHI_NUM; k ++ ) {
|
1384
|
+
FreeINChIArrays( pINChI[k], pINChI_Aux[k], num_components[k] );
|
1385
|
+
num_components[k] = 0;
|
1386
|
+
if ( pINChI[k] ) {
|
1387
|
+
inchi_free( pINChI[k] );
|
1388
|
+
pINChI[k] = NULL;
|
1389
|
+
}
|
1390
|
+
if ( pINChI_Aux[k] ) {
|
1391
|
+
inchi_free( pINChI_Aux[k] );
|
1392
|
+
pINChI_Aux[k] = NULL;
|
1393
|
+
}
|
1394
|
+
|
1395
|
+
}
|
1396
|
+
}
|
1397
|
+
/**********************************************************************************/
|
1398
|
+
void FreeINChIArrays( PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int num_components )
|
1399
|
+
{
|
1400
|
+
int i, k;
|
1401
|
+
/* release allocated memory */
|
1402
|
+
if ( pINChI ) {
|
1403
|
+
for ( i = 0; i < num_components; i ++ ) {
|
1404
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1405
|
+
Free_INChI( &pINChI[i][k] );
|
1406
|
+
/*
|
1407
|
+
inchi_free( pINChI[i][k] );
|
1408
|
+
pINChI[i][k] = NULL;
|
1409
|
+
*/
|
1410
|
+
}
|
1411
|
+
}
|
1412
|
+
}
|
1413
|
+
if ( pINChI_Aux ) {
|
1414
|
+
for ( i = 0; i < num_components; i ++ ) {
|
1415
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1416
|
+
Free_INChI_Aux( &pINChI_Aux[i][k] );
|
1417
|
+
/*
|
1418
|
+
inchi_free( pINChI_Aux[i][k] );
|
1419
|
+
pINChI_Aux[i][k] = NULL;
|
1420
|
+
*/
|
1421
|
+
}
|
1422
|
+
}
|
1423
|
+
}
|
1424
|
+
}
|
1425
|
+
|
1426
|
+
|
1427
|
+
/**********************************************
|
1428
|
+
* output " L=V" or " L missing" or ""
|
1429
|
+
* The fprintf format string must contain %s%s%s%s
|
1430
|
+
*/
|
1431
|
+
char gsMissing[] = "is missing";
|
1432
|
+
char gsEmpty[] = "";
|
1433
|
+
char gsSpace[] = " ";
|
1434
|
+
char gsEqual[] = "=";
|
1435
|
+
|
1436
|
+
#ifndef INCHI_LIBRARY
|
1437
|
+
/*********************************************************************************************************/
|
1438
|
+
void SplitTime( unsigned long ulTotalTime, int *hours, int *minutes, int *seconds, int *mseconds )
|
1439
|
+
{
|
1440
|
+
*mseconds = (int)(ulTotalTime % 1000);
|
1441
|
+
ulTotalTime /= 1000;
|
1442
|
+
*seconds = (int)(ulTotalTime % 60);
|
1443
|
+
ulTotalTime /= 60;
|
1444
|
+
*minutes = (int)(ulTotalTime % 60);
|
1445
|
+
ulTotalTime /= 60;
|
1446
|
+
*hours = (int)(ulTotalTime);
|
1447
|
+
}
|
1448
|
+
/*********************************************************************************************************/
|
1449
|
+
int ReadTheStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, FILE *inp_file, ORIG_ATOM_DATA *orig_inp_data,
|
1450
|
+
/* for CML:*/ int inp_index, int *out_index )
|
1451
|
+
{
|
1452
|
+
inchiTime ulTStart;
|
1453
|
+
int nRet = 0, nRet2 = 0;
|
1454
|
+
int bGetOrigCoord = !(ip->bINChIOutputOptions & (INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO));
|
1455
|
+
INCHI_MODE InpAtomFlags = 0; /* reading Molfile may set FLAG_INP_AT_CHIRAL bit */
|
1456
|
+
|
1457
|
+
memset( sd, 0, sizeof(*sd) );
|
1458
|
+
switch ( ip->nInputType ) {
|
1459
|
+
case INPUT_MOLFILE:
|
1460
|
+
case INPUT_SDFILE:
|
1461
|
+
if ( orig_inp_data ) {
|
1462
|
+
if ( ip->pSdfValue && ip->pSdfValue[0] ) {
|
1463
|
+
/* Added 07-29-2003 to avoid inheriting exact value from prev. structure
|
1464
|
+
and to make reference to a (bad) structure with unknown ID Value */
|
1465
|
+
char *p, *q; /* q shadows prev declaration of const char *q */
|
1466
|
+
int n;
|
1467
|
+
if ( (p = strrchr( ip->pSdfValue, '+' )) &&
|
1468
|
+
'[' == *(p-1) && 0 < (n=strtol(p+1,&q,10)) && q[0] && ']'==q[0] && !q[1] ) {
|
1469
|
+
sprintf( p+1, "%d]", n+1 );
|
1470
|
+
} else {
|
1471
|
+
strcat( ip->pSdfValue, " [+1]" );
|
1472
|
+
}
|
1473
|
+
}
|
1474
|
+
InchiTimeGet( &ulTStart );
|
1475
|
+
sd->fPtrStart = (inp_file == stdin)? -1 : ftell( inp_file );
|
1476
|
+
/* read the original structure */
|
1477
|
+
nRet2 = MolfileToOrigAtom( inp_file, orig_inp_data, ip->bMergeAllInputStructures, bGetOrigCoord, ip->bDoNotAddH,
|
1478
|
+
ip->pSdfLabel, ip->pSdfValue, &ip->lSdfId, &ip->lMolfileNumber,
|
1479
|
+
&InpAtomFlags, &sd->nStructReadError, sd->pStrErrStruct );
|
1480
|
+
|
1481
|
+
|
1482
|
+
if ( !ip->bGetSdfileId || ip->lSdfId == 999999) ip->lSdfId = 0;
|
1483
|
+
if ( !ip->bGetMolfileNumber || ip->lMolfileNumber < 0 ) ip->lMolfileNumber = 0;
|
1484
|
+
sd->fPtrEnd = (inp_file == stdin)? -1 : ftell( inp_file );
|
1485
|
+
sd->ulStructTime += InchiTimeElapsed( &ulTStart );
|
1486
|
+
#if( bRELEASE_VERSION == 0 )
|
1487
|
+
sd->bExtract |= orig_inp_data->bExtract;
|
1488
|
+
#endif
|
1489
|
+
/* 2004-11-16: added Molfile Chiral Flag Mode */
|
1490
|
+
/* *****************************************************************************
|
1491
|
+
* Chiral flags are set in:
|
1492
|
+
* - RunICHI.c #1610 -- ReadTheStructure() -- cInChI, wInChI (here)
|
1493
|
+
* - e_IchiMain.c #273 -- main() -- C example of calling InChI dll
|
1494
|
+
* - inchi_dll.c #1662 -- ExtractOneStructure -- InChI dll code
|
1495
|
+
*******************************************************************************/
|
1496
|
+
/* 1. Highest precedence: Chiral Flag set by the user */
|
1497
|
+
if ( ip->bChiralFlag & FLAG_SET_INP_AT_CHIRAL ) {
|
1498
|
+
InpAtomFlags = FLAG_INP_AT_CHIRAL; /* forced by the user */
|
1499
|
+
} else
|
1500
|
+
if ( ip->bChiralFlag & FLAG_SET_INP_AT_NONCHIRAL ) {
|
1501
|
+
InpAtomFlags = FLAG_INP_AT_NONCHIRAL; /* forced by the user */
|
1502
|
+
} else
|
1503
|
+
if ( (InpAtomFlags & FLAG_INP_AT_CHIRAL) && (InpAtomFlags && FLAG_INP_AT_NONCHIRAL) ) {
|
1504
|
+
InpAtomFlags &= ~FLAG_INP_AT_NONCHIRAL;
|
1505
|
+
}
|
1506
|
+
/* save requested flags in the AuxInfo */
|
1507
|
+
sd->bChiralFlag &= ~( FLAG_INP_AT_CHIRAL | FLAG_INP_AT_NONCHIRAL );
|
1508
|
+
sd->bChiralFlag |= InpAtomFlags & ( FLAG_INP_AT_CHIRAL | FLAG_INP_AT_NONCHIRAL );
|
1509
|
+
/* quick fix: modify ip->nMode on the fly */
|
1510
|
+
/* 2. The user requested both Stereo AND Chiral flag */
|
1511
|
+
if ( (ip->nMode & REQ_MODE_CHIR_FLG_STEREO) && (ip->nMode & REQ_MODE_STEREO) ) {
|
1512
|
+
if ( InpAtomFlags & FLAG_INP_AT_CHIRAL ) {
|
1513
|
+
/* structure has chiral flag or the user said it is chiral */
|
1514
|
+
ip->nMode &= ~(REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO);
|
1515
|
+
sd->bChiralFlag |= FLAG_INP_AT_CHIRAL; /* write AuxInfo as chiral */
|
1516
|
+
} else {
|
1517
|
+
ip->nMode &= ~REQ_MODE_RACEMIC_STEREO;
|
1518
|
+
ip->nMode |= REQ_MODE_RELATIVE_STEREO;
|
1519
|
+
sd->bChiralFlag |= FLAG_INP_AT_NONCHIRAL; /* write AuxInfo as explicitly not chiral */
|
1520
|
+
}
|
1521
|
+
}
|
1522
|
+
} else {
|
1523
|
+
/* read the next original structure */
|
1524
|
+
int nStructReadError=0;
|
1525
|
+
if ( !ip->bMergeAllInputStructures ) {
|
1526
|
+
nRet2 = MolfileToOrigAtom( inp_file, NULL, 0, 0, 0,
|
1527
|
+
NULL, NULL, NULL, NULL,
|
1528
|
+
NULL, &nStructReadError, NULL );
|
1529
|
+
if ( nRet2 <= 0 && 10 < nStructReadError && nStructReadError < 20 ) {
|
1530
|
+
return _IS_EOF;
|
1531
|
+
}
|
1532
|
+
} else {
|
1533
|
+
return _IS_EOF;
|
1534
|
+
}
|
1535
|
+
}
|
1536
|
+
break;
|
1537
|
+
case INPUT_INCHI_XML:
|
1538
|
+
case INPUT_INCHI_PLAIN:
|
1539
|
+
if ( orig_inp_data ) {
|
1540
|
+
if ( ip->pSdfValue && ip->pSdfValue[0] ) {
|
1541
|
+
/* Added 07-29-2003 to avoid inheriting exact value from prev. structure
|
1542
|
+
and to make reference to a (bad) structure with unknown ID Value */
|
1543
|
+
char *p, *q;
|
1544
|
+
int n;
|
1545
|
+
if ( (p = strrchr( ip->pSdfValue, '+' )) &&
|
1546
|
+
'[' == *(p-1) && 0 < (n=strtol(p+1,&q,10)) && q[0] && ']'==q[0] && !q[1] ) {
|
1547
|
+
sprintf( p+1, "%d]", n+1 );
|
1548
|
+
} else {
|
1549
|
+
strcat( ip->pSdfValue, " [+1]" );
|
1550
|
+
}
|
1551
|
+
}
|
1552
|
+
InchiTimeGet( &ulTStart );
|
1553
|
+
sd->fPtrStart = (inp_file == stdin)? -1 : ftell( inp_file );
|
1554
|
+
/* read the original structure */
|
1555
|
+
nRet2 = INChIToOrigAtom( inp_file, orig_inp_data, ip->bMergeAllInputStructures,
|
1556
|
+
bGetOrigCoord, ip->bDoNotAddH,
|
1557
|
+
ip->nInputType, ip->pSdfLabel, ip->pSdfValue, &ip->lMolfileNumber,
|
1558
|
+
&InpAtomFlags, &sd->nStructReadError, sd->pStrErrStruct );
|
1559
|
+
/*if ( !ip->bGetSdfileId || ip->lSdfId == 999999) ip->lSdfId = 0;*/
|
1560
|
+
sd->fPtrEnd = (inp_file == stdin)? -1 : ftell( inp_file );
|
1561
|
+
|
1562
|
+
sd->ulStructTime += InchiTimeElapsed( &ulTStart );
|
1563
|
+
#if( bRELEASE_VERSION == 0 )
|
1564
|
+
sd->bExtract |= orig_inp_data->bExtract;
|
1565
|
+
#endif
|
1566
|
+
/* 2004-11-16: added Molfile Chiral Flag Mode */
|
1567
|
+
if ( ip->bChiralFlag & FLAG_SET_INP_AT_CHIRAL ) {
|
1568
|
+
InpAtomFlags = FLAG_INP_AT_CHIRAL; /* forced by the user */
|
1569
|
+
} else
|
1570
|
+
if ( ip->bChiralFlag & FLAG_SET_INP_AT_NONCHIRAL ) {
|
1571
|
+
InpAtomFlags = FLAG_INP_AT_NONCHIRAL; /* forced by the user */
|
1572
|
+
} else
|
1573
|
+
if ( (InpAtomFlags & FLAG_INP_AT_CHIRAL) && (InpAtomFlags && FLAG_INP_AT_NONCHIRAL) ) {
|
1574
|
+
InpAtomFlags &= ~FLAG_INP_AT_NONCHIRAL;
|
1575
|
+
}
|
1576
|
+
sd->bChiralFlag |= InpAtomFlags; /* copy chiral flag to AuxInfo */
|
1577
|
+
/* quick fix: modify ip->nMode on the fly */
|
1578
|
+
if ( (ip->nMode & REQ_MODE_CHIR_FLG_STEREO) && (ip->nMode & REQ_MODE_STEREO) ) {
|
1579
|
+
if ( InpAtomFlags & FLAG_INP_AT_CHIRAL ) {
|
1580
|
+
ip->nMode &= ~(REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO);
|
1581
|
+
} else {
|
1582
|
+
ip->nMode &= ~REQ_MODE_RACEMIC_STEREO;
|
1583
|
+
ip->nMode |= REQ_MODE_RELATIVE_STEREO;
|
1584
|
+
}
|
1585
|
+
}
|
1586
|
+
} else {
|
1587
|
+
/* read the next original structure */
|
1588
|
+
int nStructReadError=0;
|
1589
|
+
if ( !ip->bMergeAllInputStructures ) {
|
1590
|
+
nRet2 = INChIToOrigAtom( inp_file, NULL, 0, 0, 0,
|
1591
|
+
ip->nInputType, NULL, NULL, NULL, NULL, &nStructReadError, NULL );
|
1592
|
+
if ( nRet2 <= 0 && 10 < nStructReadError && nStructReadError < 20 ) {
|
1593
|
+
return _IS_EOF;
|
1594
|
+
}
|
1595
|
+
} else {
|
1596
|
+
return _IS_EOF;
|
1597
|
+
}
|
1598
|
+
}
|
1599
|
+
break;
|
1600
|
+
|
1601
|
+
#if( ADD_CMLPP == 1 )
|
1602
|
+
/* BILLY 8/6/04 */
|
1603
|
+
case INPUT_CMLFILE:
|
1604
|
+
if ( orig_inp_data ) {
|
1605
|
+
|
1606
|
+
InchiTimeGet( &ulTStart );
|
1607
|
+
/*
|
1608
|
+
if ( inp_index >= 0 ) {
|
1609
|
+
sd->fPtrStart = inp_index;
|
1610
|
+
} else {
|
1611
|
+
sd->fPtrStart = GetCmlStructIndex();
|
1612
|
+
}
|
1613
|
+
*/
|
1614
|
+
sd->fPtrStart = -1; /* disable "CopyMOLfile() for CML input files */
|
1615
|
+
sd->fPtrEnd = -1;
|
1616
|
+
/* read the original structure */
|
1617
|
+
nRet = CmlfileToOrigAtom( inp_file, orig_inp_data, ip->bMergeAllInputStructures,
|
1618
|
+
bGetOrigCoord, ip->bDoNotAddH, inp_index, out_index,
|
1619
|
+
ip->pSdfLabel, ip->pSdfValue, &ip->lSdfId,
|
1620
|
+
&sd->nStructReadError, sd->pStrErrStruct );
|
1621
|
+
|
1622
|
+
|
1623
|
+
sd->ulStructTime += InchiTimeElapsed( &ulTStart );
|
1624
|
+
#if( bRELEASE_VERSION == 0 )
|
1625
|
+
sd->bExtract |= orig_inp_data->bExtract;
|
1626
|
+
#endif
|
1627
|
+
} else {
|
1628
|
+
/* read the next original structure */
|
1629
|
+
int nStructReadError=0;
|
1630
|
+
if ( !ip->bMergeAllInputStructures ) {
|
1631
|
+
nRet2 = CmlfileToOrigAtom( inp_file, NULL, 0, 0, 0, inp_index, out_index,
|
1632
|
+
NULL, NULL, NULL, &nStructReadError, NULL );
|
1633
|
+
|
1634
|
+
if ( nRet2 <= 0 && 10 < nStructReadError && nStructReadError < 20 ) {
|
1635
|
+
return _IS_EOF;
|
1636
|
+
}
|
1637
|
+
} else {
|
1638
|
+
return _IS_EOF;
|
1639
|
+
}
|
1640
|
+
}
|
1641
|
+
break;
|
1642
|
+
#endif
|
1643
|
+
|
1644
|
+
default:
|
1645
|
+
nRet = _IS_FATAL; /* wrong file type */
|
1646
|
+
}
|
1647
|
+
return nRet;
|
1648
|
+
}
|
1649
|
+
#endif
|
1650
|
+
/*****************************************************************************************************/
|
1651
|
+
int TreatReadTheStructureErrors( STRUCT_DATA *sd, INPUT_PARMS *ip, int nLogMask,
|
1652
|
+
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
1653
|
+
ORIG_ATOM_DATA *orig_inp_data, int *num_inp, char *pStr, int nStrLen )
|
1654
|
+
{
|
1655
|
+
int nRet = _IS_OKAY;
|
1656
|
+
/* End of file */
|
1657
|
+
if ( 10 < sd->nStructReadError && sd->nStructReadError < 20 ) {
|
1658
|
+
if ( sd->pStrErrStruct[0] ) {
|
1659
|
+
my_fprintf( log_file, "%s inp structure #%d: End of file.%s%s%s%s \n", sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1660
|
+
}
|
1661
|
+
my_fprintf( log_file, "End of file detected after structure #%d. \n", *num_inp-1 );
|
1662
|
+
nRet = _IS_EOF;
|
1663
|
+
goto exit_function; /* end of file */
|
1664
|
+
}
|
1665
|
+
|
1666
|
+
/*(*num_inp) ++;*/
|
1667
|
+
|
1668
|
+
/* Skipping the structures */
|
1669
|
+
if ( *num_inp < ip->first_struct_number ) {
|
1670
|
+
#ifndef INCHI_LIBRARY
|
1671
|
+
if ( log_file != stderr ) {
|
1672
|
+
my_fprintf( stderr, "\rSkipping structure #%d.%s%s%s%s...", *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue));
|
1673
|
+
}
|
1674
|
+
#endif
|
1675
|
+
nRet = sd->nErrorType = _IS_SKIP;
|
1676
|
+
goto exit_function;
|
1677
|
+
}
|
1678
|
+
|
1679
|
+
sd->nErrorType = GetInpStructErrorType( ip, sd->nStructReadError, sd->pStrErrStruct, orig_inp_data->num_inp_atoms );
|
1680
|
+
|
1681
|
+
/* init xml output */
|
1682
|
+
if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && !ip->bXmlStarted ) {
|
1683
|
+
OutputINChIXmlRootStartTag( output_file );
|
1684
|
+
ip->bXmlStarted ++;
|
1685
|
+
}
|
1686
|
+
/* init xml structure block */
|
1687
|
+
if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && !sd->bXmlStructStarted ) {
|
1688
|
+
if ( !OutputINChIXmlStructStartTag( output_file, pStr, 1, nStrLen, ip->bNoStructLabels,
|
1689
|
+
*num_inp, ip->pSdfLabel, ip->pSdfValue ) ) {
|
1690
|
+
my_fprintf( log_file, "Cannot create start xml tag for structure #%d.%s%s%s%s Terminating.\n", *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1691
|
+
sd->bXmlStructStarted = -1;
|
1692
|
+
nRet = _IS_FATAL;
|
1693
|
+
goto exit_function;
|
1694
|
+
}
|
1695
|
+
sd->bXmlStructStarted ++;
|
1696
|
+
}
|
1697
|
+
|
1698
|
+
/* Fatal error */
|
1699
|
+
if ( sd->nErrorType == _IS_FATAL ) {
|
1700
|
+
if ( nLogMask & LOG_MASK_FATAL )
|
1701
|
+
my_fprintf( log_file, "Fatal Error %d (aborted; %s) inp structure #%d.%s%s%s%s\n",
|
1702
|
+
sd->nStructReadError, sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1703
|
+
#if( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 )
|
1704
|
+
if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem ) {
|
1705
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, *num_inp);
|
1706
|
+
}
|
1707
|
+
#endif
|
1708
|
+
/* goto exit_function; */
|
1709
|
+
}
|
1710
|
+
/* Non-fatal errors: do not produce INChI */
|
1711
|
+
if ( sd->nErrorType == _IS_ERROR ) { /* 70 => too many atoms */
|
1712
|
+
if ( nLogMask & LOG_MASK_ERR )
|
1713
|
+
my_fprintf( log_file, "Error %d (no %s; %s) inp structure #%d.%s%s%s%s\n",
|
1714
|
+
sd->nStructReadError, INCHI_NAME, sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1715
|
+
#if( bRELEASE_VERSION == 1 || EXTR_FLAGS == 0 )
|
1716
|
+
if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem) {
|
1717
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, *num_inp);
|
1718
|
+
}
|
1719
|
+
#endif
|
1720
|
+
}
|
1721
|
+
|
1722
|
+
/* Warnings: try to produce INChI */
|
1723
|
+
if ( sd->nErrorType == _IS_WARNING ) {
|
1724
|
+
if ( nLogMask & LOG_MASK_WARN )
|
1725
|
+
my_fprintf( log_file, "Warning: (%s) inp structure #%d.%s%s%s%s\n",
|
1726
|
+
sd->pStrErrStruct, *num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1727
|
+
}
|
1728
|
+
|
1729
|
+
/* xml error/warning processing; close xml struct block if error */
|
1730
|
+
if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
|
1731
|
+
#ifdef INCHI_LIB
|
1732
|
+
|| (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
|
1733
|
+
#endif
|
1734
|
+
) {
|
1735
|
+
if ( sd->nErrorType != _IS_OKAY && sd->nErrorType != _IS_WARNING ) {
|
1736
|
+
sd->nErrorType =
|
1737
|
+
ProcessStructError( output_file, log_file, /*sd->nStructReadError,*/
|
1738
|
+
sd->pStrErrStruct, sd->nErrorType, &sd->bXmlStructStarted, *num_inp, ip, pStr, nStrLen );
|
1739
|
+
}
|
1740
|
+
}
|
1741
|
+
exit_function:
|
1742
|
+
if ( nRet <= _IS_OKAY && sd->nErrorType > 0 ) {
|
1743
|
+
nRet = sd->nErrorType;
|
1744
|
+
}
|
1745
|
+
return nRet;
|
1746
|
+
}
|
1747
|
+
/******************************************************************************************************/
|
1748
|
+
int GetOneComponent( STRUCT_DATA *sd, INPUT_PARMS *ip, INCHI_FILE *log_file, INCHI_FILE *output_file,
|
1749
|
+
INP_ATOM_DATA *inp_cur_data,
|
1750
|
+
ORIG_ATOM_DATA *orig_inp_data, int i, int num_inp, char *pStr, int nStrLen )
|
1751
|
+
{
|
1752
|
+
inchiTime ulTStart;
|
1753
|
+
InchiTimeGet( &ulTStart );
|
1754
|
+
CreateInpAtomData( inp_cur_data, orig_inp_data->nCurAtLen[i], 0 );
|
1755
|
+
inp_cur_data->num_at = ExtractConnectedComponent( orig_inp_data->at, orig_inp_data->num_inp_atoms, i+1, inp_cur_data->at );
|
1756
|
+
sd->ulStructTime += InchiTimeElapsed( &ulTStart );
|
1757
|
+
|
1758
|
+
/* error processing */
|
1759
|
+
if ( inp_cur_data->num_at <= 0 || orig_inp_data->nCurAtLen[i] != inp_cur_data->num_at ) {
|
1760
|
+
/* log error message */
|
1761
|
+
AddMOLfileError(sd->pStrErrStruct, "Cannot extract Component");
|
1762
|
+
my_fprintf( log_file, "%s #%d structure #%d.%s%s%s%s\n", sd->pStrErrStruct, i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue));
|
1763
|
+
sd->nErrorCode = inp_cur_data->num_at < 0? inp_cur_data->num_at : (orig_inp_data->nCurAtLen[i] != inp_cur_data->num_at)? CT_ATOMCOUNT_ERR : CT_UNKNOWN_ERR;
|
1764
|
+
/* num_err ++; */
|
1765
|
+
sd->nErrorType = _IS_ERROR;
|
1766
|
+
if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
|
1767
|
+
#ifdef INCHI_LIB
|
1768
|
+
|| (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
|
1769
|
+
#endif
|
1770
|
+
) {
|
1771
|
+
/* xml error message */
|
1772
|
+
sd->nErrorType = ProcessStructError( output_file, log_file, /*sd->nErrorCode,*/ sd->pStrErrStruct,
|
1773
|
+
sd->nErrorType, &sd->bXmlStructStarted, num_inp, ip, pStr, nStrLen );
|
1774
|
+
}
|
1775
|
+
}
|
1776
|
+
return sd->nErrorType;
|
1777
|
+
}
|
1778
|
+
/*******************************************************************************************/
|
1779
|
+
int GetProcessingWarningsOneINChI(INChI *pINChI, INP_ATOM_DATA *inp_norm_data, char *pStrErrStruct)
|
1780
|
+
{
|
1781
|
+
int i, j;
|
1782
|
+
int nAmbiguousStereoAtoms, nAmbiguousStereoBonds;
|
1783
|
+
nAmbiguousStereoAtoms = 0;
|
1784
|
+
nAmbiguousStereoBonds = 0;
|
1785
|
+
|
1786
|
+
for ( i = 0; i < 2; i ++ ) {
|
1787
|
+
if ( !inp_norm_data->at )
|
1788
|
+
continue;
|
1789
|
+
for ( j = 0; j < pINChI->nNumberOfAtoms; j ++ ) {
|
1790
|
+
if ( inp_norm_data->at[j].bAmbiguousStereo & (AMBIGUOUS_STEREO_ATOM | AMBIGUOUS_STEREO_ATOM_ISO) ) {
|
1791
|
+
nAmbiguousStereoAtoms ++;
|
1792
|
+
}
|
1793
|
+
if ( inp_norm_data->at[j].bAmbiguousStereo & (AMBIGUOUS_STEREO_BOND | AMBIGUOUS_STEREO_BOND_ISO) ) {
|
1794
|
+
nAmbiguousStereoBonds ++;
|
1795
|
+
}
|
1796
|
+
}
|
1797
|
+
}
|
1798
|
+
if ( nAmbiguousStereoAtoms ) {
|
1799
|
+
AddMOLfileError(pStrErrStruct, "Ambiguous stereo:");
|
1800
|
+
AddMOLfileError(pStrErrStruct, "center(s)");
|
1801
|
+
}
|
1802
|
+
if ( nAmbiguousStereoBonds ) {
|
1803
|
+
AddMOLfileError(pStrErrStruct, "Ambiguous stereo:");
|
1804
|
+
AddMOLfileError(pStrErrStruct, "bond(s)");
|
1805
|
+
}
|
1806
|
+
return (nAmbiguousStereoAtoms || nAmbiguousStereoBonds);
|
1807
|
+
}
|
1808
|
+
/*******************************************************************************************/
|
1809
|
+
int GetProcessingWarnings(INChI *cur_INChI[], INP_ATOM_DATA **inp_norm_data, STRUCT_DATA *sd)
|
1810
|
+
{
|
1811
|
+
int i, ret = 0;
|
1812
|
+
for (i = 0; i < TAUT_NUM; i ++ ) {
|
1813
|
+
if ( cur_INChI[i] && cur_INChI[i]->nNumberOfAtoms>0 ) {
|
1814
|
+
ret |= GetProcessingWarningsOneINChI(cur_INChI[i], inp_norm_data[i], sd->pStrErrStruct);
|
1815
|
+
}
|
1816
|
+
}
|
1817
|
+
return ret;
|
1818
|
+
}
|
1819
|
+
|
1820
|
+
/*******************************************************************************************/
|
1821
|
+
int CreateOneComponentINChI( STRUCT_DATA *sd, INPUT_PARMS *ip, INP_ATOM_DATA *inp_cur_data, ORIG_ATOM_DATA *orig_inp_data,
|
1822
|
+
PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int iINChI,
|
1823
|
+
int i, int num_inp, INP_ATOM_DATA **inp_norm_data, NORM_CANON_FLAGS *pncFlags, INCHI_FILE *log_file )
|
1824
|
+
{
|
1825
|
+
inchiTime ulTStart, ulTEnd, *pulTEnd = NULL;
|
1826
|
+
int k, num_at, ret = 0;
|
1827
|
+
int bOrigCoord;
|
1828
|
+
INCHI_MODE bTautFlags = ip->bTautFlags;
|
1829
|
+
INCHI_MODE bTautFlagsDone = (ip->bTautFlagsDone | sd->bTautFlagsDone[INCHI_BAS]);
|
1830
|
+
INChI *cur_INChI[TAUT_NUM];
|
1831
|
+
INChI_Aux *cur_INChI_Aux[TAUT_NUM];
|
1832
|
+
long lElapsedTime;
|
1833
|
+
/*
|
1834
|
+
PINChI2 *pINChI = pINChI2[iINChI];
|
1835
|
+
PINChI_Aux2 *pINChI_Aux = pINChI_Aux2[iINChI];
|
1836
|
+
*/
|
1837
|
+
InchiTimeGet( &ulTStart );
|
1838
|
+
bOrigCoord = !(ip->bINChIOutputOptions & (INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO));
|
1839
|
+
|
1840
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1841
|
+
cur_INChI[k] = NULL;
|
1842
|
+
cur_INChI_Aux[k] = NULL;
|
1843
|
+
}
|
1844
|
+
/* allocate memory for non-tautimeric (k=0) and tautomeric (k=1) results */
|
1845
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1846
|
+
int nAllocMode = (k==TAUT_YES? REQ_MODE_TAUT:0) |
|
1847
|
+
(bTautFlagsDone & ( TG_FLAG_FOUND_ISOTOPIC_H_DONE |
|
1848
|
+
TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE ))?
|
1849
|
+
(ip->nMode & REQ_MODE_ISO):0;
|
1850
|
+
|
1851
|
+
if ( k==TAUT_NON && (ip->nMode & REQ_MODE_BASIC ) ||
|
1852
|
+
k==TAUT_YES && (ip->nMode & REQ_MODE_TAUT ) ) {
|
1853
|
+
/* alloc INChI and INChI_Aux */
|
1854
|
+
cur_INChI[k] = Alloc_INChI( inp_cur_data->at, inp_cur_data->num_at, &inp_cur_data->num_bonds,
|
1855
|
+
&inp_cur_data->num_isotopic, nAllocMode );
|
1856
|
+
cur_INChI_Aux[k] = Alloc_INChI_Aux( inp_cur_data->num_at,
|
1857
|
+
inp_cur_data->num_isotopic, nAllocMode, bOrigCoord );
|
1858
|
+
if ( cur_INChI_Aux[k] ) {
|
1859
|
+
cur_INChI_Aux[k]->bIsIsotopic = inp_cur_data->num_isotopic;
|
1860
|
+
}
|
1861
|
+
/* alloc memory for the output structure: non-tautomeric and tautomeric (for displaying) */
|
1862
|
+
CreateInpAtomData( inp_norm_data[k], inp_cur_data->num_at, k );
|
1863
|
+
} else {
|
1864
|
+
FreeInpAtomData( inp_norm_data[k] );
|
1865
|
+
}
|
1866
|
+
}
|
1867
|
+
lElapsedTime = InchiTimeElapsed( &ulTStart );
|
1868
|
+
if ( ip->msec_MaxTime ) {
|
1869
|
+
ip->msec_LeftTime -= lElapsedTime;
|
1870
|
+
}
|
1871
|
+
sd->ulStructTime += lElapsedTime;
|
1872
|
+
|
1873
|
+
|
1874
|
+
#if( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) )
|
1875
|
+
#if( TEST_RENUMB_ATOMS != 1 )
|
1876
|
+
/* log file / console output */
|
1877
|
+
if ( log_file != stderr ) {
|
1878
|
+
if ( ip->bDisplay )
|
1879
|
+
my_fprintf( log_file, "Component #%d structure #%d.%s%s%s%s...\n", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1880
|
+
else
|
1881
|
+
//my_fprintf( stderr, "Component #%d structure #%d.%s%s%s%s...\r", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1882
|
+
}
|
1883
|
+
#endif
|
1884
|
+
#endif
|
1885
|
+
/******************************************************
|
1886
|
+
*
|
1887
|
+
* Get one component canonical numberings, etc.
|
1888
|
+
*
|
1889
|
+
******************************************************/
|
1890
|
+
|
1891
|
+
/*
|
1892
|
+
* Create_INChI() return value:
|
1893
|
+
* num_at <= 0: error code
|
1894
|
+
* num_at > 0: number of atoms (excluding terminal hydrogen atoms)
|
1895
|
+
* inp_norm_data[0] => non-tautomeric, inp_norm_data[1] => tautomeric
|
1896
|
+
*/
|
1897
|
+
InchiTimeGet( &ulTStart );
|
1898
|
+
if ( ip->msec_MaxTime ) {
|
1899
|
+
ulTEnd = ulTStart;
|
1900
|
+
pulTEnd = &ulTEnd;
|
1901
|
+
if ( ip->msec_LeftTime > 0 ) {
|
1902
|
+
InchiTimeAddMsec( pulTEnd, ip->msec_LeftTime );
|
1903
|
+
}
|
1904
|
+
}
|
1905
|
+
num_at = Create_INChI( cur_INChI, cur_INChI_Aux, orig_inp_data, inp_cur_data->at,
|
1906
|
+
inp_norm_data,
|
1907
|
+
inp_cur_data->num_at,
|
1908
|
+
ip->nMode, &bTautFlags, &bTautFlagsDone, pulTEnd, sd->pStrErrStruct);
|
1909
|
+
SetConnectedComponentNumber( inp_cur_data->at, inp_cur_data->num_at, i+1 ); /* normalization alters structure component number */
|
1910
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1911
|
+
if ( cur_INChI_Aux[k] && cur_INChI_Aux[k]->nNumberOfAtoms > 0 ) {
|
1912
|
+
pncFlags->bNormalizationFlags[iINChI][k] |= cur_INChI_Aux[k]->bNormalizationFlags;
|
1913
|
+
pncFlags->bTautFlags[iINChI][k] |= cur_INChI_Aux[k]->bTautFlags;
|
1914
|
+
pncFlags->bTautFlagsDone[iINChI][k] |= cur_INChI_Aux[k]->bTautFlagsDone;
|
1915
|
+
pncFlags->nCanonFlags[iINChI][k] |= cur_INChI_Aux[k]->nCanonFlags;
|
1916
|
+
}
|
1917
|
+
}
|
1918
|
+
|
1919
|
+
/* Detect errors */
|
1920
|
+
if ( num_at < 0 ) {
|
1921
|
+
sd->nErrorCode = num_at;
|
1922
|
+
} else
|
1923
|
+
if ( num_at == 0 ) {
|
1924
|
+
sd->nErrorCode = -1;
|
1925
|
+
} else
|
1926
|
+
if ( cur_INChI[TAUT_NON] && cur_INChI[TAUT_NON]->nErrorCode ) {
|
1927
|
+
/* non-tautomeric error */
|
1928
|
+
sd->nErrorCode = cur_INChI[TAUT_NON]->nErrorCode;
|
1929
|
+
} else
|
1930
|
+
if ( cur_INChI[TAUT_YES] && cur_INChI[TAUT_YES]->nErrorCode ) {
|
1931
|
+
/* tautomeric error */
|
1932
|
+
sd->nErrorCode = cur_INChI[TAUT_YES]->nErrorCode;
|
1933
|
+
}
|
1934
|
+
#if( bRELEASE_VERSION == 0 )
|
1935
|
+
if ( cur_INChI[TAUT_NON] ) sd->bExtract |= cur_INChI[TAUT_NON]->bExtract;
|
1936
|
+
if ( cur_INChI[TAUT_YES] ) sd->bExtract |= cur_INChI[TAUT_YES]->bExtract;
|
1937
|
+
if ( (TG_FLAG_TEST_TAUT3_SALTS_DONE & bTautFlagsDone) ) {
|
1938
|
+
sd->bExtract |= EXTR_TEST_TAUT3_SALTS_DONE;
|
1939
|
+
}
|
1940
|
+
#endif
|
1941
|
+
/* detect and store stereo warnings */
|
1942
|
+
if ( !sd->nErrorCode ) {
|
1943
|
+
GetProcessingWarnings(cur_INChI, inp_norm_data, sd);
|
1944
|
+
}
|
1945
|
+
|
1946
|
+
lElapsedTime = InchiTimeElapsed( &ulTStart );
|
1947
|
+
if ( ip->msec_MaxTime ) {
|
1948
|
+
ip->msec_LeftTime -= lElapsedTime;
|
1949
|
+
}
|
1950
|
+
sd->ulStructTime += lElapsedTime;
|
1951
|
+
#ifndef INCHI_LIBRARY
|
1952
|
+
/* Display the results */
|
1953
|
+
if ( ip->bDisplay )
|
1954
|
+
eat_keyboard_input();
|
1955
|
+
#endif
|
1956
|
+
/* a) No matter what happened save the allocated INChI pointers */
|
1957
|
+
/* save the INChI of the current component */
|
1958
|
+
|
1959
|
+
InchiTimeGet( &ulTStart );
|
1960
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
1961
|
+
pINChI[i][k] = cur_INChI[k];
|
1962
|
+
pINChI_Aux[i][k] = cur_INChI_Aux[k];
|
1963
|
+
|
1964
|
+
cur_INChI[k] = NULL;
|
1965
|
+
cur_INChI_Aux[k] = NULL;
|
1966
|
+
}
|
1967
|
+
|
1968
|
+
/* b) Count one component structure and/or INChI results only if there was no error */
|
1969
|
+
/* Set inp_norm_data[j]->num_removed_H = number of removed explicit H */
|
1970
|
+
|
1971
|
+
if ( !sd->nErrorCode ) {
|
1972
|
+
|
1973
|
+
/* find where the current processed structure is located */
|
1974
|
+
int cur_is_in_non_taut = (pINChI[i][TAUT_NON] && pINChI[i][TAUT_NON]->nNumberOfAtoms>0);
|
1975
|
+
int cur_is_in_taut = (pINChI[i][TAUT_YES] && pINChI[i][TAUT_YES]->nNumberOfAtoms>0);
|
1976
|
+
int cur_is_non_taut = cur_is_in_non_taut && 0 == pINChI[i][TAUT_NON]->lenTautomer ||
|
1977
|
+
cur_is_in_taut && 0 == pINChI[i][TAUT_YES]->lenTautomer;
|
1978
|
+
int cur_is_taut = cur_is_in_taut && 0 < pINChI[i][TAUT_YES]->lenTautomer;
|
1979
|
+
/*
|
1980
|
+
sd->bTautFlags[iINChI] |= bTautFlags;
|
1981
|
+
sd->bTautFlagsDone[iINChI] |= bTautFlagsDone;
|
1982
|
+
*/
|
1983
|
+
if ( cur_is_non_taut + cur_is_taut ) {
|
1984
|
+
/* count tautomeric and non-tautomeric components of the structures */
|
1985
|
+
int j1 = cur_is_in_non_taut? TAUT_NON:TAUT_YES;
|
1986
|
+
int j2 = cur_is_in_taut? TAUT_YES:TAUT_NON;
|
1987
|
+
int j;
|
1988
|
+
sd->num_non_taut[iINChI] += cur_is_non_taut;
|
1989
|
+
sd->num_taut[iINChI] += cur_is_taut;
|
1990
|
+
for ( j = j1; j <= j2; j ++ ) {
|
1991
|
+
int bIsotopic = (pINChI[i][j]->nNumberOfIsotopicAtoms ||
|
1992
|
+
pINChI[i][j]->nNumberOfIsotopicTGroups ||
|
1993
|
+
pINChI[i][j]->nPossibleLocationsOfIsotopicH && pINChI[i][j]->nPossibleLocationsOfIsotopicH[0]>1);
|
1994
|
+
if ( j == TAUT_YES ) {
|
1995
|
+
bIsotopic |= (0 < pINChI_Aux[i][j]->nNumRemovedIsotopicH[0] +
|
1996
|
+
pINChI_Aux[i][j]->nNumRemovedIsotopicH[1] +
|
1997
|
+
pINChI_Aux[i][j]->nNumRemovedIsotopicH[2]);
|
1998
|
+
}
|
1999
|
+
inp_norm_data[j]->bExists = 1; /* j=0: non-taut exists, j=1: taut exists */
|
2000
|
+
inp_norm_data[j]->bHasIsotopicLayer = bIsotopic;
|
2001
|
+
/*inp_norm_data[j]->num_removed_H = inp_norm_data[j]->num_at - num_at;*/
|
2002
|
+
}
|
2003
|
+
}
|
2004
|
+
}
|
2005
|
+
/*
|
2006
|
+
return (sd->nErrorCode==CT_OUT_OF_RAM || sd->nErrorCode==CT_USER_QUIT_ERR)? _IS_FATAL :
|
2007
|
+
sd->nErrorCode? _IS_ERROR : 0;
|
2008
|
+
*/
|
2009
|
+
if ( sd->nErrorCode==CT_OUT_OF_RAM || sd->nErrorCode==CT_USER_QUIT_ERR ) {
|
2010
|
+
ret = _IS_FATAL;
|
2011
|
+
} else
|
2012
|
+
if ( sd->nErrorCode ) {
|
2013
|
+
ret = _IS_ERROR;
|
2014
|
+
}
|
2015
|
+
lElapsedTime = InchiTimeElapsed( &ulTStart );
|
2016
|
+
if ( ip->msec_MaxTime ) {
|
2017
|
+
ip->msec_LeftTime -= lElapsedTime;
|
2018
|
+
}
|
2019
|
+
sd->ulStructTime += lElapsedTime;
|
2020
|
+
return ret;
|
2021
|
+
}
|
2022
|
+
/****************************************************************************************************/
|
2023
|
+
int TreatCreateOneComponentINChIError(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data,
|
2024
|
+
int i, int num_inp,
|
2025
|
+
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
2026
|
+
char *pStr, int nStrLen )
|
2027
|
+
{
|
2028
|
+
if ( sd->nErrorCode ) {
|
2029
|
+
AddMOLfileError(sd->pStrErrStruct, ErrMsg(sd->nErrorCode) );
|
2030
|
+
my_fprintf( log_file, "Error %d (%s) structure #%d component %d.%s%s%s%s\n",
|
2031
|
+
sd->nErrorCode, sd->pStrErrStruct, num_inp, i+1, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2032
|
+
sd->nErrorType = (sd->nErrorCode==CT_OUT_OF_RAM || sd->nErrorCode==CT_USER_QUIT_ERR)? _IS_FATAL : _IS_ERROR;
|
2033
|
+
if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
|
2034
|
+
#ifdef INCHI_LIB
|
2035
|
+
|| (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
|
2036
|
+
#endif
|
2037
|
+
) {
|
2038
|
+
sd->nErrorType = ProcessStructError( output_file, log_file, /*sd->nErrorCode,*/ sd->pStrErrStruct,
|
2039
|
+
sd->nErrorType, &sd->bXmlStructStarted, num_inp, ip, pStr, nStrLen );
|
2040
|
+
/* save the problem structure */
|
2041
|
+
if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem ) {
|
2042
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
|
2043
|
+
}
|
2044
|
+
} else {
|
2045
|
+
/* save the problem structure */
|
2046
|
+
if ( sd->nErrorCode && prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && !ip->bSaveAllGoodStructsAsProblem ) {
|
2047
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
|
2048
|
+
}
|
2049
|
+
}
|
2050
|
+
}
|
2051
|
+
#ifndef INCHI_LIBRARY
|
2052
|
+
/* print the logfile record */
|
2053
|
+
if ( log_file && log_file != stderr && (sd->ulStructTime >= 1000 || sd->nErrorCode) ) {
|
2054
|
+
fprintf( log_file, "%10lu msec structure #%d.%s%s%s%s (%d component%s, %d atom%s, error=%d).\n",
|
2055
|
+
sd->ulStructTime, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue),
|
2056
|
+
orig_inp_data->num_components, orig_inp_data->num_components==1?"":"s",
|
2057
|
+
orig_inp_data->num_inp_atoms, orig_inp_data->num_inp_atoms==1?"":"s", sd->nErrorCode );
|
2058
|
+
}
|
2059
|
+
#endif
|
2060
|
+
return sd->nErrorType;
|
2061
|
+
}
|
2062
|
+
/****************************************************************************************************/
|
2063
|
+
int TreatCreateINChIWarning(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, int num_inp,
|
2064
|
+
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
2065
|
+
char *pStr, int nStrLen )
|
2066
|
+
{
|
2067
|
+
#if( bRELEASE_VERSION == 0 && (EXTR_FLAGS || EXTR_MASK) )
|
2068
|
+
if ( EXTR_MASK? ((sd->bExtract & EXTR_MASK) == EXTR_FLAGS) : (sd->bExtract & EXTR_FLAGS) ) {
|
2069
|
+
char szMsg[64];
|
2070
|
+
sprintf( szMsg, "ExtractStruct.code=0x%X", sd->bExtract);
|
2071
|
+
AddMOLfileError(sd->pStrErrStruct, szMsg);
|
2072
|
+
}
|
2073
|
+
#endif
|
2074
|
+
if ( !sd->nErrorCode && sd->pStrErrStruct[0] ) {
|
2075
|
+
my_fprintf( log_file, "Warning (%s) structure #%d.%s%s%s%s\n",
|
2076
|
+
sd->pStrErrStruct, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2077
|
+
sd->nErrorType = _IS_WARNING;
|
2078
|
+
if ( (ip->bINChIOutputOptions & INCHI_OUT_XML)
|
2079
|
+
#ifdef INCHI_LIB
|
2080
|
+
|| (ip->bINChIOutputOptions & INCHI_OUT_WINCHI_WINDOW) && (ip->bINChIOutputOptions & INCHI_OUT_PLAIN_TEXT)
|
2081
|
+
#endif
|
2082
|
+
) {
|
2083
|
+
sd->nErrorType = ProcessStructError( output_file, log_file, /*sd->nErrorCode,*/ sd->pStrErrStruct,
|
2084
|
+
sd->nErrorType, &sd->bXmlStructStarted, num_inp, ip, pStr, nStrLen );
|
2085
|
+
}
|
2086
|
+
/* save the structure as a problem structure if requested */
|
2087
|
+
if ( ip->bSaveWarningStructsAsProblem && !ip->bSaveAllGoodStructsAsProblem &&
|
2088
|
+
prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd ) {
|
2089
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
|
2090
|
+
}
|
2091
|
+
#if( bRELEASE_VERSION == 0 )
|
2092
|
+
/* otherwise extract the structure as a problem structure if requested */
|
2093
|
+
else
|
2094
|
+
if ( (EXTR_MASK? ((sd->bExtract & EXTR_MASK) == EXTR_FLAGS) : (sd->bExtract & EXTR_FLAGS)) && !ip->bSaveAllGoodStructsAsProblem &&
|
2095
|
+
prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd ) {
|
2096
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, num_inp);
|
2097
|
+
}
|
2098
|
+
#endif
|
2099
|
+
}
|
2100
|
+
#if( bRELEASE_VERSION != 1 && bOUTPUT_ONE_STRUCT_TIME == 1 )
|
2101
|
+
#ifndef INCHI_LIBRARY
|
2102
|
+
if ( log_file && log_file != stderr ) {
|
2103
|
+
fprintf( log_file, "%10lu msec structure %1dD #%d.%s%s%s%s (%d component%s, %d atom%s, error=%d).\n",
|
2104
|
+
sd->ulStructTime, orig_inp_data->num_dimensions, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue),
|
2105
|
+
orig_inp_data->num_components, orig_inp_data->num_components==1?"":"s",
|
2106
|
+
orig_inp_data->num_inp_atoms, orig_inp_data->num_inp_atoms==1?"":"s", sd->nErrorCode );
|
2107
|
+
}
|
2108
|
+
#else
|
2109
|
+
if ( log_file ) {
|
2110
|
+
my_fprintf( log_file, "%10lu msec structure %1dD #%d.%s%s%s%s (%d component%s, %d atom%s, error=%d).\n",
|
2111
|
+
sd->ulStructTime, orig_inp_data->num_dimensions, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue),
|
2112
|
+
orig_inp_data->num_components, orig_inp_data->num_components==1?"":"s",
|
2113
|
+
orig_inp_data->num_inp_atoms, orig_inp_data->num_inp_atoms==1?"":"s", sd->nErrorCode );
|
2114
|
+
}
|
2115
|
+
#endif
|
2116
|
+
#endif
|
2117
|
+
return sd->nErrorType;
|
2118
|
+
}
|
2119
|
+
/*******************************************************************************************/
|
2120
|
+
int DuplicateOrigAtom( ORIG_ATOM_DATA *new_orig_atom, ORIG_ATOM_DATA *orig_atom )
|
2121
|
+
{
|
2122
|
+
inp_ATOM *at = NULL;
|
2123
|
+
AT_NUMB *nCurAtLen = NULL;
|
2124
|
+
AT_NUMB *nOldCompNumber = NULL;
|
2125
|
+
|
2126
|
+
if ( new_orig_atom->at && new_orig_atom->num_inp_atoms >= orig_atom->num_inp_atoms ) {
|
2127
|
+
at = new_orig_atom->at;
|
2128
|
+
} else {
|
2129
|
+
at = (inp_ATOM *)inchi_calloc(orig_atom->num_inp_atoms+1, sizeof(at[0]));
|
2130
|
+
}
|
2131
|
+
if ( new_orig_atom->nOldCompNumber && new_orig_atom->num_components >= orig_atom->num_components ) {
|
2132
|
+
nCurAtLen = new_orig_atom->nCurAtLen;
|
2133
|
+
} else {
|
2134
|
+
nCurAtLen = (AT_NUMB *)inchi_calloc(orig_atom->num_components+1, sizeof(nCurAtLen[0]));
|
2135
|
+
}
|
2136
|
+
if ( new_orig_atom->nCurAtLen && new_orig_atom->num_components >= orig_atom->num_components ) {
|
2137
|
+
nOldCompNumber = new_orig_atom->nOldCompNumber;
|
2138
|
+
} else {
|
2139
|
+
nOldCompNumber = (AT_NUMB *)inchi_calloc(orig_atom->num_components+1, sizeof(nOldCompNumber[0]));
|
2140
|
+
}
|
2141
|
+
|
2142
|
+
if ( at && nCurAtLen && nOldCompNumber ) {
|
2143
|
+
/* copy */
|
2144
|
+
if ( orig_atom->at )
|
2145
|
+
memcpy( at, orig_atom->at, orig_atom->num_inp_atoms * sizeof(new_orig_atom->at[0]) );
|
2146
|
+
if ( orig_atom->nCurAtLen )
|
2147
|
+
memcpy( nCurAtLen, orig_atom->nCurAtLen, orig_atom->num_components*sizeof(nCurAtLen[0]) );
|
2148
|
+
if ( orig_atom->nOldCompNumber )
|
2149
|
+
memcpy( nOldCompNumber, orig_atom->nOldCompNumber, orig_atom->num_components*sizeof(nOldCompNumber[0]) );
|
2150
|
+
/* deallocate */
|
2151
|
+
if ( new_orig_atom->at && new_orig_atom->at != at )
|
2152
|
+
inchi_free( new_orig_atom->at );
|
2153
|
+
if ( new_orig_atom->nCurAtLen && new_orig_atom->nCurAtLen != nCurAtLen )
|
2154
|
+
inchi_free( new_orig_atom->nCurAtLen );
|
2155
|
+
if ( new_orig_atom->nOldCompNumber && new_orig_atom->nOldCompNumber != nOldCompNumber )
|
2156
|
+
inchi_free( new_orig_atom->nOldCompNumber );
|
2157
|
+
|
2158
|
+
*new_orig_atom = *orig_atom;
|
2159
|
+
new_orig_atom->at = at;
|
2160
|
+
new_orig_atom->nCurAtLen = nCurAtLen;
|
2161
|
+
new_orig_atom->nOldCompNumber = nOldCompNumber;
|
2162
|
+
/* data that are not to be copied */
|
2163
|
+
new_orig_atom->nNumEquSets = 0;
|
2164
|
+
memset(new_orig_atom->bSavedInINCHI_LIB, 0, sizeof(new_orig_atom->bSavedInINCHI_LIB));
|
2165
|
+
memset(new_orig_atom->bPreprocessed, 0, sizeof(new_orig_atom->bPreprocessed));
|
2166
|
+
/* arrays that are not to be copied */
|
2167
|
+
new_orig_atom->szCoord = NULL;
|
2168
|
+
new_orig_atom->nEquLabels = NULL;
|
2169
|
+
new_orig_atom->nSortedOrder = NULL;
|
2170
|
+
return 0;
|
2171
|
+
}
|
2172
|
+
|
2173
|
+
/* deallocate */
|
2174
|
+
if ( at && new_orig_atom->at != at )
|
2175
|
+
inchi_free( at );
|
2176
|
+
if ( nCurAtLen && new_orig_atom->nCurAtLen != nCurAtLen )
|
2177
|
+
inchi_free( nCurAtLen );
|
2178
|
+
if ( nOldCompNumber && new_orig_atom->nOldCompNumber != nOldCompNumber )
|
2179
|
+
inchi_free( nOldCompNumber );
|
2180
|
+
|
2181
|
+
return -1; /* failed */
|
2182
|
+
}
|
2183
|
+
#ifndef INCHI_LIBRARY
|
2184
|
+
/*******************************************************************************************/
|
2185
|
+
int GetOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
|
2186
|
+
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
2187
|
+
ORIG_ATOM_DATA *orig_inp_data, int *num_inp, char *pStr, int nStrLen, STRUCT_FPTRS *struct_fptrs )
|
2188
|
+
{
|
2189
|
+
int nRet, inp_index, out_index, bUseFptr = (NULL != struct_fptrs);
|
2190
|
+
|
2191
|
+
FreeOrigAtData( orig_inp_data );
|
2192
|
+
/*
|
2193
|
+
FreeOrigAtData( orig_inp_data + 1 );
|
2194
|
+
FreeOrigAtData( orig_inp_data + 2 );
|
2195
|
+
*/
|
2196
|
+
|
2197
|
+
/* added for INCHI_LIB early EOF detection */
|
2198
|
+
inp_index = -1;
|
2199
|
+
out_index = -1;
|
2200
|
+
if ( struct_fptrs ) {
|
2201
|
+
if ( inp_file == stdin ) {
|
2202
|
+
return _IS_FATAL;
|
2203
|
+
}
|
2204
|
+
if ( ip->nInputType == INPUT_CMLFILE ) {
|
2205
|
+
bUseFptr = 0;
|
2206
|
+
}
|
2207
|
+
/* initially allocate or increase length of struct_fptrs->fptr array */
|
2208
|
+
if ( !struct_fptrs->fptr || struct_fptrs->len_fptr <= struct_fptrs->cur_fptr+1 ) {
|
2209
|
+
INCHI_FPTR *new_fptr = (INCHI_FPTR *)inchi_calloc( struct_fptrs->len_fptr + ADD_LEN_STRUCT_FPTRS, sizeof(new_fptr[0]) );
|
2210
|
+
if ( new_fptr ) {
|
2211
|
+
if ( struct_fptrs->fptr ) {
|
2212
|
+
if ( struct_fptrs->len_fptr ) {
|
2213
|
+
memcpy( new_fptr, struct_fptrs->fptr, struct_fptrs->len_fptr*sizeof(new_fptr[0]));
|
2214
|
+
}
|
2215
|
+
inchi_free( struct_fptrs->fptr );
|
2216
|
+
} else {
|
2217
|
+
struct_fptrs->len_fptr = 0;
|
2218
|
+
struct_fptrs->cur_fptr = 0;
|
2219
|
+
struct_fptrs->max_fptr = 0;
|
2220
|
+
}
|
2221
|
+
struct_fptrs->len_fptr += ADD_LEN_STRUCT_FPTRS;
|
2222
|
+
struct_fptrs->fptr = new_fptr;
|
2223
|
+
} else {
|
2224
|
+
return _IS_FATAL; /* new_fptr allocation error */
|
2225
|
+
}
|
2226
|
+
}
|
2227
|
+
if ( struct_fptrs->fptr[struct_fptrs->cur_fptr] == EOF ) {
|
2228
|
+
return _IS_EOF;
|
2229
|
+
} else {
|
2230
|
+
if ( bUseFptr ) {
|
2231
|
+
if( fseek( inp_file, struct_fptrs->fptr[struct_fptrs->cur_fptr], SEEK_SET) ) {
|
2232
|
+
return _IS_FATAL;
|
2233
|
+
}
|
2234
|
+
if ( struct_fptrs->cur_fptr && struct_fptrs->max_fptr <= struct_fptrs->cur_fptr ) {
|
2235
|
+
return _IS_FATAL;
|
2236
|
+
}
|
2237
|
+
} else {
|
2238
|
+
inp_index = struct_fptrs->fptr[struct_fptrs->cur_fptr];
|
2239
|
+
out_index = EOF;
|
2240
|
+
}
|
2241
|
+
}
|
2242
|
+
*num_inp = struct_fptrs->cur_fptr; /* set structure count */
|
2243
|
+
}
|
2244
|
+
|
2245
|
+
nRet = ReadTheStructure( sd, ip, inp_file, orig_inp_data, inp_index, &out_index );
|
2246
|
+
|
2247
|
+
if ( !nRet ) {
|
2248
|
+
/*****************************************************
|
2249
|
+
* In case of no error output structure xml start tag
|
2250
|
+
* output read the structure errors and warnings
|
2251
|
+
*****************************************************/
|
2252
|
+
if ( ip->nInputType == INPUT_INCHI_PLAIN || ip->nInputType == INPUT_INCHI_XML ||
|
2253
|
+
ip->nInputType == INPUT_MOLFILE || ip->nInputType == INPUT_SDFILE) {
|
2254
|
+
if ( ip->lMolfileNumber ) {
|
2255
|
+
*num_inp = ip->lMolfileNumber;
|
2256
|
+
} else {
|
2257
|
+
*num_inp += 1;
|
2258
|
+
}
|
2259
|
+
} else {
|
2260
|
+
*num_inp += 1;
|
2261
|
+
}
|
2262
|
+
nRet = TreatReadTheStructureErrors( sd, ip, LOG_MASK_ALL, inp_file, log_file, output_file, prb_file,
|
2263
|
+
orig_inp_data, num_inp, pStr, nStrLen );
|
2264
|
+
}
|
2265
|
+
|
2266
|
+
/************************************************************/
|
2267
|
+
/* added for INCHI_LIB: look ahead for end of file detection */
|
2268
|
+
/************************************************************/
|
2269
|
+
if ( struct_fptrs && struct_fptrs->fptr && struct_fptrs->fptr[struct_fptrs->cur_fptr+1] <= 0 ) {
|
2270
|
+
int nRet2 = 0;
|
2271
|
+
INCHI_FPTR next_fptr;
|
2272
|
+
STRUCT_DATA sd2;
|
2273
|
+
|
2274
|
+
if ( nRet != _IS_EOF && nRet != _IS_FATAL ) {
|
2275
|
+
if ( inp_file == stdin || struct_fptrs->len_fptr <= struct_fptrs->cur_fptr+1 ) {
|
2276
|
+
return _IS_FATAL;
|
2277
|
+
}
|
2278
|
+
/* get next structure fptr */
|
2279
|
+
if ( bUseFptr ) {
|
2280
|
+
next_fptr = ftell( inp_file );
|
2281
|
+
} else {
|
2282
|
+
inp_index = out_index;
|
2283
|
+
out_index = EOF;
|
2284
|
+
}
|
2285
|
+
/* read the next structure */
|
2286
|
+
nRet2 = ReadTheStructure( &sd2, ip, inp_file, NULL, inp_index, &out_index );
|
2287
|
+
/* restore fptr to the next structure */
|
2288
|
+
if ( bUseFptr ) {
|
2289
|
+
if ( next_fptr != -1L ) {
|
2290
|
+
fseek( inp_file, next_fptr, SEEK_SET);
|
2291
|
+
}
|
2292
|
+
}
|
2293
|
+
#if ( ADD_CMLPP == 1 )
|
2294
|
+
else {
|
2295
|
+
if ( inp_index >= 0 ) {
|
2296
|
+
SetCmlStructIndex( inp_index ); /* so far nothing to do */
|
2297
|
+
}
|
2298
|
+
}
|
2299
|
+
#endif
|
2300
|
+
} else {
|
2301
|
+
/* treat current fatal error as end of file */
|
2302
|
+
struct_fptrs->fptr[struct_fptrs->cur_fptr] = EOF;
|
2303
|
+
}
|
2304
|
+
/* next is end of file or fatal */
|
2305
|
+
if ( nRet == _IS_EOF || nRet == _IS_FATAL ||
|
2306
|
+
nRet2 == _IS_EOF || nRet2 == _IS_FATAL ) {
|
2307
|
+
struct_fptrs->fptr[struct_fptrs->cur_fptr+1] = EOF;
|
2308
|
+
} else {
|
2309
|
+
struct_fptrs->fptr[struct_fptrs->cur_fptr+1] = bUseFptr? sd->fPtrEnd : inp_index;
|
2310
|
+
}
|
2311
|
+
|
2312
|
+
/* update struct_fptrs->max_fptr */
|
2313
|
+
if ( struct_fptrs->max_fptr <= struct_fptrs->cur_fptr+1 ) {
|
2314
|
+
struct_fptrs->max_fptr = struct_fptrs->cur_fptr+2;
|
2315
|
+
}
|
2316
|
+
}
|
2317
|
+
|
2318
|
+
switch ( nRet ) {
|
2319
|
+
case _IS_EOF:
|
2320
|
+
*num_inp -= 1;
|
2321
|
+
case _IS_FATAL:
|
2322
|
+
case _IS_ERROR:
|
2323
|
+
case _IS_SKIP:
|
2324
|
+
goto exit_function;
|
2325
|
+
}
|
2326
|
+
|
2327
|
+
/*
|
2328
|
+
if ( !orig_inp_data->num_dimensions ) {
|
2329
|
+
AddMOLfileError(sd->pStrErrStruct, "0D"); */ /* 0D-structure: no coordinates
|
2330
|
+
}
|
2331
|
+
*/
|
2332
|
+
|
2333
|
+
|
2334
|
+
exit_function:
|
2335
|
+
return nRet;
|
2336
|
+
}
|
2337
|
+
#endif
|
2338
|
+
#if( TEST_RENUMB_ATOMS == 1 ) /* { */
|
2339
|
+
/************************************************************************************************/
|
2340
|
+
int RenumberingTestInit( RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data )
|
2341
|
+
{
|
2342
|
+
int j;
|
2343
|
+
pRenumbData->ren_inp_norm_data[0] = &pRenumbData->ren_inp_norm_data1;
|
2344
|
+
pRenumbData->ren_inp_norm_data[1] = &pRenumbData->ren_inp_norm_data2;
|
2345
|
+
memset( pRenumbData->ren_INChI2, 0, sizeof( pRenumbData->ren_INChI2 ));
|
2346
|
+
memset( pRenumbData->ren_INChI_Aux, 0, sizeof( pRenumbData->ren_INChI_Aux ));
|
2347
|
+
memset( &pRenumbData->orig_inp_cur_data, 0, sizeof( pRenumbData->orig_inp_cur_data ));
|
2348
|
+
memset( &pRenumbData->saved_inp_cur_data, 0, sizeof( pRenumbData->saved_inp_cur_data ));
|
2349
|
+
memset( pRenumbData->ren_inp_norm_data[0], 0, sizeof( *pRenumbData->ren_inp_norm_data[0] ));
|
2350
|
+
memset( pRenumbData->ren_inp_norm_data[1], 0, sizeof( *pRenumbData->ren_inp_norm_data[1] ));
|
2351
|
+
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
|
2352
|
+
memset( &pRenumbData->longest_inp_cur_data, 0, sizeof(pRenumbData->longest_inp_cur_data));
|
2353
|
+
#endif
|
2354
|
+
CopyInpAtomData( &pRenumbData->orig_inp_cur_data, inp_cur_data );
|
2355
|
+
pRenumbData->ren_counter = pRenumbData->orig_inp_cur_data.num_at * pRenumbData->orig_inp_cur_data.num_at;
|
2356
|
+
srand(1); /* for reproducibility */
|
2357
|
+
rand(); /* shift to avoid prev. sequences */
|
2358
|
+
pRenumbData->nComp = 0;
|
2359
|
+
/*ren_counter = 29;*/
|
2360
|
+
pRenumbData->new_ord = (AT_RANK *)inchi_calloc( pRenumbData->orig_inp_cur_data.num_at, sizeof(pRenumbData->new_ord[0]) );
|
2361
|
+
if ( pRenumbData->new_ord ) {
|
2362
|
+
for ( j = 0; j < pRenumbData->orig_inp_cur_data.num_at; j ++ ) {
|
2363
|
+
pRenumbData->new_ord[j] = (AT_RANK)j;
|
2364
|
+
}
|
2365
|
+
return 0;
|
2366
|
+
}
|
2367
|
+
return -1; /* out of RAM */
|
2368
|
+
}
|
2369
|
+
/************************************************************************************************/
|
2370
|
+
int RenumberingTestUninit( RENUMB_DATA *pRenumbData )
|
2371
|
+
{
|
2372
|
+
FreeInpAtomData( &pRenumbData->orig_inp_cur_data );
|
2373
|
+
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
|
2374
|
+
FreeInpAtomData( &pRenumbData->longest_inp_cur_data );
|
2375
|
+
#endif
|
2376
|
+
inchi_free( pRenumbData->new_ord );
|
2377
|
+
return 0;
|
2378
|
+
}
|
2379
|
+
/************************************************************************************************/
|
2380
|
+
int RenumberingTest( PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, ORIG_ATOM_DATA *orig_inp_data, int iINChI,
|
2381
|
+
RENUMB_DATA *pRenumbData, INP_ATOM_DATA *inp_cur_data, INP_ATOM_DATA **inp_norm_data,
|
2382
|
+
STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, INCHI_FILE *log_file, INCHI_FILE *prb_file,
|
2383
|
+
int i, int num_inp, NORM_CANON_FLAGS *pncFlags)
|
2384
|
+
{
|
2385
|
+
int k, bLongerTime;
|
2386
|
+
CopyInpAtomData( &pRenumbData->saved_inp_cur_data, inp_cur_data );
|
2387
|
+
pRenumbData->nRet2 = 0;
|
2388
|
+
pRenumbData->num_taut0 = sd->num_taut[iINChI];
|
2389
|
+
pRenumbData->num_non_taut0 = sd->num_non_taut[iINChI];
|
2390
|
+
pRenumbData->ulMaxTime = 0;
|
2391
|
+
while ( -- pRenumbData->ren_counter >= 0 && !pRenumbData->nRet2 ) {
|
2392
|
+
pRenumbData->nComp ++;
|
2393
|
+
MakeNewOrd( pRenumbData->orig_inp_cur_data.num_at, pRenumbData->new_ord );
|
2394
|
+
RenumbInpAtomData( inp_cur_data, &pRenumbData->orig_inp_cur_data, pRenumbData->new_ord );
|
2395
|
+
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
|
2396
|
+
CopyInpAtomData( &pRenumbData->longest_inp_cur_data, inp_cur_data );
|
2397
|
+
#endif
|
2398
|
+
if ( 470 == pRenumbData->nComp ) {
|
2399
|
+
int stop = 1; /* debug only */
|
2400
|
+
}
|
2401
|
+
|
2402
|
+
pRenumbData->nRet2 = CreateOneComponentINChI( sd, ip, inp_cur_data, NULL /*orig_inp_data*/,
|
2403
|
+
pRenumbData->ren_INChI2, pRenumbData->ren_INChI_Aux, iINChI,
|
2404
|
+
0, num_inp, pRenumbData->ren_inp_norm_data, pncFlags, log_file );
|
2405
|
+
/*
|
2406
|
+
CreateOneComponentINChI( sd, ip, inp_cur_data, orig_inp_data, pINChI2[iINChI], pINChI_Aux2[iINChI], iINChI,
|
2407
|
+
i, num_inp, inp_norm_data, log_file );
|
2408
|
+
*/
|
2409
|
+
if ( !pRenumbData->nRet2 ) {
|
2410
|
+
pRenumbData->c1 = CompareINChI( pINChI[i][TAUT_NON], pRenumbData->ren_INChI2[0][TAUT_NON],
|
2411
|
+
pINChI_Aux[i][TAUT_NON], pRenumbData->ren_INChI_Aux[0][TAUT_NON]);
|
2412
|
+
pRenumbData->c2 = CompareINChI( pINChI[i][TAUT_YES], pRenumbData->ren_INChI2[0][TAUT_YES],
|
2413
|
+
pINChI_Aux[i][TAUT_YES], pRenumbData->ren_INChI_Aux[0][TAUT_YES]);
|
2414
|
+
if ( pRenumbData->c1 || pRenumbData->c2 || pRenumbData->nRet2 ) {
|
2415
|
+
|
2416
|
+
/****** the renumbering result is different ******/
|
2417
|
+
|
2418
|
+
my_fprintf( log_file, "Compare (%d,%d) %d (err=%d) %s structure #%d component %d.%s%s%s%s\n",
|
2419
|
+
pRenumbData->c1, pRenumbData->c2,
|
2420
|
+
pRenumbData->nComp, pRenumbData->nRet2, INCHI_NAME,
|
2421
|
+
num_inp, i+1, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2422
|
+
for ( k = 0; k < pRenumbData->orig_inp_cur_data.num_at; k ++ ) {
|
2423
|
+
my_fprintf( log_file, " %d", (int)pRenumbData->new_ord[k] );
|
2424
|
+
}
|
2425
|
+
my_fprintf( log_file, "\n" );
|
2426
|
+
pRenumbData->ren_counter = 0; /* force exit */
|
2427
|
+
pRenumbData->bRenumbErr = 1000*pRenumbData->c2 + pRenumbData->c1;
|
2428
|
+
}
|
2429
|
+
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
|
2430
|
+
/* output time per this component */
|
2431
|
+
my_fprintf( stderr, "\rComp#%d str#%d/%d%s%s%s%s Ren %d/%d n(%lu:%lu)c(%lu:%lu)...\r",
|
2432
|
+
i+1, num_inp, iINChI, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), pRenumbData->nComp, pRenumbData->ren_counter+pRenumbData->nComp,
|
2433
|
+
pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime,
|
2434
|
+
pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime);
|
2435
|
+
#endif
|
2436
|
+
/* make sure the max. time is not overwritten */
|
2437
|
+
pRenumbData->ulCurTime0 = pRenumbData->ren_INChI_Aux[0][TAUT_NON]?
|
2438
|
+
(pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime
|
2439
|
+
+ pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime) : 0;
|
2440
|
+
pRenumbData->ulCurTime1 = pRenumbData->ren_INChI_Aux[0][TAUT_YES]?
|
2441
|
+
(pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime
|
2442
|
+
+ pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime) : 0;
|
2443
|
+
pRenumbData->ulCurTime = inchi_max( pRenumbData->ulCurTime0, pRenumbData->ulCurTime1 );
|
2444
|
+
|
2445
|
+
pRenumbData->ulCurTimeCanon0 = pRenumbData->ren_INChI_Aux[0][TAUT_NON]? pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime : 0;
|
2446
|
+
pRenumbData->ulCurTimeCanon1 = pRenumbData->ren_INChI_Aux[0][TAUT_YES]? pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime : 0;
|
2447
|
+
pRenumbData->ulCurTimeCanon = inchi_max( pRenumbData->ulCurTimeCanon0, pRenumbData->ulCurTimeCanon1);
|
2448
|
+
|
2449
|
+
pRenumbData->ulCurTimeNorm0 = pRenumbData->ren_INChI_Aux[0][TAUT_NON]? pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime:0;
|
2450
|
+
pRenumbData->ulCurTimeNorm1 = pRenumbData->ren_INChI_Aux[0][TAUT_YES]? pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime:0;
|
2451
|
+
pRenumbData->ulCurTimeNorm = inchi_max( pRenumbData->ulCurTimeNorm0, pRenumbData->ulCurTimeNorm1);
|
2452
|
+
|
2453
|
+
|
2454
|
+
bLongerTime = 0;
|
2455
|
+
if ( pRenumbData->ulCurTime > pRenumbData->ulMaxTime ) {
|
2456
|
+
pRenumbData->ulMaxTime = pRenumbData->ulCurTime;
|
2457
|
+
bLongerTime = 1;
|
2458
|
+
}
|
2459
|
+
if ( pRenumbData->ulMaxTimeCanon > pRenumbData->ulCurTimeCanon ) {
|
2460
|
+
pRenumbData->ulMaxTimeCanon = pRenumbData->ulCurTimeCanon;
|
2461
|
+
bLongerTime = 1;
|
2462
|
+
}
|
2463
|
+
if ( pRenumbData->ulMaxTimeNorm > pRenumbData->ulCurTimeCanon ) {
|
2464
|
+
pRenumbData->ulMaxTimeCanon = pRenumbData->ulCurTimeCanon;
|
2465
|
+
bLongerTime = 1;
|
2466
|
+
}
|
2467
|
+
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
|
2468
|
+
if ( bLongerTime ) {
|
2469
|
+
char szLine[512];
|
2470
|
+
char szValue[512];
|
2471
|
+
//my_fprintf( stderr, "\n" );
|
2472
|
+
sprintf( szLine, "Comp#%d str#%d/%d%s%s%s%s Ren %d/%d n=%lu:%lu c=%lu:%lu",
|
2473
|
+
i+1, num_inp, iINChI, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), pRenumbData->nComp, pRenumbData->ren_counter+pRenumbData->nComp,
|
2474
|
+
pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime,
|
2475
|
+
pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime);
|
2476
|
+
sprintf( szValue, "%s (c%d/s%d/i%d, r%d/%d n=%lu:%lu c=%lu:%lu)",
|
2477
|
+
(ip->pSdfValue && ip->pSdfValue[0])? ip->pSdfValue:"unk",
|
2478
|
+
i+1, num_inp, iINChI, pRenumbData->nComp, pRenumbData->ren_counter+pRenumbData->nComp,
|
2479
|
+
pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_NON]->ulCanonTime,
|
2480
|
+
pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulNormTime, pRenumbData->ren_INChI_Aux[0][TAUT_YES]->ulCanonTime);
|
2481
|
+
|
2482
|
+
WriteToSDfile( &pRenumbData->longest_inp_cur_data, prb_file, szLine, NULL, ip->pSdfLabel, szValue );
|
2483
|
+
}
|
2484
|
+
#endif
|
2485
|
+
|
2486
|
+
#if ( TEST_RENUMB_SWITCH == 1 )
|
2487
|
+
if ( pRenumbData->c1 || pRenumbData->c2 || !pRenumbData->ren_counter ) {
|
2488
|
+
swap( (char*)&pINChI[i][TAUT_NON], (char*)&pRenumbData->ren_INChI2[0][TAUT_NON], sizeof(&pRenumbData->ren_INChI2[0][0]) );
|
2489
|
+
swap( (char*)&pINChI[i][TAUT_YES], (char*)&pRenumbData->ren_INChI2[0][TAUT_YES], sizeof(&pRenumbData->ren_INChI2[0][0]) );
|
2490
|
+
swap( (char*)&pINChI_Aux[i][TAUT_NON], (char*)&pRenumbData->ren_INChI_Aux[0][TAUT_NON], sizeof(&pRenumbData->ren_INChI_Aux[0][0]) );
|
2491
|
+
swap( (char*)&pINChI_Aux[i][TAUT_YES], (char*)&pRenumbData->ren_INChI_Aux[0][TAUT_YES], sizeof(&pRenumbData->ren_INChI_Aux[0][0]) );
|
2492
|
+
}
|
2493
|
+
#endif
|
2494
|
+
}
|
2495
|
+
|
2496
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
2497
|
+
if ( pRenumbData->ren_INChI2[0][k] ) {
|
2498
|
+
Free_INChI(&pRenumbData->ren_INChI2[0][k]);
|
2499
|
+
/*
|
2500
|
+
inchi_free(pRenumbData->ren_INChI2[0][k]);
|
2501
|
+
pRenumbData->ren_INChI2[0][k] = NULL;
|
2502
|
+
*/
|
2503
|
+
}
|
2504
|
+
if ( pRenumbData->ren_INChI_Aux[0][k] ) {
|
2505
|
+
Free_INChI_Aux(&pRenumbData->ren_INChI_Aux[0][k]);
|
2506
|
+
/*
|
2507
|
+
inchi_free(pRenumbData->ren_INChI_Aux[0][k]);
|
2508
|
+
pRenumbData->ren_INChI_Aux[0][k] = NULL;
|
2509
|
+
*/
|
2510
|
+
}
|
2511
|
+
}
|
2512
|
+
}
|
2513
|
+
/* eliminate overcounting due to multiple renumberings/recalculations */
|
2514
|
+
pRenumbData->num_taut = sd->num_taut[iINChI] - pRenumbData->num_taut0;
|
2515
|
+
pRenumbData->num_non_taut = sd->num_non_taut[iINChI] - pRenumbData->num_non_taut0;
|
2516
|
+
sd->num_taut[iINChI] = pRenumbData->num_taut0;
|
2517
|
+
sd->num_non_taut[iINChI] = pRenumbData->num_non_taut0;
|
2518
|
+
if ( pRenumbData->num_taut % pRenumbData->nComp || pRenumbData->num_non_taut % pRenumbData->nComp ) {
|
2519
|
+
my_fprintf( log_file, "Compare (%d,%d) %d (err=%d) %s structure #%d component %d.%s%s%s%s\n",
|
2520
|
+
pRenumbData->num_non_taut % pRenumbData->nComp, pRenumbData->num_taut % pRenumbData->nComp,
|
2521
|
+
pRenumbData->nComp, 333, INCHI_NAME, num_inp, i+1, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2522
|
+
}
|
2523
|
+
#if ( TEST_RENUMB_SWITCH == 1 ) /* { */
|
2524
|
+
CopyInpAtomData( inp_norm_data[TAUT_NON], pRenumbData->ren_inp_norm_data[TAUT_NON] );
|
2525
|
+
CopyInpAtomData( inp_norm_data[TAUT_YES], pRenumbData->ren_inp_norm_data[TAUT_YES] );
|
2526
|
+
/* renumbered input structure */
|
2527
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
2528
|
+
if ( /*ip->bDisplayEachComponentINChI &&*/ !pRenumbData->nRet2 ) {
|
2529
|
+
int err;
|
2530
|
+
err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at, 0, 0, 0, 0, NULL, NULL,
|
2531
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
|
2532
|
+
sd->bUserQuitComponentDisplay = (err==ESC_KEY);
|
2533
|
+
if ( !err ) {
|
2534
|
+
my_fprintf( stderr, "Cannot display the structure\n");
|
2535
|
+
}
|
2536
|
+
}
|
2537
|
+
#endif /* } INCHI_ANSI_ONLY */
|
2538
|
+
#else /* } TEST_RENUMB_SWITCH { */
|
2539
|
+
CopyInpAtomData( inp_cur_data, &pRenumbData->saved_inp_cur_data );
|
2540
|
+
#endif /* } TEST_RENUMB_SWITCH */
|
2541
|
+
FreeInpAtomData( &pRenumbData->saved_inp_cur_data );
|
2542
|
+
FreeInpAtomData( pRenumbData->ren_inp_norm_data[TAUT_NON] );
|
2543
|
+
FreeInpAtomData( pRenumbData->ren_inp_norm_data[TAUT_YES] );
|
2544
|
+
|
2545
|
+
return pRenumbData->nRet2;
|
2546
|
+
}
|
2547
|
+
#endif /* } TEST_RENUMB_ATOMS */
|
2548
|
+
|
2549
|
+
/****************************************************************************/
|
2550
|
+
int bCheckUnusualValences( ORIG_ATOM_DATA *orig_at_data, int bAddIsoH, char *pStrErrStruct )
|
2551
|
+
{
|
2552
|
+
int i, val, num_found = 0;
|
2553
|
+
char msg[32];
|
2554
|
+
int len, num_H;
|
2555
|
+
inp_ATOM *at = ( orig_at_data && orig_at_data->num_inp_atoms > 0 )? orig_at_data->at : NULL;
|
2556
|
+
|
2557
|
+
if ( at ) {
|
2558
|
+
for ( i = 0, num_found = 0; i < orig_at_data->num_inp_atoms; i ++ ) {
|
2559
|
+
num_H = bAddIsoH? NUMH(at,i) : at[i].num_H;
|
2560
|
+
val = detect_unusual_el_valence( at[i].el_number, at[i].charge, at[i].radical,
|
2561
|
+
at[i].chem_bonds_valence, num_H, at[i].valence );
|
2562
|
+
if ( val ) {
|
2563
|
+
num_found ++;
|
2564
|
+
/* produce message */
|
2565
|
+
AddMOLfileError(pStrErrStruct, "Accepted unusual valence(s):");
|
2566
|
+
len = sprintf( msg, "%s", at[i].elname );
|
2567
|
+
if ( at[i].charge ) {
|
2568
|
+
len += sprintf( msg+len, "%+d", at[i].charge );
|
2569
|
+
}
|
2570
|
+
if ( at[i].radical ) {
|
2571
|
+
len += sprintf( msg + len, ",%s", at[i].radical == RADICAL_SINGLET? "s" :
|
2572
|
+
at[i].radical == RADICAL_DOUBLET? "d" :
|
2573
|
+
at[i].radical == RADICAL_TRIPLET? "t" : "?" );
|
2574
|
+
}
|
2575
|
+
len += sprintf( msg + len, "(%d)", val );
|
2576
|
+
AddMOLfileError(pStrErrStruct, msg);
|
2577
|
+
}
|
2578
|
+
}
|
2579
|
+
}
|
2580
|
+
return num_found;
|
2581
|
+
}
|
2582
|
+
/***************************************************************************/
|
2583
|
+
int PreprocessOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data )
|
2584
|
+
{
|
2585
|
+
int i;
|
2586
|
+
INCHI_MODE bTautFlags = 0;
|
2587
|
+
INCHI_MODE bTautFlagsDone = 0;
|
2588
|
+
/*************************************************/
|
2589
|
+
/* 1. copy orig_inp_data --> prep_inp_data */
|
2590
|
+
/*************************************************/
|
2591
|
+
if ( 0 > DuplicateOrigAtom( prep_inp_data, orig_inp_data ) ) {
|
2592
|
+
AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
|
2593
|
+
sd->nStructReadError = 99;
|
2594
|
+
sd->nErrorType = _IS_FATAL;
|
2595
|
+
goto exit_function;
|
2596
|
+
}
|
2597
|
+
#if( bRELEASE_VERSION == 0 && (EXTR_HAS_METAL_ATOM & (EXTR_MASK | EXTR_FLAG) ) )
|
2598
|
+
if ( bHasMetalAtom( orig_inp_data ) ) {
|
2599
|
+
sd->bExtract |= EXTR_HAS_METAL_ATOM;
|
2600
|
+
}
|
2601
|
+
#endif
|
2602
|
+
|
2603
|
+
/*************************************************/
|
2604
|
+
/* 2. fix odd things in prep_inp_data */
|
2605
|
+
/*************************************************/
|
2606
|
+
|
2607
|
+
if ( 0 < fix_odd_things( prep_inp_data->num_inp_atoms, prep_inp_data->at ) ) {
|
2608
|
+
AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
|
2609
|
+
if ( sd->nErrorType < _IS_WARNING ) {
|
2610
|
+
sd->nErrorType = _IS_WARNING;
|
2611
|
+
}
|
2612
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
|
2613
|
+
}
|
2614
|
+
#if( bRELEASE_VERSION == 0 && (EXTR_FLAGS & EXTR_HAS_FEATURE) )
|
2615
|
+
if ( bFoundFeature( prep_inp_data->at, prep_inp_data->num_inp_atoms ) ) {
|
2616
|
+
sd->bExtract |= EXTR_HAS_FEATURE;
|
2617
|
+
}
|
2618
|
+
#endif
|
2619
|
+
|
2620
|
+
/*******************************************************************
|
2621
|
+
* Find whether the structure can be disconnected or is a salt
|
2622
|
+
*******************************************************************/
|
2623
|
+
|
2624
|
+
|
2625
|
+
/* needs salt disconnection? */
|
2626
|
+
if ( ip->bTautFlags & TG_FLAG_DISCONNECT_SALTS ) {
|
2627
|
+
prep_inp_data->bDisconnectSalts = (0 < DisconnectSalts( prep_inp_data, 0 ));
|
2628
|
+
} else {
|
2629
|
+
prep_inp_data->bDisconnectSalts = 0;
|
2630
|
+
}
|
2631
|
+
/* needs metal disconnection? */
|
2632
|
+
if ( ip->bTautFlags & TG_FLAG_DISCONNECT_COORD ) {
|
2633
|
+
i = (0 != (ip->bTautFlags & TG_FLAG_CHECK_VALENCE_COORD));
|
2634
|
+
bMayDisconnectMetals( prep_inp_data, i, &bTautFlagsDone ); /* changes prep_inp_data->bDisconnectCoord */
|
2635
|
+
sd->bTautFlagsDone[INCHI_BAS] |= bTautFlagsDone; /* whether any disconnection has been rejected because of the metal proper valence */
|
2636
|
+
#if( bRELEASE_VERSION == 0 )
|
2637
|
+
if ( i && (bTautFlagsDone & TG_FLAG_CHECK_VALENCE_COORD_DONE) ) {
|
2638
|
+
sd->bExtract |= EXTR_METAL_WAS_NOT_DISCONNECTED;
|
2639
|
+
}
|
2640
|
+
#endif
|
2641
|
+
} else {
|
2642
|
+
prep_inp_data->bDisconnectCoord = 0;
|
2643
|
+
}
|
2644
|
+
orig_inp_data->bDisconnectSalts = prep_inp_data->bDisconnectSalts;
|
2645
|
+
orig_inp_data->bDisconnectCoord = prep_inp_data->bDisconnectCoord;
|
2646
|
+
|
2647
|
+
/*************************************************/
|
2648
|
+
/* 3. if( orig_inp_data->bDisconnectSalts ) then */
|
2649
|
+
/* -- disconnect salts in prep_inp_data */
|
2650
|
+
/*************************************************/
|
2651
|
+
|
2652
|
+
if ( ( ip->bTautFlags & TG_FLAG_DISCONNECT_SALTS ) && prep_inp_data->bDisconnectSalts &&
|
2653
|
+
0 < (i=DisconnectSalts( prep_inp_data, 1 )) ) {
|
2654
|
+
AddMOLfileError(sd->pStrErrStruct, "Salt was disconnected");
|
2655
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_DISCONNECT_SALTS_DONE;
|
2656
|
+
if ( sd->nErrorType < _IS_WARNING ) {
|
2657
|
+
sd->nErrorType = _IS_WARNING;
|
2658
|
+
}
|
2659
|
+
if ( i = ReconcileAllCmlBondParities( prep_inp_data->at, prep_inp_data->num_inp_atoms, 0 ) ) {
|
2660
|
+
char szErrCode[16];
|
2661
|
+
sprintf( szErrCode, "%d", i);
|
2662
|
+
AddMOLfileError( sd->pStrErrStruct, "0D Parities Reconciliation failed:" );
|
2663
|
+
AddMOLfileError( sd->pStrErrStruct, szErrCode );
|
2664
|
+
}
|
2665
|
+
#if( bRELEASE_VERSION == 0 )
|
2666
|
+
sd->bExtract |= EXTR_SALT_WAS_DISCONNECTED;
|
2667
|
+
#endif
|
2668
|
+
} else {
|
2669
|
+
prep_inp_data->bDisconnectSalts = 0;
|
2670
|
+
}
|
2671
|
+
|
2672
|
+
/***********************************************************/
|
2673
|
+
/* mark the (disconnected) components in prep_inp_data */
|
2674
|
+
/***********************************************************/
|
2675
|
+
|
2676
|
+
prep_inp_data->num_components = MarkDisconnectedComponents( prep_inp_data, 0 );
|
2677
|
+
|
2678
|
+
if ( prep_inp_data->num_components < 0 ) {
|
2679
|
+
AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
|
2680
|
+
sd->nStructReadError = 99;
|
2681
|
+
sd->nErrorType = _IS_FATAL;
|
2682
|
+
goto exit_function;
|
2683
|
+
}
|
2684
|
+
|
2685
|
+
/***********************************************************/
|
2686
|
+
/* Detect isotopic H on heteroatoms -- necessary condition */
|
2687
|
+
/* for global isotopic tautomerism */
|
2688
|
+
/***********************************************************/
|
2689
|
+
|
2690
|
+
if ( i = bNumHeterAtomHasIsotopicH( prep_inp_data->at, prep_inp_data->num_inp_atoms ) ) {
|
2691
|
+
if ( i & 1 ) {
|
2692
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FOUND_ISOTOPIC_H_DONE;
|
2693
|
+
}
|
2694
|
+
if ( i & 2 ) {
|
2695
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FOUND_ISOTOPIC_ATOM_DONE;
|
2696
|
+
}
|
2697
|
+
}
|
2698
|
+
|
2699
|
+
|
2700
|
+
/****************************************************************************/
|
2701
|
+
/* 4a. Detect unusual valences */
|
2702
|
+
/* should be called before metal disconnection */
|
2703
|
+
/****************************************************************************/
|
2704
|
+
|
2705
|
+
|
2706
|
+
if ( bCheckUnusualValences( prep_inp_data, 1, sd->pStrErrStruct ) ) {
|
2707
|
+
#if( bRELEASE_VERSION == 0 )
|
2708
|
+
sd->bExtract |= EXTR_UNUSUAL_VALENCES;
|
2709
|
+
#else
|
2710
|
+
;
|
2711
|
+
#endif
|
2712
|
+
}
|
2713
|
+
/***********************************************************/
|
2714
|
+
/* 5. if( orig_inp_data->bDisconnectCoord ) then */
|
2715
|
+
/* -- copy prep_inp_data --> prep_inp_data+1 */
|
2716
|
+
/* -- disconnect metals in prep_inp_data */
|
2717
|
+
/***********************************************************/
|
2718
|
+
|
2719
|
+
if ( prep_inp_data->bDisconnectCoord ) {
|
2720
|
+
|
2721
|
+
prep_inp_data->num_components = MarkDisconnectedComponents( prep_inp_data, 0 );
|
2722
|
+
if ( prep_inp_data->num_components < 0 ) {
|
2723
|
+
AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
|
2724
|
+
sd->nStructReadError = 99;
|
2725
|
+
sd->nErrorType = _IS_FATAL;
|
2726
|
+
goto exit_function;
|
2727
|
+
}
|
2728
|
+
/* save Reconnected structure in prep_inp_data+1 if requested */
|
2729
|
+
if ( 0 != ( ip->bTautFlags & TG_FLAG_RECONNECT_COORD) ) {
|
2730
|
+
if ( 0 > DuplicateOrigAtom( prep_inp_data+1, prep_inp_data ) ) {
|
2731
|
+
AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
|
2732
|
+
sd->nStructReadError = 99;
|
2733
|
+
sd->nErrorType = _IS_FATAL;
|
2734
|
+
goto exit_function;
|
2735
|
+
}
|
2736
|
+
sd->bTautFlags[INCHI_REC] = sd->bTautFlags[INCHI_BAS];
|
2737
|
+
sd->bTautFlagsDone[INCHI_REC] = sd->bTautFlagsDone[INCHI_BAS];
|
2738
|
+
{ /* remove "parity undefined in disconnected structure" flag from reconnected structure */
|
2739
|
+
int k, m, p;
|
2740
|
+
inp_ATOM *at = (prep_inp_data+1)->at;
|
2741
|
+
int num_at = (prep_inp_data+1)->num_inp_atoms;
|
2742
|
+
for ( k = 0; k < num_at; k ++ ) {
|
2743
|
+
for ( m = 0; m < MAX_NUM_STEREO_BONDS && (p=at[k].sb_parity[m]); m ++ ) {
|
2744
|
+
at[k].sb_parity[m] &= SB_PARITY_MASK;
|
2745
|
+
}
|
2746
|
+
}
|
2747
|
+
}
|
2748
|
+
}
|
2749
|
+
|
2750
|
+
/* make Disconnected structure in prep_inp_data */
|
2751
|
+
i = (0 != ( ip->bTautFlags & TG_FLAG_CHECK_VALENCE_COORD ));
|
2752
|
+
/* prep_inp_data->bDisconnectCoord > 1 means add prep_inp_data->bDisconnectCoord-1 explicit H atoms */
|
2753
|
+
if ( 0 < (i = DisconnectMetals( prep_inp_data, i, &bTautFlagsDone ) ) ) {
|
2754
|
+
AddMOLfileError(sd->pStrErrStruct, "Metal was disconnected");
|
2755
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_DISCONNECT_COORD_DONE;
|
2756
|
+
if ( sd->nErrorType < _IS_WARNING ) {
|
2757
|
+
sd->nErrorType = _IS_WARNING;
|
2758
|
+
}
|
2759
|
+
#if( bRELEASE_VERSION == 0 )
|
2760
|
+
sd->bExtract |= EXTR_METAL_WAS_DISCONNECTED;
|
2761
|
+
#endif
|
2762
|
+
/* last parm=1 means find link between unchanged by Metal Disconnection components */
|
2763
|
+
prep_inp_data->num_components = MarkDisconnectedComponents( prep_inp_data, 1 );
|
2764
|
+
if ( prep_inp_data->num_components < 0 ) {
|
2765
|
+
AddMOLfileError(sd->pStrErrStruct, "Out of RAM");
|
2766
|
+
sd->nStructReadError = 99;
|
2767
|
+
sd->nErrorType = _IS_FATAL;
|
2768
|
+
goto exit_function;
|
2769
|
+
}
|
2770
|
+
|
2771
|
+
{ /* set parities for the disconnected structure */
|
2772
|
+
int k, m, p;
|
2773
|
+
inp_ATOM *at = (prep_inp_data)->at;
|
2774
|
+
int num_at = (prep_inp_data)->num_inp_atoms;
|
2775
|
+
for ( k = 0; k < num_at; k ++ ) {
|
2776
|
+
for ( m = 0; m < MAX_NUM_STEREO_BONDS && (p=at[k].sb_parity[m]); m ++ ) {
|
2777
|
+
if ( p & SB_PARITY_FLAG ) {
|
2778
|
+
at[k].sb_parity[m] = (p >> SB_PARITY_SHFT) & SB_PARITY_MASK;
|
2779
|
+
}
|
2780
|
+
}
|
2781
|
+
}
|
2782
|
+
}
|
2783
|
+
|
2784
|
+
if ( i = ReconcileAllCmlBondParities( prep_inp_data->at, prep_inp_data->num_inp_atoms, 1 ) ) {
|
2785
|
+
char szErrCode[16];
|
2786
|
+
sprintf( szErrCode, "%d", i);
|
2787
|
+
AddMOLfileError( sd->pStrErrStruct, "0D Parities Reconciliation failed:" );
|
2788
|
+
AddMOLfileError( sd->pStrErrStruct, szErrCode );
|
2789
|
+
}
|
2790
|
+
|
2791
|
+
#if ( REMOVE_ION_PAIRS_DISC_STRU == 1 )
|
2792
|
+
if ( 0 < remove_ion_pairs( prep_inp_data->num_inp_atoms, prep_inp_data->at ) ) {
|
2793
|
+
AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
|
2794
|
+
if ( sd->nErrorType < _IS_WARNING ) {
|
2795
|
+
sd->nErrorType = _IS_WARNING;
|
2796
|
+
}
|
2797
|
+
sd->bTautFlagsDone[INCHI_REC] |= TG_FLAG_FIX_ODD_THINGS_DONE;
|
2798
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
|
2799
|
+
}
|
2800
|
+
#endif
|
2801
|
+
|
2802
|
+
/*
|
2803
|
+
if prep_inp_data->nOldCompNumber[i] = iINChI+1 > 0 then
|
2804
|
+
component #(i+1) in prep_inp_data is identical to component #(iINChI+1) in prep_inp_data+1
|
2805
|
+
*/
|
2806
|
+
} else
|
2807
|
+
if ( i < 0 ) {
|
2808
|
+
AddMOLfileError(sd->pStrErrStruct, "Cannot disconnect metal error");
|
2809
|
+
sd->nStructReadError = i;
|
2810
|
+
sd->nErrorType = _IS_ERROR;
|
2811
|
+
goto exit_function;
|
2812
|
+
}
|
2813
|
+
} else
|
2814
|
+
{ /* remove "disconnected structure parities" from the structure */
|
2815
|
+
int k, m, p;
|
2816
|
+
inp_ATOM *at = (prep_inp_data)->at;
|
2817
|
+
int num_at = (prep_inp_data)->num_inp_atoms;
|
2818
|
+
for ( k = 0; k < num_at; k ++ ) {
|
2819
|
+
for ( m = 0; m < MAX_NUM_STEREO_BONDS && (p=at[k].sb_parity[m]); m ++ ) {
|
2820
|
+
at[k].sb_parity[m] &= SB_PARITY_MASK;
|
2821
|
+
}
|
2822
|
+
}
|
2823
|
+
}
|
2824
|
+
|
2825
|
+
|
2826
|
+
exit_function:
|
2827
|
+
|
2828
|
+
if ( sd->nErrorType < _IS_ERROR && prep_inp_data ) {
|
2829
|
+
|
2830
|
+
if ( 0 < post_fix_odd_things( prep_inp_data->num_inp_atoms, prep_inp_data->at ) ) {
|
2831
|
+
AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
|
2832
|
+
if ( sd->nErrorType < _IS_WARNING ) {
|
2833
|
+
sd->nErrorType = _IS_WARNING;
|
2834
|
+
}
|
2835
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
|
2836
|
+
}
|
2837
|
+
if ( (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
|
2838
|
+
(prep_inp_data+1)->at && (prep_inp_data+1)->num_inp_atoms > 0 ) {
|
2839
|
+
if ( 0 < post_fix_odd_things( (prep_inp_data+1)->num_inp_atoms, (prep_inp_data+1)->at ) ) {
|
2840
|
+
AddMOLfileError(sd->pStrErrStruct, "Charges were rearranged");
|
2841
|
+
if ( sd->nErrorType < _IS_WARNING ) {
|
2842
|
+
sd->nErrorType = _IS_WARNING;
|
2843
|
+
}
|
2844
|
+
sd->bTautFlagsDone[INCHI_REC] |= TG_FLAG_FIX_ODD_THINGS_DONE;
|
2845
|
+
sd->bTautFlagsDone[INCHI_BAS] |= TG_FLAG_FIX_ODD_THINGS_DONE;
|
2846
|
+
}
|
2847
|
+
}
|
2848
|
+
}
|
2849
|
+
|
2850
|
+
sd->bTautFlags[INCHI_BAS] |= bTautFlags; /* TG_FLAG_CHECK_VALENCE_COORD_DONE, TG_FLAG_MOVE_CHARGE_COORD_DONE */
|
2851
|
+
sd->bTautFlagsDone[INCHI_BAS] |= bTautFlagsDone; /* TG_FLAG_CHECK_VALENCE_COORD_DONE, TG_FLAG_MOVE_CHARGE_COORD_DONE */
|
2852
|
+
return sd->nErrorType;
|
2853
|
+
}
|
2854
|
+
|
2855
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
2856
|
+
/************************************************************************************************/
|
2857
|
+
int DisplayTheWholeStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle, FILE *inp_file, INCHI_FILE *log_file,
|
2858
|
+
ORIG_ATOM_DATA *orig_inp_data, int num_inp, int iINChI, int bShowStruct, int bINCHI_LIB_Flag )
|
2859
|
+
{
|
2860
|
+
|
2861
|
+
int bDisplayEqu = 0;
|
2862
|
+
#ifndef INCHI_LIB
|
2863
|
+
/* Displaying equivalent input structures when disconnection has been done: */
|
2864
|
+
/* in case of INCHI_LIB equivalence info is always unknown here and bOriginalReconnected=0 */
|
2865
|
+
int bOriginalReconnected = iINChI < 0 && orig_inp_data && orig_inp_data->nEquLabels &&
|
2866
|
+
(sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
|
2867
|
+
(ip->bTautFlags & TG_FLAG_RECONNECT_COORD);
|
2868
|
+
const char *lpszType = bOriginalReconnected? " (Reconnected)" :
|
2869
|
+
(iINChI < 0 )? "" :
|
2870
|
+
(iINChI == INCHI_BAS )? " (Preprocessed)" :
|
2871
|
+
(iINChI == INCHI_REC )? " (Reconnected)" : "";
|
2872
|
+
int err = 0;
|
2873
|
+
/* Display the original structure */
|
2874
|
+
bDisplayEqu = bShowStruct && ip->bDisplay &&
|
2875
|
+
ip->dp.nEquLabels && 0 < ip->dp.nCurEquLabel && ip->dp.nCurEquLabel <= ip->dp.nNumEquSets;
|
2876
|
+
#else
|
2877
|
+
if(!DRAWDATA || !DRAWDATA_EXISTS)
|
2878
|
+
return 0;
|
2879
|
+
#endif
|
2880
|
+
#ifndef INCHI_LIBRARY
|
2881
|
+
/********************************************************************
|
2882
|
+
* Ask the user whether to process the input structure or quit
|
2883
|
+
*/
|
2884
|
+
if ( ip->bDisplay && inp_file != stdin ) {
|
2885
|
+
if ( user_quit(bDisplayEqu?"Enter=Display identical components, Esc=Stop ?" : "Enter=Display, Esc=Stop ?", ip->ulDisplTime) ) {
|
2886
|
+
sd->bUserQuit = 1;
|
2887
|
+
goto exit_function;
|
2888
|
+
}
|
2889
|
+
}
|
2890
|
+
#endif
|
2891
|
+
/******************************************************
|
2892
|
+
* Display the whole input structure in console app
|
2893
|
+
*/
|
2894
|
+
#ifndef INCHI_LIB
|
2895
|
+
if ( bShowStruct && ip->bDisplay ) {
|
2896
|
+
if ( bDisplayEqu ) {
|
2897
|
+
sprintf( szTitle, " Equ Set %d of %d, Input Structure #%d.%s%s%s%s%s",
|
2898
|
+
ip->dp.nCurEquLabel, ip->dp.nNumEquSets,
|
2899
|
+
num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), lpszType);
|
2900
|
+
} else {
|
2901
|
+
sprintf( szTitle, "Input Structure #%d.%s%s%s%s%s", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), lpszType);
|
2902
|
+
}
|
2903
|
+
err = DisplayStructure( orig_inp_data->at, orig_inp_data->num_inp_atoms, 0, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
|
2904
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
|
2905
|
+
sd->bUserQuitComponent = (err==ESC_KEY);
|
2906
|
+
if ( !err ) {
|
2907
|
+
my_fprintf( stderr, "Cannot display the structure\n");
|
2908
|
+
}
|
2909
|
+
}
|
2910
|
+
if( !bDisplayEqu ) {
|
2911
|
+
/* console output progress report */
|
2912
|
+
if ( ip->bDisplay && !sd->bUserQuitComponent ) {
|
2913
|
+
if ( iINChI == 1 ) {
|
2914
|
+
if ( ip->bDisplay )
|
2915
|
+
my_fprintf( log_file, "Processing (rec) structure #%d.%s%s%s%s...\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2916
|
+
else
|
2917
|
+
my_fprintf( stderr, "Processing (rec) structure #%d.%s%s%s%s...\r", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2918
|
+
} else {
|
2919
|
+
if ( ip->bDisplay )
|
2920
|
+
my_fprintf( log_file, "Processing structure #%d.%s%s%s%s...\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2921
|
+
else
|
2922
|
+
my_fprintf( stderr, "Processing structure #%d.%s%s%s%s...\r", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
2923
|
+
}
|
2924
|
+
}
|
2925
|
+
}
|
2926
|
+
#endif
|
2927
|
+
|
2928
|
+
|
2929
|
+
/******************************************************
|
2930
|
+
* Store the whole input structure in GUI application
|
2931
|
+
*/
|
2932
|
+
#ifdef INCHI_LIB
|
2933
|
+
if ( ip->bDisplay && bINCHI_LIB_Flag )
|
2934
|
+
#else
|
2935
|
+
if ( (ip->bDisplay || (ip->bCompareComponents & CMP_COMPONENTS)) && bINCHI_LIB_Flag )
|
2936
|
+
#endif
|
2937
|
+
{
|
2938
|
+
int bBit, k, bReconnected, nComponent, bPreprocessed;
|
2939
|
+
for ( bBit = 1, k = 0; k < 8; k ++, bBit <<= 1 ) {
|
2940
|
+
/******************************************************************************
|
2941
|
+
* bReconnected = k%2 (0 or 1)
|
2942
|
+
* nComponent = k/4 (0 or 1)
|
2943
|
+
* bPreprocessed = (k/2)%2 (0 or 1)
|
2944
|
+
******************************************************************************/
|
2945
|
+
if ( !(bINCHI_LIB_Flag & bBit) ) {
|
2946
|
+
continue;
|
2947
|
+
}
|
2948
|
+
bReconnected = k%2;
|
2949
|
+
nComponent = k/4;
|
2950
|
+
bPreprocessed = ((k/2)%2);
|
2951
|
+
|
2952
|
+
sprintf( szTitle, "%s Structure #%d.%s%s%s%s",
|
2953
|
+
bPreprocessed? "Preprocessed" : bReconnected? "Reconnected" : "Input",
|
2954
|
+
num_inp,
|
2955
|
+
SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue));
|
2956
|
+
|
2957
|
+
#ifdef INCHI_LIB
|
2958
|
+
if(DRAWDATA && DRAWDATA_EXISTS)
|
2959
|
+
{
|
2960
|
+
struct DrawData vDrawData;
|
2961
|
+
int nType = bPreprocessed? COMPONENT_ORIGINAL_PREPROCESSED : COMPONENT_ORIGINAL;
|
2962
|
+
if ( DRAWDATA_EXISTS( nComponent, bPreprocessed, bReconnected ) ) {
|
2963
|
+
sd->nErrorType = _IS_FATAL;
|
2964
|
+
sd->nErrorCode = CT_UNKNOWN_ERR;
|
2965
|
+
return -1;
|
2966
|
+
}
|
2967
|
+
vDrawData.pWindowData = CreateWinData_( orig_inp_data->at, orig_inp_data->num_inp_atoms,
|
2968
|
+
0, 0, NULL, 1, 0, NULL, NULL,
|
2969
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode );
|
2970
|
+
if( vDrawData.pWindowData != NULL )
|
2971
|
+
{
|
2972
|
+
vDrawData.nComponent = nComponent;
|
2973
|
+
vDrawData.nType = nType; /* COMPONENT_ORIGINAL or COMPONENT_ORIGINAL_PREPROCESSED */
|
2974
|
+
vDrawData.bReconnected = bReconnected; /* 0=>main; 1=>reconnected */
|
2975
|
+
vDrawData.pWindowData->szTitle = _strdup(szTitle);
|
2976
|
+
vDrawData.szTitle = _strdup(szTitle);
|
2977
|
+
DRAWDATA(&vDrawData);
|
2978
|
+
if ( !nComponent ) {
|
2979
|
+
/* keep track of saved INCHI_LIB data */
|
2980
|
+
orig_inp_data->bSavedInINCHI_LIB[bReconnected] ++;
|
2981
|
+
orig_inp_data->bPreprocessed[bReconnected] = bPreprocessed;
|
2982
|
+
}
|
2983
|
+
}
|
2984
|
+
}
|
2985
|
+
#else
|
2986
|
+
if ( !nComponent ) {
|
2987
|
+
/* keep track of saved INCHI_LIB data */
|
2988
|
+
orig_inp_data->bSavedInINCHI_LIB[bReconnected] ++;
|
2989
|
+
orig_inp_data->bPreprocessed[bReconnected] = bPreprocessed;
|
2990
|
+
}
|
2991
|
+
#endif
|
2992
|
+
|
2993
|
+
}
|
2994
|
+
}
|
2995
|
+
|
2996
|
+
exit_function:
|
2997
|
+
return sd->bUserQuit;
|
2998
|
+
}
|
2999
|
+
#endif /* } INCHI_ANSI_ONLY */
|
3000
|
+
/************************************************************************************************/
|
3001
|
+
int ProcessOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
|
3002
|
+
PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM],
|
3003
|
+
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
3004
|
+
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
|
3005
|
+
int num_inp, char *pStr, int nStrLen )
|
3006
|
+
{
|
3007
|
+
int nRet = 0, nRet1, i, k, maxINChI=0;
|
3008
|
+
COMP_ATOM_DATA composite_norm_data[INCHI_NUM][TAUT_NUM+1]; /* [0]:non-taut, [1]:taut, [2]:intermediate taut struct */
|
3009
|
+
NORM_CANON_FLAGS ncFlags;
|
3010
|
+
NORM_CANON_FLAGS *pncFlags = &ncFlags;
|
3011
|
+
ORIG_STRUCT OrigStruct;
|
3012
|
+
ORIG_STRUCT *pOrigStruct = NULL;
|
3013
|
+
int bSortPrintINChIFlags = 0;
|
3014
|
+
|
3015
|
+
sd->bUserQuitComponent = 0;
|
3016
|
+
sd->bUserQuitComponentDisplay = 0;
|
3017
|
+
memset( composite_norm_data, 0, sizeof(composite_norm_data) );
|
3018
|
+
memset( pncFlags, 0, sizeof(*pncFlags) );
|
3019
|
+
/* ip->msec_LeftTime = ip->msec_MaxTime; */ /* start timeout countdown */
|
3020
|
+
|
3021
|
+
/* for testing only */
|
3022
|
+
#if( REMOVE_ION_PAIRS_ORIG_STRU == 1 )
|
3023
|
+
fix_odd_things( orig_inp_data->num_inp_atoms, orig_inp_data->at );
|
3024
|
+
#endif
|
3025
|
+
|
3026
|
+
/***** output MOLfile ***************/
|
3027
|
+
if ( ip->bINChIOutputOptions & INCHI_OUT_SDFILE_ONLY ) {
|
3028
|
+
char szNumber[32];
|
3029
|
+
#if ( !defined( INCHI_LIB ) && !defined( INCHI_LIBRARY ) )
|
3030
|
+
#if( TEST_RENUMB_ATOMS != 1 )
|
3031
|
+
/* log file / console output */
|
3032
|
+
if ( log_file != stderr ) {
|
3033
|
+
if ( ip->bDisplay )
|
3034
|
+
my_fprintf( log_file, "Writing structure #%d.%s%s%s%s...\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
3035
|
+
else
|
3036
|
+
my_fprintf( stderr, "Writing structure #%d.%s%s%s%s...\r", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
3037
|
+
}
|
3038
|
+
#endif
|
3039
|
+
#endif
|
3040
|
+
sprintf( szNumber, "Structure #%d", num_inp );
|
3041
|
+
WriteOrigAtomDataToSDfile( orig_inp_data, output_file, szNumber, NULL,
|
3042
|
+
(sd->bChiralFlag & FLAG_INP_AT_CHIRAL)? 1:0, ip->pSdfLabel, ip->pSdfValue );
|
3043
|
+
goto exit_function;
|
3044
|
+
}
|
3045
|
+
|
3046
|
+
/******* create full reversibility information **************/
|
3047
|
+
if ( !(ip->bINChIOutputOptions & (INCHI_OUT_NO_AUX_INFO | INCHI_OUT_SHORT_AUX_INFO)) ) {
|
3048
|
+
pOrigStruct = &OrigStruct;
|
3049
|
+
memset( pOrigStruct, 0, sizeof(*pOrigStruct));
|
3050
|
+
if ( FillOutOrigStruct( orig_inp_data, pOrigStruct, sd ) ) {
|
3051
|
+
AddMOLfileError(sd->pStrErrStruct, "Cannot interpret reversibility information");
|
3052
|
+
sd->nStructReadError = 99;
|
3053
|
+
sd->nErrorType = _IS_ERROR;
|
3054
|
+
nRet = _IS_ERROR;
|
3055
|
+
}
|
3056
|
+
}
|
3057
|
+
/* create INChI for each connected component of the structure and optionally display them */
|
3058
|
+
/* create INChI for the whole disconnected or original structure */
|
3059
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
|
3060
|
+
nRet1 = CreateOneStructureINChI( sd, ip, szTitle, pINChI, pINChI_Aux, INCHI_BAS,
|
3061
|
+
inp_file, log_file, output_file, prb_file,
|
3062
|
+
orig_inp_data, prep_inp_data, composite_norm_data,
|
3063
|
+
num_inp, pStr, nStrLen, pncFlags );
|
3064
|
+
nRet = inchi_max(nRet, nRet1);
|
3065
|
+
}
|
3066
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
|
3067
|
+
maxINChI = 1;
|
3068
|
+
}
|
3069
|
+
|
3070
|
+
|
3071
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR &&
|
3072
|
+
(sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
|
3073
|
+
(ip->bTautFlags & TG_FLAG_RECONNECT_COORD) ) {
|
3074
|
+
|
3075
|
+
/* create INChI for the whole reconnected structure */
|
3076
|
+
nRet1 = CreateOneStructureINChI( sd, ip, szTitle, pINChI, pINChI_Aux, INCHI_REC,
|
3077
|
+
inp_file, log_file, output_file, prb_file,
|
3078
|
+
orig_inp_data, prep_inp_data, composite_norm_data,
|
3079
|
+
num_inp, pStr, nStrLen, pncFlags );
|
3080
|
+
nRet = inchi_max(nRet, nRet1);
|
3081
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
|
3082
|
+
maxINChI = 2;
|
3083
|
+
}
|
3084
|
+
}
|
3085
|
+
|
3086
|
+
|
3087
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
|
3088
|
+
|
3089
|
+
if ( (sd->bChiralFlag & FLAG_INP_AT_CHIRAL) &&
|
3090
|
+
(ip->nMode & REQ_MODE_STEREO) &&
|
3091
|
+
!(ip->nMode & (REQ_MODE_RELATIVE_STEREO | REQ_MODE_RACEMIC_STEREO)) &&
|
3092
|
+
!bIsStructChiral( pINChI, sd->num_components ) ) {
|
3093
|
+
|
3094
|
+
AddMOLfileError(sd->pStrErrStruct, "Not chiral");
|
3095
|
+
}
|
3096
|
+
/*************************************/
|
3097
|
+
/* Output err/warn messages */
|
3098
|
+
/*************************************/
|
3099
|
+
if ( /*!sd->nErrorCode &&*/ !sd->bUserQuitComponent && !sd->bUserQuit ) {
|
3100
|
+
/* if successful then returns 0, otherwise returns _IS_FATAL */
|
3101
|
+
/* exctract the structure if requested */
|
3102
|
+
nRet1 = TreatCreateINChIWarning(sd, ip, prep_inp_data, num_inp,
|
3103
|
+
inp_file, log_file, output_file, prb_file,pStr, nStrLen );
|
3104
|
+
nRet = inchi_max(nRet, nRet1);
|
3105
|
+
}
|
3106
|
+
}
|
3107
|
+
|
3108
|
+
|
3109
|
+
/************************************************/
|
3110
|
+
/* sort and print INChI for the whole structure */
|
3111
|
+
/************************************************/
|
3112
|
+
|
3113
|
+
|
3114
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
|
3115
|
+
|
3116
|
+
nRet1 = SortAndPrintINChI( output_file, pStr, nStrLen, log_file, ip, orig_inp_data, prep_inp_data,
|
3117
|
+
composite_norm_data, pOrigStruct,
|
3118
|
+
sd->num_components, sd->num_non_taut, sd->num_taut,
|
3119
|
+
sd->bTautFlags, sd->bTautFlagsDone, pncFlags, num_inp,
|
3120
|
+
pINChI, pINChI_Aux, &bSortPrintINChIFlags );
|
3121
|
+
nRet = inchi_max(nRet, nRet1);
|
3122
|
+
}
|
3123
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
3124
|
+
|
3125
|
+
/* display equivalent components on original or preprocessed structure(s) */
|
3126
|
+
|
3127
|
+
#ifndef INCHI_LIB
|
3128
|
+
|
3129
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR && /*ip->bDisplay &&*/
|
3130
|
+
(ip->bCompareComponents & CMP_COMPONENTS) && !sd->bUserQuit && !sd->bUserQuitComponent ) {
|
3131
|
+
int j, ret, ord;
|
3132
|
+
int bDisplaySaved = ip->bDisplay;
|
3133
|
+
ORIG_ATOM_DATA *inp_data;
|
3134
|
+
AT_NUMB nEquSet;
|
3135
|
+
for ( ord = -1; ord < INCHI_NUM; ord ++ ) {
|
3136
|
+
switch( ord ) {
|
3137
|
+
case -1:
|
3138
|
+
j = INCHI_BAS; /* preprocessed non-tautomeric */
|
3139
|
+
break;
|
3140
|
+
case 0:
|
3141
|
+
j = INCHI_REC; /* preprocessed tautomeric */
|
3142
|
+
break;
|
3143
|
+
case 1:
|
3144
|
+
j = -1; /* original input */
|
3145
|
+
break;
|
3146
|
+
default:
|
3147
|
+
continue;
|
3148
|
+
}
|
3149
|
+
inp_data = j < 0? orig_inp_data : prep_inp_data+j;
|
3150
|
+
if ( inp_data && inp_data->num_inp_atoms && inp_data->at &&
|
3151
|
+
inp_data->nEquLabels &&
|
3152
|
+
inp_data->nNumEquSets ) {
|
3153
|
+
for ( nEquSet = 1; nEquSet <= inp_data->nNumEquSets; nEquSet ++ ) {
|
3154
|
+
ip->dp.nEquLabels = inp_data->nEquLabels;
|
3155
|
+
ip->dp.nCurEquLabel = nEquSet;
|
3156
|
+
ip->dp.nNumEquSets = inp_data->nNumEquSets;
|
3157
|
+
ip->bDisplay = 1; /* force display if it was not requested */
|
3158
|
+
ret = DisplayTheWholeStructure( sd, ip, szTitle, inp_file, log_file, inp_data, num_inp,
|
3159
|
+
j, 1 /*bShowStructure*/, 0 );
|
3160
|
+
ip->dp.nEquLabels = NULL;
|
3161
|
+
ip->dp.nCurEquLabel = 0;
|
3162
|
+
ip->dp.nNumEquSets = 0;
|
3163
|
+
ip->bDisplay = bDisplaySaved; /* restore display option */
|
3164
|
+
if ( ret ) {
|
3165
|
+
/* user pressed Esc */
|
3166
|
+
goto exit_loop;
|
3167
|
+
}
|
3168
|
+
}
|
3169
|
+
}
|
3170
|
+
}
|
3171
|
+
exit_loop:;
|
3172
|
+
}
|
3173
|
+
|
3174
|
+
#endif
|
3175
|
+
|
3176
|
+
|
3177
|
+
|
3178
|
+
/* display composite results and equivalent components on composite results */
|
3179
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR && /*ip->bDisplay &&*/
|
3180
|
+
ip->bDisplayCompositeResults ) {
|
3181
|
+
int iINChI;
|
3182
|
+
for ( iINChI = 0; iINChI < maxINChI && !sd->bUserQuitComponentDisplay; iINChI ++ ) {
|
3183
|
+
DisplayTheWholeCompositeStructure( ip, sd, num_inp, iINChI,
|
3184
|
+
pINChI[iINChI], pINChI_Aux[iINChI],
|
3185
|
+
orig_inp_data, prep_inp_data,
|
3186
|
+
composite_norm_data[iINChI] );
|
3187
|
+
}
|
3188
|
+
#ifndef INCHI_LIB
|
3189
|
+
if( !ip->bDisplay && sd->bUserQuitComponentDisplay ) {
|
3190
|
+
sd->bUserQuit = 1;
|
3191
|
+
}
|
3192
|
+
#endif
|
3193
|
+
}
|
3194
|
+
|
3195
|
+
#endif /* } INCHI_ANSI_ONLY */
|
3196
|
+
|
3197
|
+
|
3198
|
+
/* XML struct end tag */
|
3199
|
+
if ( (ip->bINChIOutputOptions & INCHI_OUT_XML) && sd->bXmlStructStarted > 0 ) {
|
3200
|
+
if ( !OutputINChIXmlStructEndTag( output_file, pStr, nStrLen, 1 ) ) {
|
3201
|
+
my_fprintf( log_file, "Cannot create end xml tag for structure #%d.%s%s%s%s Terminating.\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
3202
|
+
sd->bXmlStructStarted = -1; /* do not repeat same message */
|
3203
|
+
nRet = _IS_FATAL;
|
3204
|
+
} else {
|
3205
|
+
sd->bXmlStructStarted = 0; /* do not continue xml output for this structure */
|
3206
|
+
}
|
3207
|
+
}
|
3208
|
+
if ( nRet != _IS_FATAL && nRet != _IS_ERROR ) {
|
3209
|
+
/* Special mode: extract all good MOLfiles into the problem file
|
3210
|
+
* Do not extract any MOLfile that could not be processed (option /PGO)
|
3211
|
+
*/
|
3212
|
+
if ( prb_file && 0L <= sd->fPtrStart && sd->fPtrStart < sd->fPtrEnd && ip->bSaveAllGoodStructsAsProblem ) {
|
3213
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, 0);
|
3214
|
+
}
|
3215
|
+
#if( /*bRELEASE_VERSION != 1 &&*/ EXTR_FLAGS == EXTR_TRANSPOSITION_EXAMPLES && EXTR_MASK == EXTR_FLAGS )
|
3216
|
+
else
|
3217
|
+
if ( prb_file && (bSortPrintINChIFlags &
|
3218
|
+
( FLAG_SORT_PRINT_TRANSPOS_BAS | FLAG_SORT_PRINT_TRANSPOS_REC ) )
|
3219
|
+
) {
|
3220
|
+
CopyMOLfile(inp_file, sd->fPtrStart, sd->fPtrEnd, prb_file, 0);
|
3221
|
+
}
|
3222
|
+
#endif
|
3223
|
+
}
|
3224
|
+
for ( i = 0; i < INCHI_NUM; i ++ ) {
|
3225
|
+
for ( k = 0; k < TAUT_NUM+1; k ++ ) {
|
3226
|
+
FreeCompAtomData( &composite_norm_data[i][k] );
|
3227
|
+
}
|
3228
|
+
}
|
3229
|
+
FreeOrigStruct( pOrigStruct);
|
3230
|
+
|
3231
|
+
|
3232
|
+
/*
|
3233
|
+
FreeInpAtomData( inp_cur_data );
|
3234
|
+
FreeInpAtomData( inp_norm_data[0] );
|
3235
|
+
FreeInpAtomData( inp_norm_data[1] );
|
3236
|
+
*/
|
3237
|
+
exit_function:
|
3238
|
+
|
3239
|
+
return nRet;
|
3240
|
+
}
|
3241
|
+
/************************************************************************************************/
|
3242
|
+
int bIsStructChiral( PINChI2 *pINChI2[INCHI_NUM], int num_components[] )
|
3243
|
+
{
|
3244
|
+
int i, j, k;
|
3245
|
+
INChI *pINChI;
|
3246
|
+
INChI_Stereo *Stereo;
|
3247
|
+
for ( j = 0; j < INCHI_NUM; j ++ ) { /* disconnected / reconnected */
|
3248
|
+
if ( !num_components[j] ) {
|
3249
|
+
continue;
|
3250
|
+
}
|
3251
|
+
for ( i = 0; i < num_components[j]; i ++ ) { /* component */
|
3252
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) { /* mobile/immobile H */
|
3253
|
+
if ( (pINChI = pINChI2[j][i][k]) &&
|
3254
|
+
!pINChI->bDeleted &&
|
3255
|
+
pINChI->nNumberOfAtoms > 0 ) {
|
3256
|
+
|
3257
|
+
if ( (Stereo = pINChI->Stereo) &&
|
3258
|
+
Stereo->t_parity &&
|
3259
|
+
Stereo->nNumberOfStereoCenters > 0 &&
|
3260
|
+
Stereo->nCompInv2Abs ) {
|
3261
|
+
return 1; /* inversion changed stereo */
|
3262
|
+
}
|
3263
|
+
if ( (Stereo = pINChI->StereoIsotopic) &&
|
3264
|
+
Stereo->t_parity &&
|
3265
|
+
Stereo->nNumberOfStereoCenters > 0 &&
|
3266
|
+
Stereo->nCompInv2Abs ) {
|
3267
|
+
return 1; /* inversion changed stereo */
|
3268
|
+
}
|
3269
|
+
}
|
3270
|
+
}
|
3271
|
+
}
|
3272
|
+
}
|
3273
|
+
return 0;
|
3274
|
+
}
|
3275
|
+
/************************************************************************************************/
|
3276
|
+
int CreateOneStructureINChI( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
|
3277
|
+
PINChI2 *pINChI2[INCHI_NUM], PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], int iINChI,
|
3278
|
+
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
3279
|
+
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
|
3280
|
+
COMP_ATOM_DATA composite_norm_data2[][TAUT_NUM+1],
|
3281
|
+
int num_inp, char *pStr, int nStrLen, NORM_CANON_FLAGS *pncFlags )
|
3282
|
+
{
|
3283
|
+
int i, j, k, /*m,*/ nRet = 0;
|
3284
|
+
#ifndef INCHI_LIB
|
3285
|
+
int n;
|
3286
|
+
#ifndef INCHI_ANSI_ONLY
|
3287
|
+
int err;
|
3288
|
+
#endif
|
3289
|
+
#endif
|
3290
|
+
|
3291
|
+
PINChI2 *pINChI = NULL;
|
3292
|
+
PINChI_Aux2 *pINChI_Aux = NULL;
|
3293
|
+
|
3294
|
+
INP_ATOM_DATA InpCurAtData;
|
3295
|
+
INP_ATOM_DATA *inp_cur_data;
|
3296
|
+
|
3297
|
+
INP_ATOM_DATA InpNormAtData, InpNormTautData;
|
3298
|
+
INP_ATOM_DATA *inp_norm_data[TAUT_NUM]; /* = { &InpNormAtData, &InpNormTautData }; */
|
3299
|
+
ORIG_ATOM_DATA *cur_prep_inp_data = prep_inp_data + iINChI;
|
3300
|
+
inchiTime ulTStart;
|
3301
|
+
#ifndef INCHI_ANSI_ONLY
|
3302
|
+
int bShowStructure = 0;
|
3303
|
+
int bStructurePreprocessed = 0; /* All changes except disconnection */
|
3304
|
+
int bStructureDisconnected = 0;
|
3305
|
+
int bAlsoOutputReconnected = 0, bINCHI_LIB_Flag = 0;
|
3306
|
+
COMP_ATOM_DATA *composite_norm_data = composite_norm_data2[iINChI];
|
3307
|
+
INP_ATOM_DATA2 *all_inp_norm_data = NULL;
|
3308
|
+
#endif
|
3309
|
+
|
3310
|
+
/*
|
3311
|
+
if ( orig_inp_data is NOT empty AND
|
3312
|
+
prep_inp_data[0] IS empty ) then:
|
3313
|
+
|
3314
|
+
1. copy orig_inp_data --> prep_inp_data[0]
|
3315
|
+
2. fix odd things in prep_inp_data[0]
|
3316
|
+
3. if( orig_inp_data->bDisconnectSalts ) then
|
3317
|
+
-- disconnect salts in prep_inp_data[0]
|
3318
|
+
4. move protons to neutralize charges on heteroatoms
|
3319
|
+
5. if( orig_inp_data->bDisconnectCoord ) then
|
3320
|
+
-- copy prep_inp_data[0] --> prep_inp_data[1]
|
3321
|
+
-- disconnect metals in prep_inp_data[0]
|
3322
|
+
|
3323
|
+
[ This all is done in PreprocessOneStructure() ]
|
3324
|
+
|
3325
|
+
iINChI = 0
|
3326
|
+
=========
|
3327
|
+
(normal/disconnected layer)
|
3328
|
+
|
3329
|
+
1. normalize prep_inp_data[0] in inp_norm_data[0,1]
|
3330
|
+
2. create INChI[ iINChI ] out of inp_norm_data[0,1]
|
3331
|
+
|
3332
|
+
|
3333
|
+
iINChI = 1 AND orig_inp_data->bDisconnectCoord > 0
|
3334
|
+
=================================================
|
3335
|
+
(reconnected layer)
|
3336
|
+
|
3337
|
+
1. normalize prep_inp_data[1] in inp_norm_data[0,1]
|
3338
|
+
2. create INChI[ iINChI ] out of inp_norm_data[0,1]
|
3339
|
+
|
3340
|
+
*/
|
3341
|
+
|
3342
|
+
#if( TEST_RENUMB_ATOMS == 1 )
|
3343
|
+
RENUMB_DATA RenumbData;
|
3344
|
+
RENUMB_DATA *pRenumbData = &RenumbData;
|
3345
|
+
#endif
|
3346
|
+
|
3347
|
+
|
3348
|
+
ip->msec_LeftTime = ip->msec_MaxTime; /* start timeout countdown for each component */
|
3349
|
+
|
3350
|
+
#if( TEST_RENUMB_ATOMS == 1 )
|
3351
|
+
memset( pRenumbData, 0, sizeof(*pRenumbData) );
|
3352
|
+
#endif
|
3353
|
+
|
3354
|
+
inp_cur_data = &InpCurAtData;
|
3355
|
+
inp_norm_data[TAUT_NON] = &InpNormAtData;
|
3356
|
+
inp_norm_data[TAUT_YES] = &InpNormTautData;
|
3357
|
+
|
3358
|
+
memset( inp_cur_data , 0, sizeof( *inp_cur_data ) );
|
3359
|
+
memset( inp_norm_data[TAUT_NON], 0, sizeof( *inp_norm_data[0] ) );
|
3360
|
+
memset( inp_norm_data[TAUT_YES], 0, sizeof( *inp_norm_data[0] ) );
|
3361
|
+
|
3362
|
+
#ifndef INCHI_ANSI_ONLY
|
3363
|
+
memset( composite_norm_data+TAUT_NON, 0, sizeof( composite_norm_data[0] ) );
|
3364
|
+
memset( composite_norm_data+TAUT_YES, 0, sizeof( composite_norm_data[0] ) );
|
3365
|
+
memset( composite_norm_data+TAUT_INI, 0, sizeof( composite_norm_data[0] ) );
|
3366
|
+
#endif
|
3367
|
+
if ( ip->bAllowEmptyStructure && !orig_inp_data->at && !orig_inp_data->num_inp_atoms ) {
|
3368
|
+
;
|
3369
|
+
} else
|
3370
|
+
if ( !orig_inp_data->at || !orig_inp_data->num_inp_atoms ) {
|
3371
|
+
return 0; /* nothing to do */
|
3372
|
+
}
|
3373
|
+
if ( iINChI == 1 && orig_inp_data->bDisconnectCoord <= 0 ) {
|
3374
|
+
return 0;
|
3375
|
+
}
|
3376
|
+
|
3377
|
+
/* m = iINChI; */ /* orig_inp_data index */
|
3378
|
+
|
3379
|
+
if ( iINChI != INCHI_BAS && iINChI != INCHI_REC ) {
|
3380
|
+
AddMOLfileError(sd->pStrErrStruct, "Fatal undetermined program error");
|
3381
|
+
sd->nStructReadError = 97;
|
3382
|
+
nRet = sd->nErrorType = _IS_FATAL;
|
3383
|
+
goto exit_function;
|
3384
|
+
}
|
3385
|
+
|
3386
|
+
/*******************************************************************
|
3387
|
+
* *
|
3388
|
+
* *
|
3389
|
+
* Whole structure preprocessing: 1st step of the normalization *
|
3390
|
+
* *
|
3391
|
+
* Happen only on the first call to CreateOneStructureINChI() *
|
3392
|
+
* *
|
3393
|
+
* *
|
3394
|
+
*******************************************************************/
|
3395
|
+
|
3396
|
+
if ( (!prep_inp_data->at || !prep_inp_data->num_inp_atoms) && orig_inp_data->num_inp_atoms > 0 ) {
|
3397
|
+
/* the structure has not been preprocessed */
|
3398
|
+
if ( ip->msec_MaxTime ) {
|
3399
|
+
InchiTimeGet( &ulTStart );
|
3400
|
+
}
|
3401
|
+
PreprocessOneStructure( sd, ip, orig_inp_data, prep_inp_data );
|
3402
|
+
pncFlags->bTautFlags[iINChI][TAUT_YES] =
|
3403
|
+
pncFlags->bTautFlags[iINChI][TAUT_NON] = sd->bTautFlags[INCHI_BAS] | ip->bTautFlags;
|
3404
|
+
pncFlags->bTautFlagsDone[iINChI][TAUT_YES] =
|
3405
|
+
pncFlags->bTautFlagsDone[iINChI][TAUT_NON] = sd->bTautFlagsDone[INCHI_BAS] | ip->bTautFlagsDone;
|
3406
|
+
|
3407
|
+
#ifndef INCHI_ANSI_ONLY
|
3408
|
+
/* in this location the call happens once for each input structure, before preprocessing */
|
3409
|
+
bStructurePreprocessed = (0 != (sd->bTautFlagsDone[INCHI_BAS] & (
|
3410
|
+
TG_FLAG_MOVE_HPLUS2NEUTR_DONE |
|
3411
|
+
TG_FLAG_DISCONNECT_SALTS_DONE |
|
3412
|
+
TG_FLAG_MOVE_POS_CHARGES_DONE |
|
3413
|
+
TG_FLAG_FIX_ODD_THINGS_DONE )));
|
3414
|
+
bStructureDisconnected = (0 != (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE));
|
3415
|
+
|
3416
|
+
bShowStructure = ( bStructurePreprocessed ||
|
3417
|
+
bStructureDisconnected ||
|
3418
|
+
prep_inp_data[0].num_components > 1);
|
3419
|
+
|
3420
|
+
/* sd->bTautFlags[] contains output flags
|
3421
|
+
ip->bTautFlags contains input flags
|
3422
|
+
*/
|
3423
|
+
bAlsoOutputReconnected = (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
|
3424
|
+
(ip->bTautFlags & TG_FLAG_RECONNECT_COORD);
|
3425
|
+
bINCHI_LIB_Flag = 0;
|
3426
|
+
|
3427
|
+
/*************** output structures to INCHI_LIB conditions *********************
|
3428
|
+
*
|
3429
|
+
* Send to INCHI_LIB:
|
3430
|
+
*
|
3431
|
+
* type component conditions
|
3432
|
+
*
|
3433
|
+
* COMPONENT_ORIGINAL #0: (num_components > 1)
|
3434
|
+
* COMPONENT_ORIGINAL_PREPROCESSED #0: (num_components > 1) && (preprocessed)
|
3435
|
+
* COMPONENT_ORIGINAL #1: (num_components = 1) && (preprocessed)
|
3436
|
+
*
|
3437
|
+
* Flags explanation:
|
3438
|
+
* MAIN => iINChI=0, RECN => iINChI=1 (Reconnected)
|
3439
|
+
* ORIG => Original, PREP => Preprocessed
|
3440
|
+
*
|
3441
|
+
* Possible flags: k
|
3442
|
+
*
|
3443
|
+
* COMP_ORIG_0_MAIN 0x0001 0 COMPONENT_ORIGINAL, bMain, component #0
|
3444
|
+
* COMP_ORIG_0_RECN 0x0002 1 COMPONENT_ORIGINAL, bRecn, component #0
|
3445
|
+
*
|
3446
|
+
* COMP_PREP_0_MAIN 0x0004 2 COMPONENT_ORIGINAL_PREPROCESSED, bMain, component #0
|
3447
|
+
* COMP_PREP_0_RECN 0x0008 3 COMPONENT_ORIGINAL_PREPROCESSED, bRecn, component #0
|
3448
|
+
*
|
3449
|
+
* COMP_ORIG_1_MAIN 0x0010 4 COMPONENT_ORIGINAL, bMain, component #1
|
3450
|
+
* COMP_ORIG_1_RECN 0x0020 5 COMPONENT_ORIGINAL, bRecn, component #1
|
3451
|
+
*
|
3452
|
+
* bReconnected = k%2 (0 or 1)
|
3453
|
+
* nComponent = k/4 (0 or 1)
|
3454
|
+
* bPreprocessed = (k/2)%2 (0 or 1)
|
3455
|
+
*
|
3456
|
+
******************************************************************************/
|
3457
|
+
/* Original -> Main, component #0, Original */
|
3458
|
+
if ( prep_inp_data[INCHI_BAS].num_components > 1 ) {
|
3459
|
+
bINCHI_LIB_Flag |= COMP_ORIG_0_MAIN;
|
3460
|
+
} else
|
3461
|
+
/* Original -> Main, component #1, Original */
|
3462
|
+
if ( prep_inp_data[INCHI_BAS].num_components == 1 && bStructurePreprocessed ) {
|
3463
|
+
bINCHI_LIB_Flag |= COMP_ORIG_1_MAIN;
|
3464
|
+
/* preprocessed will be added when output canonicalization results */
|
3465
|
+
}
|
3466
|
+
if ( bAlsoOutputReconnected ) {
|
3467
|
+
/* Original -> Reconnected, component #0, Original */
|
3468
|
+
if ( prep_inp_data[INCHI_REC].num_components > 1 ) {
|
3469
|
+
bINCHI_LIB_Flag |= COMP_ORIG_0_RECN;
|
3470
|
+
} else
|
3471
|
+
/* Original -> Reconnected, component #1, Original */
|
3472
|
+
if ( prep_inp_data[INCHI_BAS].num_components == 1 && bStructurePreprocessed ) {
|
3473
|
+
bINCHI_LIB_Flag |= COMP_ORIG_1_RECN;
|
3474
|
+
/* preprocessed will be added when output canonicalization results */
|
3475
|
+
}
|
3476
|
+
}
|
3477
|
+
if ( ip->msec_MaxTime ) {
|
3478
|
+
ip->msec_LeftTime -= InchiTimeElapsed( &ulTStart );
|
3479
|
+
}
|
3480
|
+
|
3481
|
+
/* display the ORIGINAL, UN-PREPROCESSED structure */
|
3482
|
+
if ( DisplayTheWholeStructure( sd, ip, szTitle, inp_file, log_file, orig_inp_data, num_inp,
|
3483
|
+
-1, bShowStructure, bINCHI_LIB_Flag ) ) {
|
3484
|
+
goto exit_function;
|
3485
|
+
}
|
3486
|
+
#endif
|
3487
|
+
switch (sd->nErrorType) {
|
3488
|
+
case _IS_ERROR:
|
3489
|
+
case _IS_FATAL:
|
3490
|
+
/* error message */
|
3491
|
+
nRet = TreatReadTheStructureErrors( sd, ip, LOG_MASK_ALL, inp_file, log_file, output_file, prb_file,
|
3492
|
+
prep_inp_data, &num_inp, pStr, nStrLen );
|
3493
|
+
goto exit_cycle;
|
3494
|
+
}
|
3495
|
+
}
|
3496
|
+
/* tranfer flags from INChI_Aux to sd */
|
3497
|
+
|
3498
|
+
|
3499
|
+
|
3500
|
+
|
3501
|
+
|
3502
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
3503
|
+
|
3504
|
+
/******************************************/
|
3505
|
+
/* Displaying the structures */
|
3506
|
+
/* Only under WIN32 */
|
3507
|
+
/******************************************/
|
3508
|
+
if ( ip->bDisplayCompositeResults &&
|
3509
|
+
!sd->bUserQuitComponentDisplay && prep_inp_data[iINChI].num_components > 1) {
|
3510
|
+
all_inp_norm_data = (INP_ATOM_DATA2 *)inchi_calloc( prep_inp_data[iINChI].num_components, sizeof(all_inp_norm_data[0]));
|
3511
|
+
}
|
3512
|
+
|
3513
|
+
|
3514
|
+
/* Display the input structure AFTER PREPROCESSING */
|
3515
|
+
switch ( iINChI ) {
|
3516
|
+
|
3517
|
+
case INCHI_BAS:
|
3518
|
+
/*------------ Possibly disconnected structure -------------------*/
|
3519
|
+
bStructurePreprocessed = 0 != (sd->bTautFlagsDone[iINChI] & (
|
3520
|
+
TG_FLAG_MOVE_HPLUS2NEUTR_DONE |
|
3521
|
+
TG_FLAG_DISCONNECT_SALTS_DONE |
|
3522
|
+
TG_FLAG_MOVE_POS_CHARGES_DONE |
|
3523
|
+
TG_FLAG_MOVE_CHARGE_COORD_DONE |
|
3524
|
+
TG_FLAG_DISCONNECT_COORD_DONE |
|
3525
|
+
TG_FLAG_FIX_ODD_THINGS_DONE ));
|
3526
|
+
bINCHI_LIB_Flag = 0;
|
3527
|
+
|
3528
|
+
/* Preprocessed/Main -> Main, component #0, Preprocessed */
|
3529
|
+
if ( prep_inp_data[iINChI].num_components > 1 && bStructurePreprocessed ) {
|
3530
|
+
bINCHI_LIB_Flag |= COMP_PREP_0_MAIN;
|
3531
|
+
}
|
3532
|
+
|
3533
|
+
bShowStructure = ( bStructurePreprocessed && prep_inp_data[iINChI].num_components > 1);
|
3534
|
+
break;
|
3535
|
+
|
3536
|
+
case INCHI_REC:
|
3537
|
+
/*------------ Reconnected structure ------------------------------*/
|
3538
|
+
bAlsoOutputReconnected = (sd->bTautFlagsDone[INCHI_BAS] & TG_FLAG_DISCONNECT_COORD_DONE) &&
|
3539
|
+
(ip->bTautFlags & TG_FLAG_RECONNECT_COORD);
|
3540
|
+
if ( !bAlsoOutputReconnected ) {
|
3541
|
+
break;
|
3542
|
+
}
|
3543
|
+
bStructurePreprocessed = 0 != (sd->bTautFlagsDone[iINChI] & (
|
3544
|
+
TG_FLAG_MOVE_HPLUS2NEUTR_DONE |
|
3545
|
+
TG_FLAG_DISCONNECT_SALTS_DONE |
|
3546
|
+
TG_FLAG_MOVE_POS_CHARGES_DONE |
|
3547
|
+
TG_FLAG_FIX_ODD_THINGS_DONE ));
|
3548
|
+
bINCHI_LIB_Flag = 0;
|
3549
|
+
|
3550
|
+
/* Preprocessed/Reconnected -> Reconnected, component #0, Preprocessed */
|
3551
|
+
if ( prep_inp_data[iINChI].num_components > 1 && bStructurePreprocessed ) {
|
3552
|
+
bINCHI_LIB_Flag |= COMP_PREP_0_RECN;
|
3553
|
+
}
|
3554
|
+
|
3555
|
+
bShowStructure = ( bStructurePreprocessed && prep_inp_data[iINChI].num_components > 1 );
|
3556
|
+
break;
|
3557
|
+
default:
|
3558
|
+
bShowStructure = 0;
|
3559
|
+
}
|
3560
|
+
if ( prep_inp_data[iINChI].num_inp_atoms > 0 ) {
|
3561
|
+
if ( DisplayTheWholeStructure( sd, ip, szTitle, inp_file, log_file, prep_inp_data+iINChI, num_inp,
|
3562
|
+
iINChI, bShowStructure, bINCHI_LIB_Flag ) ) {
|
3563
|
+
goto exit_function;
|
3564
|
+
}
|
3565
|
+
}
|
3566
|
+
#endif /* } ifndef INCHI_ANSI_ONLY */
|
3567
|
+
|
3568
|
+
|
3569
|
+
|
3570
|
+
/* allocate pINChI[iINChI] and pINChI_Aux2[iINChI] -- arrays of pointers to INChI and INChI_Aux */
|
3571
|
+
/* assign values to sd->num_components[] */
|
3572
|
+
MYREALLOC2(PINChI2, PINChI_Aux2, pINChI2[iINChI], pINChI_Aux2[iINChI], sd->num_components[iINChI], cur_prep_inp_data->num_components, k);
|
3573
|
+
if ( k ) {
|
3574
|
+
AddMOLfileError(sd->pStrErrStruct, "Cannot allocate output data. Terminating");
|
3575
|
+
sd->nStructReadError = 99;
|
3576
|
+
sd->nErrorType = _IS_FATAL;
|
3577
|
+
goto exit_function;
|
3578
|
+
}
|
3579
|
+
pINChI = pINChI2[iINChI];
|
3580
|
+
pINChI_Aux = pINChI_Aux2[iINChI];
|
3581
|
+
|
3582
|
+
/**************************************************************************/
|
3583
|
+
/* */
|
3584
|
+
/* */
|
3585
|
+
/* 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 */
|
3586
|
+
/* */
|
3587
|
+
/* */
|
3588
|
+
/* O N E B Y O N E */
|
3589
|
+
/* */
|
3590
|
+
/* */
|
3591
|
+
/**************************************************************************/
|
3592
|
+
|
3593
|
+
for ( i = 0, nRet = 0; !sd->bUserQuitComponent && i < cur_prep_inp_data->num_components; i ++ ) {
|
3594
|
+
if ( ip->msec_MaxTime ) {
|
3595
|
+
InchiTimeGet( &ulTStart );
|
3596
|
+
}
|
3597
|
+
#ifndef INCHI_LIB /* { */
|
3598
|
+
#if( bREUSE_INCHI == 1 )
|
3599
|
+
if ( iINChI == INCHI_REC && (!ip->bDisplay && !(ip->bCompareComponents & CMP_COMPONENTS) ||
|
3600
|
+
sd->bUserQuitComponentDisplay) ) {
|
3601
|
+
/* reconnected structure */
|
3602
|
+
int m = iINChI-1;
|
3603
|
+
/* find whether we have already calculated this INChI in basic (disconnected) layer */
|
3604
|
+
for ( j = n = 0; j < prep_inp_data[m].num_components; j ++ ) {
|
3605
|
+
if ( i+1 == prep_inp_data[m].nOldCompNumber[j] &&
|
3606
|
+
(pINChI2[m][j][TAUT_NON] || pINChI2[m][j][TAUT_YES]) ) {
|
3607
|
+
/* yes, we have already done this */
|
3608
|
+
if ( !n++ ) {
|
3609
|
+
memcpy( pINChI +i, pINChI2 [m]+j, sizeof(pINChI[0]));
|
3610
|
+
memcpy( pINChI_Aux+i, pINChI_Aux2[m]+j, sizeof(pINChI_Aux[0]));
|
3611
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
3612
|
+
if ( pINChI[i][k] ) {
|
3613
|
+
pINChI[i][k]->nRefCount ++;
|
3614
|
+
if ( pINChI[i][k]->nNumberOfAtoms > 0 ) {
|
3615
|
+
switch( k ) {
|
3616
|
+
case TAUT_NON:
|
3617
|
+
sd->num_non_taut[iINChI] ++;
|
3618
|
+
break;
|
3619
|
+
case TAUT_YES:
|
3620
|
+
if ( pINChI[i][k]->lenTautomer > 0 ) {
|
3621
|
+
sd->num_taut[iINChI] ++;
|
3622
|
+
} else
|
3623
|
+
if ( !pINChI[i][TAUT_NON] || !pINChI[i][TAUT_NON]->nNumberOfAtoms ) {
|
3624
|
+
sd->num_non_taut[iINChI] ++;
|
3625
|
+
}
|
3626
|
+
break;
|
3627
|
+
}
|
3628
|
+
}
|
3629
|
+
}
|
3630
|
+
if ( pINChI_Aux[i][k] ) {
|
3631
|
+
pINChI_Aux[i][k]->nRefCount ++;
|
3632
|
+
}
|
3633
|
+
}
|
3634
|
+
}
|
3635
|
+
}
|
3636
|
+
}
|
3637
|
+
if ( n == 1 ) {
|
3638
|
+
continue;
|
3639
|
+
}
|
3640
|
+
if ( n > 1 ) { /* ith component is equivalent to more than one another component */
|
3641
|
+
AddMOLfileError(sd->pStrErrStruct, "Cannot distinguish components");
|
3642
|
+
sd->nStructReadError = 99;
|
3643
|
+
sd->nErrorType = _IS_ERROR;
|
3644
|
+
goto exit_function;
|
3645
|
+
}
|
3646
|
+
}
|
3647
|
+
#endif
|
3648
|
+
#endif /* } INCHI_LIB */
|
3649
|
+
|
3650
|
+
/*****************************************************/
|
3651
|
+
/* a) allocate memory and extract current component */
|
3652
|
+
/*****************************************************/
|
3653
|
+
nRet = GetOneComponent( sd, ip, log_file, output_file, inp_cur_data, cur_prep_inp_data, i, num_inp, pStr, nStrLen );
|
3654
|
+
if ( ip->msec_MaxTime ) {
|
3655
|
+
ip->msec_LeftTime -= InchiTimeElapsed( &ulTStart );
|
3656
|
+
}
|
3657
|
+
switch ( nRet ) {
|
3658
|
+
case _IS_ERROR:
|
3659
|
+
case _IS_FATAL:
|
3660
|
+
goto exit_cycle;
|
3661
|
+
}
|
3662
|
+
#ifndef INCHI_LIBRARY
|
3663
|
+
/* console request: Display the component? */
|
3664
|
+
if ( ip->bDisplay && inp_file != stdin ) {
|
3665
|
+
if ( user_quit("Enter=Display Component, Esc=Stop ?", ip->ulDisplTime) ) {
|
3666
|
+
sd->bUserQuitComponent = 1;
|
3667
|
+
break;
|
3668
|
+
}
|
3669
|
+
}
|
3670
|
+
#endif
|
3671
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
3672
|
+
/* b) Display the extracted original component structure */
|
3673
|
+
if ( inp_cur_data->at && ip->bDisplay && !sd->bUserQuitComponentDisplay ) {
|
3674
|
+
if ( cur_prep_inp_data->num_components == 1 ) {
|
3675
|
+
sprintf( szTitle, "%sInput Structure #%d.%s%s%s%s%s",
|
3676
|
+
bStructurePreprocessed? "Preprocessed ":"",
|
3677
|
+
num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
|
3678
|
+
} else {
|
3679
|
+
sprintf( szTitle, "Component #%d of %d, Input Structure #%d.%s%s%s%s%s",
|
3680
|
+
i+1, cur_prep_inp_data->num_components,
|
3681
|
+
num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
|
3682
|
+
}
|
3683
|
+
#ifndef INCHI_LIB
|
3684
|
+
err = DisplayStructure( inp_cur_data->at, inp_cur_data->num_at,
|
3685
|
+
0, 0, NULL, 1/*isotopic*/, 0/*taut*/, NULL, NULL,
|
3686
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
|
3687
|
+
sd->bUserQuitComponentDisplay = (err==ESC_KEY);
|
3688
|
+
if ( !err ) {
|
3689
|
+
my_fprintf( stderr, "Cannot display the structure\n");
|
3690
|
+
}
|
3691
|
+
#else
|
3692
|
+
if(DRAWDATA && DRAWDATA_EXISTS)
|
3693
|
+
{
|
3694
|
+
struct DrawData vDrawData;
|
3695
|
+
int nType = COMPONENT_ORIGINAL;
|
3696
|
+
vDrawData.pWindowData = CreateWinData_( inp_cur_data->at, inp_cur_data->num_at,
|
3697
|
+
0, 0, NULL,
|
3698
|
+
1 /* display isotopic if present */, 0, NULL, NULL,
|
3699
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode );
|
3700
|
+
if( vDrawData.pWindowData != NULL )
|
3701
|
+
{
|
3702
|
+
if ( DRAWDATA_EXISTS ( i+1, nType, iINChI ) ) { /* i = component number */
|
3703
|
+
nType = COMPONENT_ORIGINAL_PREPROCESSED;
|
3704
|
+
}
|
3705
|
+
vDrawData.nComponent = i+1;
|
3706
|
+
vDrawData.nType = nType;
|
3707
|
+
vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
|
3708
|
+
vDrawData.szTitle = _strdup(szTitle);
|
3709
|
+
vDrawData.pWindowData->szTitle = _strdup(szTitle);
|
3710
|
+
DRAWDATA(&vDrawData);
|
3711
|
+
}
|
3712
|
+
}
|
3713
|
+
#endif
|
3714
|
+
}
|
3715
|
+
#endif /* } INCHI_ANSI_ONLY */
|
3716
|
+
|
3717
|
+
#if( TEST_RENUMB_ATOMS == 1 ) /* { */
|
3718
|
+
/****************************************************************************/
|
3719
|
+
/* R E N U M B E R I N G (testing only) Part I STARTS here */
|
3720
|
+
/****************************************************************************/
|
3721
|
+
RenumberingTestInit( pRenumbData, inp_cur_data );
|
3722
|
+
if ( log_file != stderr ) {
|
3723
|
+
if ( ip->bDisplay )
|
3724
|
+
my_fprintf( log_file, "Component #%d structure #%d.%s%s%s%s...\n", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
3725
|
+
else
|
3726
|
+
my_fprintf( stderr, "Component #%d structure #%d.%s%s%s%s...\r", i+1, num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
3727
|
+
}
|
3728
|
+
/****************************************************************************/
|
3729
|
+
/* R E N U M B E R I N G (testing only) Part I ENDS here */
|
3730
|
+
/****************************************************************************/
|
3731
|
+
#endif /* } TEST_RENUMB_ATOMS */
|
3732
|
+
|
3733
|
+
|
3734
|
+
/*******************************************************************************/
|
3735
|
+
/* */
|
3736
|
+
/* 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 */
|
3737
|
+
/* */
|
3738
|
+
/* (both tautomeric and non-tautomeric if requested) */
|
3739
|
+
/* */
|
3740
|
+
/*******************************************************************************/
|
3741
|
+
/* c) Create the component's INChI ( copies ip->bTautFlags into sd->bTautFlags)*/
|
3742
|
+
/*******************************************************************************/
|
3743
|
+
nRet = CreateOneComponentINChI( sd, ip, inp_cur_data, orig_inp_data, pINChI/*2[iINChI]*/, pINChI_Aux/*2[iINChI]*/, iINChI,
|
3744
|
+
i, num_inp, inp_norm_data, pncFlags, log_file );
|
3745
|
+
|
3746
|
+
|
3747
|
+
#if( TEST_RENUMB_ATOMS == 1 ) /* { */
|
3748
|
+
/****************************************************************************/
|
3749
|
+
/* R E N U M B E R I N G (testing only) Part II STARTS here */
|
3750
|
+
/****************************************************************************/
|
3751
|
+
if ( !nRet ) {
|
3752
|
+
nRet = RenumberingTest( pINChI/*2[iINChI]*/, pINChI_Aux/*2[iINChI]*/, orig_inp_data, iINChI, pRenumbData, inp_cur_data, inp_norm_data, sd, ip, szTitle, log_file, prb_file, i, num_inp, pncFlags);
|
3753
|
+
}
|
3754
|
+
RenumberingTestUninit( pRenumbData );
|
3755
|
+
/****************************************************************************/
|
3756
|
+
/* R E N U M B E R I N G (testing only) Part II ENDS here */
|
3757
|
+
/****************************************************************************/
|
3758
|
+
#endif /* } TEST_RENUMB_ATOMS */
|
3759
|
+
|
3760
|
+
|
3761
|
+
/* d) Display one component structure and/or INChI results only if there was no error */
|
3762
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
3763
|
+
if ( !nRet ) {
|
3764
|
+
/* output one component INChI to the stdout if requested */
|
3765
|
+
/*
|
3766
|
+
if ( ip->bDisplayEachComponentINChI ) {
|
3767
|
+
int cur_num_non_taut = (pINChI[i][TAUT_NON] && pINChI[i][TAUT_NON]->nNumberOfAtoms>0);
|
3768
|
+
int cur_num_taut = (pINChI[i][TAUT_YES] && pINChI[i][TAUT_YES]->nNumberOfAtoms>0);
|
3769
|
+
if ( ip->bDisplayEachComponentINChI && cur_num_non_taut + cur_num_taut ) {
|
3770
|
+
SortAndPrintINChI( stdout, pStr, nStrLen, NULL, ip, 1, cur_num_non_taut, cur_num_taut,
|
3771
|
+
num_inp, pINChI+i, pINChI_Aux+i );
|
3772
|
+
}
|
3773
|
+
}
|
3774
|
+
*/
|
3775
|
+
/**************************************************************************
|
3776
|
+
* display from one up to 4 structure pictures-results for each component *
|
3777
|
+
* Enable buttons: *
|
3778
|
+
* BN (non-tautomeric non-isotopic): inp_norm_data[0]->bExists *
|
3779
|
+
* TN (tautomeric non-isotopic): inp_norm_data[1]->bExists *
|
3780
|
+
* BI (non-tautomeric isotopic): inp_norm_data[0]->bExists && *
|
3781
|
+
* inp_norm_data[0]->bHasIsotopicLayer *
|
3782
|
+
* TI (tautomeric isotopic): inp_norm_data[1]->bExists && *
|
3783
|
+
* inp_norm_data[1]->bHasIsotopicLayer *
|
3784
|
+
**************************************************************************/
|
3785
|
+
int bIsotopic, bTautomeric, bDisplayTaut, bHasIsotopicLayer, bFixedBondsTaut, m_max, m, nNumDisplayedFixedBondTaut=0;
|
3786
|
+
for ( j = 0; ip->bDisplay && !sd->bUserQuitComponentDisplay && j < TAUT_NUM; j ++ ) {
|
3787
|
+
if ( inp_norm_data[j]->bExists && !inp_norm_data[j]->bDeleted ) {
|
3788
|
+
bTautomeric = (pINChI[i][j]->lenTautomer > 0); /* same as (inp_norm_data[j]->bTautomeric > 0) */
|
3789
|
+
/* if requested tautomeric and no tautmerism found then do not say mobile or fixed H. 2004-10-27 */
|
3790
|
+
bDisplayTaut = (!(ip->nMode & REQ_MODE_BASIC) && !bTautomeric)? -1 : bTautomeric;
|
3791
|
+
bHasIsotopicLayer = (inp_norm_data[j]->bHasIsotopicLayer > 0);
|
3792
|
+
for ( k = 0; k <= bHasIsotopicLayer; k ++ ) {
|
3793
|
+
bIsotopic = (k > 0);
|
3794
|
+
m_max = inp_norm_data[j]->at_fixed_bonds && inp_norm_data[j]->bTautPreprocessed? 1 : 0;
|
3795
|
+
for ( m = m_max; 0 <= m; m -- ) {
|
3796
|
+
bFixedBondsTaut = (m>0);
|
3797
|
+
nNumDisplayedFixedBondTaut += bFixedBondsTaut; /* display only one time */
|
3798
|
+
/* added number of components, added another format for a single component case - DCh */
|
3799
|
+
if ( cur_prep_inp_data->num_components > 1 ) {
|
3800
|
+
sprintf( szTitle, "%s Component #%d of %d, Structure #%d%s%s.%s%s%s%s%s",
|
3801
|
+
bFixedBondsTaut? "Preprocessed":"Result for",
|
3802
|
+
i+1, cur_prep_inp_data->num_components, num_inp,
|
3803
|
+
bDisplayTaut==1? ", mobile H": bDisplayTaut==0?", fixed H":"",
|
3804
|
+
bIsotopic? ", isotopic":"",
|
3805
|
+
SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
|
3806
|
+
} else {
|
3807
|
+
sprintf( szTitle, "%s Structure #%d%s%s.%s%s%s%s%s",
|
3808
|
+
bFixedBondsTaut? "Preprocessed":"Result for",
|
3809
|
+
num_inp,
|
3810
|
+
bDisplayTaut==1? ", mobile H": bDisplayTaut==0?", fixed H":"",
|
3811
|
+
bIsotopic? ", isotopic":"",
|
3812
|
+
SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue), iINChI? " (Reconnected)":"");
|
3813
|
+
}
|
3814
|
+
#ifndef INCHI_LIB
|
3815
|
+
if ( bFixedBondsTaut && nNumDisplayedFixedBondTaut != 1 )
|
3816
|
+
continue;
|
3817
|
+
if ( bFixedBondsTaut ) {
|
3818
|
+
err = DisplayStructure( inp_norm_data[j]->at_fixed_bonds, inp_norm_data[j]->num_at,
|
3819
|
+
inp_norm_data[j]->num_removed_H,
|
3820
|
+
inp_norm_data[j]->nNumRemovedProtons,
|
3821
|
+
inp_norm_data[j]->nNumRemovedProtonsIsotopic,
|
3822
|
+
bHasIsotopicLayer, j, NULL, NULL,
|
3823
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
|
3824
|
+
} else {
|
3825
|
+
err = DisplayStructure( inp_norm_data[j]->at, inp_norm_data[j]->num_at,
|
3826
|
+
0, 0, NULL,
|
3827
|
+
k, j, pINChI[i], pINChI_Aux[i],
|
3828
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode, szTitle );
|
3829
|
+
}
|
3830
|
+
if ( sd->bUserQuitComponentDisplay = (err==ESC_KEY) ) {
|
3831
|
+
break;
|
3832
|
+
}
|
3833
|
+
#else
|
3834
|
+
if(DRAWDATA && !bFixedBondsTaut)
|
3835
|
+
{
|
3836
|
+
struct DrawData vDrawData;
|
3837
|
+
vDrawData.pWindowData = CreateWinData_( inp_norm_data[j]->at, inp_norm_data[j]->num_at,
|
3838
|
+
0, 0, NULL,
|
3839
|
+
k, j, pINChI[i], pINChI_Aux[i],
|
3840
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode );
|
3841
|
+
if( vDrawData.pWindowData != NULL )
|
3842
|
+
{
|
3843
|
+
int nType;
|
3844
|
+
vDrawData.nComponent = i+1;
|
3845
|
+
if( bTautomeric == 0 )
|
3846
|
+
nType = (bIsotopic == 0) ? COMPONENT_BN: COMPONENT_BI;
|
3847
|
+
else
|
3848
|
+
nType = (bIsotopic == 0) ? COMPONENT_TN: COMPONENT_TI;
|
3849
|
+
vDrawData.nType = nType;
|
3850
|
+
vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
|
3851
|
+
vDrawData.szTitle = _strdup(szTitle);
|
3852
|
+
vDrawData.pWindowData->szTitle = _strdup(szTitle);
|
3853
|
+
DRAWDATA(&vDrawData);
|
3854
|
+
}
|
3855
|
+
} else
|
3856
|
+
if(DRAWDATA && bFixedBondsTaut)
|
3857
|
+
{
|
3858
|
+
struct DrawData vDrawData;
|
3859
|
+
if ( (ip->bCompareComponents & CMP_COMPONENTS) &&
|
3860
|
+
!(ip->bCompareComponents & CMP_COMPONENTS_NONTAUT) &&
|
3861
|
+
!bIsotopic == !inp_norm_data[j]->bHasIsotopicLayer ) {
|
3862
|
+
|
3863
|
+
vDrawData.pWindowData =
|
3864
|
+
CreateWinData_( inp_norm_data[j]->at_fixed_bonds, inp_norm_data[j]->num_at,
|
3865
|
+
inp_norm_data[j]->num_removed_H,
|
3866
|
+
inp_norm_data[j]->nNumRemovedProtons,
|
3867
|
+
inp_norm_data[j]->nNumRemovedProtonsIsotopic,
|
3868
|
+
k, j, NULL, NULL,
|
3869
|
+
ip->bAbcNumbers, &ip->dp, ip->nMode );
|
3870
|
+
} else {
|
3871
|
+
continue;
|
3872
|
+
}
|
3873
|
+
if( vDrawData.pWindowData != NULL )
|
3874
|
+
{
|
3875
|
+
vDrawData.nComponent = i+1;
|
3876
|
+
vDrawData.nType = COMPONENT_ORIGINAL_PREPROCESSED;
|
3877
|
+
vDrawData.bReconnected = iINChI; /* 0=>main; 1=>reconnected */
|
3878
|
+
vDrawData.szTitle = _strdup(szTitle);
|
3879
|
+
vDrawData.pWindowData->szTitle = _strdup(szTitle);
|
3880
|
+
DRAWDATA(&vDrawData);
|
3881
|
+
}
|
3882
|
+
}
|
3883
|
+
#endif
|
3884
|
+
}
|
3885
|
+
}
|
3886
|
+
}
|
3887
|
+
}
|
3888
|
+
|
3889
|
+
/* save normalized components for composite display */
|
3890
|
+
if ( ip->bDisplayCompositeResults && all_inp_norm_data ) {
|
3891
|
+
for ( j = 0; j < TAUT_NUM; j ++ ) {
|
3892
|
+
if ( inp_norm_data[j]->bExists ) {
|
3893
|
+
all_inp_norm_data[i][j] = *inp_norm_data[j];
|
3894
|
+
memset( inp_norm_data[j], 0, sizeof(*inp_norm_data[0]) );
|
3895
|
+
}
|
3896
|
+
}
|
3897
|
+
}
|
3898
|
+
|
3899
|
+
}
|
3900
|
+
#endif /* } INCHI_ANSI_ONLY */
|
3901
|
+
if ( nRet ) {
|
3902
|
+
nRet = TreatCreateOneComponentINChIError(sd, ip, cur_prep_inp_data, i, num_inp,
|
3903
|
+
inp_file, log_file, output_file, prb_file,pStr, nStrLen );
|
3904
|
+
|
3905
|
+
break;
|
3906
|
+
}
|
3907
|
+
}
|
3908
|
+
/**************************************************************************/
|
3909
|
+
/* */
|
3910
|
+
/* */
|
3911
|
+
/* 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 */
|
3912
|
+
/* */
|
3913
|
+
/* C O M P O N E N T S O N E B Y O N E */
|
3914
|
+
/* */
|
3915
|
+
/* */
|
3916
|
+
/**************************************************************************/
|
3917
|
+
|
3918
|
+
|
3919
|
+
exit_cycle:
|
3920
|
+
|
3921
|
+
#if( TEST_RENUMB_ATOMS == 1 ) /* { */
|
3922
|
+
if ( pRenumbData->bRenumbErr && (!nRet || nRet==_IS_WARNING) ) {
|
3923
|
+
sd->nErrorCode = pRenumbData->bRenumbErr;
|
3924
|
+
nRet = TreatCreateOneComponentINChIError(sd, ip, cur_prep_inp_data, -1, num_inp,
|
3925
|
+
inp_file, log_file, output_file, prb_file,pStr, nStrLen );
|
3926
|
+
/* nRet = _IS_ERROR; */
|
3927
|
+
sd->nErrorCode = 0;
|
3928
|
+
nRet = 0;
|
3929
|
+
}
|
3930
|
+
#endif /* } TEST_RENUMB_ATOMS */
|
3931
|
+
switch ( nRet ) {
|
3932
|
+
|
3933
|
+
case _IS_FATAL:
|
3934
|
+
case _IS_ERROR:
|
3935
|
+
break;
|
3936
|
+
|
3937
|
+
default:
|
3938
|
+
|
3939
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
3940
|
+
/* composite results picture(s) */
|
3941
|
+
if ( all_inp_norm_data ) {
|
3942
|
+
int res = CreateCompositeNormAtom( composite_norm_data, all_inp_norm_data, pINChI, pINChI_Aux,
|
3943
|
+
prep_inp_data[iINChI].num_components, ip->nMode );
|
3944
|
+
/*
|
3945
|
+
for ( i = 0; i < prep_inp_data[iINChI].num_components; i ++ ) {
|
3946
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
3947
|
+
FreeInpAtomData( &all_inp_norm_data[i][k] );
|
3948
|
+
}
|
3949
|
+
}
|
3950
|
+
inchi_free( all_inp_norm_data );
|
3951
|
+
all_inp_norm_data = NULL;
|
3952
|
+
*/
|
3953
|
+
}
|
3954
|
+
#endif /* } INCHI_ANSI_ONLY */
|
3955
|
+
|
3956
|
+
break;
|
3957
|
+
}
|
3958
|
+
|
3959
|
+
|
3960
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
3961
|
+
/* avoid memory leaks in case of error */
|
3962
|
+
if ( all_inp_norm_data ) {
|
3963
|
+
for ( i = 0; i < prep_inp_data[iINChI].num_components; i ++ ) {
|
3964
|
+
for ( k = 0; k < TAUT_NUM; k ++ ) {
|
3965
|
+
FreeInpAtomData( &all_inp_norm_data[i][k] );
|
3966
|
+
}
|
3967
|
+
}
|
3968
|
+
inchi_free( all_inp_norm_data );
|
3969
|
+
all_inp_norm_data = NULL;
|
3970
|
+
}
|
3971
|
+
#endif /* } INCHI_ANSI_ONLY */
|
3972
|
+
|
3973
|
+
|
3974
|
+
FreeInpAtomData( inp_cur_data );
|
3975
|
+
for ( i = 0; i < TAUT_NUM; i ++ ) {
|
3976
|
+
FreeInpAtomData( inp_norm_data[i] );
|
3977
|
+
}
|
3978
|
+
|
3979
|
+
|
3980
|
+
exit_function:
|
3981
|
+
|
3982
|
+
return nRet;
|
3983
|
+
}
|
3984
|
+
|
3985
|
+
|
3986
|
+
|
3987
|
+
#ifndef INCHI_ANSI_ONLY /* { */
|
3988
|
+
/****************************************************************************/
|
3989
|
+
int CreateCompositeNormAtom( COMP_ATOM_DATA *composite_norm_data, INP_ATOM_DATA2 *all_inp_norm_data,
|
3990
|
+
PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int num_components, INCHI_MODE nMode )
|
3991
|
+
{
|
3992
|
+
int i, j, jj, k, n, m, tot_num_at, tot_num_H, cur_num_at, cur_num_H, nNumRemovedProtons;
|
3993
|
+
int num_comp[TAUT_NUM+1], num_taut[TAUT_NUM+1], num_del[TAUT_NUM+1], num_at[TAUT_NUM+1], num_inp_at[TAUT_NUM+1];
|
3994
|
+
int ret = 0, indicator = 1;
|
3995
|
+
inp_ATOM *at, *at_from;
|
3996
|
+
memset( num_comp, 0, sizeof(num_comp) );
|
3997
|
+
memset( num_taut, 0, sizeof(num_taut) );
|
3998
|
+
memset( num_del, 0, sizeof(num_taut) );
|
3999
|
+
/* count taut and non-taut components */
|
4000
|
+
for ( j = 0; j < TAUT_NUM; j ++ ) {
|
4001
|
+
num_comp[j] = num_taut[j] = 0;
|
4002
|
+
for ( i = 0; i < num_components; i ++ ) {
|
4003
|
+
if ( all_inp_norm_data[i][j].bExists ) {
|
4004
|
+
num_del[j] += (0 != all_inp_norm_data[i][j].bDeleted );
|
4005
|
+
num_comp[j] ++;
|
4006
|
+
num_taut[j] += (0 != all_inp_norm_data[i][j].bTautomeric);
|
4007
|
+
}
|
4008
|
+
}
|
4009
|
+
}
|
4010
|
+
/* count intermediate taut structure components */
|
4011
|
+
if ( num_comp[TAUT_YES] > num_del[TAUT_YES] && num_taut[TAUT_YES] ) {
|
4012
|
+
/*
|
4013
|
+
num_comp[TAUT_INI] = num_comp[TAUT_YES] - num_del[TAUT_YES];
|
4014
|
+
*/
|
4015
|
+
|
4016
|
+
for ( i = 0, j=TAUT_YES; i < num_components; i ++ ) {
|
4017
|
+
if ( all_inp_norm_data[i][j].bExists &&
|
4018
|
+
(all_inp_norm_data[i][j].bDeleted ||
|
4019
|
+
all_inp_norm_data[i][j].bTautomeric &&
|
4020
|
+
all_inp_norm_data[i][j].at_fixed_bonds &&
|
4021
|
+
all_inp_norm_data[i][j].bTautPreprocessed) ) {
|
4022
|
+
num_comp[TAUT_INI] ++;
|
4023
|
+
}
|
4024
|
+
}
|
4025
|
+
|
4026
|
+
}
|
4027
|
+
/* count atoms and allocate composite atom data */
|
4028
|
+
for ( jj = 0; jj <= TAUT_INI; jj ++ ) {
|
4029
|
+
num_at[jj] = num_inp_at[jj] = 0;
|
4030
|
+
j = inchi_min (jj, TAUT_YES);
|
4031
|
+
if ( num_comp[jj] ) {
|
4032
|
+
for ( i = 0; i < num_components; i ++ ) {
|
4033
|
+
if ( all_inp_norm_data[i][j].bDeleted )
|
4034
|
+
continue;
|
4035
|
+
/* find k = the normaized structure index */
|
4036
|
+
if ( jj == TAUT_INI ) {
|
4037
|
+
if ( all_inp_norm_data[i][j].bExists &&
|
4038
|
+
all_inp_norm_data[i][j].at_fixed_bonds ) {
|
4039
|
+
k = j;
|
4040
|
+
} else
|
4041
|
+
if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted &&
|
4042
|
+
!all_inp_norm_data[i][j].bDeleted ) {
|
4043
|
+
k = ALT_TAUT(j);
|
4044
|
+
} else
|
4045
|
+
if ( all_inp_norm_data[i][j].bExists ) {
|
4046
|
+
k = j;
|
4047
|
+
} else {
|
4048
|
+
continue;
|
4049
|
+
}
|
4050
|
+
} else {
|
4051
|
+
if ( all_inp_norm_data[i][j].bExists ) {
|
4052
|
+
k = j;
|
4053
|
+
} else
|
4054
|
+
if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted) {
|
4055
|
+
k = ALT_TAUT(j);
|
4056
|
+
} else {
|
4057
|
+
continue;
|
4058
|
+
}
|
4059
|
+
}
|
4060
|
+
num_inp_at[jj] += all_inp_norm_data[i][k].num_at; /* all atoms including terminal H */
|
4061
|
+
num_at[jj] += all_inp_norm_data[i][k].num_at - all_inp_norm_data[i][k].num_removed_H;
|
4062
|
+
}
|
4063
|
+
if ( num_inp_at[jj] ) {
|
4064
|
+
if ( !CreateCompAtomData( composite_norm_data+jj, num_inp_at[jj], num_components, jj == TAUT_INI ) )
|
4065
|
+
goto exit_error;
|
4066
|
+
composite_norm_data[jj].num_removed_H = num_inp_at[jj] - num_at[jj];
|
4067
|
+
}
|
4068
|
+
}
|
4069
|
+
}
|
4070
|
+
/* fill out composite atom */
|
4071
|
+
for ( jj = 0; jj <= TAUT_INI; jj ++, indicator <<= 1 ) {
|
4072
|
+
j = inchi_min (jj, TAUT_YES);
|
4073
|
+
if ( num_comp[jj] ) {
|
4074
|
+
tot_num_at = 0;
|
4075
|
+
tot_num_H = 0;
|
4076
|
+
for ( i = 0; i < num_components; i ++ ) {
|
4077
|
+
if ( all_inp_norm_data[i][j].bDeleted ) {
|
4078
|
+
composite_norm_data[jj].nNumRemovedProtons += all_inp_norm_data[i][j].nNumRemovedProtons;
|
4079
|
+
for ( n = 0; n < NUM_H_ISOTOPES; n ++ ) {
|
4080
|
+
composite_norm_data[jj].nNumRemovedProtonsIsotopic[n] += all_inp_norm_data[i][j].nNumRemovedProtonsIsotopic[n];
|
4081
|
+
}
|
4082
|
+
continue;
|
4083
|
+
}
|
4084
|
+
nNumRemovedProtons = 0;
|
4085
|
+
k = TAUT_NUM;
|
4086
|
+
/* find k = the normaized structure index */
|
4087
|
+
if ( jj == TAUT_INI ) {
|
4088
|
+
if ( all_inp_norm_data[i][j].bExists && all_inp_norm_data[i][j].at_fixed_bonds ) {
|
4089
|
+
k = j;
|
4090
|
+
} else
|
4091
|
+
if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists ) {
|
4092
|
+
k = ALT_TAUT(j);
|
4093
|
+
} else
|
4094
|
+
if ( all_inp_norm_data[i][j].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted ) {
|
4095
|
+
k = j;
|
4096
|
+
} else {
|
4097
|
+
continue;
|
4098
|
+
}
|
4099
|
+
} else {
|
4100
|
+
if ( all_inp_norm_data[i][j].bExists ) {
|
4101
|
+
k = j;
|
4102
|
+
} else
|
4103
|
+
if ( all_inp_norm_data[i][ALT_TAUT(j)].bExists && !all_inp_norm_data[i][ALT_TAUT(j)].bDeleted ) {
|
4104
|
+
k = ALT_TAUT(j);
|
4105
|
+
} else {
|
4106
|
+
continue;
|
4107
|
+
}
|
4108
|
+
}
|
4109
|
+
/* copy main atoms */
|
4110
|
+
cur_num_H = all_inp_norm_data[i][k].num_removed_H; /* number of terminal H atoms */
|
4111
|
+
cur_num_at = all_inp_norm_data[i][k].num_at - cur_num_H; /* number of all but explicit terminal H atoms */
|
4112
|
+
|
4113
|
+
if ( (tot_num_at + cur_num_at) > num_at[jj] ||
|
4114
|
+
(num_at[jj] + tot_num_H + cur_num_H) > num_inp_at[jj] ) {
|
4115
|
+
goto exit_error; /* miscount */
|
4116
|
+
}
|
4117
|
+
at = composite_norm_data[jj].at+tot_num_at; /* points to the 1st destination atom */
|
4118
|
+
at_from = (jj == TAUT_INI && k == TAUT_YES && all_inp_norm_data[i][k].at_fixed_bonds)?
|
4119
|
+
all_inp_norm_data[i][k].at_fixed_bonds : all_inp_norm_data[i][k].at;
|
4120
|
+
memcpy( at, at_from, sizeof(composite_norm_data[0].at[0]) * cur_num_at ); /* copy atoms except terminal H */
|
4121
|
+
/* shift neighbors of main atoms */
|
4122
|
+
for ( n = 0; n < cur_num_at; n ++, at ++ ) {
|
4123
|
+
for ( m = 0; m < at->valence; m ++ ) {
|
4124
|
+
at->neighbor[m] += tot_num_at;
|
4125
|
+
}
|
4126
|
+
}
|
4127
|
+
/* copy explicit H */
|
4128
|
+
if ( cur_num_H ) {
|
4129
|
+
at = composite_norm_data[jj].at+num_at[jj]+tot_num_H; /* points to the 1st destination atom */
|
4130
|
+
memcpy( at, at_from+cur_num_at,
|
4131
|
+
sizeof(composite_norm_data[0].at[0]) * cur_num_H );
|
4132
|
+
/* shift neighbors of explicit H atoms */
|
4133
|
+
for ( n = 0; n < cur_num_H; n ++, at ++ ) {
|
4134
|
+
for ( m = 0; m < at->valence; m ++ ) {
|
4135
|
+
at->neighbor[m] += tot_num_at;
|
4136
|
+
}
|
4137
|
+
}
|
4138
|
+
}
|
4139
|
+
/* composite counts */
|
4140
|
+
composite_norm_data[jj].bHasIsotopicLayer |= all_inp_norm_data[i][k].bHasIsotopicLayer;
|
4141
|
+
composite_norm_data[jj].num_isotopic += all_inp_norm_data[i][k].num_isotopic;
|
4142
|
+
composite_norm_data[jj].num_bonds += all_inp_norm_data[i][k].num_bonds;
|
4143
|
+
composite_norm_data[jj].bTautomeric += (j == jj) && all_inp_norm_data[i][k].bTautomeric;
|
4144
|
+
composite_norm_data[jj].nNumRemovedProtons += all_inp_norm_data[i][k].nNumRemovedProtons;
|
4145
|
+
for ( n = 0; n < NUM_H_ISOTOPES; n ++ ) {
|
4146
|
+
composite_norm_data[jj].nNumRemovedProtonsIsotopic[n] += all_inp_norm_data[i][k].nNumRemovedProtonsIsotopic[n];
|
4147
|
+
composite_norm_data[jj].num_iso_H[n] += all_inp_norm_data[i][k].num_iso_H[n];
|
4148
|
+
}
|
4149
|
+
/*
|
4150
|
+
composite_norm_data[j].num_at += cur_num_at + cur_num_H;
|
4151
|
+
composite_norm_data[j].num_removed_H += cur_num_H;
|
4152
|
+
*/
|
4153
|
+
/* total count */
|
4154
|
+
tot_num_at += cur_num_at;
|
4155
|
+
tot_num_H += cur_num_H;
|
4156
|
+
/* offset for the next component */
|
4157
|
+
if ( composite_norm_data[jj].nOffsetAtAndH ) {
|
4158
|
+
composite_norm_data[jj].nOffsetAtAndH[2*i] = tot_num_at;
|
4159
|
+
composite_norm_data[jj].nOffsetAtAndH[2*i+1] = num_at[jj]+tot_num_H;
|
4160
|
+
}
|
4161
|
+
}
|
4162
|
+
if ( tot_num_at != num_at[jj] ||
|
4163
|
+
num_at[jj] + tot_num_H != num_inp_at[jj] ) {
|
4164
|
+
goto exit_error; /* miscount */
|
4165
|
+
}
|
4166
|
+
composite_norm_data[jj].bExists = (tot_num_at>0);
|
4167
|
+
ret |= indicator;
|
4168
|
+
}
|
4169
|
+
}
|
4170
|
+
return ret;
|
4171
|
+
|
4172
|
+
|
4173
|
+
|
4174
|
+
|
4175
|
+
|
4176
|
+
exit_error:
|
4177
|
+
return ret;
|
4178
|
+
}
|
4179
|
+
#endif /* } INCHI_ANSI_ONLY */
|