rino 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/Rakefile +1 -1
  2. data/ext/extconf.rb +1 -24
  3. data/ext/libinchi.so +0 -0
  4. data/ext/src/aux2atom.h +120 -39
  5. data/ext/src/comdef.h +3 -3
  6. data/ext/src/dispstru.c +2547 -0
  7. data/ext/src/dispstru.h +73 -0
  8. data/ext/src/extr_ct.h +5 -2
  9. data/ext/src/ichi.h +27 -11
  10. data/ext/src/ichi_bns.c +1800 -254
  11. data/ext/src/ichi_bns.h +205 -4
  12. data/ext/src/ichican2.c +197 -86
  13. data/ext/src/ichicano.c +8 -13
  14. data/ext/src/ichicano.h +2 -2
  15. data/ext/src/ichicans.c +11 -6
  16. data/ext/src/ichicant.h +2 -2
  17. data/ext/src/ichicomn.h +2 -2
  18. data/ext/src/ichicomp.h +19 -4
  19. data/ext/src/ichidrp.h +9 -5
  20. data/ext/src/ichierr.h +5 -3
  21. data/ext/src/ichiisot.c +2 -2
  22. data/ext/src/ichimain.c +461 -0
  23. data/ext/src/ichimain.h +23 -15
  24. data/ext/src/ichimak2.c +6 -6
  25. data/ext/src/ichimake.c +843 -42
  26. data/ext/src/ichimake.h +4 -2
  27. data/ext/src/ichimap1.c +5 -5
  28. data/ext/src/ichimap2.c +2 -2
  29. data/ext/src/ichimap4.c +34 -21
  30. data/ext/src/ichinorm.c +11 -5
  31. data/ext/src/ichinorm.h +3 -2
  32. data/ext/src/ichiparm.c +2 -2
  33. data/ext/src/ichiparm.h +232 -30
  34. data/ext/src/ichiprt1.c +35 -11
  35. data/ext/src/ichiprt2.c +78 -7
  36. data/ext/src/ichiprt3.c +300 -120
  37. data/ext/src/ichiqueu.c +17 -2
  38. data/ext/src/ichiread.c +6932 -0
  39. data/ext/src/ichiring.c +3 -2
  40. data/ext/src/ichiring.h +2 -2
  41. data/ext/src/ichirvr1.c +4891 -0
  42. data/ext/src/ichirvr2.c +6344 -0
  43. data/ext/src/ichirvr3.c +5499 -0
  44. data/ext/src/ichirvr4.c +3177 -0
  45. data/ext/src/ichirvr5.c +1166 -0
  46. data/ext/src/ichirvr6.c +1287 -0
  47. data/ext/src/ichirvr7.c +2319 -0
  48. data/ext/src/ichirvrs.h +882 -0
  49. data/ext/src/ichisize.h +2 -2
  50. data/ext/src/ichisort.c +5 -5
  51. data/ext/src/ichister.c +281 -86
  52. data/ext/src/ichister.h +9 -3
  53. data/ext/src/ichitaut.c +208 -9
  54. data/ext/src/ichitaut.h +13 -11
  55. data/ext/src/ichitime.h +16 -2
  56. data/ext/src/inchicmp.h +107 -0
  57. data/ext/src/inpdef.h +6 -3
  58. data/ext/src/libinchi_wrap.c +912 -0
  59. data/ext/src/lreadmol.h +34 -31
  60. data/ext/src/mode.h +244 -7
  61. data/ext/src/mol2atom.c +1060 -0
  62. data/ext/src/mol2atom.h +31 -0
  63. data/ext/src/readinch.c +239 -0
  64. data/ext/src/readmol.c +28 -0
  65. data/ext/src/{e_readmol.h → readmol.h} +7 -9
  66. data/ext/src/runichi.c +251 -177
  67. data/ext/src/strutil.c +444 -238
  68. data/ext/src/strutil.h +150 -11
  69. data/ext/src/util.c +176 -118
  70. data/ext/src/util.h +15 -3
  71. data/lib/rino.rb +71 -3
  72. data/test/test.rb +33 -4
  73. metadata +22 -34
  74. data/ext/ruby_inchi_main.so +0 -0
  75. data/ext/src/e_0dstereo.c +0 -3014
  76. data/ext/src/e_0dstereo.h +0 -31
  77. data/ext/src/e_comdef.h +0 -57
  78. data/ext/src/e_ctl_data.h +0 -147
  79. data/ext/src/e_ichi_io.c +0 -498
  80. data/ext/src/e_ichi_io.h +0 -40
  81. data/ext/src/e_ichi_parms.c +0 -37
  82. data/ext/src/e_ichi_parms.h +0 -41
  83. data/ext/src/e_ichicomp.h +0 -50
  84. data/ext/src/e_ichierr.h +0 -40
  85. data/ext/src/e_ichimain.c +0 -593
  86. data/ext/src/e_ichisize.h +0 -43
  87. data/ext/src/e_inchi_atom.c +0 -75
  88. data/ext/src/e_inchi_atom.h +0 -33
  89. data/ext/src/e_inpdef.h +0 -41
  90. data/ext/src/e_mode.h +0 -706
  91. data/ext/src/e_mol2atom.c +0 -649
  92. data/ext/src/e_readinch.c +0 -58
  93. data/ext/src/e_readmol.c +0 -54
  94. data/ext/src/e_readstru.c +0 -251
  95. data/ext/src/e_readstru.h +0 -33
  96. data/ext/src/e_util.c +0 -284
  97. data/ext/src/e_util.h +0 -61
  98. data/ext/src/ichilnct.c +0 -286
  99. data/ext/src/inchi_api.h +0 -670
  100. data/ext/src/inchi_dll.c +0 -1480
  101. data/ext/src/inchi_dll.h +0 -34
  102. data/ext/src/inchi_dll_main.c +0 -23
  103. data/ext/src/inchi_dll_main.h +0 -31
  104. data/ext/src/ruby_inchi_main.c +0 -558
@@ -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.00
6
- * April 13, 2005
5
+ * Software version 1.01
6
+ * July 21, 2006
7
7
  * Developed at NIST
8
8
  */
9
9
 
@@ -11,7 +11,7 @@
11
11
  #define __INCHI_BNS_H___
12
12
 
13
13
  #define BN_MAX_ALTP 16
14
- #define MAX_VERTEX 1024 /* including s; if vert[] has num_vert then MAX_VERTEX has (2*num_vert+2+FIRST_INDX) elements */
14
+ /*#define MAX_VERTEX 1024*/ /* including s; if vert[] has num_vert then MAX_VERTEX has (2*num_vert+2+FIRST_INDX) elements */
15
15
 
16
16
  /* forward declarations */
17
17
 
@@ -34,6 +34,118 @@ typedef S_SHORT VertexFlow;
34
34
 
35
35
  #define BNS_EDGE_FORBIDDEN_MASK 1
36
36
  #define BNS_EDGE_FORBIDDEN_TEMP 2
