rino 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 */
|