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