rino 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +44 -0
- data/Rakefile +123 -0
- data/ext/extconf.rb +26 -0
- data/ext/ruby_inchi_main.so +0 -0
- data/ext/src/aux2atom.h +2786 -0
- data/ext/src/comdef.h +148 -0
- data/ext/src/e_0dstereo.c +3014 -0
- data/ext/src/e_0dstereo.h +31 -0
- data/ext/src/e_comdef.h +57 -0
- data/ext/src/e_ctl_data.h +147 -0
- data/ext/src/e_ichi_io.c +498 -0
- data/ext/src/e_ichi_io.h +40 -0
- data/ext/src/e_ichi_parms.c +37 -0
- data/ext/src/e_ichi_parms.h +41 -0
- data/ext/src/e_ichicomp.h +50 -0
- data/ext/src/e_ichierr.h +40 -0
- data/ext/src/e_ichimain.c +593 -0
- data/ext/src/e_ichisize.h +43 -0
- data/ext/src/e_inchi_atom.c +75 -0
- data/ext/src/e_inchi_atom.h +33 -0
- data/ext/src/e_inpdef.h +41 -0
- data/ext/src/e_mode.h +706 -0
- data/ext/src/e_mol2atom.c +649 -0
- data/ext/src/e_readinch.c +58 -0
- data/ext/src/e_readmol.c +54 -0
- data/ext/src/e_readmol.h +180 -0
- data/ext/src/e_readstru.c +251 -0
- data/ext/src/e_readstru.h +33 -0
- data/ext/src/e_util.c +284 -0
- data/ext/src/e_util.h +61 -0
- data/ext/src/extr_ct.h +251 -0
- data/ext/src/ichi.h +206 -0
- data/ext/src/ichi_bns.c +7999 -0
- data/ext/src/ichi_bns.h +231 -0
- data/ext/src/ichican2.c +5000 -0
- data/ext/src/ichicano.c +2195 -0
- data/ext/src/ichicano.h +49 -0
- data/ext/src/ichicans.c +1625 -0
- data/ext/src/ichicant.h +379 -0
- data/ext/src/ichicomn.h +260 -0
- data/ext/src/ichicomp.h +50 -0
- data/ext/src/ichidrp.h +119 -0
- data/ext/src/ichierr.h +124 -0
- data/ext/src/ichiisot.c +101 -0
- data/ext/src/ichilnct.c +286 -0
- data/ext/src/ichimain.h +132 -0
- data/ext/src/ichimak2.c +1189 -0
- data/ext/src/ichimake.c +3812 -0
- data/ext/src/ichimake.h +205 -0
- data/ext/src/ichimap1.c +851 -0
- data/ext/src/ichimap2.c +2856 -0
- data/ext/src/ichimap4.c +1609 -0
- data/ext/src/ichinorm.c +741 -0
- data/ext/src/ichinorm.h +67 -0
- data/ext/src/ichiparm.c +45 -0
- data/ext/src/ichiparm.h +1441 -0
- data/ext/src/ichiprt1.c +3612 -0
- data/ext/src/ichiprt2.c +1511 -0
- data/ext/src/ichiprt3.c +3011 -0
- data/ext/src/ichiqueu.c +1003 -0
- data/ext/src/ichiring.c +326 -0
- data/ext/src/ichiring.h +49 -0
- data/ext/src/ichisize.h +35 -0
- data/ext/src/ichisort.c +539 -0
- data/ext/src/ichister.c +3538 -0
- data/ext/src/ichister.h +35 -0
- data/ext/src/ichitaut.c +3843 -0
- data/ext/src/ichitaut.h +387 -0
- data/ext/src/ichitime.h +74 -0
- data/ext/src/inchi_api.h +670 -0
- data/ext/src/inchi_dll.c +1480 -0
- data/ext/src/inchi_dll.h +34 -0
- data/ext/src/inchi_dll_main.c +23 -0
- data/ext/src/inchi_dll_main.h +31 -0
- data/ext/src/inpdef.h +328 -0
- data/ext/src/lreadmol.h +1246 -0
- data/ext/src/mode.h +706 -0
- data/ext/src/ruby_inchi_main.c +558 -0
- data/ext/src/runichi.c +4179 -0
- data/ext/src/strutil.c +3861 -0
- data/ext/src/strutil.h +182 -0
- data/ext/src/util.c +1130 -0
- data/ext/src/util.h +85 -0
- data/lib/clean_tempfile.rb +220 -0
- data/lib/rino.rb +111 -0
- data/test/test.rb +386 -0
- metadata +130 -0
data/ext/src/ichisort.c
ADDED
@@ -0,0 +1,539 @@
|
|
1
|
+
/*
|
2
|
+
* International Union of Pure and Applied Chemistry (IUPAC)
|
3
|
+
* International Chemical Identifier (InChI)
|
4
|
+
* Version 1
|
5
|
+
* Software version 1.00
|
6
|
+
* April 13, 2005
|
7
|
+
* Developed at NIST
|
8
|
+
*/
|
9
|
+
|
10
|
+
#include <stdio.h>
|
11
|
+
#include <stdlib.h>
|
12
|
+
#include <string.h>
|
13
|
+
|
14
|
+
#include "mode.h"
|
15
|
+
|
16
|
+
#include "comdef.h"
|
17
|
+
#include "extr_ct.h"
|
18
|
+
#include "ichitaut.h"
|
19
|
+
#include "ichicant.h"
|
20
|
+
#include "ichicomn.h"
|
21
|
+
|
22
|
+
#include "ichicomp.h"
|
23
|
+
|
24
|
+
#define RET_MAX 32767
|
25
|
+
|
26
|
+
/**********************************************************************************/
|
27
|
+
void swap ( char *a, char *b, size_t width )
|
28
|
+
{
|
29
|
+
char tmp;
|
30
|
+
if ( a != b )
|
31
|
+
while ( width-- ) {
|
32
|
+
tmp = *a;
|
33
|
+
*a++ = *b;
|
34
|
+
*b++ = tmp;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
/**********************************************************************************/
|
38
|
+
/* Sort by insertions */
|
39
|
+
int insertions_sort( void *base, size_t num, size_t width, int ( *compare )(const void *e1, const void *e2 ) )
|
40
|
+
{
|
41
|
+
char *i, *j, *pk;
|
42
|
+
int num_trans = 0;
|
43
|
+
size_t k;
|
44
|
+
for( k=1, pk = (char*)base; k < num; k++, pk += width ) {
|
45
|
+
for( i = pk, j = pk + width; j > (char*)base && (*compare)(i,j) > 0; j=i, i -= width ) {
|
46
|
+
swap( i, j, width );
|
47
|
+
num_trans ++;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
return num_trans;
|
51
|
+
}
|
52
|
+
/**********************************************************************************/
|
53
|
+
/* Sort by insertions */
|
54
|
+
int insertions_sort_AT_NUMBERS( AT_NUMB *base, int num, int ( *compare )(const void *e1, const void *e2 ) )
|
55
|
+
{
|
56
|
+
AT_NUMB *i, *j, *pk, tmp;
|
57
|
+
int k, num_trans = 0;
|
58
|
+
for( k=1, pk = base; k < num; k++, pk ++ ) {
|
59
|
+
for( j = (i = pk) + 1, tmp = *j; j > base && (*compare)(i,&tmp) > 0; j=i, i -- ) {
|
60
|
+
*j = *i;
|
61
|
+
num_trans ++;
|
62
|
+
}
|
63
|
+
*j = tmp;
|
64
|
+
}
|
65
|
+
return num_trans;
|
66
|
+
}
|
67
|
+
/**********************************************************************************/
|
68
|
+
/* Sort neighbors according to ranks in ascending order */
|
69
|
+
void insertions_sort_NeighList_AT_NUMBERS( NEIGH_LIST base, AT_RANK *nRank )
|
70
|
+
{
|
71
|
+
AT_NUMB *i, *j, *pk, tmp;
|
72
|
+
AT_RANK rj; /* optimization */
|
73
|
+
int k, num = (int)*base++;
|
74
|
+
for( k=1, pk = base; k < num; k++, pk ++ ) {
|
75
|
+
for( j = (i = pk) + 1, rj=nRank[(int)*j]; j > base && nRank[(int)*i] > rj; j=i, i -- ) {
|
76
|
+
tmp = *i;
|
77
|
+
*i = *j;
|
78
|
+
*j = tmp;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
/**********************************************************************************/
|
83
|
+
/* Sort neighbors according to ranks in ascending order */
|
84
|
+
int insertions_sort_AT_RANK( AT_RANK *base, int num )
|
85
|
+
{
|
86
|
+
AT_RANK *i, *j, *pk, tmp;
|
87
|
+
int k, num_trans = 0;
|
88
|
+
for( k=1, pk = base; k < num; k++, pk ++ ) {
|
89
|
+
for( j = (i = pk) + 1, tmp = *j; j > base && *i > tmp; j=i, i -- ) {
|
90
|
+
*j = *i;
|
91
|
+
num_trans ++;
|
92
|
+
}
|
93
|
+
*j = tmp;
|
94
|
+
}
|
95
|
+
return num_trans;
|
96
|
+
}
|
97
|
+
/**********************************************************************************/
|
98
|
+
/* Sort neighbors according to ranks in ascending order */
|
99
|
+
int insertions_sort_NeighList_AT_NUMBERS3( NEIGH_LIST base, AT_RANK *nRank )
|
100
|
+
{
|
101
|
+
AT_NUMB *i, *j, *pk, tmp;
|
102
|
+
AT_RANK rj;
|
103
|
+
int k, n, num = (int)*base++;
|
104
|
+
for( k=1, pk = base, n=0; k < num; k++, pk ++ ) {
|
105
|
+
for( j = (i = pk) + 1, rj=nRank[(int)(tmp=*j)]; j > base && nRank[(int)*i] > rj; j=i, i -- ) {
|
106
|
+
*j = *i;
|
107
|
+
n ++;
|
108
|
+
}
|
109
|
+
*j = tmp;
|
110
|
+
}
|
111
|
+
return n;
|
112
|
+
}
|
113
|
+
|
114
|
+
/**********************************************************************************/
|
115
|
+
/* Sort neighbors according to symm. ranks (primary key) and canon. ranks (secondary key), in descending order */
|
116
|
+
void insertions_sort_NeighListBySymmAndCanonRank( NEIGH_LIST base, const AT_RANK *nSymmRank, const AT_RANK *nCanonRank )
|
117
|
+
{
|
118
|
+
AT_NUMB *i, *j, *pk, tmp;
|
119
|
+
int diff;
|
120
|
+
int k, num = (int)*base++;
|
121
|
+
for( k=1, pk = base; k < num; k++, pk ++ ) {
|
122
|
+
for( j = (i = pk) + 1; j > base && /* always j > i */
|
123
|
+
( 0 > (diff = (int)nSymmRank[(int)*i] - (int)nSymmRank[(int)*j]) ||
|
124
|
+
!diff && nCanonRank[(int)*i] < nCanonRank[(int)*j]); j=i, i -- ) {
|
125
|
+
tmp = *i;
|
126
|
+
*i = *j;
|
127
|
+
*j = tmp;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
/*********************************************************************************************
|
133
|
+
*
|
134
|
+
* Comparison functions
|
135
|
+
*
|
136
|
+
*********************************************************************************************/
|
137
|
+
int CompNeighborsAT_NUMBER( const void* a1, const void* a2)
|
138
|
+
{
|
139
|
+
#ifdef CT_NEIGH_INCREASE
|
140
|
+
return (int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a1]] -
|
141
|
+
(int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a2]];
|
142
|
+
#else
|
143
|
+
return (int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a2]] -
|
144
|
+
(int)pn_RankForSort[pNeighborsForSort[(int)*(const AT_NUMB*)a1]];
|
145
|
+
#endif
|
146
|
+
}
|
147
|
+
|
148
|
+
/**********************************************************************************/
|
149
|
+
int comp_AT_RANK( const void* a1, const void* a2)
|
150
|
+
{
|
151
|
+
return (int)*(const AT_RANK*)a1 - (int)*(const AT_RANK*)a2;
|
152
|
+
}
|
153
|
+
|
154
|
+
/**********************************************************************************/
|
155
|
+
/* Compare for sorting Ranks only */
|
156
|
+
int CompRank(const void* a1, const void* a2 )
|
157
|
+
{
|
158
|
+
int ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a1] -
|
159
|
+
(int)pn_RankForSort[(int)*(const AT_RANK*)a2];
|
160
|
+
return ret;
|
161
|
+
}
|
162
|
+
/**********************************************************************************/
|
163
|
+
int CompRanksOrd( const void* a1, const void* a2 )
|
164
|
+
{
|
165
|
+
int ret;
|
166
|
+
ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a1] -
|
167
|
+
(int)pn_RankForSort[(int)*(const AT_RANK*)a2];
|
168
|
+
if ( !ret )
|
169
|
+
ret = (int)*(const AT_RANK*)a1 - (int)*(const AT_RANK*)a2;
|
170
|
+
return ret;
|
171
|
+
}
|
172
|
+
/**********************************************************************************/
|
173
|
+
int CompAtomInvariants2Only( const void* a1, const void* a2 )
|
174
|
+
{
|
175
|
+
const ATOM_INVARIANT2 *pAI1 = pAtomInvariant2ForSort + (int)*(const AT_RANK*)a1;
|
176
|
+
const ATOM_INVARIANT2 *pAI2 = pAtomInvariant2ForSort + (int)*(const AT_RANK*)a2;
|
177
|
+
int i;
|
178
|
+
for ( i = 0; i < AT_INV_BREAK1; i ++ ) {
|
179
|
+
if ( pAI1->val[i] == pAI2->val[i] )
|
180
|
+
continue;
|
181
|
+
return (int)pAI1->val[i] - (int)pAI2->val[i];
|
182
|
+
}
|
183
|
+
if ( pAI1->iso_sort_key != pAI2->iso_sort_key ) {
|
184
|
+
return ( pAI1->iso_sort_key > pAI2->iso_sort_key )? 1 : -1;
|
185
|
+
}
|
186
|
+
for ( ; i < AT_INV_LENGTH; i ++ ) {
|
187
|
+
if ( pAI1->val[i] != pAI2->val[i] )
|
188
|
+
continue;
|
189
|
+
return (int)pAI1->val[i] - (int)pAI2->val[i];
|
190
|
+
}
|
191
|
+
if ( pAI1->iso_aux_key != pAI2->iso_aux_key ) {
|
192
|
+
return ( pAI1->iso_aux_key > pAI2->iso_aux_key )? 1 : -1;
|
193
|
+
}
|
194
|
+
return 0;
|
195
|
+
}
|
196
|
+
/**********************************************************************************/
|
197
|
+
int CompAtomInvariants2( const void* a1, const void* a2 )
|
198
|
+
{
|
199
|
+
/* Warning: the following line may be compiler implementation dependent */
|
200
|
+
int ret = CompAtomInvariants2Only( a1, a2 );
|
201
|
+
if ( !ret )
|
202
|
+
ret = (int)*(const AT_RANK*)a1 - (int)*(const AT_RANK*)a2;
|
203
|
+
return ret;
|
204
|
+
}
|
205
|
+
/**********************************************************************************/
|
206
|
+
/* Compare two elements lexic�graphically */
|
207
|
+
int CompChemElemLex( const void *a1, const void *a2 )
|
208
|
+
{
|
209
|
+
return memcmp( a1, a2, 2);
|
210
|
+
}
|
211
|
+
/**********************************************************************************/
|
212
|
+
/* lexicographic compare */
|
213
|
+
int CompareNeighListLex( NEIGH_LIST pp1, NEIGH_LIST pp2, const AT_RANK *nRank)
|
214
|
+
{
|
215
|
+
int len1 = (int)*pp1++;
|
216
|
+
int len2 = (int)*pp2++;
|
217
|
+
int len = inchi_min( len1, len2 );
|
218
|
+
int diff = 0;
|
219
|
+
while ( len -- > 0 && !( diff = (int)nRank[*pp1++] - (int)nRank[*pp2++] ) )
|
220
|
+
;
|
221
|
+
return diff? diff : (len1 - len2);
|
222
|
+
|
223
|
+
}
|
224
|
+
/**********************************************************************************/
|
225
|
+
/* lexicographic compare */
|
226
|
+
int CompareNeighListLexUpToMaxRank( NEIGH_LIST pp1, NEIGH_LIST pp2, const AT_RANK *nRank, AT_RANK nMaxAtNeighRank )
|
227
|
+
{
|
228
|
+
int len1 = (int)*pp1++;
|
229
|
+
int len2 = (int)*pp2++;
|
230
|
+
int diff = 0;
|
231
|
+
int len;
|
232
|
+
while( 0 < len1 && nRank[pp1[len1-1]] > nMaxAtNeighRank ) {
|
233
|
+
len1 --;
|
234
|
+
}
|
235
|
+
while( 0 < len2 && nRank[pp2[len2-1]] > nMaxAtNeighRank ) {
|
236
|
+
len2 --;
|
237
|
+
}
|
238
|
+
len = inchi_min( len1, len2 );
|
239
|
+
while ( len -- > 0 && !( diff = (int)nRank[*pp1++] - (int)nRank[*pp2++] ) )
|
240
|
+
;
|
241
|
+
return diff? diff : (len1 - len2);
|
242
|
+
|
243
|
+
}
|
244
|
+
/**********************************************************************************/
|
245
|
+
int compare_NeighLists( const NEIGH_LIST *op1, const NEIGH_LIST *op2 )
|
246
|
+
{
|
247
|
+
return CompareNeighListLex( *op1, *op2, pn_RankForSort);
|
248
|
+
}
|
249
|
+
/**********************************************************************************/
|
250
|
+
int CompNeighListRanks( const void* a1, const void* a2 )
|
251
|
+
{
|
252
|
+
int ret;
|
253
|
+
ret = (int)pn_RankForSort[*((const AT_RANK*)a1)] -
|
254
|
+
(int)pn_RankForSort[*((const AT_RANK*)a2)];
|
255
|
+
if ( !ret )
|
256
|
+
ret = compare_NeighLists( pNeighList_RankForSort + *((const AT_RANK*)a1),
|
257
|
+
pNeighList_RankForSort + *((const AT_RANK*)a2) );
|
258
|
+
return ret;
|
259
|
+
}
|
260
|
+
/**********************************************************************************/
|
261
|
+
int CompNeighLists( const void* a1, const void* a2 )
|
262
|
+
{
|
263
|
+
int ret;
|
264
|
+
ret = compare_NeighLists( pNeighList_RankForSort + *((const AT_RANK*)a1),
|
265
|
+
pNeighList_RankForSort + *((const AT_RANK*)a2) );
|
266
|
+
return ret;
|
267
|
+
}
|
268
|
+
/**********************************************************************************/
|
269
|
+
int CompNeighListsUpToMaxRank( const void* a1, const void* a2 )
|
270
|
+
{
|
271
|
+
int ret;
|
272
|
+
ret = CompareNeighListLexUpToMaxRank( pNeighList_RankForSort[*((const AT_RANK*)a1)],
|
273
|
+
pNeighList_RankForSort[*((const AT_RANK*)a2)],
|
274
|
+
pn_RankForSort, nMaxAtNeighRankForSort );
|
275
|
+
return ret;
|
276
|
+
}
|
277
|
+
/**********************************************************************************/
|
278
|
+
int CompNeighListRanksOrd( const void* a1, const void* a2 )
|
279
|
+
{
|
280
|
+
int ret = CompNeighListRanks( a1, a2 );
|
281
|
+
if ( !ret )
|
282
|
+
ret = (int)*((const AT_RANK*)a1) - (int)*((const AT_RANK*)a2); /* keep original order if identical */
|
283
|
+
return ret;
|
284
|
+
}
|
285
|
+
/**********************************************************************************/
|
286
|
+
int CompRanksInvOrd( const void* a1, const void* a2 )
|
287
|
+
{
|
288
|
+
return (int)*(const AT_RANK*)a2 - (int)*(const AT_RANK*)a1;
|
289
|
+
}
|
290
|
+
/**********************************************************************************/
|
291
|
+
int CompNeighborsRanksCountEql( const void* a1, const void* a2 )
|
292
|
+
{
|
293
|
+
#ifdef CT_NEIGH_INCREASE
|
294
|
+
int ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a1] -
|
295
|
+
(int)pn_RankForSort[(int)*(const AT_RANK*)a2];
|
296
|
+
#else
|
297
|
+
int ret = (int)pn_RankForSort[(int)*(const AT_RANK*)a2] -
|
298
|
+
(int)pn_RankForSort[(int)*(const AT_RANK*)a1];
|
299
|
+
#endif
|
300
|
+
nNumCompNeighborsRanksCountEql += !ret;
|
301
|
+
return ret;
|
302
|
+
}
|
303
|
+
/****************************************************************************************
|
304
|
+
*
|
305
|
+
* In this neighbor list the (vertex number) = (canonical number) - 1
|
306
|
+
* Since LinearCT is sorted so that parents are in ascending order
|
307
|
+
* and all neighbors of a parent are smaller than the parent and are
|
308
|
+
* in ascending order, the neighbors in the NEIGH_LIST are automatically
|
309
|
+
* sorted in ascending order
|
310
|
+
*/
|
311
|
+
NEIGH_LIST *CreateNeighListFromLinearCT( AT_NUMB *LinearCT, int nLenCT, int num_atoms )
|
312
|
+
{
|
313
|
+
/* atom numbers in LinearCT are canonical numbers
|
314
|
+
* order: parent[i] > neigh[i][0] < neigh[i][1]...<neigh[i][n] < parent[i+1] > neigh[i+1][0] < ...
|
315
|
+
* parent[i] < parent[i+1]
|
316
|
+
*/
|
317
|
+
int i, j;
|
318
|
+
S_CHAR *valence = NULL;
|
319
|
+
NEIGH_LIST *pp = NULL;
|
320
|
+
AT_NUMB *pAtList = NULL;
|
321
|
+
AT_RANK n_vertex, n_neigh;
|
322
|
+
int err = 1, num_bonds;
|
323
|
+
int length, start;
|
324
|
+
if ( (int)LinearCT[0] > num_atoms ) {
|
325
|
+
goto exit_function;
|
326
|
+
}
|
327
|
+
if ( !(valence = (S_CHAR*)inchi_calloc( num_atoms+1, sizeof(valence[0]) ) ) ) {
|
328
|
+
goto exit_function;
|
329
|
+
}
|
330
|
+
for ( i = 1, num_bonds = 0, n_vertex = LinearCT[0]; i < nLenCT; i ++ ) {
|
331
|
+
if ( (n_neigh = LinearCT[i]) < n_vertex ) {
|
332
|
+
valence[n_neigh] ++;
|
333
|
+
valence[n_vertex] ++;
|
334
|
+
num_bonds += 2;
|
335
|
+
} else
|
336
|
+
if ( (int)(n_vertex = n_neigh) > num_atoms ) {
|
337
|
+
goto exit_function;
|
338
|
+
}
|
339
|
+
}
|
340
|
+
if ( (int)n_vertex != num_atoms ) {
|
341
|
+
goto exit_function;
|
342
|
+
}
|
343
|
+
length = num_bonds + num_atoms + 1;
|
344
|
+
if ( pp = (NEIGH_LIST *) inchi_calloc((num_atoms+1), sizeof(NEIGH_LIST)) ) {
|
345
|
+
if ( pAtList = (AT_NUMB *) inchi_malloc( length*sizeof(*pAtList) ) ) {
|
346
|
+
/* create empty connection table */
|
347
|
+
for ( i = 1, length = 0; i <= num_atoms; i ++ ) {
|
348
|
+
start = length;
|
349
|
+
length += (valence[i]+1);
|
350
|
+
pp[i-1] = pAtList + start;
|
351
|
+
pp[i-1][0] = 0;
|
352
|
+
}
|
353
|
+
/* fill out the CT */
|
354
|
+
for ( i = 1, n_vertex = LinearCT[0]-1; i < nLenCT; i ++ ) {
|
355
|
+
if ( (n_neigh = LinearCT[i]-1) < n_vertex ) {
|
356
|
+
/* vertex - neighbor connection */
|
357
|
+
j = (int)(++pp[(int)n_vertex][0]);
|
358
|
+
pp[(int)n_vertex][j] = n_neigh;
|
359
|
+
/* neighbor - vertex connection */
|
360
|
+
j = (int)(++pp[(int)n_neigh][0]);
|
361
|
+
pp[(int)n_neigh][j] = n_vertex;
|
362
|
+
|
363
|
+
} else
|
364
|
+
if ( (int)(n_vertex = n_neigh) >= num_atoms ) {
|
365
|
+
goto exit_function;
|
366
|
+
}
|
367
|
+
}
|
368
|
+
err = 0;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
exit_function:
|
372
|
+
if ( valence ) {
|
373
|
+
inchi_free( valence );
|
374
|
+
}
|
375
|
+
if ( err ) {
|
376
|
+
if ( pAtList )
|
377
|
+
inchi_free( pAtList );
|
378
|
+
if ( pp ) {
|
379
|
+
inchi_free( pp );
|
380
|
+
pp = NULL;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
return pp;
|
384
|
+
}
|
385
|
+
|
386
|
+
/***********************************************************************************
|
387
|
+
* NEIGH_LIST pp[] is an array of pointers to the lists of neighboring atoms numbers
|
388
|
+
* The first number in each list is a number of neighbors.
|
389
|
+
* In case of bDoubleBondSquare != 0 neighbors connected by the double bond appear 2 times
|
390
|
+
* The first element pp[0] is a pointer to be deallocated to free all the lists.
|
391
|
+
*/
|
392
|
+
NEIGH_LIST *CreateNeighList( int num_atoms, int num_at_tg, sp_ATOM* at,
|
393
|
+
int bDoubleBondSquare, T_GROUP_INFO *t_group_info )
|
394
|
+
{
|
395
|
+
/* +1 to add NULL termination */
|
396
|
+
NEIGH_LIST *pp = (NEIGH_LIST *) inchi_calloc((num_at_tg+1), sizeof(NEIGH_LIST));
|
397
|
+
T_GROUP *t_group = NULL;
|
398
|
+
AT_NUMB *nEndpointAtomNumber = NULL;
|
399
|
+
int num_t_groups = 0;
|
400
|
+
int nFirstEndpointAtNoPos;
|
401
|
+
|
402
|
+
AT_NUMB *pAtList = NULL;
|
403
|
+
int length, start, val, i, j;
|
404
|
+
if ( pp ) {
|
405
|
+
if ( num_at_tg > num_atoms ) {
|
406
|
+
t_group = t_group_info->t_group;
|
407
|
+
num_t_groups = t_group_info->num_t_groups;
|
408
|
+
nEndpointAtomNumber = t_group_info->nEndpointAtomNumber;
|
409
|
+
}
|
410
|
+
|
411
|
+
if ( !bDoubleBondSquare ) {
|
412
|
+
for ( i = 0, length = 0; i < num_atoms; i ++ ) {
|
413
|
+
length += (int)at[i].valence + (num_t_groups && at[i].endpoint);
|
414
|
+
}
|
415
|
+
length += num_atoms;
|
416
|
+
for ( i = 0; i < num_t_groups; i ++ ) {
|
417
|
+
length += (int)t_group[i].nNumEndpoints;
|
418
|
+
}
|
419
|
+
length += num_t_groups;
|
420
|
+
|
421
|
+
} else {
|
422
|
+
for ( i = 0, length = 0; i < num_atoms; i ++ ) {
|
423
|
+
val = (int)at[i].valence;
|
424
|
+
for ( j = 0; j < val; j ++ ) {
|
425
|
+
length += 1 + (bDoubleBondSquare && BOND_DOUBLE == at[i].bond_type[j]);
|
426
|
+
}
|
427
|
+
length += (num_t_groups && at[i].endpoint);
|
428
|
+
}
|
429
|
+
length += num_atoms;
|
430
|
+
for ( i = 0; i < num_t_groups; i ++ ) {
|
431
|
+
length += (int)t_group[i].nNumEndpoints;
|
432
|
+
}
|
433
|
+
length += num_t_groups;
|
434
|
+
}
|
435
|
+
length ++; /* +1 to save number of neighbors */
|
436
|
+
if ( pAtList = (AT_NUMB *) inchi_malloc( length*sizeof(*pAtList) ) ) {
|
437
|
+
if ( !bDoubleBondSquare ) {
|
438
|
+
for ( i = 0, length = 0; i < num_atoms; i ++ ) {
|
439
|
+
val = at[i].valence;
|
440
|
+
start = length ++;
|
441
|
+
for ( j = 0; j < val; j ++ ) {
|
442
|
+
pAtList[length ++] = at[i].neighbor[j];
|
443
|
+
}
|
444
|
+
/* add endpoint */
|
445
|
+
if (num_t_groups && at[i].endpoint) {
|
446
|
+
pAtList[length ++] = num_atoms + (int)at[i].endpoint - 1;
|
447
|
+
}
|
448
|
+
pAtList[start] = length - start - 1; /* number of neighbors before the list of neighbors */
|
449
|
+
pp[i] = pAtList + start; /* pointer to the <num.neigh.><list of neigh> */
|
450
|
+
}
|
451
|
+
|
452
|
+
} else {
|
453
|
+
for ( i = 0, length = 0; i < num_atoms; i ++ ) {
|
454
|
+
val = at[i].valence;
|
455
|
+
start = length ++;
|
456
|
+
for ( j = 0; j < val; j ++ ) {
|
457
|
+
pAtList[length ++] = at[i].neighbor[j];
|
458
|
+
if ( bDoubleBondSquare && BOND_DOUBLE == at[i].bond_type[j] ) {
|
459
|
+
pAtList[length ++] = at[i].neighbor[j]; /* a list of neighbor orig. numbers */
|
460
|
+
}
|
461
|
+
}
|
462
|
+
/* add endpoint */
|
463
|
+
if (num_t_groups && at[i].endpoint) {
|
464
|
+
pAtList[length ++] = num_atoms + (int)at[i].endpoint - 1;
|
465
|
+
}
|
466
|
+
pAtList[start] = length - start - 1; /* number of neighbors before the list of neighbors */
|
467
|
+
pp[i] = pAtList + start; /* pointer to the <num.neigh.><list of neigh> */
|
468
|
+
}
|
469
|
+
}
|
470
|
+
|
471
|
+
/* add t-groups */
|
472
|
+
for ( i = 0; i < num_t_groups; i ++ ) {
|
473
|
+
val = (int)t_group[i].nNumEndpoints;
|
474
|
+
start = length ++;
|
475
|
+
nFirstEndpointAtNoPos = (int)t_group[i].nFirstEndpointAtNoPos;
|
476
|
+
for ( j = 0; j < val; j ++ ) {
|
477
|
+
pAtList[length ++] = nEndpointAtomNumber[nFirstEndpointAtNoPos+j];
|
478
|
+
}
|
479
|
+
pAtList[start] = length - start - 1; /* number of neighbors before the list of neighbors */
|
480
|
+
pp[num_atoms+i] = pAtList + start; /* pointer to the <num.neigh.><list of neigh> */
|
481
|
+
}
|
482
|
+
} else {
|
483
|
+
inchi_free ( pp );
|
484
|
+
return NULL;
|
485
|
+
}
|
486
|
+
}
|
487
|
+
return pp;
|
488
|
+
}
|
489
|
+
/**********************************************************************************/
|
490
|
+
void FreeNeighList( NEIGH_LIST *pp )
|
491
|
+
{
|
492
|
+
if ( pp ) {
|
493
|
+
if ( pp[0] ) {
|
494
|
+
inchi_free( pp[0] );
|
495
|
+
}
|
496
|
+
inchi_free( pp );
|
497
|
+
}
|
498
|
+
}
|
499
|
+
|
500
|
+
/**********************************************************************************/
|
501
|
+
int BreakAllTies( int num_atoms, int num_max, AT_RANK **pRankStack,
|
502
|
+
NEIGH_LIST *NeighList, AT_RANK *nTempRank, CANON_STAT *pCS)
|
503
|
+
{
|
504
|
+
int i, nRet = -1, nNumRanks=1 /* value does not matter*/;
|
505
|
+
|
506
|
+
AT_RANK *nPrevRank = *pRankStack ++;
|
507
|
+
AT_RANK *nPrevAtomNumber = *pRankStack ++;
|
508
|
+
|
509
|
+
AT_RANK *nNewRank = NULL;
|
510
|
+
AT_RANK *nNewAtomNumber = NULL;
|
511
|
+
|
512
|
+
if ( !pRankStack[0] ) {
|
513
|
+
pRankStack[0] = (AT_RANK *)inchi_malloc(num_max*sizeof(*nNewRank));
|
514
|
+
}
|
515
|
+
if ( !pRankStack[1] ) {
|
516
|
+
pRankStack[1] = (AT_RANK *)inchi_malloc(num_max*sizeof(*nNewAtomNumber));
|
517
|
+
}
|
518
|
+
if ( !pRankStack[0] || !pRankStack[1] )
|
519
|
+
return CT_OUT_OF_RAM; /* <BRKPT> */
|
520
|
+
nNewRank = pRankStack[0];
|
521
|
+
nNewAtomNumber = pRankStack[1];
|
522
|
+
|
523
|
+
if ( nNewRank && nNewAtomNumber ) {
|
524
|
+
memcpy( nNewAtomNumber, nPrevAtomNumber, num_atoms*sizeof(nNewAtomNumber[0]));
|
525
|
+
memcpy( nNewRank, nPrevRank, num_atoms*sizeof(nNewRank[0]));
|
526
|
+
|
527
|
+
for ( i = 1, nRet=0; i < num_atoms; i ++ ) { /* 12-12-2001: replaced Prev... with New... */
|
528
|
+
if ( nNewRank[(int)nNewAtomNumber[i-1]] == nNewRank[(int)nNewAtomNumber[i]] ) {
|
529
|
+
nNewRank[nNewAtomNumber[i-1]] = (AT_RANK)i;
|
530
|
+
nNumRanks = DifferentiateRanks2( num_atoms, NeighList,
|
531
|
+
nNumRanks, nNewRank, nTempRank,
|
532
|
+
nNewAtomNumber, &pCS->lNumNeighListIter, 1 );
|
533
|
+
pCS->lNumBreakTies ++;
|
534
|
+
nRet ++;
|
535
|
+
}
|
536
|
+
}
|
537
|
+
}
|
538
|
+
return nRet;
|
539
|
+
}
|