37
+ #define BNS_EDGE_FORBIDDEN_TEST 4
38
+
39
+ /* BNS vertex types */
40
+
41
+ #define BNS_VERT_TYPE_ATOM 0x0001
42
+ #define BNS_VERT_TYPE_ENDPOINT 0x0002 /* attribute */
43
+ #define BNS_VERT_TYPE_TGROUP 0x0004
44
+ #define BNS_VERT_TYPE_C_POINT 0x0008
45
+ #define BNS_VERT_TYPE_C_GROUP 0x0010
46
+ #define BNS_VERT_TYPE_SUPER_TGROUP 0x0020
47
+ #define BNS_VERT_TYPE_TEMP 0x0040
48
+
49
+ #define BNS_VERT_TYPE__AUX 0x0080 /* vertex added to build charge substructures */
50
+ #define BNS_VERT_TYPE_C_NEGATIVE 0x0100 /* negative charge group; attribute, should be used with BNS_VERT_TYPE_C_GROUP */
51
+ #define BNS_VERT_TYPE_ACID 0x0200 /* only for this type are allowed paths: t_group-atom-c_group_neg (path_TACN) */
52
+ #define BNS_VERT_TYPE_CARBON_GR 0x0400 /* charge of carbon atom; should be used with BNS_VT_C_POS, BNS_VT_C_NEG */
53
+ #define BNS_VERT_TYPE_METAL_GR 0x0800 /* metal atom group; may be used alone or with BNS_VT_M_POS, BNS_VT_M_NEG */
54
+
55
+ #define BNS_VERT_TYPE_ANY_GROUP (BNS_VERT_TYPE_TGROUP | BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_SUPER_TGROUP)
56
+
57
+ /* InChI->Structure */
58
+
59
+ #define BNS_VT_C_POS BNS_VERT_TYPE_C_GROUP /* positive charge group, heteroat */
60
+ #define BNS_VT_C_NEG (BNS_VERT_TYPE_C_GROUP | BNS_VERT_TYPE_C_NEGATIVE) /* negative charge group, heteroat */
61
+ #define BNS_VT_C_POS_C (BNS_VT_C_POS | BNS_VERT_TYPE_CARBON_GR) /* positive charge group, C, Si, Ge, Sn */
62
+ #define BNS_VT_C_NEG_C (BNS_VT_C_NEG | BNS_VERT_TYPE_CARBON_GR) /* negative charge group, C, Si, Ge, Sn */
63
+ #define BNS_VT_C_POS_M (BNS_VT_C_POS | BNS_VERT_TYPE_METAL_GR) /* positive charge group, metal */
64
+ #define BNS_VT_C_NEG_M (BNS_VT_C_NEG | BNS_VERT_TYPE_METAL_GR) /* negative charge group, metal */
65
+ #define BNS_VT_M_GROUP BNS_VERT_TYPE_METAL_GR /* metal-group, flower vertex */
66
+
67
+ #define BNS_VT_C_POS_ALL (BNS_VERT_TYPE_SUPER_TGROUP | BNS_VERT_TYPE_C_GROUP) /* supergroup (+) */
68
+ #define BNS_VT_C_NEG_ALL (BNS_VT_C_POS_ALL | BNS_VERT_TYPE_C_NEGATIVE) /* supergroup (-) */
69
+
70
+ #define BNS_VT_CHRG_STRUCT (BNS_VERT_TYPE__AUX | BNS_VERT_TYPE_TEMP) /* ChargeStruct vertex */
71
+ #define BNS_VT_YVCONNECTOR BNS_VERT_TYPE__AUX /* group connection */
72
+
73
+ #define IS_BNS_VT_C_OR_CSUPER_GR(X) ((X) & BNS_VT_C_POS)
74
+ #define IS_BNS_VT_C_GR(X) (((X) & BNS_VT_C_POS_ALL) == BNS_VERT_TYPE_C_GROUP)
75
+ #define IS_BNS_VT_CM_GR(X) (((X) & BNS_VT_C_POS_M) == BNS_VT_C_POS_M) /* metal charge group */
76
+ #define IS_BNS_VT_M_GR(X) ((X) == BNS_VERT_TYPE_METAL_GR ) /* metal flower base or vertices */
77
+ #define IS_BNS_VT_YVCONNECTOR(X) (((X) & BNS_VERT_TYPE__AUX) && !((X) & BNS_VERT_TYPE_TEMP))
78
+ #define IS_BNS_VT_CHRG_STRUCT(X) (((X) & BNS_VERT_TYPE__AUX) && ((X) & BNS_VERT_TYPE_TEMP))
79
+ #define IS_BNS_VT_ATOM(X) ((X) & BNS_VERT_TYPE_ATOM)
80
+
81
+ #define BNS_ADD_SUPER_TGROUP 1 /* reserve one more edge for a t-group to connect to a single super-t-group */
82
+ #define NUM_KINDS_OF_GROUPS 2 /* 1 accounts for t-group kind, one more 1 accounts for c-group kind */
83
+
84
+ #define BNS_ADD_ATOMS 2 /* max. number of fictitious atoms to add (except t-gtoups) */
85
+ #define BNS_ADD_EDGES 1 /* max. number of edges to add to each atom (except edges to a t-group or c-group) */
86
+
87
+ typedef enum tagAltPathConst {
88
+ iALTP_MAX_LEN, /* 0 */
89
+ iALTP_FLOW, /* 1 */
90
+ iALTP_PATH_LEN, /* 2 */
91
+ iALTP_START_ATOM, /* 3 */
92
+ iALTP_END_ATOM, /* 4 */
93
+ iALTP_NEIGHBOR, /* 5 */
94
+ iALTP_HDR_LEN = iALTP_NEIGHBOR
95
+ } ALT_CONST;
96
+
97
+ #define ALTP_PATH_LEN(altp) (altp)[iALTP_PATH_LEN].number /* number of bonds = number of atoms-1*/
98
+ #define ALTP_END_ATOM(altp) (altp)[iALTP_END_ATOM].number
99
+ #define ALTP_START_ATOM(altp) (altp)[iALTP_START_ATOM].number
100
+ #define ALTP_THIS_ATOM_NEIGHBOR(altp,X) (altp)[iALTP_NEIGHBOR+(X)].ineigh[0] /* 0 <= X < path_len */
101
+ #define ALTP_NEXT_ATOM_NEIGHBOR(altp,X) (altp)[iALTP_NEIGHBOR+(X)].ineigh[1]
102
+ #define ALTP_CUR_THIS_ATOM_NEIGHBOR(altp) (altp)[iALTP_NEIGHBOR+ALTP_PATH_LEN(altp)].ineigh[0] /* 0 <= X < path_len */
103
+ #define ALTP_CUR_NEXT_ATOM_NEIGHBOR(altp) (altp)[iALTP_NEIGHBOR+ALTP_PATH_LEN(altp)].ineigh[1]
104
+ #define ALTP_NEXT(altp) (++ALTP_PATH_LEN(altp))
105
+ #define ALTP_PREV(altp) (--ALTP_PATH_LEN(altp))
106
+ #define ALTP_MAY_ADD(altp) (iALTP_NEIGHBOR + (altp)[iALTP_PATH_LEN].number < (altp)[iALTP_MAX_LEN].number)
107
+ #define ALTP_ALLOCATED_LEN(altp) (altp)[iALTP_MAX_LEN].number
108
+ #define ALTP_DELTA(altp) (altp)[iALTP_FLOW].flow[0]
109
+ #define ALTP_OVERFLOW(altp) (altp)[iALTP_FLOW].flow[1]
110
+
111
+ #define Vertex_s 0
112
+ #define Vertex_t 1
113
+
114
+ #define NO_VERTEX -2
115
+ #define BLOSSOM_BASE -1
116
+
117
+ #define ADD_CAPACITY_RADICAL 1 /* add capacity to radical */
118
+
119
+ #define MAX_BOND_EDGE_CAP 2 /* triple bond */
120
+ #define AROM_BOND_EDGE_CAP 1
121
+ #define MAX_TGROUP_EDGE_CAP 2 /* -NH2 provides max. capacity */
122
+
123
+ /* edge to s or t */
124
+ #define EDGE_FLOW_ST_MASK 0x3fff /* mask for flow */
125
+ #define EDGE_FLOW_ST_PATH 0x4000 /* mark: the edge belongs to the augmenting path */
126
+
127
+ /* edges between other vertices */
128
+ /* EdgeFlow defined as S_SHORT; change from S_CHAR made 9-23-2005 */
129
+ #define EDGE_FLOW_MASK 0x3fff /* mask for flow */
130
+ #define EDGE_FLOW_PATH 0x4000 /* mark: the edge belongs to the augmenting path */
131
+
132
+ /*********************************************************************************/
133
+ #if( ADD_CAPACITY_RADICAL == 1 ) /* { */
134
+ /* -- do not treat triplets as moving dots -- 2004-02-18 --
135
+ #define MAX_AT_FLOW(X) (((X).chem_bonds_valence - (X).valence)+\
136
+ ((is_centerpoint_elem((X).el_number)||get_endpoint_valence((X).el_number))?\
137
+ (((X).radical==RADICAL_DOUBLET)+2*((X).radical==RADICAL_TRIPLET)):0))
138
+ */
139
+ #define MAX_AT_FLOW(X) (((X).chem_bonds_valence - (X).valence)+\
140
+ ((is_centerpoint_elem((X).el_number)||get_endpoint_valence((X).el_number))?\
141
+ (((X).radical==RADICAL_DOUBLET)/*+2*((X).radical==RADICAL_TRIPLET)*/):0))
142
+
143
+
144
+ #else /* } ADD_CAPACITY_RADICAL { */
145
+
146
+ #define MAX_AT_FLOW(X) (((X).chem_bonds_valence - (X).valence)
147
+
148
+ #endif /* } ADD_CAPACITY_RADICAL */
37
149
 
