rino 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/ext/extconf.rb +1 -24
- data/ext/libinchi.so +0 -0
- data/ext/src/aux2atom.h +120 -39
- data/ext/src/comdef.h +3 -3
- data/ext/src/dispstru.c +2547 -0
- data/ext/src/dispstru.h +73 -0
- data/ext/src/extr_ct.h +5 -2
- data/ext/src/ichi.h +27 -11
- data/ext/src/ichi_bns.c +1800 -254
- data/ext/src/ichi_bns.h +205 -4
- data/ext/src/ichican2.c +197 -86
- data/ext/src/ichicano.c +8 -13
- data/ext/src/ichicano.h +2 -2
- data/ext/src/ichicans.c +11 -6
- data/ext/src/ichicant.h +2 -2
- data/ext/src/ichicomn.h +2 -2
- data/ext/src/ichicomp.h +19 -4
- data/ext/src/ichidrp.h +9 -5
- data/ext/src/ichierr.h +5 -3
- data/ext/src/ichiisot.c +2 -2
- data/ext/src/ichimain.c +461 -0
- data/ext/src/ichimain.h +23 -15
- data/ext/src/ichimak2.c +6 -6
- data/ext/src/ichimake.c +843 -42
- data/ext/src/ichimake.h +4 -2
- data/ext/src/ichimap1.c +5 -5
- data/ext/src/ichimap2.c +2 -2
- data/ext/src/ichimap4.c +34 -21
- data/ext/src/ichinorm.c +11 -5
- data/ext/src/ichinorm.h +3 -2
- data/ext/src/ichiparm.c +2 -2
- data/ext/src/ichiparm.h +232 -30
- data/ext/src/ichiprt1.c +35 -11
- data/ext/src/ichiprt2.c +78 -7
- data/ext/src/ichiprt3.c +300 -120
- data/ext/src/ichiqueu.c +17 -2
- data/ext/src/ichiread.c +6932 -0
- data/ext/src/ichiring.c +3 -2
- data/ext/src/ichiring.h +2 -2
- data/ext/src/ichirvr1.c +4891 -0
- data/ext/src/ichirvr2.c +6344 -0
- data/ext/src/ichirvr3.c +5499 -0
- data/ext/src/ichirvr4.c +3177 -0
- data/ext/src/ichirvr5.c +1166 -0
- data/ext/src/ichirvr6.c +1287 -0
- data/ext/src/ichirvr7.c +2319 -0
- data/ext/src/ichirvrs.h +882 -0
- data/ext/src/ichisize.h +2 -2
- data/ext/src/ichisort.c +5 -5
- data/ext/src/ichister.c +281 -86
- data/ext/src/ichister.h +9 -3
- data/ext/src/ichitaut.c +208 -9
- data/ext/src/ichitaut.h +13 -11
- data/ext/src/ichitime.h +16 -2
- data/ext/src/inchicmp.h +107 -0
- data/ext/src/inpdef.h +6 -3
- data/ext/src/libinchi_wrap.c +912 -0
- data/ext/src/lreadmol.h +34 -31
- data/ext/src/mode.h +244 -7
- data/ext/src/mol2atom.c +1060 -0
- data/ext/src/mol2atom.h +31 -0
- data/ext/src/readinch.c +239 -0
- data/ext/src/readmol.c +28 -0
- data/ext/src/{e_readmol.h → readmol.h} +7 -9
- data/ext/src/runichi.c +251 -177
- data/ext/src/strutil.c +444 -238
- data/ext/src/strutil.h +150 -11
- data/ext/src/util.c +176 -118
- data/ext/src/util.h +15 -3
- data/lib/rino.rb +71 -3
- data/test/test.rb +33 -4
- metadata +22 -34
- data/ext/ruby_inchi_main.so +0 -0
- data/ext/src/e_0dstereo.c +0 -3014
- data/ext/src/e_0dstereo.h +0 -31
- data/ext/src/e_comdef.h +0 -57
- data/ext/src/e_ctl_data.h +0 -147
- data/ext/src/e_ichi_io.c +0 -498
- data/ext/src/e_ichi_io.h +0 -40
- data/ext/src/e_ichi_parms.c +0 -37
- data/ext/src/e_ichi_parms.h +0 -41
- data/ext/src/e_ichicomp.h +0 -50
- data/ext/src/e_ichierr.h +0 -40
- data/ext/src/e_ichimain.c +0 -593
- data/ext/src/e_ichisize.h +0 -43
- data/ext/src/e_inchi_atom.c +0 -75
- data/ext/src/e_inchi_atom.h +0 -33
- data/ext/src/e_inpdef.h +0 -41
- data/ext/src/e_mode.h +0 -706
- data/ext/src/e_mol2atom.c +0 -649
- data/ext/src/e_readinch.c +0 -58
- data/ext/src/e_readmol.c +0 -54
- data/ext/src/e_readstru.c +0 -251
- data/ext/src/e_readstru.h +0 -33
- data/ext/src/e_util.c +0 -284
- data/ext/src/e_util.h +0 -61
- data/ext/src/ichilnct.c +0 -286
- data/ext/src/inchi_api.h +0 -670
- data/ext/src/inchi_dll.c +0 -1480
- data/ext/src/inchi_dll.h +0 -34
- data/ext/src/inchi_dll_main.c +0 -23
- data/ext/src/inchi_dll_main.h +0 -31
- data/ext/src/ruby_inchi_main.c +0 -558
data/ext/src/ichimain.h
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
* International Union of Pure and Applied Chemistry (IUPAC)
|
3
3
|
* International Chemical Identifier (InChI)
|
4
4
|
* Version 1
|
5
|
-
* Software version 1.
|
6
|
-
*
|
5
|
+
* Software version 1.01
|
6
|
+
* July 21, 2006
|
7
7
|
* Developed at NIST
|
8
8
|
*/
|
9
9
|
|
@@ -11,6 +11,7 @@
|
|
11
11
|
#define __INCHIMAIN_H__
|
12
12
|
|
13
13
|
#define ESC_KEY 27
|
14
|
+
#define INCHI_SEGM_BUFLEN 64000
|
14
15
|
|
15
16
|
/********************************************************************/
|
16
17
|
typedef struct tagStructData {
|
@@ -19,8 +20,8 @@ typedef struct tagStructData {
|
|
19
20
|
int nErrorType;
|
20
21
|
int nStructReadError;
|
21
22
|
char pStrErrStruct[STR_ERR_LEN];
|
22
|
-
long fPtrStart;
|
23
|
-
long fPtrEnd;
|
23
|
+
long fPtrStart; /* or number of processed structures */
|
24
|
+
long fPtrEnd; /* or number of errors */
|
24
25
|
int bXmlStructStarted;
|
25
26
|
int bUserQuit;
|
26
27
|
int bUserQuitComponent;
|
@@ -50,7 +51,7 @@ int ReadCommandLineParms( int argc, const char *argv[], INPUT_PARMS *ip, char *s
|
|
50
51
|
void HelpCommandLineParms( INCHI_FILE *f );
|
51
52
|
int OpenFiles( FILE **inp_file, FILE **output_file, FILE **log_file, FILE **prb_file, INPUT_PARMS *ip );
|
52
53
|
#ifndef INCHI_ANSI_ONLY
|
53
|
-
int DisplayStructure( inp_ATOM *at, int num_at, int num_removed_H, int nNumRemovedProtons, NUM_H nNumRemovedProtonsIsotopic[],
|
54
|
+
int DisplayStructure( inp_ATOM *at, int num_at, int num_removed_H, int bAdd_DT_to_num_H, int nNumRemovedProtons, NUM_H nNumRemovedProtonsIsotopic[],
|
54
55
|
int bIsotopic, int j /*bTautomeric*/, INChI **cur_INChI, INChI_Aux **cur_INChI_Aux,
|
55
56
|
int bAbcNumbers, DRAW_PARMS *dp, INCHI_MODE nMode, char *szTitle );
|
56
57
|
void FillTableParms( SET_DRAW_PARMS *sdp, INChI **cur_INChI, INChI_Aux **cur_INChI_Aux, INCHI_MODE nMode, int bShowIsotopic, int bShowTaut );
|
@@ -65,7 +66,7 @@ int SortAndPrintINChI( INCHI_FILE *output_file, char *pStr, int nStrLen, INCHI_F
|
|
65
66
|
ORIG_STRUCT *pOrigStruct, int num_components[INCHI_NUM],
|
66
67
|
int num_non_taut[INCHI_NUM], int num_taut[INCHI_NUM],
|
67
68
|
INCHI_MODE bTautFlags[INCHI_NUM], INCHI_MODE bTautFlagsDone[INCHI_NUM],
|
68
|
-
NORM_CANON_FLAGS *pncFlags,
|
69
|
+
NORM_CANON_FLAGS *pncFlags, long num_inp,
|
69
70
|
PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM], int *bSortPrintINChIFlags );
|
70
71
|
void FreeAllINChIArrays( PINChI2 *pINChI[INCHI_NUM], PINChI_Aux2 *pINChI_Aux[INCHI_NUM], int num_components[2] );
|
71
72
|
void FreeINChIArrays( PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int num_components );
|
@@ -75,24 +76,24 @@ int ReadTheStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, FILE *inp_file, ORIG_ATO
|
|
75
76
|
int inp_index, int *out_index );
|
76
77
|
int TreatReadTheStructureErrors( STRUCT_DATA *sd, INPUT_PARMS *ip, int nLogMask,
|
77
78
|
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
78
|
-
ORIG_ATOM_DATA *orig_inp_data,
|
79
|
+
ORIG_ATOM_DATA *orig_inp_data, long *num_inp, char *pStr, int nStrLen );
|
79
80
|
|
80
81
|
int GetOneComponent( STRUCT_DATA *sd, INPUT_PARMS *ip, INCHI_FILE *log_file, INCHI_FILE *output_file,
|
81
82
|
INP_ATOM_DATA *inp_cur_data,
|
82
|
-
ORIG_ATOM_DATA *orig_inp_data, int i,
|
83
|
+
ORIG_ATOM_DATA *orig_inp_data, int i, long num_inp, char *pStr, int nStrLen );
|
83
84
|
int CreateOneComponentINChI( STRUCT_DATA *sd, INPUT_PARMS *ip, INP_ATOM_DATA *inp_cur_data, ORIG_ATOM_DATA *orig_inp_data,
|
84
85
|
PINChI2 *pINChI, PINChI_Aux2 *pINChI_Aux, int iINChI,
|
85
|
-
int i,
|
86
|
+
int i, long num_inp, INP_ATOM_DATA **inp_norm_data,
|
86
87
|
NORM_CANON_FLAGS *pncFlags, INCHI_FILE *log_file );
|
87
88
|
int TreatCreateOneComponentINChIError(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data,
|
88
|
-
int i,
|
89
|
+
int i, long num_inp,
|
89
90
|
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
90
91
|
char *pStr, int nStrLen );
|
91
|
-
int TreatCreateINChIWarning(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data,
|
92
|
+
int TreatCreateINChIWarning(STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *orig_inp_data, long num_inp,
|
92
93
|
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
93
94
|
char *pStr, int nStrLen );
|
94
95
|
|
95
|
-
#if( TEST_RENUMB_ATOMS == 1 ) /* { */
|
96
|
+
#if( TEST_RENUMB_ATOMS == 1 || READ_INCHI_STRING == 1 ) /* { */
|
96
97
|
int CompareINChI( INChI *i1, INChI *i2, INChI_Aux *a1, INChI_Aux *a2 );
|
97
98
|
#endif
|
98
99
|
|
@@ -101,19 +102,19 @@ int user_quit( const char *msg, unsigned long ulMaxTime );
|
|
101
102
|
|
102
103
|
int GetOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
|
103
104
|
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
104
|
-
ORIG_ATOM_DATA *orig_inp_data,
|
105
|
+
ORIG_ATOM_DATA *orig_inp_data, long *num_inp, char *pStr, int nStrLen, STRUCT_FPTRS *struct_fptrs );
|
105
106
|
int ProcessOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
|
106
107
|
PINChI2 *pINChI2[INCHI_NUM], PINChI_Aux2 *pINChI_Aux2[INCHI_NUM],
|
107
108
|
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
108
109
|
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
|
109
|
-
|
110
|
+
long num_inp, char *pStr, int nStrLen );
|
110
111
|
|
111
112
|
int CreateOneStructureINChI( STRUCT_DATA *sd, INPUT_PARMS *ip, char *szTitle,
|
112
113
|
PINChI2 *pINChI2[INCHI_NUM], PINChI_Aux2 *pINChI_Aux2[INCHI_NUM], int iINChI,
|
113
114
|
FILE *inp_file, INCHI_FILE *log_file, INCHI_FILE *output_file, INCHI_FILE *prb_file,
|
114
115
|
ORIG_ATOM_DATA *orig_inp_data, ORIG_ATOM_DATA *prep_inp_data,
|
115
116
|
COMP_ATOM_DATA composite_norm_data2[][TAUT_NUM+1],
|
116
|
-
|
117
|
+
long num_inp, char *pStr, int nStrLen, NORM_CANON_FLAGS *pncFlags );
|
117
118
|
|
118
119
|
int bIsStructChiral( PINChI2 *pINChI2[INCHI_NUM], int num_components[] );
|
119
120
|
|
@@ -122,6 +123,13 @@ int PreprocessOneStructure( STRUCT_DATA *sd, INPUT_PARMS *ip, ORIG_ATOM_DATA *or
|
|
122
123
|
int FillOutOrigStruct( ORIG_ATOM_DATA *orig_inp_data, ORIG_STRUCT *pOrigStruct, STRUCT_DATA *sd );
|
123
124
|
void FreeOrigStruct( ORIG_STRUCT *pOrigStruct);
|
124
125
|
|
126
|
+
int ReadWriteInChI( INCHI_FILE *pInp, INCHI_FILE *pOut, INCHI_FILE *pLog,
|
127
|
+
INPUT_PARMS *ip, STRUCT_DATA *sd, inp_ATOM **at, int *num_at,
|
128
|
+
char *szMsg, int nMsgLen, unsigned long WarningFlags[2][2] );
|
129
|
+
|
130
|
+
int CompareHillFormulasNoH( const char *f1, const char *f2, int *num_H1, int *num_H2 );
|
131
|
+
|
132
|
+
|
125
133
|
#ifndef INCHI_ALL_CPP
|
126
134
|
#ifdef __cplusplus
|
127
135
|
}
|
data/ext/src/ichimak2.c
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
* International Union of Pure and Applied Chemistry (IUPAC)
|
3
3
|
* International Chemical Identifier (InChI)
|
4
4
|
* Version 1
|
5
|
-
* Software version 1.
|
6
|
-
*
|
5
|
+
* Software version 1.01
|
6
|
+
* July 21, 2006
|
7
7
|
* Developed at NIST
|
8
8
|
*/
|
9
9
|
|
@@ -94,7 +94,7 @@ int GetHillFormulaCounts( U_CHAR *nAtom, S_CHAR *nNum_H, int num_atoms,
|
|
94
94
|
int *pnum_C, int *pnum_H, int *pnLen, int *pnNumNonHAtoms )
|
95
95
|
{
|
96
96
|
char szElement[4];
|
97
|
-
U_CHAR nPrevAtom = (U_CHAR)-
|
97
|
+
U_CHAR nPrevAtom = (U_CHAR)-2;
|
98
98
|
int bCarbon, bHydrogen, nElemLen, nFormLen, nNumNonHAtoms;
|
99
99
|
int mult, i, num_H, num_C;
|
100
100
|
|
@@ -210,7 +210,7 @@ int MakeHillFormula( U_CHAR *nAtom, int num_atoms,
|
|
210
210
|
nLen = 0;
|
211
211
|
mult = 0;
|
212
212
|
bOvfl = 0;
|
213
|
-
nPrevAtom = (U_CHAR)-
|
213
|
+
nPrevAtom = (U_CHAR)-2; /* non-existent number */
|
214
214
|
|
215
215
|
|
216
216
|
if ( num_C ) {
|
@@ -958,8 +958,8 @@ int FillOutINChI( INChI *pINChI, INChI_Aux *pINChI_Aux,
|
|
958
958
|
/* Allocate and fill Hill formula */
|
959
959
|
if ( !(pINChI->szHillFormula = AllocateAndFillHillFormula( pINChI ) ) ) {
|
960
960
|
nErrorCode = 0;
|
961
|
-
ret = CT_OUT_OF_RAM
|
962
|
-
pINChI->nErrorCode = pINChI_Aux->nErrorCode =
|
961
|
+
ret = CT_WRONG_FORMULA; /* CT_OUT_OF_RAM;*/ /* <BRKPT> */
|
962
|
+
pINChI->nErrorCode = pINChI_Aux->nErrorCode = ret;
|
963
963
|
goto exit_function;
|
964
964
|
}
|
965
965
|
|
data/ext/src/ichimake.c
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
* International Union of Pure and Applied Chemistry (IUPAC)
|
3
3
|
* International Chemical Identifier (InChI)
|
4
4
|
* Version 1
|
5
|
-
* Software version 1.
|
6
|
-
*
|
5
|
+
* Software version 1.01
|
6
|
+
* July 21, 2006
|
7
7
|
* Developed at NIST
|
8
8
|
*/
|
9
9
|
|
@@ -36,8 +36,8 @@
|
|
36
36
|
int inp2spATOM( inp_ATOM *inp_at, int num_inp_at, sp_ATOM *at );
|
37
37
|
int GetElementAndCount( const char **f, char *szEl, int *count );
|
38
38
|
int CompareHillFormulas( const char *f1, const char *f2 );
|
39
|
-
int CompareHillFormulasNoH( const char *f1, const char *f2, int *num_H1, int *num_H2 );
|
40
39
|
int CompareInchiStereo( INChI_Stereo *Stereo1, INCHI_MODE nFlags1, INChI_Stereo *Stereo2, INCHI_MODE nFlags2 );
|
40
|
+
int CompareReversedStereoINChI( INChI_Stereo *s1/* InChI from reversed struct */, INChI_Stereo *s2 /* input InChI */);
|
41
41
|
int GetAtomOrdNbrInCanonOrd( inp_ATOM *norm_at, AT_NUMB *nAtomOrdNbr,
|
42
42
|
AT_NUMB *nOrigAtNosInCanonOrd, int num_at );
|
43
43
|
int FillOutCanonInfAtom(inp_ATOM *norm_at, INF_ATOM_DATA *inf_norm_at_data, int init_num_at, int bIsotopic,
|
@@ -46,7 +46,7 @@ int FillOutOneCanonInfAtom(inp_ATOM *inp_norm_at, INF_ATOM_DATA *inf_norm_at_dat
|
|
46
46
|
AT_NUMB *pStereoFlags, int init_num_at, int offset, int offset_H, int bIsotopic,
|
47
47
|
INChI *pINChI, INChI_Aux *pINChI_Aux, int bAbcNumbers, INCHI_MODE nMode);
|
48
48
|
int FillOutInputInfAtom(inp_ATOM *inp_at, INF_ATOM_DATA *inf_at_data, int init_num_at, int num_removed_H,
|
49
|
-
int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic, int bIsotopic, int bAbcNumbers);
|
49
|
+
int bAdd_DT_to_num_H, int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic, int bIsotopic, int bAbcNumbers);
|
50
50
|
|
51
51
|
int CheckCanonNumberingCorrectness(
|
52
52
|
int num_atoms, int num_at_tg,
|
@@ -57,10 +57,16 @@ static int CompareDfsDescendants4CT( const void *a1, const void *a2 );
|
|
57
57
|
int GetSp3RelRacAbs( const INChI *pINChI, INChI_Stereo *Stereo );
|
58
58
|
|
59
59
|
|
60
|
-
#if( TEST_RENUMB_ATOMS == 1 ) /* { */
|
60
|
+
#if( TEST_RENUMB_ATOMS == 1 || READ_INCHI_STRING == 1 ) /* { */
|
61
61
|
int CompareStereoINChI( INChI_Stereo *s1, INChI_Stereo *s2 );
|
62
62
|
#endif
|
63
63
|
|
64
|
+
#if( READ_INCHI_STRING == 1 ) /* { */
|
65
|
+
/*************************************************************************************/
|
66
|
+
|
67
|
+
int CompareReversedStereoINChI2( INChI_Stereo *s1, INChI_Stereo *s2, ICR *picr);
|
68
|
+
|
69
|
+
#endif
|
64
70
|
/**********************************************************************************************/
|
65
71
|
int inp2spATOM( inp_ATOM *inp_at, int num_inp_at, sp_ATOM *at )
|
66
72
|
{
|
@@ -742,9 +748,9 @@ int CompINChILayers(const INCHI_SORT *p1, const INCHI_SORT *p2, char sDifSegs[][
|
|
742
748
|
/*==== /t, /m, /s for M ======*/
|
743
749
|
/*==================================*/
|
744
750
|
/* M sp3 stereo */
|
745
|
-
bRelRac[DIFL_M ] = GetSp3RelRacAbs( i1, Stereo1 );
|
751
|
+
bRelRac[DIFL_M ] = GetSp3RelRacAbs( i1, Stereo1 ); /* Mobile-H */
|
746
752
|
bRelRac[DIFL_MI] = GetSp3RelRacAbs( i1, IsoStereo1 );
|
747
|
-
bRelRac[DIFL_F ] = GetSp3RelRacAbs( i2, Stereo2 );
|
753
|
+
bRelRac[DIFL_F ] = GetSp3RelRacAbs( i2, Stereo2 ); /* Fixed-H */
|
748
754
|
bRelRac[DIFL_FI] = GetSp3RelRacAbs( i2, IsoStereo2 );
|
749
755
|
if ( SP3_NONE != bRelRac[DIFL_M] ) {
|
750
756
|
sDifSegs[DIFL_M][DIFS_t_SATOMS] |= (bRelRac[DIFL_M] & SP3_ANY)? DIFV_NEQ2PRECED : DIFV_BOTH_EMPTY;
|
@@ -1567,7 +1573,10 @@ AT_NUMB *GetDfsOrder4CT( AT_NUMB *LinearCT, int nLenCT, S_CHAR *nNum_H, int num_
|
|
1567
1573
|
|
1568
1574
|
do {
|
1569
1575
|
/* advance */
|
1570
|
-
while ( (int)
|
1576
|
+
while ( i=(int)nStackAtom[nTopStackAtom], j = (int)cNeighNumb[i]+1, (int)nl[i][0] >= j )
|
1577
|
+
/*while ( (int)nl[i=nStackAtom[nTopStackAtom]][0] >= (j = (int)cNeighNumb[i]+1) )*/
|
1578
|
+
/* replaced due to missing sequence point; undefined behavior, pointed by Geoffrey Hutchison */
|
1579
|
+
{
|
1571
1580
|
cNeighNumb[i] ++;
|
1572
1581
|
u = (int)nl[i][j]; /* jth neighbor of the vertex i */
|
1573
1582
|
if ( !nDfsNumber[u] ) {
|
@@ -1679,7 +1688,10 @@ AT_NUMB *GetDfsOrder4CT( AT_NUMB *LinearCT, int nLenCT, S_CHAR *nNum_H, int num_
|
|
1679
1688
|
|
1680
1689
|
do {
|
1681
1690
|
/* advance */
|
1682
|
-
while ( (int)
|
1691
|
+
while ( i=(int)nStackAtom[nTopStackAtom], j = (int)cNeighNumb[i]+1, (int)nl[i][0] >= j )
|
1692
|
+
/*while ( (int)nl[i=nStackAtom[nTopStackAtom]][0] >= (j = (int)cNeighNumb[i]+1) )*/
|
1693
|
+
/* replaced due to missing sequence point; undefined behavior, reported by Geoffrey Hutchison */
|
1694
|
+
{
|
1683
1695
|
k += 3;
|
1684
1696
|
if ( k+6 > nTotOutputStringLen ) {
|
1685
1697
|
goto exit_error; /* program error */
|
@@ -1760,7 +1772,7 @@ int GetInpStructErrorType( INPUT_PARMS *ip, int err, char *pStrErrStruct, int nu
|
|
1760
1772
|
}
|
1761
1773
|
/**********************************************************************************************/
|
1762
1774
|
int ProcessStructError( INCHI_FILE *output_file, INCHI_FILE *log_file, /*int err,*/ char *pStrErrStruct, int nErrorType,
|
1763
|
-
int *bXmlStructStarted,
|
1775
|
+
int *bXmlStructStarted, long num_inp, INPUT_PARMS *ip, char *pStr, int nStrLen )
|
1764
1776
|
{
|
1765
1777
|
int b_ok;
|
1766
1778
|
#ifdef INCHI_LIB
|
@@ -1777,20 +1789,20 @@ int ProcessStructError( INCHI_FILE *output_file, INCHI_FILE *log_file, /*int err
|
|
1777
1789
|
if ( nErrorType ) {
|
1778
1790
|
if ( bPlainText ) {
|
1779
1791
|
if ( !(b_ok=OutputINChIPlainError( output_file, pStr, nStrLen, pStrErrStruct, nErrorType ) ) ) {
|
1780
|
-
my_fprintf( log_file, "Cannot create message for error (structure #%
|
1792
|
+
my_fprintf( log_file, "Cannot create message for error (structure #%ld.%s%s%s%s) Terminating.\n",
|
1781
1793
|
num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1782
1794
|
} else {
|
1783
1795
|
inchi_print( output_file, "\n" ); /* add a blank line after the WINCHI Window message */
|
1784
1796
|
}
|
1785
1797
|
} else {
|
1786
1798
|
if ( !(b_ok=OutputINChIXmlError( output_file, pStr, nStrLen, 2, /*err,*/ pStrErrStruct, nErrorType ) ) ) {
|
1787
|
-
my_fprintf( log_file, "Cannot create xml tag for error (structure #%
|
1799
|
+
my_fprintf( log_file, "Cannot create xml tag for error (structure #%ld.%s%s%s%s) Terminating.\n",
|
1788
1800
|
num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1789
1801
|
}
|
1790
1802
|
if ( !b_ok || nErrorType == _IS_FATAL || nErrorType == _IS_ERROR ) {
|
1791
1803
|
/* close current structure output */
|
1792
1804
|
if ( !OutputINChIXmlStructEndTag( output_file, pStr, nStrLen, 1 ) ) {
|
1793
|
-
my_fprintf( log_file, "Cannot create end xml tag for structure #%
|
1805
|
+
my_fprintf( log_file, "Cannot create end xml tag for structure #%ld.%s%s%s%s Terminating.\n", num_inp, SDF_LBL_VAL(ip->pSdfLabel,ip->pSdfValue) );
|
1794
1806
|
*bXmlStructStarted = -1;
|
1795
1807
|
b_ok = 0;
|
1796
1808
|
} else {
|
@@ -1919,12 +1931,787 @@ int CompareINChI( INChI *i1, INChI *i2, INChI_Aux *a1, INChI_Aux *a2 )
|
|
1919
1931
|
return 0;
|
1920
1932
|
}
|
1921
1933
|
#endif /* } TEST_RENUMB_ATOMS == 1 */
|
1934
|
+
#if( READ_INCHI_STRING == 1 ) /* { */
|
1935
|
+
/*************************************************************************************/
|
1936
|
+
int CompareReversedStereoINChI( INChI_Stereo *s1/* InChI from reversed struct */, INChI_Stereo *s2 /* input InChI */)
|
1937
|
+
{
|
1938
|
+
if ( s1 == NULL && s2 == NULL )
|
1939
|
+
return 0;
|
1940
|
+
if ( (s1 == NULL) ^ (s2 == NULL) ) {
|
1941
|
+
INChI_Stereo *s = s1? s1 : s2;
|
1942
|
+
if ( s->nNumberOfStereoCenters || s->nNumberOfStereoBonds ) {
|
1943
|
+
return 20; /* Diff: Missing Stereo */
|
1944
|
+
} else {
|
1945
|
+
return 0;
|
1946
|
+
}
|
1947
|
+
}
|
1948
|
+
|
1949
|
+
if ( s1->nNumberOfStereoCenters != s2->nNumberOfStereoCenters )
|
1950
|
+
return 21; /* Diff: Number of sp3 stereocenters */
|
1951
|
+
if ( s1->nNumberOfStereoCenters > 0 ) {
|
1952
|
+
if ( memcmp( s1->nNumber, s2->nNumber, s1->nNumberOfStereoCenters*sizeof(s1->nNumber[0]) ) )
|
1953
|
+
return 22; /* Diff: sp3 stereocenter locations */
|
1954
|
+
if ( memcmp( s1->t_parity, s2->t_parity, s1->nNumberOfStereoCenters*sizeof(s1->t_parity[0]) ) )
|
1955
|
+
return 23; /* Diff: sp3 stereocenter parities */
|
1956
|
+
if ( s1->nCompInv2Abs != s2->nCompInv2Abs && s1->nCompInv2Abs && s2->nCompInv2Abs )
|
1957
|
+
return 24; /* Diff: sp3 inversion */
|
1958
|
+
/*
|
1959
|
+
if ( s1->nNumberInv && s2->nNumberInv ) {
|
1960
|
+
if ( memcmp( s1->nNumberInv, s2->nNumberInv, s1->nNumberOfStereoCenters*sizeof(s1->nNumber[0]) ) )
|
1961
|
+
return 25;
|
1962
|
+
if ( memcmp( s1->t_parityInv, s2->t_parityInv, s1->nNumberOfStereoCenters*sizeof(s1->t_parity[0]) ) )
|
1963
|
+
return 26;
|
1964
|
+
if ( s1->nCompInv2Abs != s2->nCompInv2Abs ||
|
1965
|
+
s1->bTrivialInv != s2->bTrivialInv ) {
|
1966
|
+
return 27;
|
1967
|
+
}
|
1968
|
+
} else
|
1969
|
+
if ( s1->nNumberInv || s2->nNumberInv ) {
|
1970
|
+
return 28;
|
1971
|
+
}
|
1972
|
+
*/
|
1973
|
+
}
|
1974
|
+
if ( s1->nNumberOfStereoBonds != s2->nNumberOfStereoBonds )
|
1975
|
+
return 25; /* Diff: Number of stereobonds */
|
1976
|
+
if ( s1->nNumberOfStereoBonds > 0 ) {
|
1977
|
+
if ( memcmp( s1->nBondAtom1, s2->nBondAtom1, s1->nNumberOfStereoBonds*sizeof(s1->nBondAtom1[0]) ) )
|
1978
|
+
return 26; /* Diff: Stereobond 1st atom locations */
|
1979
|
+
if ( memcmp( s1->nBondAtom2, s2->nBondAtom2, s1->nNumberOfStereoBonds*sizeof(s1->nBondAtom2[0]) ) )
|
1980
|
+
return 27; /* Diff: Stereobond 2nd atom locations */
|
1981
|
+
if ( memcmp( s1->b_parity, s2->b_parity, s1->nNumberOfStereoBonds*sizeof(s1->b_parity[0]) ) )
|
1982
|
+
return 28; /* Diff: Stereobond parities */
|
1983
|
+
}
|
1984
|
+
return 0;
|
1985
|
+
}
|
1986
|
+
/*************************************************************************************/
|
1987
|
+
int CompareReversedStereoINChI2( INChI_Stereo *s1/* InChI from reversed struct */, INChI_Stereo *s2 /* input InChI */, ICR *picr)
|
1988
|
+
{
|
1989
|
+
int ret = 0;
|
1990
|
+
int j1, j2, num_eq, num_dif, num_extra_undf, num_miss_undf, num_in1_only, num_in2_only;
|
1991
|
+
int bAddSb = !(picr->num_sb_undef_in1_only + picr->num_sb_in1_only + picr->num_sb_in2_only);
|
1992
|
+
int bAddSc = !(picr->num_sc_undef_in1_only + picr->num_sc_in1_only + picr->num_sc_in2_only);
|
1993
|
+
|
1994
|
+
int nNumSc1 = s1? s1->nNumberOfStereoCenters : 0;
|
1995
|
+
int nNumSc2 = s2? s2->nNumberOfStereoCenters : 0;
|
1996
|
+
int nNumSb1 = s1? s1->nNumberOfStereoBonds : 0;
|
1997
|
+
int nNumSb2 = s2? s2->nNumberOfStereoBonds : 0;
|
1998
|
+
|
1999
|
+
if ( (nNumSc1 || nNumSc1) &&
|
2000
|
+
( nNumSc1 != nNumSc2 ||
|
2001
|
+
memcmp( s1->nNumber, s2->nNumber, nNumSc1*sizeof(s1->nNumber[0] ) ) ||
|
2002
|
+
memcmp( s1->t_parity, s2->t_parity, nNumSc1*sizeof(s1->t_parity[0]) ) ) ) {
|
2003
|
+
|
2004
|
+
num_eq = num_dif = num_extra_undf = num_miss_undf = num_in1_only = num_in2_only = 0;
|
2005
|
+
for ( j1 = j2 = 0; j1 < nNumSc1 && j2 < nNumSc2; ) {
|
2006
|
+
if ( s1->nNumber[j1] == s2->nNumber[j2] ) {
|
2007
|
+
if ( s1->t_parity[j1] == s2->t_parity[j2] ) {
|
2008
|
+
num_eq ++;
|
2009
|
+
} else {
|
2010
|
+
num_dif ++;
|
2011
|
+
}
|
2012
|
+
j1 ++;
|
2013
|
+
j2 ++;
|
2014
|
+
} else
|
2015
|
+
if ( s1->nNumber[j1] < s2->nNumber[j2] ) {
|
2016
|
+
num_in1_only ++;
|
2017
|
+
if ( s1->t_parity[j1] == AB_PARITY_UNDF ) {
|
2018
|
+
num_extra_undf ++;
|
2019
|
+
}
|
2020
|
+
if ( bAddSc ) {
|
2021
|
+
if ( picr->num_sc_in1_only < ICR_MAX_SC_IN1_ONLY )
|
2022
|
+
picr->sc_in1_only[picr->num_sc_in1_only ++] = j1;
|
2023
|
+
if ( s1->t_parity[j1] == AB_PARITY_UNDF ) {
|
2024
|
+
if ( picr->num_sc_undef_in1_only < ICR_MAX_SC_UNDF )
|
2025
|
+
picr->sc_undef_in1_only[picr->num_sc_undef_in1_only ++] = j1;
|
2026
|
+
}
|
2027
|
+
}
|
2028
|
+
j1 ++;
|
2029
|
+
} else {
|
2030
|
+
num_in2_only ++;
|
2031
|
+
if ( s2->t_parity[j2] == AB_PARITY_UNDF ) {
|
2032
|
+
num_miss_undf ++;
|
2033
|
+
}
|
2034
|
+
if ( bAddSc ) {
|
2035
|
+
if ( picr->num_sc_in2_only < ICR_MAX_SC_IN2_ONLY )
|
2036
|
+
picr->sc_in2_only[picr->num_sc_in2_only ++] = j2;
|
2037
|
+
if ( s2->t_parity[j2] == AB_PARITY_UNDF ) {
|
2038
|
+
if ( picr->num_sc_undef_in2_only < ICR_MAX_SC_UNDF )
|
2039
|
+
picr->sc_undef_in2_only[picr->num_sc_undef_in2_only ++] = j1;
|
2040
|
+
}
|
2041
|
+
}
|
2042
|
+
j2 ++;
|
2043
|
+
}
|
2044
|
+
}
|
2045
|
+
while ( j1 < nNumSc1 ) {
|
2046
|
+
if ( s1->t_parity[j1] == AB_PARITY_UNDF ) {
|
2047
|
+
num_extra_undf ++;
|
2048
|
+
}
|
2049
|
+
num_in1_only ++;
|
2050
|
+
if ( bAddSc ) {
|
2051
|
+
if ( picr->num_sc_in1_only < ICR_MAX_SC_IN1_ONLY )
|
2052
|
+
picr->sc_in1_only[picr->num_sc_in1_only ++] = j1;
|
2053
|
+
if ( s1->t_parity[j1] == AB_PARITY_UNDF ) {
|
2054
|
+
if ( picr->num_sc_undef_in1_only < ICR_MAX_SC_UNDF )
|
2055
|
+
picr->sc_undef_in1_only[picr->num_sc_undef_in1_only ++] = j1;
|
2056
|
+
}
|
2057
|
+
}
|
2058
|
+
j1 ++;
|
2059
|
+
}
|
2060
|
+
while ( j2 < nNumSc2 ) {
|
2061
|
+
if ( s2->t_parity[j2] == AB_PARITY_UNDF ) {
|
2062
|
+
num_miss_undf ++;
|
2063
|
+
}
|
2064
|
+
num_in2_only ++;
|
2065
|
+
if ( bAddSc ) {
|
2066
|
+
if ( picr->num_sc_in2_only < ICR_MAX_SC_IN2_ONLY )
|
2067
|
+
picr->sc_in2_only[picr->num_sc_in2_only ++] = j2;
|
2068
|
+
}
|
2069
|
+
j2 ++;
|
2070
|
+
}
|
2071
|
+
if ( num_dif ) {
|
2072
|
+
ret |= IDIF_SC_PARITY;
|
2073
|
+
}
|
2074
|
+
if ( num_in1_only ) {
|
2075
|
+
if ( num_extra_undf ) {
|
2076
|
+
ret |= IDIF_SC_EXTRA_UNDF;
|
2077
|
+
}
|
2078
|
+
if ( num_in1_only != num_extra_undf ) {
|
2079
|
+
ret |= IDIF_SC_EXTRA;
|
2080
|
+
}
|
2081
|
+
}
|
2082
|
+
if ( num_in2_only ) {
|
2083
|
+
if ( num_miss_undf ) {
|
2084
|
+
ret |= IDIF_SC_MISS_UNDF;
|
2085
|
+
}
|
2086
|
+
if ( num_in2_only != num_miss_undf ) {
|
2087
|
+
ret |= IDIF_SC_MISS;
|
2088
|
+
}
|
2089
|
+
}
|
2090
|
+
}
|
2091
|
+
if ( s1 && s2 && s1->nCompInv2Abs != s2->nCompInv2Abs && s1->nCompInv2Abs && s2->nCompInv2Abs ) {
|
2092
|
+
ret |= IDIF_SC_INV;
|
2093
|
+
}
|
2094
|
+
|
2095
|
+
if ( (nNumSb1 || nNumSb2 ) &&
|
2096
|
+
(nNumSb1 != nNumSb2 ||
|
2097
|
+
memcmp( s1->nBondAtom1, s2->nBondAtom1, nNumSb1*sizeof(s1->nBondAtom1[0]) ) ||
|
2098
|
+
memcmp( s1->nBondAtom2, s2->nBondAtom2, nNumSb1*sizeof(s1->nBondAtom2[0]) ) ||
|
2099
|
+
memcmp( s1->b_parity, s2->b_parity, nNumSb1*sizeof(s1->b_parity[0]) ) ) ) {
|
2100
|
+
|
2101
|
+
num_eq = num_dif = num_extra_undf = num_miss_undf = num_in1_only = num_in2_only = 0;
|
2102
|
+
for ( j1 = j2 = 0; j1 < nNumSb1 && j2 < nNumSb2; ) {
|
2103
|
+
if ( s1->nBondAtom1[j1] == s2->nBondAtom1[j2] &&
|
2104
|
+
s1->nBondAtom2[j1] == s2->nBondAtom2[j2] ) {
|
2105
|
+
if ( s1->b_parity[j1] == s2->b_parity[j2] ) {
|
2106
|
+
num_eq ++;
|
2107
|
+
} else {
|
2108
|
+
num_dif ++;
|
2109
|
+
}
|
2110
|
+
j1 ++;
|
2111
|
+
j2 ++;
|
2112
|
+
} else
|
2113
|
+
if ( s1->nBondAtom1[j1] < s2->nBondAtom1[j2] ||
|
2114
|
+
s1->nBondAtom1[j1] == s2->nBondAtom1[j2] && s1->nBondAtom2[j1] < s2->nBondAtom2[j2]) {
|
2115
|
+
num_in1_only ++;
|
2116
|
+
if ( s1->b_parity[j1] == AB_PARITY_UNDF ) {
|
2117
|
+
num_extra_undf ++;
|
2118
|
+
}
|
2119
|
+
if ( bAddSb ) {
|
2120
|
+
if ( picr->num_sb_in1_only < ICR_MAX_SB_IN1_ONLY )
|
2121
|
+
picr->sb_in1_only[picr->num_sb_in1_only ++] = j1;
|
2122
|
+
if ( s1->b_parity[j1] == AB_PARITY_UNDF ) {
|
2123
|
+
if ( picr->num_sb_undef_in1_only < ICR_MAX_SB_UNDF )
|
2124
|
+
picr->sb_undef_in1_only[picr->num_sb_undef_in1_only ++] = j1;
|
2125
|
+
}
|
2126
|
+
}
|
2127
|
+
j1 ++;
|
2128
|
+
} else {
|
2129
|
+
num_in2_only ++;
|
2130
|
+
if ( s2->b_parity[j2] == AB_PARITY_UNDF ) {
|
2131
|
+
num_miss_undf ++;
|
2132
|
+
}
|
2133
|
+
if ( bAddSb ) {
|
2134
|
+
if ( picr->num_sb_in2_only < ICR_MAX_SB_IN2_ONLY )
|
2135
|
+
picr->sb_in2_only[picr->num_sb_in2_only ++] = j2;
|
2136
|
+
if ( s2->b_parity[j2] == AB_PARITY_UNDF ) {
|
2137
|
+
if ( picr->num_sb_undef_in2_only < ICR_MAX_SB_UNDF )
|
2138
|
+
picr->sb_undef_in2_only[picr->num_sb_undef_in2_only ++] = j1;
|
2139
|
+
}
|
2140
|
+
}
|
2141
|
+
j2 ++;
|
2142
|
+
}
|
2143
|
+
}
|
2144
|
+
while ( j1 < nNumSb1 ) {
|
2145
|
+
num_in1_only ++;
|
2146
|
+
if ( s1->b_parity[j1] == AB_PARITY_UNDF ) {
|
2147
|
+
num_extra_undf ++;
|
2148
|
+
}
|
2149
|
+
if ( bAddSb ) {
|
2150
|
+
if ( picr->num_sb_in1_only < ICR_MAX_SB_IN1_ONLY )
|
2151
|
+
picr->sb_in1_only[picr->num_sb_in1_only ++] = j1;
|
2152
|
+
if ( s1->b_parity[j1] == AB_PARITY_UNDF ) {
|
2153
|
+
if ( picr->num_sb_undef_in1_only < ICR_MAX_SB_UNDF )
|
2154
|
+
picr->sb_undef_in1_only[picr->num_sb_undef_in1_only ++] = j1;
|
2155
|
+
}
|
2156
|
+
}
|
2157
|
+
j1 ++;
|
2158
|
+
}
|
2159
|
+
while ( j2 < nNumSb2 ) {
|
2160
|
+
num_in2_only ++;
|
2161
|
+
if ( s2->b_parity[j2] == AB_PARITY_UNDF ) {
|
2162
|
+
num_miss_undf ++;
|
2163
|
+
}
|
2164
|
+
if ( bAddSb ) {
|
2165
|
+
if ( picr->num_sb_in2_only < ICR_MAX_SB_IN2_ONLY )
|
2166
|
+
picr->sb_in2_only[picr->num_sb_in2_only ++] = j2;
|
2167
|
+
if ( s2->b_parity[j2] == AB_PARITY_UNDF ) {
|
2168
|
+
if ( picr->num_sb_undef_in2_only < ICR_MAX_SB_UNDF )
|
2169
|
+
picr->sb_undef_in2_only[picr->num_sb_undef_in2_only ++] = j1;
|
2170
|
+
}
|
2171
|
+
}
|
2172
|
+
j2 ++;
|
2173
|
+
}
|
2174
|
+
if ( num_dif ) {
|
2175
|
+
ret |= IDIF_SB_PARITY;
|
2176
|
+
}
|
2177
|
+
if ( num_in1_only ) {
|
2178
|
+
if ( num_extra_undf ) {
|
2179
|
+
ret |= IDIF_SB_EXTRA_UNDF;
|
2180
|
+
}
|
2181
|
+
if ( num_in1_only != num_extra_undf ) {
|
2182
|
+
ret |= IDIF_SB_EXTRA;
|
2183
|
+
}
|
2184
|
+
}
|
2185
|
+
if ( num_in2_only ) {
|
2186
|
+
if ( num_miss_undf ) {
|
2187
|
+
ret |= IDIF_SB_MISS_UNDF;
|
2188
|
+
}
|
2189
|
+
if ( num_in2_only != num_miss_undf ) {
|
2190
|
+
ret |= IDIF_SB_MISS;
|
2191
|
+
}
|
2192
|
+
}
|
2193
|
+
}
|
2194
|
+
|
2195
|
+
return ret;
|
2196
|
+
}
|
2197
|
+
/*************************************************************************************/
|
2198
|
+
int CompareReversedINChI( INChI *i1 /* InChI from reversed struct */, INChI *i2 /* input InChI */, INChI_Aux *a1, INChI_Aux *a2 )
|
2199
|
+
{
|
2200
|
+
int ret;
|
2201
|
+
if ( i1 == NULL && i2 == NULL )
|
2202
|
+
return 0;
|
2203
|
+
if ( (i1 == NULL) ^ (i2 == NULL) )
|
2204
|
+
return 1; /* Diff: Missing InChI */
|
2205
|
+
|
2206
|
+
if ( i1->nErrorCode == i2->nErrorCode ) {
|
2207
|
+
if ( i1->nErrorCode )
|
2208
|
+
return 0;
|
2209
|
+
} else {
|
2210
|
+
return 2; /* Diff: Error codes */
|
2211
|
+
}
|
2212
|
+
if ( i1->bDeleted != i2->bDeleted ) {
|
2213
|
+
return 1; /* Diff: Missing InChI */
|
2214
|
+
}
|
2215
|
+
if ( i1->nNumberOfAtoms != i2->nNumberOfAtoms )
|
2216
|
+
return 3; /* Diff: Num. atoms */
|
2217
|
+
if ( i1->nNumberOfAtoms > 0 ) {
|
2218
|
+
if ( memcmp( i1->nAtom, i2->nAtom, i1->nNumberOfAtoms*sizeof(i1->nAtom[0]) ) )
|
2219
|
+
return 4; /* Diff: Elements */
|
2220
|
+
if ( strcmp( i1->szHillFormula, i2->szHillFormula ) )
|
2221
|
+
return 7; /* Diff: Hill Formulas */
|
2222
|
+
if ( memcmp( i1->nNum_H, i2->nNum_H, i1->nNumberOfAtoms*sizeof(i1->nNum_H[0]) ) ) {
|
2223
|
+
if ( i1->lenConnTable > 1 || i2->lenConnTable > 1 ) {
|
2224
|
+
return 5; /* Diff: H Locations (mobile H present) */
|
2225
|
+
} else {
|
2226
|
+
return 6; /* Diff: H Locations (no mobile H) */
|
2227
|
+
}
|
2228
|
+
}
|
2229
|
+
/* fixed H */
|
2230
|
+
if ( i1->nNum_H_fixed || i2->nNum_H_fixed ) {
|
2231
|
+
int bHasFixedH1 = 0, bHasFixedH2 = 0, i, j1, j2;
|
2232
|
+
if ( i1->nNum_H_fixed ) {
|
2233
|
+
for ( i = 0; i < i1->nNumberOfAtoms; i ++ ) {
|
2234
|
+
if ( i1->nNum_H_fixed[i] ) {
|
2235
|
+
bHasFixedH1 ++;
|
2236
|
+
}
|
2237
|
+
}
|
2238
|
+
}
|
2239
|
+
if ( i2->nNum_H_fixed ) {
|
2240
|
+
for ( i = 0; i < i2->nNumberOfAtoms; i ++ ) {
|
2241
|
+
if ( i2->nNum_H_fixed[i] ) {
|
2242
|
+
bHasFixedH2 ++;
|
2243
|
+
}
|
2244
|
+
}
|
2245
|
+
}
|
2246
|
+
/* count the differences */
|
2247
|
+
j1 = j2 = 0;
|
2248
|
+
if ( bHasFixedH1 && !bHasFixedH2 ) {
|
2249
|
+
for ( i = 0; i < i1->nNumberOfAtoms; i ++ ) {
|
2250
|
+
if ( i1->nNum_H_fixed[i] > 0 ) {
|
2251
|
+
j1 ++;
|
2252
|
+
} else
|
2253
|
+
if ( i1->nNum_H_fixed[i] < 0 ) {
|
2254
|
+
j2 ++;
|
2255
|
+
}
|
2256
|
+
}
|
2257
|
+
|
2258
|
+
return 18; /* Diff: Extra Fixed-H */
|
2259
|
+
} else
|
2260
|
+
if ( !bHasFixedH1 && bHasFixedH2 ) {
|
2261
|
+
for ( i = j1 = j2 = 0; i < i1->nNumberOfAtoms; i ++ ) {
|
2262
|
+
if ( 0 > i2->nNum_H_fixed[i] ) {
|
2263
|
+
j1 ++;
|
2264
|
+
} else
|
2265
|
+
if ( 0 < i2->nNum_H_fixed[i] ) {
|
2266
|
+
j2 ++;
|
2267
|
+
}
|
2268
|
+
}
|
2269
|
+
return 19; /* Diff: Missed Fixed-H */
|
2270
|
+
} else
|
2271
|
+
if ( bHasFixedH1 && bHasFixedH2 &&
|
2272
|
+
memcmp( i1->nNum_H_fixed, i2->nNum_H_fixed, i1->nNumberOfAtoms*sizeof(i1->nNum_H_fixed[0]) ) ) {
|
2273
|
+
for ( i = j1 = j2 = 0; i < i1->nNumberOfAtoms; i ++ ) {
|
2274
|
+
if ( i1->nNum_H_fixed[i] > i2->nNum_H_fixed[i] ) {
|
2275
|
+
j1 ++;
|
2276
|
+
} else
|
2277
|
+
if ( i1->nNum_H_fixed[i] < i2->nNum_H_fixed[i] ) {
|
2278
|
+
j2 ++;
|
2279
|
+
}
|
2280
|
+
}
|
2281
|
+
}
|
2282
|
+
ret = (j1 && j2)? 20 : j1? 18 : j2? 19 : 0;
|
2283
|
+
if ( ret ) {
|
2284
|
+
return ret; /* 20 => Diff: NotEql Fixed-H */
|
2285
|
+
/* 19 => Diff: Missed Fixed-H (i1 has less) */
|
2286
|
+
/* 18 => Diff: Extra Fixed-H (i1 has more) */
|
2287
|
+
}
|
2288
|
+
}
|
2289
|
+
}
|
2290
|
+
|
2291
|
+
if ( i1->lenConnTable != i2->lenConnTable )
|
2292
|
+
return 8; /* Diff: Connections length */
|
2293
|
+
if ( i1->lenConnTable > 0 && memcmp( i1->nConnTable, i2->nConnTable, i1->lenConnTable*sizeof(i1->nConnTable[0]) ) )
|
2294
|
+
return 9; /* Diff: Connections */
|
2295
|
+
/* output special cases: different number of t-groups, different sizes of t-groups, different endpoints */
|
2296
|
+
if ( i1->lenTautomer != i2->lenTautomer && (i1->lenTautomer > 1 || i2->lenTautomer > 1) )
|
2297
|
+
return 10; /* Diff: Mobile groups length */ /* in isotopic or deprotonated cases i1->lenTautomer == 1 && i1->nTautomer[0] = 0 */
|
2298
|
+
if ( (i1->lenTautomer > 1 && i2->lenTautomer > 1) &&
|
2299
|
+
memcmp( i1->nTautomer, i2->nTautomer, i1->lenTautomer*sizeof(i1->nTautomer[0]) ) )
|
2300
|
+
return 11; /* Diff: Mobile groups */
|
2301
|
+
|
2302
|
+
if ( i1->nNumberOfIsotopicAtoms != i2->nNumberOfIsotopicAtoms )
|
2303
|
+
return 12; /* Diff: Isotopic atoms number */
|
2304
|
+
if ( i1->nNumberOfIsotopicAtoms > 0 && memcmp( i1->IsotopicAtom, i2->IsotopicAtom, i1->nNumberOfIsotopicAtoms*sizeof(i1->IsotopicAtom[0]) ) )
|
2305
|
+
return 13; /* Diff: Isotopic atoms */
|
2306
|
+
if ( i1->nTotalCharge != i2->nTotalCharge )
|
2307
|
+
return 14; /* Diff: Charge */
|
2308
|
+
/*
|
2309
|
+
if ( i1->nNumberOfIsotopicTGroups != i2->nNumberOfIsotopicTGroups )
|
2310
|
+
return 14;
|
2311
|
+
if ( i1->nNumberOfIsotopicTGroups > 0 && memcmp( i1->IsotopicTGroup, i2->IsotopicTGroup, i1->nNumberOfIsotopicTGroups*sizeof(i1->IsotopicTGroup[0]) ) )
|
2312
|
+
return 15;
|
2313
|
+
*/
|
2314
|
+
if ( a1 && a2 ) {
|
2315
|
+
if ( a1->nNumRemovedProtons != a2->nNumRemovedProtons )
|
2316
|
+
return 16; /* Diff: Number of removed protons */
|
2317
|
+
if ( memcmp( a1->nNumRemovedIsotopicH, a2->nNumRemovedIsotopicH, sizeof(a1->nNumRemovedIsotopicH) ) )
|
2318
|
+
return 17; /* Diff: Removed isotopic H */
|
2319
|
+
}
|
2320
|
+
/*
|
2321
|
+
if ( i1->nPossibleLocationsOfIsotopicH && i2->nPossibleLocationsOfIsotopicH ) {
|
2322
|
+
if ( i1->nPossibleLocationsOfIsotopicH[0] != i2->nPossibleLocationsOfIsotopicH[0] ||
|
2323
|
+
memcmp(i1->nPossibleLocationsOfIsotopicH, i2->nPossibleLocationsOfIsotopicH,
|
2324
|
+
sizeof(i1->nPossibleLocationsOfIsotopicH[0])*i1->nPossibleLocationsOfIsotopicH[0]) )
|
2325
|
+
return 18;
|
2326
|
+
} else
|
2327
|
+
if ( !i1->nPossibleLocationsOfIsotopicH != !i2->nPossibleLocationsOfIsotopicH ) {
|
2328
|
+
return 19;
|
2329
|
+
}
|
2330
|
+
*/
|
2331
|
+
/* ret = 20..31 => 40..51 */
|
2332
|
+
if ( ret = CompareReversedStereoINChI( i1->Stereo, i2->Stereo ) )
|
2333
|
+
return ret+20;
|
2334
|
+
/* ret = 40..51 => 60..71 */
|
2335
|
+
|
2336
|
+
if ( !i2->StereoIsotopic && i2->Stereo && i1->StereoIsotopic &&
|
2337
|
+
0 < (i1->StereoIsotopic->nNumberOfStereoBonds + i1->StereoIsotopic->nNumberOfStereoCenters) &&
|
2338
|
+
0 == CompareReversedStereoINChI( i1->StereoIsotopic, i2->Stereo ) ) {
|
2339
|
+
/* InChI from reversed structure does not contain fully duplicated isotopic stereo */
|
2340
|
+
;
|
2341
|
+
} else
|
2342
|
+
|
2343
|
+
if ( ret = CompareReversedStereoINChI( i1->StereoIsotopic, i2->StereoIsotopic ) ) {
|
2344
|
+
return ret+40;
|
2345
|
+
}
|
2346
|
+
|
2347
|
+
return 0;
|
2348
|
+
}
|
2349
|
+
|
2350
|
+
/*******************************************************************************/
|
2351
|
+
int CompareIcr( ICR *picr1, ICR *picr2, INCHI_MODE *pin1, INCHI_MODE *pin2, INCHI_MODE mask )
|
2352
|
+
{
|
2353
|
+
int nNumExtraBits1 = 0, nNumExtraBits2 = 0, bit1, bit2;
|
2354
|
+
INCHI_MODE Flg1=picr1->flags, Flg2 = picr2->flags, cur_bit = 1, in1, in2;
|
2355
|
+
int i, ret;
|
2356
|
+
|
2357
|
+
/* compare flags */
|
2358
|
+
in1 = in2 = 0;
|
2359
|
+
for ( i = 0; Flg1 || Flg2; i ++, Flg1 >>= 1, Flg2 >>= 1, cur_bit <<= 1 ) {
|
2360
|
+
if ( !(mask & cur_bit) ) {
|
2361
|
+
continue;
|
2362
|
+
}
|
2363
|
+
bit1 = Flg1 & 1;
|
2364
|
+
bit2 = Flg2 & 1;
|
2365
|
+
if ( bit1 && !bit2 ) {
|
2366
|
+
in1 |= 1 << i;
|
2367
|
+
nNumExtraBits1 ++;
|
2368
|
+
} else
|
2369
|
+
if ( !bit1 && bit2 ) {
|
2370
|
+
in2 |= 1 << i;
|
2371
|
+
nNumExtraBits2 ++;
|
2372
|
+
}
|
2373
|
+
}
|
2374
|
+
if ( nNumExtraBits1 && !nNumExtraBits2 ) {
|
2375
|
+
ret = 1;
|
2376
|
+
} else
|
2377
|
+
if ( !nNumExtraBits1 && nNumExtraBits2 ) {
|
2378
|
+
ret = -1;
|
2379
|
+
} else
|
2380
|
+
if ( !in1 && !in2 ) {
|
2381
|
+
ret = 0;
|
2382
|
+
} else {
|
2383
|
+
ret = 2; /* compare produced undefined results */
|
2384
|
+
}
|
2385
|
+
if ( pin1 ) *pin1 = in1;
|
2386
|
+
if ( pin2 ) *pin2 = in2;
|
2387
|
+
/* more detailed compare not implemented */
|
2388
|
+
return ret;
|
2389
|
+
}
|
2390
|
+
|
2391
|
+
/*********************************************************************************************************/
|
2392
|
+
INCHI_MODE CompareReversedINChI2( INChI *i1 /* InChI from reversed struct */, INChI *i2 /* input InChI */,
|
2393
|
+
INChI_Aux *a1, INChI_Aux *a2, ICR *picr, int *err )
|
2394
|
+
{
|
2395
|
+
INCHI_MODE ret = 0;
|
2396
|
+
INChI_Stereo *Stereo1=NULL, *Stereo2=NULL;
|
2397
|
+
int n1, n2, m, j, j1, j2, ret2, num_H1, num_H2;
|
2398
|
+
|
2399
|
+
*err = 0;
|
2400
|
+
|
2401
|
+
memset( picr, 0, sizeof(*picr) );
|
2402
|
+
|
2403
|
+
if ( i1 == NULL && i2 == NULL )
|
2404
|
+
return 0;
|
2405
|
+
if ( (i1 == NULL) ^ (i2 == NULL) ) {
|
2406
|
+
ret |= IDIF_PROBLEM; /* one InChI exists while another doesn't */
|
2407
|
+
goto exit_function;
|
2408
|
+
}
|
2409
|
+
|
2410
|
+
if ( i1->nErrorCode == i2->nErrorCode ) {
|
2411
|
+
if ( i1->nErrorCode ) {
|
2412
|
+
ret |= IDIF_PROBLEM; /* both InChI have same error codes */
|
2413
|
+
goto exit_function;
|
2414
|
+
}
|
2415
|
+
} else {
|
2416
|
+
ret |= IDIF_PROBLEM; /* at least one InChI has an error code */
|
2417
|
+
goto exit_function;
|
2418
|
+
}
|
2419
|
+
|
2420
|
+
if ( i1->nNumberOfAtoms != i2->nNumberOfAtoms ) {
|
2421
|
+
ret |= IDIF_NUM_AT;
|
2422
|
+
goto exit_function;
|
2423
|
+
}
|
2424
|
+
if ( i1->nNumberOfAtoms > 0 ) {
|
2425
|
+
if ( memcmp( i1->nAtom, i2->nAtom, i1->nNumberOfAtoms*sizeof(i1->nAtom[0]) ) ) {
|
2426
|
+
ret |= IDIF_ATOMS;
|
2427
|
+
goto exit_function;
|
2428
|
+
}
|
2429
|
+
/* IDIF_NON_TAUT_H, IDIF_MORE_FH, IDIF_LESS_FH */
|
2430
|
+
if ( memcmp( i1->nNum_H, i2->nNum_H, i1->nNumberOfAtoms*sizeof(i1->nNum_H[0]) ) ) {
|
2431
|
+
ret |= IDIF_POSITION_H;
|
2432
|
+
for ( j1 = 0; j1 < i1->nNumberOfAtoms; j1 ++ ) {
|
2433
|
+
if ( i1->nNum_H[j1] != i2->nNum_H[j1] && picr->num_diff_pos_H < ICR_MAX_DIFF_FIXED_H ) {
|
2434
|
+
picr->diff_pos_H_at[picr->num_diff_pos_H] = j1;
|
2435
|
+
picr->diff_pos_H_nH[picr->num_diff_pos_H] = i1->nNum_H[j1] - i2->nNum_H[j1];
|
2436
|
+
picr->num_diff_pos_H ++;
|
2437
|
+
}
|
2438
|
+
}
|
2439
|
+
}
|
2440
|
+
/* fixed H */
|
2441
|
+
if ( i1->nNum_H_fixed || i2->nNum_H_fixed ) {
|
2442
|
+
int bHasFixedH1 = 0, bHasFixedH2 = 0, i;
|
2443
|
+
if ( i1->nNum_H_fixed ) {
|
2444
|
+
for ( i = 0; i < i1->nNumberOfAtoms; i ++ ) {
|
2445
|
+
if ( i1->nNum_H_fixed[i] ) {
|
2446
|
+
bHasFixedH1 ++;
|
2447
|
+
}
|
2448
|
+
}
|
2449
|
+
}
|
2450
|
+
if ( i2->nNum_H_fixed ) {
|
2451
|
+
for ( i = 0; i < i2->nNumberOfAtoms; i ++ ) {
|
2452
|
+
if ( i2->nNum_H_fixed[i] ) {
|
2453
|
+
bHasFixedH2 ++;
|
2454
|
+
}
|
2455
|
+
}
|
2456
|
+
}
|
2457
|
+
if ( bHasFixedH1 && !bHasFixedH2 ) {
|
2458
|
+
for ( i = j = 0; i < i1->nNumberOfAtoms; i ++ ) {
|
2459
|
+
if ( i1->nNum_H_fixed[i] ) {
|
2460
|
+
if ( j < ICR_MAX_DIFF_FIXED_H ) {
|
2461
|
+
picr->fixed_H_at1_more[j] = i;
|
2462
|
+
picr->fixed_H_nH1_more[j] = i1->nNum_H_fixed[i];
|
2463
|
+
j ++;
|
2464
|
+
}
|
2465
|
+
}
|
2466
|
+
}
|
2467
|
+
picr->num_fixed_H1_more = j;
|
2468
|
+
ret |= IDIF_MORE_FH; /* Extra Fixed-H */
|
2469
|
+
} else
|
2470
|
+
if ( !bHasFixedH1 && bHasFixedH2 ) {
|
2471
|
+
for ( i = j = 0; i < i2->nNumberOfAtoms; i ++ ) {
|
2472
|
+
if ( i2->nNum_H_fixed[i] ) {
|
2473
|
+
if ( j < ICR_MAX_DIFF_FIXED_H ) {
|
2474
|
+
picr->fixed_H_at2_more[j] = i;
|
2475
|
+
picr->fixed_H_nH2_more[j] = i2->nNum_H_fixed[i];
|
2476
|
+
j ++;
|
2477
|
+
}
|
2478
|
+
}
|
2479
|
+
}
|
2480
|
+
picr->num_fixed_H2_more = j;
|
2481
|
+
ret |= IDIF_LESS_FH; /* Missed Fixed-H */
|
2482
|
+
} else
|
2483
|
+
if ( bHasFixedH1 && bHasFixedH2 &&
|
2484
|
+
memcmp( i1->nNum_H_fixed, i2->nNum_H_fixed, i1->nNumberOfAtoms*sizeof(i1->nNum_H_fixed[0]) ) ) {
|
2485
|
+
for ( i = j1 = j2 = 0; i < i1->nNumberOfAtoms; i ++ ) {
|
2486
|
+
if ( i1->nNum_H_fixed[i] > i2->nNum_H_fixed[i] ) {
|
2487
|
+
if ( j1 < ICR_MAX_DIFF_FIXED_H ) {
|
2488
|
+
picr->fixed_H_at1_more[j1] = i;
|
2489
|
+
picr->fixed_H_nH1_more[j1] = i1->nNum_H_fixed[i] - i2->nNum_H_fixed[i];
|
2490
|
+
j1 ++;
|
2491
|
+
}
|
2492
|
+
} else
|
2493
|
+
if ( i1->nNum_H_fixed[i] < i2->nNum_H_fixed[i] ) {
|
2494
|
+
if ( j2 < ICR_MAX_DIFF_FIXED_H ) {
|
2495
|
+
picr->fixed_H_at2_more[j2] = i;
|
2496
|
+
picr->fixed_H_nH2_more[j2] = i2->nNum_H_fixed[i] - i1->nNum_H_fixed[i];
|
2497
|
+
j2 ++;
|
2498
|
+
}
|
2499
|
+
}
|
2500
|
+
}
|
2501
|
+
ret |= (j1? IDIF_MORE_FH:0) | (j2? IDIF_LESS_FH:0);
|
2502
|
+
picr->num_fixed_H1_more = j1;
|
2503
|
+
picr->num_fixed_H2_more = j2;
|
2504
|
+
}
|
2505
|
+
}
|
2506
|
+
}
|
2507
|
+
/* compare formulas and H */
|
2508
|
+
num_H1 = 0;
|
2509
|
+
num_H2 = 0;
|
2510
|
+
ret2 = CompareHillFormulasNoH( i1->szHillFormula, i2->szHillFormula, &num_H1, &num_H2 );
|
2511
|
+
picr->tot_num_H1 = num_H1;
|
2512
|
+
picr->tot_num_H2 = num_H2;
|
2513
|
+
if ( ret2 ) {
|
2514
|
+
ret |= IDIF_NUM_EL;
|
2515
|
+
goto exit_function;
|
2516
|
+
}
|
2517
|
+
if ( num_H1 > num_H2 ) {
|
2518
|
+
ret |= IDIF_MORE_H;
|
2519
|
+
}
|
2520
|
+
if ( num_H1 < num_H2 ) {
|
2521
|
+
ret |= IDIF_LESS_H;
|
2522
|
+
}
|
2523
|
+
|
2524
|
+
if ( i1->lenConnTable != i2->lenConnTable ) {
|
2525
|
+
ret |= IDIF_CON_LEN;
|
2526
|
+
goto exit_function;
|
2527
|
+
} else
|
2528
|
+
if ( i1->lenConnTable > 0 && memcmp( i1->nConnTable, i2->nConnTable, i1->lenConnTable*sizeof(i1->nConnTable[0]) ) ) {
|
2529
|
+
ret |= IDIF_CON_TBL;
|
2530
|
+
goto exit_function;
|
2531
|
+
}
|
2532
|
+
/* output special cases: different number of t-groups, different sizes of t-groups, different endpoints */
|
2533
|
+
/* in isotopic or deprotonated cases i1->lenTautomer == 1 && i1->nTautomer[0] = 0 */
|
2534
|
+
/*
|
2535
|
+
if ( i1->lenTautomer != i2->lenTautomer && (i1->lenTautomer > 1 || i2->lenTautomer > 1) ) {
|
2536
|
+
ret |= IDIF_TAUT_LEN;
|
2537
|
+
}
|
2538
|
+
*/
|
2539
|
+
/* compare number of t-groups */
|
2540
|
+
n1 = i1->lenTautomer? i1->nTautomer[0] : 0;
|
2541
|
+
n2 = i2->lenTautomer? i2->nTautomer[0] : 0;
|
2542
|
+
if ( !n1 && n2 ) {
|
2543
|
+
ret |= IDIF_NO_TAUT;
|
2544
|
+
} else
|
2545
|
+
if ( n1 && !n2 ) {
|
2546
|
+
ret |= IDIF_WRONG_TAUT;
|
2547
|
+
} else
|
2548
|
+
if ( n1 == 1 && n2 > 1 ) {
|
2549
|
+
ret |= IDIF_SINGLE_TG;
|
2550
|
+
} else
|
2551
|
+
if ( n1 > 1 && n2 == 1 ) {
|
2552
|
+
ret |= IDIF_MULTIPLE_TG;
|
2553
|
+
} else
|
2554
|
+
if ( n1 != n2 ) {
|
2555
|
+
ret |= IDIF_NUM_TG;
|
2556
|
+
}
|
2557
|
+
if ( n1 || n2 ) {
|
2558
|
+
/* number of endpoints */
|
2559
|
+
int num1 = 0, num2 = 0, num_M1=0, num_M2=0;
|
2560
|
+
int len, num_eq, num_in1_only, num_in2_only;
|
2561
|
+
AT_NUMB *pe1 = (AT_NUMB *)inchi_malloc( (i1->lenTautomer+1) * sizeof(pe1[0]) );
|
2562
|
+
AT_NUMB *pe2 = (AT_NUMB *)inchi_malloc( (i2->lenTautomer+1) * sizeof(pe2[0]) );
|
2563
|
+
num_H1 = num_H2=0;
|
2564
|
+
/* collect endpoints, H, (-) */
|
2565
|
+
if ( !pe1 || !pe2 ) {
|
2566
|
+
if ( pe1 ) inchi_free( pe1 );
|
2567
|
+
if ( pe2 ) inchi_free( pe2 );
|
2568
|
+
*err = -1; /* allocation error */
|
2569
|
+
goto exit_function;
|
2570
|
+
}
|
2571
|
+
for ( m = 1; m < i1->lenTautomer; m += len ) {
|
2572
|
+
len = i1->nTautomer[m ++];
|
2573
|
+
num_H1 += i1->nTautomer[m];
|
2574
|
+
num_M1 += i1->nTautomer[m+1];
|
2575
|
+
for ( j = 2; j < len; j ++ ) {
|
2576
|
+
pe1[num1 ++] = i1->nTautomer[m + j];
|
2577
|
+
}
|
2578
|
+
}
|
2579
|
+
for ( m = 1; m < i2->lenTautomer; m += len ) {
|
2580
|
+
len = i2->nTautomer[m ++];
|
2581
|
+
num_H2 += i2->nTautomer[m];
|
2582
|
+
num_M2 += i2->nTautomer[m+1];
|
2583
|
+
for ( j = 2; j < len; j ++ ) {
|
2584
|
+
pe2[num2 ++] = i2->nTautomer[m + j];
|
2585
|
+
}
|
2586
|
+
}
|
2587
|
+
picr->num_taut_H1 = num_H1;
|
2588
|
+
picr->num_taut_H2 = num_H2;
|
2589
|
+
picr->num_taut_M1 = num_M1;
|
2590
|
+
picr->num_taut_M2 = num_M2;
|
2591
|
+
/* sort endpoints */
|
2592
|
+
insertions_sort_AT_RANK( pe1, num1 );
|
2593
|
+
insertions_sort_AT_RANK( pe2, num2 );
|
2594
|
+
/* compare */
|
2595
|
+
/*
|
2596
|
+
if ( num1 < num2 ) {
|
2597
|
+
ret |= IDIF_LESS_TG_ENDP;
|
2598
|
+
} else
|
2599
|
+
if ( num1 > num2 ) {
|
2600
|
+
ret |= IDIF_MORE_TG_ENDP;
|
2601
|
+
}
|
2602
|
+
*/
|
2603
|
+
/* compare all */
|
2604
|
+
num_eq = num_in1_only = num_in2_only = 0;
|
2605
|
+
for ( j1 = j2 = 0; j1 < num1 && j2 < num2; ) {
|
2606
|
+
if( pe1[j1] == pe2[j2] ) {
|
2607
|
+
j1 ++;
|
2608
|
+
j2 ++;
|
2609
|
+
num_eq ++;
|
2610
|
+
} else
|
2611
|
+
if ( pe1[j1] < pe2[j2] ) { /* BC: fixed, was pe2[j1] 2006-03-27 */
|
2612
|
+
if ( picr->num_endp_in1_only < ICR_MAX_ENDP_IN1_ONLY ) {
|
2613
|
+
picr->endp_in1_only[picr->num_endp_in1_only ++] = pe1[j1];
|
2614
|
+
}
|
2615
|
+
j1 ++;
|
2616
|
+
num_in1_only ++;
|
2617
|
+
} else {
|
2618
|
+
if ( picr->num_endp_in2_only < ICR_MAX_ENDP_IN2_ONLY ) {
|
2619
|
+
picr->endp_in2_only[picr->num_endp_in2_only ++] = pe2[j2];
|
2620
|
+
}
|
2621
|
+
j2 ++;
|
2622
|
+
num_in2_only ++;
|
2623
|
+
}
|
2624
|
+
}
|
2625
|
+
while ( j1 < num1 ) {
|
2626
|
+
if ( picr->num_endp_in1_only < ICR_MAX_ENDP_IN1_ONLY ) {
|
2627
|
+
picr->endp_in1_only[picr->num_endp_in1_only ++] = pe1[j1];
|
2628
|
+
}
|
2629
|
+
j1 ++;
|
2630
|
+
num_in1_only ++;
|
2631
|
+
}
|
2632
|
+
while ( j2 < num2 ) {
|
2633
|
+
if ( picr->num_endp_in2_only < ICR_MAX_ENDP_IN2_ONLY ) {
|
2634
|
+
picr->endp_in2_only[picr->num_endp_in2_only ++] = pe2[j2];
|
2635
|
+
}
|
2636
|
+
j2 ++;
|
2637
|
+
num_in2_only ++;
|
2638
|
+
}
|
2639
|
+
if ( num_in1_only ) {
|
2640
|
+
ret |= IDIF_EXTRA_TG_ENDP;
|
2641
|
+
}
|
2642
|
+
if ( num_in2_only ) {
|
2643
|
+
ret |= IDIF_MISS_TG_ENDP;
|
2644
|
+
}
|
2645
|
+
if ( !num_in1_only && !num_in2_only && num_eq ) {
|
2646
|
+
; /* same t-groups endpoints */
|
2647
|
+
} else {
|
2648
|
+
ret |= IDIF_DIFF_TG_ENDP;
|
2649
|
+
}
|
2650
|
+
inchi_free( pe1 );
|
2651
|
+
inchi_free( pe2 );
|
2652
|
+
|
2653
|
+
}
|
2654
|
+
|
2655
|
+
if ( (i1->lenTautomer > 1 && i2->lenTautomer > 1) &&
|
2656
|
+
( i1->lenTautomer != i2->lenTautomer ||
|
2657
|
+
memcmp( i1->nTautomer, i2->nTautomer, i1->lenTautomer*sizeof(i1->nTautomer[0]) ) ) )
|
2658
|
+
ret |= IDIF_TG;
|
2659
|
+
|
2660
|
+
if ( i1->nNumberOfIsotopicAtoms != i2->nNumberOfIsotopicAtoms ) {
|
2661
|
+
ret |= IDIF_NUM_ISO_AT;
|
2662
|
+
} else
|
2663
|
+
if ( i1->nNumberOfIsotopicAtoms > 0 && memcmp( i1->IsotopicAtom, i2->IsotopicAtom, i1->nNumberOfIsotopicAtoms*sizeof(i1->IsotopicAtom[0]) ) )
|
2664
|
+
ret |= IDIF_ISO_AT;
|
2665
|
+
if ( i1->nTotalCharge != i2->nTotalCharge )
|
2666
|
+
ret |= IDIF_CHARGE;
|
2667
|
+
if ( a1 && a1->nNumRemovedProtons && (!a2 || a2->nNumRemovedProtons != a1->nNumRemovedProtons) ) {
|
2668
|
+
ret |= IDIF_REM_PROT;
|
2669
|
+
}
|
2670
|
+
if ( a1 && (!a2 ||
|
2671
|
+
a2->nNumRemovedIsotopicH[0] != a1->nNumRemovedIsotopicH[0] ||
|
2672
|
+
a2->nNumRemovedIsotopicH[1] != a1->nNumRemovedIsotopicH[1] ||
|
2673
|
+
a2->nNumRemovedIsotopicH[2] != a1->nNumRemovedIsotopicH[2]) ) {
|
2674
|
+
ret |= IDIF_REM_ISO_H;
|
2675
|
+
}
|
2676
|
+
|
2677
|
+
/*
|
2678
|
+
if ( i1->nPossibleLocationsOfIsotopicH && i2->nPossibleLocationsOfIsotopicH ) {
|
2679
|
+
if ( i1->nPossibleLocationsOfIsotopicH[0] != i2->nPossibleLocationsOfIsotopicH[0] ||
|
2680
|
+
memcmp(i1->nPossibleLocationsOfIsotopicH, i2->nPossibleLocationsOfIsotopicH,
|
2681
|
+
sizeof(i1->nPossibleLocationsOfIsotopicH[0])*i1->nPossibleLocationsOfIsotopicH[0]) )
|
2682
|
+
return 18;
|
2683
|
+
} else
|
2684
|
+
if ( !i1->nPossibleLocationsOfIsotopicH != !i2->nPossibleLocationsOfIsotopicH ) {
|
2685
|
+
return 19;
|
2686
|
+
}
|
2687
|
+
*/
|
2688
|
+
if ( i1->StereoIsotopic &&
|
2689
|
+
i1->StereoIsotopic->nNumberOfStereoBonds + i1->StereoIsotopic->nNumberOfStereoCenters ) {
|
2690
|
+
Stereo1 = i1->StereoIsotopic;
|
2691
|
+
} else {
|
2692
|
+
Stereo1 = i1->Stereo;
|
2693
|
+
}
|
2694
|
+
if ( i2->StereoIsotopic &&
|
2695
|
+
i2->StereoIsotopic->nNumberOfStereoBonds + i2->StereoIsotopic->nNumberOfStereoCenters ) {
|
2696
|
+
Stereo2 = i2->StereoIsotopic;
|
2697
|
+
} else {
|
2698
|
+
Stereo2 = i2->Stereo;
|
2699
|
+
}
|
2700
|
+
ret |= CompareReversedStereoINChI2( Stereo1, Stereo2, picr );
|
2701
|
+
|
2702
|
+
exit_function:
|
2703
|
+
|
2704
|
+
picr->flags = ret;
|
2705
|
+
|
2706
|
+
return ret;
|
2707
|
+
}
|
2708
|
+
#endif /* } READ_INCHI_STRING */
|
1922
2709
|
/***************************************************************************************/
|
1923
|
-
int Create_INChI( INChI **ppINChI, INChI_Aux **ppINChI_Aux, ORIG_ATOM_DATA *orig_inp_data,
|
2710
|
+
int Create_INChI( INChI **ppINChI, INChI_Aux **ppINChI_Aux, ORIG_ATOM_DATA *orig_inp_data, /* not used */
|
1924
2711
|
inp_ATOM *inp_at, INP_ATOM_DATA *out_norm_data[2],
|
1925
2712
|
int num_inp_at, INCHI_MODE nUserMode,
|
1926
2713
|
INCHI_MODE *pbTautFlags, INCHI_MODE *pbTautFlagsDone,
|
1927
|
-
struct tagInchiTime *ulMaxTime, char *pStrErrStruct)
|
2714
|
+
struct tagInchiTime *ulMaxTime, T_GROUP_INFO *ti_out, char *pStrErrStruct)
|
1928
2715
|
{
|
1929
2716
|
/*
|
1930
2717
|
#define NON_TAUT 0
|
@@ -1952,10 +2739,13 @@ int Create_INChI( INChI **ppINChI, INChI_Aux **ppINChI_Aux, ORIG_ATOM_DATA *ori
|
|
1952
2739
|
int bMayHaveStereo = 0;
|
1953
2740
|
int num_taut_at = 0;
|
1954
2741
|
|
1955
|
-
inp_ATOM *out_at = NULL; /*, *norm_at_fixed_bonds[TAUT_NUM];
|
1956
|
-
INChI *pINChI;
|
1957
|
-
INChI_Aux *pINChI_Aux;
|
1958
|
-
int bPointedEdgeStereo = (
|
2742
|
+
inp_ATOM *out_at = NULL; /*, *norm_at_fixed_bonds[TAUT_NUM]; */ /* = {out_norm_nontaut_at, out_norm_taut_at} ; */
|
2743
|
+
INChI *pINChI=NULL; /* added initialization 2006-03 */
|
2744
|
+
INChI_Aux *pINChI_Aux=NULL; /* added initialization 2006-03 */
|
2745
|
+
int bPointedEdgeStereo = ((TG_FLAG_POINTED_EDGE_STEREO & *pbTautFlags)? PES_BIT_POINT_EDGE_STEREO:0)
|
2746
|
+
| ((TG_FLAG_PHOSPHINE_STEREO & *pbTautFlags)? PES_BIT_PHOSPHINE_STEREO :0)
|
2747
|
+
| ((TG_FLAG_ARSINE_STEREO & *pbTautFlags)? PES_BIT_ARSINE_STEREO :0)
|
2748
|
+
| ((TG_FLAG_FIX_SP3_BUG & *pbTautFlags)? PES_BIT_FIX_SP3_BUG :0);
|
1959
2749
|
INCHI_MODE bTautFlags = (*pbTautFlags & (~(INCHI_MODE)TG_FLAG_ALL_TAUTOMERIC) );
|
1960
2750
|
INCHI_MODE bTautFlagsDone = (*pbTautFlagsDone /*& (~(INCHI_MODE)TG_FLAG_ALL_TAUTOMERIC) */);
|
1961
2751
|
#if( bRELEASE_VERSION == 0 )
|
@@ -2006,11 +2796,25 @@ int Create_INChI( INChI **ppINChI, INChI_Aux **ppINChI_Aux, ORIG_ATOM_DATA *ori
|
|
2006
2796
|
|
2007
2797
|
/* Preprocess the structure; here THE NUMBER OF ATOMS MAY BE REDUCED */
|
2008
2798
|
/* ??? Ambiguity: H-D may become HD or DH (that is, H+implicit D or D+implicit H) */
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2799
|
+
if ( TG_FLAG_H_ALREADY_REMOVED & bTautFlags ) {
|
2800
|
+
INP_ATOM_DATA *out_norm_data1 = out_norm_data[TAUT_YES]->at? out_norm_data[TAUT_YES] :
|
2801
|
+
out_norm_data[TAUT_NON]->at? out_norm_data[TAUT_NON] : NULL;
|
2802
|
+
if ( out_norm_data1 ) {
|
2803
|
+
num_at_tg =
|
2804
|
+
num_atoms = out_norm_data1->num_at - out_norm_data1->num_removed_H;
|
2805
|
+
num_removed_H = out_norm_data1->num_removed_H;
|
2806
|
+
t_group_info->tni.nNumRemovedExplicitH = num_removed_H;
|
2807
|
+
} else {
|
2808
|
+
ret = -1;
|
2809
|
+
goto exit_function;
|
2810
|
+
}
|
2811
|
+
} else {
|
2812
|
+
num_at_tg =
|
2813
|
+
num_atoms = remove_terminal_HDT( num_inp_at, out_at );
|
2814
|
+
num_removed_H = num_inp_at - num_atoms;
|
2815
|
+
t_group_info->tni.nNumRemovedExplicitH = num_removed_H;
|
2816
|
+
add_DT_to_num_H( num_atoms, out_at );
|
2817
|
+
}
|
2014
2818
|
/*fix_odd_things( num_atoms, out_at );*/
|
2015
2819
|
#if( FIND_RING_SYSTEMS == 1 )
|
2016
2820
|
MarkRingSystemsInp( out_at, num_atoms );
|
@@ -2114,7 +2918,7 @@ int Create_INChI( INChI **ppINChI, INChI_Aux **ppINChI_Aux, ORIG_ATOM_DATA *ori
|
|
2114
2918
|
if ( s[TAUT_YES].nLenLinearCTTautomer > 0 ) {
|
2115
2919
|
num_at_tg = num_taut_at+t_group_info->num_t_groups;
|
2116
2920
|
/* ??? -not true- create t_group_info_orig for multiple calls with atom renumbering */
|
2117
|
-
make_a_copy_of_t_group_info( t_group_info_orig
|
2921
|
+
make_a_copy_of_t_group_info( t_group_info_orig /* dest*/, t_group_info /* source*/ );
|
2118
2922
|
/* mark isotopic tautomer groups: calculate t_group->iWeight */
|
2119
2923
|
s[TAUT_YES].nLenLinearCTIsotopicTautomer=set_tautomer_iso_sort_keys( t_group_info );
|
2120
2924
|
if ( s[TAUT_YES].nLenLinearCTIsotopicTautomer < 0 ) {
|
@@ -2400,7 +3204,7 @@ int Create_INChI( INChI **ppINChI, INChI_Aux **ppINChI_Aux, ORIG_ATOM_DATA *ori
|
|
2400
3204
|
ret = Canon_INChI( num_atoms, i?num_at_tg:num_atoms, at[i], pCS, nMode, i);
|
2401
3205
|
}
|
2402
3206
|
|
2403
|
-
pINChI = ppINChI[i];
|
3207
|
+
pINChI = ppINChI[i]; /* pointers to already allocated still empty InChI */
|
2404
3208
|
pINChI_Aux = ppINChI_Aux[i];
|
2405
3209
|
if ( ret <= 0 ) {
|
2406
3210
|
/***************************************/
|
@@ -2466,6 +3270,9 @@ int Create_INChI( INChI **ppINChI, INChI_Aux **ppINChI_Aux, ORIG_ATOM_DATA *ori
|
|
2466
3270
|
#endif
|
2467
3271
|
FreeNeighList( pCS->NeighList );
|
2468
3272
|
DeAllocateCS( pCS2 );
|
3273
|
+
|
3274
|
+
pINChI = NULL; /* avoid dangling pointers */
|
3275
|
+
pINChI_Aux = NULL; /* avoid dangling pointers */
|
2469
3276
|
}
|
2470
3277
|
if ( ret == 0 ) {
|
2471
3278
|
ret = num_atoms;
|
@@ -2478,7 +3285,11 @@ exit_function:
|
|
2478
3285
|
inchi_free( at[TAUT_YES] );
|
2479
3286
|
if ( at[TAUT_NON] )
|
2480
3287
|
inchi_free( at[TAUT_NON] );
|
2481
|
-
|
3288
|
+
if ( ti_out ) {
|
3289
|
+
*ti_out = *t_group_info;
|
3290
|
+
} else {
|
3291
|
+
free_t_group_info( t_group_info );
|
3292
|
+
}
|
2482
3293
|
free_t_group_info( t_group_info_orig );
|
2483
3294
|
return ret;
|
2484
3295
|
}
|
@@ -3499,7 +4310,7 @@ exit_function:
|
|
3499
4310
|
|
3500
4311
|
/***************************************************************************************/
|
3501
4312
|
int FillOutInputInfAtom(inp_ATOM *inp_at, INF_ATOM_DATA *inf_at_data, int init_num_at, int num_removed_H,
|
3502
|
-
int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic, int bIsotopic, int bAbcNumbers)
|
4313
|
+
int bAdd_DT_to_num_H, int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic, int bIsotopic, int bAbcNumbers)
|
3503
4314
|
{
|
3504
4315
|
int i, j, m, n, ret, len_str, len, atw;
|
3505
4316
|
int num_iso_H[NUM_H_ISOTOPES];
|
@@ -3520,16 +4331,6 @@ int FillOutInputInfAtom(inp_ATOM *inp_at, INF_ATOM_DATA *inf_at_data, int init_n
|
|
3520
4331
|
|
3521
4332
|
inf_at_data->nNumRemovedProtons = nNumRemovedProtons;
|
3522
4333
|
MakeRemovedProtonsString( nNumRemovedProtons, nNumRemovedProtonsIsotopic, NULL, bIsotopic, inf_at_data->szRemovedProtons, NULL );
|
3523
|
-
/*
|
3524
|
-
if ( inf_at_data->nNumRemovedProtons ) {
|
3525
|
-
sprintf ( inf_at_data->szRemovedProtons, "Proton balance: %c %d H+",
|
3526
|
-
inf_at_data->nNumRemovedProtons>=0? '+':'-',
|
3527
|
-
abs(inf_at_data->nNumRemovedProtons) );
|
3528
|
-
} else {
|
3529
|
-
inf_at_data->szRemovedProtons[0] = '\0';
|
3530
|
-
|
3531
|
-
}
|
3532
|
-
*/
|
3533
4334
|
/* atom canonical and equivalence numbers > 0 */
|
3534
4335
|
for ( i = 0; i < num_at; i ++ ) {
|
3535
4336
|
#if( DISPLAY_ORIG_AT_NUMBERS == 1 )
|
@@ -3577,7 +4378,7 @@ int FillOutInputInfAtom(inp_ATOM *inp_at, INF_ATOM_DATA *inf_at_data, int init_n
|
|
3577
4378
|
}
|
3578
4379
|
}
|
3579
4380
|
}
|
3580
|
-
if ( bIsotopic ) {
|
4381
|
+
if ( bIsotopic && !bAdd_DT_to_num_H ) {
|
3581
4382
|
/* subtract number of isotopic H atoms from the total number of H atoms */
|
3582
4383
|
for ( j = 0; j < NUM_H_ISOTOPES; j ++ ) {
|
3583
4384
|
n -= num_iso_H[j];
|
@@ -3656,7 +4457,7 @@ int FillOutInputInfAtom(inp_ATOM *inp_at, INF_ATOM_DATA *inf_at_data, int init_n
|
|
3656
4457
|
}
|
3657
4458
|
/**********************************************************************************************/
|
3658
4459
|
int FillOutInfAtom(inp_ATOM *norm_at, INF_ATOM_DATA *inf_norm_at_data, int init_num_at, int num_removed_H,
|
3659
|
-
int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic, int bIsotopic,
|
4460
|
+
int bAdd_DT_to_num_H, int nNumRemovedProtons, NUM_H *nNumRemovedProtonsIsotopic, int bIsotopic,
|
3660
4461
|
INChI *pINChI, INChI_Aux *pINChI_Aux, int bAbcNumbers, INCHI_MODE nMode )
|
3661
4462
|
{
|
3662
4463
|
if ( norm_at && inf_norm_at_data && inf_norm_at_data->at ) {
|
@@ -3664,7 +4465,7 @@ int FillOutInfAtom(inp_ATOM *norm_at, INF_ATOM_DATA *inf_norm_at_data, int init_
|
|
3664
4465
|
return FillOutCanonInfAtom( norm_at, inf_norm_at_data, init_num_at, bIsotopic, pINChI,
|
3665
4466
|
pINChI_Aux, bAbcNumbers, nMode);
|
3666
4467
|
} else {
|
3667
|
-
return FillOutInputInfAtom( norm_at, inf_norm_at_data, init_num_at, num_removed_H,
|
4468
|
+
return FillOutInputInfAtom( norm_at, inf_norm_at_data, init_num_at, num_removed_H, bAdd_DT_to_num_H,
|
3668
4469
|
nNumRemovedProtons, nNumRemovedProtonsIsotopic, bIsotopic, bAbcNumbers);
|
3669
4470
|
}
|
3670
4471
|
}
|
@@ -3689,7 +4490,7 @@ int FillOutCompositeCanonInfAtom(COMP_ATOM_DATA *composite_norm_data, INF_ATOM_D
|
|
3689
4490
|
offset_H = composite_norm_data->num_at - composite_norm_data->num_removed_H;
|
3690
4491
|
if ( bTautomeric == TAUT_INI ) {
|
3691
4492
|
ret = FillOutInputInfAtom( composite_norm_data->at, inf_norm_at_data, composite_norm_data->num_at,
|
3692
|
-
composite_norm_data->num_removed_H,
|
4493
|
+
composite_norm_data->num_removed_H, 0 /*bAdd_DT_to_num_H*/,
|
3693
4494
|
composite_norm_data->nNumRemovedProtons,
|
3694
4495
|
composite_norm_data->nNumRemovedProtonsIsotopic,
|
3695
4496
|
bIsotopic, bAbcNumbers);
|