diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b324705..d8d7c572 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,13 +2,22 @@ cmake_minimum_required(VERSION 3.21 FATAL_ERROR) project(InChI C CXX) +option(COVERAGE "Enable coverage reporting" OFF) + +if(COVERAGE) + message(STATUS "Building with code coverage enabled") + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + add_compile_options(--coverage -O0 -g) + add_link_options(--coverage) + else() + message(WARNING "Coverage only supported with GCC or Clang") + endif() +endif() + set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 11) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") - include(FetchContent) FetchContent_Declare( googletest @@ -26,3 +35,11 @@ add_subdirectory(INCHI-1-SRC/INCHI_EXE/inchi-1/src) add_subdirectory(INCHI-1-SRC/INCHI_API/libinchi/src) add_subdirectory(INCHI-1-TEST/tests/test_unit) +if(COVERAGE) + add_custom_target(coverage + COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure + COMMAND find . -name '*.gcno' -exec gcov -b -c {} + + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Running tests and generating .gcov coverage reports" + ) +endif() diff --git a/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt b/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt index 60f769ed..8fd3b273 100644 --- a/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt +++ b/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt @@ -5,11 +5,18 @@ project(LibInChI_API VERSION 1.7) add_library(libinchi_compiler_flags INTERFACE) target_compile_features(libinchi_compiler_flags INTERFACE c_std_11) -set(gcc_like_cxx "$") -set(msvc_cxx "$") +# set(gcc_like_cxx "$") +# set(msvc_cxx "$") target_compile_options(libinchi_compiler_flags INTERFACE - "$<${gcc_like_cxx}:$>" - "$<${msvc_cxx}:$>" + # "$<$:<${gcc_like_cxx}:$>" + # "$<$:<${msvc_cxx}:$>" + # "$<$:<${gcc_like_cxx}:$>" + # "$<$:<${msvc_cxx}:$>" + + "$<$,$>:-g;-O1;-c;-fno-strict-aliasing;-Wno-all>" + "$<$,$>:-W3;-MT;-O2>" + "$<$,$>:-g;-O0;-fsanitize=address;-c;-fno-strict-aliasing;-Wno-all>" + "$<$,$>:-W3;-MT;-g;-O0>" ) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/static") @@ -165,8 +172,12 @@ string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAG set_target_properties(libinchi PROPERTIES PREFIX "") +target_link_options(libinchi PRIVATE + "$<$,$>:-fsanitize=address>" +) + if(UNIX AND NOT APPLE) target_link_options(libinchi PRIVATE "LINKER:--version-script=${P_LIBINCHI_MAP}/libinchi.map,-z,relro") elseif(WIN32 AND NOT MSVC) target_link_options(libinchi PRIVATE "LINKER:--version-script=${P_LIBINCHI_MAP}/libinchi.map") -endif() \ No newline at end of file +endif() diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c b/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c index 4c14a938..bcb40541 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichi_io.c @@ -1679,7 +1679,7 @@ int inchi_strbuf_addline(INCHI_IOS_STRING* buf, /****************************************************************************/ /* djb-rwth: placed as a global variable to avoid function buffer issues */ char it_buffer[32767]; -int _inchi_trace(char* format, ...) +int _inchi_trace(const char* format, ...) { /* TCHAR buffer[32767]; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichidrp.h b/INCHI-1-SRC/INCHI_BASE/src/ichidrp.h index ff555c93..7e0e7673 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichidrp.h +++ b/INCHI-1-SRC/INCHI_BASE/src/ichidrp.h @@ -187,6 +187,7 @@ typedef struct tagInputParms { int bNoWarnings; /* v. 1.06+ suppress warning messages */ int bHideInChI; /* v. 1.06+ Do not print InChI itself */ + int bEnhancedStereo; /* */ INCHI_MODE bTautFlags; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichimain.h b/INCHI-1-SRC/INCHI_BASE/src/ichimain.h index 779d6b3e..c7f45018 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichimain.h +++ b/INCHI-1-SRC/INCHI_BASE/src/ichimain.h @@ -125,7 +125,7 @@ typedef struct tagINCHI_OUT_CTL int iCurTautMode; int num_components; - int nNumRemovedProtons; + int nNumRemovedProtons; int nTag; int bTag1; int bTag2; diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichimake.c b/INCHI-1-SRC/INCHI_BASE/src/ichimake.c index 369133dc..0826571d 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichimake.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichimake.c @@ -608,22 +608,21 @@ int GetSp3RelRacAbs(const INChI* pINChI, INChI_Stereo* Stereo) nRet = SP3_REL; #endif } - else - if (pINChI->nFlags & INCHI_FLAG_RAC_STEREO) - { + else if (pINChI->nFlags & INCHI_FLAG_RAC_STEREO) + { #if ( REL_RAC_STEREO_IGN_1_SC == 1 ) - if (1 < Stereo->nNumberOfStereoCenters) - { - nRet = SP3_REL; - } -#else - nRet = SP3_RAC; -#endif - } - else + if (1 < Stereo->nNumberOfStereoCenters) { - nRet = SP3_ABS; + nRet = SP3_REL; } +#else + nRet = SP3_RAC; +#endif + } + else + { + nRet = SP3_ABS; + } } else #if ( REL_RAC_STEREO_IGN_1_SC == 1 ) diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichimake.h b/INCHI-1-SRC/INCHI_BASE/src/ichimake.h index 4f7f9db5..fd35db2a 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichimake.h +++ b/INCHI-1-SRC/INCHI_BASE/src/ichimake.h @@ -208,6 +208,20 @@ const char *EquString( int EquVal ); INCHI_IOS_STRING *buf, int nCtMode, int *bOverflow ); + int MakeEnhStereoString( INChI_Aux *pAux, + INCHI_IOS_STRING *strbuf, + const char* conf_stereo_string, + int **enh_stereo, + int nof_stereo_groups, + int nCtMode, + int *bOverflow ); + int MakeSlayerString( ORIG_ATOM_DATA *orig_inp_data, + INCHI_SORT *pINChISort, + INCHI_IOS_STRING *strbuf, + int bOutType, + int num_components, + int nCtMode, + int *bOverflow ); int MakeCRVString( ORIG_INFO *OrigInfo, int nLenCT, int bAddDelim, diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c b/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c index bfa14414..dcf4d9b8 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiparm.c @@ -122,7 +122,8 @@ int set_common_options_by_parg(const char* pArg, int* pbNPZz, int* pbNoWarnings, int* pbMergeHash, - int* pbHideInChI); + int* pbHideInChI, + int* pbEnhancedStereochemistry); /**************************************************************************** @@ -165,7 +166,8 @@ int set_common_options_by_parg(const char* pArg, int* pbNPZz, int* pbNoWarnings, int* pbMergeHash, - int* pbHideInChI + int* pbHideInChI, + int* pbEnhancedStereochemistry ) { int got = 0; @@ -266,6 +268,11 @@ int set_common_options_by_parg(const char* pArg, (*pbLooseTSACheck) = 1; got = 1; } + else if (!inchi_stricmp(pArg, "EnhancedStereochemistry")) + { + *pbEnhancedStereochemistry = 1; + got = 1; + } #ifndef USE_STDINCHI_API /* These options DO TURN OFF Std flag */ @@ -643,6 +650,7 @@ int ReadCommandLineParms(int argc, int bAcidTautomerism = (DISCONNECT_SALTS == 1) ? (TEST_REMOVE_S_ATOMS == 1 ? 2 : 1) : 0; int bUnchargedAcidTaut = (CHARGED_SALTS_ONLY == 0); int bMergeSaltTGroups = (DISCONNECT_SALTS == 1); + int bEnhancedStereochemistry = 0; #if ( MIN_SB_RING_SIZE > 0 ) int nMinDbRinSize = MIN_SB_RING_SIZE, mdbr = 0; #endif @@ -795,7 +803,8 @@ int ReadCommandLineParms(int argc, &bLargeMolecules, &bPolymers, &bFoldPolymerSRU, &bFrameShiftScheme, &bStereoAtZz, &bNPZz, - &bNoWarnings, &bMergeHash, &bHideInChI); + &bNoWarnings, &bMergeHash, &bHideInChI, + &bEnhancedStereochemistry); if (got) { ; @@ -1243,7 +1252,8 @@ int ReadCommandLineParms(int argc, &bLargeMolecules, &bPolymers, &bFoldPolymerSRU, &bFrameShiftScheme, &bStereoAtZz, &bNPZz, - &bNoWarnings, &bMergeHash, &bHideInChI); + &bNoWarnings, &bMergeHash, &bHideInChI, + &bEnhancedStereochemistry); if (got) { @@ -2120,6 +2130,8 @@ int ReadCommandLineParms(int argc, ip->bINChIOutputOptions2 = bINChIOutputOptions2; + ip->bEnhancedStereo = bEnhancedStereochemistry; + return 0; } diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c b/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c index 0547b3e5..0ee22261 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c @@ -129,6 +129,13 @@ static int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, INCHI_OUT_CTL *io, char *pLF, char *pTAB ); +static int OutputINCHI_StereoLayer_EnhancedStereo( CANON_GLOBALS *pCG, + INCHI_IOSTREAM *out_file, + INCHI_IOS_STRING *strbuf, + INCHI_OUT_CTL *io, + ORIG_ATOM_DATA *orig_inp_data, + char *pLF, + char *pTAB ); static int OutputINCHI_IsotopicLayer( CANON_GLOBALS *pCG, INCHI_IOSTREAM *out_file, INCHI_IOS_STRING *strbuf, @@ -150,11 +157,11 @@ static int OutputINCHI_PolymerLayer( CANON_GLOBALS *pCG, INCHI_IOSTREAM *out_fil INCHI_OUT_CTL *io, char *pLF, char *pTAB ); static int OutputINCHI_PolymerLayer_SingleUnit( OAD_PolymerUnit *u, int bPolymers, - int total_star_atoms, + int total_star_atoms, int *n_used_stars, - OAD_AtProps *aprops, + OAD_AtProps *aprops, int *cano_nums, - ORIG_ATOM_DATA *orig_inp_data, + ORIG_ATOM_DATA *orig_inp_data, ORIG_STRUCT *pOrigStruct, INCHI_IOS_STRING *strbuf ); static int OutputAUXINFO_HeaderAndNormalization_type( CANON_GLOBALS *pCG, @@ -1032,14 +1039,29 @@ int OutputINChI2( CANON_GLOBALS *pCG, return ret; } - -/* */ -/* OutputINChI1( ... ) */ -/* */ -/* Main actual worker which serializes InChI to string. */ -/* */ -/* Called from OutputINChI2( ... ) and from itself */ -/* */ +/** + * @brief Main actual worker which serializes InChI to string. Called from OutputINChI2( ... ) and from itself. + * + * @param pCG Pointer to global canonicalization data. + * @param strbuf Pointer to the output string buffer. + * @param pINChISortTautAndNonTaut2 Array of pointers to INCHI_SORT structures for tautomeric and non-tautomeric forms. + * @param INCHI_basic_or_INCHI_reconnected Flag indicating basic or reconnected InChI output. + * @param orig_inp_data Pointer to original atom data. + * @param pOrigStruct Pointer to the original structure data. + * @param ip Pointer to input parameters. + * @param bDisconnectedCoord Flag for disconnected metal coordination. + * @param bOutputType Output type (tautomeric/non-tautomeric/both). + * @param bINChIOutputOptions Bitmask of output options. + * @param num_components2 Array of component counts for each structure type. + * @param num_non_taut2 Array of non-tautomeric component counts. + * @param num_taut2 Array of tautomeric component counts. + * @param out_file Output stream for InChI string. + * @param log_file Output stream for logging. + * @param num_input_struct Number of input structures. + * @param pSortPrintINChIFlags Pointer to flags controlling sorting and printing. + * @param save_opt_bits Encoded bits for saved InChI creation options. + * @return int + */ int OutputINChI1( CANON_GLOBALS *pCG, INCHI_IOS_STRING *strbuf, INCHI_SORT *pINChISortTautAndNonTaut2[][TAUT_NUM], @@ -1160,7 +1182,7 @@ int OutputINChI1( CANON_GLOBALS *pCG, io.n_pzz = orig_inp_data->polymer->n_pzz; } } - + io.bPolymers = ip->bPolymers; @@ -1615,6 +1637,11 @@ int OutputINChI1( CANON_GLOBALS *pCG, io.bChargesRadVal[ii] |= 1; } } + + if (ip->bEnhancedStereo) + { + set_EnhancedStereo_t_m_layers(orig_inp_data, pINChI, pINChI_Aux); + } } } if (bCompExists) @@ -1701,6 +1728,10 @@ int OutputINChI1( CANON_GLOBALS *pCG, { is_beta = 1; } + else if (ip->bEnhancedStereo) + { + is_beta = 1; + } OutputINCHI_VersionAndKind( out_file, strbuf, bINChIOutputOptions, is_beta, pLF, pTAB ); } @@ -1753,7 +1784,11 @@ int OutputINChI1( CANON_GLOBALS *pCG, } /* InChI output: stereo (non-isotopic) */ - intermediate_result = OutputINCHI_StereoLayer( pCG, out_file, strbuf, &io, pLF, pTAB ); + if (ip->bEnhancedStereo) { + intermediate_result = OutputINCHI_StereoLayer_EnhancedStereo( pCG, out_file, strbuf, &io, orig_inp_data, pLF, pTAB ); + } else { + intermediate_result = OutputINCHI_StereoLayer( pCG, out_file, strbuf, &io, pLF, pTAB ); + } if (intermediate_result != 0) goto exit_function; @@ -2640,7 +2675,7 @@ int WriteOrigBonds( CANON_GLOBALS *pCG, num_trans = 0; /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ nNeighOrder[0] = 0; } - for (kk = 0; kk < at[j].valence; kk++) + for (kk = 0; kk < at[j].valence; kk++) { k = nNeighOrder[kk]; j2 = at[j].neighbor[k]; @@ -3121,7 +3156,7 @@ void set_line_separators( int bINChIOutputOptions, char **pLF, char **pTAB ) int bPlainTabbedOutput = 0 != ( bINChIOutputOptions & INCHI_OUT_TABBED_OUTPUT ) && bPlainText && !bPlainTextCommnts; - *pTAB = bPlainTabbedOutput ? "\t" : "\n"; + *pTAB = bPlainTabbedOutput ? (char*)"\t" : (char*)"\n"; } #else *pTAB = "\n"; @@ -3347,10 +3382,17 @@ int OutputINCHI_ChargeAndRemovedAddedProtonsLayers( CANON_GLOBALS *pCG, return 0; } - -/**************************************************************************** -Output InChI: stereo layer with sublayers -****************************************************************************/ +/** + * @brief Output InChI: stereo layer with sublayers. + * + * @param pCG Pointer to the CANON_GLOBALS structure containing global canonicalization data. + * @param out_file Pointer to the INCHI_IOSTREAM output stream where the stereo layer will be written. + * @param strbuf Pointer to an INCHI_IOS_STRING buffer used for string formatting and output. + * @param io Pointer to the INCHI_OUT_CTL structure containing output control and state information. + * @param pLF Pointer to a string used as the line feed (end-of-line) character(s). + * @param pTAB Pointer to a string used as the tab or separator character(s). + * @return Returns 0 on success, or a non-zero error code on failure. + */ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, INCHI_IOSTREAM *out_file, INCHI_IOS_STRING *strbuf, @@ -3359,16 +3401,10 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, char *pTAB ) { - { - int i; - i = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_t_SATOMS] ); /* djb-rwth: ignoring LLVM warning: variable used to store function return value */ - /* djb-rwth: removing redundant code */ - } - if (INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_b_SBONDS] ) || - INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_t_SATOMS] ) || - INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_m_SP3INV] ) || - INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_s_STYPE] )) + INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_t_SATOMS] ) || + INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_m_SP3INV] ) || + INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_s_STYPE] )) { /* stereo */ @@ -3377,8 +3413,7 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, /* sp2 */ - /*if ( bStereoSp2[io->iCurTautMode] )*/ - if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_b_SBONDS] ))) /* djb-rwth: addressing LLVM warning */ + if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_b_SBONDS] ))) { szGetTag( IdentLbl, io->nTag, io->bTag2 = io->bTag1 | IL_DBND, io->szTag2, &io->bAlways, 1 ); inchi_strbuf_reset( strbuf ); @@ -3386,8 +3421,8 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, if (INCHI_SEGM_FILL == io->nSegmAction) { io->tot_len = str_Sp2( io->pINChISort, io->pINChISort2, strbuf, &io->bOverflow, - io->bOutType, io->TAUT_MODE, io->num_components, - io->bSecondNonTautPass, io->bOmitRepetitions, io->bUseMulipliers ); + io->bOutType, io->TAUT_MODE, io->num_components, + io->bSecondNonTautPass, io->bOmitRepetitions, io->bUseMulipliers ); io->bNonTautNonIsoIdentifierNotEmpty += io->bSecondNonTautPass; } @@ -3408,7 +3443,7 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, /* sp3 */ - /*if ( bStereoSp3[io->iCurTautMode] )*/ + /* t-layer */ if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_t_SATOMS] ))) /* djb-rwth: addressing LLVM warning */ { io->bRelRac = io->bRelativeStereo[io->iCurTautMode] || io->bRacemicStereo[io->iCurTautMode]; @@ -3419,7 +3454,7 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, { io->tot_len = str_Sp3( io->pINChISort, io->pINChISort2, strbuf, &io->bOverflow, io->bOutType, io->TAUT_MODE, io->num_components, io->bRelRac, - io->bSecondNonTautPass, io->bOmitRepetitions, io->bUseMulipliers ); + io->bSecondNonTautPass, io->bOmitRepetitions, io->bUseMulipliers ); io->bNonTautNonIsoIdentifierNotEmpty += io->bSecondNonTautPass; } @@ -3432,12 +3467,13 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, } else { - if (io->bPlainTextTags == 1) inchi_ios_print_nodisplay( out_file, "/" ); /* sp3 */ + if (io->bPlainTextTags == 1) + { + inchi_ios_print_nodisplay( out_file, "/" ); /* sp3 */ + } } - /* bStereoAbsInverted[io->iCurTautMode] */ - - /* if ( bStereoAbs[io->iCurTautMode] ) */ + /* m-layer */ if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_m_SP3INV] ))) /* djb-rwth: addressing LLVM warning */ { szGetTag( IdentLbl, io->nTag, io->bTag2 = io->bTag1 | IL_INVS, io->szTag2, &io->bAlways, 1 ); @@ -3445,7 +3481,7 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, if (INCHI_SEGM_FILL == io->nSegmAction) { io->tot_len = str_StereoAbsInv( io->pINChISort, strbuf, - &io->bOverflow, io->bOutType, io->num_components ); + &io->bOverflow, io->bOutType, io->num_components ); io->bNonTautNonIsoIdentifierNotEmpty += io->bSecondNonTautPass; } @@ -3465,8 +3501,8 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, /* stereo type */ - /*if ( io->bRacemicStereo[io->iCurTautMode] || io->bRelativeStereo[io->iCurTautMode] || bStereoAbs[io->iCurTautMode] )*/ - if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_s_STYPE] ))) /* djb-rwth: addressing LLVM warning */ + /* s-layer */ + if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_s_STYPE] ))) { const char *p_stereo = io->bRelativeStereo[io->iCurTautMode] ? x_rel : io->bRacemicStereo[io->iCurTautMode] ? x_rac : x_abs; @@ -3490,15 +3526,193 @@ int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, } else { - if (io->bPlainTextTags == 1) inchi_ios_print_nodisplay( out_file, "////" ); /* sp3, sp2, abs-inv, stereo.type */ + if (io->bPlainTextTags == 1) + { + inchi_ios_print_nodisplay( out_file, "////" ); /* sp2, sp3, abs-inv, stereo.type */ + } } return 0; } +/** + * @brief Output InChI: stereo layer with sublayers for enhanced stereochemistry (absolute, relative, racemic). + * + * @param pCG Pointer to the CANON_GLOBALS structure containing global canonicalization data. + * @param out_file Pointer to the INCHI_IOSTREAM output stream where the stereo layer will be written. + * @param strbuf Pointer to an INCHI_IOS_STRING buffer used for string formatting and output. + * @param io Pointer to the INCHI_OUT_CTL structure containing output control and state information. + * @param orig_inp_data Pointer to the ORIG_ATOM_DATA containing e.g. atom information. + * @param pLF Pointer to a string used as the line feed (end-of-line) character(s). + * @param pTAB Pointer to a string used as the tab or separator character(s). + * @return Returns 0 on success, or a non-zero error code on failure. + */ +int OutputINCHI_StereoLayer_EnhancedStereo( + CANON_GLOBALS *pCG, + INCHI_IOSTREAM *out_file, + INCHI_IOS_STRING *strbuf, + INCHI_OUT_CTL *io, + ORIG_ATOM_DATA *orig_inp_data, + char *pLF, + char *pTAB ) +{ + + if (INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_b_SBONDS] ) || + INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_t_SATOMS] ) || + INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_m_SP3INV] ) || + INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_s_STYPE] )) + { + + /* stereo */ + + szGetTag( IdentLbl, io->nTag, io->bTag1 = IL_STER | io->bFhTag, io->szTag1, &io->bAlways, 1 ); + + /* sp2 */ + + if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_b_SBONDS] ))) + { + szGetTag( IdentLbl, io->nTag, io->bTag2 = io->bTag1 | IL_DBND, io->szTag2, &io->bAlways, 1 ); + inchi_strbuf_reset( strbuf ); + io->tot_len = 0; + if (INCHI_SEGM_FILL == io->nSegmAction) + { + io->tot_len = str_Sp2( io->pINChISort, io->pINChISort2, strbuf, &io->bOverflow, + io->bOutType, io->TAUT_MODE, io->num_components, + io->bSecondNonTautPass, io->bOmitRepetitions, io->bUseMulipliers ); + + io->bNonTautNonIsoIdentifierNotEmpty += io->bSecondNonTautPass; + } + + if (str_LineEnd( io->szTag2, &io->bOverflow, strbuf, -io->nSegmAction, io->bPlainTextTags )) + { + return 1; + } + inchi_ios_print_nodisplay( out_file, "%s%s", strbuf->pStr, pLF ); + } + else + { + if (io->bPlainTextTags == 1) + { + inchi_ios_print_nodisplay( out_file, "/" ); /* sp2 */ + } + } + + /* sp3 */ + + /* t-layer */ + if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_t_SATOMS] ))) /* djb-rwth: addressing LLVM warning */ + { + io->bRelRac = io->bRelativeStereo[io->iCurTautMode] || io->bRacemicStereo[io->iCurTautMode]; + szGetTag( IdentLbl, io->nTag, io->bTag2 = io->bTag1 | IL_SP3S, io->szTag2, &io->bAlways, 1 ); + inchi_strbuf_reset( strbuf ); + io->tot_len = 0; + if (INCHI_SEGM_FILL == io->nSegmAction) + { + io->tot_len = str_Sp3( io->pINChISort, io->pINChISort2, strbuf, &io->bOverflow, + io->bOutType, io->TAUT_MODE, io->num_components, io->bRelRac, + io->bSecondNonTautPass, io->bOmitRepetitions, io->bUseMulipliers ); + + io->bNonTautNonIsoIdentifierNotEmpty += io->bSecondNonTautPass; + } + + if (str_LineEnd( io->szTag2, &io->bOverflow, strbuf, -io->nSegmAction, io->bPlainTextTags )) + { + return 2; + } + inchi_ios_print_nodisplay( out_file, "%s%s", strbuf->pStr, pLF ); + } + else + { + if (io->bPlainTextTags == 1) + { + inchi_ios_print_nodisplay( out_file, "/" ); /* sp3 */ + } + } + + /* m-layer */ + if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_m_SP3INV] ))) /* djb-rwth: addressing LLVM warning */ + { + szGetTag( IdentLbl, io->nTag, io->bTag2 = io->bTag1 | IL_INVS, io->szTag2, &io->bAlways, 1 ); + inchi_strbuf_reset( strbuf ); + io->tot_len = 0; + if (INCHI_SEGM_FILL == io->nSegmAction) + { + io->tot_len = str_StereoAbsInv( io->pINChISort, strbuf, + &io->bOverflow, io->bOutType, io->num_components ); + io->bNonTautNonIsoIdentifierNotEmpty += io->bSecondNonTautPass; + } + + if (str_LineEnd( io->szTag2, &io->bOverflow, strbuf, -io->nSegmAction, io->bPlainTextTags )) + { + return 3; + } + inchi_ios_print_nodisplay( out_file, "%s%s", strbuf->pStr, pLF ); + } + else + { + if (io->bPlainTextTags == 1) + { + inchi_ios_print_nodisplay( out_file, "/" ); /* stereo-abs-inv */ + } + } + + /* stereo type */ + + /* s-layer */ + if ((io->nSegmAction = INChI_SegmentAction( io->sDifSegs[io->nCurINChISegment][DIFS_s_STYPE] ))) + { + const char *p_stereo = io->bRelativeStereo[io->iCurTautMode] ? x_rel : + io->bRacemicStereo[io->iCurTautMode] ? x_rac : x_abs; + + szGetTag( IdentLbl, io->nTag, io->bTag2 = io->bTag1 | IL_TYPS, io->szTag2, &io->bAlways, 1 ); + inchi_strbuf_reset( strbuf ); io->tot_len = 0; + + io->tot_len = 0; + if (INCHI_SEGM_FILL == io->nSegmAction) + { + if (orig_inp_data->v3000->n_steabs > 0 || + orig_inp_data->v3000->n_sterel > 0 || + orig_inp_data->v3000->n_sterac > 0) { + io->tot_len += MakeSlayerString( + orig_inp_data, + io->pINChISort, + strbuf, + io->bOutType, + io->num_components, + io->TAUT_MODE, + &io->bOverflow + ); + } else { + ( io->tot_len ) += MakeDelim( p_stereo, strbuf, &io->bOverflow ); + } + + io->bNonTautNonIsoIdentifierNotEmpty += io->bSecondNonTautPass; + } + if (str_LineEnd( io->szTag2, &io->bOverflow, strbuf, -io->nSegmAction, io->bPlainTextTags )) + { + return 1; + } + inchi_ios_print_nodisplay( out_file, "%s%s", strbuf->pStr, pLF ); + } + if (io->bPlainTextTags == 1) + { + inchi_ios_print_nodisplay( out_file, "/" ); /* no abs, inv or racemic stereo */ + } + } + else + { + if (io->bPlainTextTags == 1) + { + inchi_ios_print_nodisplay( out_file, "////" ); /* sp2, sp3, abs-inv, stereo.type */ + } + } + + return 0; +} /**************************************************************************** -Output InChI: isotopic layer and sublayers ****************************************************************************/ +Output InChI: isotopic layer and sublayers +****************************************************************************/ int OutputINCHI_IsotopicLayer( CANON_GLOBALS *pCG, INCHI_IOSTREAM *out_file, INCHI_IOS_STRING *strbuf, @@ -3908,7 +4122,7 @@ static int OutputINCHI_PolymerLayer( CANON_GLOBALS *pCG, nat = orig_inp_data->num_inp_atoms; num_inp_bonds = orig_inp_data->num_inp_bonds; - + if (pOrigStruct && !pOrigStruct->polymer) { return 0; @@ -4145,7 +4359,7 @@ static int OutputINCHI_PolymerLayer_SingleUnit( OAD_PolymerUnit *u, a2 = u->blist[1]; a3 = u->blist[2]; a4 = u->blist[3]; - + if (is_in_the_ilist( u->alist, a1, u->na )) { tmp = a2; @@ -4172,7 +4386,7 @@ static int OutputINCHI_PolymerLayer_SingleUnit( OAD_PolymerUnit *u, /* The first printed is the crossing bond pointing to more senior CRU end ("head") */ swap = (OAD_Polymer_IsFirstAtomRankLower(a2, a4, aprops) == 1); } - + if (swap) { inchi_strbuf_printf( strbuf, "(%-d-%-d,%-d-%-d)", a3, a4, a1, a2 ); @@ -4288,8 +4502,8 @@ static int OutputINCHI_PolymerLayer_SingleUnit( OAD_PolymerUnit *u, here at1, at2 is the most senior bond, and at1 is more senior than at2 all other pairs at3,at4, at5,at6, ... are sorted just in increasing - order of first number in pair, then second one, e.g.: at3frame_shift_scheme != FSS_NONE && u->nbkbonds >= 1 && u->cap1 >= 1 && u->cap2 >= 1) @@ -5046,7 +5260,7 @@ void EditINCHI_HidePolymerZz(INCHI_IOSTREAM *out, int n_pzz, int n_zy) eol_was_consumed = 0, pre_eol = 0, nonprt_sym = 0, nonprt_prev = 0; - if (n_zy > 0) + if (n_zy > 0) { /* We have some placeholder pseudo atoms which should not be removed below (if anyway they are allowed) */ if (n_pzz == 0) @@ -5131,7 +5345,7 @@ void EditINCHI_HidePolymerZz(INCHI_IOSTREAM *out, int n_pzz, int n_zy) AT_NUMB ia = (AT_NUMB) inchi_strtol(p, &q, 10); /* make compiler happy: */ /* djb-rwth: removing redundant code; ignoring LLVM warning: variable used to store function return value */ if (*q != '-') { - skip = 1; + skip = 1; } } } @@ -5283,7 +5497,7 @@ int CountPseudoElementInFormula( const char *pseudo, char *s ) /* djb-rwth: igno char prev = '/'; /* - format is + format is [sequence of] [.[int_mult[Zz[int_index]]]] */ @@ -5291,8 +5505,8 @@ int CountPseudoElementInFormula( const char *pseudo, char *s ) /* djb-rwth: igno { return 0; } - - p = s; + + p = s; while (*p) /*for (p = s ; *p; p++)*/ { @@ -5317,7 +5531,7 @@ int CountPseudoElementInFormula( const char *pseudo, char *s ) /* djb-rwth: igno { mult = (int)inchi_strtol(p, &q, 10); p = q; - prev = *q--; + prev = *q--; continue; } else @@ -5326,7 +5540,7 @@ int CountPseudoElementInFormula( const char *pseudo, char *s ) /* djb-rwth: igno } if (!mult) { - break; + break; } } else if (*p== pseudo[1] && prev== pseudo[0]) @@ -5446,7 +5660,7 @@ int MergeZzInHillFormula(INCHI_IOS_STRING *strbuf) { inchi_free(scopy); /* djb-rwth: avoiding memory leak */ return -1; /* failed */ - } + } memcpy(scopy, strbuf->pStr, strbuf->nAllocatedLength); stmp = (char *)inchi_calloc((long long)strbuf->nAllocatedLength + 1, sizeof(char)); /* djb-rwth: cast operator added */ if (!stmp) @@ -5458,7 +5672,7 @@ int MergeZzInHillFormula(INCHI_IOS_STRING *strbuf) inchi_strbuf_reset(strbuf); p0 = scopy; p = p0; - do + do { /* djb-rwth: removing redundant code */ pend = strchr(p, '.'); diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c b/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c index d9c37b6a..cef4b29c 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c @@ -471,8 +471,64 @@ int MakeMult( int mult, return 0; } +/** + * @brief Adds the number to the string buffer. + * + * @param number Input number to be added + * @param szTailingDelim Pointer to the trailing delimiter string + * @param buf Pointer to the output string buffer + * @param nCtMode Mode flag for string representation + * @param bOverflow Pointer to overflow flag + * @return Returns the number of characters added to the buffer + */ +int MakeNumber_EnhStereo( int number, + const char *szTailingDelim, + INCHI_IOS_STRING *buf, + int nCtMode, + int *bOverflow ) +{ + char szValue[2048]; + int len = 0; + int len_delim; + int n; + + if (*bOverflow) + { + return 0; + } + if (nCtMode & CT_MODE_ABC_NUMBERS) + { + len += MakeAbcNumber( szValue, ( int )sizeof( szValue ), NULL, number ); + } + else + { + len += MakeDecNumber( szValue, ( int )sizeof( szValue ), NULL, number ); + } + len_delim = (int) strlen( szTailingDelim ); + + if (len + len_delim < ( int )sizeof( szValue )) + { + strcpy(szValue + len, szTailingDelim); + n = inchi_strbuf_printf( buf, "%s", szValue ); + if (-1 == n) *bOverflow |= 1; + return n; + } + + *bOverflow |= 1; + + return 0; +} + /****************************************************************************/ +/** + * @brief Adds the delimiter to the string buffer if it is not empty and there is no overflow. + * + * @param szTailingDelim Pointer to the trailing delimiter string + * @param buf Pointer to the output string buffer + * @param bOverflow Pointer to overflow flag + * @return Returns the number of characters added to the buffer, or 0 if the delimiter is empty or there is an overflow + */ int MakeDelim( const char *szTailingDelim, INCHI_IOS_STRING *buf, int *bOverflow ) @@ -1464,7 +1520,7 @@ int MakeCRVString( ORIG_INFO *OrigInfo, } /* radical */ if (OrigInfo[k].cRadical) - { + { if (len >= 2047) /* djb-rwth: fixing coverity ID #499515 */ { len = 2047; @@ -2116,6 +2172,268 @@ int MakeStereoString( AT_NUMB *at1, return nLen; } +/** + * @brief Compares two integers for qsort. + * + * @param a First integer pointer. + * @param b Second integer pointer. + * @return Returns negative, zero, or positive value based on comparison. + */ +int compare_ints(const void *a, const void *b) { + int arg1 = *(const int *)a; + int arg2 = *(const int *)b; + return (arg1 > arg2) - (arg1 < arg2); +} + +/** + * @brief Compares the third value of two integer arrays for qsort. Used to sort enhanced stereochemistry groups based on the canonical atom number of the first atom in the group. + * + * @param a First integer array pointer. + * @param b Second integer array pointer. + * @return Returns negative, zero, or positive value based on comparison. + */ +int compare_third_value(const void *a, const void *b) { + const int *arr1 = *(const int **)a; + const int *arr2 = *(const int **)b; + return arr1[2] - arr2[2]; +} + +/** + * @brief Creates the enhanced stereochemistry string for the s - layer. + * + * @param pAux Pointer to the INCHI_AUX structure. + * @param conf_stereo_string Pointer to the configuration stereochemistry string (abs, rel, rac). + * @param enh_stereo Pointer to list of enhanced stereochemistry groups. + * @param nof_stereo_groups Number of enhanced stereochemistry groups. + * @param strbuf Pointer to the output string buffer. + * @param nCtMode Mode flag for string representation. + * @param bOverflow Pointer to overflow flag. + * @return Returns the length of the created string. + */ +int MakeEnhStereoString( INChI_Aux *pAux, + INCHI_IOS_STRING *strbuf, + const char* conf_stereo_string, + int **enh_stereo, + int nof_stereo_groups, + int nCtMode, + int *bOverflow ) +{ + int tot_len = 0; + int count_added = 0; + + if (pAux == NULL) { + return 0; + } + + if (enh_stereo == NULL) { + return 0; + } + + if (nof_stereo_groups < 1) { + return 0; + } + + tot_len += MakeDelim( conf_stereo_string, strbuf, bOverflow ); + + int **enh_stereo_canon = (int**)inchi_calloc(nof_stereo_groups, sizeof(int*)); + + // Converts the original atom numbers in the enhanced stereochemistry groups to canonical atom numbers + // and sorts the atoms within each group based on their canonical atom numbers. This ensures that the order of + // atoms in the string representation is consistent and does not depend on the order of atoms in the input data. + // enh_stereo_canon is a 2D array where each row corresponds to an enhanced stereochemistry group. The first element + // of each row (index 0) stores the number of atoms in the group, the second element (index 1) stores the count of found + // atoms, and the remaining elements (starting from index 2) store the canonical atom numbers of the atoms in the group. + for (int i = 0; i < nof_stereo_groups; i++) { + const int *atom_numbers = &enh_stereo[i][2]; + int count_found_atoms = 0; + int nof_atoms = enh_stereo[i][1]; + + enh_stereo_canon[i] = (int*)inchi_calloc(nof_atoms + 2, sizeof(int)); + enh_stereo_canon[i][0] = nof_atoms; + for (int j = 0; j < nof_atoms; j++) { + + int orig_atom_num = atom_numbers[j]; + int canon_atom_num = get_canonical_atom_number(pAux, orig_atom_num); + if (canon_atom_num != -1) { + count_found_atoms++; + } else { + canon_atom_num = INT_MAX; + } + + enh_stereo_canon[i][j + 2] = canon_atom_num; + } + enh_stereo_canon[i][1] = count_found_atoms; + + if (nof_atoms > 1) { + qsort(&enh_stereo_canon[i][2], nof_atoms, sizeof(int), compare_ints); + } + } + + // Sorts the enhanced stereochemistry groups based on the canonical atom number of the first atom in the group. + // This ensures that the groups are always in a consistent order in the string representation, regardless of the + // order they were added to the input data (e.g. AND1, AND2, ... or OR1, OR2, ...). + qsort(enh_stereo_canon, nof_stereo_groups, sizeof(int*), compare_third_value); + + // Creates the string for the stereo group based on the canonical atom numbers of the atoms in the group. If no + // atoms were found for the group, it will not be added to the string. + for (int i = 0; i < nof_stereo_groups; i++) { + int nof_atoms = enh_stereo_canon[i][0]; + int nof_found_atoms = enh_stereo_canon[i][1]; + + if (nof_found_atoms > 0) { + tot_len += MakeDelim( "(", strbuf, bOverflow ); + for (int j = 0; j < nof_found_atoms; j++) { + tot_len += MakeNumber_EnhStereo( enh_stereo_canon[i][j + 2], "", strbuf, nCtMode, bOverflow ); + count_added++; + + if ((j + 1) < nof_found_atoms) { + tot_len += MakeDelim( ",", strbuf, bOverflow ); + } + } + tot_len += MakeDelim( ")", strbuf, bOverflow ); + } + } + + for (int i = 0; i < nof_stereo_groups; i++) { + inchi_free(enh_stereo_canon[i]); + } + inchi_free(enh_stereo_canon); + + // Removes the last value for the stereo group (1,2,3) if no atoms were added to the string + if (count_added == 0) { + if (strbuf && strbuf->nUsedLength > 0) { + strbuf->nUsedLength--; + strbuf->pStr[strbuf->nUsedLength] = '\0'; + } + + tot_len = tot_len - 1; + } + + return tot_len; +} + +/** + * @brief Creates the string for the s - layer based on the enhanced stereochemistry information. + * + * @param orig_inp_data Pointer to the original atom data. + * @param pINChISort Pointer to the INCHI_SORT structure. + * @param bOutType Output type flag. + * @param num_components Number of components in the molecule. + * @param strbuf Pointer to the output string buffer. + * @param nCtMode Mode flag for string representation. + * @param bOverflow Pointer to overflow flag. + * @return Returns the length of the created string. + */ +int MakeSlayerString( ORIG_ATOM_DATA *orig_inp_data, + INCHI_SORT *pINChISort, + INCHI_IOS_STRING *strbuf, + int bOutType, + int num_components, + int nCtMode, + int *bOverflow ) +{ + + int tot_len = 0; + int ii; + + const char* x_abs = "1"; + const char* x_rel = "2"; + const char* x_rac = "3"; + + const INCHI_SORT *is = NULL; + const INCHI_SORT *is0 = pINChISort; + + // INChI *pINChI = NULL; + INChI_Aux *pAux = NULL; + + char **dictionary = (char**)inchi_calloc(ENH_STEREO_DICT_SIZE, sizeof(char*)); + int *counts = (int*)inchi_calloc(ENH_STEREO_DICT_SIZE, sizeof(int)); + + for (int i = 0; i < ENH_STEREO_DICT_SIZE; i++) { + dictionary[i] = NULL; + counts[i] = 0; + } + + INCHI_IOS_STRING tmpbuf = {0}; + + for (int cur_c = 0; !*bOverflow && cur_c < num_components; cur_c++) + { + + is = is0 + cur_c; + // pINChI = ( 0 <= ( ii = GET_II( bOutType, is ) ) ) ? is->pINChI[ii] : NULL; + pAux = ( 0 <= ( ii = GET_II( bOutType, is ) ) ) ? is->pINChI_Aux[ii] : NULL; + + inchi_strbuf_init(&tmpbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + // s1 + tot_len += MakeEnhStereoString( pAux, + &tmpbuf, + x_abs, + orig_inp_data->v3000->lists_steabs, + orig_inp_data->v3000->n_steabs, + nCtMode, + bOverflow); + + // s2 + tot_len += MakeEnhStereoString( pAux, + &tmpbuf, + x_rel, + orig_inp_data->v3000->lists_sterel, + orig_inp_data->v3000->n_sterel, + nCtMode, + bOverflow); + + // s3 + tot_len += MakeEnhStereoString( pAux, + &tmpbuf, + x_rac, + orig_inp_data->v3000->lists_sterac, + orig_inp_data->v3000->n_sterac, + nCtMode, + bOverflow); + + int found = 0; + for (int i = 0; i < ENH_STEREO_DICT_SIZE; i++) { + if (dictionary[i] && strcmp(tmpbuf.pStr, dictionary[i]) == 0) { + counts[i]++; + found = 1; + break; + } + } + if (!found) { + for (int i = 0; i < ENH_STEREO_DICT_SIZE; i++) { + if (dictionary[i] == NULL) { + dictionary[i] = strdup(tmpbuf.pStr); + counts[i] = 1; + break; + } + } + } + inchi_strbuf_close(&tmpbuf); + } + + // String deduplication based on dictionary and counts + int count = 0; + for (int i = 0; i < ENH_STEREO_DICT_SIZE; i++) { + if (dictionary[i]) { + if (count > 0) { + tot_len += MakeDelim( ";", strbuf, bOverflow ); + } + if (counts[i] > 1) { + tot_len = inchi_strbuf_printf(strbuf, "%d*%s", counts[i], dictionary[i]); + } else { + tot_len = inchi_strbuf_printf(strbuf, "%s", dictionary[i]); + } + inchi_free(dictionary[i]); + count++; + } + } + + inchi_free(dictionary); + inchi_free(counts); + + return tot_len; +} #ifdef ALPHA_BASE #if ( ALPHA_BASE != 27 ) diff --git a/INCHI-1-SRC/INCHI_BASE/src/ichiprt3.c b/INCHI-1-SRC/INCHI_BASE/src/ichiprt3.c index 6f51233f..a17b0324 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/ichiprt3.c +++ b/INCHI-1-SRC/INCHI_BASE/src/ichiprt3.c @@ -718,10 +718,21 @@ int str_FixedH_atoms( INCHI_SORT *pINChISort, return ( strbuf->nUsedLength - nUsedLength0 ); } - -/**************************************************************************** - Produce double bond stereo substring of the whole structure InChI string. -****************************************************************************/ +/** + * @brief Produce double bond stereo substring of the whole structure InChI string. + * + * @param pINChISort Pointer to the primary INCHI_SORT structure containing input data. + * @param pINChISort2 Pointer to the secondary INCHI_SORT structure, used for comparison or additional data. + * @param strbuf Pointer to an INCHI_IOS_STRING buffer where the output string will be stored. + * @param bOverflow Pointer to an integer flag that will be set if the output overflows the buffer. + * @param bOutType Output type flag specifying the format or type of output. + * @param TAUT_MODE Tautomer mode flag indicating how tautomers are handled. + * @param num_components Number of components to process. + * @param bSecondNonTautPass Flag indicating if this is the second pass for non-tautomeric processing. + * @param bOmitRepetitions Flag to omit repeated entries in the output. + * @param bUseMulipliers Flag to use multipliers in the output representation. + * @return Returns number of characters written to strbuf + */ int str_Sp2( INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, INCHI_IOS_STRING *strbuf, @@ -950,10 +961,22 @@ int str_Sp2( INCHI_SORT *pINChISort, return ( strbuf->nUsedLength - nUsedLength0 ); } - -/**************************************************************************** - Produce tetrahedral stereo substring of the whole structure InChI string. -****************************************************************************/ +/** + * @brief Produce tetrahedral stereo substring of the whole structure InChI string. + * + * @param pINChISort Pointer to the primary INCHI_SORT structure containing input data. + * @param pINChISort2 Pointer to the secondary INCHI_SORT structure, used for comparison or additional data. + * @param strbuf Pointer to an INCHI_IOS_STRING buffer where the output string will be stored. + * @param bOverflow Pointer to an integer flag that will be set if the output overflows the buffer. + * @param bOutType Output type flag specifying the format or type of output. + * @param TAUT_MODE Tautomer mode flag indicating how tautomers are handled. + * @param num_components The number of components to process. + * @param bRelRac Flag for relative or racemic stereochemistry. + * @param bSecondNonTautPass Flag indicating if this is the second pass for non-tautomeric processing. + * @param bOmitRepetitions Flag to omit repeated entries in the output. + * @param bUseMulipliers Flag to use multipliers in the output representation. + * @return int + */ int str_Sp3( INCHI_SORT *pINChISort, INCHI_SORT *pINChISort2, INCHI_IOS_STRING *strbuf, @@ -1184,10 +1207,15 @@ int str_Sp3( INCHI_SORT *pINChISort, return ( strbuf->nUsedLength - nUsedLength0 ); } - -/**************************************************************************** - Output abs stero inversion substring of the whole structure InChI string -****************************************************************************/ +/** + * @brief Output absolute stereo inversion substring of the whole structure InChI string + * @param pINChISort Pointer to INCHI_SORT array + * @param strbuf Pointer to string buffer + * @param bOverflow Overflow flag + * @param bOutType Output type + * @param num_components Number of connected components + * @return Length of the added substring (return value '0', '1', or '.' in strbuf) + */ int str_StereoAbsInv( INCHI_SORT *pINChISort, INCHI_IOS_STRING *strbuf, int *bOverflow, @@ -4131,7 +4159,7 @@ int bin_AuxTautTrans( INCHI_SORT *pINChISort, if (nTrans_n && nTrans_s) { /* new ordering number for original non-tautomeric component number is->ord_number */ - nTrans_n[is->ord_number] = i + 1; /*nTrans_t[is2->ord_number] =*/ + nTrans_n[is->ord_number] = i + 1; /*nTrans_t[is2->ord_number] =*/ } } } diff --git a/INCHI-1-SRC/INCHI_BASE/src/mode.h b/INCHI-1-SRC/INCHI_BASE/src/mode.h index a83bbbc6..638b1c8c 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mode.h +++ b/INCHI-1-SRC/INCHI_BASE/src/mode.h @@ -376,7 +376,7 @@ extern "C" { /* InChI and sometimes resulted in memory corruption on */ /* accessing array of len == NUM_H_ISOTOPES that is 3. */ -#define FIX_OLEAN_SPIRO_CHIRALITY_DETECTION_BUG 1 +#define FIX_OLEAN_SPIRO_CHIRALITY_DETECTION_BUG 1 /* (2018-05-03) thanks, DT; fix for 'olean spiro chirality' */ @@ -438,7 +438,7 @@ extern "C" { #define FIX_NP_MINUS_BUG 1 /* 2010-03-11 DT Fix for bug reported by Timo Boehme */ - /* in normalization procedure for some structures containing N2(+) fragment */ + /* in normalization procedure for some structures containing N2(+) fragment */ /* which may result in producing different InChI strings for the same */ /* molecule, depending on original order of the atomic numbers */ @@ -478,7 +478,7 @@ extern "C" { #define TAUT_PT_06_00 1 /* tautomerism rule PT_06_00 */ #define TAUT_PT_39_00 1 /* tautomerism rule PT_39_00 */ #define TAUT_PT_13_00 1 /* tautomerism rule PT_13_00 */ -#define TAUT_PT_18_00 1 /* tautomerism rule PT_18_00 */ +#define TAUT_PT_18_00 1 /* tautomerism rule PT_18_00 */ #ifdef BUILD_WITH_ENG_OPTIONS #define UNDERIVATIZE 1 /* split to possible underivatized fragments */ @@ -634,6 +634,8 @@ extern "C" { /* 0=> allow other definitions (below) to be active */ #define ONE_BAD_SB_NEIGHBOR 1 /* 1 => allow 1 "bad" bond type neighbor to a stereobond atom. 2004-06-02 */ +#define ENH_STEREO_DICT_SIZE 100 /* 100 => size of the dictionary for enhanced stereo */ + /* more stereo settings */ #define BREAK_ONE_MORE_SC_TIE 1 /* break one more tie when comparing possible stereocenter neighbors */ #define BREAK_ALSO_NEIGH_TIE 0 /* post 1.12Beta 2004-08-20: if fixed neighbor has equ neighbors, fix the one with smaller canon. rank */ @@ -1245,8 +1247,8 @@ do {\ #define POLYMERS_MODERN 1 /* v. 1.06+ way to treat polymers with Zz */ #define POLYMERS_LEGACY 2 /* v. 1.05 mode, no explicit Zz (internally they are here) */ #define POLYMERS_LEGACY_PLUS 3 /* v. 1.05 mode with an addition of that in all - frame-shiftable-bistar-CRUs their backbone bonds - are reordered in descending seniority order. + frame-shiftable-bistar-CRUs their backbone bonds + are reordered in descending seniority order. Used as hidden 1st pass in 1.06 treatment */ diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c b/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c index 29e2389e..ed84245c 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol2atom.c @@ -1337,6 +1337,7 @@ void FreeExtOrigAtData(OAD_Polymer *pd, OAD_V3000 *v3k) } /****************************************************************************/ + int SetExtOrigAtDataByMolfileExtInput(MOL_FMT_DATA *mfdata, OAD_Polymer **ppPolymer, OAD_V3000 **ppV3000, diff --git a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c index ba9844ee..f2a4ffde 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c +++ b/INCHI-1-SRC/INCHI_BASE/src/mol_fmt3.c @@ -842,13 +842,13 @@ int MolfileV3000ReadCollections(MOL_FMT_CTAB *ctab, goto err_fin; } - /* Error: No V3000 Collection end marker */ - if (ctab->v3000->n_steabs || - ctab->v3000->n_sterel || - ctab->v3000->n_sterac) - { - AddErrorMessage(pStrErr, "V3000 enhanced stereo read/stored but ignored"); - } + // /* Error: No V3000 Collection end marker */ + // if (ctab->v3000->n_steabs || + // ctab->v3000->n_sterel || + // ctab->v3000->n_sterac) + // { + // AddErrorMessage(pStrErr, "V3000 enhanced stereo read/stored but ignored"); + // } err_fin: diff --git a/INCHI-1-SRC/INCHI_BASE/src/strutil.c b/INCHI-1-SRC/INCHI_BASE/src/strutil.c index 981ff18a..cfaf9e8e 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/strutil.c +++ b/INCHI-1-SRC/INCHI_BASE/src/strutil.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "mode.h" @@ -1096,12 +1097,12 @@ int remove_ion_pairs( int num_atoms, inp_ATOM *at ) num_N_minus++; } #ifdef FIX_P_IV_Plus_O_Minus - num_P_IV_plus += a->el_number != EL_NUMBER_N && + num_P_IV_plus += a->el_number != EL_NUMBER_N && chrg == 1 && - a->valence == 4 && + a->valence == 4 && a->chem_bonds_valence == 4; /* added 2010-03-17 DT */ -#endif - break; +#endif + break; } } else if (!chrg && a->chem_bonds_valence + NUMH( a, 0 ) == 2 && @@ -3674,7 +3675,7 @@ int move_explicit_Hcation( inp_ATOM *at, /* connect H to at[iat] */ val = at[iat].valence; - + #pragma warning (push) #pragma warning (disable: 6386) if (val < MAXVAL) @@ -4269,6 +4270,195 @@ int cmp_components( const void *a1, const void *a2 ) return ret; } +/** + * @brief Get the canonical atom number from original atom number + * + * @param aux Pointer to INChI auxiliary data + * @param orig_atom_num Original atom number + * @return Returns the canonical atom number, or -1 if not found + */ +int get_canonical_atom_number( const INChI_Aux *aux, + int orig_atom_num) +{ + if (aux == NULL) { + return -1; + } + + if (aux->nOrigAtNosInCanonOrd == NULL) { + return -1; + } + + for (int canon_num = 1; canon_num <= aux->nNumberOfAtoms; canon_num++) { + if (aux->nOrigAtNosInCanonOrd[canon_num - 1] == orig_atom_num) { + return canon_num; + } + } + return -1; +} + +/** + * @brief Get the parity idx from canonical atom number object + * + * @param canon_atom_num Canonical atom number + * @param nNumber Pointer to array of canonical atom numbers + * @param nof_atoms Number of atoms + * @return Returns the parity index, or -1 if not found + */ +int get_parity_idx_from_canonical_atom_number( int canon_atom_num, + const AT_NUMB *nNumber, + int nof_atoms) +{ + if (nNumber == NULL) { + return -1; + } + + if (nof_atoms <= 0) { + return -1; + } + + for (int i = 0; i < nof_atoms; i++) { + if (nNumber[i] == canon_atom_num) { + return i; + } + } + return -1; +} + +/** + * @brief Invert the parities for enhanced stereochemistry t- and m-layers + * + * @param inchi Pointer to INChI structure + * @param aux Pointer to INChI auxiliary data + * @param list_atoms Pointer to list of atom lists for abs, rel or rac information + * @param nof_lists Number of lists + * @param is_absolute Flag indicating if processing absolute stereochemistry + * @return Returns 0 on success, 1 if list_atoms is NULL + */ +int invert_parities(const INChI *inchi, + const INChI_Aux *aux, + int **list_atoms, + int nof_lists, + int is_absolute) +{ + + // t - layer: parities + // 2 = + + // 1 = - + + // m - layer + // -1 = m0 + // 1 = m1 + + if (list_atoms == NULL) { + return 1; + } + + if (nof_lists == 0) + { + return 1; + } + + S_CHAR *t_parity = inchi->Stereo->t_parity; + + for (int i = 0; i < nof_lists; i++) { + int nof_atoms = list_atoms[i][1]; + + AT_NUMB min_c_atom_num = (AT_NUMB)INT_MAX; + for (int j = 0; j < nof_atoms; j++) { + int orig_atom_num = list_atoms[i][2 + j]; + AT_NUMB canon_atom_num = (AT_NUMB)get_canonical_atom_number(aux, orig_atom_num); + if (canon_atom_num < min_c_atom_num) { + min_c_atom_num = canon_atom_num; + } + } + if (min_c_atom_num == (AT_NUMB)INT_MAX) { + continue; + } + int min_c_parity_idx = get_parity_idx_from_canonical_atom_number(min_c_atom_num, + inchi->Stereo->nNumber, + inchi->Stereo->nNumberOfStereoCenters); + + if (min_c_parity_idx == -1) { + continue; + } + + int min_c_atom_parity = t_parity[min_c_parity_idx]; + if (min_c_atom_parity == 2) { + + for (int j = 0; j < nof_atoms; j++) { + int orig_atom_num = list_atoms[i][2 + j]; + AT_NUMB canon_atom_num = (AT_NUMB)get_canonical_atom_number(aux, orig_atom_num); + int parity_idx = get_parity_idx_from_canonical_atom_number(canon_atom_num, + inchi->Stereo->nNumber, + inchi->Stereo->nNumberOfStereoCenters); + + if (parity_idx == -1) { + continue; + } + + if (t_parity[parity_idx] == 2) { + t_parity[parity_idx] = 1; + } else if(t_parity[parity_idx] == 1) { + t_parity[parity_idx] = 2; + } + } + + if (is_absolute) { + inchi->Stereo->nCompInv2Abs = -1; //m1 + } + } + } + return 0; +} + +/** + * @brief Set the enhanced stereochemistry information for t- and m-layers + * + * @param orig_inp_data Pointer to original input atom data + * @param inchi Pointer to INChI structure + * @param aux Pointer to INChI auxiliary data + * @return Retruns 1 if not V3000, otherwise 0 + */ +int set_EnhancedStereo_t_m_layers( const ORIG_ATOM_DATA *orig_inp_data, + const INChI *inchi, + const INChI_Aux *aux) +{ + int ret = 0; + + if (!orig_inp_data->v3000) + { + return 1; + } + + if (inchi == NULL || aux == NULL) + { + return 1; + } + + if (inchi->Stereo == NULL || + inchi->Stereo->t_parity == NULL || + inchi->Stereo->nNumber == NULL || + inchi->Stereo->nNumberOfStereoCenters <= 0) { + return 1; + } + + if (aux->nOrigAtNosInCanonOrd == NULL || + aux->nNumberOfAtoms <= 0) { + return 1; + } + + int ret_abs = invert_parities(inchi, aux, orig_inp_data->v3000->lists_steabs, orig_inp_data->v3000->n_steabs, 1); + int ret_rac = invert_parities(inchi, aux, orig_inp_data->v3000->lists_sterac, orig_inp_data->v3000->n_sterac, 0); + int ret_rel = invert_parities(inchi, aux, orig_inp_data->v3000->lists_sterel, orig_inp_data->v3000->n_sterel, 0); + + if ((orig_inp_data->v3000->n_steabs == 0) && + (orig_inp_data->v3000->n_sterel > 0 || + orig_inp_data->v3000->n_sterac)) { + inchi->Stereo->nCompInv2Abs = 1; //m0 + } + + return ret; +} /**************************************************************************** Set the (disconnected) component numbers in ORIG_ATOM_DATA 'at[*].component' @@ -4324,7 +4514,7 @@ int MarkDisconnectedComponents( ORIG_ATOM_DATA *orig_at_data, nPrevAtom = (AT_NUMB*)inchi_calloc(num_at, sizeof(nPrevAtom[0])); iNeigh = (S_CHAR*)inchi_calloc(num_at, sizeof(iNeigh[0])); - if (!nNewCompNumber || !nPrevAtom || !iNeigh) /* nNewCompNumber: for non-recursive DFS only: */ + if (!nNewCompNumber || !nPrevAtom || !iNeigh) /* nNewCompNumber: for non-recursive DFS only: */ { goto exit_function; } @@ -4333,7 +4523,7 @@ int MarkDisconnectedComponents( ORIG_ATOM_DATA *orig_at_data, /* Mark and count; avoid deep DFS recursion: it may make verifying software unhappy */ /* nNewCompNumber[i] will contain new component number for atoms at[i], i=0..num_at-1 */ - + for (j = 0; j < num_at; j++) { if (!nNewCompNumber[j]) @@ -4709,7 +4899,7 @@ int Free_INChI_Members( INChI *pINChI ) qzfree(pINChI->IsotopicAtom); qzfree(pINChI->IsotopicTGroup); qzfree(pINChI->nPossibleLocationsOfIsotopicH); - qzfree( pINChI->Stereo ); + qzfree( pINChI->Stereo ); qzfree( pINChI->StereoIsotopic ); qzfree( pINChI->szHillFormula ); } @@ -5004,7 +5194,7 @@ void CompAtomData_GetNumMapping( COMP_ATOM_DATA *adata, int *orig_num, int *curr ****************************************************************************/ int imat_new( int m, int n, int ***a ) { - int i; + int i; if (m == 0 || n == 0) { return 0; @@ -5106,7 +5296,7 @@ subgraf *subgraf_new( ORIG_ATOM_DATA *orig_inp_data, sg->orig2node[sg->nodes[i]] = i; } - /* Create and fill subgraph adjacency matrix based on nodes/orig atom numbers + /* Create and fill subgraph adjacency matrix based on nodes/orig atom numbers and connections stored in orig_inp_data */ sg->adj = (subgraf_edge **) inchi_calloc( nnodes, sizeof( subgraf_edge * ) ); if (!sg->adj) @@ -5266,7 +5456,7 @@ void subgraf_pathfinder_free( subgraf_pathfinder *spf ) /**************************************************************************** - Find path(s) from subgraf node spf->start to spf->end + Find path(s) from subgraf node spf->start to spf->end and fill bonds[nbonds] and atoms[natoms] Do not traverse through supplied forbidden edges (if not zero/NULL) ****************************************************************************/ @@ -5298,7 +5488,7 @@ void subgraf_pathfinder_run( subgraf_pathfinder *spf, continue; } if (nforbidden && forbidden) - { + { skip = 0; for (f = 0; f < nforbidden; f++) { diff --git a/INCHI-1-SRC/INCHI_BASE/src/strutil.h b/INCHI-1-SRC/INCHI_BASE/src/strutil.h index 14af75ba..df950476 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/strutil.h +++ b/INCHI-1-SRC/INCHI_BASE/src/strutil.h @@ -57,6 +57,57 @@ extern "C" struct tagTautomerGroupsInfo; struct tagCANON_GLOBALS; + /** + * @brief Set the enhanced stereochemistry for t- and m-layers + * + * @param orig_inp_data + * @param inchi + * @param aux + * @return int + */ + int set_EnhancedStereo_t_m_layers(const ORIG_ATOM_DATA *orig_inp_data, + const INChI *inchi, + const INChI_Aux *aux); + + /** + * @brief Get the canonical atom number object + * + * @param aux Pointer to INChI_Aux data structure + * @param orig_atom_num Original atom number + * @return Returns canonical atom number if found, -1 if not + */ + int get_canonical_atom_number( const INChI_Aux *aux, + int orig_atom_num); + + /** + * @brief Get the parity index from canonical atom number + * + * @param canon_atom_num Canonical atom number + * @param nNumber Pointer to atom number array + * @param nof_atoms Number of atoms + * @return Returns parity index if found, -1 if not + */ + int get_parity_idx_from_canonical_atom_number( int canon_atom_num, + const AT_NUMB *nNumber, + int nof_atoms); + + /** + * @brief Invert the parities for enhanced stereochemistry t- and m-layers + * + * @param inchi Pointer to INChI structure + * @param aux Pointer to INChI auxiliary data + * @param list_atoms Pointer to list of atom lists for abs, rel or rac information + * @param nof_lists Number of lists + * @param is_absolute Flag indicating if processing absolute stereochemistry + * @return Returns 0 on success, 1 if list_atoms is NULL + */ + + int invert_parities(const INChI *inchi, + const INChI_Aux *aux, + int **list_atoms, + int nof_lists, + int is_absolute); + /** * @brief Extract one (connected) component * @@ -407,9 +458,9 @@ extern "C" * @brief Compares stereo information of two structures * * @param s1 Pointer to stereo information of first structure - * @param eql1 Flag for stereo information check + * @param eql1 Flag for stereo information check (EQL_EXISTS, EQL_SP3, EQL_SP3_INV, EQL_SP2) * @param s2 Pointer to stereo information of second structure - * @param eql2 Flag for stereo information check + * @param eql2 Flag for stereo information check (EQL_EXISTS, EQL_SP3, EQL_SP3_INV, EQL_SP2) * @param bRelRac Flag to compare racemic stereo information * @return int 0 if unequal, 1 if equal */ diff --git a/INCHI-1-SRC/INCHI_BASE/src/util.c b/INCHI-1-SRC/INCHI_BASE/src/util.c index 72a518bb..e72f89e8 100644 --- a/INCHI-1-SRC/INCHI_BASE/src/util.c +++ b/INCHI-1-SRC/INCHI_BASE/src/util.c @@ -263,10 +263,10 @@ const ELDATA ElData[] = { "Zy", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {1,}, {0,}, {0,} }}, { "Zz", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {1,}, {0,}, {0,} }}, #ifdef INCHI_ZFRAG -{ "Zu", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {1,}, {0,}, {0,} }}, -{ "Zv", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {2,}, {0,}, {0,} }}, -{ "Zw", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {3,}, {0,}, {0,} }}, -{ "Zx", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {1,2,}, {0,}, {0,} }}, +{ "Zu", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {1,}, {0,}, {0,} }}, +{ "Zv", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {2,}, {0,}, {0,} }}, +{ "Zw", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {3,}, {0,}, {0,} }}, +{ "Zx", 0, 0, 0.000000000, 0 , 0, 1, {{0,}, {0,}, {1,2,}, {0,}, {0,} }}, #endif { "", 0, 0, 0.000000000, 0 , 0, 0, {{0,}, {0,}, {0,}, {0,}, {0,} }}, @@ -376,36 +376,36 @@ int get_periodic_table_number( const char* elname ) } /* the single letter (common) elements */ - if (!elname[1]) + if (!elname[1]) { - switch (elname[0]) + switch (elname[0]) { - case 'H': - return EL_NUMBER_H; + case 'H': + return EL_NUMBER_H; break; - case 'B': - return EL_NUMBER_B; + case 'B': + return EL_NUMBER_B; break; - case 'C': - return EL_NUMBER_C; + case 'C': + return EL_NUMBER_C; break; - case 'N': - return EL_NUMBER_N; + case 'N': + return EL_NUMBER_N; break; - case 'O': - return EL_NUMBER_O; + case 'O': + return EL_NUMBER_O; break; - case 'P': - return EL_NUMBER_P; + case 'P': + return EL_NUMBER_P; break; - case 'S': - return EL_NUMBER_S; + case 'S': + return EL_NUMBER_S; break; - case 'F': - return EL_NUMBER_F; + case 'F': + return EL_NUMBER_F; break; - case 'I': - return EL_NUMBER_I; + case 'I': + return EL_NUMBER_I; break; } } @@ -1065,7 +1065,6 @@ AT_NUMB *is_in_the_list( AT_NUMB *pathAtom, AT_NUMB nNextAtom, int nPathLen ) return nPathLen ? pathAtom : NULL; } - /**************************************************************************** Check if integer is in the list ****************************************************************************/ @@ -1150,12 +1149,12 @@ int num_of_H( inp_ATOM *at, int iat ) /****************************************************************************/ U_CHAR ion_el_group( int el ) { - switch ( el ) + switch ( el ) { case EL_NUMBER_C: /* fallthrough */ -#if ( FIX_REM_ION_PAIRS_Si_BUG == 1 ) +#if ( FIX_REM_ION_PAIRS_Si_BUG == 1 ) case EL_NUMBER_SI: -#endif +#endif return EL_NUMBER_C; case EL_NUMBER_N: /* fallthrough */ case EL_NUMBER_P: @@ -1507,17 +1506,17 @@ int MakeRemovedProtonsString( int nNumRemovedProtons, /****************************************************************************/ int get_endpoint_valence( U_CHAR el_number ) -{ - switch (el_number) +{ + switch (el_number) { case EL_NUMBER_O: /* fallthrough */ - case EL_NUMBER_S: - case EL_NUMBER_SE: - case EL_NUMBER_TE: + case EL_NUMBER_S: + case EL_NUMBER_SE: + case EL_NUMBER_TE: return 2; - case EL_NUMBER_N: + case EL_NUMBER_N: return 3; - default: + default: return 0; } } @@ -1529,13 +1528,13 @@ int get_endpoint_valence( U_CHAR el_number ) /****************************************************************************/ int get_endpoint_valence_KET( U_CHAR el_number ) { - switch (el_number) + switch (el_number) { - case EL_NUMBER_C: + case EL_NUMBER_C: return 4; - case EL_NUMBER_O: + case EL_NUMBER_O: return 2; - default: + default: return 0; } } @@ -1768,7 +1767,7 @@ int mystrncpy( char *target, const char *source, unsigned maxlen ) } /* giallu: PR #163 */ - /* Find actual source length first to limit memchr search */ + /* Find actual source length first to limit memchr search */ source_len = (unsigned)strlen(source); if (source_len < maxlen) @@ -1777,12 +1776,12 @@ int mystrncpy( char *target, const char *source, unsigned maxlen ) len = source_len; } else if ((p = (const char*)memchr(source, 0, maxlen))) /* djb-rwth: addressing LLVM warning */ - { + { /* maxlen does not include the found zero termination */ len = (int) ( p - source ); } else - { + { /* reduced length does not include one more byte for zero termination */ len = maxlen - 1; } @@ -1816,7 +1815,7 @@ char* lrtrim( char *p, int* nLen ) len -= i; /* djb-rwth: variable has to be decreased before memmove */ (memmove)(p, p + i, ((long long)len + 1)); /* djb-rwth: now cast operator can be added */ } - + for (; 0 < len && is_ascii( p[len - 1] ) && isspace( p[len - 1] ); len--) { ; diff --git a/INCHI-1-TEST/tests/test_executable/test_io.py b/INCHI-1-TEST/tests/test_executable/test_io.py index d507960f..dd38d1ed 100644 --- a/INCHI-1-TEST/tests/test_executable/test_io.py +++ b/INCHI-1-TEST/tests/test_executable/test_io.py @@ -59,7 +59,8 @@ def test_executable_rejects_more_than_999_atoms( result = run_inchi_exe(molfile_v3000_more_than_999_atoms_and_bonds) assert ( - "Error 170 (no InChI; V3000 enhanced stereo read/stored but ignored; Too many atoms [did you forget 'LargeMolecules' switch?])" + # "Error 170 (no InChI; V3000 enhanced stereo read/stored but ignored; Too many atoms [did you forget 'LargeMolecules' switch?])" + "Error 170 (no InChI; Too many atoms [did you forget 'LargeMolecules' switch?])" in result.stderr ) @@ -72,7 +73,8 @@ def test_executable_accepts_more_than_999_atoms_with_flag( ) assert ( - "Error 170 (no InChI; V3000 enhanced stereo read/stored but ignored; Too many atoms [did you forget 'LargeMolecules' switch?])" + # "Error 170 (no InChI; V3000 enhanced stereo read/stored but ignored; Too many atoms [did you forget 'LargeMolecules' switch?])" + "Error 170 (no InChI; Too many atoms [did you forget 'LargeMolecules' switch?])" not in result.stderr ) assert "Experimental mode: Up to 32766 atoms per structure" in result.stderr diff --git a/INCHI-1-TEST/tests/test_unit/CMakeLists.txt b/INCHI-1-TEST/tests/test_unit/CMakeLists.txt index 248af435..0419209c 100644 --- a/INCHI-1-TEST/tests/test_unit/CMakeLists.txt +++ b/INCHI-1-TEST/tests/test_unit/CMakeLists.txt @@ -13,6 +13,12 @@ file(GLOB TEST_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/test_*.cpp foreach(test_src ${TEST_SOURCES}) get_filename_component(test_name "${test_src}" NAME_WE) add_executable(${test_name} ${test_src}) + target_compile_options(${test_name} PRIVATE + "$<$:-g;-O0;-fsanitize=address>" + ) + target_link_options(${test_name} PRIVATE + "$<$:-g;-O0;-fsanitize=address>" + ) target_link_libraries(${test_name} PRIVATE gtest_main gmock_main test_dependencies libinchi) add_test(NAME ${test_name} COMMAND $) endforeach() diff --git a/INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_1.sdf b/INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_1.sdf new file mode 100644 index 00000000..1bffa89f --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_1.sdf @@ -0,0 +1,1016 @@ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 C -1.429260 -0.206189 0.000000 0 +M V30 2 C -0.714790 0.206311 0.000000 0 +M V30 3 O -0.714790 1.031557 0.000000 0 +M V30 4 C -0.000107 -0.206312 0.000000 0 +M V30 5 C 0.714577 0.206311 0.000000 0 +M V30 6 C 1.429260 -0.206312 0.000000 0 +M V30 7 N -0.000107 -1.031557 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 2 3 CFG=1 +M V30 3 1 2 4 +M V30 4 1 4 5 +M V30 5 1 5 6 +M V30 6 1 4 7 CFG=1 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 5 4 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.071918 -0.206311 0.000000 0 +M V30 2 C 0.357235 -0.618934 0.000000 0 +M V30 3 C -0.357448 -0.206311 0.000000 0 +M V30 4 O -0.357448 0.618934 0.000000 0 +M V30 5 C -1.071918 -0.618811 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=1 +M V30 4 1 5 3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(1 3) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.429260 -0.206311 0.000000 0 +M V30 2 C 0.714576 0.206311 0.000000 0 +M V30 3 C -0.000107 -0.206311 0.000000 0 +M V30 4 N -0.000107 -1.031556 0.000000 0 +M V30 5 C -0.714790 0.206311 0.000000 0 +M V30 6 O -0.714790 1.031556 0.000000 0 +M V30 7 C -1.429260 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=1 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 3 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 5 4 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1.071919 -0.206311 0.000000 0 +M V30 2 C 0.357235 -0.618934 0.000000 0 +M V30 3 C -0.357448 -0.206311 0.000000 0 +M V30 4 O -0.357448 0.618934 0.000000 0 +M V30 5 C -1.071919 -0.618811 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=1 +M V30 4 1 5 3 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.429261 -0.206311 0.000000 0 +M V30 2 C 0.714577 0.206311 0.000000 0 +M V30 3 C -0.000106 -0.206311 0.000000 0 +M V30 4 N -0.000106 -1.031556 0.000000 0 +M V30 5 C -0.714790 0.206311 0.000000 0 +M V30 6 O -0.714790 1.031556 0.000000 0 +M V30 7 C -1.429261 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=1 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL2 ATOMS=(1 3) +M V30 MDLV30/STEREL1 ATOMS=(1 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.429261 -0.206311 0.000000 0 +M V30 2 C 0.714578 0.206311 0.000000 0 +M V30 3 C -0.000106 -0.206311 0.000000 0 +M V30 4 N -0.000106 -1.031556 0.000000 0 +M V30 5 C -0.714790 0.206311 0.000000 0 +M V30 6 O -0.714790 1.031556 0.000000 0 +M V30 7 C -1.429261 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 +M V30 4 1 5 3 +M V30 5 1 5 6 +M V30 6 1 7 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 N -0.000106 -1.031556 0.000000 0 +M V30 2 C -0.000106 -0.206311 0.000000 0 +M V30 3 C 0.714578 0.206311 0.000000 0 +M V30 4 C 1.429261 -0.206311 0.000000 0 +M V30 5 C -0.714789 0.206311 0.000000 0 +M V30 6 O -0.714789 1.031556 0.000000 0 +M V30 7 C -1.429261 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 2 3 +M V30 3 1 3 4 +M V30 4 1 5 2 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(2 2 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 5 4 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.071919 -0.206311 0.000000 0 +M V30 2 C 0.357236 -0.618934 0.000000 0 +M V30 3 C -0.357448 -0.206311 0.000000 0 +M V30 4 O -0.357448 0.618934 0.000000 0 +M V30 5 C -1.071919 -0.618811 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=1 +M V30 4 1 5 3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 3) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 5 4 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.071919 -0.206311 0.000000 0 +M V30 2 C 0.357236 -0.618934 0.000000 0 +M V30 3 C -0.357448 -0.206311 0.000000 0 +M V30 4 O -0.357448 0.618934 0.000000 0 +M V30 5 C -1.071919 -0.618811 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 +M V30 4 1 5 3 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 N -0.000106 -1.031556 0.000000 0 +M V30 2 C -0.000106 -0.206311 0.000000 0 +M V30 3 C 0.714578 0.206311 0.000000 0 +M V30 4 C 1.429261 -0.206311 0.000000 0 +M V30 5 C -0.714789 0.206311 0.000000 0 +M V30 6 O -0.714789 1.031556 0.000000 0 +M V30 7 C -1.429261 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 2 3 +M V30 3 1 3 4 +M V30 4 1 5 2 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 2) +M V30 MDLV30/STERAC1 ATOMS=(1 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 C -0.412473 1.071585 0.000000 0 +M V30 2 C -0.824982 0.357119 0.000000 0 +M V30 3 C -0.412509 -0.357346 0.000000 0 +M V30 4 C 0.412473 -0.357346 0.000000 0 +M V30 5 C 0.824982 0.357119 0.000000 0 +M V30 6 C 0.412509 1.071585 0.000000 0 +M V30 7 O 1.649713 0.357119 0.000000 0 +M V30 8 O 0.824839 -1.071585 0.000000 0 +M V30 9 O -1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 2 3 +M V30 3 1 3 4 +M V30 4 1 4 5 +M V30 5 1 5 6 +M V30 6 1 1 6 +M V30 7 1 5 7 CFG=1 +M V30 8 1 4 8 CFG=1 +M V30 9 1 2 9 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(2 2 5) +M V30 MDLV30/STEREL1 ATOMS=(1 4) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 1 +M V30 BEGIN ATOM +M V30 1 O 0.824838 -1.071585 0.000000 0 +M V30 2 C 0.412472 -0.357346 0.000000 0 +M V30 3 C -0.412509 -0.357346 0.000000 0 +M V30 4 C -0.824982 0.357119 0.000000 0 +M V30 5 O -1.649714 0.357119 0.000000 0 +M V30 6 C -0.412473 1.071585 0.000000 0 +M V30 7 C 0.412509 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649714 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=1 +M V30 9 1 2 8 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824838 -1.071585 0.000000 0 +M V30 2 C 0.412472 -0.357346 0.000000 0 +M V30 3 C -0.412509 -0.357346 0.000000 0 +M V30 4 C -0.824982 0.357119 0.000000 0 +M V30 5 O -1.649714 0.357119 0.000000 0 +M V30 6 C -0.412473 1.071585 0.000000 0 +M V30 7 C 0.412509 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649714 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=1 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 2 8) +M V30 MDLV30/STEABS ATOMS=(1 4) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 1 +M V30 BEGIN ATOM +M V30 1 O 0.824838 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412508 -0.357346 0.000000 0 +M V30 4 C -0.824981 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412472 1.071585 0.000000 0 +M V30 7 C 0.412510 1.071585 0.000000 0 +M V30 8 C 0.824983 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 +M V30 9 1 2 8 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824839 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412508 -0.357346 0.000000 0 +M V30 4 C -0.824981 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412472 1.071585 0.000000 0 +M V30 7 C 0.412510 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=3 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 2 8) +M V30 MDLV30/STEABS ATOMS=(1 4) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 8 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.071919 -0.206312 0.000000 0 +M V30 2 C 0.357236 0.206310 0.000000 0 +M V30 3 C -0.357448 -0.206312 0.000000 0 +M V30 4 N -0.357448 -1.031557 0.000000 0 +M V30 5 C -1.072131 0.206310 0.000000 0 +M V30 6 O -1.072131 1.031557 0.000000 0 +M V30 7 C -1.786602 -0.206188 0.000000 0 +M V30 8 C 0.357236 1.031557 0.000000 0 +M V30 9 C 1.786602 0.206310 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=1 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 7 1 2 8 CFG=1 +M V30 8 1 1 9 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(1 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 8 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1.786602 0.206312 0.000000 0 +M V30 2 C 1.071918 -0.206312 0.000000 0 +M V30 3 C 0.357235 0.206312 0.000000 0 +M V30 4 C 0.357235 1.031557 0.000000 0 +M V30 5 C -0.357448 -0.206312 0.000000 0 +M V30 6 N -0.357448 -1.031557 0.000000 0 +M V30 7 C -1.072132 0.206312 0.000000 0 +M V30 8 O -1.072132 1.031557 0.000000 0 +M V30 9 C -1.786602 -0.206188 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 +M V30 4 1 5 3 +M V30 5 1 5 6 +M V30 6 1 7 5 +M V30 7 1 7 8 CFG=1 +M V30 8 1 9 7 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 8 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.786602 0.206312 0.000000 0 +M V30 2 C 1.071919 -0.206312 0.000000 0 +M V30 3 C 0.357236 0.206312 0.000000 0 +M V30 4 C 0.357236 1.031557 0.000000 0 +M V30 5 C -0.357448 -0.206312 0.000000 0 +M V30 6 N -0.357448 -1.031557 0.000000 0 +M V30 7 C -1.072131 0.206312 0.000000 0 +M V30 8 O -1.072131 1.031557 0.000000 0 +M V30 9 C -1.786602 -0.206188 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=3 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 7 1 7 8 CFG=1 +M V30 8 1 9 7 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 3 5) +M V30 MDLV30/STEABS ATOMS=(1 7) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824839 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412508 -0.357346 0.000000 0 +M V30 4 C -0.824981 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412472 1.071585 0.000000 0 +M V30 7 C 0.412510 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=1 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(1 2) +M V30 MDLV30/STEABS ATOMS=(1 4) +M V30 MDLV30/STEREL2 ATOMS=(1 8) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 C -1.429261 -0.206189 0.000000 0 +M V30 2 C -0.714790 0.206311 0.000000 0 +M V30 3 C -0.000107 -0.206311 0.000000 0 +M V30 4 N -0.000107 -1.031556 0.000000 0 +M V30 5 C 0.714577 0.206311 0.000000 0 +M V30 6 C 1.429261 -0.206311 0.000000 0 +M V30 7 O -0.714790 1.031556 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 2 3 +M V30 3 1 3 4 CFG=1 +M V30 4 1 3 5 +M V30 5 1 5 6 +M V30 6 1 2 7 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(1 2) +M V30 MDLV30/STERAC1 ATOMS=(1 3) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.429260 -0.206311 0.000000 0 +M V30 2 C 0.714577 0.206311 0.000000 0 +M V30 3 C -0.000107 -0.206311 0.000000 0 +M V30 4 N -0.000107 -1.031556 0.000000 0 +M V30 5 C -0.714790 0.206311 0.000000 0 +M V30 6 O -0.714790 1.031556 0.000000 0 +M V30 7 C -1.429260 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824838 -1.071585 0.000000 0 +M V30 2 C 0.412472 -0.357346 0.000000 0 +M V30 3 C -0.412509 -0.357346 0.000000 0 +M V30 4 C -0.824982 0.357119 0.000000 0 +M V30 5 O -1.649714 0.357119 0.000000 0 +M V30 6 C -0.412473 1.071585 0.000000 0 +M V30 7 C 0.412509 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649714 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=3 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(2 2 8) +M V30 MDLV30/STEABS ATOMS=(1 4) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824839 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412509 -0.357346 0.000000 0 +M V30 4 C -0.824982 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412473 1.071585 0.000000 0 +M V30 7 C 0.412509 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=1 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(2 2 8) +M V30 MDLV30/STEABS ATOMS=(1 4) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824839 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412508 -0.357346 0.000000 0 +M V30 4 C -0.824981 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412472 1.071585 0.000000 0 +M V30 7 C 0.412510 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 4) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 8 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.786602 0.206312 0.000000 0 +M V30 2 C 1.071918 -0.206310 0.000000 0 +M V30 3 C 0.357235 0.206312 0.000000 0 +M V30 4 C 0.357235 1.031557 0.000000 0 +M V30 5 C -0.357448 -0.206310 0.000000 0 +M V30 6 N -0.357448 -1.031557 0.000000 0 +M V30 7 C -1.072132 0.206312 0.000000 0 +M V30 8 O -1.072132 1.031557 0.000000 0 +M V30 9 C -1.786602 -0.206188 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 +M V30 4 1 5 3 +M V30 5 1 5 6 +M V30 6 1 7 5 +M V30 7 1 7 8 CFG=1 +M V30 8 1 9 7 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 7) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 8 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.786602 0.206312 0.000000 0 +M V30 2 C 1.071918 -0.206310 0.000000 0 +M V30 3 C 0.357235 0.206312 0.000000 0 +M V30 4 C 0.357235 1.031557 0.000000 0 +M V30 5 C -0.357448 -0.206310 0.000000 0 +M V30 6 N -0.357448 -1.031557 0.000000 0 +M V30 7 C -1.072132 0.206312 0.000000 0 +M V30 8 O -1.072132 1.031557 0.000000 0 +M V30 9 C -1.786602 -0.206188 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=3 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 7 1 7 8 CFG=1 +M V30 8 1 9 7 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(2 3 5) +M V30 MDLV30/STEABS ATOMS=(1 7) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 8 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 1.786602 0.206311 0.000000 0 +M V30 2 C 1.071919 -0.206312 0.000000 0 +M V30 3 C 0.357236 0.206311 0.000000 0 +M V30 4 C 0.357236 1.031557 0.000000 0 +M V30 5 C -0.357448 -0.206312 0.000000 0 +M V30 6 N -0.357448 -1.031557 0.000000 0 +M V30 7 C -1.072132 0.206311 0.000000 0 +M V30 8 O -1.072132 1.031557 0.000000 0 +M V30 9 C -1.786602 -0.206188 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 CFG=1 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 7 1 7 8 CFG=1 +M V30 8 1 9 7 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(2 3 5) +M V30 MDLV30/STEABS ATOMS=(1 7) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824839 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412509 -0.357346 0.000000 0 +M V30 4 C -0.824981 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412472 1.071585 0.000000 0 +M V30 7 C 0.412510 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=1 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 2) +M V30 MDLV30/STEABS ATOMS=(1 4) +M V30 MDLV30/STERAC2 ATOMS=(1 8) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824839 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412508 -0.357346 0.000000 0 +M V30 4 C -0.824981 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412472 1.071585 0.000000 0 +M V30 7 C 0.412510 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 CFG=1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 CFG=1 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 CFG=1 +M V30 9 1 2 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 2) +M V30 MDLV30/STEABS ATOMS=(1 4) +M V30 MDLV30/STEREL1 ATOMS=(1 8) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1.429261 -0.206312 0.000000 0 +M V30 2 C 0.714577 0.206310 0.000000 0 +M V30 3 C -0.000106 -0.206312 0.000000 0 +M V30 4 N -0.000106 -1.031557 0.000000 0 +M V30 5 C -0.714790 0.206310 0.000000 0 +M V30 6 O -0.714790 1.031557 0.000000 0 +M V30 7 C -1.429261 -0.206188 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 3 4 +M V30 4 1 5 3 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 N -0.000106 -1.031556 0.000000 0 +M V30 2 C -0.000106 -0.206312 0.000000 0 +M V30 3 C 0.714577 0.206311 0.000000 0 +M V30 4 C 1.429261 -0.206312 0.000000 0 +M V30 5 C -0.714789 0.206311 0.000000 0 +M V30 6 O -0.714789 1.031556 0.000000 0 +M V30 7 C -1.429261 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 2 3 +M V30 3 1 3 4 +M V30 4 1 5 2 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 0 +M V30 BEGIN ATOM +M V30 1 N -0.000106 -1.031556 0.000000 0 +M V30 2 C -0.000106 -0.206312 0.000000 0 +M V30 3 C 0.714577 0.206311 0.000000 0 +M V30 4 C 1.429261 -0.206312 0.000000 0 +M V30 5 C -0.714789 0.206311 0.000000 0 +M V30 6 O -0.714789 1.031556 0.000000 0 +M V30 7 C -1.429261 -0.206189 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 2 3 +M V30 3 1 3 4 +M V30 4 1 5 2 +M V30 5 1 5 6 CFG=1 +M V30 6 1 7 5 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(1 5) +M V30 END COLLECTION +M V30 END CTAB +M END +$$$$ +Structure drawings enhanced stereochemistry.sdf + ChemDraw01282608392D + + 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 9 9 0 0 0 +M V30 BEGIN ATOM +M V30 1 O 0.824839 -1.071585 0.000000 0 +M V30 2 C 0.412473 -0.357346 0.000000 0 +M V30 3 C -0.412508 -0.357346 0.000000 0 +M V30 4 C -0.824981 0.357119 0.000000 0 +M V30 5 O -1.649713 0.357119 0.000000 0 +M V30 6 C -0.412472 1.071585 0.000000 0 +M V30 7 C 0.412510 1.071585 0.000000 0 +M V30 8 C 0.824982 0.357119 0.000000 0 +M V30 9 O 1.649713 0.357119 0.000000 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 2 1 +M V30 2 1 3 2 +M V30 3 1 4 3 +M V30 4 1 4 5 +M V30 5 1 6 4 +M V30 6 1 6 7 +M V30 7 1 8 7 +M V30 8 1 8 9 +M V30 9 1 2 8 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_2.sdf b/INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_2.sdf new file mode 100644 index 00000000..ef407954 --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_2.sdf @@ -0,0 +1,1972 @@ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 3424.1946 -1936.7935 0 0 +M V30 2 C 3352.3145 -1895.2935 0 0 +M V30 3 C 3280.4346 -1936.7935 0 0 +M V30 4 C 3208.5542 -1895.2935 0 0 +M V30 5 C 3136.6743 -1936.7935 0 0 +M V30 6 C 3064.7944 -1895.2935 0 0 +M V30 7 Br 3136.6743 -2019.7935 0 0 +M V30 8 Cl 3208.5542 -1812.2935 0 0 +M V30 9 Cl 3280.4346 -2019.7935 0 0 +M V30 10 Cl 3352.3145 -1812.2935 0 0 +M V30 11 Cl 3424.1946 -2019.7935 0 0 +M V30 12 C 3496.075 -1895.2935 0 0 +M V30 13 C 3567.9548 -1936.7942 0 0 +M V30 14 C 3639.835 -1895.2944 0 0 +M V30 15 C 3711.7148 -1936.7942 0 0 +M V30 16 Cl 3639.835 -1812.2944 0 0 +M V30 17 Cl 3567.9548 -2019.7942 0 0 +M V30 18 Cl 3496.075 -1812.2937 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6+,7-,8+,9+,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 2617.5557 -1933.6348 0 0 +M V30 2 C 2545.6758 -1892.1348 0 0 +M V30 3 C 2473.7957 -1933.6348 0 0 +M V30 4 C 2401.9155 -1892.1348 0 0 +M V30 5 C 2330.0354 -1933.6348 0 0 +M V30 6 C 2258.1553 -1892.1348 0 0 +M V30 7 Br 2330.0354 -2016.6348 0 0 +M V30 8 Cl 2401.9155 -1809.1348 0 0 +M V30 9 Cl 2473.7957 -2016.6348 0 0 +M V30 10 Cl 2545.6758 -1809.1348 0 0 +M V30 11 Cl 2617.5557 -2016.6348 0 0 +M V30 12 C 2689.436 -1892.1348 0 0 +M V30 13 C 2761.3159 -1933.6355 0 0 +M V30 14 C 2833.1958 -1892.1357 0 0 +M V30 15 C 2905.0759 -1933.6355 0 0 +M V30 16 Cl 2833.1958 -1809.1357 0 0 +M V30 17 Cl 2761.3159 -2016.6355 0 0 +M V30 18 Cl 2689.436 -1809.135 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6+,7-,8+,9+,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1652.5557 -1930.6348 0 0 +M V30 2 C 1580.6757 -1889.1348 0 0 +M V30 3 C 1508.7957 -1930.6348 0 0 +M V30 4 C 1436.9154 -1889.1348 0 0 +M V30 5 C 1365.0354 -1930.6348 0 0 +M V30 6 C 1293.1554 -1889.1348 0 0 +M V30 7 Br 1365.0354 -2013.6348 0 0 +M V30 8 Cl 1436.9154 -1806.1348 0 0 +M V30 9 Cl 1508.7957 -2013.6348 0 0 +M V30 10 Cl 1580.6757 -1806.1348 0 0 +M V30 11 Cl 1652.5557 -2013.6348 0 0 +M V30 12 C 1724.436 -1889.1348 0 0 +M V30 13 C 1796.3159 -1930.6355 0 0 +M V30 14 C 1868.196 -1889.1357 0 0 +M V30 15 C 1940.0759 -1930.6355 0 0 +M V30 16 Cl 1868.196 -1806.1357 0 0 +M V30 17 Cl 1796.3159 -2013.6355 0 0 +M V30 18 Cl 1724.436 -1806.135 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 845.9167 -1927.4761 0 0 +M V30 2 C 774.0367 -1885.9761 0 0 +M V30 3 C 702.1567 -1927.4761 0 0 +M V30 4 C 630.2765 -1885.9761 0 0 +M V30 5 C 558.3965 -1927.4761 0 0 +M V30 6 C 486.5165 -1885.9761 0 0 +M V30 7 Br 558.3965 -2010.4761 0 0 +M V30 8 Cl 630.2765 -1802.9761 0 0 +M V30 9 Cl 702.1567 -2010.4761 0 0 +M V30 10 Cl 774.0367 -1802.9761 0 0 +M V30 11 Cl 845.9167 -2010.4761 0 0 +M V30 12 C 917.7971 -1885.9761 0 0 +M V30 13 C 989.677 -1927.4768 0 0 +M V30 14 C 1061.557 -1885.9771 0 0 +M V30 15 C 1133.437 -1927.4768 0 0 +M V30 16 Cl 1061.557 -1802.9771 0 0 +M V30 17 Cl 989.677 -2010.4768 0 0 +M V30 18 Cl 917.7971 -1802.9763 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 3436.5557 -1571.6348 0 0 +M V30 2 C 3364.6758 -1530.1348 0 0 +M V30 3 C 3292.7957 -1571.6348 0 0 +M V30 4 C 3220.9155 -1530.1348 0 0 +M V30 5 C 3149.0354 -1571.6348 0 0 +M V30 6 C 3077.1553 -1530.1348 0 0 +M V30 7 Br 3149.0354 -1654.6346 0 0 +M V30 8 Cl 3220.9155 -1447.1348 0 0 +M V30 9 Cl 3292.7957 -1654.6346 0 0 +M V30 10 Cl 3364.6758 -1447.1348 0 0 +M V30 11 Cl 3436.5557 -1654.6346 0 0 +M V30 12 C 3508.436 -1530.1349 0 0 +M V30 13 C 3580.3159 -1571.6355 0 0 +M V30 14 C 3652.1958 -1530.1356 0 0 +M V30 15 C 3724.0759 -1571.6355 0 0 +M V30 16 Cl 3652.1958 -1447.1356 0 0 +M V30 17 Cl 3580.3159 -1654.6355 0 0 +M V30 18 Cl 3508.436 -1447.135 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6+,7-,8+,9+,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 2629.9167 -1568.4761 0 0 +M V30 2 C 2558.0366 -1526.9761 0 0 +M V30 3 C 2486.1567 -1568.4761 0 0 +M V30 4 C 2414.2764 -1526.9761 0 0 +M V30 5 C 2342.3965 -1568.4761 0 0 +M V30 6 C 2270.5166 -1526.9761 0 0 +M V30 7 Br 2342.3965 -1651.476 0 0 +M V30 8 Cl 2414.2764 -1443.9761 0 0 +M V30 9 Cl 2486.1567 -1651.476 0 0 +M V30 10 Cl 2558.0366 -1443.9761 0 0 +M V30 11 Cl 2629.9167 -1651.476 0 0 +M V30 12 C 2701.7971 -1526.9762 0 0 +M V30 13 C 2773.677 -1568.4768 0 0 +M V30 14 C 2845.5571 -1526.9769 0 0 +M V30 15 C 2917.437 -1568.4768 0 0 +M V30 16 Cl 2845.5571 -1443.9769 0 0 +M V30 17 Cl 2773.677 -1651.4768 0 0 +M V30 18 Cl 2701.7971 -1443.9763 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6+,7-,8+,9+,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1664.9167 -1565.4761 0 0 +M V30 2 C 1593.0367 -1523.9761 0 0 +M V30 3 C 1521.1567 -1565.4761 0 0 +M V30 4 C 1449.2765 -1523.9761 0 0 +M V30 5 C 1377.3965 -1565.4761 0 0 +M V30 6 C 1305.5165 -1523.9761 0 0 +M V30 7 Br 1377.3965 -1648.476 0 0 +M V30 8 Cl 1449.2765 -1440.9761 0 0 +M V30 9 Cl 1521.1567 -1648.476 0 0 +M V30 10 Cl 1593.0367 -1440.9761 0 0 +M V30 11 Cl 1664.9167 -1648.476 0 0 +M V30 12 C 1736.7971 -1523.9762 0 0 +M V30 13 C 1808.677 -1565.4768 0 0 +M V30 14 C 1880.5569 -1523.9769 0 0 +M V30 15 C 1952.437 -1565.4768 0 0 +M V30 16 Cl 1880.5569 -1440.9769 0 0 +M V30 17 Cl 1808.677 -1648.4768 0 0 +M V30 18 Cl 1736.7971 -1440.9763 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7-,8-,9+,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 858.2778 -1562.3174 0 0 +M V30 2 C 786.3978 -1520.8174 0 0 +M V30 3 C 714.5178 -1562.3174 0 0 +M V30 4 C 642.6376 -1520.8174 0 0 +M V30 5 C 570.7576 -1562.3174 0 0 +M V30 6 C 498.8776 -1520.8174 0 0 +M V30 7 Br 570.7576 -1645.3173 0 0 +M V30 8 Cl 642.6376 -1437.8174 0 0 +M V30 9 Cl 714.5178 -1645.3173 0 0 +M V30 10 Cl 786.3978 -1437.8174 0 0 +M V30 11 Cl 858.2778 -1645.3173 0 0 +M V30 12 C 930.1582 -1520.8175 0 0 +M V30 13 C 1002.0381 -1562.3181 0 0 +M V30 14 C 1073.9181 -1520.8182 0 0 +M V30 15 C 1145.7981 -1562.3181 0 0 +M V30 16 Cl 1073.9181 -1437.8182 0 0 +M V30 17 Cl 1002.0381 -1645.3181 0 0 +M V30 18 Cl 930.1582 -1437.8176 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=1 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=1 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7-,8-,9+,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 3428.5557 -1046.6348 0 0 +M V30 2 C 3356.6758 -1005.1348 0 0 +M V30 3 C 3284.7957 -1046.6348 0 0 +M V30 4 C 3212.9155 -1005.1348 0 0 +M V30 5 C 3141.0354 -1046.6348 0 0 +M V30 6 C 3069.1553 -1005.1348 0 0 +M V30 7 Br 3141.0354 -1129.6346 0 0 +M V30 8 Cl 3212.9155 -922.1348 0 0 +M V30 9 Cl 3284.7957 -1129.6346 0 0 +M V30 10 Cl 3356.6758 -922.1348 0 0 +M V30 11 Cl 3428.5557 -1129.6346 0 0 +M V30 12 C 3500.436 -1005.1349 0 0 +M V30 13 C 3572.3159 -1046.6355 0 0 +M V30 14 C 3644.196 -1005.1356 0 0 +M V30 15 C 3716.0759 -1046.6355 0 0 +M V30 16 Cl 3644.196 -922.1356 0 0 +M V30 17 Cl 3572.3159 -1129.6355 0 0 +M V30 18 Cl 3500.436 -922.135 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6+,7+,8+,9-,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 2621.9167 -1043.4761 0 0 +M V30 2 C 2550.0366 -1001.9761 0 0 +M V30 3 C 2478.1567 -1043.4761 0 0 +M V30 4 C 2406.2764 -1001.9761 0 0 +M V30 5 C 2334.3965 -1043.4761 0 0 +M V30 6 C 2262.5166 -1001.9761 0 0 +M V30 7 Br 2334.3965 -1126.476 0 0 +M V30 8 Cl 2406.2764 -918.9761 0 0 +M V30 9 Cl 2478.1567 -1126.476 0 0 +M V30 10 Cl 2550.0366 -918.9761 0 0 +M V30 11 Cl 2621.9167 -1126.476 0 0 +M V30 12 C 2693.7971 -1001.9762 0 0 +M V30 13 C 2765.677 -1043.4768 0 0 +M V30 14 C 2837.5571 -1001.9769 0 0 +M V30 15 C 2909.437 -1043.4768 0 0 +M V30 16 Cl 2837.5571 -918.9769 0 0 +M V30 17 Cl 2765.677 -1126.4768 0 0 +M V30 18 Cl 2693.7971 -918.9763 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6+,7+,8+,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1656.9167 -1040.4761 0 0 +M V30 2 C 1585.0367 -998.9761 0 0 +M V30 3 C 1513.1567 -1040.4761 0 0 +M V30 4 C 1441.2765 -998.9761 0 0 +M V30 5 C 1369.3965 -1040.4761 0 0 +M V30 6 C 1297.5165 -998.9761 0 0 +M V30 7 Br 1369.3965 -1123.476 0 0 +M V30 8 Cl 1441.2765 -915.9761 0 0 +M V30 9 Cl 1513.1567 -1123.476 0 0 +M V30 10 Cl 1585.0367 -915.9761 0 0 +M V30 11 Cl 1656.9167 -1123.476 0 0 +M V30 12 C 1728.7971 -998.9762 0 0 +M V30 13 C 1800.677 -1040.4768 0 0 +M V30 14 C 1872.5571 -998.9769 0 0 +M V30 15 C 1944.437 -1040.4768 0 0 +M V30 16 Cl 1872.5571 -915.9769 0 0 +M V30 17 Cl 1800.677 -1123.4768 0 0 +M V30 18 Cl 1728.7971 -915.9763 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7+,8-,9-,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 850.2778 -1037.3174 0 0 +M V30 2 C 778.3978 -995.8174 0 0 +M V30 3 C 706.5178 -1037.3174 0 0 +M V30 4 C 634.6376 -995.8174 0 0 +M V30 5 C 562.7576 -1037.3174 0 0 +M V30 6 C 490.8776 -995.8174 0 0 +M V30 7 Br 562.7576 -1120.3173 0 0 +M V30 8 Cl 634.6376 -912.8174 0 0 +M V30 9 Cl 706.5178 -1120.3173 0 0 +M V30 10 Cl 778.3978 -912.8174 0 0 +M V30 11 Cl 850.2778 -1120.3173 0 0 +M V30 12 C 922.1582 -995.8175 0 0 +M V30 13 C 994.0381 -1037.3181 0 0 +M V30 14 C 1065.9181 -995.8182 0 0 +M V30 15 C 1137.7981 -1037.3181 0 0 +M V30 16 Cl 1065.9181 -912.8182 0 0 +M V30 17 Cl 994.0381 -1120.3181 0 0 +M V30 18 Cl 922.1582 -912.8176 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7+,8-,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 3440.9167 -681.4761 0 0 +M V30 2 C 3369.0366 -639.976 0 0 +M V30 3 C 3297.1567 -681.4761 0 0 +M V30 4 C 3225.2764 -639.976 0 0 +M V30 5 C 3153.3965 -681.4761 0 0 +M V30 6 C 3081.5166 -639.976 0 0 +M V30 7 Br 3153.3965 -764.476 0 0 +M V30 8 Cl 3225.2764 -556.976 0 0 +M V30 9 Cl 3297.1567 -764.476 0 0 +M V30 10 Cl 3369.0366 -556.976 0 0 +M V30 11 Cl 3440.9167 -764.476 0 0 +M V30 12 C 3512.7971 -639.9762 0 0 +M V30 13 C 3584.677 -681.4769 0 0 +M V30 14 C 3656.5569 -639.9769 0 0 +M V30 15 C 3728.437 -681.4769 0 0 +M V30 16 Cl 3656.5569 -556.9769 0 0 +M V30 17 Cl 3584.677 -764.4768 0 0 +M V30 18 Cl 3512.7971 -556.9764 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6+,7+,8+,9-,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 2634.2778 -678.3174 0 0 +M V30 2 C 2562.3979 -636.8173 0 0 +M V30 3 C 2490.5178 -678.3174 0 0 +M V30 4 C 2418.6377 -636.8173 0 0 +M V30 5 C 2346.7576 -678.3174 0 0 +M V30 6 C 2274.8774 -636.8173 0 0 +M V30 7 Br 2346.7576 -761.3173 0 0 +M V30 8 Cl 2418.6377 -553.8173 0 0 +M V30 9 Cl 2490.5178 -761.3173 0 0 +M V30 10 Cl 2562.3979 -553.8173 0 0 +M V30 11 Cl 2634.2778 -761.3173 0 0 +M V30 12 C 2706.1582 -636.8175 0 0 +M V30 13 C 2778.0381 -678.3182 0 0 +M V30 14 C 2849.918 -636.8182 0 0 +M V30 15 C 2921.7981 -678.3182 0 0 +M V30 16 Cl 2849.918 -553.8182 0 0 +M V30 17 Cl 2778.0381 -761.3181 0 0 +M V30 18 Cl 2706.1582 -553.8177 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6+,7+,8+,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1669.2778 -675.3174 0 0 +M V30 2 C 1597.3978 -633.8173 0 0 +M V30 3 C 1525.5178 -675.3174 0 0 +M V30 4 C 1453.6376 -633.8173 0 0 +M V30 5 C 1381.7576 -675.3174 0 0 +M V30 6 C 1309.8776 -633.8173 0 0 +M V30 7 Br 1381.7576 -758.3173 0 0 +M V30 8 Cl 1453.6376 -550.8173 0 0 +M V30 9 Cl 1525.5178 -758.3173 0 0 +M V30 10 Cl 1597.3978 -550.8173 0 0 +M V30 11 Cl 1669.2778 -758.3173 0 0 +M V30 12 C 1741.1582 -633.8175 0 0 +M V30 13 C 1813.0381 -675.3182 0 0 +M V30 14 C 1884.918 -633.8182 0 0 +M V30 15 C 1956.7981 -675.3182 0 0 +M V30 16 Cl 1884.918 -550.8182 0 0 +M V30 17 Cl 1813.0381 -758.3181 0 0 +M V30 18 Cl 1741.1582 -550.8177 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7+,8-,9-,10-/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 719.8806 -405.6257 0 0 +M V30 2 C 638.4742 -358.6256 0 0 +M V30 3 C 557.0679 -405.6257 0 0 +M V30 4 C 475.6614 -358.6256 0 0 +M V30 5 C 394.255 -405.6257 0 0 +M V30 6 C 312.8487 -358.6256 0 0 +M V30 7 Br 394.255 -499.6256 0 0 +M V30 8 Cl 475.6614 -264.6255 0 0 +M V30 9 Cl 557.0679 -499.6256 0 0 +M V30 10 Cl 638.4742 -264.6255 0 0 +M V30 11 Cl 719.8806 -499.6256 0 0 +M V30 12 C 801.2872 -358.6258 0 0 +M V30 13 C 882.6934 -405.6266 0 0 +M V30 14 C 964.0997 -358.6266 0 0 +M V30 15 C 1045.5061 -405.6266 0 0 +M V30 16 Cl 964.0997 -264.6266 0 0 +M V30 17 Cl 882.6934 -499.6266 0 0 +M V30 18 Cl 801.2872 -264.626 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STERAC1 ATOMS=(2 2 3) +M V30 MDLV30/STEABS ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7+,8-,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10) + +> +1EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1789.6389 -266.1587 0 0 +M V30 2 C 1717.7589 -224.6586 0 0 +M V30 3 C 1645.8789 -266.1587 0 0 +M V30 4 C 1573.9987 -224.6586 0 0 +M V30 5 C 1502.1187 -266.1587 0 0 +M V30 6 C 1430.2386 -224.6586 0 0 +M V30 7 Br 1502.1187 -349.1586 0 0 +M V30 8 Cl 1573.9987 -141.6586 0 0 +M V30 9 Cl 1645.8789 -349.1586 0 0 +M V30 10 Cl 1717.7589 -141.6586 0 0 +M V30 11 Cl 1789.6389 -349.1586 0 0 +M V30 12 C 1861.5193 -224.6588 0 0 +M V30 13 C 1933.3992 -266.1595 0 0 +M V30 14 C 2005.2792 -224.6595 0 0 +M V30 15 C 2077.1592 -266.1595 0 0 +M V30 16 Cl 2005.2792 -141.6595 0 0 +M V30 17 Cl 1933.3992 -349.1595 0 0 +M V30 18 Cl 1861.5193 -141.659 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=3 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=3 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC2 ATOMS=(1 1) +M V30 MDLV30/STEABS ATOMS=(2 2 3) +M V30 MDLV30/STERAC1 ATOMS=(2 4 5) +M V30 MDLV30/STEREL2 ATOMS=(2 12 13) +M V30 MDLV30/STEREL1 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m1/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m1/s1(7,9)2(4)(6,8)3(3,5)(10) + +> +2EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1789.6389 -266.1587 0 0 +M V30 2 C 1717.7589 -224.6586 0 0 +M V30 3 C 1645.8789 -266.1587 0 0 +M V30 4 C 1573.9987 -224.6586 0 0 +M V30 5 C 1502.1187 -266.1587 0 0 +M V30 6 C 1430.2386 -224.6586 0 0 +M V30 7 Br 1502.1187 -349.1586 0 0 +M V30 8 Cl 1573.9987 -141.6586 0 0 +M V30 9 Cl 1645.8789 -349.1586 0 0 +M V30 10 Cl 1717.7589 -141.6586 0 0 +M V30 11 Cl 1789.6389 -349.1586 0 0 +M V30 12 C 1861.5193 -224.6588 0 0 +M V30 13 C 1933.3992 -266.1595 0 0 +M V30 14 C 2005.2792 -224.6595 0 0 +M V30 15 C 2077.1592 -266.1595 0 0 +M V30 16 Cl 2005.2792 -141.6595 0 0 +M V30 17 Cl 1933.3992 -349.1595 0 0 +M V30 18 Cl 1861.5193 -141.659 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=3 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=3 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 1) +M V30 MDLV30/STEABS ATOMS=(2 2 3) +M V30 MDLV30/STERAC2 ATOMS=(2 4 5) +M V30 MDLV30/STEREL2 ATOMS=(2 12 13) +M V30 MDLV30/STEREL1 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7+,8-,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m1/s1(7,9)2(4)(6,8)3(3,5)(10) + +> +2EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1789.6389 -266.1587 0 0 +M V30 2 C 1717.7589 -224.6586 0 0 +M V30 3 C 1645.8789 -266.1587 0 0 +M V30 4 C 1573.9987 -224.6586 0 0 +M V30 5 C 1502.1187 -266.1587 0 0 +M V30 6 C 1430.2386 -224.6586 0 0 +M V30 7 Br 1502.1187 -349.1586 0 0 +M V30 8 Cl 1573.9987 -141.6586 0 0 +M V30 9 Cl 1645.8789 -349.1586 0 0 +M V30 10 Cl 1717.7589 -141.6586 0 0 +M V30 11 Cl 1789.6389 -349.1586 0 0 +M V30 12 C 1861.5193 -224.6588 0 0 +M V30 13 C 1933.3992 -266.1595 0 0 +M V30 14 C 2005.2792 -224.6595 0 0 +M V30 15 C 2077.1592 -266.1595 0 0 +M V30 16 Cl 2005.2792 -141.6595 0 0 +M V30 17 Cl 1933.3992 -349.1595 0 0 +M V30 18 Cl 1861.5193 -141.659 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=3 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=3 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 1) +M V30 MDLV30/STEABS ATOMS=(2 2 3) +M V30 MDLV30/STERAC2 ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7+,8-,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m1/s1(7,9)2(4)(6,8)3(3,5)(10) + +> +2EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1789.6389 -266.1587 0 0 +M V30 2 C 1717.7589 -224.6586 0 0 +M V30 3 C 1645.8789 -266.1587 0 0 +M V30 4 C 1573.9987 -224.6586 0 0 +M V30 5 C 1502.1187 -266.1587 0 0 +M V30 6 C 1430.2386 -224.6586 0 0 +M V30 7 Br 1502.1187 -349.1586 0 0 +M V30 8 Cl 1573.9987 -141.6586 0 0 +M V30 9 Cl 1645.8789 -349.1586 0 0 +M V30 10 Cl 1717.7589 -141.6586 0 0 +M V30 11 Cl 1789.6389 -349.1586 0 0 +M V30 12 C 1861.5193 -224.6588 0 0 +M V30 13 C 1933.3992 -266.1595 0 0 +M V30 14 C 2005.2792 -224.6595 0 0 +M V30 15 C 2077.1592 -266.1595 0 0 +M V30 16 Cl 2005.2792 -141.6595 0 0 +M V30 17 Cl 1933.3992 -349.1595 0 0 +M V30 18 Cl 1861.5193 -141.659 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=3 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=3 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=1 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 1) +M V30 MDLV30/STEABS ATOMS=(2 2 3) +M V30 MDLV30/STERAC2 ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7+,8-,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m1/s1(7,9)2(4)(6,8)3(3,5)(10) + +> +2EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 18 17 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1789.6389 -266.1587 0 0 +M V30 2 C 1717.7589 -224.6586 0 0 +M V30 3 C 1645.8789 -266.1587 0 0 +M V30 4 C 1573.9987 -224.6586 0 0 +M V30 5 C 1502.1187 -266.1587 0 0 +M V30 6 C 1430.2386 -224.6586 0 0 +M V30 7 Br 1502.1187 -349.1586 0 0 +M V30 8 Cl 1573.9987 -141.6586 0 0 +M V30 9 Cl 1645.8789 -349.1586 0 0 +M V30 10 Cl 1717.7589 -141.6586 0 0 +M V30 11 Cl 1789.6389 -349.1586 0 0 +M V30 12 C 1861.5193 -224.6588 0 0 +M V30 13 C 1933.3992 -266.1595 0 0 +M V30 14 C 2005.2792 -224.6595 0 0 +M V30 15 C 2077.1592 -266.1595 0 0 +M V30 16 Cl 2005.2792 -141.6595 0 0 +M V30 17 Cl 1933.3992 -349.1595 0 0 +M V30 18 Cl 1861.5193 -141.659 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 CFG=1 +M V30 3 1 1 12 +M V30 4 1 2 3 +M V30 5 1 2 10 CFG=3 +M V30 6 1 3 4 +M V30 7 1 3 9 CFG=3 +M V30 8 1 4 5 +M V30 9 1 4 8 CFG=1 +M V30 10 1 5 6 +M V30 11 1 5 7 CFG=1 +M V30 12 1 12 13 +M V30 13 1 12 18 CFG=1 +M V30 14 1 13 14 +M V30 15 1 13 17 CFG=3 +M V30 16 1 14 15 +M V30 17 1 14 16 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(1 1) +M V30 MDLV30/STEABS ATOMS=(2 2 3) +M V30 MDLV30/STERAC2 ATOMS=(2 4 5) +M V30 MDLV30/STEREL1 ATOMS=(2 12 13) +M V30 MDLV30/STEREL2 ATOMS=(1 14) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4+,5+,6-,7+,8-,9-,10+/m0/s1 + +> +InChI=1S/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m1/s1(7,9)2(4)(6,8)3(3,5)(10) + +> +2EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 8 8 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 858.7786 -570.2803 0 0 +M V30 2 C 907.3196 -535.0132 0 0 +M V30 3 C 877.3196 -627.3436 0 0 +M V30 4 O 801.7153 -551.7392 0 0 +M V30 5 O 907.3197 -475.0132 0 0 +M V30 6 C 955.8607 -570.2803 0 0 +M V30 7 Cl 1012.9241 -551.7394 0 0 +M V30 8 C 937.3196 -627.3438 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 3 +M V30 3 1 1 4 CFG=1 +M V30 4 1 2 5 CFG=1 +M V30 5 1 2 6 +M V30 6 1 3 8 +M V30 7 1 6 7 CFG=1 +M V30 8 1 6 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(3 1 2 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m0/s1 + +> +InChI=1/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m0/s2 + +> +3EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 8 8 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 413.74 -573.2996 0 0 +M V30 2 C 462.2811 -538.0325 0 0 +M V30 3 C 432.2809 -630.3629 0 0 +M V30 4 O 356.6766 -554.7585 0 0 +M V30 5 O 462.2811 -478.0325 0 0 +M V30 6 C 510.822 -573.2996 0 0 +M V30 7 Cl 567.8854 -554.7587 0 0 +M V30 8 C 492.281 -630.363 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 3 +M V30 3 1 1 4 CFG=3 +M V30 4 1 2 5 CFG=3 +M V30 5 1 2 6 +M V30 6 1 3 8 +M V30 7 1 6 7 CFG=3 +M V30 8 1 6 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(3 1 2 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m1/s1 + +> +InChI=1/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m0/s2 + +> +3EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 8 8 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1839.8173 -572.261 0 0 +M V30 2 C 1888.3582 -536.9939 0 0 +M V30 3 C 1858.3582 -629.3243 0 0 +M V30 4 O 1782.7539 -553.7199 0 0 +M V30 5 O 1888.3583 -476.9939 0 0 +M V30 6 C 1936.8992 -572.261 0 0 +M V30 7 Cl 1993.9626 -553.7202 0 0 +M V30 8 C 1918.358 -629.3245 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 3 +M V30 3 1 1 4 CFG=1 +M V30 4 1 2 5 CFG=1 +M V30 5 1 2 6 +M V30 6 1 3 8 +M V30 7 1 6 7 CFG=1 +M V30 8 1 6 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(3 1 2 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m0/s1 + +> +InChI=1/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m0/s3 + +> +4EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 8 8 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1394.7787 -575.2803 0 0 +M V30 2 C 1443.3196 -540.0132 0 0 +M V30 3 C 1413.3196 -632.3436 0 0 +M V30 4 O 1337.7153 -556.7392 0 0 +M V30 5 O 1443.3197 -480.0132 0 0 +M V30 6 C 1491.8606 -575.2803 0 0 +M V30 7 Cl 1548.9241 -556.7394 0 0 +M V30 8 C 1473.3195 -632.3438 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 3 +M V30 3 1 1 4 CFG=3 +M V30 4 1 2 5 CFG=3 +M V30 5 1 2 6 +M V30 6 1 3 8 +M V30 7 1 6 7 CFG=3 +M V30 8 1 6 8 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STERAC1 ATOMS=(3 1 2 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m1/s1 + +> +InChI=1/C5H9ClO2/c6-3-1-2-4(7)5(3)8/h3-5,7-8H,1-2H2/t3-,4+,5-/m0/s3 + +> +4EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 11 10 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 5.15734 -5.49189 0.0 0 +M V30 2 C 6.02876 -5.00137 0.0 0 CFG=2 +M V30 3 C 6.88929 -5.51079 0.0 0 +M V30 4 C 7.76071 -5.02026 0.0 0 CFG=2 +M V30 5 C 8.62123 -5.52968 0.0 0 +M V30 6 C 9.49266 -5.03916 0.0 0 CFG=2 +M V30 7 C 10.3532 -5.54857 0.0 0 +M V30 8 Cl 6.03968 -4.00143 0.0 0 +M V30 9 Br 7.77162 -4.02032 0.0 0 +M V30 10 O 9.50357 -4.03922 0.0 0 +M V30 11 C 4.29682 -4.98247 0.0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 +M V30 3 1 2 3 +M V30 4 1 2 8 CFG=1 +M V30 5 1 3 4 +M V30 6 1 4 5 +M V30 7 1 4 9 CFG=1 +M V30 8 1 5 6 +M V30 9 1 6 7 +M V30 10 1 6 10 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(3 2 4 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6+,7-/m1/s1 + +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6+,7-/m1/s1 + +> +5EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 10 9 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 250 -700 0 0 +M V30 2 C 302.2857 -670.5686 0 0 +M V30 3 C 353.9169 -701.1337 0 0 +M V30 4 C 406.2026 -671.7023 0 0 +M V30 5 C 457.8337 -702.2673 0 0 +M V30 6 C 510.1194 -672.8359 0 0 +M V30 7 C 561.7506 -703.4009 0 0 +M V30 8 Cl 302.9404 -610.5721 0 0 +M V30 9 Br 406.8572 -611.7058 0 0 +M V30 10 O 510.7741 -612.8395 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 2 3 +M V30 3 1 2 8 CFG=1 +M V30 4 1 3 4 +M V30 5 1 4 5 +M V30 6 1 4 9 CFG=1 +M V30 7 1 5 6 +M V30 8 1 6 7 +M V30 9 1 6 10 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(1 2) +M V30 MDLV30/STEREL1 ATOMS=(1 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6-,7-/m1/s1 + +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6-,7-/m1/s1(5)2(7)3(6) + +> +6EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 10 9 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 250 -700 0 0 +M V30 2 C 302.2857 -670.5686 0 0 +M V30 3 C 353.9169 -701.1337 0 0 +M V30 4 C 406.2026 -671.7023 0 0 +M V30 5 C 457.8337 -702.2673 0 0 +M V30 6 C 510.1194 -672.8359 0 0 +M V30 7 C 561.7506 -703.4009 0 0 +M V30 8 Cl 302.9404 -610.5721 0 0 +M V30 9 Br 406.8572 -611.7058 0 0 +M V30 10 O 510.7741 -612.8395 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 2 3 +M V30 3 1 2 8 CFG=1 +M V30 4 1 3 4 +M V30 5 1 4 5 +M V30 6 1 4 9 CFG=3 +M V30 7 1 5 6 +M V30 8 1 6 7 +M V30 9 1 6 10 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(1 2) +M V30 MDLV30/STEREL1 ATOMS=(1 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6-,7+/m1/s1 + +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6-,7-/m1/s1(5)2(7)3(6) + +> +6EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 10 9 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 250 -700 0 0 +M V30 2 C 302.2857 -670.5686 0 0 +M V30 3 C 353.9169 -701.1337 0 0 +M V30 4 C 406.2026 -671.7023 0 0 +M V30 5 C 457.8337 -702.2673 0 0 +M V30 6 C 510.1194 -672.8359 0 0 +M V30 7 C 561.7506 -703.4009 0 0 +M V30 8 Cl 302.9404 -610.5721 0 0 +M V30 9 Br 406.8572 -611.7058 0 0 +M V30 10 O 510.7741 -612.8395 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 2 3 +M V30 3 1 2 8 CFG=1 +M V30 4 1 3 4 +M V30 5 1 4 5 +M V30 6 1 4 9 CFG=3 +M V30 7 1 5 6 +M V30 8 1 6 7 +M V30 9 1 6 10 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(1 2) +M V30 MDLV30/STEREL1 ATOMS=(1 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6+,7+/m1/s1 + +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6-,7-/m1/s1(5)2(7)3(6) + +> +6EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 10 9 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 250 -700 0 0 +M V30 2 C 302.2857 -670.5686 0 0 +M V30 3 C 353.9169 -701.1337 0 0 +M V30 4 C 406.2026 -671.7023 0 0 +M V30 5 C 457.8337 -702.2673 0 0 +M V30 6 C 510.1194 -672.8359 0 0 +M V30 7 C 561.7506 -703.4009 0 0 +M V30 8 Cl 302.9404 -610.5721 0 0 +M V30 9 Br 406.8572 -611.7058 0 0 +M V30 10 O 510.7741 -612.8395 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 2 3 +M V30 3 1 2 8 CFG=1 +M V30 4 1 3 4 +M V30 5 1 4 5 +M V30 6 1 4 9 CFG=1 +M V30 7 1 5 6 +M V30 8 1 6 7 +M V30 9 1 6 10 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(1 2) +M V30 MDLV30/STEREL1 ATOMS=(1 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6+,7-/m1/s1 + +> +InChI=1S/C7H14BrClO/c1-5(9)3-7(8)4-6(2)10/h5-7,10H,3-4H2,1-2H3/t5-,6-,7-/m1/s1(5)2(7)3(6) + +> +6EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0 0 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 11 10 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 3.40734 -5.94189 0.0 0 +M V30 2 C 4.27876 -5.45137 0.0 0 CFG=2 +M V30 3 C 5.13929 -5.96079 0.0 0 +M V30 4 C 6.01071 -5.47026 0.0 0 CFG=2 +M V30 5 C 6.87123 -5.97968 0.0 0 +M V30 6 C 7.74266 -5.48916 0.0 0 CFG=2 +M V30 7 C 8.60318 -5.99857 0.0 0 +M V30 8 Cl 4.28968 -4.45143 0.0 0 +M V30 9 Br 6.02162 -4.47032 0.0 0 +M V30 10 O 7.75357 -4.48922 0.0 0 +M V30 11 C 2.54682 -5.43247 0.0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 +M V30 3 1 2 3 +M V30 4 1 2 8 CFG=1 +M V30 5 1 3 4 +M V30 6 1 4 5 +M V30 7 1 4 9 CFG=1 +M V30 8 1 5 6 +M V30 9 1 6 7 +M V30 10 1 6 10 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEABS ATOMS=(3 2 4 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m0/s1 + +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m0/s1 + +> +7EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 11 10 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1012 -1609 0 0 +M V30 2 C 1064.2856 -1579.5686 0 0 +M V30 3 C 1115.9169 -1610.1337 0 0 +M V30 4 C 1168.2026 -1580.7023 0 0 +M V30 5 C 1219.8337 -1611.2673 0 0 +M V30 6 C 1272.1194 -1581.8359 0 0 +M V30 7 C 1323.7506 -1612.4009 0 0 +M V30 8 Cl 1064.9404 -1519.5721 0 0 +M V30 9 Br 1168.8572 -1520.7058 0 0 +M V30 10 O 1272.7742 -1521.8395 0 0 +M V30 11 C 960.3689 -1578.4348 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 +M V30 3 1 2 3 +M V30 4 1 2 8 CFG=3 +M V30 5 1 3 4 +M V30 6 1 4 5 +M V30 7 1 4 9 CFG=3 +M V30 8 1 5 6 +M V30 9 1 6 7 +M V30 10 1 6 10 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 2 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m1/s1 + +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m0/s2(7,8)3(6) + +> +8EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 11 10 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1012 -1609 0 0 +M V30 2 C 1064.2856 -1579.5686 0 0 +M V30 3 C 1115.9169 -1610.1337 0 0 +M V30 4 C 1168.2026 -1580.7023 0 0 +M V30 5 C 1219.8337 -1611.2673 0 0 +M V30 6 C 1272.1194 -1581.8359 0 0 +M V30 7 C 1323.7506 -1612.4009 0 0 +M V30 8 Cl 1064.9404 -1519.5721 0 0 +M V30 9 Br 1168.8572 -1520.7058 0 0 +M V30 10 O 1272.7742 -1521.8395 0 0 +M V30 11 C 960.3689 -1578.4348 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 +M V30 3 1 2 3 +M V30 4 1 2 8 CFG=1 +M V30 5 1 3 4 +M V30 6 1 4 5 +M V30 7 1 4 9 CFG=1 +M V30 8 1 5 6 +M V30 9 1 6 7 +M V30 10 1 6 10 CFG=3 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 2 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7+,8-/m1/s1 + +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m0/s2(7,8)3(6) + +> +8EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 11 10 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1012 -1609 0 0 +M V30 2 C 1064.2856 -1579.5686 0 0 +M V30 3 C 1115.9169 -1610.1337 0 0 +M V30 4 C 1168.2026 -1580.7023 0 0 +M V30 5 C 1219.8337 -1611.2673 0 0 +M V30 6 C 1272.1194 -1581.8359 0 0 +M V30 7 C 1323.7506 -1612.4009 0 0 +M V30 8 Cl 1064.9404 -1519.5721 0 0 +M V30 9 Br 1168.8572 -1520.7058 0 0 +M V30 10 O 1272.7742 -1521.8395 0 0 +M V30 11 C 960.3689 -1578.4348 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 +M V30 3 1 2 3 +M V30 4 1 2 8 CFG=3 +M V30 5 1 3 4 +M V30 6 1 4 5 +M V30 7 1 4 9 CFG=3 +M V30 8 1 5 6 +M V30 9 1 6 7 +M V30 10 1 6 10 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 2 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7+,8-/m0/s1 + +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m0/s2(7,8)3(6) + +> +8EN + +$$$$ + + ACD/LABS08242216132D + + 0 0 0 0 0 0 0 0 0 0999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 11 10 0 0 1 +M V30 BEGIN ATOM +M V30 1 C 1016 -1151 0 0 +M V30 2 C 1068.2856 -1121.5686 0 0 +M V30 3 C 1119.9169 -1152.1337 0 0 +M V30 4 C 1172.2026 -1122.7023 0 0 +M V30 5 C 1223.8337 -1153.2673 0 0 +M V30 6 C 1276.1194 -1123.8359 0 0 +M V30 7 C 1327.7506 -1154.4009 0 0 +M V30 8 Cl 1068.9404 -1061.5721 0 0 +M V30 9 Br 1172.8572 -1062.7058 0 0 +M V30 10 O 1276.7742 -1063.8395 0 0 +M V30 11 C 964.3689 -1120.4348 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 11 +M V30 3 1 2 3 +M V30 4 1 2 8 CFG=1 +M V30 5 1 3 4 +M V30 6 1 4 5 +M V30 7 1 4 9 CFG=1 +M V30 8 1 5 6 +M V30 9 1 6 7 +M V30 10 1 6 10 CFG=1 +M V30 END BOND +M V30 BEGIN COLLECTION +M V30 MDLV30/STEREL1 ATOMS=(2 2 4) +M V30 MDLV30/STERAC1 ATOMS=(1 6) +M V30 END COLLECTION +M V30 END CTAB +M END +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m0/s1 + +> +InChI=1S/C8H16BrClO/c1-3-8(10)5-7(9)4-6(2)11/h6-8,11H,3-5H2,1-2H3/t6-,7-,8+/m0/s2(7,8)3(6) + +> +8EN + +$$$$ diff --git a/INCHI-1-TEST/tests/test_unit/test_enhancedStereo.cpp b/INCHI-1-TEST/tests/test_unit/test_enhancedStereo.cpp new file mode 100644 index 00000000..0a771802 --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/test_enhancedStereo.cpp @@ -0,0 +1,1229 @@ +#include +#include + +extern "C" +{ +#include "../../../INCHI-1-SRC/INCHI_BASE/src/inchi_api.h" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/mode.h" +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_molfile_v2) +{ + const char *molblock = + "test_mol_2 \n" + " Ketcher 1302610202D 1 1.00000 0.00000 0 \n" + " \n" + " 13 12 0 0 0 0 0 0 0 0999 V2000 \n" + " 2.9420 -4.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 3.8080 -3.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 4.6740 -4.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 5.5401 -3.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 6.4061 -4.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 7.2721 -3.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 8.1381 -4.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 6.4061 -5.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 5.5401 -2.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 5.5401 -5.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 5.5401 -6.6000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 6.4061 -2.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 6.4061 -1.1000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 \n" + " 1 2 1 0 0 0 \n" + " 2 3 1 0 0 0 \n" + " 3 4 1 0 0 0 \n" + " 4 5 1 0 0 0 \n" + " 5 6 1 0 0 0 \n" + " 6 7 1 0 0 0 \n" + " 5 8 1 0 0 0 \n" + " 4 9 1 0 0 0 \n" + " 8 10 1 0 0 0 \n" + " 10 11 1 0 0 0 \n" + " 9 12 1 0 0 0 \n" + " 12 13 1 0 0 0 \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C13H28/c1-5-9-12(8-4)13(10-6-2)11-7-3/h12-13H,5-11H2,1-4H3"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 1); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_1) +{ + const char *molblock = + "enhanc_stereo1 \n" + " ACD/LABS08242216132D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0999 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 18 17 0 0 1 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 3424.1946 -1936.7935 0 0 \n" + "M V30 2 C 3352.3145 -1895.2935 0 0 \n" + "M V30 3 C 3280.4346 -1936.7935 0 0 \n" + "M V30 4 C 3208.5542 -1895.2935 0 0 \n" + "M V30 5 C 3136.6743 -1936.7935 0 0 \n" + "M V30 6 C 3064.7944 -1895.2935 0 0 \n" + "M V30 7 Br 3136.6743 -2019.7935 0 0 \n" + "M V30 8 Cl 3208.5542 -1812.2935 0 0 \n" + "M V30 9 Cl 3280.4346 -2019.7935 0 0 \n" + "M V30 10 Cl 3352.3145 -1812.2935 0 0 \n" + "M V30 11 Cl 3424.1946 -2019.7935 0 0 \n" + "M V30 12 C 3496.075 -1895.2935 0 0 \n" + "M V30 13 C 3567.9548 -1936.7942 0 0 \n" + "M V30 14 C 3639.835 -1895.2944 0 0 \n" + "M V30 15 C 3711.7148 -1936.7942 0 0 \n" + "M V30 16 Cl 3639.835 -1812.2944 0 0 \n" + "M V30 17 Cl 3567.9548 -2019.7942 0 0 \n" + "M V30 18 Cl 3496.075 -1812.2937 0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 1 11 CFG=3 \n" + "M V30 3 1 1 12 \n" + "M V30 4 1 2 3 \n" + "M V30 5 1 2 10 CFG=1 \n" + "M V30 6 1 3 4 \n" + "M V30 7 1 3 9 CFG=1 \n" + "M V30 8 1 4 5 \n" + "M V30 9 1 4 8 CFG=1 \n" + "M V30 10 1 5 6 \n" + "M V30 11 1 5 7 CFG=1 \n" + "M V30 12 1 12 13 \n" + "M V30 13 1 12 18 CFG=3 \n" + "M V30 14 1 13 14 \n" + "M V30 15 1 13 17 CFG=1 \n" + "M V30 16 1 14 15 \n" + "M V30 17 1 14 16 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 1) \n" + "M V30 MDLV30/STERAC1 ATOMS=(2 2 3) \n" + "M V30 MDLV30/STEABS ATOMS=(2 4 5) \n" + "M V30 MDLV30/STEREL1 ATOMS=(2 12 13) \n" + "M V30 MDLV30/STEREL2 ATOMS=(1 14) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C10H14BrCl7/c1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h3-10H,1-2H3/t3-,4-,5+,6-,7-,8-,9+,10-/m0/s1(3,5)2(4)(6,8)3(7,9)(10)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_2_atropisomer) +{ + const char *molblock = + "test_mol_atropisomer_1 \n" + " -INDIGO-02052611532D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 16 17 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 6.11597 -6.27499 0.0 0 \n" + "M V30 2 C 5.24996 -5.775 0.0 0 \n" + "M V30 3 C 4.38395 -6.27499 0.0 0 \n" + "M V30 4 C 4.38395 -7.27499 0.0 0 \n" + "M V30 5 C 5.24996 -7.77498 0.0 0 \n" + "M V30 6 C 6.11597 -7.27499 0.0 0 \n" + "M V30 7 C 6.11605 -4.27501 0.0 0 \n" + "M V30 8 C 5.24996 -4.775 0.0 0 \n" + "M V30 9 C 4.38395 -4.27501 0.0 0 \n" + "M V30 10 C 4.38395 -3.27501 0.0 0 \n" + "M V30 11 C 6.11605 -3.27501 0.0 0 \n" + "M V30 12 C 5.25004 -2.77502 0.0 0 \n" + "M V30 13 Br 6.98205 -4.775 0.0 0 \n" + "M V30 14 Cl 3.51795 -4.775 0.0 0 \n" + "M V30 15 Cl 3.51795 -5.77492 0.0 0 \n" + "M V30 16 Br 6.98205 -5.775 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 6 \n" + "M V30 2 2 1 2 \n" + "M V30 3 1 2 3 CFG=1 \n" + "M V30 4 1 2 8 \n" + "M V30 5 2 3 4 \n" + "M V30 6 1 5 4 \n" + "M V30 7 2 5 6 \n" + "M V30 8 1 8 7 CFG=1 \n" + "M V30 9 2 7 11 \n" + "M V30 10 2 8 9 \n" + "M V30 11 1 9 10 \n" + "M V30 12 2 10 12 \n" + "M V30 13 1 12 11 \n" + "M V30 14 1 7 13 \n" + "M V30 15 1 9 14 \n" + "M V30 16 1 3 15 \n" + "M V30 17 1 1 16 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STEABS ATOMS=(2 2 8) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C12H6Br2Cl2/c13-7-3-1-5-9(15)11(7)12-8(14)4-2-6-10(12)16/h1-6H"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_3_empty_collection_info) +{ + const char *molblock = + "broken_mol? \n" + " -INDIGO-02062608442D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 9 8 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 4.64199 -4.9 0.0 0 \n" + "M V30 2 C 5.50801 -4.4 0.0 0 CFG=2 \n" + "M V30 3 C 6.37404 -4.9 0.0 0 CFG=2 \n" + "M V30 4 C 7.24006 -4.4 0.0 0 CFG=2 \n" + "M V30 5 C 8.10609 -4.9 0.0 0 \n" + "M V30 6 C 6.37404 -5.9 0.0 0 \n" + "M V30 7 C 5.50801 -3.4 0.0 0 \n" + "M V30 8 C 8.97211 -4.4 0.0 0 \n" + "M V30 9 C 7.24006 -3.4 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 2 3 \n" + "M V30 3 1 3 4 \n" + "M V30 4 1 4 5 \n" + "M V30 5 1 3 6 CFG=3 \n" + "M V30 6 1 2 7 CFG=1 \n" + "M V30 7 1 5 8 \n" + "M V30 8 1 4 9 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC1 ATOMS=(1 ) \n" + "M V30 MDLV30/STEABS ATOMS=(2 ) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C9H20/c1-6-8(4)9(5)7(2)3/h7-9H,6H2,1-5H3/t8-,9+/m0"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_3_wrong_atoms_in_collection) +{ + const char *molblock = + "broken_mol? \n" + " -INDIGO-02062608442D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 9 8 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 4.64199 -4.9 0.0 0 \n" + "M V30 2 C 5.50801 -4.4 0.0 0 CFG=2 \n" + "M V30 3 C 6.37404 -4.9 0.0 0 CFG=2 \n" + "M V30 4 C 7.24006 -4.4 0.0 0 CFG=2 \n" + "M V30 5 C 8.10609 -4.9 0.0 0 \n" + "M V30 6 C 6.37404 -5.9 0.0 0 \n" + "M V30 7 C 5.50801 -3.4 0.0 0 \n" + "M V30 8 C 8.97211 -4.4 0.0 0 \n" + "M V30 9 C 7.24006 -3.4 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 2 3 \n" + "M V30 3 1 3 4 \n" + "M V30 4 1 4 5 \n" + "M V30 5 1 3 6 CFG=3 \n" + "M V30 6 1 2 7 CFG=1 \n" + "M V30 7 1 5 8 \n" + "M V30 8 1 4 9 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC1 ATOMS=(1 -2) \n" + "M V30 MDLV30/STEABS ATOMS=(2 13 43) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C9H20/c1-6-8(4)9(5)7(2)3/h7-9H,6H2,1-5H3/t8-,9+/m0"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_2_mols) +{ + const char *molblock = + "test_mol \n" + " -INDIGO-01232613552D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 36 34 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 5.83301 -3.275 0.0 0 CFG=1 \n" + "M V30 2 C 4.96699 -2.775 0.0 0 CFG=1 \n" + "M V30 3 C 4.10096 -3.275 0.0 0 CFG=2 \n" + "M V30 4 C 3.23493 -2.775 0.0 0 CFG=1 \n" + "M V30 5 C 2.36891 -3.275 0.0 0 CFG=2 \n" + "M V30 6 C 1.50289 -2.775 0.0 0 \n" + "M V30 7 Br 2.36891 -4.275 0.0 0 \n" + "M V30 8 Cl 3.23493 -1.775 0.0 0 \n" + "M V30 9 Cl 4.10096 -4.275 0.0 0 \n" + "M V30 10 Cl 4.96699 -1.775 0.0 0 \n" + "M V30 11 Cl 5.83301 -4.275 0.0 0 \n" + "M V30 12 C 6.69904 -2.775 0.0 0 CFG=1 \n" + "M V30 13 C 7.56506 -3.275 0.0 0 CFG=1 \n" + "M V30 14 C 8.43109 -2.77501 0.0 0 CFG=2 \n" + "M V30 15 C 9.29711 -3.275 0.0 0 \n" + "M V30 16 Cl 8.43109 -1.77501 0.0 0 \n" + "M V30 17 Cl 7.56506 -4.275 0.0 0 \n" + "M V30 18 Cl 6.69904 -1.775 0.0 0 \n" + "M V30 19 C 6.13302 -7.62502 0.0 0 CFG=2 \n" + "M V30 20 C 5.26698 -7.12498 0.0 0 CFG=1 \n" + "M V30 21 C 4.40101 -7.62502 0.0 0 CFG=2 \n" + "M V30 22 C 3.53496 -7.12498 0.0 0 CFG=1 \n" + "M V30 23 C 2.66891 -7.62502 0.0 0 CFG=2 \n" + "M V30 24 C 6.99899 -7.12498 0.0 0 CFG=2 \n" + "M V30 25 C 7.86504 -7.62502 0.0 0 CFG=2 \n" + "M V30 26 C 8.73109 -7.12498 0.0 0 CFG=2 \n" + "M V30 27 C 1.80295 -7.12498 0.0 0 \n" + "M V30 28 Br 2.66891 -8.62501 0.0 0 \n" + "M V30 29 Cl 3.53496 -6.12499 0.0 0 \n" + "M V30 30 Cl 4.40101 -8.62501 0.0 0 \n" + "M V30 31 Cl 5.26698 -6.12499 0.0 0 \n" + "M V30 32 Cl 6.13302 -8.62501 0.0 0 \n" + "M V30 33 C 9.59705 -7.62502 0.0 0 \n" + "M V30 34 Cl 8.73109 -6.12499 0.0 0 \n" + "M V30 35 Cl 7.86504 -8.62501 0.0 0 \n" + "M V30 36 Cl 6.99899 -6.12499 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 1 11 CFG=3 \n" + "M V30 3 1 1 12 \n" + "M V30 4 1 2 3 \n" + "M V30 5 1 2 10 CFG=1 \n" + "M V30 6 1 3 4 \n" + "M V30 7 1 3 9 CFG=1 \n" + "M V30 8 1 4 5 \n" + "M V30 9 1 4 8 CFG=1 \n" + "M V30 10 1 5 6 \n" + "M V30 11 1 5 7 CFG=1 \n" + "M V30 12 1 12 13 \n" + "M V30 13 1 12 18 CFG=3 \n" + "M V30 14 1 13 14 \n" + "M V30 15 1 13 17 CFG=1 \n" + "M V30 16 1 14 15 \n" + "M V30 17 1 14 16 CFG=1 \n" + "M V30 18 1 19 20 \n" + "M V30 19 1 20 21 \n" + "M V30 20 1 21 22 \n" + "M V30 21 1 22 23 \n" + "M V30 22 1 19 24 \n" + "M V30 23 1 24 25 \n" + "M V30 24 1 25 26 \n" + "M V30 25 1 23 27 \n" + "M V30 26 1 23 28 CFG=1 \n" + "M V30 27 1 22 29 CFG=1 \n" + "M V30 28 1 21 30 CFG=1 \n" + "M V30 29 1 20 31 CFG=1 \n" + "M V30 30 1 19 32 CFG=3 \n" + "M V30 31 1 26 33 \n" + "M V30 32 1 26 34 CFG=1 \n" + "M V30 33 1 25 35 CFG=3 \n" + "M V30 34 1 24 36 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 1) \n" + "M V30 MDLV30/STERAC1 ATOMS=(2 2 3) \n" + "M V30 MDLV30/STEABS ATOMS=(4 4 5 22 23) \n" + "M V30 MDLV30/STEREL1 ATOMS=(2 12 13) \n" + "M V30 MDLV30/STEREL2 ATOMS=(1 14) \n" + "M V30 MDLV30/STERAC4 ATOMS=(1 19) \n" + "M V30 MDLV30/STERAC3 ATOMS=(2 20 21) \n" + "M V30 MDLV30/STEREL3 ATOMS=(2 24 25) \n" + "M V30 MDLV30/STEREL4 ATOMS=(1 26) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/2C10H14BrCl7/c2*1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h2*3-10H,1-2H3/t2*3-,4-,5+,6-,7-,8-,9+,10-/m00/s2*1(3,5)2(4)(6,8)3(7,9)(10)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_3_mols) +{ + const char *molblock = + "test mol \n" + " -INDIGO-01272609172D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 44 41 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 5.48304 -3.77499 0.0 0 CFG=1 \n" + "M V30 2 C 4.61702 -3.27499 0.0 0 CFG=1 \n" + "M V30 3 C 3.75099 -3.77499 0.0 0 CFG=2 \n" + "M V30 4 C 2.88496 -3.27499 0.0 0 CFG=1 \n" + "M V30 5 C 2.01894 -3.77499 0.0 0 CFG=2 \n" + "M V30 6 C 1.15292 -3.27499 0.0 0 \n" + "M V30 7 Br 2.01894 -4.77499 0.0 0 \n" + "M V30 8 Cl 2.88496 -2.27499 0.0 0 \n" + "M V30 9 Cl 3.75099 -4.77499 0.0 0 \n" + "M V30 10 Cl 4.61702 -2.27499 0.0 0 \n" + "M V30 11 Cl 5.48304 -4.77499 0.0 0 \n" + "M V30 12 C 6.34907 -3.27499 0.0 0 CFG=1 \n" + "M V30 13 C 7.21509 -3.77499 0.0 0 CFG=1 \n" + "M V30 14 C 8.08112 -3.275 0.0 0 CFG=2 \n" + "M V30 15 C 8.94714 -3.77499 0.0 0 \n" + "M V30 16 Cl 8.08112 -2.275 0.0 0 \n" + "M V30 17 Cl 7.21509 -4.77499 0.0 0 \n" + "M V30 18 Cl 6.34907 -2.27499 0.0 0 \n" + "M V30 19 C 5.78305 -8.12502 0.0 0 CFG=2 \n" + "M V30 20 C 4.91701 -7.62498 0.0 0 CFG=1 \n" + "M V30 21 C 4.05104 -8.12502 0.0 0 CFG=2 \n" + "M V30 22 C 3.18499 -7.62498 0.0 0 CFG=1 \n" + "M V30 23 C 2.31894 -8.12502 0.0 0 CFG=2 \n" + "M V30 24 C 6.64902 -7.62498 0.0 0 CFG=2 \n" + "M V30 25 C 7.51507 -8.12502 0.0 0 CFG=2 \n" + "M V30 26 C 8.38112 -7.62498 0.0 0 CFG=2 \n" + "M V30 27 C 1.45298 -7.62498 0.0 0 \n" + "M V30 28 Br 2.31894 -9.12501 0.0 0 \n" + "M V30 29 Cl 3.18499 -6.62499 0.0 0 \n" + "M V30 30 Cl 4.05104 -9.12501 0.0 0 \n" + "M V30 31 Cl 4.91701 -6.62499 0.0 0 \n" + "M V30 32 Cl 5.78305 -9.12501 0.0 0 \n" + "M V30 33 C 9.24708 -8.12502 0.0 0 \n" + "M V30 34 Cl 8.38112 -6.62499 0.0 0 \n" + "M V30 35 Cl 7.51507 -9.12501 0.0 0 \n" + "M V30 36 Cl 6.64902 -6.62499 0.0 0 \n" + "M V30 37 C 14.367 -4.45 0.0 0 CFG=1 \n" + "M V30 38 C 15.233 -3.95 0.0 0 CFG=2 \n" + "M V30 39 C 16.099 -4.45 0.0 0 \n" + "M V30 40 C 15.233 -2.95 0.0 0 \n" + "M V30 41 C 13.501 -3.95 0.0 0 CFG=1 \n" + "M V30 42 C 12.6349 -4.45 0.0 0 \n" + "M V30 43 C 13.501 -2.95 0.0 0 \n" + "M V30 44 C 14.367 -5.45 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 1 11 CFG=3 \n" + "M V30 3 1 1 12 \n" + "M V30 4 1 2 3 \n" + "M V30 5 1 2 10 CFG=1 \n" + "M V30 6 1 3 4 \n" + "M V30 7 1 3 9 CFG=1 \n" + "M V30 8 1 4 5 \n" + "M V30 9 1 4 8 CFG=1 \n" + "M V30 10 1 5 6 \n" + "M V30 11 1 5 7 CFG=1 \n" + "M V30 12 1 12 13 \n" + "M V30 13 1 12 18 CFG=3 \n" + "M V30 14 1 13 14 \n" + "M V30 15 1 13 17 CFG=1 \n" + "M V30 16 1 14 15 \n" + "M V30 17 1 14 16 CFG=1 \n" + "M V30 18 1 19 20 \n" + "M V30 19 1 20 21 \n" + "M V30 20 1 21 22 \n" + "M V30 21 1 22 23 \n" + "M V30 22 1 19 24 \n" + "M V30 23 1 24 25 \n" + "M V30 24 1 25 26 \n" + "M V30 25 1 23 27 \n" + "M V30 26 1 23 28 CFG=1 \n" + "M V30 27 1 22 29 CFG=1 \n" + "M V30 28 1 21 30 CFG=1 \n" + "M V30 29 1 20 31 CFG=1 \n" + "M V30 30 1 19 32 CFG=3 \n" + "M V30 31 1 26 33 \n" + "M V30 32 1 26 34 CFG=1 \n" + "M V30 33 1 25 35 CFG=3 \n" + "M V30 34 1 24 36 CFG=1 \n" + "M V30 35 1 37 38 \n" + "M V30 36 1 38 39 \n" + "M V30 37 1 38 40 CFG=1 \n" + "M V30 38 1 37 41 \n" + "M V30 39 1 41 42 \n" + "M V30 40 1 41 43 CFG=1 \n" + "M V30 41 1 37 44 CFG=3 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 1) \n" + "M V30 MDLV30/STERAC1 ATOMS=(2 2 3) \n" + "M V30 MDLV30/STEABS ATOMS=(5 4 5 22 23 38) \n" + "M V30 MDLV30/STEREL1 ATOMS=(2 12 13) \n" + "M V30 MDLV30/STEREL2 ATOMS=(1 14) \n" + "M V30 MDLV30/STERAC4 ATOMS=(1 19) \n" + "M V30 MDLV30/STERAC3 ATOMS=(2 20 21) \n" + "M V30 MDLV30/STEREL3 ATOMS=(2 24 25) \n" + "M V30 MDLV30/STEREL4 ATOMS=(1 26) \n" + "M V30 MDLV30/STERAC5 ATOMS=(2 37 41) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/2C10H14BrCl7.C8H18/c2*1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12;1-6(2)8(5)7(3)4/h2*3-10H,1-2H3;6-8H,1-5H3/t2*3-,4-,5+,6-,7-,8-,9+,10-;/m00./s2*1(3,5)2(4)(6,8)3(7,9)(10);1(6)3(7,8)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_4_mols) +{ + const char *molblock = + "test_mol \n" + " -INDIGO-01272609502D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 57 53 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 5.48304 -3.77499 0.0 0 CFG=1 \n" + "M V30 2 C 4.61702 -3.27499 0.0 0 CFG=1 \n" + "M V30 3 C 3.75099 -3.77499 0.0 0 CFG=2 \n" + "M V30 4 C 2.88496 -3.27499 0.0 0 CFG=1 \n" + "M V30 5 C 2.01894 -3.77499 0.0 0 CFG=2 \n" + "M V30 6 C 1.15292 -3.27499 0.0 0 \n" + "M V30 7 Br 2.01894 -4.77499 0.0 0 \n" + "M V30 8 Cl 2.88496 -2.27499 0.0 0 \n" + "M V30 9 Cl 3.75099 -4.77499 0.0 0 \n" + "M V30 10 Cl 4.61702 -2.27499 0.0 0 \n" + "M V30 11 Cl 5.48304 -4.77499 0.0 0 \n" + "M V30 12 C 6.34907 -3.27499 0.0 0 CFG=1 \n" + "M V30 13 C 7.21509 -3.77499 0.0 0 CFG=1 \n" + "M V30 14 C 8.08112 -3.275 0.0 0 CFG=2 \n" + "M V30 15 C 8.94714 -3.77499 0.0 0 \n" + "M V30 16 Cl 8.08112 -2.275 0.0 0 \n" + "M V30 17 Cl 7.21509 -4.77499 0.0 0 \n" + "M V30 18 Cl 6.34907 -2.27499 0.0 0 \n" + "M V30 19 C 5.78305 -8.12502 0.0 0 CFG=2 \n" + "M V30 20 C 4.91701 -7.62498 0.0 0 CFG=1 \n" + "M V30 21 C 4.05104 -8.12502 0.0 0 CFG=2 \n" + "M V30 22 C 3.18499 -7.62498 0.0 0 CFG=1 \n" + "M V30 23 C 2.31894 -8.12502 0.0 0 CFG=2 \n" + "M V30 24 C 6.64902 -7.62498 0.0 0 CFG=2 \n" + "M V30 25 C 7.51507 -8.12502 0.0 0 CFG=2 \n" + "M V30 26 C 8.38112 -7.62498 0.0 0 CFG=2 \n" + "M V30 27 C 1.45298 -7.62498 0.0 0 \n" + "M V30 28 Br 2.31894 -9.12501 0.0 0 \n" + "M V30 29 Cl 3.18499 -6.62499 0.0 0 \n" + "M V30 30 Cl 4.05104 -9.12501 0.0 0 \n" + "M V30 31 Cl 4.91701 -6.62499 0.0 0 \n" + "M V30 32 Cl 5.78305 -9.12501 0.0 0 \n" + "M V30 33 C 9.24708 -8.12502 0.0 0 \n" + "M V30 34 Cl 8.38112 -6.62499 0.0 0 \n" + "M V30 35 Cl 7.51507 -9.12501 0.0 0 \n" + "M V30 36 Cl 6.64902 -6.62499 0.0 0 \n" + "M V30 37 C 14.367 -4.45 0.0 0 CFG=1 \n" + "M V30 38 C 15.233 -3.95 0.0 0 CFG=2 \n" + "M V30 39 C 16.099 -4.45 0.0 0 \n" + "M V30 40 C 15.233 -2.95 0.0 0 \n" + "M V30 41 C 13.501 -3.95 0.0 0 CFG=1 \n" + "M V30 42 C 12.6349 -4.45 0.0 0 \n" + "M V30 43 C 13.501 -2.95 0.0 0 \n" + "M V30 44 C 14.367 -5.45 0.0 0 \n" + "M V30 45 C 11.7689 -3.95 0.0 0 \n" + "M V30 46 C 11.417 -7.75 0.0 0 \n" + "M V30 47 C 12.283 -7.25 0.0 0 CFG=2 \n" + "M V30 48 C 13.149 -7.75 0.0 0 \n" + "M V30 49 C 14.0151 -7.25 0.0 0 CFG=2 \n" + "M V30 50 C 14.8811 -7.75 0.0 0 \n" + "M V30 51 C 13.149 -8.75 0.0 0 CFG=2 \n" + "M V30 52 C 12.283 -9.25 0.0 0 \n" + "M V30 53 C 14.0151 -9.25 0.0 0 CFG=2 \n" + "M V30 54 C 14.0151 -10.25 0.0 0 \n" + "M V30 55 C 14.8811 -8.75 0.0 0 \n" + "M V30 56 C 14.0151 -6.25 0.0 0 \n" + "M V30 57 C 12.283 -6.25 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 1 11 CFG=3 \n" + "M V30 3 1 1 12 \n" + "M V30 4 1 2 3 \n" + "M V30 5 1 2 10 CFG=1 \n" + "M V30 6 1 3 4 \n" + "M V30 7 1 3 9 CFG=1 \n" + "M V30 8 1 4 5 \n" + "M V30 9 1 4 8 CFG=1 \n" + "M V30 10 1 5 6 \n" + "M V30 11 1 5 7 CFG=1 \n" + "M V30 12 1 12 13 \n" + "M V30 13 1 12 18 CFG=3 \n" + "M V30 14 1 13 14 \n" + "M V30 15 1 13 17 CFG=1 \n" + "M V30 16 1 14 15 \n" + "M V30 17 1 14 16 CFG=1 \n" + "M V30 18 1 19 20 \n" + "M V30 19 1 20 21 \n" + "M V30 20 1 21 22 \n" + "M V30 21 1 22 23 \n" + "M V30 22 1 19 24 \n" + "M V30 23 1 24 25 \n" + "M V30 24 1 25 26 \n" + "M V30 25 1 23 27 \n" + "M V30 26 1 23 28 CFG=1 \n" + "M V30 27 1 22 29 CFG=1 \n" + "M V30 28 1 21 30 CFG=1 \n" + "M V30 29 1 20 31 CFG=1 \n" + "M V30 30 1 19 32 CFG=3 \n" + "M V30 31 1 26 33 \n" + "M V30 32 1 26 34 CFG=1 \n" + "M V30 33 1 25 35 CFG=3 \n" + "M V30 34 1 24 36 CFG=1 \n" + "M V30 35 1 37 38 \n" + "M V30 36 1 38 39 \n" + "M V30 37 1 38 40 CFG=1 \n" + "M V30 38 1 37 41 \n" + "M V30 39 1 41 42 \n" + "M V30 40 1 41 43 CFG=1 \n" + "M V30 41 1 37 44 CFG=3 \n" + "M V30 42 1 42 45 \n" + "M V30 43 1 46 47 \n" + "M V30 44 1 47 48 \n" + "M V30 45 1 48 49 \n" + "M V30 46 1 49 50 \n" + "M V30 47 1 48 51 \n" + "M V30 48 1 51 52 CFG=1 \n" + "M V30 49 1 51 53 \n" + "M V30 50 1 53 54 \n" + "M V30 51 1 53 55 CFG=1 \n" + "M V30 52 1 49 56 CFG=1 \n" + "M V30 53 1 47 57 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 1) \n" + "M V30 MDLV30/STERAC1 ATOMS=(2 2 3) \n" + "M V30 MDLV30/STEABS ATOMS=(9 4 5 22 23 38 47 49 51 53) \n" + "M V30 MDLV30/STEREL1 ATOMS=(2 12 13) \n" + "M V30 MDLV30/STEREL2 ATOMS=(1 14) \n" + "M V30 MDLV30/STERAC4 ATOMS=(1 19) \n" + "M V30 MDLV30/STERAC3 ATOMS=(2 20 21) \n" + "M V30 MDLV30/STEREL3 ATOMS=(2 24 25) \n" + "M V30 MDLV30/STEREL4 ATOMS=(1 26) \n" + "M V30 MDLV30/STERAC5 ATOMS=(2 37 41) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C12H26.2C10H14BrCl7.C9H20/c1-8(2)11(7)12(9(3)4)10(5)6;2*1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12;1-6-8(4)9(5)7(2)3/h8-12H,1-7H3;2*3-10H,1-2H3;7-9H,6H2,1-5H3/t11-;2*3-,4-,5+,6-,7-,8-,9+,10-;8-,9+/m1001/s1(8,9,10,11);2*1(3,5)2(4)(6,8)3(7,9)(10);1(7)3(8,9)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_2_mols_inter_enhstereo_grps_1) +{ + const char *molblock = + "my_test_mol \n" + " -INDIGO-01232613442D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 36 34 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 5.83301 -3.275 0.0 0 CFG=1 \n" + "M V30 2 C 4.96699 -2.775 0.0 0 CFG=1 \n" + "M V30 3 C 4.10096 -3.275 0.0 0 CFG=2 \n" + "M V30 4 C 3.23493 -2.775 0.0 0 CFG=1 \n" + "M V30 5 C 2.36891 -3.275 0.0 0 CFG=2 \n" + "M V30 6 C 1.50289 -2.775 0.0 0 \n" + "M V30 7 Br 2.36891 -4.275 0.0 0 \n" + "M V30 8 Cl 3.23493 -1.775 0.0 0 \n" + "M V30 9 Cl 4.10096 -4.275 0.0 0 \n" + "M V30 10 Cl 4.96699 -1.775 0.0 0 \n" + "M V30 11 Cl 5.83301 -4.275 0.0 0 \n" + "M V30 12 C 6.69904 -2.775 0.0 0 CFG=1 \n" + "M V30 13 C 7.56506 -3.275 0.0 0 CFG=1 \n" + "M V30 14 C 8.43109 -2.77501 0.0 0 CFG=2 \n" + "M V30 15 C 9.29711 -3.275 0.0 0 \n" + "M V30 16 Cl 8.43109 -1.77501 0.0 0 \n" + "M V30 17 Cl 7.56506 -4.275 0.0 0 \n" + "M V30 18 Cl 6.69904 -1.775 0.0 0 \n" + "M V30 19 C 6.13302 -7.62502 0.0 0 CFG=2 \n" + "M V30 20 C 5.26698 -7.12498 0.0 0 CFG=1 \n" + "M V30 21 C 4.40101 -7.62502 0.0 0 CFG=2 \n" + "M V30 22 C 3.53496 -7.12498 0.0 0 CFG=1 \n" + "M V30 23 C 2.66891 -7.62502 0.0 0 CFG=2 \n" + "M V30 24 C 6.99899 -7.12498 0.0 0 CFG=2 \n" + "M V30 25 C 7.86504 -7.62502 0.0 0 CFG=2 \n" + "M V30 26 C 8.73109 -7.12498 0.0 0 CFG=2 \n" + "M V30 27 C 1.80295 -7.12498 0.0 0 \n" + "M V30 28 Br 2.66891 -8.62501 0.0 0 \n" + "M V30 29 Cl 3.53496 -6.12499 0.0 0 \n" + "M V30 30 Cl 4.40101 -8.62501 0.0 0 \n" + "M V30 31 Cl 5.26698 -6.12499 0.0 0 \n" + "M V30 32 Cl 6.13302 -8.62501 0.0 0 \n" + "M V30 33 C 9.59705 -7.62502 0.0 0 \n" + "M V30 34 Cl 8.73109 -6.12499 0.0 0 \n" + "M V30 35 Cl 7.86504 -8.62501 0.0 0 \n" + "M V30 36 Cl 6.99899 -6.12499 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 1 11 CFG=3 \n" + "M V30 3 1 1 12 \n" + "M V30 4 1 2 3 \n" + "M V30 5 1 2 10 CFG=1 \n" + "M V30 6 1 3 4 \n" + "M V30 7 1 3 9 CFG=1 \n" + "M V30 8 1 4 5 \n" + "M V30 9 1 4 8 CFG=1 \n" + "M V30 10 1 5 6 \n" + "M V30 11 1 5 7 CFG=1 \n" + "M V30 12 1 12 13 \n" + "M V30 13 1 12 18 CFG=3 \n" + "M V30 14 1 13 14 \n" + "M V30 15 1 13 17 CFG=1 \n" + "M V30 16 1 14 15 \n" + "M V30 17 1 14 16 CFG=1 \n" + "M V30 18 1 19 20 \n" + "M V30 19 1 20 21 \n" + "M V30 20 1 21 22 \n" + "M V30 21 1 22 23 \n" + "M V30 22 1 19 24 \n" + "M V30 23 1 24 25 \n" + "M V30 24 1 25 26 \n" + "M V30 25 1 23 27 \n" + "M V30 26 1 23 28 CFG=1 \n" + "M V30 27 1 22 29 CFG=1 \n" + "M V30 28 1 21 30 CFG=1 \n" + "M V30 29 1 20 31 CFG=1 \n" + "M V30 30 1 19 32 CFG=3 \n" + "M V30 31 1 26 33 \n" + "M V30 32 1 26 34 CFG=1 \n" + "M V30 33 1 25 35 CFG=3 \n" + "M V30 34 1 24 36 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(2 1 19) \n" + "M V30 MDLV30/STERAC1 ATOMS=(4 2 3 20 21) \n" + "M V30 MDLV30/STEABS ATOMS=(4 4 5 22 23) \n" + "M V30 MDLV30/STEREL1 ATOMS=(4 12 13 24 25) \n" + "M V30 MDLV30/STEREL2 ATOMS=(2 14 26) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/2C10H14BrCl7/c2*1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h2*3-10H,1-2H3/t2*3-,4-,5+,6-,7-,8-,9+,10-/m00/s2*1(3,5)2(4)(6,8)3(7,9)(10)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_2_mols_inter_enhstereo_grps_2) +{ + const char *molblock = + "test_mol \n" + " -INDIGO-02042609012D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 18 16 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 3.06699 -3.575 0.0 0 \n" + "M V30 2 C 3.93301 -3.075 0.0 0 \n" + "M V30 3 C 4.79904 -3.575 0.0 0 CFG=1 \n" + "M V30 4 C 5.66506 -3.075 0.0 0 CFG=2 \n" + "M V30 5 C 6.53109 -3.575 0.0 0 \n" + "M V30 6 C 7.39711 -3.075 0.0 0 \n" + "M V30 7 C 4.79904 -4.575 0.0 0 \n" + "M V30 8 C 5.66506 -2.075 0.0 0 \n" + "M V30 9 C 3.06699 -8.475 0.0 0 \n" + "M V30 10 C 3.93301 -7.975 0.0 0 CFG=2 \n" + "M V30 11 C 4.79904 -8.475 0.0 0 CFG=2 \n" + "M V30 12 C 5.66506 -7.975 0.0 0 \n" + "M V30 13 C 6.53109 -8.475 0.0 0 \n" + "M V30 14 C 3.93301 -6.975 0.0 0 \n" + "M V30 15 C 4.79904 -9.475 0.0 0 \n" + "M V30 16 C 7.39711 -7.975 0.0 0 \n" + "M V30 17 C 8.26314 -8.475 0.0 0 \n" + "M V30 18 C 9.12916 -7.975 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 2 3 \n" + "M V30 3 1 3 4 \n" + "M V30 4 1 4 5 \n" + "M V30 5 1 5 6 \n" + "M V30 6 1 3 7 CFG=1 \n" + "M V30 7 1 4 8 CFG=1 \n" + "M V30 8 1 9 10 \n" + "M V30 9 1 10 11 \n" + "M V30 10 1 11 12 \n" + "M V30 11 1 12 13 \n" + "M V30 12 1 10 14 CFG=1 \n" + "M V30 13 1 11 15 CFG=3 \n" + "M V30 14 1 13 16 \n" + "M V30 15 1 16 17 \n" + "M V30 16 1 17 18 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STEABS ATOMS=(2 3 11) \n" + "M V30 MDLV30/STERAC1 ATOMS=(2 4 10) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C10H22.C8H18/c1-5-6-7-8-10(4)9(2)3;1-5-7(3)8(4)6-2/h9-10H,5-8H2,1-4H3;7-8H,5-6H2,1-4H3/t10-;7-,8-/m00/s1(10)3(9);1(7)3(8)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_2_different_mols_inter_enhstereo_grps) +{ + const char *molblock = + "test_mols \n" + " -INDIGO-01272610042D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 37 35 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 5.43304 -3.47499 0.0 0 CFG=1 \n" + "M V30 2 C 4.56702 -2.97499 0.0 0 CFG=1 \n" + "M V30 3 C 3.70099 -3.47499 0.0 0 CFG=2 \n" + "M V30 4 C 2.83496 -2.97499 0.0 0 CFG=1 \n" + "M V30 5 C 1.96894 -3.47499 0.0 0 CFG=2 \n" + "M V30 6 C 1.10292 -2.97499 0.0 0 \n" + "M V30 7 Br 1.96894 -4.47499 0.0 0 \n" + "M V30 8 Cl 2.83496 -1.97499 0.0 0 \n" + "M V30 9 Cl 3.70099 -4.47499 0.0 0 \n" + "M V30 10 Cl 4.56702 -1.97499 0.0 0 \n" + "M V30 11 Cl 5.43304 -4.47499 0.0 0 \n" + "M V30 12 C 6.29907 -2.97499 0.0 0 CFG=1 \n" + "M V30 13 C 7.16509 -3.47499 0.0 0 CFG=1 \n" + "M V30 14 C 8.03112 -2.975 0.0 0 CFG=2 \n" + "M V30 15 C 8.89714 -3.47499 0.0 0 \n" + "M V30 16 Cl 8.03112 -1.975 0.0 0 \n" + "M V30 17 Cl 7.16509 -4.47499 0.0 0 \n" + "M V30 18 Cl 6.29907 -1.97499 0.0 0 \n" + "M V30 19 C 5.73305 -7.82502 0.0 0 CFG=2 \n" + "M V30 20 C 4.86701 -7.32498 0.0 0 CFG=1 \n" + "M V30 21 C 4.00104 -7.82502 0.0 0 CFG=2 \n" + "M V30 22 C 3.13499 -7.32498 0.0 0 CFG=1 \n" + "M V30 23 C 2.26894 -7.82502 0.0 0 CFG=2 \n" + "M V30 24 C 6.59902 -7.32498 0.0 0 CFG=2 \n" + "M V30 25 C 7.46507 -7.82502 0.0 0 CFG=2 \n" + "M V30 26 C 8.33112 -7.32498 0.0 0 CFG=2 \n" + "M V30 27 C 1.40298 -7.32498 0.0 0 \n" + "M V30 28 Br 2.26894 -8.82501 0.0 0 \n" + "M V30 29 Cl 3.13499 -6.32499 0.0 0 \n" + "M V30 30 Cl 4.00104 -8.82501 0.0 0 \n" + "M V30 31 Cl 4.86701 -6.32499 0.0 0 \n" + "M V30 32 Cl 5.73305 -8.82501 0.0 0 \n" + "M V30 33 C 9.19708 -7.82502 0.0 0 \n" + "M V30 34 Cl 8.33112 -6.32499 0.0 0 \n" + "M V30 35 Cl 7.46507 -8.82501 0.0 0 \n" + "M V30 36 Cl 6.59902 -6.32499 0.0 0 \n" + "M V30 37 C 9.19702 -8.82502 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 1 11 CFG=3 \n" + "M V30 3 1 1 12 \n" + "M V30 4 1 2 3 \n" + "M V30 5 1 2 10 CFG=1 \n" + "M V30 6 1 3 4 \n" + "M V30 7 1 3 9 CFG=1 \n" + "M V30 8 1 4 5 \n" + "M V30 9 1 4 8 CFG=1 \n" + "M V30 10 1 5 6 \n" + "M V30 11 1 5 7 CFG=1 \n" + "M V30 12 1 12 13 \n" + "M V30 13 1 12 18 CFG=3 \n" + "M V30 14 1 13 14 \n" + "M V30 15 1 13 17 CFG=1 \n" + "M V30 16 1 14 15 \n" + "M V30 17 1 14 16 CFG=1 \n" + "M V30 18 1 19 20 \n" + "M V30 19 1 20 21 \n" + "M V30 20 1 21 22 \n" + "M V30 21 1 22 23 \n" + "M V30 22 1 19 24 \n" + "M V30 23 1 24 25 \n" + "M V30 24 1 25 26 \n" + "M V30 25 1 23 27 \n" + "M V30 26 1 23 28 CFG=1 \n" + "M V30 27 1 22 29 CFG=1 \n" + "M V30 28 1 21 30 CFG=1 \n" + "M V30 29 1 20 31 CFG=1 \n" + "M V30 30 1 19 32 CFG=3 \n" + "M V30 31 1 26 33 \n" + "M V30 32 1 26 34 CFG=1 \n" + "M V30 33 1 25 35 CFG=3 \n" + "M V30 34 1 24 36 CFG=1 \n" + "M V30 35 1 33 37 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(2 1 19) \n" + "M V30 MDLV30/STERAC1 ATOMS=(4 2 3 20 21) \n" + "M V30 MDLV30/STEABS ATOMS=(4 4 5 22 23) \n" + "M V30 MDLV30/STEREL1 ATOMS=(4 12 13 24 25) \n" + "M V30 MDLV30/STEREL2 ATOMS=(2 14 26) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/C11H16BrCl7.C10H14BrCl7/c1-3-5(13)7(15)9(17)11(19)10(18)8(16)6(14)4(2)12;1-3(11)5(13)7(15)9(17)10(18)8(16)6(14)4(2)12/h4-11H,3H2,1-2H3;3-10H,1-2H3/t4-,5-,6+,7-,8-,9-,10+,11-;3-,4-,5+,6-,7-,8-,9+,10-/m00/s1(4,6)2(5)(7,9)3(8,10)(11);1(3,5)2(4)(6,8)3(7,9)(10)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_differing_AND_groups_of_same_molecule_1) +{ + const char *molblock1 = + "test mol \n" + " -INDIGO-02192610442D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 7 6 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 O 1.54199 -5.725 0.0 0 \n" + "M V30 2 C 2.40801 -5.225 0.0 0 \n" + "M V30 3 C 3.27404 -5.725 0.0 0 CFG=1 \n" + "M V30 4 C 4.14006 -5.225 0.0 0 CFG=2 \n" + "M V30 5 C 5.00609 -5.725 0.0 0 \n" + "M V30 6 Br 4.14006 -4.225 0.0 0 \n" + "M V30 7 Cl 3.27404 -6.725 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 2 3 \n" + "M V30 3 1 3 4 \n" + "M V30 4 1 4 5 \n" + "M V30 5 1 4 6 CFG=1 \n" + "M V30 6 1 3 7 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC1 ATOMS=(1 3) \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 4) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + const char *molblock2 = + "test mol \n" + " -INDIGO-02192610462D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 7 6 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 O 1.54199 -5.725 0.0 0 \n" + "M V30 2 C 2.40801 -5.225 0.0 0 \n" + "M V30 3 C 3.27404 -5.725 0.0 0 CFG=1 \n" + "M V30 4 C 4.14006 -5.225 0.0 0 CFG=2 \n" + "M V30 5 C 5.00609 -5.725 0.0 0 \n" + "M V30 6 Br 4.14006 -4.225 0.0 0 \n" + "M V30 7 Cl 3.27404 -6.725 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 2 3 \n" + "M V30 3 1 3 4 \n" + "M V30 4 1 4 5 \n" + "M V30 5 1 4 6 CFG=1 \n" + "M V30 6 1 3 7 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 3) \n" + "M V30 MDLV30/STERAC1 ATOMS=(1 4) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + const char expected_inchi[] = "InChI=1B/C4H8BrClO/c1-3(5)4(6)2-7/h3-4,7H,2H2,1H3/t3-,4-/m0/s3(3)(4)"; + + inchi_Output output1; + inchi_Output *poutput1 = &output1; + EXPECT_EQ(MakeINCHIFromMolfileText(molblock1, options, poutput1), 0); + EXPECT_STREQ(poutput1->szInChI, expected_inchi); + + inchi_Output output2; + inchi_Output *poutput2 = &output2; + EXPECT_EQ(MakeINCHIFromMolfileText(molblock2, options, poutput2), 0); + EXPECT_STREQ(poutput2->szInChI, expected_inchi); + + poutput1->szLog = nullptr; + poutput1->szMessage = nullptr; + FreeINCHI(poutput1); + + poutput2->szLog = nullptr; + poutput2->szMessage = nullptr; + FreeINCHI(poutput2); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_differing_AND_groups_of_same_molecule_2) +{ + const char *molblock = + "test_mol \n" + " -INDIGO-02192611042D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0 0 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 14 12 0 0 0 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 O 4.21699 -6.575 0.0 0 \n" + "M V30 2 C 5.08301 -6.075 0.0 0 \n" + "M V30 3 C 5.94904 -6.575 0.0 0 CFG=1 \n" + "M V30 4 C 6.81506 -6.075 0.0 0 CFG=2 \n" + "M V30 5 C 7.68109 -6.575 0.0 0 \n" + "M V30 6 Br 6.81506 -5.075 0.0 0 \n" + "M V30 7 Cl 5.94904 -7.575 0.0 0 \n" + "M V30 8 O 11.2179 -6.4 0.0 0 \n" + "M V30 9 C 12.084 -5.9 0.0 0 \n" + "M V30 10 C 12.95 -6.4 0.0 0 CFG=1 \n" + "M V30 11 C 13.816 -5.9 0.0 0 CFG=2 \n" + "M V30 12 C 14.6821 -6.4 0.0 0 \n" + "M V30 13 Br 13.816 -4.9 0.0 0 \n" + "M V30 14 Cl 12.95 -7.4 0.0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 2 3 \n" + "M V30 3 1 3 4 \n" + "M V30 4 1 4 5 \n" + "M V30 5 1 4 6 CFG=1 \n" + "M V30 6 1 3 7 CFG=1 \n" + "M V30 7 1 8 9 \n" + "M V30 8 1 9 10 \n" + "M V30 9 1 10 11 \n" + "M V30 10 1 11 12 \n" + "M V30 11 1 11 13 CFG=1 \n" + "M V30 12 1 10 14 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 3) \n" + "M V30 MDLV30/STERAC1 ATOMS=(1 4) \n" + "M V30 MDLV30/STERAC3 ATOMS=(1 10) \n" + "M V30 MDLV30/STERAC4 ATOMS=(1 11) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + char options[] = "-EnhancedStereochemistry"; + inchi_Output output; + inchi_Output *poutput = &output; + const char expected_inchi[] = "InChI=1B/2C4H8BrClO/c2*1-3(5)4(6)2-7/h2*3-4,7H,2H2,1H3/t2*3-,4-/m00/s2*3(3)(4)"; + + EXPECT_EQ(MakeINCHIFromMolfileText(molblock, options, poutput), 0); + EXPECT_STREQ(poutput->szInChI, expected_inchi); + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + + FreeINCHI(poutput); +} + +TEST(test_enhancedStereo, test_EnhancedStereochemistry_test_file_1) +{ + + const char* inchi_filename = "../../../../../INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_1.sdf"; + // const char* inchi_filename = "/workspaces/InChI/INCHI-1-TEST/tests/test_unit/fixtures/enh_stereo_test_file_1.sdf"; + + std::ifstream file_inchi(inchi_filename, std::ios::binary); + ASSERT_TRUE(file_inchi.is_open()); + + // Read the whole file into a string + std::stringstream buffer; + buffer << file_inchi.rdbuf(); + std::string file_content = buffer.str(); + file_inchi.close(); + + // Split on "$$$$" + std::vector molblocks; + size_t pos = 0; + size_t prev = 0; + const std::string delimiter = "$$$$"; + while ((pos = file_content.find(delimiter, prev)) != std::string::npos) { + std::string mol = file_content.substr(prev, pos - prev); + // Optionally trim whitespace + size_t first_non_ws = mol.find_first_not_of(" \t\r\n"); + if (first_non_ws != std::string::npos) { + mol = mol.substr(first_non_ws); + molblocks.push_back(mol); + } + prev = pos + delimiter.length(); + } + // Add the last block if any + std::string mol = file_content.substr(prev); + size_t first_non_ws = mol.find_first_not_of(" \t\r\n"); + if (first_non_ws != std::string::npos) { + mol = mol.substr(first_non_ws); + molblocks.push_back(mol); + } + + std::vector list_expected_inchis = { + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5-/m1/s1", + "InChI=1B/C4H10O/c1-3-4(2)5/h4-5H,3H2,1-2H3/t4-/m0/s2(4)", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5-/m0/s2(4,5)", + "InChI=1B/C4H10O/c1-3-4(2)5/h4-5H,3H2,1-2H3/t4-/m1/s1", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5-/m0/s2(4)(5)", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5-/m0/s3(4,5)", + "InChI=1B/C4H10O/c1-3-4(2)5/h4-5H,3H2,1-2H3/t4-/m0/s3(4)", + "InChI=1B/C4H10O/c1-3-4(2)5/h4-5H,3H2,1-2H3", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5-/m0/s3(4)(5)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5+,6-/m0/s1(4,5)2(6)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5+,6?/m0/s1", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5-,6+/m0/s1(4)2(5,6)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5?,6?/m0/s1", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5-,6-/m0/s1(4)2(5,6)", + "InChI=1B/C7H17NO/c1-4-5(2)7(8)6(3)9/h5-7,9H,4,8H2,1-3H3/t5-,6-,7+/m1/s1(6)2(5,7)", + "InChI=1B/C7H17NO/c1-4-5(2)7(8)6(3)9/h5-7,9H,4,8H2,1-3H3/t5?,6-,7?/m1/s1", + "InChI=1B/C7H17NO/c1-4-5(2)7(8)6(3)9/h5-7,9H,4,8H2,1-3H3/t5-,6-,7-/m1/s1(6)2(5,7)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5-,6-/m0/s1(4)2(5)(6)", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5-/m1/s1(4)3(5)", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5?/m0/s3(4)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5-,6-/m0/s1(4)3(5,6)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5-,6+/m0/s1(4)3(5,6)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5?,6?/m0/s3(4)", + "InChI=1B/C7H17NO/c1-4-5(2)7(8)6(3)9/h5-7,9H,4,8H2,1-3H3/t5?,6-,7?/m0/s3(6)", + "InChI=1B/C7H17NO/c1-4-5(2)7(8)6(3)9/h5-7,9H,4,8H2,1-3H3/t5-,6-,7-/m1/s1(6)3(5,7)", + "InChI=1B/C7H17NO/c1-4-5(2)7(8)6(3)9/h5-7,9H,4,8H2,1-3H3/t5-,6-,7+/m1/s1(6)3(5,7)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5-,6-/m0/s1(4)3(5)(6)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2/t4-,5-,6-/m0/s1(4)2(5)3(6)", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5?/m1/s1", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5?/m0/s3(4)", + "InChI=1B/C5H13NO/c1-3-5(6)4(2)7/h4-5,7H,3,6H2,1-2H3/t4-,5?/m0/s2(4)", + "InChI=1B/C6H12O3/c7-4-1-2-5(8)6(9)3-4/h4-9H,1-3H2", + }; + + int nof_inchis = 33; + + EXPECT_EQ(nof_inchis, molblocks.size()); + EXPECT_EQ(nof_inchis, list_expected_inchis.size()); + + char options[] = "-EnhancedStereochemistry"; + + for (int i = 0; i < nof_inchis; ++i) { + + inchi_Output output; + inchi_Output* poutput = &output; + + poutput->szLog = nullptr; + poutput->szMessage = nullptr; + poutput->szInChI = nullptr; + + int ret = MakeINCHIFromMolfileText(molblocks[i].c_str(), options, poutput); + + EXPECT_LT(ret, 2); + + EXPECT_STREQ(poutput->szInChI, list_expected_inchis[i].c_str()); + + if (poutput->szLog) { + inchi_free(poutput->szLog); + poutput->szLog = nullptr; + } + if (poutput->szMessage) { + inchi_free(poutput->szMessage); + poutput->szMessage = nullptr; + } + if (poutput->szInChI) { + inchi_free(poutput->szInChI); + poutput->szInChI = nullptr; + } + } +} diff --git a/INCHI-1-TEST/tests/test_unit/test_ichimain.cpp b/INCHI-1-TEST/tests/test_unit/test_ichimain.cpp index 7b7458dd..9b1d09b0 100644 --- a/INCHI-1-TEST/tests/test_unit/test_ichimain.cpp +++ b/INCHI-1-TEST/tests/test_unit/test_ichimain.cpp @@ -191,7 +191,6 @@ TEST(test_ichimain, test_CalcAndPrintINCHIAndINCHIKEY) { PINChI_Aux2* pINChI_Aux[INCHI_NUM] = {}; ORIG_ATOM_DATA prep_inp_data = {}; INCHI_IOS_STRING *strbuf = new INCHI_IOS_STRING; - memset(strbuf, 0, sizeof(*strbuf)); inchi_strbuf_init(strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); unsigned long pulTotalProcessingTime = 0; @@ -292,7 +291,8 @@ TEST(test_ichimain, test_ProcessMultipleInputFiles_2mol_files) char tmpl[] = "../../../../../INCHI-1-TEST/tests/test_unit/fixtures/inchi_mol_test_XXXXXX"; char *tmpd = mkdtemp(tmpl); - ASSERT_NE(tmpd, nullptr); + + EXPECT_NE(tmpd, nullptr); std::vector dist_paths; for (auto cur_filename : input_mols) { diff --git a/INCHI-1-TEST/tests/test_unit/test_ichimake.cpp b/INCHI-1-TEST/tests/test_unit/test_ichimake.cpp new file mode 100644 index 00000000..94a2c69a --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/test_ichimake.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichimake.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichi_io.h" +} + +TEST(test_ichimake, test_GetSp3RelRacAbs_none) +{ + + INChI inchi = {0}; + INChI_Stereo stereo = {0}; + + stereo.nNumberOfStereoCenters = 0; + + // pINChI->bDeleted + // Stereo->nCompInv2Abs + // 0: No inversion (structure unchanged by inversion) + // Positive integer (>0): Indicates inversion changes the structure (normal/absolute stereo) + // Negative integer (<0): Indicates inversion changes the structure (inverted/absolute stereo) + + //int GetSp3RelRacAbs(const INChI* pINChI, INChI_Stereo* Stereo); + + int result = GetSp3RelRacAbs(&inchi, &stereo); + + EXPECT_EQ(result, SP3_NONE); + +} + +TEST(test_ichimake, test_GetSp3RelRacAbs_sp3) +{ + INChI inchi = {0}; + INChI_Stereo stereo = {0}; + + stereo.nNumberOfStereoCenters = 1; + stereo.nCompInv2Abs = 0; + + int result = GetSp3RelRacAbs(&inchi, &stereo); + + EXPECT_EQ(result, SP3_ONLY); +} + +TEST(test_ichimake, test_GetSp3RelRacAbs_rel) +{ + INChI inchi = {0}; + INChI_Stereo stereo = {0}; + + inchi.nFlags = INCHI_FLAG_REL_STEREO; + stereo.nNumberOfStereoCenters = 1; + stereo.nCompInv2Abs = 1; + + int result = GetSp3RelRacAbs(&inchi, &stereo); + + EXPECT_EQ(result, SP3_REL); +} + +TEST(test_ichimake, test_GetSp3RelRacAbs_rac) +{ + INChI inchi = {0}; + INChI_Stereo stereo = {0}; + + inchi.nFlags = INCHI_FLAG_RAC_STEREO; + stereo.nNumberOfStereoCenters = 1; + stereo.nCompInv2Abs = 1; + + int result = GetSp3RelRacAbs(&inchi, &stereo); + + EXPECT_EQ(result, SP3_RAC); +} + +TEST(test_ichimake, test_GetSp3RelRacAbs_abs) +{ + INChI inchi = {0}; + INChI_Stereo stereo = {0}; + + inchi.nFlags = 0x0111; + stereo.nNumberOfStereoCenters = 1; + stereo.nCompInv2Abs = 1; + + int result = GetSp3RelRacAbs(&inchi, &stereo); + + EXPECT_EQ(result, SP3_ABS); +} diff --git a/INCHI-1-TEST/tests/test_unit/test_ichiprt1.cpp b/INCHI-1-TEST/tests/test_unit/test_ichiprt1.cpp new file mode 100644 index 00000000..67b5aefc --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/test_ichiprt1.cpp @@ -0,0 +1,594 @@ +#include +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichi_io.h" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/strutil.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichimake.h" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichicano.h" +} + + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer) +{ + + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + char lf[] = "\n"; + char tab[] = "\t"; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + // int OutputINCHI_StereoLayer( CANON_GLOBALS *pCG, + // INCHI_IOSTREAM *out_file, + // INCHI_IOS_STRING *strbuf, + // INCHI_OUT_CTL *io, + // char *pLF, + // char *pTAB ) + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, lf, tab); + + EXPECT_EQ(ret, 0); + + // Clean up + inchi_strbuf_close(&strbuf); + +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_b_1) +{ + int num_at = 2; + int found_num_bonds = 0; + int found_num_isotopic = 0; + + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + INCHI_SORT inchi_sort = {0}; + inp_ATOM *atoms = CreateInpAtom(num_at); + + atoms[0].valence = 1; + // atoms[0].el_number = (U_CHAR)get_periodic_table_number("C"); + // atoms[0].orig_at_number = 4; + // atoms[0].neighbor[0] = 3; + // atoms[0].bond_type[0] = 2; + + atoms[1].valence = 1; + // atoms[1].el_number = (U_CHAR)get_periodic_table_number("C"); + // atoms[1].orig_at_number = 3; + // atoms[1].neighbor[0] = 4; + // atoms[1].bond_type[0] = 2; + + INChI *inchi = Alloc_INChI(atoms, num_at, &found_num_bonds, &found_num_isotopic, 0); + + inchi->nNumberOfAtoms = num_at; + + int bond_atom1[1] = {4}; + int bond_atom2[1] = {3}; + S_CHAR b_parity[1] = {1}; // 1 = -, 2 = + + + for (int i = 0; i < found_num_bonds; i++) { + inchi->Stereo->nBondAtom1[i] = bond_atom1[i]; + inchi->Stereo->nBondAtom2[i] = bond_atom2[i]; + inchi->Stereo->b_parity[i] = b_parity[i]; + } + + // inchi->Stereo->nCompInv2Abs = 1; + inchi->Stereo->nNumberOfStereoBonds = 1; + // inchi->Stereo->nNumberOfStereoCenters = 0; + + inchi_sort.pINChI[0] = inchi; + + io.pINChISort = &inchi_sort; + io.num_components = 1; + + // io.bRelativeStereo[0] = 0; + // io.bRacemicStereo[0] = 0; + + io.sDifSegs[0][DIFS_b_SBONDS] = DIFV_OUTPUT_FILL_T; // b + // io.sDifSegs[0][DIFS_t_SATOMS] = DIFV_OUTPUT_FILL_T; // t + // io.sDifSegs[0][DIFS_m_SP3INV] = DIFV_OUTPUT_FILL_T; // m + // io.sDifSegs[0][DIFS_s_STYPE] = DIFV_OUTPUT_FILL_T; // s + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 2; + io.nTag = 2; + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + io.bOutType = OUT_TN; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(out_file.s.pStr), "/b4-3-"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); + + FreeInpAtom(&atoms); + Free_INChI(&inchi); +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_m0) +{ + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + + io.sDifSegs[0][DIFS_m_SP3INV] = DIFV_OUTPUT_FILL_T; + + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 1; + io.bRelativeStereo[0] = 0; + io.bRacemicStereo[0] = 0; + io.bAlways = 0; + io.nTag = 2; // plain text + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + io.bOverflow = 0; + io.bOutType = OUT_TN; + io.num_components = 1; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int num_at = 2; + + int found_num_bonds = 0; + int found_num_isotopic = 0; + inp_ATOM *at = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(at, num_at, &found_num_bonds, &found_num_isotopic, 0); + inchi->Stereo->nCompInv2Abs = 1; + inchi->nNumberOfAtoms = num_at; + + INCHI_SORT *inchi_sort = (INCHI_SORT*)calloc(1, sizeof(INCHI_SORT)); + inchi_sort->pINChI[TAUT_YES] = inchi; + + io.pINChISort = inchi_sort; + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(strbuf.pStr), "/m0"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); + + Free_INChI( &inchi ); + + FreeInpAtom(&at); + + free(inchi_sort); +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_m1) +{ + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + + io.sDifSegs[0][DIFS_m_SP3INV] = DIFV_OUTPUT_FILL_T; + + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 1; + io.bRelativeStereo[0] = 0; + io.bRacemicStereo[0] = 0; + io.bAlways = 0; + io.nTag = 2; // plain text + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + io.bOverflow = 0; + io.bOutType = OUT_TN; + io.num_components = 1; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int num_at = 2; + + int found_num_bonds = 0; + int found_num_isotopic = 0; + inp_ATOM *at = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(at, num_at, &found_num_bonds, &found_num_isotopic, 0); + inchi->Stereo->nCompInv2Abs = -1; + inchi->nNumberOfAtoms = num_at; + + INCHI_SORT *inchi_sort = (INCHI_SORT*)calloc(1, sizeof(INCHI_SORT)); + inchi_sort->pINChI[TAUT_YES] = inchi; + + io.pINChISort = inchi_sort; + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(strbuf.pStr), "/m1"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); + + Free_INChI( &inchi ); + + FreeInpAtom(&at); + + free(inchi_sort); +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_s1) +{ + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + + io.sDifSegs[0][DIFS_s_STYPE] = DIFV_OUTPUT_FILL_T; + + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 1; + io.bRelativeStereo[0] = 0; + io.bRacemicStereo[0] = 0; + io.bAlways = 0; + io.nTag = 2; // plain text + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(strbuf.pStr), "/s1"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_s2) +{ + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + + io.sDifSegs[0][DIFS_s_STYPE] = DIFV_OUTPUT_FILL_T; + + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 1; + io.bRelativeStereo[0] = 1; + io.bRacemicStereo[0] = 0; + io.bAlways = 0; + io.nTag = 2; // plain text + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(strbuf.pStr), "/s2"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_s3) +{ + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + + + io.sDifSegs[0][DIFS_s_STYPE] = DIFV_OUTPUT_FILL_T; + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 1; + io.bRelativeStereo[0] = 0; + io.bRacemicStereo[0] = 1; + io.bAlways = 0; + io.nTag = 2; // plain text + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(strbuf.pStr), "/s3"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); + +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_layers_t) +{ + + int num_at = 8; + int found_num_bonds = 0; + int found_num_isotopic = 0; + + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + INCHI_SORT inchi_sort = {0}; + AT_NUMB numbers[8] = {3,4,5,6,7,8,9,10}; + S_CHAR parities[8] = {1,1,2,2,1,2,2,1};// -,-,+,+,-,+,+,- + inp_ATOM *at = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(at, num_at, &found_num_bonds, &found_num_isotopic, 0); + + inchi->nNumberOfAtoms = num_at; + inchi->Stereo->nCompInv2Abs = 1; + inchi->Stereo->nNumberOfStereoBonds = 0; + inchi->Stereo->nNumberOfStereoCenters = num_at; + + for (int i = 0; i < num_at; i++) { + inchi->Stereo->nNumber[i] = numbers[i]; + inchi->Stereo->t_parity[i] = parities[i]; + } + + inchi_sort.pINChI[0] = inchi; + + io.pINChISort = &inchi_sort; + io.num_components = 1; + io.bRelativeStereo[0] = 0; + io.bRacemicStereo[0] = 1; + // io.sDifSegs[0][DIFS_b_SBONDS] = DIFV_OUTPUT_FILL_T; // b + io.sDifSegs[0][DIFS_t_SATOMS] = DIFV_OUTPUT_FILL_T; // t + // io.sDifSegs[0][DIFS_m_SP3INV] = DIFV_OUTPUT_FILL_T; // m + // io.sDifSegs[0][DIFS_s_STYPE] = DIFV_OUTPUT_FILL_T; // s + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 2; /* 0 => no plain tags, 1=> plain text tags, 2=>plaintext tags without consecutive // */ + io.nTag = 2; + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + io.bOutType = OUT_TN; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(out_file.s.pStr), "/t3-,4-,5+,6+,7-,8+,9+,10-"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); + + FreeInpAtom(&at); + Free_INChI(&inchi); +} + +TEST(test_ichiprt1, test_OutputINCHI_StereoLayer_layers_t_m_s) +{ + + int num_at = 8; + int found_num_bonds = 0; + int found_num_isotopic = 0; + + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + INCHI_SORT inchi_sort = {0}; + AT_NUMB numbers[8] = {3,4,5,6,7,8,9,10}; + S_CHAR parities[8] = {1,1,2,2,1,2,2,1};// -,-,+,+,-,+,+,- + inp_ATOM *at = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(at, num_at, &found_num_bonds, &found_num_isotopic, 0); + + inchi->nNumberOfAtoms = num_at; + inchi->Stereo->nCompInv2Abs = 1; + inchi->Stereo->nNumberOfStereoBonds = 0; + inchi->Stereo->nNumberOfStereoCenters = num_at; + + for (int i = 0; i < num_at; i++) { + inchi->Stereo->nNumber[i] = numbers[i]; + inchi->Stereo->t_parity[i] = parities[i]; + } + + inchi_sort.pINChI[0] = inchi; + + io.pINChISort = &inchi_sort; + io.num_components = 1; + io.bRelativeStereo[0] = 0; + io.bRacemicStereo[0] = 1; + io.sDifSegs[0][DIFS_b_SBONDS] = DIFV_OUTPUT_FILL_T; // b + io.sDifSegs[0][DIFS_t_SATOMS] = DIFV_OUTPUT_FILL_T; // t + io.sDifSegs[0][DIFS_m_SP3INV] = DIFV_OUTPUT_FILL_T; // m + io.sDifSegs[0][DIFS_s_STYPE] = DIFV_OUTPUT_FILL_T; // s + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 2; /* 0 => no plain tags, 1=> plain text tags, 2=>plaintext tags without consecutive // */ + io.nTag = 2; + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + io.bOutType = OUT_TN; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int ret = OutputINCHI_StereoLayer(&cg, &out_file, &strbuf, &io, (char*)"", (char*)""); + + EXPECT_EQ(std::string(out_file.s.pStr), "/t3-,4-,5+,6+,7-,8+,9+,10-/m0/s3"); + EXPECT_EQ(ret, 0); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); + + FreeInpAtom(&at); + Free_INChI(&inchi); +} + +TEST(test_ichiprt1, test_set_line_separators) +{ + + // void set_line_separators( int bINChIOutputOptions, char **pLF, char **pTAB ) + + char *lf = nullptr; + char *tab = nullptr; + + // Plain text comments option + set_line_separators(INCHI_OUT_PLAIN_TEXT_COMMENTS, &lf, &tab); + EXPECT_STREQ(lf, "\n"); + EXPECT_STREQ(tab, "\n"); + + // Tabbed output option + set_line_separators(INCHI_OUT_PLAIN_TEXT | INCHI_OUT_TABBED_OUTPUT, &lf, &tab); + EXPECT_STREQ(lf, "\0"); + EXPECT_STREQ(tab, "\t"); + + // Plain text only + set_line_separators(INCHI_OUT_PLAIN_TEXT, &lf, &tab); + EXPECT_STREQ(lf, "\0"); + EXPECT_STREQ(tab, "\n"); + + // No options + set_line_separators(0, &lf, &tab); + EXPECT_STREQ(lf, "\0"); + EXPECT_STREQ(tab, "\n"); + + +} + +TEST(test_ichiprt1, test_szGetTag_basic) +{ + + // nTag = 1: XML label (szXmlLabel) + // nTag = 2: Plain text label (szPlainLabel) + // nTag = 3: Plain label with comments (sometimes) + + // bTag: A bitmask indicating which tag (or tags) to look up in the INCHI_TAG array. + + char szTag[64] = {0}; + int bAlways = -1; + + EXPECT_STREQ(szGetTag(IdentLbl, 0, 0, szTag, &bAlways, 0), "???"); //fixed-H + EXPECT_STREQ(szTag, "???"); + +} + +TEST(test_ichiprt1, test_szGetTag_returns_unknown_for_invalid_index) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 0, bTag = 0, should return "???" + EXPECT_STREQ(szGetTag(IdentLbl, 0, 0, szTag, &bAlways, 0), "???"); + EXPECT_STREQ(szTag, "???"); +} + +TEST(test_ichiprt1, test_szGetTag_stereo_1) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_STER (stereo) + EXPECT_STREQ(szGetTag(IdentLbl, 2, IL_STER, szTag, &bAlways, 0), "/"); + EXPECT_STREQ(szTag, "/"); +} + +TEST(test_ichiprt1, test_szGetTag_stereo_2) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_STER (stereo) + EXPECT_STREQ(szGetTag(IdentLbl, 1, IL_STER, szTag, &bAlways, 0), "stereo"); + EXPECT_STREQ(szTag, "stereo"); +} + +TEST(test_ichiprt1, test_szGetTag_stereo_3) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_STER (stereo) + EXPECT_STREQ(szGetTag(IdentLbl, 2, IL_SP3S, szTag, &bAlways, 0), "/t"); + EXPECT_STREQ(szTag, "/t"); +} + +TEST(test_ichiprt1, test_szGetTag_stereo_4) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_STER (stereo) + EXPECT_STREQ(szGetTag(IdentLbl, 2, IL_INVS, szTag, &bAlways, 0), "/m"); + EXPECT_STREQ(szTag, "/m"); +} + +TEST(test_ichiprt1, test_szGetTag_stereo_5) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_STER (stereo) + EXPECT_STREQ(szGetTag(IdentLbl, 2, IL_TYPS, szTag, &bAlways, 0), "/s"); + EXPECT_STREQ(szTag, "/s"); +} + +TEST(test_ichiprt1, test_szGetTag_stereo_6) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_STER (stereo) + EXPECT_STREQ(szGetTag(IdentLbl, 1, IL_TYPS, szTag, &bAlways, 0), "type"); + EXPECT_STREQ(szTag, "type"); +} + +TEST(test_ichiprt1, test_szGetTag_hfixed) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_STER (stereo) + EXPECT_STREQ(szGetTag(IdentLbl, 1, IL_FIXH, szTag, &bAlways, 0), "fixed-H"); + EXPECT_STREQ(szTag, "fixed-H"); +} + +TEST(test_ichiprt1, test_szGetTag_returns_xml_label) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 1 (XML), bTag = IL_CONN (connections) + EXPECT_STREQ(szGetTag(IdentLbl, 1, IL_CONN, szTag, &bAlways, 0), "connections"); + EXPECT_STREQ(szTag, "connections"); +} + +TEST(test_ichiprt1, test_szGetTag_sets_bAlways) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_FML_ (formula), which has bAlwaysOutput = 1 + szGetTag(IdentLbl, 2, IL_FML_, szTag, &bAlways, 0); + EXPECT_EQ(bAlways, -1); + EXPECT_STREQ(szTag, "/"); +} + +TEST(test_ichiprt1, test_szGetTag_charge) +{ + char szTag[64] = {0}; + int bAlways = -1; + // nTag = 2 (plain text), bTag = IL_CHRG (charge) + EXPECT_STREQ(szGetTag(IdentLbl, 2, IL_CHRG, szTag, &bAlways, 0), "/q"); + EXPECT_STREQ(szTag, "/q"); +} diff --git a/INCHI-1-TEST/tests/test_unit/test_ichiprt1_enhancedStereo.cpp b/INCHI-1-TEST/tests/test_unit/test_ichiprt1_enhancedStereo.cpp new file mode 100644 index 00000000..7c5f7bef --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/test_ichiprt1_enhancedStereo.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichi_io.h" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichiprt1.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/strutil.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichimake.h" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichicano.h" +} + + +TEST(test_ichiprt1_enhancedStereo, test_OutputINCHI_StereoLayer_enhanced_stereo_1) +{ + + CANON_GLOBALS cg = {0}; + INCHI_IOSTREAM out_file = {0}; + INCHI_IOS_STRING strbuf = {0}; + INCHI_OUT_CTL io = {0}; + ORIG_ATOM_DATA *oad; + + oad = (ORIG_ATOM_DATA *)inchi_calloc(1, sizeof(ORIG_ATOM_DATA)); + oad->v3000 = (OAD_V3000 *)inchi_calloc(1, sizeof(OAD_V3000)); + + oad->v3000->n_collections = 5; + oad->v3000->n_steabs = 1; + + oad->v3000->lists_steabs = (int **)inchi_calloc(oad->v3000->n_steabs, sizeof(int*)); + oad->v3000->lists_steabs[0] = (int *)inchi_calloc(2+2, sizeof(int)); + + // STEABS ATOMS=(2 4 5) + oad->v3000->lists_steabs[0][0] = 1; // - not used + oad->v3000->lists_steabs[0][1] = 2; // number of members in collection + oad->v3000->lists_steabs[0][2] = 4; // member atom numbers + oad->v3000->lists_steabs[0][3] = 5; // member atom numbers + + // STERAC2 ATOMS=(1 1) + oad->v3000->n_sterac = 2; + + oad->v3000->lists_sterac = (int **)inchi_calloc(oad->v3000->n_sterac, sizeof(int*)); + oad->v3000->lists_sterac[0] = (int *)inchi_calloc(2 + 1, sizeof(int)); + oad->v3000->lists_sterac[1] = (int *)inchi_calloc(2 + 2, sizeof(int)); + + oad->v3000->lists_sterac[0][0] = 2; // n from "STERACn" tag + oad->v3000->lists_sterac[0][1] = 1; // number of members in collection + oad->v3000->lists_sterac[0][2] = 1; // member atom numbers + + // STERAC1 ATOMS=(2 2 3) + oad->v3000->lists_sterac[1][0] = 1; // STERAC1 ATOMS=(2 2 3) + oad->v3000->lists_sterac[1][1] = 2; // number of members in collection + oad->v3000->lists_sterac[1][2] = 2; // member atom numbers + oad->v3000->lists_sterac[1][3] = 3; // member atom numbers + + oad->v3000->n_sterel = 2; + oad->v3000->lists_sterel = (int **)inchi_calloc(oad->v3000->n_sterel, sizeof(int*)); + oad->v3000->lists_sterel[0] = (int *)inchi_calloc(2 + 2, sizeof(int)); + oad->v3000->lists_sterel[1] = (int *)inchi_calloc(2 + 1, sizeof(int)); + + // STEREL1 ATOMS=(2 12 13) + oad->v3000->lists_sterel[0][0] = 1; // n from "STERELn" tag + oad->v3000->lists_sterel[0][1] = 2; // number of members in collection + oad->v3000->lists_sterel[0][2] = 12; // member atom numbers + oad->v3000->lists_sterel[0][3] = 13; // member atom numbers + + // STEREL2 ATOMS=(1 14) + oad->v3000->lists_sterel[1][0] = 2; // n from "STERELn" tag + oad->v3000->lists_sterel[1][1] = 1; // number of members in collection + oad->v3000->lists_sterel[1][2] = 14; // member atom numbers + + INCHI_SORT *inchi_sort = (INCHI_SORT*)inchi_calloc(1, sizeof(INCHI_SORT)); + + int num_at = 8; + int num_iso_at = 1; + int alloc_mode = 0; + int bOrigatomflag = 0; + int found_num_bonds = 0; + int found_num_isotopic = 0; + + inp_ATOM *atoms = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(atoms, num_at, &found_num_bonds, &found_num_isotopic, 0); + inchi->nNumberOfAtoms = num_at; + + INChI_Aux *pAux = Alloc_INChI_Aux(num_at, num_iso_at, alloc_mode, bOrigatomflag); + + pAux->nNumberOfAtoms = num_at; + // pAux->nOrigAtNosInCanonOrd = (AT_NUMB*)inchi_calloc(num_at, sizeof(AT_NUMB)); + + // canonical atom i+1 maps to original atom i+1 + pAux->nOrigAtNosInCanonOrd[0] = 4; + pAux->nOrigAtNosInCanonOrd[1] = 5; + pAux->nOrigAtNosInCanonOrd[2] = 1; + pAux->nOrigAtNosInCanonOrd[3] = 2; + pAux->nOrigAtNosInCanonOrd[4] = 3; + pAux->nOrigAtNosInCanonOrd[5] = 12; + pAux->nOrigAtNosInCanonOrd[6] = 13; + pAux->nOrigAtNosInCanonOrd[7] = 14; + + inchi_sort->pINChI[0] = inchi; + inchi_sort->pINChI_Aux[0] = pAux; + io.pINChISort = inchi_sort; + + io.bOutType = OUT_TN; + io.num_components = 1; + io.sDifSegs[0][DIFS_s_STYPE] = DIFV_OUTPUT_FILL_T; + io.nCurINChISegment = 0; + io.iCurTautMode = 0; + io.bPlainTextTags = 1; + io.bRelativeStereo[0] = 0; + io.bRacemicStereo[0] = 0; + io.bAlways = 0; + io.nTag = 2; // plain text + io.bTag1 = IL_STER; + io.bTag2 = IL_STER | IL_TYPS; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_ios_init(&out_file, INCHI_IOS_TYPE_STRING, nullptr); + + int ret = OutputINCHI_StereoLayer_EnhancedStereo(&cg, &out_file, &strbuf, &io, oad, (char*)"", (char*)""); + + // EXPECT_EQ(std::string(strbuf.pStr), "/s1(4,5)2(12,13;14)3(1;2,3)"); + EXPECT_EQ(std::string(strbuf.pStr), "/s1(1,2)2(6,7)(8)3(3)(4,5)"); + EXPECT_EQ(ret, 0); + + for (int i = 0; i < oad->v3000->n_steabs; i++) { + inchi_free(oad->v3000->lists_steabs[i]); + } + inchi_free(oad->v3000->lists_steabs); + + for (int i = 0; i < oad->v3000->n_sterel; i++) { + inchi_free(oad->v3000->lists_sterel[i]); + } + inchi_free(oad->v3000->lists_sterel); + + for (int i = 0; i < oad->v3000->n_sterac; i++) { + inchi_free(oad->v3000->lists_sterac[i]); + } + inchi_free(oad->v3000->lists_sterac); + + inchi_free(oad->v3000); + inchi_free(oad); + + inchi_free(inchi_sort); + + FreeInpAtom(&atoms); + Free_INChI_Aux(&pAux); + Free_INChI(&inchi); + + inchi_strbuf_close(&strbuf); + inchi_ios_close(&out_file); +} + diff --git a/INCHI-1-TEST/tests/test_unit/test_ichiprt2.cpp b/INCHI-1-TEST/tests/test_unit/test_ichiprt2.cpp new file mode 100644 index 00000000..fdb7f5ab --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/test_ichiprt2.cpp @@ -0,0 +1,378 @@ +#include +#include + +extern "C" +{ +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichiprt2.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichi_io.h" +} + +TEST(test_ichiprt2, MakeStereoString_outputs_expected_sp3_string) +{ + AT_NUMB at1[8] = {3,4,5,6,7,8,9,10}; + S_CHAR parity[8] = {1,1,2,2,1,2,2,1}; + + INCHI_IOS_STRING strbuf = {0}; + + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int ret = MakeStereoString(at1, nullptr, parity, 0, 8, &strbuf, 0, &bOverflow); + + EXPECT_EQ(strbuf.nUsedLength, strlen(strbuf.pStr)); + EXPECT_NE(std::string(strbuf.pStr).find("3-,4-,5+,6+,7-,8+,9+,10-"), std::string::npos); + EXPECT_EQ(std::string(strbuf.pStr), "3-,4-,5+,6+,7-,8+,9+,10-"); + EXPECT_EQ(strbuf.pStr[0], '3'); + EXPECT_EQ(bOverflow, 0); + EXPECT_EQ(ret, 24); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeMult_mult_gt_1_appends_number_and_delim) +{ + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int ret = MakeMult(5, "-", &strbuf, 0, &bOverflow); + + EXPECT_EQ(std::string(strbuf.pStr), "5-"); + EXPECT_EQ(ret, 2); + EXPECT_EQ(bOverflow, 0); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeMult_mult_2) +{ + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int ret = MakeMult(10, "+", &strbuf, 0, &bOverflow); + + EXPECT_EQ(std::string(strbuf.pStr), "10+"); + EXPECT_EQ(ret, 3); + EXPECT_EQ(bOverflow, 0); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeMult_mult_eq_1_does_nothing) +{ + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + inchi_strbuf_printf(&strbuf, "start"); + + int bOverflow = 0; + int ret = MakeMult(1, "-", &strbuf, 0, &bOverflow); + + EXPECT_EQ(std::string(strbuf.pStr), "start"); + EXPECT_EQ(ret, 0); + EXPECT_EQ(bOverflow, 0); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, Eql_INChI_Stereo_sp2_equal) +{ + // Setup two identical SP2 stereo objects + INChI_Stereo s1 = {0}, s2 = {0}; + int num_bonds = 2; + AT_NUMB bond_atom1[2] = {1, 3}; + AT_NUMB bond_atom2[2] = {2, 4}; + S_CHAR b_parity[2] = {1, 2}; + + s1.nNumberOfStereoBonds = num_bonds; + s1.nBondAtom1 = bond_atom1; + s1.nBondAtom2 = bond_atom2; + s1.b_parity = b_parity; + + s2.nNumberOfStereoBonds = num_bonds; + s2.nBondAtom1 = bond_atom1; + s2.nBondAtom2 = bond_atom2; + s2.b_parity = b_parity; + + // Should be equal + EXPECT_EQ(Eql_INChI_Stereo(&s1, EQL_SP2, &s2, EQL_SP2, 0), 1); +} + +TEST(test_ichiprt2, Eql_INChI_Stereo_sp2_not_equal) +{ + // Setup two different SP2 stereo objects + INChI_Stereo s1 = {0}, s2 = {0}; + AT_NUMB bond_atom1_1[2] = {1, 3}; + AT_NUMB bond_atom2_1[2] = {2, 4}; + S_CHAR b_parity_1[2] = {1, 2}; + + AT_NUMB bond_atom1_2[2] = {1, 5}; + AT_NUMB bond_atom2_2[2] = {2, 6}; + S_CHAR b_parity_2[2] = {1, 1}; + + s1.nNumberOfStereoBonds = 2; + s1.nBondAtom1 = bond_atom1_1; + s1.nBondAtom2 = bond_atom2_1; + s1.b_parity = b_parity_1; + + s2.nNumberOfStereoBonds = 2; + s2.nBondAtom1 = bond_atom1_2; + s2.nBondAtom2 = bond_atom2_2; + s2.b_parity = b_parity_2; + + // Should not be equal + EXPECT_EQ(Eql_INChI_Stereo(&s1, EQL_SP2, &s2, EQL_SP2, 0), 0); +} + +TEST(test_ichiprt2, Eql_INChI_Stereo_sp2_exists) +{ + // s1 has stereo, s2 is nullptr, eql2 is EQL_EXISTS + INChI_Stereo s1 = {0}; + AT_NUMB bond_atom1[1] = {1}; + AT_NUMB bond_atom2[1] = {2}; + S_CHAR b_parity[1] = {1}; + + s1.nNumberOfStereoBonds = 1; + s1.nBondAtom1 = bond_atom1; + s1.nBondAtom2 = bond_atom2; + s1.b_parity = b_parity; + + EXPECT_EQ(Eql_INChI_Stereo(&s1, EQL_SP2, nullptr, EQL_EXISTS, 0), 1); +} + +TEST(test_ichiprt2, Eql_INChI_Stereo_sp3_equal) +{ + // Setup two identical SP3 stereo objects + INChI_Stereo s1 = {0}, s2 = {0}; + int num_centers = 2; + AT_NUMB nNumber1[2] = {5, 6}; + S_CHAR t_parity1[2] = {1, 2}; + + s1.nNumberOfStereoCenters = num_centers; + s1.nNumber = nNumber1; + s1.t_parity = t_parity1; + + s2.nNumberOfStereoCenters = num_centers; + s2.nNumber = nNumber1; + s2.t_parity = t_parity1; + + // Should be equal + EXPECT_EQ(Eql_INChI_Stereo(&s1, EQL_SP3, &s2, EQL_SP3, 0), 1); +} + +TEST(test_ichiprt2, Eql_INChI_Stereo_sp3_not_equal) +{ + // Setup two different SP3 stereo objects + INChI_Stereo s1 = {0}, s2 = {0}; + int num_centers = 2; + AT_NUMB nNumber1[2] = {5, 6}; + S_CHAR t_parity1[2] = {1, 2}; + + AT_NUMB nNumber2[2] = {7, 8}; + S_CHAR t_parity2[2] = {2, 1}; + + s1.nNumberOfStereoCenters = num_centers; + s1.nNumber = nNumber1; + s1.t_parity = t_parity1; + + s2.nNumberOfStereoCenters = num_centers; + s2.nNumber = nNumber2; + s2.t_parity = t_parity2; + + // Should not be equal + EXPECT_EQ(Eql_INChI_Stereo(&s1, EQL_SP3, &s2, EQL_SP3, 0), 0); +} + +TEST(test_ichiprt2, test_compare_ints_basic) +{ + int a = 5, b = 10, c = 5; + + // a < b + EXPECT_LT(compare_ints(&a, &b), 0); + + // b > a + EXPECT_GT(compare_ints(&b, &a), 0); + + // a == c + EXPECT_EQ(compare_ints(&a, &c), 0); +} + +TEST(test_ichiprt2, MakeNumber_EnhStereo_decimal) +{ + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int nCtMode = 0; // decimal mode + + int n = MakeNumber_EnhStereo(42, ",", &strbuf, nCtMode, &bOverflow); + + EXPECT_EQ(bOverflow, 0); + EXPECT_EQ(std::string(strbuf.pStr), "42,"); + EXPECT_EQ(n, 3); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeNumber_EnhStereo_abc) +{ + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + int bOverflow = 0; + int nCtMode = CT_MODE_ABC_NUMBERS; // alphabetic mode + + int n = MakeNumber_EnhStereo(28, ";", &strbuf, nCtMode, &bOverflow); + + EXPECT_EQ(bOverflow, 0); + // 28 in base-27 is "aa", so expect "Aa;" + EXPECT_EQ(std::string(strbuf.pStr), "Aa;"); + EXPECT_EQ(n, 3); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeEnhStereoString_basic) +{ + // Setup INChI_Aux with 3 atoms, canonical numbers 1, 2, 3 + INChI_Aux aux = {0}; + AT_NUMB orig_atoms[] = {1, 2, 3}; + aux.nNumberOfAtoms = 3; + aux.nOrigAtNosInCanonOrd = orig_atoms; + + // Enhanced stereo group: one group, 3 atoms (original numbers 1,2,3) + int group1[] = {0, 3, 1, 2, 3}; // [unused, n_atoms, orig_atom1, orig_atom2, orig_atom3] + int* enh_stereo[1] = {group1}; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + int bOverflow = 0; + int nCtMode = 0; + + int len = MakeEnhStereoString(&aux, &strbuf, "1", enh_stereo, 1, nCtMode, &bOverflow); + + EXPECT_EQ(bOverflow, 0); + EXPECT_EQ(std::string(strbuf.pStr), "1(1,2,3)"); + EXPECT_EQ(len, 8); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeEnhStereoString_multiple_groups) +{ + INChI_Aux aux = {0}; + AT_NUMB orig_atoms[] = {1, 2, 3, 4}; + aux.nNumberOfAtoms = 4; + aux.nOrigAtNosInCanonOrd = orig_atoms; + + int group1[] = {0, 2, 1, 2}; // [unused, n_atoms, orig_atom1, orig_atom2] + int group2[] = {0, 2, 3, 4}; // [unused, n_atoms, orig_atom3, orig_atom4] + int* enh_stereo[2] = {group1, group2}; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + int bOverflow = 0; + int nCtMode = 0; + + int len = MakeEnhStereoString(&aux, &strbuf, "2", enh_stereo, 2, nCtMode, &bOverflow); + + EXPECT_EQ(bOverflow, 0); + EXPECT_EQ(std::string(strbuf.pStr), "2(1,2)(3,4)"); + EXPECT_EQ(len, 11); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeEnhStereoString_empty_group) +{ + INChI_Aux aux = {0}; + AT_NUMB orig_atoms[] = {1, 2, 3}; + aux.nNumberOfAtoms = 3; + aux.nOrigAtNosInCanonOrd = orig_atoms; + + // Group with no valid atoms + int group1[] = {0, 2, 99, 100}; // [unused, n_atoms, orig_atom99, orig_atom100] + int* enh_stereo[1] = {group1}; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + int bOverflow = 0; + int nCtMode = 0; + + int len = MakeEnhStereoString(&aux, &strbuf, "3", enh_stereo, 1, nCtMode, &bOverflow); + + EXPECT_EQ(bOverflow, 0); + EXPECT_EQ(std::string(strbuf.pStr), ""); + EXPECT_EQ(len, 0); + + inchi_strbuf_close(&strbuf); +} + +TEST(test_ichiprt2, MakeSlayerString_basic) +{ + + ORIG_ATOM_DATA *oad = (ORIG_ATOM_DATA *)inchi_calloc(1, sizeof(ORIG_ATOM_DATA)); + + OAD_V3000 *v3000 = (OAD_V3000 *)inchi_calloc(1, sizeof(OAD_V3000)); + + // One absolute group: 2 atoms (original numbers 1,2) + int group_abs[] = {0, 2, 1, 2}; + v3000->n_steabs = 1; + v3000->lists_steabs = (int**)inchi_calloc(1, sizeof(int*)); + v3000->lists_steabs[0] = group_abs; + + // One relative group: 1 atom (original number 3) + int group_rel[] = {0, 1, 3}; + v3000->n_sterel = 1; + v3000->lists_sterel = (int**)inchi_calloc(1, sizeof(int*)); + v3000->lists_sterel[0] = group_rel; + + // No racemic groups + v3000->n_sterac = 0; + + oad->v3000 = v3000; + + // Setup INCHI_SORT and INChI_Aux + INCHI_SORT *inchi_sort = (INCHI_SORT*)inchi_calloc(1, sizeof(INCHI_SORT)); + + int num_at = 8; + int num_iso_at = 1; + int alloc_mode = 0; + int bOrigatomflag = 0; + int found_num_bonds = 0; + int found_num_isotopic = 0; + + inp_ATOM *atoms = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(atoms, num_at, &found_num_bonds, &found_num_isotopic, 0); + inchi->nNumberOfAtoms = num_at; + + INChI_Aux *pAux = Alloc_INChI_Aux(num_at, num_iso_at, alloc_mode, bOrigatomflag); + pAux->nNumberOfAtoms = 3; + pAux->nOrigAtNosInCanonOrd[0] = 1; + pAux->nOrigAtNosInCanonOrd[1] = 2; + pAux->nOrigAtNosInCanonOrd[2] = 3; + + inchi_sort->pINChI_Aux[0] = pAux; + inchi_sort->pINChI[0] = inchi; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + int bOverflow = 0; + int nCtMode = 0; + + int len = MakeSlayerString(oad, inchi_sort, &strbuf, OUT_TN, 1, nCtMode, &bOverflow); + + EXPECT_EQ(bOverflow, 0); + EXPECT_EQ(std::string(strbuf.pStr), "1(1,2)2(3)"); + EXPECT_EQ(len, 10); + + inchi_free(oad->v3000->lists_steabs); + inchi_free(oad->v3000->lists_sterel); + inchi_free(oad->v3000); + inchi_free(oad); + inchi_free(inchi_sort); + + inchi_strbuf_close(&strbuf); + FreeInpAtom(&atoms); + Free_INChI_Aux(&pAux); + Free_INChI(&inchi); +} diff --git a/INCHI-1-TEST/tests/test_unit/test_ichiprt3.cpp b/INCHI-1-TEST/tests/test_unit/test_ichiprt3.cpp new file mode 100644 index 00000000..c5b8def9 --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/test_ichiprt3.cpp @@ -0,0 +1,260 @@ +#include +#include + +extern "C" +{ +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichiprt3.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/strutil.c" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichi_io.h" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichimake.h" +} + +TEST(test_ichiprt3, test_str_Sp2_outputs_expected_sp2_string_1) +{ + int num_at = 2; + int num_bonds = 1; + int bond_atom1[1] = {4}; + int bond_atom2[1] = {3}; + S_CHAR b_parity[1] = {1}; // 1 = -, 2 = + + + INChI_Stereo* stereo = Alloc_INChI_Stereo(num_at, num_bonds); + stereo->nNumberOfStereoBonds = num_bonds; + for (int i = 0; i < num_bonds; i++) { + stereo->nBondAtom1[i] = bond_atom1[i]; + stereo->nBondAtom2[i] = bond_atom2[i]; + stereo->b_parity[i] = b_parity[i]; + } + + INChI inchi = {0}; + inchi.nNumberOfAtoms = num_at; + inchi.Stereo = stereo; + + INCHI_SORT inchi_sort = {0}; + inchi_sort.pINChI[0] = &inchi; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int bOutputType = OUT_N1; // OUT_TN + int taut_mode = 0; // CT_MODE_ABC_NUMBERS + int num_components = 1; + + int bSecondNonTautPass = 0; + int bOmitRepetitions = 0; + int bUseMulipliers = 1; + + int ret = str_Sp2( + &inchi_sort, + NULL, + &strbuf, + &bOverflow, + bOutputType, + taut_mode, + num_components, + bSecondNonTautPass, + bOmitRepetitions, + bUseMulipliers + ); + + EXPECT_EQ(strbuf.nUsedLength, strlen(strbuf.pStr)); + EXPECT_EQ(std::string(strbuf.pStr), "4-3-"); + EXPECT_EQ(strbuf.pStr[0], '4'); + EXPECT_EQ(bOverflow, 0); + + // The return value should be the length of the output string + EXPECT_EQ(ret, 4); + + inchi_strbuf_close(&strbuf); + Free_INChI_Stereo(stereo); + inchi_free(stereo); +} + +TEST(test_ichiprt3, test_str_Sp2_outputs_expected_sp2_string_2) +{ + int num_at = 4; + int num_bonds = 2; + int bond_atom1[2] = {1, 3}; + int bond_atom2[2] = {2, 4}; + S_CHAR b_parity[2] = {1, 2}; // 1 = -, 2 = + + + INChI_Stereo* stereo = Alloc_INChI_Stereo(num_at, num_bonds); + stereo->nNumberOfStereoBonds = num_bonds; + for (int i = 0; i < num_bonds; i++) { + stereo->nBondAtom1[i] = bond_atom1[i]; + stereo->nBondAtom2[i] = bond_atom2[i]; + stereo->b_parity[i] = b_parity[i]; + } + + INChI inchi = {0}; + inchi.nNumberOfAtoms = num_at; + inchi.Stereo = stereo; + + INCHI_SORT inchi_sort = {0}; + inchi_sort.pINChI[0] = &inchi; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int bOutputType = OUT_N1; // OUT_TN + int taut_mode = 0; // CT_MODE_ABC_NUMBERS + int num_components = 1; + + int bSecondNonTautPass = 0; + int bOmitRepetitions = 0; + int bUseMulipliers = 1; + + int ret = str_Sp2( + &inchi_sort, + NULL, + &strbuf, + &bOverflow, + bOutputType, + taut_mode, + num_components, + bSecondNonTautPass, + bOmitRepetitions, + bUseMulipliers + ); + + EXPECT_EQ(strbuf.nUsedLength, strlen(strbuf.pStr)); + EXPECT_EQ(std::string(strbuf.pStr), "1-2-,3-4+"); + EXPECT_EQ(strbuf.pStr[0], '1'); + EXPECT_EQ(bOverflow, 0); + + // The return value should be the length of the output string + EXPECT_EQ(ret, 9); + + inchi_strbuf_close(&strbuf); + Free_INChI_Stereo(stereo); + inchi_free(stereo); +} + +TEST(test_ichiprt3, test_str_Sp3_outputs_expected_sp3_string) +{ + int numbers[8] = {3,4,5,6,7,8,9,10}; + S_CHAR parities[8] = {1,1,2,2,1,2,2,1}; // 1 = -, 2 = + + int num_at = 8; + static INChI_Stereo *stereo = Alloc_INChI_Stereo( num_at, 0 ); + stereo->nNumberOfStereoCenters = num_at; + + for (int i = 0; i < num_at; i++) { + stereo->nNumber[i] = numbers[i]; + stereo->t_parity[i] = parities[i]; + } + + INChI inchi = {0}; + inchi.nNumberOfAtoms = 10; + inchi.Stereo = stereo; + + INCHI_SORT inchi_sort = {0}; + inchi_sort.pINChI[0] = &inchi; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + + int bOverflow = 0; + int num_components = 1; + + int bIsotopicRelativeStereo = 0; // INCHI_FLAG_REL_STEREO + int bIsotopicRacemicStereo = 0; // INCHI_FLAG_RAC_STEREO + + int bRelRac = bIsotopicRelativeStereo || bIsotopicRacemicStereo; + + int ret = str_Sp3(&inchi_sort, NULL, &strbuf, &bOverflow, 0, 0, num_components, bRelRac, 0, 0, 0); + + EXPECT_EQ(strbuf.nUsedLength, strlen(strbuf.pStr)); + EXPECT_EQ(std::string(strbuf.pStr), "3-,4-,5+,6+,7-,8+,9+,10-"); + EXPECT_EQ(strbuf.pStr[0], '3'); + EXPECT_EQ(bOverflow, 0); + + EXPECT_EQ(ret, 24); + + inchi_strbuf_close(&strbuf); + + Free_INChI_Stereo(stereo); +} + +TEST(test_ichiprt3, test_str_StereoAbsInv_1) +{ + + int num_at = 2; + int num_bonds = 1; + int found_num_bonds = 0; + int found_num_isotopic = 0; + inp_ATOM *at = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(at, num_at, &found_num_bonds, &found_num_isotopic, 0); + inchi->Stereo->nCompInv2Abs = -1; + inchi->nNumberOfAtoms = num_at; + + INCHI_SORT *inchi_sort = (INCHI_SORT*)calloc(1, sizeof(INCHI_SORT)); + inchi_sort->pINChI[TAUT_YES] = inchi; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int bOutType = OUT_TN; + int num_components = 1; + + // int test_ret0 = HAS_T(inchi_sort); + // int test_ret1 = GET_II( bOutType, inchi_sort); + + int ret = str_StereoAbsInv(inchi_sort, &strbuf, &bOverflow, bOutType, num_components); + + EXPECT_EQ(ret, 1); + EXPECT_EQ(std::string(strbuf.pStr), "1"); + EXPECT_EQ(bOverflow, 0); + + inchi_strbuf_close(&strbuf); + + Free_INChI(&inchi); + + FreeInpAtom(&at); + + free(inchi_sort); +} + +TEST(test_ichiprt3, test_str_StereoAbsInv_2) +{ + + int num_at = 2; + int num_bonds = 1; + int found_num_bonds = 0; + int found_num_isotopic = 0; + inp_ATOM *at = CreateInpAtom(num_at); + static INChI *inchi = Alloc_INChI(at, num_at, &found_num_bonds, &found_num_isotopic, 0); + + inchi->Stereo->nCompInv2Abs = 1; + + inchi->nNumberOfAtoms = num_at; + + INCHI_SORT *inchi_sort = (INCHI_SORT*)calloc(1, sizeof(INCHI_SORT)); + inchi_sort->pINChI[TAUT_YES] = inchi; + + INCHI_IOS_STRING strbuf = {0}; + inchi_strbuf_init(&strbuf, INCHI_STRBUF_INITIAL_SIZE, INCHI_STRBUF_SIZE_INCREMENT); + + int bOverflow = 0; + int bOutType = OUT_TN; + int num_components = 1; + + // int test_ret0 = HAS_T(inchi_sort); + // int test_ret1 = GET_II( bOutType, inchi_sort); + + int ret = str_StereoAbsInv(inchi_sort, &strbuf, &bOverflow, bOutType, num_components); + + EXPECT_EQ(ret, 1); + EXPECT_EQ(std::string(strbuf.pStr), "0"); + EXPECT_EQ(bOverflow, 0); + + inchi_strbuf_close(&strbuf); + + Free_INChI(&inchi); + + FreeInpAtom(&at); + + free(inchi_sort); +} diff --git a/INCHI-1-TEST/tests/test_unit/test_inpdef.cpp b/INCHI-1-TEST/tests/test_unit/test_inpdef.cpp index 986b6c6d..d3a0228b 100644 --- a/INCHI-1-TEST/tests/test_unit/test_inpdef.cpp +++ b/INCHI-1-TEST/tests/test_unit/test_inpdef.cpp @@ -71,23 +71,6 @@ TEST(test_inpdef, test_CreateOrigInpDataFromMolfile_v3000_sgroup) inchi_ios_init(&input_stream, INCHI_IOS_TYPE_STRING, nullptr); inchi_ios_print_nodisplay(&input_stream, molblock); - // int ret = CreateOrigInpDataFromMolfile( - // INCHI_IOSTREAM *inp_file, - // ORIG_ATOM_DATA *orig_at_data, - // int bMergeAllInputStructures, - // int bGetOrigCoord, - // int bDoNotAddH, - // int treat_polymers, - // int treat_NPZz, - // const char *pSdfLabel, - // char *pSdfValue, - // unsigned long *lSdfId, - // long *lMolfileNumber, - // INCHI_MODE *pInpAtomFlags, - // int *err, - // char *pStrErr, - // int bNoWarnings); - ORIG_ATOM_DATA orig_at_data = {}; int bMergeAllInputStructures = 0; int bGetOrigCoord = 0; diff --git a/INCHI-1-TEST/tests/test_unit/test_mol_fmt.cpp b/INCHI-1-TEST/tests/test_unit/test_mol_fmt.cpp index 23003716..cdf361e6 100644 --- a/INCHI-1-TEST/tests/test_unit/test_mol_fmt.cpp +++ b/INCHI-1-TEST/tests/test_unit/test_mol_fmt.cpp @@ -28,8 +28,6 @@ TEST(test_mol_fmt, test_MolfileStrnread) TEST(test_mol_fmt, test_MolfileReadField) { - // int MolfileReadField(void *data, int field_len, int data_type, char **line_ptr) - // SEG FAULT? // EXPECT_EQ(MolfileReadField(NULL, 0, MOL_FMT_STRING_DATA, NULL), 0); // no data, no line pointer @@ -110,11 +108,6 @@ TEST(test_mol_fmt, test_MolfileReadField) TEST(test_mol_fmt, test_MolfileV3000ReadField) { - - // int MolfileV3000ReadField(void *data, - // int data_type, - // char **line_ptr); - int n_coll = 0; char source_data[] = "2 ATOMS=(1 1)"; @@ -362,31 +355,19 @@ TEST(test_mol_fmt, test_MolfileHasNoChemStruc) TEST(test_mol_fmt, test_FreeMolfileData) { + MOL_FMT_DATA *mfdata = (MOL_FMT_DATA *)calloc(1, sizeof(MOL_FMT_DATA)); - MOL_FMT_DATA *mfdata; + MOL_FMT_HEADER_BLOCK *hdr = (MOL_FMT_HEADER_BLOCK *)calloc(1, sizeof(MOL_FMT_HEADER_BLOCK)); - MOL_FMT_HEADER_BLOCK *hdr; + MOL_FMT_CTAB *ctab = (MOL_FMT_CTAB *)calloc(1, sizeof(MOL_FMT_CTAB)); + MOL_FMT_ATOM *atoms = (MOL_FMT_ATOM *)calloc(1, sizeof(MOL_FMT_ATOM)); + MOL_FMT_BOND *bonds = (MOL_FMT_BOND *)calloc(1, sizeof(MOL_FMT_BOND)); - MOL_FMT_CTAB *ctab; - MOL_FMT_BOND *bonds; - MOL_FMT_ATOM *atoms; + MOL_FMT_SGROUPS *sgroups = (MOL_FMT_SGROUPS *)calloc(1, sizeof(MOL_FMT_SGROUPS)); - MOL_FMT_SGROUPS *sgroups; - MOL_COORD *coords; - MOL_FMT_v3000 *v3000; + MOL_COORD *coords = (MOL_COORD *)calloc(1, sizeof(MOL_COORD)); - mfdata = (MOL_FMT_DATA *)calloc(1, sizeof(MOL_FMT_DATA)); - - hdr = (MOL_FMT_HEADER_BLOCK *)calloc(1, sizeof(MOL_FMT_HEADER_BLOCK)); - - ctab = (MOL_FMT_CTAB *)calloc(1, sizeof(MOL_FMT_CTAB)); - atoms = (MOL_FMT_ATOM *)calloc(1, sizeof(MOL_FMT_ATOM)); - bonds = (MOL_FMT_BOND *)calloc(1, sizeof(MOL_FMT_BOND)); - - sgroups = (MOL_FMT_SGROUPS *)calloc(1, sizeof(MOL_FMT_SGROUPS)); - - coords = (MOL_COORD *)calloc(1, sizeof(MOL_COORD)); - v3000 = (MOL_FMT_v3000 *)calloc(1, sizeof(MOL_FMT_v3000)); + MOL_FMT_v3000 *v3000 = (MOL_FMT_v3000 *)calloc(1, sizeof(MOL_FMT_v3000)); mfdata->hdr = *hdr; @@ -472,21 +453,6 @@ TEST(test_mol_fmt, test_ReadMolfile_v2000) inchi_ios_init(&input_stream, INCHI_IOS_TYPE_STRING, nullptr); inchi_ios_print_nodisplay(&input_stream, molblock); - // MOL_FMT_DATA *ReadMolfile(INCHI_IOSTREAM *inp_file, - // MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock, - // MOL_FMT_CTAB *OnlyCTab, - // int bGetOrigCoord, - // int treat_polymers, - // int treat_NPZz, - // char *pname, - // int lname, - // unsigned long *Id, - // const char *pSdfLabel, - // char *pSdfValue, - // int *err, - // char *pStrErr, - // int bNoWarnings) - INCHI_IOSTREAM *inp_file = &input_stream; MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock = nullptr; MOL_FMT_CTAB *OnlyCTab = nullptr; @@ -599,21 +565,6 @@ TEST(test_mol_fmt, test_ReadMolfile_v3000) inchi_ios_init(&input_stream, INCHI_IOS_TYPE_STRING, nullptr); inchi_ios_print_nodisplay(&input_stream, molblock); - // MOL_FMT_DATA *ReadMolfile(INCHI_IOSTREAM *inp_file, - // MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock, - // MOL_FMT_CTAB *OnlyCTab, - // int bGetOrigCoord, - // int treat_polymers, - // int treat_NPZz, - // char *pname, - // int lname, - // unsigned long *Id, - // const char *pSdfLabel, - // char *pSdfValue, - // int *err, - // char *pStrErr, - // int bNoWarnings) - INCHI_IOSTREAM *inp_file = &input_stream; MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock = nullptr; MOL_FMT_CTAB *OnlyCTab = nullptr; @@ -696,21 +647,6 @@ TEST(test_mol_fmt, test_ReadMolfile_v3000_collection_1) inchi_ios_init(&input_stream, INCHI_IOS_TYPE_STRING, nullptr); inchi_ios_print_nodisplay(&input_stream, molblock); - // MOL_FMT_DATA *ReadMolfile(INCHI_IOSTREAM *inp_file, - // MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock, - // MOL_FMT_CTAB *OnlyCTab, - // int bGetOrigCoord, - // int treat_polymers, - // int treat_NPZz, - // char *pname, - // int lname, - // unsigned long *Id, - // const char *pSdfLabel, - // char *pSdfValue, - // int *err, - // char *pStrErr, - // int bNoWarnings) - INCHI_IOSTREAM *inp_file = &input_stream; MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock = nullptr; MOL_FMT_CTAB *OnlyCTab = nullptr; @@ -829,21 +765,6 @@ TEST(test_mol_fmt, test_ReadMolfile_v3000_collection_2) inchi_ios_init(&input_stream, INCHI_IOS_TYPE_STRING, nullptr); inchi_ios_print_nodisplay(&input_stream, molblock); - // MOL_FMT_DATA *ReadMolfile(INCHI_IOSTREAM *inp_file, - // MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock, - // MOL_FMT_CTAB *OnlyCTab, - // int bGetOrigCoord, - // int treat_polymers, - // int treat_NPZz, - // char *pname, - // int lname, - // unsigned long *Id, - // const char *pSdfLabel, - // char *pSdfValue, - // int *err, - // char *pStrErr, - // int bNoWarnings) - INCHI_IOSTREAM *inp_file = &input_stream; MOL_FMT_HEADER_BLOCK *OnlyHeaderBlock = nullptr; MOL_FMT_CTAB *OnlyCTab = nullptr; diff --git a/INCHI-1-TEST/tests/test_unit/test_strutil.cpp b/INCHI-1-TEST/tests/test_unit/test_strutil.cpp index f09afffe..3654e48d 100644 --- a/INCHI-1-TEST/tests/test_unit/test_strutil.cpp +++ b/INCHI-1-TEST/tests/test_unit/test_strutil.cpp @@ -13,7 +13,6 @@ TEST(test_strutil, test_ExtractConnectedComponent) inp_ATOM *new_mol = CreateInpAtom(num_atoms); inp_ATOM *cmp_mol = CreateInpAtom(num_atoms); - // int ExtractConnectedComponent(inp_ATOM *at, int num_at, int component_number, inp_ATOM *component_at) EXPECT_EQ(ExtractConnectedComponent(nullptr, 0, test_component_number, nullptr), 0); for (int i = 0; i < num_atoms; i++) @@ -34,7 +33,6 @@ TEST(test_strutil, test_SetConnectedComponentNumber) int test_component_number = 23; inp_ATOM *new_mol = CreateInpAtom(num_atoms); - // int SetConnectedComponentNumber( inp_ATOM *at, int num_at, int component_number ) EXPECT_EQ(SetConnectedComponentNumber(new_mol, num_atoms, test_component_number), 0); for (int i = 0; i < num_atoms; i++) @@ -55,7 +53,6 @@ TEST(test_strutil, test_UnMarkRingSystemsInp) new_mol[i].nRingSystem = i + 1; } - // int UnMarkRingSystemsInp( inp_ATOM *at, int num_atoms ) EXPECT_EQ(UnMarkRingSystemsInp(new_mol, num_atoms), 0); for (int i = 0; i < num_atoms; i++) diff --git a/INCHI-1-TEST/tests/test_unit/test_strutil_enhancedStereo.cpp b/INCHI-1-TEST/tests/test_unit/test_strutil_enhancedStereo.cpp new file mode 100644 index 00000000..b4b3bb0c --- /dev/null +++ b/INCHI-1-TEST/tests/test_unit/test_strutil_enhancedStereo.cpp @@ -0,0 +1,262 @@ +#include + +extern "C" +{ +#include "../../../INCHI-1-SRC/INCHI_BASE/src/strutil.h" +#include "../../../INCHI-1-SRC/INCHI_BASE/src/ichi_io.h" +} + +TEST(test_strutil_enhancedStereo, test_set_EnhancedStereo_t_m_layers_1) +{ + + INCHI_IOSTREAM input_stream; + + const char *molblock = + "enhanc_stereo1 \n" + " ACD/LABS08242216132D \n" + " \n" + " 0 0 0 0 0 0 0 0 0 0999 V3000 \n" + "M V30 BEGIN CTAB \n" + "M V30 COUNTS 18 17 0 0 1 \n" + "M V30 BEGIN ATOM \n" + "M V30 1 C 3424.1946 -1936.7935 0 0 \n" + "M V30 2 C 3352.3145 -1895.2935 0 0 \n" + "M V30 3 C 3280.4346 -1936.7935 0 0 \n" + "M V30 4 C 3208.5542 -1895.2935 0 0 \n" + "M V30 5 C 3136.6743 -1936.7935 0 0 \n" + "M V30 6 C 3064.7944 -1895.2935 0 0 \n" + "M V30 7 Br 3136.6743 -2019.7935 0 0 \n" + "M V30 8 Cl 3208.5542 -1812.2935 0 0 \n" + "M V30 9 Cl 3280.4346 -2019.7935 0 0 \n" + "M V30 10 Cl 3352.3145 -1812.2935 0 0 \n" + "M V30 11 Cl 3424.1946 -2019.7935 0 0 \n" + "M V30 12 C 3496.075 -1895.2935 0 0 \n" + "M V30 13 C 3567.9548 -1936.7942 0 0 \n" + "M V30 14 C 3639.835 -1895.2944 0 0 \n" + "M V30 15 C 3711.7148 -1936.7942 0 0 \n" + "M V30 16 Cl 3639.835 -1812.2944 0 0 \n" + "M V30 17 Cl 3567.9548 -2019.7942 0 0 \n" + "M V30 18 Cl 3496.075 -1812.2937 0 0 \n" + "M V30 END ATOM \n" + "M V30 BEGIN BOND \n" + "M V30 1 1 1 2 \n" + "M V30 2 1 1 11 CFG=3 \n" + "M V30 3 1 1 12 \n" + "M V30 4 1 2 3 \n" + "M V30 5 1 2 10 CFG=1 \n" + "M V30 6 1 3 4 \n" + "M V30 7 1 3 9 CFG=1 \n" + "M V30 8 1 4 5 \n" + "M V30 9 1 4 8 CFG=1 \n" + "M V30 10 1 5 6 \n" + "M V30 11 1 5 7 CFG=1 \n" + "M V30 12 1 12 13 \n" + "M V30 13 1 12 18 CFG=3 \n" + "M V30 14 1 13 14 \n" + "M V30 15 1 13 17 CFG=1 \n" + "M V30 16 1 14 15 \n" + "M V30 17 1 14 16 CFG=1 \n" + "M V30 END BOND \n" + "M V30 BEGIN COLLECTION \n" + "M V30 MDLV30/STERAC2 ATOMS=(1 1) \n" + "M V30 MDLV30/STERAC1 ATOMS=(2 2 3) \n" + "M V30 MDLV30/STEABS ATOMS=(2 4 5) \n" + "M V30 MDLV30/STEREL1 ATOMS=(2 12 13) \n" + "M V30 MDLV30/STEREL2 ATOMS=(1 14) \n" + "M V30 END COLLECTION \n" + "M V30 END CTAB \n" + "M END \n"; + + inchi_ios_init(&input_stream, INCHI_IOS_TYPE_STRING, nullptr); + inchi_ios_print_nodisplay(&input_stream, molblock); + + ORIG_ATOM_DATA *orig_inp_data = (ORIG_ATOM_DATA*)inchi_calloc(1, sizeof(ORIG_ATOM_DATA)); + int bMergeAllInputStructures = 0; + int bGetOrigCoord = 0; + int bDoNotAddH = 0; + int treat_polymers = 0; + int treat_NPZz = 0; + const char *pSdfLabel = nullptr; + char *pSdfValue = nullptr; + unsigned long *lSdfId = nullptr; + long *lMolfileNumber = nullptr; + INCHI_MODE pInpAtomFlags = 0; + int err = 0; + char *pStrErr = nullptr; + int bNoWarnings = 0; + + int ret = CreateOrigInpDataFromMolfile( + &input_stream, + orig_inp_data, + bMergeAllInputStructures, + bGetOrigCoord, + bDoNotAddH, + treat_polymers, + treat_NPZz, + pSdfLabel, + pSdfValue, + lSdfId, + lMolfileNumber, + &pInpAtomFlags, + &err, + pStrErr, + bNoWarnings); + + EXPECT_EQ(ret, orig_inp_data->num_inp_atoms); + + int num_at = orig_inp_data->num_inp_atoms; + + int found_num_bonds = 0; + int found_num_isotopic = 0; + + inp_ATOM *at = CreateInpAtom(num_at); + INChI *inchi = Alloc_INChI(at, num_at, &found_num_bonds, &found_num_isotopic, 0); + + AT_NUMB at_tmp[] = {0,1,2,3,4,5,6,7,8}; + S_CHAR parity_tmp[] = {2,1,1,2,2,1,2,2,1}; + for (int i = 0; i < 9; i++) { + inchi->Stereo->nNumber[i] = at_tmp[i]; + inchi->Stereo->t_parity[i] = parity_tmp[i]; + } + + inchi->Stereo->nNumberOfStereoCenters = 9; + inchi->Stereo->nCompInv2Abs = -1; + inchi->nNumberOfAtoms = num_at; + + int nAllocMode = 0; + int bOrigCoord = 0; + + INChI_Aux *pAux = Alloc_INChI_Aux( num_at, + 0, // inp_cur_data->num_isotopic, + nAllocMode, + bOrigCoord ); + + + pAux->nNumberOfAtoms = 9; + + pAux->nOrigAtNosInCanonOrd[0] = 4; + pAux->nOrigAtNosInCanonOrd[1] = 5; + pAux->nOrigAtNosInCanonOrd[2] = 1; + pAux->nOrigAtNosInCanonOrd[3] = 2; + pAux->nOrigAtNosInCanonOrd[4] = 3; + pAux->nOrigAtNosInCanonOrd[5] = 12; + pAux->nOrigAtNosInCanonOrd[6] = 13; + pAux->nOrigAtNosInCanonOrd[7] = 14; + + ret = set_EnhancedStereo_t_m_layers(orig_inp_data, inchi, pAux); + + EXPECT_EQ(ret, 0); + + FreeOrigAtData(orig_inp_data); + inchi_free(orig_inp_data); + Free_INChI_Aux(&pAux); + Free_INChI(&inchi); + FreeInpAtom(&at); + + inchi_ios_free_str(&input_stream); + +} + +TEST(test_strutil_enhancedStereo, test_get_canonical_atom_number_1) +{ + + INChI_Aux aux; + int n_atoms = 5; + AT_NUMB orig_atoms[] = {10, 20, 30, 40, 50}; + aux.nNumberOfAtoms = n_atoms; + aux.nOrigAtNosInCanonOrd = orig_atoms; + + // Should return 1-based canonical atom number for each original atom number + EXPECT_EQ(get_canonical_atom_number(&aux, 10), 1); + EXPECT_EQ(get_canonical_atom_number(&aux, 20), 2); + EXPECT_EQ(get_canonical_atom_number(&aux, 30), 3); + EXPECT_EQ(get_canonical_atom_number(&aux, 40), 4); + EXPECT_EQ(get_canonical_atom_number(&aux, 50), 5); + + // Should return -1 for atom numbers not present + EXPECT_EQ(get_canonical_atom_number(&aux, 99), -1); + EXPECT_EQ(get_canonical_atom_number(&aux, 0), -1); + +} + +TEST(test_strutil_enhancedStereo, test_get_parity_idx_from_canonical_atom_number) +{ + + // Example: canonical atom numbers for a molecule with 4 stereo centers + AT_NUMB nNumber[] = {3, 1, 4, 2}; + int nof_atoms = 4; + + // Should return the index where the canonical atom number is found + EXPECT_EQ(get_parity_idx_from_canonical_atom_number(3, nNumber, nof_atoms), 0); + EXPECT_EQ(get_parity_idx_from_canonical_atom_number(1, nNumber, nof_atoms), 1); + EXPECT_EQ(get_parity_idx_from_canonical_atom_number(4, nNumber, nof_atoms), 2); + EXPECT_EQ(get_parity_idx_from_canonical_atom_number(2, nNumber, nof_atoms), 3); + + // Should return -1 for a canonical atom number not present + EXPECT_EQ(get_parity_idx_from_canonical_atom_number(5, nNumber, nof_atoms), -1); + EXPECT_EQ(get_parity_idx_from_canonical_atom_number(0, nNumber, nof_atoms), -1); +} + +TEST(test_strutil_enhancedStereo, invert_parities_basic) +{ + // Setup INChI_Stereo + INChI_Stereo stereo; + AT_NUMB nNumber[] = {1, 2, 3}; + S_CHAR t_parity[] = {2, 1, 2}; // 2=+, 1=- + stereo.nNumber = nNumber; + stereo.t_parity = t_parity; + stereo.nNumberOfStereoCenters = 3; + stereo.nCompInv2Abs = 1; + + // Setup INChI + INChI inchi = {0}; + inchi.Stereo = &stereo; + + // Setup INChI_Aux + INChI_Aux aux = {0}; + AT_NUMB orig_atoms[] = {1, 2, 3}; + aux.nNumberOfAtoms = 3; + aux.nOrigAtNosInCanonOrd = orig_atoms; + + // Setup list_atoms: one group, 3 atoms (original numbers 1,2,3) + int group1[] = {0, 3, 1, 2, 3}; // [unused, n_atoms, orig_atom1, orig_atom2, orig_atom3] + int* lists[1] = {group1}; + + // Call invert_parities for absolute group + int ret = invert_parities(&inchi, &aux, lists, 1, 1); + + EXPECT_EQ(ret, 0); + + EXPECT_EQ(stereo.t_parity[0], 1); + EXPECT_EQ(stereo.t_parity[1], 2); + EXPECT_EQ(stereo.t_parity[2], 1); + + EXPECT_EQ(stereo.nCompInv2Abs, -1); + + t_parity[0] = 2; + t_parity[1] = 1; + t_parity[2] = 2; + + stereo.nCompInv2Abs = 1; + + ret = invert_parities(&inchi, &aux, lists, 1, 0); + + EXPECT_EQ(ret, 0); + + EXPECT_EQ(stereo.t_parity[0], 1); + EXPECT_EQ(stereo.t_parity[1], 2); + EXPECT_EQ(stereo.t_parity[2], 1); + + EXPECT_EQ(stereo.nCompInv2Abs, 1); + + ret = invert_parities(&inchi, &aux, lists, 1, 0); + + EXPECT_EQ(ret, 0); + + EXPECT_EQ(stereo.t_parity[0], 1); + EXPECT_EQ(stereo.t_parity[1], 2); + EXPECT_EQ(stereo.t_parity[2], 1); + + EXPECT_EQ(stereo.nCompInv2Abs, 1); +} + diff --git a/INCHI-1-TEST/tests/test_unit/test_util.cpp b/INCHI-1-TEST/tests/test_unit/test_util.cpp index 037caa99..f4eb26ca 100644 --- a/INCHI-1-TEST/tests/test_unit/test_util.cpp +++ b/INCHI-1-TEST/tests/test_unit/test_util.cpp @@ -978,19 +978,3 @@ TEST(test_util, test_extract_stereo_info_from_inchi_string) EXPECT_EQ(found_stereo2, 0); } - -// TEST(test_util, test_extract_all_backbone_bonds_from_inchi_string) -// { - -// // int extract_all_backbone_bonds_from_inchi_string(char *sinchi, int *n_all_bkb_orig, int *orig, int *all_bkb_orig); - -// char inchi1[] = "InChI=1S/C2H6/c1-2/h1-2H3"; - -// int n_all_bkb_orig[2] = {0, 0}; -// int orig[2] = {0, 1}; -// int all_bkb_orig[2] = {0, 0}; - -// int ret1 = extract_all_backbone_bonds_from_inchi_string(inchi1, n_all_bkb_orig, orig, all_bkb_orig); - -// EXPECT_EQ(ret1, 0); -// }