38
150
  /**************************** BNS_EDGE ************************************/
39
151
  typedef struct BnsEdge {
@@ -91,6 +203,7 @@ typedef struct BalancedNetworkStructure {
91
203
  /*int len_vertices; */ /* allocation size for BNS_VERTEX data */
92
204
  int num_bonds; /* number of real bonds/2 = number of edges between real atoms */
93
205
  int num_edges; /* number of currently in effect */
206
+ int num_iedges; /* added 9-16-2005; used only in InChI Reversing */
94
207
  int num_added_edges; /* number of added edges (not including edges to t-groups) */
95
208
  int nMaxAddEdges; /* max. number edges of add to each atom (not including edges to t-groups) */
96
209
 
@@ -125,6 +238,10 @@ typedef struct BalancedNetworkStructure {
125
238
  } BN_STRUCT;
126
239
 
127
240
  /********************* BN_DATA *******************************************/
241
+ typedef enum tagBnsRadSrchMode {
242
+ RAD_SRCH_NORM = 0, /* normal search for normalization */
243
+ RAD_SRCH_FROM_FICT = 1 /* search from fict. vertices to atoms */
244
+ } BRS_MODE;
128
245
  typedef struct BalancedNetworkData {
129
246
  Vertex *BasePtr; /*[MAX_VERTEX]; pointer toward the base of C(v) */
130
247
  Edge *SwitchEdge; /*[MAX_VERTEX]; a pair of vertices and an edge, implemented here as [*][2] array */
@@ -135,7 +252,14 @@ typedef struct BalancedNetworkData {
135
252
  Vertex *Pv; /*[MAX_VERTEX/2+1] */
136
253
  int max_num_vertices; /* allocation size of all except Pu, Pv */
137
254
  int max_len_Pu_Pv; /* allocation size of Pu and Pv */
138
-
255
+ #if( BNS_RAD_SEARCH == 1 )
256
+ Vertex *RadEndpoints; /*[MAX_VERTEX*/
257
+ int nNumRadEndpoints;
258
+ EdgeIndex *RadEdges;
259
+ int nNumRadEdges;
260
+ int nNumRadicals;
261
+ BRS_MODE bRadSrchMode; /* 1 => connect fict. vertices-radicals to the accessible atoms */
262
+ #endif
139
263
  } BN_DATA;
140
264
 
141
265
  /* internal array size */
@@ -187,6 +311,16 @@ typedef struct tagBNS_FLOW_CHANGES {
187
311
  #define ALT_PATH_MODE_ADD2H_TST 8 /* test-add 2 H along alt. path A=-=B => AH-=-BH; restore changed bonds */
188
312
  #define ALT_PATH_MODE_REM_PROTON 9 /* remove proton, adjust bonds, charges, H-counts 2004-03-05 */
189
313
 
314
+ typedef U_SHORT bitWord;
315
+ #define BIT_WORD_MASK ((bitWord)~0)
316
+
317
+ typedef struct tagNodeSet {
318
+ bitWord **bitword;
319
+ int num_set; /* number of sets */
320
+ int len_set; /* number of bitWords in each set */
321
+ } NodeSet;
322
+
323
+
190
324
  #ifndef INCHI_ALL_CPP
191
325
  #ifdef __cplusplus
192
326
  extern "C" {
@@ -194,6 +328,47 @@ extern "C" {
194
328
  #endif
195
329
 
196
330
 
331
+ /*********************************************************************************
332
+ bChangeFlow:
333
+ 1 => change flow inside the BNS search
334
+ 3 => change flow inside the BNS search and undo the flow change in the BNS structure here
335
+ 4 => change bonds in the structure according to the flow
336
+ 8 => make altern. bonds in the structure
337
+
338
+ Note: (bChangeFlow & 1) == 1 is needed for multiple runs
339
+ **********************************************************************************/
340
+
341
+ /* "EF" = "Edge Flow" */
342
+ #define BNS_EF_CHNG_FLOW 1 /* change Balanced Network (BN) flow inside the BNS search */
343
+ #define BNS_EF_RSTR_FLOW 2 /* undo BN flow changes after BNS */
344
+ #define BNS_EF_CHNG_RSTR (BNS_EF_CHNG_FLOW | BNS_EF_RSTR_FLOW)
345
+ #define BNS_EF_CHNG_BONDS 4 /* change bonds in the structure according to the BN flow */
346
+ #define BNS_EF_ALTR_BONDS 8 /* make altern. bonds in the structure if the flow has changed */
347
+ #define BNS_EF_UPD_RAD_ORI 16 /* update BN flow0 & Atom radical values:
348
+ flow0 := flow, radical:=st_cap - st_flow */
349
+ #define BNS_EF_SET_NOSTEREO 32 /* in combination with BNS_EF_ALTR_BONDS only:
350
+ ALT12 bond cannot be stereogenic */
351
+ #define BNS_EF_UPD_H_CHARGE 64 /* update charges and H-counts according to change flow to c- and t-group vertices */
352
+
353
+ #define BNS_EF_SAVE_ALL (BNS_EF_CHNG_FLOW | BNS_EF_CHNG_BONDS | BNS_EF_UPD_RAD_ORI)
354
+ #define BNS_EF_ALTR_NS (BNS_EF_ALTR_BONDS | BNS_EF_SET_NOSTEREO)
355
+
356
+ #define BNS_EF_RAD_SRCH 128 /* search for rafical paths closures */
357
+
358
+
359
+
360
+ int SetBitCreate( void );
361
+ int NodeSetCreate( NodeSet *pSet, int n, int L );
362
+ void NodeSetFree( NodeSet *pSet );
363
+
364
+ int IsNodeSetEmpty( NodeSet *cur_nodes, int k);
365
+ int DoNodeSetsIntersect( NodeSet *cur_nodes, int k1, int k2);
366
+ void AddNodeSet2ToNodeSet1( NodeSet *cur_nodes, int k1, int k2);
367
+ void NodeSetFromRadEndpoints( NodeSet *cur_nodes, int k, /*Node *v*/ Vertex RadEndpoints[], int num_v);
368
+ void RemoveFromNodeSet( NodeSet *cur_nodes, int k, Vertex v[], int num_v);
369
+ int AddNodesToRadEndpoints( NodeSet *cur_nodes, int k, Vertex RadEndpoints[], Vertex vRad, int nStart, int nLen );
370
+
371
+
197
372
  int nExists2AtMoveAltPath( struct BalancedNetworkStructure *pBNS, struct BalancedNetworkData *pBD,
198
373
  struct BN_AtomsAtTautGroup *pAATG, inp_ATOM *at, int num_atoms,
199
374
  int jj2, int jj1, struct tagSaltChargeCandidate *s_candidate, int nNumCandidates,
@@ -221,6 +396,32 @@ int ReconnectTestAtomToTGroup( struct BalancedNetworkStructure *pBNS, int v1, in
221
396
 
222
397
  int bIsHardRemHCandidate( inp_ATOM *at, int i, int *cSubType );
223
398
 
399
+ /* moved from ichi_bns.c 2005-08-23 */
400
+ int RunBalancedNetworkSearch( BN_STRUCT *pBNS, BN_DATA *pBD, int bChangeFlow );
401
+ BN_STRUCT* AllocateAndInitBnStruct( inp_ATOM *at, int num_atoms, int nMaxAddAtoms, int nMaxAddEdges, int max_altp, int *num_changed_bonds );
402
+ BN_STRUCT* DeAllocateBnStruct( BN_STRUCT *pBNS );
403
+ int ReInitBnStructAltPaths( BN_STRUCT *pBNS );
404
+ int ReInitBnStructForMoveableAltBondTest( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms );
405
+ void ClearAllBnDataVertices( Vertex *v, Vertex value, int size );
406
+ void ClearAllBnDataEdges( Edge *e, Vertex value, int size );
407
+ BN_DATA *DeAllocateBnData( BN_DATA *pBD );
408
+ BN_DATA *AllocateAndInitBnData( int max_num_vertices );
409
+ int ReInitBnData( BN_DATA *pBD );
410
+ int SetForbiddenEdges( BN_STRUCT *pBNS, inp_ATOM *at, int num_atoms, int edge_forbidden_mask );
411
+ /* main function: find augmenting path */
412
+ int BalancedNetworkSearch ( BN_STRUCT* pBNS, BN_DATA *pBD, int bChangeFlow );
413
+
414
+ int SetRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode );
415
+ int SetRadEndpoints2( BN_STRUCT *pBNS, BN_DATA *pBD, BRS_MODE bRadSrchMode );
416
+
417
+ int RemoveRadEndpoints( BN_STRUCT *pBNS, BN_DATA *pBD, inp_ATOM *at );
418
+
419
+ int AddRemoveProtonsRestr( inp_ATOM *at, int num_atoms, int *num_protons_to_add,
420
+ int nNumProtAddedByRestr, INCHI_MODE bNormalizationFlags,
421
+ int num_tg, int nChargeRevrs, int nChargeInChI );
422
+ int AddRemoveIsoProtonsRestr( inp_ATOM *at, int num_atoms, NUM_H num_protons_to_add[], int num_tg );
423
+
424
+
224
425
  #ifndef INCHI_ALL_CPP
225
426
  #ifdef __cplusplus
226
427
  }
@@ -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.00
6
- * April 13, 2005
5
+ * Software version 1.01
6
+ * July 21, 2006
7
7
  * Developed at NIST
8
8
  */
9
9
 
@@ -13,6 +13,7 @@
13
13
  #include <ctype.h>
14
14
  #include <limits.h>
15
15
 
16
+ /* #define CHECK_WIN32_VC_HEAP */
16
17
  #include "mode.h"
17
18
 
18
19
  #include "ichi.h"
@@ -43,25 +44,6 @@
43
44
  /* #define INCHI_CANON_USE_HASH */
44
45
  #define INCHI_CANON_MIN
45
46
 
46
- #if ( defined(_DEBUG) && 0 )
47
- #include <malloc.h>
48
- #define HEAPCHK \
49
- do {\
50
- int heapstatus = _heapchk(); \
51
- switch( heapstatus ) \
52
- { \
53
- case _HEAPBADBEGIN: \
54
- printf( "ERROR - bad start of heap %d\n", __LINE__ ); \
55
- break; \
56
- case _HEAPBADNODE: \
57
- printf( "ERROR - bad node in heap %d\n", __LINE__ ); \
58
- break; \
59
- } \
60
- } while(0);
61
- #else
62
- #define HEAPCHK
63
- #endif
64
-
65
47
  /****************************************************************/
66
48
  #ifdef INCHI_CANON_USE_HASH
67
49
  typedef unsigned long U_INT_32;
@@ -70,8 +52,10 @@ typedef U_INT_32 CtHash;
70
52
  CtHash hash_mark_bit;
71
53
  #endif
72
54
 
55
+ /* -- moved to ichi_bns.h --
73
56
  typedef U_SHORT bitWord;
74
57
  #define BIT_WORD_MASK ((bitWord)~0)
58
+ */
75
59
 
76
60
  static bitWord *bBit = NULL;
77
61
  static int num_bit = 0;
@@ -100,12 +84,13 @@ typedef struct tagCell {
100
84
  int prev; /* position of the previously returned cell element */
101
85
  } Cell;
102
86
 
87
+ #ifdef NEVER /* moved to ichi_bns.h */
103
88
  typedef struct tagNodeSet {
104
89
  bitWord **bitword;
105
90
  int num_set; /* number of sets */
106
91
  int len_set; /* number of bitWords in each set */
107
92
  } NodeSet;
108
-
93
+ #endif
109
94
 
110
95
  typedef struct tagTransposition {
111
96
  AT_NUMB *nAtNumb;
@@ -178,7 +163,6 @@ int CanonGraph( int n, int n_tg, int n_max, int bDigraph, Graph *G, Partition pi
178
163
  AT_RANK *nSymmRank, AT_RANK *nCanonRank, AT_NUMB *nAtomNumberCanon,
179
164
  CANON_DATA *pCD, CANON_COUNTS *pCC,
180
165
  ConTable **pp_zb_rho_inp, ConTable **pp_zb_rho_out );
181
- int SetBitCreate( void );
182
166
 
183
167
  void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
184
168
  ConTable *Ct, int k, int n, int n_tg );
@@ -194,7 +178,7 @@ int CtFullCompareLayers( kLeast *kLeastForLayer );
194
178
  int CtCompareLayersGetFirstDiff( kLeast *kLeast_rho, int nOneAdditionalLayer,
195
179
  int *L_rho, int *I_rho, int *k_rho );
196
180
  int CtPartCompareLayers( kLeast *kLeast_rho, int L_rho_fix_prev, int nOneAdditionalLayer );
197
- void UpdateCompareLayers( kLeast kLeastForLayer[], int hz );
181
+ void UpdateCompareLayers( kLeast kLeastForLayer[], int hzz );
198
182
  int GetOneAdditionalLayer( CANON_DATA *pCD, ConTable *pzb_rho_fix );
199
183
 
200
184
  void CleanNumH( NUM_H *NumH, int len );
@@ -227,8 +211,6 @@ void UnorderedPartitionFree( UnorderedPartition *p );
227
211
  int UnorderedPartitionCreate( UnorderedPartition *p, int n );
228
212
  void CTableFree( ConTable *Ct );
229
213
  int CTableCreate( ConTable *Ct, int n, CANON_DATA *pCD );
230
- int NodeSetCreate( NodeSet *pSet, int n, int L );
231
- void NodeSetFree( NodeSet *pSet );
232
214
  void TranspositionFree( Transposition *p );
233
215
  int TranspositionCreate( Transposition *p, int n );
234
216
  void TranspositionGetMcrAndFixSetAndUnorderedPartition( Transposition *gamma, NodeSet *McrSet, NodeSet *FixSet, int n, int l, UnorderedPartition *p );
@@ -484,6 +466,7 @@ void NodeSetFree( NodeSet *pSet )
484
466
  inchi_free( pSet->bitword[0] );
485
467
  }
486
468
  inchi_free( pSet->bitword );
469
+ pSet->bitword = NULL;
487
470
  }
488
471
  }
489
472
  /****************************************************************/
@@ -605,7 +588,7 @@ void UnorderedPartitionMakeDiscrete( UnorderedPartition *p, int n)
605
588
  p->equ2[i] = (AT_NUMB)i;
606
589
  /* p->next[i] = INFINITY; */
607
590
  }
608
- HEAPCHK
591
+ INCHI_HEAPCHK
609
592
  }
610
593
  /****************************************************************/
611
594
  int PartitionCreate( Partition *p, int n)
@@ -638,11 +621,11 @@ int PartitionIsDiscrete( Partition *p, int n)
638
621
  AT_RANK r;
639
622
  for ( i = 0, r = 1; i < n; i ++, r ++ ) {
640
623
  if ( r != (rank_mask_bit & p->Rank[p->AtNumber[i]]) ) {
641
- HEAPCHK
624
+ INCHI_HEAPCHK
642
625
  return 0;
643
626
  }
644
627
  }
645
- HEAPCHK
628
+ INCHI_HEAPCHK
646
629
  return 1;
647
630
  }
