rino 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/ext/extconf.rb +1 -24
- data/ext/libinchi.so +0 -0
- data/ext/src/aux2atom.h +120 -39
- data/ext/src/comdef.h +3 -3
- data/ext/src/dispstru.c +2547 -0
- data/ext/src/dispstru.h +73 -0
- data/ext/src/extr_ct.h +5 -2
- data/ext/src/ichi.h +27 -11
- data/ext/src/ichi_bns.c +1800 -254
- data/ext/src/ichi_bns.h +205 -4
- data/ext/src/ichican2.c +197 -86
- data/ext/src/ichicano.c +8 -13
- data/ext/src/ichicano.h +2 -2
- data/ext/src/ichicans.c +11 -6
- data/ext/src/ichicant.h +2 -2
- data/ext/src/ichicomn.h +2 -2
- data/ext/src/ichicomp.h +19 -4
- data/ext/src/ichidrp.h +9 -5
- data/ext/src/ichierr.h +5 -3
- data/ext/src/ichiisot.c +2 -2
- data/ext/src/ichimain.c +461 -0
- data/ext/src/ichimain.h +23 -15
- data/ext/src/ichimak2.c +6 -6
- data/ext/src/ichimake.c +843 -42
- data/ext/src/ichimake.h +4 -2
- data/ext/src/ichimap1.c +5 -5
- data/ext/src/ichimap2.c +2 -2
- data/ext/src/ichimap4.c +34 -21
- data/ext/src/ichinorm.c +11 -5
- data/ext/src/ichinorm.h +3 -2
- data/ext/src/ichiparm.c +2 -2
- data/ext/src/ichiparm.h +232 -30
- data/ext/src/ichiprt1.c +35 -11
- data/ext/src/ichiprt2.c +78 -7
- data/ext/src/ichiprt3.c +300 -120
- data/ext/src/ichiqueu.c +17 -2
- data/ext/src/ichiread.c +6932 -0
- data/ext/src/ichiring.c +3 -2
- data/ext/src/ichiring.h +2 -2
- data/ext/src/ichirvr1.c +4891 -0
- data/ext/src/ichirvr2.c +6344 -0
- data/ext/src/ichirvr3.c +5499 -0
- data/ext/src/ichirvr4.c +3177 -0
- data/ext/src/ichirvr5.c +1166 -0
- data/ext/src/ichirvr6.c +1287 -0
- data/ext/src/ichirvr7.c +2319 -0
- data/ext/src/ichirvrs.h +882 -0
- data/ext/src/ichisize.h +2 -2
- data/ext/src/ichisort.c +5 -5
- data/ext/src/ichister.c +281 -86
- data/ext/src/ichister.h +9 -3
- data/ext/src/ichitaut.c +208 -9
- data/ext/src/ichitaut.h +13 -11
- data/ext/src/ichitime.h +16 -2
- data/ext/src/inchicmp.h +107 -0
- data/ext/src/inpdef.h +6 -3
- data/ext/src/libinchi_wrap.c +912 -0
- data/ext/src/lreadmol.h +34 -31
- data/ext/src/mode.h +244 -7
- data/ext/src/mol2atom.c +1060 -0
- data/ext/src/mol2atom.h +31 -0
- data/ext/src/readinch.c +239 -0
- data/ext/src/readmol.c +28 -0
- data/ext/src/{e_readmol.h → readmol.h} +7 -9
- data/ext/src/runichi.c +251 -177
- data/ext/src/strutil.c +444 -238
- data/ext/src/strutil.h +150 -11
- data/ext/src/util.c +176 -118
- data/ext/src/util.h +15 -3
- data/lib/rino.rb +71 -3
- data/test/test.rb +33 -4
- metadata +22 -34
- data/ext/ruby_inchi_main.so +0 -0
- data/ext/src/e_0dstereo.c +0 -3014
- data/ext/src/e_0dstereo.h +0 -31
- data/ext/src/e_comdef.h +0 -57
- data/ext/src/e_ctl_data.h +0 -147
- data/ext/src/e_ichi_io.c +0 -498
- data/ext/src/e_ichi_io.h +0 -40
- data/ext/src/e_ichi_parms.c +0 -37
- data/ext/src/e_ichi_parms.h +0 -41
- data/ext/src/e_ichicomp.h +0 -50
- data/ext/src/e_ichierr.h +0 -40
- data/ext/src/e_ichimain.c +0 -593
- data/ext/src/e_ichisize.h +0 -43
- data/ext/src/e_inchi_atom.c +0 -75
- data/ext/src/e_inchi_atom.h +0 -33
- data/ext/src/e_inpdef.h +0 -41
- data/ext/src/e_mode.h +0 -706
- data/ext/src/e_mol2atom.c +0 -649
- data/ext/src/e_readinch.c +0 -58
- data/ext/src/e_readmol.c +0 -54
- data/ext/src/e_readstru.c +0 -251
- data/ext/src/e_readstru.h +0 -33
- data/ext/src/e_util.c +0 -284
- data/ext/src/e_util.h +0 -61
- data/ext/src/ichilnct.c +0 -286
- data/ext/src/inchi_api.h +0 -670
- data/ext/src/inchi_dll.c +0 -1480
- data/ext/src/inchi_dll.h +0 -34
- data/ext/src/inchi_dll_main.c +0 -23
- data/ext/src/inchi_dll_main.h +0 -31
- data/ext/src/ruby_inchi_main.c +0 -558
data/ext/src/strutil.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
|
|
@@ -27,8 +27,7 @@
|
|
27
27
|
|
28
28
|
/* local prototypes */
|
29
29
|
int cmp_components( const void *a1, const void *a2 );
|
30
|
-
int mark_one_struct_component( inp_ATOM* at, int j, AT_NUMB *mark, AT_NUMB num_disconnected_components )
|
31
|
-
int Free_INChI_Stereo( INChI_Stereo *pINChI_Stereo );
|
30
|
+
/*int mark_one_struct_component( inp_ATOM* at, int j, AT_NUMB *mark, AT_NUMB num_disconnected_components );*/
|
32
31
|
INChI_Stereo *Alloc_INChI_Stereo(int num_at, int num_bonds);
|
33
32
|
int RemoveInpAtBond( inp_ATOM *at, int iat, int k );
|
34
33
|
int DisconnectInpAtBond( inp_ATOM *at, AT_NUMB *nOldCompNumber, int iat, int neigh_ord );
|
@@ -37,7 +36,7 @@ int DisconnectOneLigand( inp_ATOM *at, AT_NUMB *nOldCompNumber, S_CHAR *bMetal,
|
|
37
36
|
int num_halogens, int num_atoms, int iMetal, int jLigand, INCHI_MODE *bTautFlagsDone );
|
38
37
|
int bIsAmmoniumSalt( inp_ATOM *at, int i, int *piO, int *pk, S_CHAR *num_explicit_H );
|
39
38
|
int DisconnectAmmoniumSalt ( inp_ATOM *at, int i, int iO, int k, S_CHAR *num_explicit_H );
|
40
|
-
int bIsMetalSalt( inp_ATOM *at, int i );
|
39
|
+
/*int bIsMetalSalt( inp_ATOM *at, int i ); - moved to strutil,h */
|
41
40
|
int DisconnectMetalSalt( inp_ATOM *at, int i );
|
42
41
|
int bIsMetalToDisconnect(inp_ATOM *at, int i, int bCheckMetalValence);
|
43
42
|
|
@@ -93,7 +92,7 @@ int the_only_doublet_neigh(inp_ATOM *at, int i1, int *ineigh1, int *ineigh2)
|
|
93
92
|
}
|
94
93
|
|
95
94
|
/************************************************************************/
|
96
|
-
int fix_odd_things( int num_atoms, inp_ATOM *at )
|
95
|
+
int fix_odd_things( int num_atoms, inp_ATOM *at, int bFixBug )
|
97
96
|
{ /* 0 1 2 3 4 5 6 7 8 9 */
|
98
97
|
static const char el[] = "N;P;As;Sb;O;S;Se;Te;"; /* 8 elements + C, Si */
|
99
98
|
static U_CHAR en[10]; /* same number: 8 elements */
|
@@ -196,7 +195,7 @@ int fix_odd_things( int num_atoms, inp_ATOM *at )
|
|
196
195
|
}
|
197
196
|
} else
|
198
197
|
if ( at[i1].bond_type[ineigh] == BOND_TYPE_DOUBLE ) {
|
199
|
-
/* found a candidate for Y; bond must
|
198
|
+
/* found a candidate for Y; bond must be double */
|
200
199
|
i1_c = ineigh;
|
201
200
|
c = neigh;
|
202
201
|
}
|
@@ -322,6 +321,13 @@ int fix_odd_things( int num_atoms, inp_ATOM *at )
|
|
322
321
|
break;
|
323
322
|
}
|
324
323
|
}
|
324
|
+
#if( FIX_ODD_THINGS_REM_Plus_BUG == 1 )
|
325
|
+
at[c].charge -= charge;
|
326
|
+
#else
|
327
|
+
if ( bFixBug ) {
|
328
|
+
at[c].charge -= charge;
|
329
|
+
}
|
330
|
+
#endif
|
325
331
|
break;
|
326
332
|
}
|
327
333
|
}
|
@@ -454,7 +460,11 @@ int remove_ion_pairs( int num_atoms, inp_ATOM *at )
|
|
454
460
|
int num_changes = 0;
|
455
461
|
|
456
462
|
/* 0 1 2 3 4 5 6 7 8 9 8 9 */
|
463
|
+
#if( FIX_REM_ION_PAIRS_Si_BUG == 1 )
|
464
|
+
static const char el[] = "N;P;As;Sb;O;S;Se;Te;C;Si;"; /* 8 elements + C, Si */
|
465
|
+
#else
|
457
466
|
static const char el[] = "N;P;As;Sb;O;S;Se;Te;C;Si"; /* 8 elements + C, Si */
|
467
|
+
#endif
|
458
468
|
static char en[12]; /* same number: 8 elements */
|
459
469
|
static int ne=0; /* will be 8 and 10 */
|
460
470
|
|
@@ -1267,7 +1277,7 @@ int RemoveInpAtBond( inp_ATOM *atom, int iat, int k )
|
|
1267
1277
|
{
|
1268
1278
|
int i, j, m, m2, k2;
|
1269
1279
|
inp_ATOM *at = atom + iat;
|
1270
|
-
inp_ATOM *at2;
|
1280
|
+
inp_ATOM *at2 = NULL;
|
1271
1281
|
int val = at->valence - 1;
|
1272
1282
|
if ( val >= 0 ) {
|
1273
1283
|
int bond = at->bond_type[k];
|
@@ -2550,6 +2560,85 @@ int get_iat_number( int el_number, const int el_num[], int el_num_len )
|
|
2550
2560
|
IAT_MAX
|
2551
2561
|
} ION_ATOM_TYPE;
|
2552
2562
|
|
2563
|
+
#if( READ_INCHI_STRING == 1 )
|
2564
|
+
/****************************************************************************************/
|
2565
|
+
int bHeteroAtomMayHaveXchgIsoH( inp_ATOM *atom, int iat )
|
2566
|
+
{
|
2567
|
+
inp_ATOM *at = atom + iat, *at2;
|
2568
|
+
static int el_num[IAT_MAX];
|
2569
|
+
int j, val, is_O=0, is_Cl=0, is_N=0, is_H=0, num_H, iat_numb, bAccept, cur_num_iso_H;
|
2570
|
+
|
2571
|
+
if ( !el_num[IAT_H]) {
|
2572
|
+
el_num[IAT_H ] = get_periodic_table_number( "H" );
|
2573
|
+
el_num[IAT_C ] = get_periodic_table_number( "C" );
|
2574
|
+
el_num[IAT_N ] = get_periodic_table_number( "N" );
|
2575
|
+
el_num[IAT_P ] = get_periodic_table_number( "P" );
|
2576
|
+
el_num[IAT_O ] = get_periodic_table_number( "O" );
|
2577
|
+
el_num[IAT_S ] = get_periodic_table_number( "S" );
|
2578
|
+
el_num[IAT_Se] = get_periodic_table_number( "Se");
|
2579
|
+
el_num[IAT_Te] = get_periodic_table_number( "Te");
|
2580
|
+
el_num[IAT_F ] = get_periodic_table_number( "F" );
|
2581
|
+
el_num[IAT_Cl] = get_periodic_table_number( "Cl");
|
2582
|
+
el_num[IAT_Br] = get_periodic_table_number( "Br");
|
2583
|
+
el_num[IAT_I ] = get_periodic_table_number( "I" );
|
2584
|
+
}
|
2585
|
+
if ( 0 > (iat_numb = get_iat_number( at->el_number, el_num, IAT_MAX )) ) {
|
2586
|
+
return 0;
|
2587
|
+
}
|
2588
|
+
if ( abs(at->charge) > 1 || at->radical && RADICAL_SINGLET != at->radical ) {
|
2589
|
+
return 0;
|
2590
|
+
}
|
2591
|
+
val = -1;
|
2592
|
+
switch( iat_numb ) {
|
2593
|
+
case IAT_N:
|
2594
|
+
case IAT_P:
|
2595
|
+
is_N = 1;
|
2596
|
+
val = 3+at->charge;
|
2597
|
+
break;
|
2598
|
+
case IAT_O:
|
2599
|
+
case IAT_S:
|
2600
|
+
case IAT_Se:
|
2601
|
+
case IAT_Te:
|
2602
|
+
is_O = 1;
|
2603
|
+
val = 2+at->charge;
|
2604
|
+
break;
|
2605
|
+
case IAT_F:
|
2606
|
+
case IAT_Cl:
|
2607
|
+
case IAT_Br:
|
2608
|
+
case IAT_I:
|
2609
|
+
if ( at->charge == 0 ) {
|
2610
|
+
is_Cl = 1; /* isolated HCl */
|
2611
|
+
val = 1;
|
2612
|
+
}
|
2613
|
+
break;
|
2614
|
+
case IAT_H:
|
2615
|
+
if ( at->valence == 0 &&
|
2616
|
+
at->charge == 1 ) {
|
2617
|
+
is_H = 1; /* isolated proton */
|
2618
|
+
val = 0;
|
2619
|
+
}
|
2620
|
+
}
|
2621
|
+
if ( val < 0 ) {
|
2622
|
+
return 0;
|
2623
|
+
}
|
2624
|
+
num_H = NUMH(at,0);
|
2625
|
+
if ( val != at->chem_bonds_valence + num_H ) {
|
2626
|
+
return 0;
|
2627
|
+
}
|
2628
|
+
if ( is_H ) {
|
2629
|
+
return 2; /* H atom */
|
2630
|
+
} else {
|
2631
|
+
cur_num_iso_H = 0;
|
2632
|
+
for ( j = 0, bAccept = 1; j < at->valence && bAccept; j ++ ) {
|
2633
|
+
at2 = atom + (int)at->neighbor[j];
|
2634
|
+
if ( at2->charge && at->charge || (at2->radical && RADICAL_SINGLET != at2->radical ) ) {
|
2635
|
+
return 0; /* adjacent charged/radical atoms: do not neutralizate */
|
2636
|
+
}
|
2637
|
+
}
|
2638
|
+
}
|
2639
|
+
return 1;
|
2640
|
+
}
|
2641
|
+
#endif
|
2553
2642
|
/****************************************************************************************/
|
2554
2643
|
int bNumHeterAtomHasIsotopicH( inp_ATOM *atom, int num_atoms )
|
2555
2644
|
{
|
@@ -2673,22 +2762,6 @@ int cmp_components( const void *a1, const void *a2 )
|
|
2673
2762
|
|
2674
2763
|
}
|
2675
2764
|
/*************************************************************************************************/
|
2676
|
-
int mark_one_struct_component( inp_ATOM* at, int j, AT_NUMB *mark, AT_NUMB num_disconnected_components )
|
2677
|
-
{
|
2678
|
-
if ( mark[j] ) {
|
2679
|
-
return 0;
|
2680
|
-
} else {
|
2681
|
-
int i;
|
2682
|
-
mark[j] = num_disconnected_components;
|
2683
|
-
for ( i = 0; i < at[j].valence; i++ ) {
|
2684
|
-
if ( !mark[(int)at[j].neighbor[i]] ) {
|
2685
|
-
mark_one_struct_component( at, (int)at[j].neighbor[i], mark, num_disconnected_components );
|
2686
|
-
}
|
2687
|
-
}
|
2688
|
-
}
|
2689
|
-
return 1;
|
2690
|
-
}
|
2691
|
-
/*************************************************************************************************/
|
2692
2765
|
int MarkDisconnectedComponents( ORIG_ATOM_DATA *orig_at_data, int bProcessOldCompNumbers )
|
2693
2766
|
{
|
2694
2767
|
typedef AT_NUMB AT_TRIPLE[3];
|
@@ -2696,7 +2769,11 @@ int MarkDisconnectedComponents( ORIG_ATOM_DATA *orig_at_data, int bProcessOldCom
|
|
2696
2769
|
inp_ATOM *at = orig_at_data->at;
|
2697
2770
|
int num_at = orig_at_data->num_inp_atoms;
|
2698
2771
|
AT_NUMB *nCurAtLen = NULL;
|
2772
|
+
|
2699
2773
|
AT_NUMB *nNewCompNumber = NULL;
|
2774
|
+
AT_NUMB *nPrevAtom = NULL;
|
2775
|
+
S_CHAR *iNeigh = NULL;
|
2776
|
+
|
2700
2777
|
AT_NUMB *nOldCompNumber = NULL;
|
2701
2778
|
int i, j, num_components, ret;
|
2702
2779
|
int new_comp_no;
|
@@ -2713,6 +2790,7 @@ int MarkDisconnectedComponents( ORIG_ATOM_DATA *orig_at_data, int bProcessOldCom
|
|
2713
2790
|
if ( bProcessOldCompNumbers && !orig_at_data->nOldCompNumber ) {
|
2714
2791
|
bProcessOldCompNumbers = 0;
|
2715
2792
|
}
|
2793
|
+
num_components = 0;
|
2716
2794
|
/*
|
2717
2795
|
for ( j = 0; j < num_at; j ++ ) {
|
2718
2796
|
at[j].component = 0;
|
@@ -2722,17 +2800,43 @@ int MarkDisconnectedComponents( ORIG_ATOM_DATA *orig_at_data, int bProcessOldCom
|
|
2722
2800
|
if ( !num_at ) {
|
2723
2801
|
return 0;
|
2724
2802
|
}
|
2725
|
-
if ( !( nNewCompNumber = (AT_NUMB *) inchi_calloc( num_at, sizeof(nNewCompNumber[0]) ) )
|
2803
|
+
if ( !( nNewCompNumber = (AT_NUMB *) inchi_calloc( num_at, sizeof(nNewCompNumber[0]) ) ) ||
|
2804
|
+
/* for non-recursive DFS only: */
|
2805
|
+
!( nPrevAtom = (AT_NUMB *) inchi_calloc( num_at, sizeof(nPrevAtom[0]) ) ) ||
|
2806
|
+
!( iNeigh = (S_CHAR *) inchi_calloc( num_at, sizeof(iNeigh[0]) ) )) {
|
2726
2807
|
goto exit_function;
|
2727
2808
|
}
|
2728
|
-
/* mark and count */
|
2729
|
-
|
2809
|
+
/* mark and count; avoid deep DFS recursion: it may make verifying software unhappy */
|
2810
|
+
/* nNewCompNumber[i] will contain new component number for atoms at[i], i=0..num_at-1 */
|
2811
|
+
for ( j = 0; j < num_at; j++ ) {
|
2730
2812
|
if ( !nNewCompNumber[j] ) {
|
2731
|
-
/*
|
2732
|
-
|
2813
|
+
/* mark starting with at[j] */
|
2814
|
+
int fst_at, nxt_at, cur_at = j;
|
2733
2815
|
num_components ++;
|
2816
|
+
/* first time at at[j] */
|
2817
|
+
nNewCompNumber[fst_at = cur_at] = (AT_NUMB) num_components;
|
2818
|
+
/* find next neighbor */
|
2819
|
+
while ( 1 ) {
|
2820
|
+
if ( iNeigh[cur_at] < at[cur_at].valence ) {
|
2821
|
+
nxt_at = at[cur_at].neighbor[(int)iNeigh[cur_at] ++];
|
2822
|
+
if ( !nNewCompNumber[nxt_at] ) {
|
2823
|
+
/* forward edge: found new atom */
|
2824
|
+
nNewCompNumber[nxt_at] = (AT_NUMB) num_components;
|
2825
|
+
nPrevAtom[nxt_at] = (AT_NUMB) cur_at;
|
2826
|
+
cur_at = nxt_at;
|
2827
|
+
}
|
2828
|
+
} else
|
2829
|
+
if ( cur_at == fst_at ) {
|
2830
|
+
break; /* done */
|
2831
|
+
} else {
|
2832
|
+
cur_at = nPrevAtom[cur_at]; /* retract */
|
2833
|
+
}
|
2834
|
+
}
|
2734
2835
|
}
|
2735
2836
|
}
|
2837
|
+
inchi_free( nPrevAtom ); nPrevAtom = NULL;
|
2838
|
+
inchi_free( iNeigh ); iNeigh = NULL;
|
2839
|
+
|
2736
2840
|
/* Allocate more memory */
|
2737
2841
|
i = inchi_max( num_components, orig_at_data->num_components );
|
2738
2842
|
if ( !(nCurAtLen = (AT_NUMB *) inchi_calloc( num_components+1, sizeof(nCurAtLen[0]) ) ) ||
|
@@ -2814,6 +2918,14 @@ exit_function:
|
|
2814
2918
|
inchi_free( component_nbr );
|
2815
2919
|
|
2816
2920
|
if ( ret < 0 ) {
|
2921
|
+
if ( nPrevAtom ) {
|
2922
|
+
inchi_free( nPrevAtom );
|
2923
|
+
nPrevAtom = NULL;
|
2924
|
+
}
|
2925
|
+
if ( iNeigh ) {
|
2926
|
+
inchi_free( iNeigh );
|
2927
|
+
iNeigh = NULL;
|
2928
|
+
}
|
2817
2929
|
if ( nCurAtLen ) {
|
2818
2930
|
inchi_free( nCurAtLen );
|
2819
2931
|
nCurAtLen = NULL;
|
@@ -2835,7 +2947,7 @@ exit_function:
|
|
2835
2947
|
|
2836
2948
|
orig_at_data->num_components = num_components;
|
2837
2949
|
|
2838
|
-
return
|
2950
|
+
return ret; /* number of disconnected components; 1=>single connected structure*/
|
2839
2951
|
}
|
2840
2952
|
/******************************************************************************/
|
2841
2953
|
/* Extract one (connected) component */
|
@@ -2932,13 +3044,21 @@ int Free_INChI(INChI **ppINChI)
|
|
2932
3044
|
if ( pINChI->nRefCount -- > 0 )
|
2933
3045
|
return 1;
|
2934
3046
|
#endif
|
3047
|
+
Free_INChI_Members(pINChI);
|
3048
|
+
|
3049
|
+
qzfree( pINChI );
|
3050
|
+
*ppINChI = NULL;
|
3051
|
+
|
3052
|
+
}
|
3053
|
+
return 0;
|
3054
|
+
}
|
3055
|
+
/****************************************************************/
|
3056
|
+
int Free_INChI_Members(INChI *pINChI)
|
3057
|
+
{
|
3058
|
+
if ( pINChI ) {
|
2935
3059
|
|
2936
3060
|
Free_INChI_Stereo(pINChI->Stereo );
|
2937
3061
|
Free_INChI_Stereo(pINChI->StereoIsotopic );
|
2938
|
-
/*
|
2939
|
-
Free_INChI_Stereo(pINChI->StereoInv );
|
2940
|
-
Free_INChI_Stereo(pINChI->StereoIsotopicInv);
|
2941
|
-
*/
|
2942
3062
|
qzfree(pINChI->nAtom );
|
2943
3063
|
qzfree(pINChI->nConnTable );
|
2944
3064
|
qzfree(pINChI->nTautomer );
|
@@ -2949,29 +3069,10 @@ int Free_INChI(INChI **ppINChI)
|
|
2949
3069
|
qzfree(pINChI->nPossibleLocationsOfIsotopicH);
|
2950
3070
|
qzfree(pINChI->Stereo );
|
2951
3071
|
qzfree(pINChI->StereoIsotopic );
|
2952
|
-
/*
|
2953
|
-
qzfree(pINChI->StereoInv );
|
2954
|
-
qzfree(pINChI->StereoIsotopicInv);
|
2955
|
-
*/
|
2956
3072
|
qzfree(pINChI->szHillFormula );
|
2957
|
-
/*
|
2958
|
-
pINChI->nAtom = NULL;
|
2959
|
-
pINChI->nConnTable = NULL;
|
2960
|
-
pINChI->nTautomer = NULL;
|
2961
|
-
pINChI->nNum_H = NULL;
|
2962
|
-
pINChI->IsotopicAtom = NULL;
|
2963
|
-
pINChI->IsotopicTGroup = NULL;
|
2964
|
-
pINChI->Stereo = NULL;
|
2965
|
-
pINChI->StereoIsotopic = NULL;
|
2966
|
-
pINChI->szHillFormula = NULL;
|
2967
|
-
*/
|
2968
|
-
qzfree( pINChI );
|
2969
|
-
*ppINChI = NULL;
|
2970
|
-
|
2971
3073
|
}
|
2972
3074
|
return 0;
|
2973
3075
|
}
|
2974
|
-
|
2975
3076
|
/****************************************************************/
|
2976
3077
|
INChI *Alloc_INChI( inp_ATOM *at, int num_at, int *found_num_bonds, int *found_num_isotopic, int nAllocMode )
|
2977
3078
|
{
|
@@ -3126,7 +3227,7 @@ INChI_Aux *Alloc_INChI_Aux( int num_at, int num_isotopic_atoms, int nAllocMode,
|
|
3126
3227
|
}
|
3127
3228
|
|
3128
3229
|
if ( num_at > 1 &&
|
3129
|
-
(pINChI_Aux->nConstitEquTGroupNumbers = (AT_NUMB*)inchi_calloc(sizeof(pINChI_Aux->nConstitEquTGroupNumbers[0]), num_at/2)) ) {
|
3230
|
+
(pINChI_Aux->nConstitEquTGroupNumbers = (AT_NUMB*)inchi_calloc(sizeof(pINChI_Aux->nConstitEquTGroupNumbers[0]), num_at/2+1)) ) {
|
3130
3231
|
;
|
3131
3232
|
} else
|
3132
3233
|
if ( num_at > 1 ) {
|
@@ -3154,7 +3255,7 @@ INChI_Aux *Alloc_INChI_Aux( int num_at, int num_isotopic_atoms, int nAllocMode,
|
|
3154
3255
|
goto out_of_RAM;
|
3155
3256
|
}
|
3156
3257
|
if ( /*num_isotopic_atoms && num_at > 1 &&*/
|
3157
|
-
(pINChI_Aux->nConstitEquIsotopicTGroupNumbers = (AT_NUMB*)inchi_calloc(sizeof(pINChI_Aux->nConstitEquIsotopicTGroupNumbers[0]), num_at/2)) ) {
|
3258
|
+
(pINChI_Aux->nConstitEquIsotopicTGroupNumbers = (AT_NUMB*)inchi_calloc(sizeof(pINChI_Aux->nConstitEquIsotopicTGroupNumbers[0]), num_at/2+1)) ) {
|
3158
3259
|
;
|
3159
3260
|
} else
|
3160
3261
|
if ( num_isotopic_atoms && num_at > 1 ) {
|
@@ -3174,21 +3275,44 @@ out_of_RAM:
|
|
3174
3275
|
return NULL;
|
3175
3276
|
}
|
3176
3277
|
/***********************************************************************************/
|
3177
|
-
|
3178
|
-
|
3179
|
-
|
3278
|
+
|
3279
|
+
#define IS_DEUTERIUM(i) (!strcmp( at[i].elname, "D" ) || at[i].iso_atw_diff == 2 && !strcmp( at[i].elname, "H" ))
|
3280
|
+
#define IS_TRITIUM(i) (!strcmp( at[i].elname, "T" ) || at[i].iso_atw_diff == 3 && !strcmp( at[i].elname, "H" ))
|
3281
|
+
|
3282
|
+
#define ABNORMAL_ISO(i) (at[i].iso_atw_diff == 1 || at[i].iso_atw_diff < -3 || at[i].iso_atw_diff > 5 )
|
3283
|
+
#define ABNORMAL_CHG(i) (abs(at[i].charge) > 3)
|
3284
|
+
#define ABNORMAL_RAD(i) (RADICAL_SINGLET <= at[i].radical && at[i].radical <= RADICAL_TRIPLET )
|
3285
|
+
|
3286
|
+
#define ANY_ISO(i, X) ((X)? (at[i].iso_atw_diff && !IS_DEUTERIUM(i) && !IS_TRITIUM(i)) :\
|
3287
|
+
(at[i].iso_atw_diff || IS_DEUTERIUM(i) || IS_TRITIUM(i)))
|
3288
|
+
#define ANY_CHG(i) (0 != at[i].charge)
|
3289
|
+
#define ANY_RAD(i) (RADICAL_SINGLET <= at[i].radical && at[i].radical <= RADICAL_TRIPLET )
|
3290
|
+
|
3291
|
+
#define NORMAL_ISO(i, X) (ANY_ISO(i, X) && !ABNORMAL_ISO(i))
|
3292
|
+
|
3293
|
+
|
3294
|
+
/* needs additional M CHG. M RAD, M ISO line */
|
3295
|
+
/* due to ISIS/Draw feature always include M RAD for any radical */
|
3296
|
+
#define ABNORMAL_AT(i) ( at[i].radical || abs(at[i].charge) > 3 || \
|
3297
|
+
ABNORMAL_ISO(i) )
|
3298
|
+
|
3299
|
+
/* always add M ISO, M RAD, M CHG; Except: (bAtomsDT && D or T) */
|
3300
|
+
#define ADD_LINE_AT(i) ( at[i].charge || \
|
3301
|
+
at[i].radical || \
|
3302
|
+
at[i].iso_atw_diff && (bAtomsDT? (at[i].iso_atw_diff != 1 || strcmp(at[i].elname, "H")) : 1) )
|
3180
3303
|
#define ALIASED_AT(i) (0 < NUM_ISO_H(at, i))
|
3181
3304
|
/***********************************************************************************/
|
3182
|
-
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 )
|
3305
|
+
#if( TEST_RENUMB_ATOMS_SAVE_LONGEST == 1 || TEST_RENUMB_SWITCH == 1 )
|
3183
3306
|
int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char* name, const char* comment,
|
3184
3307
|
const char *szLabel, const char *szValue)
|
3185
3308
|
{
|
3186
|
-
int i, j, k, num_bonds=0, ret=0
|
3309
|
+
int i, j, k, num_bonds=0, ret=0, bAtomsDT = 1 /* treat D, T as normal atoms */, bV2000 = 0 /*V2000 Molfile */;
|
3187
3310
|
int bAtomNeedsAlias;
|
3188
|
-
int flag_bad_charge=0, nNumAddLines=0,
|
3311
|
+
int flag_bad_charge=0, flag_bad_iso=0, nNumAddLines=0, nNumIsoLines=0, nNumChargeLines=0, nNumRadicalLines=0, nNumAliasLines=0;
|
3312
|
+
int nNumNecessaryIsoLines = 0, nNumNecessaryChgLines = 0, nNumNecessaryRadLines = 0;
|
3189
3313
|
/*sp_ATOM *at; */
|
3190
|
-
float fzero=0.0F
|
3191
|
-
double x, y;
|
3314
|
+
/*float fzero=0.0F;*/
|
3315
|
+
double x, y, z;
|
3192
3316
|
int bNext /*, s*/;
|
3193
3317
|
const inp_ATOM *at = inp_at_data->at_fixed_bonds? inp_at_data->at_fixed_bonds : inp_at_data->at;
|
3194
3318
|
int num_atoms = inp_at_data->num_at;
|
@@ -3233,105 +3357,95 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3233
3357
|
num_bonds += at[i].valence;
|
3234
3358
|
num_bonds /= 2;
|
3235
3359
|
|
3236
|
-
/*find if we need "M CHG"
|
3237
|
-
for (i=0, nNumAddLines = 0
|
3238
|
-
bAtomNeedsAlias = ALIASED_AT(i)
|
3239
|
-
|
3240
|
-
|
3241
|
-
|
3360
|
+
/*find if we need "M CHG", "M RAD", "M ISO" */
|
3361
|
+
for (i=0, nNumAddLines = 0; i < num_atoms; i++) {
|
3362
|
+
if ( bAtomNeedsAlias = ALIASED_AT(i) ) {
|
3363
|
+
nNumAliasLines += 2 * bAtomNeedsAlias;
|
3364
|
+
} else {
|
3365
|
+
nNumNecessaryIsoLines += ABNORMAL_ISO(i);
|
3366
|
+
nNumNecessaryChgLines += ABNORMAL_CHG(i);
|
3367
|
+
nNumNecessaryRadLines += ABNORMAL_RAD(i);
|
3368
|
+
nNumIsoLines += ANY_ISO(i, bAtomsDT);
|
3369
|
+
nNumChargeLines += ANY_CHG(i);
|
3370
|
+
nNumRadicalLines += ANY_RAD(i);
|
3371
|
+
}
|
3242
3372
|
}
|
3243
|
-
|
3244
|
-
|
3245
|
-
|
3246
|
-
|
3247
|
-
|
3248
|
-
|
3373
|
+
if ( !bV2000 ) {
|
3374
|
+
if ( !nNumNecessaryRadLines && !nNumNecessaryChgLines ) {
|
3375
|
+
nNumRadicalLines = 0;
|
3376
|
+
nNumChargeLines = 0;
|
3377
|
+
}
|
3378
|
+
if ( !nNumNecessaryIsoLines ) {
|
3379
|
+
nNumIsoLines = 0;
|
3249
3380
|
}
|
3250
3381
|
}
|
3382
|
+
|
3383
|
+
|
3384
|
+
/* count additional M lines*/
|
3251
3385
|
nNumChargeLines = ( nNumChargeLines + 7 ) / 8;
|
3252
3386
|
nNumRadicalLines = ( nNumRadicalLines + 7 ) / 8;
|
3253
|
-
|
3387
|
+
nNumIsoLines = ( nNumIsoLines + 7 ) / 8;
|
3254
3388
|
|
3255
|
-
nNumAddLines = nNumChargeLines + nNumRadicalLines + nNumAliasLines; /* 1 for M END*/
|
3389
|
+
nNumAddLines = nNumChargeLines + nNumRadicalLines + nNumIsoLines + nNumAliasLines; /* 1 for M END*/
|
3256
3390
|
|
3257
|
-
if ( nNumAddLines
|
3258
|
-
|
3259
|
-
} else {
|
3260
|
-
nNumAddLines += nNumIso+1; /* add 1 for "M END" line*/
|
3391
|
+
if ( nNumAddLines || bV2000 ) {
|
3392
|
+
nNumAddLines += 1; /* add 1 for "M END" line*/
|
3261
3393
|
}
|
3262
3394
|
|
3263
|
-
/*
|
3395
|
+
/* aaabbblllfffcccsssxxxrrrpppiiimmmvvvvvv*/
|
3264
3396
|
inchi_print_nodisplay(fcb,"%3d%3d 0 0 0 0 0 0 0 0%3d%s\n",num_atoms, num_bonds, nNumAddLines,nNumAddLines?" V2000":"");
|
3265
3397
|
/* atoms block*/
|
3266
3398
|
for (i=0; i < num_atoms; i++) {
|
3267
|
-
char elname[ATOM_EL_LEN]
|
3399
|
+
char elname[ATOM_EL_LEN];
|
3268
3400
|
int iso = 0;
|
3269
3401
|
int charge = 0;
|
3270
3402
|
int valence = 0;
|
3271
|
-
|
3272
|
-
/*
|
3273
|
-
|
3274
|
-
|
3275
|
-
|
3276
|
-
if ( iso ) {
|
3277
|
-
/* deuterium or tritium*/
|
3278
|
-
strcpy ( elname, "H" );
|
3279
|
-
} else
|
3403
|
+
int nIsotopeH = IS_DEUTERIUM(i)? 1 : IS_TRITIUM(i)? 2 : 0;
|
3404
|
+
bAtomNeedsAlias = ALIASED_AT(i); /* Has implicit D and/or T neighbors */
|
3405
|
+
memset( elname, 0, sizeof(elname) );
|
3406
|
+
|
3280
3407
|
if ( bAtomNeedsAlias ) {
|
3408
|
+
/* alias */
|
3281
3409
|
strcpy ( elname, "C" );
|
3282
3410
|
} else {
|
3283
|
-
|
3284
|
-
|
3285
|
-
|
3286
|
-
|
3287
|
-
|
3288
|
-
|
3289
|
-
|
3290
|
-
|
3291
|
-
|
3292
|
-
|
3293
|
-
|
3294
|
-
|
3295
|
-
|
3296
|
-
|
3297
|
-
|
3298
|
-
|
3299
|
-
|
3300
|
-
|
3301
|
-
|
3302
|
-
|
3303
|
-
case 2: charge = 2; break;
|
3304
|
-
case 1: charge = 3; break;
|
3305
|
-
case -1: charge = 5; break;
|
3306
|
-
case -2: charge = 6; break;
|
3307
|
-
case -3: charge = 7; break;
|
3308
|
-
case 0: charge = 0; break;
|
3309
|
-
default: flag_bad_charge = 1; break;
|
3310
|
-
};
|
3411
|
+
/* isotope*/
|
3412
|
+
if ( nIsotopeH ) {
|
3413
|
+
strcpy( elname, bAtomsDT? ( nIsotopeH==1? "D" : "T" ) : "H" );
|
3414
|
+
} else {
|
3415
|
+
strncpy ( elname, at[i].elname, sizeof(elname)-1 );
|
3416
|
+
}
|
3417
|
+
if ( !ABNORMAL_CHG(i) && !ANY_RAD(i) ) {
|
3418
|
+
/* charge*/
|
3419
|
+
/* Only atoms without alias can be here*/
|
3420
|
+
switch ( at[i].charge ) {
|
3421
|
+
case 3: charge = 1; break;
|
3422
|
+
case 2: charge = 2; break;
|
3423
|
+
case 1: charge = 3; break;
|
3424
|
+
case -1: charge = 5; break;
|
3425
|
+
case -2: charge = 6; break;
|
3426
|
+
case -3: charge = 7; break;
|
3427
|
+
case 0: charge = 0; break;
|
3428
|
+
default: flag_bad_charge = 1; break;
|
3429
|
+
};
|
3430
|
+
}
|
3311
3431
|
/* radical*/
|
3312
|
-
if (
|
3432
|
+
if ( ANY_RAD(i) && !ANY_CHG(i) ) {
|
3313
3433
|
if ( at[i].radical == RADICAL_DOUBLET ) {
|
3314
|
-
flag_bad_charge |= (charge != 0);
|
3315
3434
|
charge = 4;
|
3316
|
-
} else {
|
3317
|
-
flag_bad_charge |= 2;
|
3318
3435
|
}
|
3319
3436
|
}
|
3320
|
-
|
3321
|
-
|
3322
|
-
|
3437
|
+
}
|
3438
|
+
/* allow isotopic shift for aliased atoms */
|
3439
|
+
if ( NORMAL_ISO(i, bAtomsDT) ) {
|
3440
|
+
iso = at[i].iso_atw_diff > 0? at[i].iso_atw_diff-1:
|
3441
|
+
at[i].iso_atw_diff < 0? at[i].iso_atw_diff :
|
3442
|
+
nIsotopeH? nIsotopeH : (flag_bad_iso ++, 0);
|
3323
3443
|
}
|
3324
3444
|
|
3325
3445
|
x = at[i].x;
|
3326
3446
|
y = at[i].y;
|
3327
|
-
|
3328
|
-
|
3329
|
-
x = (x - c->xShift)/c->xCoeff;
|
3330
|
-
y = (y - c->yShift)/c->yCoeff;
|
3331
|
-
} else {
|
3332
|
-
y = -y;
|
3333
|
-
}
|
3334
|
-
----------------------*/
|
3447
|
+
z = at[i].z;
|
3448
|
+
|
3335
3449
|
if( at[i].num_H > 0 ) {
|
3336
3450
|
for ( j = 0, valence = 0; j < at[i].valence; j++ ) {
|
3337
3451
|
switch( k = at[i].bond_type[j] ) { /* fixed valence calculation 12-23-99 DCh.*/
|
@@ -3349,7 +3463,7 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3349
3463
|
valence = valence/2 + at[i].num_H;
|
3350
3464
|
} else
|
3351
3465
|
/* Added 07-09-2003 DCh*/
|
3352
|
-
if ( at[i].chem_bonds_valence > 0
|
3466
|
+
if ( at[i].chem_bonds_valence > 0 ) {
|
3353
3467
|
valence = at[i].chem_bonds_valence;
|
3354
3468
|
} else
|
3355
3469
|
/* Added 07-09-2003 DCh*/
|
@@ -3360,7 +3474,7 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3360
3474
|
/* (float)at[i].x, (float)(-at[i].y), fzero, at[i].elname, iso, charge);*/
|
3361
3475
|
/* xxxxxxyyyyyyzzzzzz aaa____ddcccsssnnnbbbvvvrrriiimmmeee */
|
3362
3476
|
inchi_print_nodisplay(fcb,"%10.4f%10.4f%10.4f %-3.3s%2d%3d 0 0%3d 0 0 0 0\n",
|
3363
|
-
x, y,
|
3477
|
+
x, y, z, elname, (int)iso, (int)charge, valence /* at[i].special*/);
|
3364
3478
|
/* reflect image against x-axis;
|
3365
3479
|
when transforming MOLfile back to STDATA in mol_to_stdata(...),
|
3366
3480
|
make one more reflection to restore original orientation.
|
@@ -3401,9 +3515,29 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3401
3515
|
num_m = 0;
|
3402
3516
|
for (i=0; i < num_atoms; i++) {
|
3403
3517
|
if ( ALIASED_AT(i) ) {
|
3518
|
+
int num_H;
|
3404
3519
|
inchi_print_nodisplay( fcb, "A %d\n", i+1 );
|
3405
3520
|
num_m ++;
|
3406
3521
|
strcpy( str_m, at[i].elname );
|
3522
|
+
/* Add H, D, T */
|
3523
|
+
if ( num_H = at[i].num_H + at[i].num_iso_H[0] ) { /* protium is lost here */
|
3524
|
+
strcat( str_m, "H" );
|
3525
|
+
if ( num_H > 1 ) {
|
3526
|
+
sprintf( str_m + strlen(str_m), "%d", num_H );
|
3527
|
+
}
|
3528
|
+
}
|
3529
|
+
if ( num_H = at[i].num_iso_H[1] ) { /* deuterium */
|
3530
|
+
strcat( str_m, "D" );
|
3531
|
+
if ( num_H > 1 ) {
|
3532
|
+
sprintf( str_m + strlen(str_m), "%d", num_H );
|
3533
|
+
}
|
3534
|
+
}
|
3535
|
+
if ( num_H = at[i].num_iso_H[2] ) { /* Tritium */
|
3536
|
+
strcat( str_m, "T" );
|
3537
|
+
if ( num_H > 1 ) {
|
3538
|
+
sprintf( str_m + strlen(str_m), "%d", num_H );
|
3539
|
+
}
|
3540
|
+
}
|
3407
3541
|
/* Add charge to the Alias */
|
3408
3542
|
if ( at[i].charge){
|
3409
3543
|
strcat(str_m, at[i].charge>0? "+" : "-");
|
@@ -3411,8 +3545,16 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3411
3545
|
sprintf( str_m+strlen(str_m), "%d", j );
|
3412
3546
|
}
|
3413
3547
|
/* Add radical to the Alias */
|
3414
|
-
|
3548
|
+
switch( at[i].radical ) {
|
3549
|
+
case RADICAL_SINGLET:
|
3550
|
+
strcat( str_m, ":" );
|
3551
|
+
break;
|
3552
|
+
case RADICAL_DOUBLET:
|
3415
3553
|
strcat( str_m, "^" );
|
3554
|
+
break;
|
3555
|
+
case RADICAL_TRIPLET:
|
3556
|
+
strcat( str_m, "^^" );
|
3557
|
+
break;
|
3416
3558
|
}
|
3417
3559
|
inchi_print_nodisplay( fcb, "%s\n", str_m );
|
3418
3560
|
num_m ++;
|
@@ -3428,7 +3570,7 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3428
3570
|
num_m = 0;
|
3429
3571
|
if ( nNumChargeLines ) {
|
3430
3572
|
for (i=0; i < num_atoms; i++) {
|
3431
|
-
if (
|
3573
|
+
if ( ANY_CHG(i) && !ALIASED_AT(i) ) {
|
3432
3574
|
sprintf( entry, " %3d %3d", i+1, (int)at[i].charge );
|
3433
3575
|
strcat( str_m, entry );
|
3434
3576
|
num_m ++;
|
@@ -3445,7 +3587,7 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3445
3587
|
num_m = 0;
|
3446
3588
|
if ( nNumRadicalLines ) {
|
3447
3589
|
for (i=0; i < num_atoms; i++) {
|
3448
|
-
if (
|
3590
|
+
if ( ANY_RAD(i) && !ALIASED_AT(i) ) {
|
3449
3591
|
int radical = (at[i].radical==RADICAL_SINGLET ||
|
3450
3592
|
at[i].radical==RADICAL_DOUBLET ||
|
3451
3593
|
at[i].radical==RADICAL_TRIPLET)? at[i].radical : 0;
|
@@ -3465,18 +3607,28 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3465
3607
|
/* isotopes*/
|
3466
3608
|
str_m[0] = 0;
|
3467
3609
|
num_m = 0;
|
3468
|
-
if (
|
3610
|
+
if ( nNumIsoLines ) {
|
3611
|
+
int el_num, iso;
|
3469
3612
|
for (i=0; i < num_atoms; i++) {
|
3470
|
-
if (
|
3471
|
-
|
3472
|
-
|
3473
|
-
|
3474
|
-
|
3475
|
-
|
3476
|
-
|
3613
|
+
if ( ANY_ISO(i,bAtomsDT) && !ALIASED_AT(i) ) {
|
3614
|
+
if ( IS_DEUTERIUM(i) ) {
|
3615
|
+
iso = 1;
|
3616
|
+
el_num = 1;
|
3617
|
+
} else
|
3618
|
+
if ( IS_TRITIUM(i) ) {
|
3619
|
+
iso = 2;
|
3620
|
+
el_num = 1;
|
3621
|
+
} else {
|
3622
|
+
iso = at[i].iso_atw_diff > 0? at[i].iso_atw_diff-1 : at[i].iso_atw_diff;
|
3623
|
+
el_num = at[i].el_number;
|
3624
|
+
}
|
3625
|
+
iso += get_atw_from_elnum( el_num );
|
3626
|
+
|
3627
|
+
sprintf( entry, " %3d %3d", i+1, iso );
|
3477
3628
|
strcat( str_m, entry );
|
3478
3629
|
num_m ++;
|
3479
3630
|
}
|
3631
|
+
|
3480
3632
|
if ( i == num_atoms-1 && num_m || num_m == 8 ) {
|
3481
3633
|
inchi_print_nodisplay( fcb, "M ISO%3d%s\n", num_m, str_m );
|
3482
3634
|
str_m[0] = 0;
|
@@ -3488,11 +3640,11 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3488
3640
|
}
|
3489
3641
|
if ( szValue && szValue[0] ) {
|
3490
3642
|
if ( szLabel && szLabel[0] ) {
|
3491
|
-
inchi_print_nodisplay( fcb, ">
|
3643
|
+
inchi_print_nodisplay( fcb, "> <%s>\n", szLabel );
|
3492
3644
|
} else {
|
3493
|
-
inchi_print_nodisplay( fcb, ">
|
3645
|
+
inchi_print_nodisplay( fcb, "> <ID>\n" );
|
3494
3646
|
}
|
3495
|
-
inchi_print_nodisplay( fcb, "
|
3647
|
+
inchi_print_nodisplay( fcb, "%s\n\n", szValue );
|
3496
3648
|
}
|
3497
3649
|
inchi_print_nodisplay(fcb, "$$$$\n");
|
3498
3650
|
|
@@ -3503,13 +3655,14 @@ int WriteToSDfile( const INP_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char
|
|
3503
3655
|
#endif
|
3504
3656
|
/***************************************************************************************************/
|
3505
3657
|
int WriteOrigAtomDataToSDfile( const ORIG_ATOM_DATA *inp_at_data, INCHI_FILE* fcb, const char* name, const char* comment,
|
3506
|
-
int bChiralFlag, const char *szLabel, const char *szValue)
|
3658
|
+
int bChiralFlag, int bAtomsDT, const char *szLabel, const char *szValue)
|
3507
3659
|
{
|
3508
3660
|
int i, j, k, num_bonds=0, ret=0;
|
3509
3661
|
int bAtomNeedsAlias;
|
3510
|
-
int flag_bad_charge=0,
|
3511
|
-
|
3512
|
-
|
3662
|
+
int flag_bad_charge=0, flag_bad_iso = 0;
|
3663
|
+
int nNumAddLines=0, nNumIsoLines=0, nNumChargeLines=0, nNumRadicalLines=0, nNumAliasLines=0;
|
3664
|
+
int nNumNecessaryIsoLines = 0, nNumNecessaryChgLines = 0, nNumNecessaryRadLines = 0;
|
3665
|
+
int bV2000 = SDF_OUTPUT_V2000;
|
3513
3666
|
double x, y, z;
|
3514
3667
|
int bNext /*, s*/;
|
3515
3668
|
const inp_ATOM *at = inp_at_data->at;
|
@@ -3563,34 +3716,43 @@ int WriteOrigAtomDataToSDfile( const ORIG_ATOM_DATA *inp_at_data, INCHI_FILE* fc
|
|
3563
3716
|
num_bonds /= 2;
|
3564
3717
|
|
3565
3718
|
/*find if we need "M CHG" and "M RAD"*/
|
3566
|
-
for (i=0
|
3567
|
-
bAtomNeedsAlias = ALIASED_AT(i)
|
3568
|
-
|
3569
|
-
|
3570
|
-
|
3571
|
-
|
3572
|
-
|
3573
|
-
|
3574
|
-
|
3575
|
-
|
3576
|
-
|
3577
|
-
|
3578
|
-
|
3719
|
+
for (i=0; i < num_atoms; i++) {
|
3720
|
+
if ( bAtomNeedsAlias = ALIASED_AT(i) ) { /* has isotopic implicit D or T; ignoring pure 1H */
|
3721
|
+
nNumAliasLines += 2 * bAtomNeedsAlias;
|
3722
|
+
} else {
|
3723
|
+
/* abnormal means atom needs CHG, RAD, or ISO entry */
|
3724
|
+
/* nNumAddLines += ABNORMAL_AT(i); */
|
3725
|
+
/* nNumIso += ( 0 == strcmp( at[i].elname, "D" ) || ( 0 == strcmp( at[i].elname, "T" ) || at[i].iso_atw_diff ) ); */
|
3726
|
+
/* nNumAddIso += at[i].iso_atw_diff && (at[i].iso_atw_diff == 1 || at[i].iso_atw_diff < -3 || at[i].iso_atw_diff > 5 ); */
|
3727
|
+
nNumNecessaryIsoLines += ABNORMAL_ISO(i);
|
3728
|
+
nNumNecessaryChgLines += ABNORMAL_CHG(i);
|
3729
|
+
nNumNecessaryRadLines += ABNORMAL_RAD(i);
|
3730
|
+
nNumIsoLines += ANY_ISO(i, bAtomsDT);
|
3731
|
+
nNumChargeLines += ANY_CHG(i);
|
3732
|
+
nNumRadicalLines += ANY_RAD(i);
|
3579
3733
|
}
|
3580
3734
|
}
|
3581
3735
|
nNumChargeLines = ( nNumChargeLines + 7 ) / 8;
|
3582
3736
|
nNumRadicalLines = ( nNumRadicalLines + 7 ) / 8;
|
3583
|
-
|
3737
|
+
nNumIsoLines = ( nNumIsoLines + 7 ) / 8;
|
3738
|
+
|
3739
|
+
if ( !bV2000 ) {
|
3740
|
+
if ( !nNumNecessaryRadLines && !nNumNecessaryChgLines ) {
|
3741
|
+
nNumRadicalLines = 0;
|
3742
|
+
nNumChargeLines = 0;
|
3743
|
+
}
|
3744
|
+
if ( !nNumNecessaryIsoLines ) {
|
3745
|
+
nNumIsoLines = 0;
|
3746
|
+
}
|
3747
|
+
}
|
3748
|
+
|
3749
|
+
|
3584
3750
|
/* recalculate number of added lines */
|
3585
|
-
nNumAddLines = nNumChargeLines + nNumRadicalLines + nNumAliasLines; /* 1 for M END*/
|
3751
|
+
nNumAddLines = nNumChargeLines + nNumRadicalLines + nNumIsoLines + nNumAliasLines; /* 1 for M END*/
|
3586
3752
|
|
3587
|
-
if ( nNumAddLines
|
3588
|
-
|
3589
|
-
} else {
|
3590
|
-
nNumAddLines += nNumIso+1; /* add 1 for "M END" line*/
|
3753
|
+
if ( nNumAddLines || bV2000 ) {
|
3754
|
+
nNumAddLines += 1; /* add 1 for "M END" line*/
|
3591
3755
|
}
|
3592
|
-
if ( !nNumAddLines )
|
3593
|
-
nNumAddLines = 1; /* always add V2000 and M END */
|
3594
3756
|
|
3595
3757
|
/* aaabbblllfffcccsssxxxrrrpppiiimmmvvvvvv*/
|
3596
3758
|
inchi_print_nodisplay(fcb,"%3d%3d 0 0%3d 0 0 0 0 0%3d%s\n",
|
@@ -3601,78 +3763,57 @@ int WriteOrigAtomDataToSDfile( const ORIG_ATOM_DATA *inp_at_data, INCHI_FILE* fc
|
|
3601
3763
|
int iso = 0;
|
3602
3764
|
int charge = 0;
|
3603
3765
|
int valence = 0;
|
3766
|
+
int nIsotopeH = IS_DEUTERIUM(i)? 1 : IS_TRITIUM(i)? 2 : 0;
|
3767
|
+
int bonds_val;
|
3604
3768
|
bAtomNeedsAlias = ALIASED_AT(i);
|
3605
|
-
|
3606
|
-
|
3607
|
-
!strcmp( at[i].elname, "T" )? 2: 0;
|
3608
|
-
|
3609
|
-
if ( iso ) {
|
3610
|
-
/* deuterium or tritium*/
|
3611
|
-
strcpy ( elname, "H" );
|
3612
|
-
} else
|
3769
|
+
memset( elname, 0, sizeof(elname) );
|
3770
|
+
|
3613
3771
|
if ( bAtomNeedsAlias ) {
|
3772
|
+
/* alias */
|
3614
3773
|
strcpy ( elname, "C" );
|
3615
3774
|
} else {
|
3616
|
-
|
3617
|
-
|
3618
|
-
|
3619
|
-
|
3620
|
-
|
3621
|
-
|
3622
|
-
|
3623
|
-
|
3624
|
-
|
3625
|
-
|
3626
|
-
|
3627
|
-
|
3628
|
-
|
3629
|
-
|
3630
|
-
|
3631
|
-
|
3632
|
-
|
3633
|
-
|
3634
|
-
|
3635
|
-
|
3636
|
-
|
3637
|
-
/* charge*/
|
3638
|
-
switch ( at[i].charge ) {
|
3639
|
-
case 3: charge = 1; break;
|
3640
|
-
case 2: charge = 2; break;
|
3641
|
-
case 1: charge = 3; break;
|
3642
|
-
case -1: charge = 5; break;
|
3643
|
-
case -2: charge = 6; break;
|
3644
|
-
case -3: charge = 7; break;
|
3645
|
-
case 0: charge = 0; break;
|
3646
|
-
default: flag_bad_charge = 1; break;
|
3647
|
-
};
|
3775
|
+
/* isotope*/
|
3776
|
+
if ( nIsotopeH ) {
|
3777
|
+
strcpy( elname, bAtomsDT? ( nIsotopeH==1? "D" : "T" ) : "H" );
|
3778
|
+
} else {
|
3779
|
+
strncpy ( elname, at[i].elname, sizeof(elname)-1 );
|
3780
|
+
}
|
3781
|
+
if ( !ABNORMAL_CHG(i) && !ANY_RAD(i) ) {
|
3782
|
+
/* charge*/
|
3783
|
+
/* Only atoms without alias can be here*/
|
3784
|
+
switch ( at[i].charge ) {
|
3785
|
+
case 3: charge = 1; break;
|
3786
|
+
case 2: charge = 2; break;
|
3787
|
+
case 1: charge = 3; break;
|
3788
|
+
case -1: charge = 5; break;
|
3789
|
+
case -2: charge = 6; break;
|
3790
|
+
case -3: charge = 7; break;
|
3791
|
+
case 0: charge = 0; break;
|
3792
|
+
default: flag_bad_charge = 1; break;
|
3793
|
+
};
|
3794
|
+
}
|
3648
3795
|
/* radical*/
|
3649
|
-
if (
|
3796
|
+
if ( ANY_RAD(i) && !ANY_CHG(i) ) {
|
3650
3797
|
if ( at[i].radical == RADICAL_DOUBLET ) {
|
3651
|
-
flag_bad_charge |= (charge != 0);
|
3652
3798
|
charge = 4;
|
3653
|
-
} else {
|
3654
|
-
flag_bad_charge |= 2;
|
3655
3799
|
}
|
3656
3800
|
}
|
3657
|
-
|
3658
|
-
|
3659
|
-
|
3801
|
+
}
|
3802
|
+
/* allow isotopic shift for aliased atoms */
|
3803
|
+
if ( NORMAL_ISO(i, bAtomsDT) ) {
|
3804
|
+
iso = at[i].iso_atw_diff > 0? at[i].iso_atw_diff-1:
|
3805
|
+
at[i].iso_atw_diff < 0? at[i].iso_atw_diff :
|
3806
|
+
nIsotopeH? nIsotopeH : (flag_bad_iso ++, 0);
|
3660
3807
|
}
|
3661
3808
|
|
3662
3809
|
x = at[i].x;
|
3663
3810
|
y = at[i].y;
|
3664
3811
|
z = at[i].z;
|
3665
|
-
|
3666
|
-
if ( c && c->xCoeff != 0.0 && c->yCoeff != 0.0 ) {
|
3667
|
-
x = (x - c->xShift)/c->xCoeff;
|
3668
|
-
y = (y - c->yShift)/c->yCoeff;
|
3669
|
-
} else {
|
3670
|
-
y = -y;
|
3671
|
-
}
|
3672
|
-
----------------------*/
|
3812
|
+
|
3673
3813
|
/* valence -- set only if needed */
|
3814
|
+
bonds_val = nBondsValenceInpAt( at+i, NULL, NULL );
|
3674
3815
|
valence=needed_unusual_el_valence( at[i].el_number, at[i].charge, at[i].radical,
|
3675
|
-
at[i].chem_bonds_valence, at
|
3816
|
+
at[i].chem_bonds_valence, bonds_val, NUMH(at, i), at[i].valence );
|
3676
3817
|
if ( valence < 0 ) {
|
3677
3818
|
valence = 15; /* means no bonds nor H */
|
3678
3819
|
}
|
@@ -3727,11 +3868,12 @@ int WriteOrigAtomDataToSDfile( const ORIG_ATOM_DATA *inp_at_data, INCHI_FILE* fc
|
|
3727
3868
|
num_m ++;
|
3728
3869
|
len = sprintf( str_m, "%s", at[i].elname );
|
3729
3870
|
/* add isotopic H to the alias */
|
3730
|
-
for ( k =
|
3731
|
-
|
3732
|
-
|
3733
|
-
|
3734
|
-
|
3871
|
+
for ( k = 0; k < NUM_H_ISOTOPES; k ++ ) {
|
3872
|
+
int num_H = at[i].num_iso_H[k] + (k? 0:at[i].num_H);
|
3873
|
+
if ( num_H ) {
|
3874
|
+
len += sprintf( str_m+len, "%s", k == 0? "H" : k==1? "D" : k==2? "T" : "?" );
|
3875
|
+
if ( num_H != 1 ) {
|
3876
|
+
len += sprintf( str_m+len, "%d", num_H );
|
3735
3877
|
}
|
3736
3878
|
}
|
3737
3879
|
}
|
@@ -3803,8 +3945,10 @@ int WriteOrigAtomDataToSDfile( const ORIG_ATOM_DATA *inp_at_data, INCHI_FILE* fc
|
|
3803
3945
|
/* isotopes*/
|
3804
3946
|
str_m[0] = 0;
|
3805
3947
|
num_m = 0;
|
3806
|
-
if (
|
3948
|
+
if ( nNumIsoLines ) {
|
3949
|
+
int el_num, iso;
|
3807
3950
|
for (i=0; i < num_atoms; i++) {
|
3951
|
+
/*
|
3808
3952
|
if ( 0 == strcmp( at[i].elname, "D" ) ) {
|
3809
3953
|
sprintf( entry, " %3d %3d", i+1, 2 );
|
3810
3954
|
strcat( str_m, entry );
|
@@ -3822,6 +3966,27 @@ int WriteOrigAtomDataToSDfile( const ORIG_ATOM_DATA *inp_at_data, INCHI_FILE* fc
|
|
3822
3966
|
strcat( str_m, entry );
|
3823
3967
|
num_m ++;
|
3824
3968
|
}
|
3969
|
+
*/
|
3970
|
+
if ( ANY_ISO(i, bAtomsDT) && !ALIASED_AT(i) ) {
|
3971
|
+
if ( IS_DEUTERIUM(i) ) {
|
3972
|
+
iso = 1;
|
3973
|
+
el_num = 1;
|
3974
|
+
} else
|
3975
|
+
if ( IS_TRITIUM(i) ) {
|
3976
|
+
iso = 2;
|
3977
|
+
el_num = 1;
|
3978
|
+
} else {
|
3979
|
+
iso = at[i].iso_atw_diff > 0? at[i].iso_atw_diff-1 : at[i].iso_atw_diff;
|
3980
|
+
el_num = at[i].el_number;
|
3981
|
+
}
|
3982
|
+
iso += get_atw_from_elnum( el_num );
|
3983
|
+
|
3984
|
+
sprintf( entry, " %3d %3d", i+1, iso );
|
3985
|
+
strcat( str_m, entry );
|
3986
|
+
num_m ++;
|
3987
|
+
}
|
3988
|
+
|
3989
|
+
|
3825
3990
|
if ( i == num_atoms-1 && num_m || num_m == 8 ) {
|
3826
3991
|
inchi_print_nodisplay( fcb, "M ISO%3d%s\n", num_m, str_m );
|
3827
3992
|
str_m[0] = 0;
|
@@ -3845,6 +4010,47 @@ int WriteOrigAtomDataToSDfile( const ORIG_ATOM_DATA *inp_at_data, INCHI_FILE* fc
|
|
3845
4010
|
return ret;
|
3846
4011
|
|
3847
4012
|
}
|
4013
|
+
#if( FIX_ADJ_RAD == 1 )
|
4014
|
+
/*************************************************************************/
|
4015
|
+
int FixNextRadicals( int cur_at, inp_ATOM *at );
|
4016
|
+
int FixNextRadicals( int cur_at, inp_ATOM *at )
|
4017
|
+
{
|
4018
|
+
int j, neigh, num_found = 0;
|
4019
|
+
for ( j = 0; j < at[cur_at].valence; j ++ ) {
|
4020
|
+
neigh = at[cur_at].neighbor[j];
|
4021
|
+
if ( at[neigh].radical == RADICAL_DOUBLET ) {
|
4022
|
+
at[neigh].radical = 0;
|
4023
|
+
num_found ++;
|
4024
|
+
num_found += FixNextRadicals( neigh, at );
|
4025
|
+
}
|
4026
|
+
}
|
4027
|
+
return num_found;
|
4028
|
+
}
|
4029
|
+
/*************************************************************************/
|
4030
|
+
int FixAdjacentRadicals( int num_inp_atoms, inp_ATOM *at )
|
4031
|
+
{
|
4032
|
+
int i, j;
|
4033
|
+
char *bVisited = NULL;
|
4034
|
+
int nNumFound = 0, neigh, cur_found;
|
4035
|
+
for ( i = 0; i < num_inp_atoms; i ++ ) {
|
4036
|
+
if ( at[i].radical == RADICAL_DOUBLET ) {
|
4037
|
+
cur_found = 1;
|
4038
|
+
for ( j = 0; j < at[i].valence; j ++ ) {
|
4039
|
+
neigh = at[i].neighbor[j];
|
4040
|
+
if ( at[neigh].radical == RADICAL_DOUBLET ) {
|
4041
|
+
cur_found ++;
|
4042
|
+
}
|
4043
|
+
}
|
4044
|
+
if ( cur_found >= 3 ) {
|
4045
|
+
nNumFound ++;
|
4046
|
+
at[i].radical = 0;
|
4047
|
+
nNumFound += FixNextRadicals( i, at );
|
4048
|
+
}
|
4049
|
+
}
|
4050
|
+
}
|
4051
|
+
return nNumFound;
|
4052
|
+
}
|
4053
|
+
#endif
|
3848
4054
|
|
3849
4055
|
#ifdef INCHI_ANSI_ONLY
|
3850
4056
|
#ifndef INCHI_LIBRARY
|