648
631
  /****************************************************************/
@@ -665,12 +648,12 @@ int PartitionGetFirstCell( Partition *p, Cell *baseW, int k, int n )
665
648
  i ++ )
666
649
  ;
667
650
  W->next = i;
668
- HEAPCHK
651
+ INCHI_HEAPCHK
669
652
  return (W->next - W->first);
670
653
  }
671
654
  W->first = INFINITY;
672
655
  W->next = 0;
673
- HEAPCHK
656
+ INCHI_HEAPCHK
674
657
  return 0;
675
658
  }
676
659
  /****************************************************************/
@@ -680,7 +663,7 @@ void CellMakeEmpty( Cell *baseW, int k )
680
663
  baseW[k].first = INFINITY;
681
664
  baseW[k].next = 0;
682
665
  baseW[k].prev = -1;
683
- HEAPCHK
666
+ INCHI_HEAPCHK
684
667
  }
685
668
  /****************************************************************/
686
669
  void NodeSetFromVertices( NodeSet *cur_nodes, int l, Node *v, int num_v)
@@ -695,7 +678,7 @@ void NodeSetFromVertices( NodeSet *cur_nodes, int l, Node *v, int num_v)
695
678
  j = (int)v[i]-1;
696
679
  Bits[ j / num_bit ] |= bBit[ j % num_bit ];
697
680
  }
698
- HEAPCHK
681
+ INCHI_HEAPCHK
699
682
  }
700
683
  /****************************************************************/
701
684
  int AllNodesAreInSet( NodeSet *cur_nodes, int lcur_nodes, NodeSet *set, int lset )
@@ -707,11 +690,11 @@ int AllNodesAreInSet( NodeSet *cur_nodes, int lcur_nodes, NodeSet *set, int lse
707
690
  /* find any BitsNode[i] bit not in BitsSet[i] */
708
691
  for ( i = 0; i < n; i ++ ) {
709
692
  if ( BitsNode[i] & ~BitsSet[i] ) {
710
- HEAPCHK
693
+ INCHI_HEAPCHK
711
694
  return 0;
712
695
  }
713
696
  }
714
- HEAPCHK
697
+ INCHI_HEAPCHK
715
698
  return 1;
716
699
  }
717
700
  /****************************************************************/
@@ -738,7 +721,108 @@ void PartitionGetMcrAndFixSet( Partition *p, NodeSet *Mcr, NodeSet *Fix, int n,
738
721
  McrBits[j1 / num_bit] |= bBit[j1 % num_bit];
739
722
  }
740
723
  }
741
- HEAPCHK
724
+ INCHI_HEAPCHK
725
+ }
726
+ /************* used in ichi_bns.c ********************************/
727
+ void NodeSetFromRadEndpoints( NodeSet *cur_nodes, int k, /*Node *v*/ Vertex RadEndpoints[], int num_v)
728
+ {
729
+ bitWord *Bits = cur_nodes->bitword[k];
730
+ int len = cur_nodes->len_set*sizeof(bitWord);
731
+ int i, j;
732
+
733
+ memset( Bits, 0, len );
734
+
735
+ for ( i = 1; i < num_v; i += 2 ) {
736
+ j = (int)RadEndpoints[i];
737
+ Bits[ j / num_bit ] |= bBit[ j % num_bit ];
738
+ }
739
+ }
740
+ /************* used in ichi_bns.c ********************************/
741
+ void RemoveFromNodeSet( NodeSet *cur_nodes, int k, Vertex v[], int num_v)
742
+ {
743
+ if ( cur_nodes->bitword ) {
744
+ bitWord *Bits = cur_nodes->bitword[k];
745
+ /*int len = cur_nodes->len_set*sizeof(bitWord);*/
746
+ int i, j;
747
+
748
+ for ( i = 0; i < num_v; i ++ ) {
749
+ j = (int) v[i];
750
+ Bits[ j / num_bit ] &= ~bBit[ j % num_bit ];
751
+ }
752
+ }
753
+ }
754
+ /************* used in ichi_bns.c ********************************/
755
+ int DoNodeSetsIntersect( NodeSet *cur_nodes, int k1, int k2)
756
+ {
757
+ if ( cur_nodes->bitword ) {
758
+ bitWord *Bits1 = cur_nodes->bitword[k1];
759
+ bitWord *Bits2 = cur_nodes->bitword[k2];
760
+ int len = cur_nodes->len_set;
761
+ int i;
762
+
763
+ for ( i = 0; i < len; i ++ ) {
764
+ if ( Bits1[i] & Bits2[i] )
765
+ return 1;
766
+ }
767
+ }
768
+ return 0;
769
+ }
770
+ /************* used in ichi_bns.c ********************************/
771
+ int IsNodeSetEmpty( NodeSet *cur_nodes, int k)
772
+ {
773
+ if ( cur_nodes->bitword ) {
774
+ bitWord *Bits = cur_nodes->bitword[k];
775
+ int len = cur_nodes->len_set;
776
+ int i;
777
+
778
+ for ( i = 0; i < len; i ++ ) {
779
+ if ( Bits[i] )
780
+ return 0;
781
+ }
782
+ }
783
+ return 1;
784
+ }
785
+ /************* used in ichi_bns.c ********************************/
786
+ void AddNodeSet2ToNodeSet1( NodeSet *cur_nodes, int k1, int k2)
787
+ {
788
+ if ( cur_nodes->bitword ) {
789
+ bitWord *Bits1 = cur_nodes->bitword[k1];
790
+ bitWord *Bits2 = cur_nodes->bitword[k2];
791
+ int len = cur_nodes->len_set;
792
+ int i;
793
+
794
+ for ( i = 0; i < len; i ++ ) {
795
+ Bits1[i] |= Bits2[i];
796
+ }
797
+ }
798
+ }
799
+ /************* used in ichi_bns.c ********************************/
800
+ int AddNodesToRadEndpoints( NodeSet *cur_nodes, int k, Vertex RadEndpoints[], Vertex vRad, int nStart, int nLen )
801
+ {
802
+ int n = nStart;
803
+ if ( cur_nodes->bitword ) {
804
+ bitWord *Bits = cur_nodes->bitword[k];
805
+ int len = cur_nodes->len_set;
806
+ int i, j;
807
+ Vertex v;
808
+
809
+ for ( i = 0, v = 0; i < len; i ++ ) {
810
+ if ( Bits[i] ) {
811
+ for ( j = 0; j < num_bit; j ++, v ++ ) {
812
+ if ( Bits[i] & bBit[j] ) {
813
+ if ( n >= nLen ) {
814
+ return -1; /* overflow */
815
+ }
816
+ RadEndpoints[n ++] = vRad;
817
+ RadEndpoints[n ++] = v;
818
+ }
819
+ }
820
+ } else {
821
+ v += num_bit;
822
+ }
823
+ }
824
+ }
825
+ return n;
742
826
  }
743
827
  /****************************************************************/
744
828
  void PartitionGetTransposition( Partition *pFrom, Partition *pTo, int n, Transposition *gamma )
@@ -747,7 +831,7 @@ void PartitionGetTransposition( Partition *pFrom, Partition *pTo, int n, Transpo
747
831
  for ( i = 0; i < n; i ++ ) {
748
832
  gamma->nAtNumb[(int)pFrom->AtNumber[i]] =pTo->AtNumber[i];
749
833
  }
750
- HEAPCHK
834
+ INCHI_HEAPCHK
751
835
  }
752
836
  /**************************************************************************************/
753
837
  /* Get minimal set (class) representative and partially compress the partitioning */
@@ -755,7 +839,7 @@ void PartitionGetTransposition( Partition *pFrom, Partition *pTo, int n, Transpo
755
839
  AT_RANK nGetMcr2( AT_RANK *nEqArray, AT_RANK n )
756
840
  {
757
841
  AT_RANK n1, n2, mcr; /* recursive version is much shorter. */
758
- HEAPCHK
842
+ INCHI_HEAPCHK
759
843
  n1=nEqArray[(int)n];
760
844
  if ( n == n1 ) {
761
845
  return n;
@@ -771,7 +855,7 @@ AT_RANK nGetMcr2( AT_RANK *nEqArray, AT_RANK n )
771
855
  nEqArray[(int)n1]=mcr;
772
856
  n1 = n2;
773
857
  }
774
- HEAPCHK
858
+ INCHI_HEAPCHK
775
859
  return ( mcr );
776
860
  }
777
861
  /**************************************************************************************/
@@ -782,22 +866,22 @@ int nJoin2Mcrs2( AT_RANK *nEqArray, AT_RANK n1, AT_RANK n2 )
782
866
  n2 = nGetMcr2( nEqArray, n2 );
783
867
  if ( n1 < n2 ) {
784
868
  nEqArray[n2] = n1;
785
- HEAPCHK
869
+ INCHI_HEAPCHK
786
870
  return 1; /* a change has been made */
787
871
  }
788
872
  if ( n2 < n1 ) {
789
873
  nEqArray[n1] = n2;
790
- HEAPCHK
874
+ INCHI_HEAPCHK
791
875
  return 1; /* a change has been made */
792
876
  }
793
- HEAPCHK
877
+ INCHI_HEAPCHK
794
878
  return 0; /* no changes */
795
879
  }
796
880
  /****************************************************************/
797
881
  Node GetUnorderedPartitionMcrNode( UnorderedPartition *p1, Node v )
798
882
  {
799
883
  Node ret = (Node)(1+ nGetMcr2( p1->equ2, (AT_RANK)(v-1) ));
800
- HEAPCHK
884
+ INCHI_HEAPCHK
801
885
  return ret;
802
886
  }
803
887
  /****************************************************************/
@@ -812,7 +896,7 @@ int UnorderedPartitionJoin( UnorderedPartition *p1, UnorderedPartition *p2, int
812
896
  }
813
897
  nNumChanges += nJoin2Mcrs2(p2->equ2, (AT_NUMB)i, (AT_NUMB)j );
814
898
  }
815
- HEAPCHK
899
+ INCHI_HEAPCHK
816
900
  return nNumChanges;
817
901
  }
818
902
  /****************************************************************/
@@ -851,10 +935,10 @@ void PartitionCopy( Partition *To, Partition *From, int n )
851
935
  for ( i = 0; i < n; i ++ ) {
852
936
  To->Rank[i] &= rank_mask_bit;
853
937
  }
854
- HEAPCHK
938
+ INCHI_HEAPCHK
855
939
  }
856
940
  /****************************************************************/
857
- /* makes new equitable partition (p+1) out of p */
941
+ /* makes new equitable partition (p+1) out of p; first reduce the rank of vertex v */
858
942
  int PartitionColorVertex( Graph *G, Partition *p, Node v, int n, int n_tg, int n_max, int bDigraph, int nNumPrevRanks )
859
943
  {
860
944
  int nNumNewRanks, i, j;
@@ -869,29 +953,31 @@ int PartitionColorVertex( Graph *G, Partition *p, Node v, int n, int n_tg, int n
869
953
  p[i].Rank = (AT_RANK *)inchi_malloc(n_max*sizeof(p[0].Rank[0]));
870
954
  }
871
955
  if ( !p[i].AtNumber || !p[i].Rank ) {
872
- HEAPCHK
956
+ INCHI_HEAPCHK
873
957
  return CT_OUT_OF_RAM;
874
958
  }
875
959
  }
876
960
  PartitionCopy( p+1, p, n_tg );
877
961
  sv = v-1; /* atom number we are looking for */
878
962
  if ( sv >= (AT_NUMB) n_tg ) {
879
- HEAPCHK
963
+ INCHI_HEAPCHK
880
964
  return CT_CANON_ERR; /* !!! severe program error: sv not found !!! */
881
965
  }
882
966
  rv = p[1].Rank[(int)sv]; /* rank of this atom */
883
- /* locate sv */
967
+ /* second, locate sv among all vertices that have same rank as v */
968
+ s = n_max + 1; /* always greater than sv; this initialization is needed only to keep the compiler happy */
884
969
  for ( j = (int)rv-1; 0 <= j && rv == (r = p[1].Rank[(int)(s=p[1].AtNumber[j])]) && s != sv; j -- )
885
970
  ;
886
971
  if ( s != sv ) {
887
- HEAPCHK
972
+ INCHI_HEAPCHK
888
973
  return CT_CANON_ERR; /* !!! severe program error: sv not found !!! */
889
974
  }
890
975
  /* shift preceding atom numbers to the right to fill the gap after removing sv */
976
+ r = rv-1; /* initialization only to keep compiler happy */
891
977
  for ( i = j--; 0 <= j && rv == (r = p[1].Rank[(int)(s=p[1].AtNumber[j])]); i = j, j -- ) {
892
978
  p[1].AtNumber[i] = s;
893
979
  }
894
- r = (i > 0)? r+1:1;
980
+ r = (i > 0)? (r+1):1; /* new reduced rank = (next lower rank)+1 or 1 */
895
981
  /* insert sv and adjust its rank */
896
982
  p[1].AtNumber[i] = sv;
897
983
  p[1].Rank[(int)sv] = r;
@@ -920,7 +1006,7 @@ int PartitionColorVertex( Graph *G, Partition *p, Node v, int n, int n_tg, int n
920
1006
  nNumPrevRanks+1, p[1].Rank, p[2].Rank /* temp array */,
921
1007
  p[1].AtNumber, &lNumNeighListIter );
922
1008
  }
923
- HEAPCHK
1009
+ INCHI_HEAPCHK
924
1010
 
925
1011
  return nNumNewRanks;
926
1012
  }
@@ -1048,7 +1134,7 @@ Node CellGetMinNode( Partition *p, Cell *W, Node v, CANON_DATA *pCD )
1048
1134
  }
1049
1135
  }
1050
1136
  if ( uMinAtNumb != INFINITY ) uMinAtNumb ++;
1051
- HEAPCHK
1137
+ INCHI_HEAPCHK
1052
1138
  return uMinAtNumb;
1053
1139
  }
1054
1140
  /****************************************************************/
@@ -1062,7 +1148,7 @@ int CellGetNumberOfNodes( Partition *p, Cell *W )
1062
1148
  num++;
1063
1149
  }
1064
1150
  }
1065
- HEAPCHK
1151
+ INCHI_HEAPCHK
1066
1152
  return num;
1067
1153
  }
1068
1154
  /****************************************************************/
@@ -1077,12 +1163,12 @@ int CellIntersectWithSet( Partition *p, Cell *W, NodeSet *Mcr, int l )
1077
1163
  }
1078
1164
  for ( i = first, k = 0; i < next; i ++ ) {
1079
1165
  j = (int)p->AtNumber[i];
1080
- if ( !(McrBits[ j / num_bit ] & bBit[ j % num_bit ]) ) {
1166
+ if ( !(McrBits[ j / num_bit ] & bBit[ j % num_bit ]) ) { /* BC: reading uninit memory ???-not examined yet */
1081
1167
  k += !(p->Rank[j] & rank_mark_bit); /* for testing only */
1082
1168
  p->Rank[j] |= rank_mark_bit;
1083
1169
  }
1084
1170
  }
1085
- HEAPCHK
1171
+ INCHI_HEAPCHK
1086
1172
  return k;
1087
1173
  }
1088
1174
  /****************************************************************/
@@ -1099,7 +1185,7 @@ void CtPartClear( ConTable *Ct, int k )
1099
1185
  Ct->lenCt = start;
1100
1186
  Ct->lenPos = k;
1101
1187
 
1102
- HEAPCHK
1188
+ INCHI_HEAPCHK
1103
1189
  }
1104
1190
  /**********************************************************************************/
1105
1191
  /* Sort neighbors according to ranks in ascending order */
@@ -1120,7 +1206,7 @@ void insertions_sort_NeighList_AT_NUMBERS2( NEIGH_LIST base, AT_RANK *nRank, AT_
1120
1206
  }
1121
1207
  }
1122
1208
  }
1123
- HEAPCHK
1209
+ INCHI_HEAPCHK
1124
1210
  }
1125
1211
  /****************************************************************/
1126
1212
  /* may need previous Lambda */
@@ -1139,7 +1225,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1139
1225
  count ++;
1140
1226
 
1141
1227
 
1142
- HEAPCHK
1228
+ INCHI_HEAPCHK
1143
1229
 
1144
1230
  k --;
1145
1231
  if ( k ) {
@@ -1174,7 +1260,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1174
1260
  }
1175
1261
  }
1176
1262
 
1177
- HEAPCHK
1263
+ INCHI_HEAPCHK
1178
1264
 
1179
1265
  /****************** well-defined part of base hydrogen atoms *******************/
1180
1266
  if ( pCD->NumH && Ct->NumH ) {
@@ -1193,7 +1279,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1193
1279
  Ct->lenNumH = 0;
1194
1280
  }
1195
1281
 
1196
- HEAPCHK
1282
+ INCHI_HEAPCHK
1197
1283
 
1198
1284
  /****************** well-defined part of fixed hydrogen atoms *******************/
1199
1285
  if ( pCD->NumHfixed && Ct->NumHfixed ) {
@@ -1201,7 +1287,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1201
1287
  for ( j = startAtOrd; j < nn; j ++ ) {
1202
1288
  Ct->NumHfixed[j] = pCD->NumHfixed[p->AtNumber[j]];
1203
1289
 
1204
- HEAPCHK
1290
+ INCHI_HEAPCHK
1205
1291
 
1206
1292
  }
1207
1293
  /* Ct->lenNumHfixed = nn; */
@@ -1209,7 +1295,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1209
1295
  ;/* Ct->lenNumHfixed = 0; */
1210
1296
  }
1211
1297
 
1212
- HEAPCHK
1298
+ INCHI_HEAPCHK
1213
1299
 
1214
1300
  /****************** well-defined part of isotopic keys ***************************/
1215
1301
  if ( pCD->iso_sort_key && Ct->iso_sort_key ) {
@@ -1221,7 +1307,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1221
1307
  Ct->len_iso_sort_key = 0;
1222
1308
  }
1223
1309
 
1224
- HEAPCHK
1310
+ INCHI_HEAPCHK
1225
1311
 
1226
1312
  /****************** well-defined part of isotopic iso_exchg_atnos ***************************/
1227
1313
  if ( pCD->iso_exchg_atnos && Ct->iso_exchg_atnos ) {
@@ -1233,7 +1319,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1233
1319
  Ct->len_iso_exchg_atnos = 0;
1234
1320
  }
1235
1321
 
1236
- HEAPCHK
1322
+ INCHI_HEAPCHK
1237
1323
  /******** well-defined part of isotopic keys for fixed hydrogen atoms ************/
1238
1324
  #if ( USE_ISO_SORT_KEY_HFIXED == 1 )
1239
1325
  if ( pCD->iso_sort_key_Hfixed && Ct->iso_sort_key_Hfixed ) {
@@ -1247,7 +1333,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1247
1333
  }
1248
1334
  #endif
1249
1335
 
1250
- HEAPCHK
1336
+ INCHI_HEAPCHK
1251
1337
 
1252
1338
  Ct->lenCt = startCtbl; /* not aways increases */
1253
1339
  Ct->nextCtblPos[k] = startCtbl;
@@ -1270,7 +1356,7 @@ void CtPartFill( Graph *G, CANON_DATA *pCD, Partition *p,
1270
1356
  Ct->hash[k] = hash;
1271
1357
  #endif
1272
1358
 
1273
- HEAPCHK
1359
+ INCHI_HEAPCHK
1274
1360
  }
1275
1361
  /****************************************************************/
1276
1362
  void CtPartInfinity( ConTable *Ct, S_CHAR *cmp, int k )
@@ -1291,7 +1377,7 @@ void CtPartInfinity( ConTable *Ct, S_CHAR *cmp, int k )
1291
1377
  if ( !startCtbl || Ct->Ctbl[startCtbl-1] != EMPTY_CT ) {
1292
1378
  Ct->Ctbl[startCtbl] = EMPTY_CT;
1293
1379
  }
1294
- HEAPCHK
1380
+ INCHI_HEAPCHK
1295
1381
  }
1296
1382
  /****************************************************************/
1297
1383
  /* Return value:
@@ -1328,7 +1414,7 @@ int CtPartCompare( ConTable *Ct1, ConTable *Ct2, S_CHAR *cmp,
1328
1414
  {
1329
1415
  int startCt1, endCt1, startCt2, endCt2; /*endCt,*/
1330
1416
  int startAt1, endAt1, startAt2, endAt2; /*endCt,*/
1331
- int midCt /* end of atoms only Ct */, midNumH /* end of atoms only NumH */, maxVert;
1417
+ int midCt /* end of atoms only Ct */, midNumH=0 /* end of atoms only NumH */, maxVert;
1332
1418
  int diff, i, k1, k2, lenNumH, len_iso_sort_key, /*mid_iso_sort_key,*/ midAt;
1333
1419
  int nLayer = 0;
1334
1420
 
@@ -1348,7 +1434,7 @@ int CtPartCompare( ConTable *Ct1, ConTable *Ct2, S_CHAR *cmp,
1348
1434
 
1349
1435
  meaning:
1350
1436
  ========
1351
- abs(kLeastForLayer[nLayer]) is the greatest level k at which
1437
+ abs(kLeastForLayer[nLayer].k) is the greatest level k at which
1352
1438
  difference at layer nLayer are zeroes of hidden by differences in smaller nLayer.
1353
1439
 
1354
1440
  "Hidden by difference in smaller level" means that nLayer of comparison
@@ -1716,7 +1802,7 @@ int CtFullCompare( ConTable *Ct1, ConTable *Ct2, int bOnlyCommon, int bSplitTaut
1716
1802
  int startCt1, endCt1, startCt2, endCt2; /*endCt,*/
1717
1803
  int startAt1, endAt1, startAt2, endAt2; /*endCt,*/
1718
1804
  int midCt /* end of atoms only in Ctbl */,
1719
- midNumH /* end of atoms only NumH */,
1805
+ midNumH = 0 /* end of atoms only NumH */,
1720
1806
  midAt /* end of atoms only */;
1721
1807
  int diff, i, k1, k2, lenNumH1, lenNumH2, lenNumH, maxVert /* min num atoms */;
1722
1808
  int len_iso_sort_key1, len_iso_sort_key2, len_iso_sort_key /*, mid_iso_sort_key*/;
@@ -1941,12 +2027,12 @@ int CtPartCompareLayers( kLeast *kLeast_rho, int L_rho_fix_prev, int nOneAdditio
1941
2027
  return 0;
1942
2028
  }
1943
2029
  /****************************************************************/
1944
- void UpdateCompareLayers( kLeast kLeastForLayer[], int hz )
2030
+ void UpdateCompareLayers( kLeast kLeastForLayer[], int hzz )
1945
2031
  {
1946
2032
  int i;
1947
2033
  if ( kLeastForLayer ) {
1948
2034
  for ( i = 0; i < MAX_LAYERS; i ++ ) {
1949
- if ( abs(kLeastForLayer[i].k) >= hz ) {
2035
+ if ( abs(kLeastForLayer[i].k) >= hzz ) {
1950
2036
  kLeastForLayer[i].k = 0;
1951
2037
  kLeastForLayer[i].i = 0;
1952
2038
  }
@@ -2061,7 +2147,7 @@ void CtPartCopy( ConTable *Ct1 /* to */, ConTable *Ct2 /* from */, int k )
2061
2147
  Ct1->hash[k] = Ct2->hash[k];
2062
2148
  #endif
2063
2149
  Ct1->lenPos = k+1;
2064
- HEAPCHK
2150
+ INCHI_HEAPCHK
2065
2151
  }
2066
2152
  /****************************************************************/
2067
2153
  void CtFullCopy( ConTable *Ct1, ConTable *Ct2 )
@@ -2128,7 +2214,7 @@ void TranspositionGetMcrAndFixSetAndUnorderedPartition( Transposition *gamma, No
2128
2214
  for ( i = 0; i < n; i ++ ) {
2129
2215
  gamma->nAtNumb[i] &= rank_mask_bit;
2130
2216
  }
2131
- HEAPCHK
2217
+ INCHI_HEAPCHK
2132
2218
  }
2133
2219
  /****************************************************************/
2134
2220
  int SetBitCreate( void )
@@ -2141,7 +2227,7 @@ int SetBitCreate( void )
2141
2227
  int i;
2142
2228
 
2143
2229
  if ( bBit ) {
2144
- HEAPCHK
2230
+ INCHI_HEAPCHK
2145
2231
  return 0; /* already created */
2146
2232
  }
2147
2233
 
@@ -2151,7 +2237,7 @@ int SetBitCreate( void )
2151
2237
  ;
2152
2238
  bBit = (bitWord*)inchi_calloc( num_bit, sizeof(bitWord));
2153
2239
  if ( !bBit ) {
2154
- HEAPCHK
2240
+ INCHI_HEAPCHK
2155
2241
  return -1; /* failed */
2156
2242
  }
2157
2243
  for ( i = 0, b1=1; i < num_bit; i++, b1 <<= 1 ) {
@@ -2168,7 +2254,7 @@ int SetBitCreate( void )
2168
2254
  ;
2169
2255
  hash_mark_bit = h1;
2170
2256
  #endif
2171
- HEAPCHK
2257
+ INCHI_HEAPCHK
2172
2258
  return 1;
2173
2259
  }
2174
2260
  /****************************************************************/
@@ -2177,10 +2263,10 @@ int SetBitFree( void )
2177
2263
  if ( bBit ) {
2178
2264
  inchi_free( bBit );
2179
2265
  bBit = NULL;
2180
- HEAPCHK
2266
+ INCHI_HEAPCHK
2181
2267
  return 1; /* success */
2182
2268
  }
2183
- HEAPCHK
2269
+ INCHI_HEAPCHK
2184
2270
  return 0; /* already destroyed */
2185
2271
  }
2186
2272
  #ifdef NEVER /* { how to renumber a graph */
@@ -2568,7 +2654,7 @@ int CanonGraph( int n, int n_tg, int n_max, int bDigraph, Graph *G, Partition pi
2568
2654
  Cell *W; /* W[i] is the first non-trivial cell of pi[i+1] */
2569
2655
  Node *v; /* v[i] is in W[i] to create T(G,pi,nu[i+1]) */
2570
2656
  Node tvc, tvh;
2571
- S_CHAR *e, *qzb=NULL;
2657
+ S_CHAR *e, *qzb=NULL; /* qzb = NULL always */
2572
2658
  /* current node CT */
2573
2659
  ConTable Lambda;
2574
2660
  /* first leaf CT */
@@ -2629,8 +2715,13 @@ int CanonGraph( int n, int n_tg, int n_max, int bDigraph, Graph *G, Partition pi
2629
2715
  ok &= UnorderedPartitionCreate( &theta_from_gamma, n_tg );
2630
2716
 
2631
2717
  ok &= (NULL != (W = (Cell*)inchi_calloc(n_tg, sizeof(W[0]))));
2718
+ ok &= (NULL != (v = (Node*)inchi_calloc(n_tg, sizeof(v[0]))));
2719
+ ok &= (NULL != (e = (S_CHAR*)inchi_calloc(n_tg, sizeof(e[0]))));
2720
+
2721
+ /*
2632
2722
  ok &= (NULL != (v = (Node*)inchi_calloc(n_tg, sizeof(W[0]))));
2633
2723
  ok &= (NULL != (e = (S_CHAR*)inchi_calloc(n_tg, sizeof(W[0]))));
2724
+ */
2634
2725
 
2635
2726
  /* ok &= (NULL != (qzb = (S_CHAR*)calloc(n_tg, sizeof(W[0])))); */
2636
2727
  ok &= CTableCreate( &Lambda, n, pCD );
@@ -2646,7 +2737,7 @@ int CanonGraph( int n, int n_tg, int n_max, int bDigraph, Graph *G, Partition pi
2646
2737
  ok &= PartitionCreate( &rho, n_tg);
2647
2738
  ok &= TranspositionCreate( &gamma, n_tg );
2648
2739
 
2649
- HEAPCHK
2740
+ INCHI_HEAPCHK
2650
2741
 
2651
2742
 
2652
2743
  /*L1:*/
@@ -2692,7 +2783,7 @@ int CanonGraph( int n, int n_tg, int n_max, int bDigraph, Graph *G, Partition pi
2692
2783
  e[k-1] = 0;
2693
2784
  */
2694
2785
  CtPartClear( &Lambda, 1 );
2695
- HEAPCHK
2786
+ INCHI_HEAPCHK
2696
2787
 
2697
2788
  /* L2: reach the first leaf and save it in zeta and rho */
2698
2789
  while( k ) {
@@ -2810,6 +2901,17 @@ L2:
2810
2901
  qzb_rho_fix = CtPartCompare( &Lambda, pzb_rho_fix, qzb, kLeast_rho_fix, k-1, 1, bSplitTautCompare );
2811
2902
  if ( !qzb_rho_fix && bRhoIsDiscrete ) {
2812
2903
  qzb_rho_fix = CtPartCompareLayers( kLeast_rho_fix, L_rho_fix_prev, nOneAdditionalLayer );
2904
+
2905
+ #if( FIX_ChCh_CONSTIT_CANON_BUG == 1 )
2906
+ if ( qzb_rho_fix ) {
2907
+ int L_rho_fix_diff = abs(qzb_rho_fix)-1;
2908
+ if ( L_rho_fix_diff < L_rho_fix_prev ||
2909
+ L_rho_fix_diff == L_rho_fix_prev && kLeast_rho_fix[L_rho_fix_diff].i < I_rho_fix_prev ) {
2910
+ qzb_rho_fix = L_rho_fix_diff+1; /* positive difference will be rejected */
2911
+ }
2912
+ }
2913
+ #endif
2914
+
2813
2915
  #if( bRELEASE_VERSION != 1 && defined(_DEBUG) )
2814
2916
  if ( qzb_rho_fix ) {
2815
2917
  int stop = 1; /* debug only */
@@ -2839,6 +2941,15 @@ L2:
2839
2941
  /* new code */
2840
2942
  if ( !qzb_rho && bRhoIsDiscrete ) {
2841
2943
  qzb_rho = CtPartCompareLayers( kLeast_rho, L_rho_fix_prev, 0 );
2944
+ #if( FIX_ChCh_CONSTIT_CANON_BUG == 1 )
2945
+ if ( qzb_rho ) {
2946
+ int L_rho_diff = abs(qzb_rho)-1;
2947
+ if ( L_rho_diff < L_rho_fix_prev ||
2948
+ L_rho_diff == L_rho_fix_prev && kLeast_rho[L_rho_diff].i < I_rho_fix_prev ) {
2949
+ qzb_rho = -(L_rho_diff+1); /* negative difference will be rejected */
2950
+ }
2951
+ }
2952
+ #endif
2842
2953
  }
2843
2954
  /* compare old results to new */
2844
2955
  #if( bRELEASE_VERSION != 1 && defined(_DEBUG) )
@@ -3207,7 +3318,7 @@ exit_function:
3207
3318
  }
3208
3319
 
3209
3320
  exit_error:
3210
- HEAPCHK
3321
+ INCHI_HEAPCHK
3211
3322
 
3212
3323
  UnorderedPartitionFree( &theta );
3213
3324
  UnorderedPartitionFree( &theta_from_gamma );
@@ -3786,7 +3897,7 @@ int GetBaseCanonRanking( int num_atoms, int num_at_tg, sp_ATOM* at[],
3786
3897
  if ( !(NeighList[TAUT_NON] = CreateNeighList( num_atoms, num_atoms, at_base, 0, NULL )) )
3787
3898
  goto exit_error_alloc;
3788
3899
  NeighList[TAUT_YES] = NULL;
3789
- HEAPCHK
3900
+ INCHI_HEAPCHK
3790
3901
  }
3791
3902
 
3792
3903
  /* avoid memory leaks in case of error */
@@ -4062,7 +4173,7 @@ int GetBaseCanonRanking( int num_atoms, int num_at_tg, sp_ATOM* at[],
4062
4173
  for ( i = 0; i < num_atoms; i ++ ) {
4063
4174
  if ( iso_sort_key_NoTautH[i] != iso_sort_key_NoTautH[nTempRank[nSymmRankNoTautH[i]-1]] ) {
4064
4175
  pCD[iOther].nCanonFlags |= CANON_FLAG_ISO_ONLY_NON_TAUT_DIFF;
4065
- break; /* atoms so far found to be equivalent have different number of H; the canonicalization is needed */
4176
+ break; /* atoms so far found to be equivalent differ in isotopes; the canonicalization is needed */
4066
4177
  }
4067
4178
  }
4068
4179
  } else {