osra-2.2.4/ 0000755 0001750 0001750 00000000000 15137157155 011157 5 ustar igor igor osra-2.2.4/src/ 0000755 0001750 0001750 00000000000 15137157137 011746 5 ustar igor igor osra-2.2.4/src/mcdlutil.cpp 0000644 0001750 0001750 00001110067 15137157137 014275 0 ustar igor igor /* -*-C++-*-
**********************************************************************
Copyright (C) 2007,2008 by Sergei V. Trepalin sergey_trepalin@chemical-block.com
Copyright (C) 2007,2008 by Andrei Gakh andrei.gakh@nnsa.doe.gov
This file is part of the Open Babel project.
For more information, see
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
***********************************************************************
*/
#include
#include
#include
#include
#include "mcdlutil.h"
#include
#include
//#ifndef WIN32
#include
//#endif
using namespace std;
namespace OpenBabel
{
#define CONNMAX 15
#define NATOMSMAX 255
#define NBONDSMAX 255
typedef struct adjustedlist
{
int nb;
int adjusted[CONNMAX];
} adjustedlist;
typedef adjustedlist neigbourlist[NATOMSMAX];
#define PI 3.141592653589793238462
#define blDenominator 4.0 //Controls bond legth in bondEnlarge
#define nRotBondsMax 20 //Determines no. rotating bonds in correctOverlapped
//Hydrogen valencies. Zero dummy element is the first
const int hVal[NELEMMCDL] =
{
0,1,0,0,0,3,4,3,2,1,
0,0,0,3,4,3,2,1,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,4,3,2,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
2,3,2,1,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,2,0,2,1,0,1,2,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0
};
const int maxVal[NELEMMCDL] =
{
0,1,0,1,2,4,4,5,3,1,
0,1,2,4,4,6,6,7,0,1,
2,3,4,5,6,7,6,4,4,2,
2,3,4,5,6,7,8,1,2,3,
4,5,6,7,8,6,6,2,2,3,
4,5,6,7,8,1,2,3,4,4,
3,3,3,3,3,4,3,3,3,3,
3,3,4,5,6,7,8,6,6,3,
2,3,4,5,6,7,8,1,2,3,
4,5,6,6,6,6,3,4,3,3,
3,3,1,1,1,0,0,0,0,0,
0,8,1,8,5,0,0,0,0,0,0
};
const int chargeVal[NELEMMCDL] = //0 - dummy
{
0,-1,-1,-1,-1,-1,-1, 1, 1, 1,-1, //Ne
-1,-1,-1,-1, 1, 1, 1,-1,-1,-1, //Ca
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, //Zn
-1,-1, 1, 1, 1,-1,-1,-1,-1,-1, //Zr
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, //Sn
1, 1, 1,-1,-1,-1,-1,-1,-1,-1, //Nd
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, //Yb
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, //Hg
-1,-1, 1, 1, 1,-1,-1,-1,-1,-1, //Th
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, //Fm
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1
};
const string aSymb[NELEMMCDL] = {"0",
"H" ,"He","Li","Be","B" ,"C" ,"N" ,"O" ,"F" ,"Ne",
"Na","Mg","Al","Si","P" ,"S" ,"Cl","Ar","K" ,"Ca",
"Sc","Ti","V" ,"Cr","Mn","Fe","Co","Ni","Cu","Zn",
"Ga","Ge","As","Se","Br","Kr","Rb","Sr","Y" ,"Zr",
"Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn",
"Sb","Te","I" ,"Xe","Cs","Ba","La","Ce","Pr","Nd",
"Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm","Yb",
"Lu","Hf","Ta","W" ,"Re","Os","Ir","Pt","Au","Hg",
"Tl","Pb","Bi","Po","At","Rn","Fr","Ra","Ac","Th",
"Pa","U" ,"Np","Pu","Am","Cm","Bk","Cf","Es","Fm",
"Md","No","Lr","D" ,"" ,"G" ,"0" ,"Xx","" ,"" ,
"M" ,"X" ,"A" ,"Q" ,"" ,"" ,"" ,"" ,"" ,""
};
#define NEXACTATOMS 21
const int exactAtom[NEXACTATOMS]= {6,14,5,50,82,8,16,34,52,7,15,33,51,9,17,35,53,32,13,26,80};
#define NALKALYATOMS 5
const int alkaly[NALKALYATOMS] = {3,11,19,37,55};
#define NALKALYEARTHATOMS 5
const int alkalyEarth[NALKALYEARTHATOMS] = {4,12,20,38,56};
#define NTRIVALENTATOMS 31
const int trivalent[NTRIVALENTATOMS] = {21,31,39,49,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,81,89,90,91,92,93,94,95,96,97,98,99};
#define NTITANATOMS 3
const int titan[NTITANATOMS] = {22,40,72};
#define NVANADIUMATOMS 3
const int vanadium[NVANADIUMATOMS] = {23,41,73};
#define NCHROMIUMATOMS 3
const int cromium[NCHROMIUMATOMS] = {24,42,74};
#define NMANGANESEATOMS 3
const int manganeze[NMANGANESEATOMS] = {25,43,75};
#define NLIKEFEATOMS 2
const int likeFe[NLIKEFEATOMS] = {27,28};
#define NPLATINUMATOMS 6
const int platinum[NPLATINUMATOMS] = {44,45,46,76,77,78};
#define NCOPPERATOMS 3
const int copper[NCOPPERATOMS] = {29,47,79};
#define NZINKATOMS 2
const int zink[NZINKATOMS] = {30,48};
#define NMETALS 78
#define NHALOGENS 5
#define NHETERO 10
#define NAROMMAX 9
#define NLIGHT_METALS 20
#define NHEAVY_METALS 58
#define DEUTERIUM_ATOM 104
#define METALL_ATOM 111
#define HALOGEN_ATOM 112
#define ANY_ATOM 113
#define HETERO_ATOM 114
#define ANY_BOND 8
const int possibleAromatic [NAROMMAX] = {7,8,15,16,33,34,51,52,HETERO_ATOM};
const int metals[NMETALS] =
{
3,4,11,12,13,19,20,21,22,23,24,25,26,27,28,29,
30,31,37,38,39,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,87,88,89,90,91,
92,93,94,95,96,97,98,99,100,101,102,103
};
//#define A B ??? -
const int lightMetals[NLIGHT_METALS] =
{
3,4,11,12,13,19,20,21,22,23,24,25,26,27,28,29,30,31,37,38
};
const int heavyMetals[NHEAVY_METALS] =
{
39,40,41,42,43,44,45,46,47,48,49,50,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,87,88,89,90,91,
92,93,94,95,96,97,98,99,100,101,102,103
};
const int halogens[NHALOGENS] = {9,17,35,53,85};
const int hetero[NHETERO] = {7,8,14,15,16,33,34,51,52,84};
#define RUNDEF -1.2345678E9
#define DEFAULTBONDLENGTH 1.44
#define NDATABASE_MOLECULES 147
const string strData[NDATABASE_MOLECULES]=
{
"05A53816506A53810000A00008692A99998857A6567442806020101030401050203050504",
"06A25008659A74998659A99994330A74990000A25000000A00004330100203030405060106060406020305010305020104",
"06A48805837A48800000A00007834A90467987A59523994A999962970802010103040106040502060503050302",
"06A33680000A00003697A90943697A90949999A00009999E3368717109020101030203010602050304050606040405",
"06A00002886A49980000A99992886A71137887A28867887E49985773070102020303060601010503040405",
"07A00002500A00007499A86397499A86392500A43200000A69404999A4235999909070203070304050402030102050606070105",
"07A18315489A81685489A18311830A81681830A49990000A00008658A9999865809050403050204010301060602020707010607",
"07A51830000A99995257A61733821A00008921A86408921A16055257E45686533100604030601070704050702050301020304050602",
"07A43300000A86602500A00002500A86607499A00007499A43309999A213550000801020301050606040402050301070607",
"07A69274000A69270000A00000000A00004000A69277999A34649999E3464599909010203040407010707060605050104060203",
"07A43309999A00007499A86607499A00002499A86602499A43300000E433049990806050406020101030305020406070702",
"08A99994342A99991475A50354342A74810040A50351475A00004363A24800000A00001455100405050301020402030107080806070506030704",
"08A14437499A43307499A57735000A43302500A14432500A00005000A57730000A57739999100102020303040405050601060407020808060607",
"08A55684926A59770000A13416715A91136862A00003196A24094926A99995337E654534311106030806020101030401070408020708060503050207",
"08A00003799A00009999A21890000A83936200A83930000A61999999E21896200E6199379912070206040206010203010805010806080703030507040405",
"08A36607320A78867320A99993660A78860000A36600000A15473660A00002113A0000520709010202030304040505060106050701080807",
"08A00005000A00008332A57705000A28419999A57708332A57701667A29290000A0000166709010202040405050301030306060707080801",
"08A48819390A53570000A00007833A90467986A59523994A11895837A99996297E48815837100603050602080803040807040502070503010401",
"08A19105257A80890000A99992628A19100000A00002628A80895257E50001004E500042531101080807070404050105060303020806070204020601",
"08A50000000A50006666A00002886A16670000A83320000A99992886E66662886E33332886100108080303040401010707060605050106020302",
"08A25008659A74998659A99994330A74990000A25000000A00004330E30622562E6937256209010202030304040505060106060703080708",
"09A24994330A74994330A24991444A74991444A49990000A99995773A00005773A85558273A144382731105040305020401030602010607010207090708060908",
"09A55375090A55370002A12826830A91696964A64713483A18610000A99995492A00003324E2320509012090305090201010304010704050207050908080308060602",
"09A18510000A00003211A90859999A70960000A00008451A52418451A70965241E52413211E18515241130905050602050102080402080608090101040907070403070603",
"09A19105257A49994253A49991004A19100000A00002628A80895257A99992628A80890000E386426281101020203030404050105060707080206030805090907",
"09A49994252A80895257A49991004A80890000A19090000A00002628A19095257A99992628E218626281101020208080404030103030505060607070103090109",
"09A00003622A10641208A32581208A49670000A32583622A99993247A81610000A68065661E593523311101020203030404050501030909070706060808050407",
"09A31703170A50000000A00004999A36604999A68293170A63394999A99994999A81698169A18308169100102010303090904040502050106070507080806",
"09A82718548A41359999A91956942A00008341A44961502A55014870A11246476A55010000E449664761107040607090401090301030609050608050804020102",
"09A70330000A29660000A00002881A00007010A29669891A70339891A99997010A99992881E63994946100102020303040405050606070708010802090509",
"09A80419999A43868037A89488452A00009735A15210000A53806452A11118037A53801698E43863169100704060702040102030103060209060805090805",
"09A10176779A34868279A63437716A99994155A63430500A34860000A10171406A00004155E26634155100102020303090905050606070708010803040504",
"09A16675773A50005773A83325773A50000000A16670000A00002886A83320000A99992886E66662886100102020909040405050601060407070808030302",
"09A70296185A40884515A09414515A42940000A00006071A88530000A99994478E46463112E779448571103050803040202050102080409080604070109070706",
"10A43309999A86597499A72165000A43305000A28867499A86592500A43300000A28862500A00002500A0000749912020303040405010507080306040810050809091001020607",
"10A46515888A50291200A06397575A81687425A55524463A17730000A16865888A88076225A00002513A9999993812070305070201010304010502080509070602090610080410",
"10A48804396A48801478A00006392A90466546A59522553A11914396A99994857A59520000A69959494A2962949412060305060201010304010704070505080208040903101009",
"10A25474570A16166133A62753127A54374570A54370000A94454931A86996254A38217369A00008932A1791999912010203010504040207040607030506030408020909100810",
"10A00006995A25904430A25900855A66250000A99991632A46986995A63859327A85547850A85544430E46981632130201030204030410010607060807090802090509040510060510",
"10A53026409A85668294A00008578A65814346A12696409A99996433A51190000A12692065A65810691E53022065130503040510010103040604091008080508070709091001020206",
"10A99994745A58033967A85242714A58030000A24865324A65322714A00002818A82426113A18370000E32963967131005061004020205030106040306020808010409090707051007",
"10A38760000A23092718A00008169A83160000A23097153A99998464A83164436A67457153E67452718E387644361405080205090402090809100101041007070406070806020103100503",
"10A36631099A20423911A00000000A82571099A20428500A99999856A82575689A66328500E66323911E366356891410050508020509040209080910010104100707040607080603020103",
"10A73929797A99996506A32668429A26361664A99991664A00009797A63030000A26366506E32663734E68198060130806100802010103030610020804030902050407050709050709",
"10A00007120A10935313A99996759A14849577A54623723A48450000A82347300A63309577A89634915E4845531312020105020610100107100506090504010708040803070903",
"10A18301830A50000000A81691830A99995000A00005000A18308169A50009999A81698169E50006340E5000366112010202030310100101050506060909080807070608040403",
"10A62500000A25002165A76109666A99992165A25006783A40838511A99996491A00009666E74798226E4083374912020110010401070406100502080506080905070903060703",
"10A73929796A99996506A32668429A26361663A99991663A00009796A63030000A26366506E32663734E6819805912080610080201010303061002080403090205040705070905",
"11A11600000A46320000A57051522A28912486A00761522A28147513A00008476A10849999A45569999A56288476A284451212002010302070608070910100609080405050104030511041101110211110311060811071111091110",
"12A86832482A65403688A00002482A21983688A43972482A43970000A21986311A00007446A43977446A65406311A43979999A8683744630030808111112120101060306060504020209090407050510100701021012091107080403010501101202120911101107080908040307030506020604",
"11A55476610A55471550A30757567A91868524A65015060A24036610A99997020A32150000A24039664A00004877A00001550130506020101030401070405020705080210061110081109060309",
"11A99994719A35190000A50464719A64810000A90277646A00004838A09727765A41667765A60187646A74542927A25462927131003041002111103040206071106030808070905030910010105",
"11A54717869A10769779A91039894A00005034A21977869A99998274A65021620A65026365A05821505A19730000E547130661405020805010203010603060801110807110709111007100910040504",
"11A63167961A37420000A00005471A63165546A43862037A09653395A68423395A00008150A18139999A47959999E342139991406030506021111030411070405020705030808090910100106070401",
"11A50227868A00000000A06467868A63146852A06463611A63142407A88964074A18652407A30859999E18656852E5022361115011111050503060808100410010411060310090309010607070408020205",
"11A33586997A99992256A00007945A62567945A51370000A20545575A82195337A20541779A61486761A86960000E33583081130805110501110608030601030906070904010704070205101002",
"11A46588688A46585901A23299999A23294644A00008688A00005901A85963661A85960000A23290000E41501367E597136611405060406020401020305030107080207040904101011071108110908",
"11A74236368A00008420A80755210A12646263A46091158A53023684A20804895A53020000A61998579A22849999E46094895130704060711040111030103061105060805080901100902100402",
"11A31388599A13560000A00009949A58129999A37597499A07368599A63938949A45724300A05043100A17822600E31384849130603050611010103040107040511070510020810110909020508",
"11A00004220A00001358A24810000A50001358A74818488A24815626A24818488A74815626A99994220A99991358E50004220130201030204031104061101060706081109081009041005080705",
"11A85916567A35746567A99992562A23462655A00009594A49450000A23469594A12637033A79770000E48375123E758051231402040102031111101004030111010406090609030810070205080705",
"11A09557693A34559510A65449510A90447693A99994755A90441816A65440000A34550000A09551816A00004755E3675475512010202030304040505060607070808090910011007110311",
"11A00009999A42230000A00006825A78729999A52073492A10255079A87345449A87348517E10258517E78726930E422350791406030506021111031011071005020705090608090708041001040301",
"11A13393318A13746318A70459999A49670000A86644773A44732909A00005045A90889045A21849999E78206545E49674999130601110210110506110406040702010708100508090210030903",
"11A99995000A81698169A81691829A00005000A50009998A50000000A18301829A18308169E50006338E31703169E6830316912070408041004050802050102030106030706110109111009",
"11A49991430A25005766A99991430A49997229A00001430A25000000A74990000A74995766E74992892E49994337E2500289212050606010701030904080201110510091110100803070402",
"12A49997216A25008659A49994330A00007216A25002886A00004330A74992886A99994330A74998659A99997216A25000000A749900001405030605040202010103040609011009080707030810051107121211",
"12A74852867A74850000A44730000A95313961A80111961A56432867A99993093A21052452A00004640A53805093A24853885E5058388515061205060201011204010704050207050809120801101011110903080203",
"12A00003057A47044586A99994586A47041529A99991529A73520000A47047643A73529172A99997643A17970584A17975530E735261151406050406021203120305020402070708080909030211100101110410",
"12A40419999A55880712A00007357A17531277A55884325A17535184A90205891A90209166A34830000E81107504E41302134E41306289160603050611121203101207100708030108010507050211040406040909020211",
"12A83909999A37070000A00005869A00008652A44813000A08764391A75144695A68408652A75147390E08767390E68405999E37074391160603050602121203111207110502070510060910070908110408030401080901",
"12A67547130A27484678A78944678A27481245A78941245A31286036A53210000A99995885A00006262A08487356E31282716E570157721412021203020406110305040711070507090210061009080301080601",
"13A00008749A21667501A21669999A46659999A68308749A46657501A21662499A46652499A68301250A46650000A21660000A00001250A3501512124010201030304040505060602021313070708080909101011111212071311131013081309131213011303130413061305",
"12A98975714A74231429A49490000A24741429A98978571A00005714A00008571A24749999A74239999E49498571E24744285E7423428512120202030304041111060607070808101009090505010112",
"13A28577422A57147422A71424948A57142474A28572474A14284948A99994948A71420000A99990000A71429897A99999897A00002474A00007422160102020303040405050601060307040808090907021010111107051201131312",
"13A99994826A91595517A83512806A74203552A54942806A94380000A44703607A85380666A16353603A25602863A13885888A00001596A08320912160507030504070204010201030408030608060907111010051310121309111209",
"13A39485622A00003358A32469999A69013962A30124453A23988376A61112528A85093962A92982528A68711132A68710000A92980000E84791132160603050602010103040107040502070510130710040808090913101111120912",
"13A60776420A66072578A90957683A28148103A52614999A83206052A20806788A00005578A07342947A07340000A20809999A52610000E40781315160506020101030401020507050807090813090213091012100512071104110603",
"13A63116880A88436880A88432580A99994701A50224701A63110000A37776880A12442580A12446880A00004701A37770000A37772580A6311258015030413030501010202040513091007090512120808100507111206131106",
"13A66660962A66662887A83333849A99992887A99990962A83330000A50000000A33330962A33332887A16660000A00000962A00002887A1666384915010202030304040505060106070808090107101111121213081009130209",
"13A22073757A07045817A48844666A00000000A07048909A68573757A25832121A52145817A29129999A52148909A22071212E48847575E25834909160806130802010103030613020810031202051009120905091101071304110704",
"13A18232941A00005293A47863921A77493823A00008725A71412941A22020980A51665293A25839999A51668725A18230000E47867254E22024215161308020101030306130208100312020510091209050911010713110704080604",
"13A85754958A99992462A99997437A00004924A14072462A85750000A85759898A42717437A42712462A14077437A57289898A57280000E5728495815020103011301060207030813091311081209040510080509120610040711",
"13A00008994A36698934A00006804A18349999A55028934A36693254A54560000A18345739A73371064A73373195A36691064E55024260E36696804160103080313080213040106110402091007090612121011071205020513100806",
"13A60780000A67532108A39210000A32242108A10892108A89102108A00003963A99993963A39215201A60785201A79516296A20486296E501033451404031304020101031302050406020705080609101110120907120811",
"13A60520000A10660521A39180000A20476299A10822113A89172113A00003961A99993961A79526299E60525168E39185168E32162113E675421131412031301010305120613070508061110091004110704080905021302",
"14A22012921A22010284A00003814A43083895A26732069A05352921A44973124A67292962A64462313A99992313A84583976A71380000A92750000E74831014190603050602010103040107040502070514120814110909120709081113121413101113100408",
"14A18759999A29620000A01974012A48374140A33072038A08392993A53803184A09386433A20735732A53808661A48875732A00008025E40976433E271529932006030506021414030414070405020705080306091304071108130911120809121011131001121001",
"14A37508659A62498659A74996495A62494330A37504330A25006495A74992165A62490000A37500000A25002165A00002165A00006495A99996495A999921651701020203030404050506010607080809091004070510120610110313071411121314",
"14A52504032A47494920A31242823A25623791A06253791A31240000A00004839A25620887A68756129A74375161A93755161A68758952A99994113A743780641705070305040702040102010304080306080611130911101301100209101409121412",
"14A49995955A36928217A99993692A49992263A00008217A86945955A13032263A00004524A63070000A99990000E86942263E63073692E36924524E130359552314050201050208050708130408130213140707041401010411100904100903100603120103120912110606011104",
"14A14989134A00007637A67720000A47251181A79534409A99995591A79536772A67722362A55916772A55914409A11815591A35457953A35453228A35455591161314121411141014091405100605070609070810041303040803021101120201",
"14A00002151A10824678A74260000A21050075A57591849A38601849A29535658A38604678A57594678A64325658A85664678A99992037E29532829E6432282918130414130305050606040314071308060905101411091011121103120208070201020401",
"14A57093413A57090749A79674204A79030000A00002206A99991915A39023454A39020749A16774204A17100083E30962955E30961415E65801415E658027892002040102031414131304030108100708091111121210090708021312060403060510090511071401",
"14A00001443A00004330A25005728A60475728A50001443A25000000A75000000A99991443A99994330A85566830E25002887E75005773E60472887E5000433018010202030314140505060106050707080809071301111113141212090910100404030413",
"14A14499999A00347478A43809999A58294608A58297478A00344608A00002521A58292521A43800000A14490000A28641391E43804999E14494999E286432171713020201050312051213030107130812090810071110091106020405041406141114",
"14A19889999A45149217A66708216A88286043A70752304A13482174A00004521A12467216A70750000A44130000E29313695E56946043E40096303E4009313018131403130403050414050614070608071308071110110910050912110412021201020801",
"14A60520641A99990000A38890641A00880000A10822716A88592716A00004565A99114565A20476866A78946866E60525772E38895772E32162716E6695271615130314010103051306140705080612111011091207090810050406020204",
"15A15004047A35682933A10222610A35680000A59083989A28862199A54313197A00003461A72723050A67272258A90903461A99991848A75220440A93850440E795414082006070402020501020604030603080108050907101109131012111413141207051509151410111315",
"14A99993463A89991732A89995196A60000000A39990000A60006927A10001732A00003463A10005196A39996927E29995196E29991732E70005196E700017321401020214140404050512120707080809091111101006061313030301",
"15A14543959A34772874A10002551A34770000A57953929A28402111A53183108A00003402A71132991A65682229A93173842A92260411A99991877A73630411E84542874190607040202050102060403060308010805090710110915101315141014091311121412130705",
"15A46187999A69287999A80825999A69284000A46184000A34645999A34642000A11552000A00004000A11555999A80822000A69280000A46180000A00007999A3464999918010202030304040505060106070808090910050706101112121313070411150110141415",
"15A33335773A50006735A33333849A66665773A50002886A66663849A16662886A00003849A16666735A00005773A50000962A66660000A83330962A83334811A9999192418050603050102020404060103091001090307070808100511111212130613061413151514",
"14A24498659A00004286A50331429A26170000A75508572A99994286A74490000A50337230E75505715E24495715E74492814E26172814E42283637E6140510915081414131303110703070906110608050905030412041202100210010801",
"16A73181418A16684435A37326615A33468273A10227107A00004783A68276769A83024030A99994030A95756586A76088273A63930000A33840000A24491418A50242305A5024478330030208070908101111070910040305060602040513121413150101121415141613161516121601161608160916101607161116040316160506161602",
"15A25446903A08194678A53505998A29245772A08191396A75436903A00005998A99992565A32750226A57301396A85660000A75431207A99995508E57304678E53502829191406041401030306040214100315020510091509050907010207130608131208151211081011",
"16A70462641A70460264A90353433A51463508A66071886A88590264A49702829A29532716A32162075A00002075A13743584A26020000A99991773A06730000E22810906E853726412316030516020101030401070405020705151208151109091207090811131603131412151410111410040806130206",
"16A38483333A57733333A67351666A57730000A38480000A28861666A28865000A38486666A57736666A28868333A38489999A57739999A67358333A09625000A00006666A09628333190102020303040405050601060708080901071011111212130810091307141415151616100209",
"16A59953466A69901721A69905199A40043466A99993466A09841721A89921721A89925199A59950000A59956920A29865199A29861721A09845199A40046920A40040000A00003442190201030104010508070208030902100311041204141115121606131106120705150913161014",
"15A71629322A12851233A50830000A00003000A71620675A50839999A95106091A00006997A95103906A12858764E76162814E34588536E76167185E08895000E3458146215150202040414110505030315130707090911120606010113140808101012",
"16A40003464A59993464A69991732A59990000A40000000A30001732A30005196A40006928A59996928A69995196A89995196A99993464A89991732A10001732A00003464A1000519618020303040405050601060708080909100107021010111112121303131415151616070614",
"16A61204512A61201863A99992864A46586454A38260538A15304689A25005747A15301863A99990000A00006454A71320000A89854620E71322864E89851869E25002832E457855732308051505020501020715060810060710160601160407010413011203011211021409021412141311110913030309",
"16A21912563A23970000A00003476A39953505A26941767A05712563A44522740A81270648A55482740A99992091A63922003A61874654A99993329E89262740E66443329E5091350521060305060201010304010704050207050416070915110911161215120914151313141310141011081008",
"16A34524404A83733226A38885581A99991895A22621178A42462150A14683840A83734659A68645581A63880000A83730000A00001843A06740461E67061178E38883226E63882407190605140602161615150502140315080209080309101611100402041113051213071201071501",
"16A21141056A39430000A60560000A78861056A78864045A60565101A00001056A99991056A99994045A00004045A21144045A39435101E39432113E60562113E39432988E6056298818010202030304041414131301010704080809071010111112120606051115151616050509",
"16A89991732A99993464A69991732A59990000A40000000A30001732A10001732A00003464A10005196A89995196A40006928A59996928E69995196E30005196E59993464E400034641716151503030404050506160606070708080909141411111212131310100202010103",
"17A57140000A42850825A71430825A42852474A71432474A85720000A28563299A57143299A99992474A99990825A28564949A14282474A57144949A42855774A14285774A00003299A000049492009100503030606100805040202010103070411071308141304081114121616170712151117150509",
"16A49994173A99990759A00001897A87120000A44480000A15444316A14701043A99993083A84913984A00003510E30513367E69853225E69110901E29411897E72051897E485210911705141305041515161614130407140204070310061003080908020611091211010112",
"16A00003849A16670962A33330000A16676735A66660000A83320962A33337697A99993849A66667697A83326735E83324810E49996735E83322887E49990962E16674810E16672887161602020303141405050606131308081111101009091212070704041515010116",
"17A06651153A56331153A00007272A15759999A00009090A56332970A15754545A06652970A47249999A62989090A62987272A47244545A31490000E31493636E47246363E31499090E1575636318041605040317030507171407121512141115100909161011070812060602080113011302",
"18A69995196A89995196A99993464A89991732A69991732A59993464A59996927A69998659A89998659A99996927A40003464A30005196A40006927A59990000A40000000A30001732A10001732A00003464220102020303040405050601060708080909100107021006111112121307130514141515161116171816171812",
"18A40005196A59995196A69993464A59991732A40001732A30003464A69996928A89996928A99995196A89993464A10003464A00005196A10006928A30006928A49993464A69990000A49990000A49998609220102020303040405050601060708080909100207031011121213131406110114021504161617171514180718",
"17A99992891A49990000A99990952A00000952A83330000A16660000A83335782A00002891A66668673A33338673A16665782E33336733E16663843E66666733E66660952E33330952E833338431716021502051506160717140709141012121111131308080404060305010317011009",
"18A50003750A50001587A99990000A38055337A31250504A12503896A20424760A12501587A87493750A00005337A79570577A61940000A68744833A87491441E62590719E20422378E79572959E374046172308051605020501020716060810060710180601180407010409131713011311171409031411031514021512110212",
"18A26160872A41280000A58720000A73830872A91270872A99992383A08720872A00002383A08723893A26163893A91273893A41284765A73833893A58724765E58723021E41283021E41281744E587217442001020203030404181817170101070708080909101016161515131314141212101311110606050504",
"19A57143298A71432474A57144949A42852474A57141649A71430824A99992474A42855773A42850824A28563298A42854124A85720000A57140000A99990824A28564949A14282474A14285773A00003298A00004949220714020606121214010204090913130610041510030108030401150816181819101617151917110405010207",
"19A29138599A32545200A00009919A53629999A72535319A07138599A60138879A75947359A50524360A46493040A52393200A47120000A33172040A64782279A35650680A61060920E39992279E59512080E3595759924060319060201010304010704190207191009181016141411110918161013111716121315171512150708020909050508",
"18A83338796A16660979A00003911A33330000A00005865A99995865A66669775A66660000A16668796A83330979A33339775A99993911E50008796E83332932E16666842E50000979E16662932E8333684218081610081410121406121806041602041702031705031505091511091311071301071801",
"20A93358165A33223593A66773593A33221633A16774532A66771633A83544532A16770694A50000694A00003593A50004532A99993593A00001633A99991633A75940000A90500000A75947145A66775470A93356205E8322069424101305100204040809040609030611020813070312141420200602051103120715061614151618031907171801191701",
"21A51751924A51750189A66372528A37722565A48541396A62861924A36552075A21641999A23691509A95021396A09942641A19000000A04970000A00001509A70751509A74262150A88882603A84492037A99992037A84493924E169606792906030506020101030401070405020705211208211109091207090811131221131411131404081506161516031910171920181810151817201617",
"20A83200000A66400000A99990000A33985090A66795090A83205090A17585090A99993327A99991714A50000000A33200000A16400000A00001714A00003427A00005090A00000000A99995090A50005090E50001714E5000332721010302011002051806051706081709080309191011101211161213161415071504071804201813141920",
"21A99995173A38633013A26931504A22882200A92786421A22880000A04432955A60151579A55582231A55580149A76552418A72793029A00001158A09390000A80304259A84673649A80305700A99993649E94724259E08932200E4223237430200703200604040702042102030621030821100909021209111208101108201313071314140612151116151717161519161818191705050101191801",
"21A93358655A33224083A66774083A33222123A16785022A66772123A83545022A16781184A49050000A00004083A50005022A99994083A00002123A99992123A75940490A90500490A75947635A66775961A93356696E83221184E500011842610130510020404082104062103061102081307031214142020060205110312071506161415161803190717180119170102092009",
"22A33333849A33335773A50006735A66665773A66663849A50002886A83336735A99995773A99993849A83332886A16672886A00003849A00005773A16676735A16678659A33339622A50008659A83338659A83330962A66660000A50000962A16670962280102020303040405050601060708080909100407051011121213131401110214151616171703141507181920202121061019112221221718",
"22A30772664A46152664A53841332A46150000A30770000A23081332A53843997A69223997A76912664A69221332A76915329A92305329A99993997A92302664A46155329A53846661A69226661A23083997A30775329A07691332A00002664A0769399727010202030304040505060106070808090910020703101112121313140811091407151516161711170118181915190620202121221822",
"22A30008660A10008660A00006928A10005196A00003464A10001732A69998660A89998660A99996928A89995196A99993464A89991732A69991732A60000000A40000000A30001732E40006928E30005196E40003464E60003464E69995196E6000692827222121202019191818172217070808090910220721101011111212132013141515161619131406050504041816060302020101170403",
"24A16673849A16675773A33336735A50005773A50003849A33332886A66666735A83325773A83323849A66662886A66660962A50000000A33330962A33338659A50009621A66668659A99998659A99996735A00006735A00008659A00000962A00002886A99992886A99990962310102020303040405050601060708080909100407051011121213130610110314141515160716171818080219192021220122232409232113112417161420",
"24A31693170A31691056A49990000A68301056A68303170A89433170A99995000A89436830A68306830A68308943A49999999A31698943A31696830A10566830A00005000A10563170A86600000A99991340A99998660A86609999A13399999A00008660A00001340A13390000280102020303040405050606070708080909101011111212131314141515161601041706181817081910202019122114222221162302242423",
"25A68361042A10676736A10673126A32261042A89323158A68368895A31618895A89326811A14140000A99751377A86340000A00001302A50240000A00004938A99754987A49499999A86349925A13409925A00008548A99758598A68366811A32263126A31616736A68363158A494949873224252325222521250124022322030422052406210723082109041005110112031304140315081606170618071902200820171505071601130214120918191110",
"24A76718683A87797576A96755665A96754023A89382063A77440869A58510000A41080000A59929999A38329999A20659069A06467650A00005731A00003835A08841987A21650706E82286173E63078094E35928094E16716173E16713458E35921537E63071537E8228345824100909181019121111191220141313201421161515211622070808220723050606230524030404240317010202170118",
"26A99991663A82650000A66210000A99990000A33330000A16890000A99993039A00001605A00003268A00006537A00008200A16899804A33339804A99996422A49770000A66669804A83099804A99998142A99999804A49779804A99994759A00009804A00004931A00000000E49776651E4977321127040102040302150326150515060524060824090823091023111022111222131220132520162017161917181914182114072101072526",
"28A49997302A49992697A73025000A26975000A20233831A38327976A61687976A31576808A79763831A79766167A68086841A38322023A61682023A68423191A31573191A06743831A00005000A06746167A38320674A49990000A61680674A93253831A99995000A93256167A61689324A49999998A38329324A202361673204050106010706080309031010111107021202131314140912151505051616171718121919202021211309222223232424100725252626272706042828182808",
"28A26160872A41280000A58720000A73830872A91270872A99995871A08720872A08722616A99994127A91272616A08727383A00005871A00004127A08729127A26169127A91277383A91279127A73839127A58729999A41289999E58728255E41288255E82555871E82554127E17445871E17444127E41281744E587217443201020203030404282827270101070708082626252511111212131308111414151522222121181819192020151817171616232324241010090906061610050504",
"30A44366431A33185790A22067722A55474499A55475790A44363849A44367722A33184499A22142574A78864569A33331924A67136525A88962558A44440000A33330649A66663849A22143849A78635797A55630649A99991924A00006423A11115774A11114499A88800015A99990649A66660000A77770649A00087746A89043888A2214647033020103070405050130020604070108020917291010181109120513291415151116041723181219142013280321282221232224252520262727240806300316102619",
"36A42856185A57146185A64284948A57143711A42853711A35714948A64282474A57141237A42851237A35712474A78564948A85713711A78562474A64287422A78567422A85716185A35717422A42858659A57148659A21434948A14296185A21437422A21432474A14293711A35710000A14291237A00003711A00006185A14298659A35719896A64289896A85718659A99996185A99993711A85711237A6428000048010202030304040505060106070808090910040705100311111212130713021414151516111601171718181914190620202121221722102323242024262309252821242730182229321519313412163336081335262536353433323130292827",
"42A17323500A17326499A08665999A17327499A17322500A08664000A08665000A08662000A00002500A00003500A00006499A00007499A08667999A43302000A34641500A51961500A25982000A43307999A34648499A51968499A25987999A69286499A77935999A69287499A69283500A77934000A69282500A60622000A77935000A60627999A51960500A43300000A34640500A86593500A86592500A77932000A77937999A86597499A86596499A34649499A43309999A5196949948020302040105010603070706050808090910061011121213130403111415141615171705181918201921210422232224252625272728281626292923243030203132323333151631343535363627263424373738383923391940404141422042",
"60A21159049A17778821A32689182A51019771A54399999A39459638A05577213A35427935A65078888A71849343A47678759A11047581A85878461A82498233A95786811A90306443A08305967A55447753A98515564A63245965A23246328A67698577A37587292A06883953A19256703A01416446A47485643A17834689A00004435A80685310A77586929A31054538A35284033A08213556A02733187A12641538A20943069A51044356A60942706A16031765A33451110A47510228A43082245A91646046A50851240A67475461A75283670A30831422A79273295A87472418A26680656A44130000A63102064A65830816A59060361A90224032A97103553A77360950A92952786A8075117890010201060112020302070304030804050409050605100611071707260818082109140918101310221122112312251226131413151416151915441619163017211724182019572030203821322231232523272435243725282629273327462833283429342935304931443146323732383343344035363640365137483839394539494041414241434252425443534456454845554647475347564851495050575058515252555354546055585659575958605960",
};
#define NBONDTYPES 11
const int bondValence[NBONDTYPES] = {1,2,3,1,1,0,0,0,1,1,1};
const string fsastart="{SA:";
const string fsbstart="{SB:";
string intToStr(int k)
{
char temp[16];
sprintf(temp,"%d",k);
string line=temp;
return line;
};
//-------------------------------------------------------------------
class Rect
{
public:
double left,top,right,bottom;
};
class Point
{
public:
double x,y;
};
//-------------------------------------------------------------------
class TSingleAtom
{
public:
short int na; /*Atom position in the Periodic Table (nucley charge)*/
short int nv; /*Current atom's valence*/
short int nc; /*-9..+9 atom's charge*/
short int iz; /*Isotope difference between round(AtomMass)*/
double rx; /*Internal X-coordinate representation*/
double ry; /*Internal Y-coordinate representation*/
short int rl; /*radical label*/
short int nb; /*Number of neightboring atoms*/
short int currvalence;
/*Valence, excluding non-defined hydrogen
atoms. Equal sum of valences for each bond type.*/
short int special;
/*Special=0 - no special definition
=1 - no other atoms, except explicitly defined, can
be connected with the atom (query structure)*/
short int ac[CONNMAX];
/*atom's numbers in array ATOM, which are
connected with the atom selected*/
short int astereo; /*=0 - no stereo, =1 - R, = 2 -S, = 3 - unknown*/
string anum;
int enumerator;
int fragIndex;
TSingleAtom()
{
na=6;
nv=hVal[na];
nc=0;
iz=0;
nb=0;
rl=0;
currvalence=0;
special=0;
astereo=0;
enumerator=0;
fragIndex=0;
};
TSingleAtom * clone();
int encoder();
int chargeConversion();
int valencyConversion();
int allAtAtom();
void atomCopy(TSingleAtom * source);
static bool atomEquivalent(TSingleAtom * structure, TSingleAtom * query,
int nHStr, int nHQuery, bool chargeSensitivity, bool isotopeSensitivity);
static int chargeDeltaValency(int atomNo);
};
class TSingleBond
{
public:
short int tb;
/*Bond type:
1 - single
2 - double
3 - triple
4 - aromathic (query)
5 - single/double (query)
6 - coordinational
7 - not used
8 - any (query)
9 - up
10 - down
11 - either*/
short int at[2]; /*Bond definition-atoms number in array ATOM*/
short int db; /*Ring/Chain conditions*/
short int bstereo; /* =0 - no, =1 - E , = 2 - Z, =3 E/Z*/
short int special;
int enumerator;
/*=1 - Chain (query)
=2 - Ring (query)
=3 - CIS/TRANS
=4 - CIS/TRANS+Chain;
=5 - CIS/TRANS+Ring;*/
TSingleBond * clone();
int bondConversion();
void bondCopy(TSingleBond * source);
static bool bondEquivalent(TSingleBond * sBond, TSingleBond * qBond);
int getValence();
};
//-------------------------------------------------------------------
TSingleAtom * TSingleAtom::clone()
{
TSingleAtom * result;
result=new TSingleAtom();
result->astereo=this->astereo;
for (int i=0; iac[i]=this->ac[i];
result->currvalence=this->currvalence;
result->iz=this->iz;
result->na=this->na;
result->nb=this->nb;
result->nc=this->nc;
result->nv=this->nv;
result->rl=this->rl;
result->rx=this->rx;
result->ry=this->ry;
result->special=this->special;
result->enumerator=this->enumerator;
result->fragIndex=this->fragIndex;
result->anum=this->anum;
return result;
};
int TSingleAtom::chargeDeltaValency(int atomNo)
{
int result=-1;
if (atomNo < NELEMMCDL) result=chargeVal[atomNo];
return result;
};
int TSingleAtom::encoder()
{
// For given atom's number ATN in array ATOM returns a number from 1 to 32.
// Atoms with related properties have the same number. It is required to reduce
// the possible number of fragments in structure}
int i;
for (i=0; i0
// 0 - charge=0
if (nc < 0) return 2;
if (nc > 0) return 1;
return 0;
};
int TSingleAtom::valencyConversion()
{
//for atom's number ATN in array ATOM returns some connected with valency value:
// =2-Valence of ATN is less, then usual
// =1-Valence of ATN is more, then usual
// =0-usual valency
int k1,k2;
int result=0;
//Default hydrogen
k1=nv;
k1=k1-currvalence-abs(nc)-rl;
if (k1<0) k1=0;
k2=hVal[na];
k2=k2-currvalence-abs(nc)-rl;
if (k2<0) k2=0;
if (k1 == k2) result=0;
else if (k1 < k2) result=1;
else result=2;
return result;
};
int TSingleAtom::allAtAtom()
{
//Define a digital representation of atom, they include:
// a) Position of atom in the Periodic System
// b) Its charge
// c) Its valency}
int b1,b2,b3,w;
b1=encoder();
b2=chargeConversion();
b3=valencyConversion();
w=b3;
w=w << 2;
w=w+b2;
w=w << 5;
w=w+b1;
if (rl != 0) w= ~w;
return w;
};
void TSingleAtom::atomCopy(TSingleAtom * source)
{
this->astereo=source->astereo;
for (int i=0; iac[i]=source->ac[i];
this->currvalence=source->currvalence;
this->iz=source->iz;
this->na=source->na;
this->nb=source->nb;
this->nc=source->nc;
this->nv=source->nv;
this->rl=source->rl;
this->rx=source->rx;
this->ry=source->ry;
this->special=source->special;
};
bool TSingleAtom::atomEquivalent(TSingleAtom * structure, TSingleAtom * query,
int nHStr, int nHQuery, bool chargeSensitivity, bool isotopeSensitivity)
{
bool result=false;
int i,j,k;
if ((structure == NULL) || (query == NULL)) return result;
i=nHQuery;
if (i>0) //if explicitly defined H is accociated with query atom
{
j=structure->nv;
k=abs(structure->nc);
if (k>9) k=k-9;
j=j-structure->currvalence-k;
if (j<0) j=0;
j=j+nHStr;
if (i>j) return result;
//on corresponding structure atom must be at least the same number of H}
}
if (((structure->nc != query->nc) && chargeSensitivity)
|| ((structure->rl != query->rl) && chargeSensitivity)
|| ((structure->iz != query->iz) && isotopeSensitivity)) return result;
//non-equivalency of Charge and Isotop is case of exact matching of these attributes
i=query->special; //'NO OTHER' attribute on query
if (i == 1) if ((structure->nb-nHStr) != query->nb) return result;
//'NO OTHER' means, that number of neighbour in query must be the same as in structure
//Checking for equivalent position in the Periodic Table
if (structure->na == query->na) result=true;
else
{
if (query->na == METALL_ATOM) //Metall checking
{
for (i=0; ina == metals[i])
{
result=true;
break;
}
}
if (query->na == HALOGEN_ATOM) //Halogen checking
{
for (i=0; ina == halogens[i])
{
result=true;
break;
}
}
if (query->na == HETERO_ATOM) //Hetero checking
{
for (i=0; ina == hetero[i])
{
result=true;
break;
}
}
if (query->na == ANY_ATOM) result=true; //Any atom
}
return result;
};
//---------------- TSingleBond methods ----------------------
TSingleBond * TSingleBond::clone()
{
TSingleBond * result;
result=new TSingleBond();
result->at[0]=this->at[0];
result->at[1]=this->at[1];
result->bstereo=this->bstereo;
result->db=this->db;
result->special=this->special;
result->tb=this->tb;
result->enumerator=this->enumerator;
return result;
};
int TSingleBond::getValence()
{
int result=0;
if (this->tb <=NBONDTYPES) result=bondValence[this->tb-1];
return result;
};
bool TSingleBond::bondEquivalent(TSingleBond * sBond, TSingleBond * qBond)
{
//for bond's number BONDNUMBER in structure (BOND) and for query bond's number
//QBONDNUMBER (QBOND) determines, if they may be accociated one with other.
//QBC-array, for each query bond contains explicitly defined cyclic conditions:
// 0-no cyclic condition is implemented
// 1-query bond and corresponding structure bond must be a Chain
// 2-query bond and corresponding structure bond must be a Ring
//Function has 'TRUE' value if bonds can be matched, FALSE otherwise
bool test1;
int bT,qBT,bD,qBD;
bool result=false;
bT=sBond->tb;
qBT=qBond->tb;
bD=sBond->db;
qBD=qBond->db;
if (sBond->special>=3) sBond->special=sBond->special-3;
if (qBond->special>=3) qBond->special=qBond->special-3;
if (((qBond->special==1) && (bD>1)) || ((qBond->special==2) && (bD<2))) return result;
//Explicitly defined cyclic conditions are violated
if ((qBD>1) && (bD<2)) return result;
//Implicitly defined cyclic conditions are violated}
if (qBT==ANY_BOND) //Any bond in query
{
result=true;
return result;
};
if ((qBT==4) || (qBD==2) || (qBD==3)) //Aromatic bond
{
result=(bD==2) || (bD==3) || (bT==4);
return result;
};
if ((bD==2) || (bD==3))
{
//non-Aromatic in query, but Aromatic in structure
result=false;
return result;
};
test1=false;
if ((qBT==5) && ((bT==1) || (bT==2) || (bT==5))) test1=true;
//SINGLE/DOUBLE query bond
if (bT==qBT) test1=true;
//Type of bonds in structure and in query are equivalent}
result=test1;
return result;
};
int TSingleBond::bondConversion()
{
//generate a code for bond's nuber BNB in array BOND. It is took into consi-
//deration bond type and cycle size
int b1,b2;
if (tb > 4) b1=0;
else b1=tb;
b2=7; //for other Switch value
switch (db)
{
case 0 :
b2=5;
break;
case 1 :
b2=0;
break;
case 2 :
b1=4;
b2=1;
break;
case 3 :
b1=4;
b2=2;
break;
case 4 :
b2=3;
break;
case 5 :
b2=4;
break;
case 6 :
b2=6;
break;
};
b2=b2 << 2;
b2=b2+b1;
return b2;
};
void TSingleBond::bondCopy(TSingleBond * source)
{
this->at[0]=source->at[0];
this->at[1]=source->at[1];
this->bstereo=source->bstereo;
this->db=source->db;
this->special=source->special;
this->tb=source->tb;
};
//******************************************************************
// TSimpleMolecule
//------------------------------------------------------------------
class TSimpleMolecule
{
protected:
std::vector fAtom;
std::vector fBond;
public:
std::ostream * refofs;
virtual ~TSimpleMolecule()
{
clear();
};
TSimpleMolecule()
{
refofs=NULL;
};
int nAtoms();
int nBonds();
TSingleAtom * getAtom(int index);
TSingleBond * getBond(int index);
void defineAtomConn();
void defineBondConn(neigbourlist & bondConnection);
void newB(neigbourlist & bk, int bnum, int anum, int & total, int * e, int * e1);
void singleVawe(neigbourlist & bk, std::vector & alreadyDefined,
std::vector & prevBond, std::vector & prevAtom,
int & nPrev, std::vector & curBond, std::vector & curAtom);
void vaweBond(int bondN, neigbourlist & bk, int & ringSize, std::vector & bondList);
void allAboutCycles();
void redraw(const std::vectorlistAtomClean, const std::vectorlistBondClean,
int & atomClean, int & bondClean, int spn, int sCHA1, int sCHB1, bool iOPT7);
void clear();
void readOBMol(OBMol * pmol);
void readConnectionMatrix(const std::vectoriA1, const std::vectoriA2, int nAtoms, int nBonds);
void readConnectionMatrix(const std::vectoriA1, const std::vectoriA2, const std::vectorrx, const std::vectorry, int nAtoms, int nBonds);
void redrawMolecule();
void getMolfile(std::ostream & data);
bool checkOverlapped();
double averageBondLength();
void flipSmall(int cHB);
int listarSize();
bool makeFragment(int& n, std::vector& list, int aT, int aTEx);
void moleculeCopy(TSimpleMolecule & source);
int correctOverlapped();
void normalizeCoordinates(double aveBL);
void makeEquivalentList(std::vector& equivalenceList, bool isTopologyOnly);
void bondEnlarge(int bN);
void deleteAtom(int index);
void deleteBond(int index);
void addAtom(TSingleAtom * sa);
void addAtom(int na, int charge, double rx, double ry);
void addBond(TSingleBond * sb);
void addBond(int tb, int at1, int at2);
void setCoordinatesString(string value);
void unitVector(int aN, double& xV, double& yV);
void bondUnitVector(int bn, double& xv, double& yv);
double bondLength(int index);
int singleAtomicDescriptor(int aNumber,int bNumber, bool useEnumerator);
int hasOverlapped(double delta, bool findFirst);
int getNH(int atomNo);
private:
bool aromatic(int cycleSize, const std::vector bondList, std::vector& arom);
void twoAtomUnitVector(int na1, int na2, double & xv, double & yv, const std::vectoratomDefine);
void defC(int& currNumDef, int baseCycle, int atomClean, std::vector& cycleDefine,
std::vector& atomDefine, std::vector& atomCycle, std::vector& cycleAddress,
std::vector& cycleSize, std::vector& dsATN, std::vector& dsTP,
std::vector& dsSC, std::vector& dsNA1, std::vector& dsNA2);
void defA(int& currNumDef, int atomClean, int sPN, int baseCycle, std::vector& atomDefine, const std::vector listAtomClean,
std::vector& cycleDefine, std::vector& cycleSize, std::vector& cycleAddress, std::vector& atomCycle,
std::vector& dsATN, std::vector& dsTP, std::vector& dsNA1, std::vector& dsNA2);
void canonizeCycle(int ringSize, std::vector & bondList);
//Chain rotate members
double atomDistanceMetric(int an);
bool bondsOverlapped(int bN1, int bN2, double delta);
int fragmentSecond(int sphere, int att, int secAt, const std::vector a,
const std::vector b, const neigbourlist bk, std::vector& wSphere);
bool threeBondResolve(int an, int bondExcluded, double& xv, double& yv, neigbourlist* bkExt);
bool unitVectorCoincident(int aN, double xV, double yV);
};
int TSimpleMolecule::getNH(int atomNo)
{
int result=0;
TSingleAtom * atom;
int i,n;
if (atomNo >= nAtoms()) return result;
atom=getAtom(atomNo);
result=atom->nv;
result=result-(atom->currvalence)+(atom->nc*TSingleAtom::chargeDeltaValency(atom->na))-(atom->rl);
if (result < 0) result=0;
if (atom->nb > 0) for (i=0; inb; i++)
{
n=atom->ac[i];
if (getAtom(n)->na == 1) result=result+1;
};
return result;
};
int TSimpleMolecule::singleAtomicDescriptor(int aNumber,int bNumber, bool useEnumerator)
{
//Bond BNumber has to have type=9 or 10
int result=0;
int an [4];
int j,m,k;
double x[3];
double y[3];
double r,r1,r2;
bool testBad;
double tn [2];
bool rsn;
bool isInvert;
if ((getAtom(aNumber)->nb < 3) || (getAtom(aNumber)->nb > 4)) return result;
for (j=0; jnb; j++) an[j]=getAtom(aNumber)->ac[j];
if (useEnumerator)
{
//fragIndex as main base
for (j=0; j<(getAtom(aNumber)->nb-1); j++) for (m=j+1; mnb; m++)
if (getAtom(an[j])->fragIndex > getAtom(an[m])->fragIndex)
{
k=an[j];
an[j]=an[m];
an[m]=k;
};
}
else
{
for (j=0; j<(getAtom(aNumber)->nb-1); j++) for (m=j+1; mnb; m++)
if (an[j] > an[m])
{
k=an[j];
an[j]=an[m];
an[m]=k;
};
};
// return 1;
for (j=0; j<3; j++)
{
k=an[j];
x[j]=getAtom(k)->rx-getAtom(aNumber)->rx;
y[j]=getAtom(k)->ry-getAtom(aNumber)->ry;
};
isInvert=true;
if (getAtom(aNumber)->nb == 4) if (getBond(bNumber)->at[1] != an[3])
{
isInvert=false;
for (j=0; j<3; j++) if (an[j] == getBond(bNumber)->at[1])
{
k=an[3];
x[j]=getAtom(k)->rx-getAtom(aNumber)->rx;
y[j]=getAtom(k)->ry-getAtom(aNumber)->ry;
};
};
testBad=false;
for (j=0; j<3; j++)
{
r=sqrt(x[j]*x[j]+y[j]*y[j]);
if (r == 0) testBad=true;
else
{
x[j]=x[j]/r;
y[j]=y[j]/r;
};
};
// return 1;
if (! testBad)
{
for (j=0; j<2; j++) //determination of the sign of rotation
{
r1=x[0]*y[j+1]-y[0]*x[j+1]; //Sin
r2=x[0]*x[j+1]+y[0]*y[j+1]; //Cos
if (r1 < 0) r2=-2-r2; // 0 degress = +1; Pi/2 degrees = 0; Pi degrees = -1; 3*Pi/2 degrees = -2; 2*Pi degrees = -3
tn[j]=r2;
};
rsn=( tn[0] > tn[1]);
//return 1;
//Analizing cases....
if (getBond(bNumber)->tb == 10) rsn=! rsn;
if (getAtom(aNumber)->nb == 4) if (isInvert) rsn=! rsn;
if (tn[0] != tn[1])
{
if (rsn) result=1;
else result=2;
};
};
return result;
};
void TSimpleMolecule::bondUnitVector(int bn, double& xv, double& yv)
{
//for bon's number BN in the structure, described by ATOM, BOND, CONN calculates
//the unit vector (Xv,Yv on output). The vector is best direction to add new fra-
//gment to current structure. The procedure is used by TEMPLATE and MAKEPOLI}
double si,r1,r2,r3,s1,s2,s3,s4,x1,y1,y2;
int na1,na2,i;
na1=getBond(bn)->at[0];
na2=getBond(bn)->at[1];
s1=getAtom(na1)->rx;
s2=getAtom(na1)->ry;
s3=getAtom(na2)->rx;
s4=getAtom(na2)->ry;
r1=s1-s3;
r2=s2-s4;
r3=sqrt(r1*r1+r2*r2);
r1=r1/r3; //COS
r2=r2/r3; //SIN
si=0;
for (i=0; inb; i++) if (getAtom(na1)->ac[i] != na2)
{
x1=getAtom(getAtom(na1)->ac[i])->rx-s1;
y1=getAtom(getAtom(na1)->ac[i])->ry-s2;
y2=x1*r2-y1*r1;
if (y2 != 0) si=si+y2/abs(y2);
}
for (i=0; inb; i++) if (getAtom(na2)->ac[i] != na1)
{
x1=getAtom(getAtom(na2)->ac[i])->rx-s3;
y1=getAtom(getAtom(na2)->ac[i])->ry-s4;
y2=x1*r2-y1*r1;
if (y2 != 0) si=si+y2/abs(y2);
}
if (si != 0) si=si/abs(si);
else si=1;
xv=-r2*si;
yv=r1*si;
}
bool TSimpleMolecule::threeBondResolve(int an, int bondExcluded, double& xv, double& yv, neigbourlist* bkExt)
{
//Addition from 16 April 2006
int bondNoList [3];
bool result=false;
double centerX[3];
double centerY[3];
int nBondNo;
neigbourlist* bk;
std::vectorbondList(listarSize());
std::vector* blStore=NULL;
bool testBad,testOK;
int m,j,n1,n2,n,k;
int rs;
double dist,x,y,minDist;
int i;
bool test;
int at;
double r1,r2,s1,s3;
if (bkExt != NULL) bk=bkExt;
else
{
bk=(neigbourlist *)malloc((CONNMAX+1)*NBONDSMAX*4);
defineBondConn(*bk);
};
nBondNo=0;
testBad=false;
testOK=true;
for (i=0; i<(*bk)[an].nb; i++)
{
n=(*bk)[an].adjusted[i];
if (n != bondExcluded)
{
vaweBond(n,*bk,rs,bondList);
if (rs > 0)
{
//I have to analize bondList to determine second cycle to exclude adamanthane
if (blStore == NULL)
{
//Save
blStore= new std::vector(rs);
for (j=0; jsize(); j++) (*blStore)[j]=bondList[j];
}
else
{
m=0;
for (j=0; jsize(); j++)
{
test=false;
for (k=0; k 1) && (m < blStore->size()))
{
testOK=false;
};
};
//center determination
centerX[nBondNo]=0;
centerY[nBondNo]=0;
for (j=0; jat[0];
n2=getBond(m)->at[1];
centerX[nBondNo]=centerX[nBondNo]+getAtom(n1)->rx+getAtom(n2)->rx;
centerY[nBondNo]=centerY[nBondNo]+getAtom(n1)->ry+getAtom(n2)->ry;
};
centerX[nBondNo]=centerX[nBondNo]/(2*rs);
centerY[nBondNo]=centerY[nBondNo]/(2*rs);
bondNoList[nBondNo]=n;
nBondNo++;
};
};// else testBad:=true;
if ((nBondNo == 3) || (testBad)) break;
};
if (nBondNo < 2) testBad=true;
if ((! testBad) && testOK)
{
dist=0;
if (nBondNo == 2)
{
//single bond, attached to ring. Re-definition center....
x=0;
y=0;
for (i=0; irx;
y=y+getAtom(i)->ry;
};
x=x/nAtoms();
y=y/nAtoms();
for (i=0; iat[0];
if (at == an) at=getBond(bondNoList[i])->at[1];
r1=getAtom(at)->rx-getAtom(an)->rx;
r2=getAtom(at)->ry-getAtom(an)->ry;
s1=sqrt(r1*r1+r2*r2);
if (s1 == 0) testBad=true;
else
{
r1=r1/s1;
r2=r2/s1;
x=-r1;
y=-r2;
minDist=1000000000;
for (j=0; jrx-centerX[j]);
r2=(y*s1+getAtom(an)->ry-centerY[j]);
s3=sqrt(r1*r1+r2*r2);
if (s3 < minDist) minDist=s3;
};
if (minDist > dist)
{
dist=minDist;
xv=x;
yv=y;
};
};
};
if (! testBad) result=true;
};
//end addition from 16 April 2006
if (bkExt == NULL) free(bk);
if (blStore != NULL) delete(blStore);
return result;
};
bool TSimpleMolecule::unitVectorCoincident(int aN, double xV, double yV)
{
bool result=false;
int i, aT;
double r1,r2,s1;
for (i=0; inb; i++)
{
aT=getAtom(aN)->ac[i];
r1=getAtom(aT)->rx-getAtom(aN)->rx;
r2=getAtom(aT)->ry-getAtom(aN)->ry;
s1=sqrt(r1*r1+r2*r2);
if (s1 > 0.00001)
{
r1=r1/s1;
r2=r2/s1;
if ((abs(r1-xV) < 0.1) && (abs(r2-yV) < 0.1)) result=true;
};
if (result) break;
};
return result;
};
void TSimpleMolecule::unitVector(int aN, double& xV, double& yV)
{
//For atom's number AN in the array ATOM (the same structure is described with
//bond's array BOND and bond-connection matrix invariants CONN) unit vector
//is calculated (XV, YV) on output. Unit vector shows the best direction to
//make new bond}
double sc[4] = {0,1/2,1.7320508/2,1};
double cc[4] = {1,1.7320508/2,1/2,0};
double sQ3=sqrt(3.0)/2.0;
double si,r1,r2,r3,r4,s1,s2,s3,s4,fi;
double xm[3]; //Initial dimensions 1..3
double ym[3]; //Initial dimensions 1..3
int i,i1,i2;
int nB1,aT,aT1;
bool mK[CONNMAX];
bool test;
nB1=1;
if (getAtom(aN)->nb == 0)
{
xV=1;
yV=0; //if no atoms connected-horizontal unit vector
return;
}
else if (getAtom(aN)->nb == 1) //single atom connected-start calculations}
{
aT=getAtom(aN)->ac[0];
r1=getAtom(aT)->rx-getAtom(aN)->rx;
r2=getAtom(aT)->ry-getAtom(aN)->ry;
s1=sqrt(r1*r1+r2*r2);
if (s1 == 0)
{
xV=0.3826834;
yV=-0.9238795;
return;
}
r1=r1/s1;
r2=r2/s1;
nB1=getAtom(aT)->nb;
si=1;
if (nB1 > 1)
{
aT1=getAtom(aT)->ac[0];
if (aT1 == aN) aT1=getAtom(aT)->ac[1];
r3=getAtom(aT1)->rx-getAtom(aN)->rx;
r4=getAtom(aT1)->ry-getAtom(aN)->ry;
s2=sqrt(r3*r3+r4*r4);
if (s2 == 0) s2=1;
r3=r3/s2;
r4=r4/s2;
si=r2*r3-r4*r1;
if (si != 0) si=si/abs(si);
else si=1;
}
s3=sqrt(3.0)/2.0;
s4=-0.5;
xV=r1*s4-r2*si*s3; //single atom connected-unit vector at 2Pi/3 angle
yV=r2*s4+r1*si*s3;
}
else //multiply connection case
{
xV=0;
yV=0;
for (i=0; inb; i++) mK[i]=true;
if (getAtom(aN)->nb == 3)
{
//three-bond connection-search for projec. of tetrahedron
if (threeBondResolve(aN,-1,xV,yV,NULL))
{
return;
};
for (i=0; i<3; i++)
{
aT=getAtom(aN)->ac[i];
xm[i]=getAtom(aT)->rx-getAtom(aN)->rx;
ym[i]=getAtom(aT)->ry-getAtom(aN)->ry;
r1=sqrt(xm[i]*xm[i]+ym[i]*ym[i]);
xm[i]=xm[i]/r1;
ym[i]=ym[i]/r1;
}
i=0;
do //Search for bond, which make 30 degree angle with another
{
i1=1;
i2=2;
switch (i)
{
case 0:
{
i1=1;
i2=2;
break;
}
case 1:
{
i1=0;
i2=2;
break;
}
case 2: //Else value - only three
{
i1=0;
i2=1;
break;
}
}
s1=xm[i1]*xm[i2]+ym[i1]*ym[i2];
s2=xm[i]*xm[i1]+ym[i]*ym[i1];
s3=xm[i]*xm[i2]+ym[i]*ym[i2];
test=false;
if (abs(s1+0.5) < 0.05) //two bonds form 120 degrees angle
{
test=(abs(s2-sQ3)<0.05) || (abs(s3-sQ3)<0.05);
if (! test) test=((abs(s2) < 0.05) && (abs(s3+sQ3)<0.05))
|| ((abs(s3)<0.05) && (abs(s2+sQ3)<0.05));
}
i++;
}
while (! (test || (i == 3)));
if (test) mK[i-1]=false; //In the original Java code without -1
}
for (i=0; inb; i++) if (mK[i])
{
aT=getAtom(aN)->ac[i];
r1=getAtom(aT)->rx-getAtom(aN)->rx;
r2=getAtom(aT)->ry-getAtom(aN)->ry;
s1=sqrt(r1*r1+r2*r2);
if (s1 < 0.05) s1=1;
r1=r1/s1;
r2=r2/s1;
xV=xV-r1;
yV=yV-r2;
}
r1=sqrt(xV*xV+yV*yV);
if (r1 > 0.05)
{
//unit vector may be calculated from current connection
xV=xV/r1;
yV=yV/r1;
}
else
{
//impossible to calculate unit vector-more definitions
if (getAtom(aN)->nb == 2) //linear existing connection-Pi/2 angle
{
aT=getAtom(aN)->ac[0];
r1=getAtom(aT)->rx-getAtom(aN)->rx;
r2=getAtom(aT)->ry-getAtom(aN)->ry;
s1=sqrt(r1*r1+r2*r2);
if (s1 < 0.05)
{
xV=0.3826834;
yV=-0.9238795;
return;
}
r1=r1/s1;
r2=r2/s1;
xV=-r2;
yV=-r1;
}
else if (getAtom(aN)->nb == 3) //3-bonds connection - projection of tetrahedrone is calculated
{
//Which of bonds has the horizontal direction
r3=100000;
for (i=0; i<3; i++)
{
aT=getAtom(aN)->ac[i];
r1=getAtom(aT)->rx-getAtom(aN)->rx;
r2=getAtom(aT)->ry-getAtom(aN)->ry;
s1=sqrt(r1*r1+r2*r2);
if (s1 < 0.05)
{
xV=0.3826834;
yV=-0.9238795;
return;
}
r1=abs(r1/s1);
r2=abs(r2/s1);
if (r1 < r3)
{
r3=r1;
nB1=i;
}
if (r2 < r3)
{
r3=r2;
nB1=i;
}
}
aT=getAtom(aN)->ac[nB1]; //Horizontal or vertical bond found}
r1=getAtom(aT)->rx-getAtom(aN)->rx;
r2=getAtom(aT)->ry-getAtom(aN)->ry;
s1=sqrt(r1*r1+r2*r2);
r1=r1/s1;
r2=r2/s1;
xV= r1*cos(150*PI/180)+r2*sin(150*PI/180);
yV=-r1*sin(150*PI/180)+r2*cos(150*PI/180);
}
else
{
xV=sqrt(2.0)/2.0; //other case - Pi/4 to horizont angle
yV=-xV;
}
}
//checking if coincided xV and uV with existing bonds
if (unitVectorCoincident(aN,xV,yV))
{
fi=15*PI/180.0;
r3=cos(fi);
r4=sin(fi);
r1= xV*r3+yV*r4;
r2=-xV*r4+yV*r3;
if (unitVectorCoincident(aN,r1,r2))
{
r1=xV*r3-yV*r4;
r2=xV*r4+yV*r3;
};
if (unitVectorCoincident(aN,r1,r2))
{
fi=7.5*PI/180.0;
r3=cos(fi);
r4=sin(fi);
r1= xV*r3+yV*r4;
r2=-xV*r4+yV*r3;
if (unitVectorCoincident(aN,r1,r2))
{
r1=xV*r3-yV*r4;
r2=xV*r4+yV*r3;
};
};
xV=r1;
yV=r2;
};
};
//Correction of angles, closed to 0, 30, 60, 90 degrees to exact values
if (getAtom(aN)->nb < 6) for (i=0; i<4; i++) if ((abs(abs(xV)-sc[i])<0.04)
&& (abs(abs(yV)-cc[i]) < 0.04))
{
if (xV < 0) xV=-sc[i];
else xV=sc[i];
if (yV < 0) yV=-cc[i];
else yV=cc[i];
}
}
void TSimpleMolecule::clear()
{
for (int i=0; ina=101;
else if (s == "2") sa->na=102;
else if (s == "3") sa->na=103;
else if (s == "A") sa->na=ANY_ATOM;
else if (s == "E")
{
sa->na=ANY_ATOM;
sa->special=1;
}
else sa->na=6; //Atom.positionofAtom(s);
n=n+1;
s=value.substr(n,4);
n=n+4;
k=strtol(s.c_str(),NULL,10);
sa->rx=(double)k/10000.0;
s=value.substr(n,4);
n=n+4;
k=strtol(s.c_str(),NULL,10);
sa->ry=(double)k/10000.0;
addAtom(sa);
};
s=value.substr(n,2); //2 symbols - number of bonds
n=n+2;
kk=strtol(s.c_str(),NULL,10);
for (i=0; itb=ANY_BOND; //any bond
s=value.substr(n,2);
n=n+2;
k=strtol(s.c_str(),NULL,10);
sb->at[0]=k-1;
s=value.substr(n,2);
n=n+2;
k=strtol(s.c_str(),NULL,10);
sb->at[1]=k-1;
addBond(sb);
};
};
void TSimpleMolecule::addAtom(TSingleAtom * sa)
{
fAtom.push_back(sa);
};
void TSimpleMolecule::addAtom(int na, int charge, double rx, double ry)
{
TSingleAtom * sa;
sa=new TSingleAtom();
sa->na=na;
sa->nc=charge;
sa->rx=rx;
sa->ry=ry;
fAtom.push_back(sa);
};
void TSimpleMolecule::addBond(TSingleBond * sb)
{
fBond.push_back(sb);
};
void TSimpleMolecule::addBond(int tb, int at1, int at2)
{
TSingleBond * sb;
sb=new TSingleBond();
sb->tb=tb;
sb->at[0]=at1;
sb->at[1]=at2;
fBond.push_back(sb);
};
void TSimpleMolecule::moleculeCopy(TSimpleMolecule & source)
{
TSingleAtom * sa;
TSingleBond * sb;
clear();
for (int i=0; iclone());
};
for (int i=0; iclone());
};
if (refofs == NULL) refofs=source.refofs;
};
void TSimpleMolecule::deleteBond(int index)
{
std::vector tempBond(nBonds());
int i,n;
n=0;
//bond deletion
for (i=0; i tempAtom(nAtoms()-1);
std::vector tempBond(nBonds());
int i,n;
n=0;
//atom deletion
for (i=0; iat[0] == index) || (getBond(i)->at[1] == index))
{
delete(getBond(i));
fBond[i]=NULL;
}
else
{
if (getBond(i)->at[0] > index) getBond(i)->at[0]=getBond(i)->at[0]-1;
if (getBond(i)->at[1] > index) getBond(i)->at[1]=getBond(i)->at[1]-1;
tempBond[n]=getBond(i);
n++;
};
};
fBond.resize(n);
for (i=0; iat[0];
k2=getBond(index)->at[1];
x=getAtom(k1)->rx-getAtom(k2)->rx;
y=getAtom(k1)->ry-getAtom(k2)->ry;
result=sqrt(x*x+y*y);
return result;
};
int TSimpleMolecule::listarSize()
{
int result=10; //Minimal vector size 10
if (nAtoms() > result) result=nAtoms();
if (nBonds() > result) result=nBonds();
return result;
};
bool TSimpleMolecule::makeFragment(int& n, std::vector& list, int aT, int aTEx)
{
//Starting from atom's number AT in bond-connection matrix invariants array CONN
//the all connected atom's (through one or more bonds) numbers are inserted into
//the LIST array. Total number of such atoms is stored in N. If ATEX non-equal
//zero, than atom with this number and all other, which is connected through
//atom ATEX, don't include in LIST array. Boolean variable TEST has TRUE value
//on output if between AT and ATEX exist cyclic bond, false otherwise}
int i,j,k,l;
bool test, test1;
test=false;
if ((nAtoms() ==0 ) || (aT < 0) || (aT >= nAtoms()))
{
n=0;
list[0]=-1;;
return test;
}
n=1;
list[0]=aT;
for (i=0; inb; i++) if (getAtom(aT)->ac[i] != aTEx)
{
list[n]=getAtom(aT)->ac[i];
n++;
}
if (n == 1) return test; //exit in AT non-connected atom
k=0;
do //iterational algorithm to define all}
{
for (i=0; inb; i++)
{
test1=false;
l=getAtom(list[k])->ac[i];
if (l != aTEx)
{
for (j=0; j= 0) && (l < nAtoms()))
{
list[n]=l;
n++;
}
}
k=k+1; //atoms which are connected with AT}
}
while (kiA1, const std::vectoriA2, int nAtoms, int nBonds)
{
TSingleAtom * sa;
TSingleBond * sb;
int i;
clear();
srand(30000);
for (i=1; i<=nAtoms; i++)
{
sa=new TSingleAtom();
sa->na=6;
sa->nv=hVal[sa->na];
sa->rx=(double)rand()/1000.0;
sa->ry=(double)rand()/1000.0;
fAtom.push_back(sa);
};
for (i=0; iat[0]=iA1[i];
sb->at[1]=iA2[i];
sb->tb=1;
fBond.push_back(sb);
};
defineAtomConn();
allAboutCycles();
};
void TSimpleMolecule::readConnectionMatrix(const std::vectoriA1, const std::vectoriA2, const std::vectorrx, const std::vectorry, int nAtoms, int nBonds)
{
readConnectionMatrix(iA1,iA2,nAtoms,nBonds);
for (int i=0; irx=rx[i];
getAtom(i)->ry=ry[i];
};
};
void TSimpleMolecule::normalizeCoordinates(double aveBL)
{
int i;
double d,xMin,yMin;
if (nAtoms() == 0) return;
d=averageBondLength();
if ((d > 0) && (aveBL>0)) for (i=0; irx=getAtom(i)->rx*aveBL/d;
getAtom(i)->ry=getAtom(i)->ry*aveBL/d;
};
//Normalizing X and Y coordinates
xMin=getAtom(0)->rx;
yMin=getAtom(0)->ry;
for (i=0; irx < xMin) xMin=getAtom(i)->rx;
if (getAtom(i)->ry < yMin) yMin=getAtom(i)->ry;
};
for (i=0; i< nAtoms(); i++)
{
getAtom(i)->rx=getAtom(i)->rx-xMin+aveBL;
getAtom(i)->ry=getAtom(i)->ry-yMin+aveBL;
};
};
void TSimpleMolecule::readOBMol(OBMol * pmol)
{
TSingleAtom * sa;
TSingleBond * sb;
OBAtom * atom;
OBBond * bond;
int na,nb,i;
clear();
na=pmol->NumAtoms();
nb=pmol->NumBonds();
for (i=1; i<=na; i++)
{
atom=pmol->GetAtom(i);
sa=new TSingleAtom();
sa->na=atom->GetAtomicNum();
sa->nc=atom->GetFormalCharge();
sa->rl=atom->GetSpinMultiplicity();
sa->rx=atom->GetX();
sa->ry=atom->GetY();
fAtom.push_back(sa);
};
for (i=0; iGetBond(i);
sb=new TSingleBond();
sb->at[0]=bond->GetBeginAtomIdx()-1;
sb->at[1]=bond->GetEndAtomIdx()-1;
sb->tb=bond->GetBondOrder();
// if (bond->IsUp()) sb->tb=9;
// if (bond->IsDown()) sb->tb=10;
if (bond->IsWedge()) sb->tb=9;
if (bond->IsHash()) sb->tb=10;
fBond.push_back(sb);
};
defineAtomConn();
allAboutCycles();
};
int TSimpleMolecule::nAtoms()
{
return fAtom.size();
};
int TSimpleMolecule::nBonds()
{
return fBond.size();
};
TSingleAtom * TSimpleMolecule::getAtom(int index)
{
return (TSingleAtom *)fAtom.at(index);
};
TSingleBond * TSimpleMolecule::getBond(int index)
{
return (TSingleBond *)fBond.at(index);
};
void TSimpleMolecule::defineAtomConn()
{
//for each atom returns list of adjusted atoms in atomConnection
int i,n1, n2;
TSingleAtom * sa;
for (i=0; inb=0;
getAtom(i)->currvalence=0;
};
for (i=0; iat[0];
n2=getBond(i)->at[1];
sa=getAtom(n1);
sa->ac[sa->nb]=n2;
sa->nb++;
sa->currvalence=sa->currvalence+getBond(i)->getValence();
sa=getAtom(n2);
sa->ac[sa->nb]=n1;
sa->nb++;
sa->currvalence=sa->currvalence+getBond(i)->getValence();
};
};
void TSimpleMolecule::defineBondConn(neigbourlist & bondConnection)
{
//for each atom returns list of adjusted bonds in bondConnection
int i,n1, n2;
for (i=0; i<=nAtoms(); i++) bondConnection[i].nb=0;
for (i=0; iat[0];
n2=getBond(i)->at[1];
bondConnection[n1].adjusted[bondConnection[n1].nb]=i;
bondConnection[n1].nb++;
bondConnection[n2].adjusted[bondConnection[n2].nb]=i;
bondConnection[n2].nb++;
};
};
void TSimpleMolecule::newB(neigbourlist & bk, int bnum, int anum, int & total, int * e, int * e1)
{
/*for atom's number ANUM calculates the bond's list, which are connected
with the ANUM, excluding bond BNUM. The bond's list is inserted into array
L, TOTAL-number of components in the array. Array L1 contains atom's number
which is connected with atom ANUM through corresponding bond in the array L.*/
int n,i;
total=0;
for (i=0; iat[0] == anum) e1[total]=getBond(n)->at[1];
else e1[total]=getBond(n)->at[0];
total++;
};
};
void TSimpleMolecule::singleVawe(neigbourlist & bk, std::vector & alreadyDefined,
std::vector & prevBond, std::vector & prevAtom,
int & nPrev, std::vector & curBond, std::vector & curAtom)
{
/*
a vawe algorithm is used to calculate the neighbour sphere. PREVBOND and
PREVATOM contain on input the bond's and atom's list correspondingly, the
atom has been took into consideration at previous step. NPREV-number of
components in PREVBOND and PREVATOM on input. ALREADYDEFINED is the global
array for procedure, which calls the SINGLEVAWE. It contains for each bond's
number either zero, if the bond has not been took into consideration yet or
bond's number from previous neighbour sphere. The subroutine makes next:
1) calculates the new neighbour sphere for each bond from PREVBOND.
2) if some bonds were not defined, they are labelled in ALREADYDEFINED,
they numbers being stored into PREVBOND and PREVATOM. So, on output
the arrays contain information for new neighbour sphere.
3) On output NPrev is changed so new number of component in PREVBOND
is lighted}
*/
int e[CONNMAX];
int e1[CONNMAX];
int i,j,ncur;
int n;
ncur=0;
n=0;
for (i=0; i & bondList)
{
/*The procedure for bond's number BONDN determines, whether or not the bond
belongs to ring (RINGSIZE=0 if not ring bond and RINGSIZE=number of atoms
in the smallest ring, to which the bond is assigned). If the bond belongs
to ring, array BONDLIST contains on output the bond's numbers, which are
also assigned to the same ring */
int i,j,k,aA,i1,i2;
std::vectorpA(NBONDSMAX);
std::vectorpB(NBONDSMAX);
std::vectoroD(NBONDSMAX);
std::vectorcurBond(NBONDSMAX);
std::vectorcurAtom(NBONDSMAX);
bool test;
int nP;
for (j=0; jat[0];//pA.setValue(1,fBond.getAT(bondN,1));
aA=getBond(bondN)->at[1];//fBond.getAT(bondN,2);
k=0;
test=false;
while (! ((nP==0) || test)) //recursion
{
ringSize++;
singleVawe(bk,oD,pB,pA,nP,curBond,curAtom); //new neighbour sphere generation}
test=false;
if (nP>0) for (j=0; j i2)
{
bondList[i]=i2;
bondList[j]=i1;
};
};
}
else ringSize=0;
};
//This method must be called ONLY from AllAboutCycles
bool TSimpleMolecule::aromatic(int cycleSize, const std::vector bondList,
std::vector& arom)
{
/*for a cycle with the dimension of CYCLESIZE determines, whether or not the
cycle is aromatic. BONDLIST contains the bond's numbers, which are belongs
to the cycle. AROM-global array for the structure under study, for each bond
in the structure contains label, whether the bond is aromatic or not. On out-
put function AROMATIC contains TRUE if the ring is aromatic, FALSE otherwise
*/
bool test;
int i,j,k,n,n1,m;
int doubleDetected[11];
int atomDetected[11];
bool result=false;
if ((cycleSize<5) || (cycleSize>6)) return result;
//procedure define aromatic only for 5 or 6 membered cycles}
//Simple Test}
n=0;
for (i=0; itb == 1) && (arom[k]==0)) doubleDetected[i]=0;
else if ((getBond(k)->tb == 2) || (getBond(k)->tb == 4) || (arom[k]>0))
{
n=n+1; //number of double or aromatic bonds calculation}
doubleDetected[i]=1;
}
else return result;
};
if (cycleSize==6) //6-membered ring}
{
if (n>=3)
{
result=true;
if (n<=4) for (i=0; iat[0] == getBond(bondList[j])->at[0]) || (getBond(bondList[i])->at[0] == getBond(bondList[j])->at[1])
|| (getBond(bondList[i])->at[1] == getBond(bondList[j])->at[0]) || (getBond(bondList[i])->at[1] == getBond(bondList[j])->at[1]);
if (test) result=false;
if (! result) break;
};
if (! result) break;
};
};
return result;
};
if (n<2) return result; //5-membered ring
m=0;
for (i=0; iat[0];
m++;
atomDetected[m]=getBond(bondList[i])->at[1];
m++;
};
n=-1;
if (m>0) for (i=0; i<(m-1); i++) for (j=i+1; j=0)
{
n1=-1;
for (i=0; i<(m-1); i++) if (i != n) for (j=i+1; j=0) return result;
};
if (n < 0) //No common atoms...
{
result=m==4;
return result;
};
test=false;
i=0;
j=getAtom(atomDetected[n])->na;
for (i=0; inc < 0);
//cyclopentadienyl checking}
result=test;
return result;
};
void TSimpleMolecule::allAboutCycles()
{
/*
for each bond in the structure cyclic conditions are calculated and stored
into the BOND[I].DB variables. Possible values:
0 - chain;
1 - chain, appended to cycle;
2 - aromatic, 5-membered ring;
3 - aromatic, 6-membered ring;
4...more = non-aromatic ring size+1}
*/
std::vectorbondTested(NBONDSMAX);
std::vectorbondList(NBONDSMAX);
std::vectorar(NBONDSMAX);
std::vectorrSize(NBONDSMAX);
std::vectorar1(NBONDSMAX);
std::vectorcycleDescription(3*NBONDSMAX);
std::vectorcycleAddress(NBONDSMAX);
int i,n,j,k;
int cycleSize;
neigbourlist * bk;
bk=(neigbourlist *)malloc((1+CONNMAX)*NBONDSMAX*4);
if (nBonds() == 0)
{
free(bk);
return;
}
defineBondConn(*bk);
//initial values for MainList-number of bonds, connected to each atom and their numbers in array BOND
for (i=0; idb=0;
ar[i]=0;;
bondTested[i]=0;
};
n=0;
cycleAddress[0]=0;
for (i=0; i0) //Yes, cyclic
{
canonizeCycle(cycleSize,bondList);
n++;
cycleAddress[n]=cycleAddress[n-1]+cycleSize; //store cycle definitions
rSize[n-1]=cycleSize;
for (j=0; j0)
{
j=1;
while (j != 0)
{
j=0;
for (i=0; idb==0) || (kdb)) getBond(bondList[j])->db=k;
};
};
for (i=0; idb=2;
if ((cycleSize==6) && (getBond(bondList[j])->db != 2)) getBond(bondList[j])->db=3;
};
};
};
free(bk);
};
void TSimpleMolecule::redrawMolecule()
{
int i;
int atomClean;
int bondClean;
std::vectorlistAtomClean(nAtoms());
std::vectorlistBondClean(nBonds());
if (nAtoms()==0) return;
for (i=0; iatomDefine)
{
/*Using atom's numbers NA1 and NA2 in the array ATOMS calculates the direction
for bond between NA1 and NA2 (XV,YV on output). At this direction new
substitutor may be added with optimal place.*/
double si,r1,r2,r3,s1,s2,s3,s4,x1,y1,y2;
int i,k;
if ((getAtom(na1)->rx==getAtom(na2)->rx) && (getAtom(na1)->ry==getAtom(na2)->ry))
{
xv=1;
yv=1;
return;
};
s1=getAtom(na1)->rx;
s2=getAtom(na1)->ry;
s3=getAtom(na2)->rx;
s4=getAtom(na2)->ry;
r1=s1-s3;
r2=s2-s4;
r3=sqrt(r1*r1+r2*r2);
r1=r1/r3;
r2=r2/r3;
si=0;
for (i=0; inb; i++)
{
k=getAtom(na1)->ac[i];
if (k != na2) if (atomDefine[k] > 0)
{
x1=getAtom(k)->rx-s1;
y1=getAtom(k)->ry-s2;
y2=x1*r2-y1*r1;
if (y2 != 0) si=si+y2/abs(y2);
};
};
for (i=0; inb; i++)
{
k=getAtom(na2)->ac[i];
if (k != na1) if (atomDefine[k] > 0)
{
x1=getAtom(k)->rx-s3;
y1=getAtom(k)->ry-s4;
y2=x1*r2-y1*r1;
if (y2 != 0) si=si+y2/abs(y2);
};
};
if (si != 0) si=si/abs(si);
else si=1;
xv=-r2*si;
yv=r1*si;
};
void TSimpleMolecule::defC(int& currNumDef, int baseCycle, int atomClean, std::vector& cycleDefine,
std::vector& atomDefine, std::vector& atomCycle, std::vector& cycleAddress,
std::vector& cycleSize, std::vector& dsATN, std::vector& dsTP,
std::vector& dsSC, std::vector& dsNA1, std::vector& dsNA2)
{
//The procedure create priority list formation for cleaning of molecule. Recur-
// sive calls to the procedure are required together with DefA. After recursion
// have been finished, the DEFINESEQUENCE array will be created. The procedure
// analyze cyclic fragments
int aA,cN,maxAtDef,i,j,atDef;
bool test;
test=true;
while (test)
{
cN=-1;
if ((baseCycle==0) || (currNumDef==atomClean)) return;
maxAtDef=0;
for (i=0; i0) atDef=atDef+1;
if (atDef > maxAtDef)
{
// { search for cycles, for which maximal number of atoms were inserted in the priority list}
maxAtDef=atDef;
cN=i;
}
else if ((maxAtDef > 0) && (atDef==maxAtDef))
{
// {search for minimal cycle size}
if (cycleSize[i]=0) if (maxAtDef==cycleSize[cN])
{
cycleDefine[cN]=1;
cN=-1;
};
// {CN-number of selected cycle with max.number of atoms, already defined, or with minimal size}
if (cN>=0)
{
cycleDefine[cN]=1; //{Label, that CN-th cycle is inserted into priority list}
test=(atomDefine[atomCycle[cycleAddress[cN]]]>0) &&
(atomDefine[atomCycle[cycleAddress[cN]+cycleSize[cN]-1]]==0);
// {if first atom from cyclic fragment was inserted into list previously and last-no}
while (! test)
{
// {enumeration of atom's sequence in cyclic fragment}
aA=atomCycle[cycleAddress[cN]];
for (j=1; j0) &&
(atomDefine[atomCycle[cycleAddress[cN]+cycleSize[cN]-1]]==0);
};
// {now first atom in the cycle definition list must be inserted into the priority list early, and the last atom-no}
for (j=0; j& atomDefine, const std::vector listAtomClean,
std::vector& cycleDefine, std::vector& cycleSize, std::vector& cycleAddress, std::vector& atomCycle,
std::vector& dsATN, std::vector& dsTP, std::vector& dsNA1, std::vector& dsNA2)
{
//The procedure create priority list formation for cleaning of molecule. Recur-
// sive calls to the procedure are required together with DefC. After recursion
//have been finished, the DEFINESEQUENCE array will be created. The procedure
//analyze chain fragments
int i,j,k,rC;
if (currNumDef==atomClean) return;
for (i=0; inb > 0) for (j=0; jnb; j++)
{
k=getAtom(listAtomClean[i])->ac[j];
if (atomDefine[k]>0)
{
//if atom has a neighbour, which has already been inserted into priority
// list, then it is inserted into the priority list}
dsATN[currNumDef]=listAtomClean[i];
atomDefine[dsATN[currNumDef]]=1;
dsTP[currNumDef]=1; //type of clean}
dsNA1[currNumDef]=k;
dsNA2[currNumDef]=-1;
currNumDef++;
//only one atom is added into priority list, then it is necessary to
// analyze cycles by DEFC procedure!}
return;
};
};
if ((sPN<3) || (sPN==4)) //{next may not be implemented to CleanGroup command}
{
//{initializing priority list for clean of a new fragment}
rC=0;
j=100000;
//minimal cycle size searching}
if (baseCycle>0) for (i=0; i0) i=atomCycle[cycleAddress[rC]];
else
{
// {not found-first undefined atom is selected}
i=0;
while (atomDefine[listAtomClean[i]] != 0) i++;
i=listAtomClean[i];
};
}
else i=listAtomClean[atomClean-1];
//for group-first atom, from which group started, is selected}
dsATN[currNumDef]=i;
atomDefine[dsATN[currNumDef]]=1;
dsTP[currNumDef]=0; //type of clean}
dsNA1[currNumDef]=-1;
dsNA2[currNumDef]=-1;
currNumDef++; //Addition the atom selected to the list}
};
void TSimpleMolecule::canonizeCycle(int ringSize, std::vector & bondList)
{
//Order of nonds in cycle description in so way, that bond with minimal number
//is the first in this description. Then is coming bond, which is appended to
//atom with maximal number, then next and so on
std::vector bondUsed(ringSize);
std::vector newBondList(ringSize);
int i,j,n,m,currentAtom;
n=bondList[0];
m=0;
for (i=0; iat[0];
if (getBond(n)->at[1] > currentAtom) currentAtom=getBond(n)->at[1];
newBondList[0]=n;
bondUsed[m]=1;
n=1;
for (i=1; iat[0] == currentAtom) || (getBond(m)->at[1] == currentAtom))
{
bondUsed[j]=1;
newBondList[n]=m;
n++;
if (getBond(m)->at[0] == currentAtom) currentAtom=getBond(m)->at[1];
else currentAtom=getBond(m)->at[0];
break;
};
};
};
//copy new set
for (i=0; i bondList(nBonds());
std::vector blStore(nBonds());
bool testBad,testOK;
int m,j,n1,n2,n,k;
int rs;
double dist,x,y,minDist;
int i;
bool test,testStore;
int at;
double r1,r2,s1,s3;
xv=0; yv=1;
nBondNo=0;
testBad=false;
testOK=true;
testStore=false;
for (i=0; i 0) {
//I have to analize bondList to determine second cycle to exclude adamanthane
if (! testStore) {
//Save
blStore.clear();
for (j=0; j 1) && (m < blStore.size())) {
testOK=false;
};
};
//center determination
centerX[nBondNo]=0;
centerY[nBondNo]=0;
for (j=0; jat[0];
n2=getBond(m)->at[1];
centerX[nBondNo]=centerX[nBondNo]+getAtom(n1)->rx+getAtom(n2)->rx;
centerY[nBondNo]=centerY[nBondNo]+getAtom(n1)->ry+getAtom(n2)->ry;
};
centerX[nBondNo]=centerX[nBondNo]/(2*rs);
centerY[nBondNo]=centerY[nBondNo]/(2*rs);
bondNoList[nBondNo]=n;
nBondNo++;
};
};// else testBad:=true;
if ((nBondNo == 3) || (testBad)) break;
};
if (nBondNo < 2) testBad=true;
if ((! testBad) && testOK) {
dist=0;
if (nBondNo == 2) {
//single bond, attached to ring. Re-definition center....
x=0; y=0;
for (i=0; irx;
y=y+getAtom(i)->ry;
};
x=x/(double)nAtoms();
y=y/(double)nAtoms();
for (i=0; iat[0];
if (at== an) getBond(bondNoList[i])->at[1];
r1=getAtom(at)->rx-getAtom(an)->rx;
r2=getAtom(at)->ry-getAtom(an)->ry;
s1=sqrt(r1*r1+r2*r2);
if (s1 == 0) testBad=true; else {
r1=r1/s1; r2=r2/s1;
x=-r1;
y=-r2;
minDist=1000000000;
for (j=0; jrx-centerX[j]);
r2=(y*s1+getAtom(an)->ry-centerY[j]);
s3=sqrt(r1*r1+r2*r2);
if (s3 < minDist) minDist=s3;
};
if (minDist > dist) {
dist=minDist;
xv=x;
yv=y;
};
};
};
if (! testBad) result=true;
};
//end addition from 16 April 2006
return result;
};
*/
void TSimpleMolecule::redraw(const std::vectorlistAtomClean, const std::vectorlistBondClean,
int & atomClean, int & bondClean, int spn, int sCHA1, int sCHB1, bool iOPT7)
{
std::vector dsATN(NBONDSMAX);
std::vector dsTP(NBONDSMAX);
std::vector dsSC(NBONDSMAX);
std::vector dsNA1(NBONDSMAX);
std::vector dsNA2(NBONDSMAX);
/*
the arrays are the priority list for clean. Minimal element of record has
the maximal priority. Each element of record contains:
ATN-atom's number in the ATOM array, coordinate of which must be calculated
at current step.
TP -type of calculation of coordinates for the atom ATN:
=0 - simple put at any position
=1 - calculation from coordinates of previously defined atom NA1. NA2
value hasn't effect in the case.
=2 - for cyclic fragment, coordinates of all cyclic atoms must be cal-
culated from the ones for atom NA1-base atom in cycle. This type
means fragment: chain bond, attached to the cycle. NA2 value hasn't
effect in the case.
=3 - for cyclic fragment, coordinates of all cyclic atoms must be cal-
culated from the ones for pair of atoms NA1 and NA2. The pair is
connected with bond. This type means fragment in condenced-cyclic
systems.
=4 - for cyclic fragment, coordinates of all cyclic atoms must be cal-
culated from the ones for pair of atoms NA1 and NA2. The pair is
connected through more, then one bond. This type means fragment
in polycyclic systems.
AN1,AN2-auxiliary atom's numbers (see TP description).
SC-cycle size minus number of already defined atoms. The variable is taken
into consideration for TP=2-4.
*/
bool test;
int cs;
int add,nb,k,k1,k2,l,i,j,baseCycle,lx,ly;
int currNumDef;
int atomSecond;
std::vector atomCycle(2*3*nBonds());
std::vector cycleDescription(2*3*nBonds());
std::vector cycleAddress(nBonds());
std::vector atomDefine(NBONDSMAX);
std::vector cycleSize(NBONDSMAX);
std::vector cycleDefine(NBONDSMAX);
std::vector tempArray(NBONDSMAX);
double r,cf,fi,ux,uy,ux1,uy1,ux2,uy2,uvX,uvY,c,s;
double xCenterOld,yCenterOld,xCenterNew,yCenterNew,bondLengthOld,bondLengthNew;
neigbourlist bk;
int n,n1,n2;
double r1;
bool isCycle,isChainFour;
int mm1,mm2,mAny,bnEx;
//Lx,Ly,Button:integer;
if ((atomClean<1) || (bondClean==0)) return;
defineAtomConn();
allAboutCycles();
test=true;
defineBondConn(bk);
//{Start clean for LISTATOMCLEAN and LISTBONDCLEAN atoms and bonds}
cycleAddress[0]=0;
baseCycle=0;
cs=0;
ux=0;
uy=0;
uvX=0;
uvY=0;
atomSecond=0;
for (i=0; i0)
{
canonizeCycle(cs,atomDefine);
test=false;
for (j=0; jat[0]==getBond(j)->at[0]) || (getBond(k)->at[0]==getBond(j)->at[1])) atomCycle[cycleAddress[i]+0]=getBond(k)->at[0];
else atomCycle[cycleAddress[i]+0]=getBond(k)->at[1];
n=atomCycle[cycleAddress[i]+0]; //previoulsly putted atom
for (j=1; jat[0]==n) atomCycle[cycleAddress[i]+j]=getBond(k)->at[1];
else atomCycle[cycleAddress[i]+j]=getBond(k)->at[0];
n=atomCycle[cycleAddress[i]+j];
};
};
//calculation of the coordinates of fragment's center and scaling factor}
if ((spn<3) || (spn==4))
{
xCenterOld=0;
yCenterOld=0;
bondLengthOld=0;
if (spn == 4)
{
for (i=0; irx;
yCenterOld=yCenterOld+getAtom(i)->ry;
n++;
};
xCenterOld=xCenterOld/(double)n;
yCenterOld=yCenterOld/(double)n;
for (i=0; ibondLength(i);
if (r < bondLengthOld) bondLengthOld=n;
r1=r1+r;
n++;
};
r1=r1/n;
if (5*bondLengthOld < r1) bondLengthOld=r1;
}
else
{
for (i=0; irx;
yCenterOld=yCenterOld+getAtom(k)->ry;
};
xCenterOld=xCenterOld/(double)atomClean;
yCenterOld=yCenterOld/(double)atomClean;
for (i=0; ibondLength(k);
};
bondLengthOld=bondLengthOld/(double)bondClean;
};
if (bondLengthOld<0.01) bondLengthOld=1;
}
else
{
xCenterOld=getAtom(sCHA1)->rx; //{CHA1 - To atom connected, CHB1-splitting bond}
yCenterOld=getAtom(sCHA1)->ry;
lx=getBond(sCHB1)->at[0];
ly=getBond(sCHB1)->at[1];
if (ly == sCHA1)
{
lx=getBond(sCHB1)->at[1];
ly=getBond(sCHB1)->at[0];
};
atomSecond=ly;
//for group it is necessary to calculate unit vector direction
uvX=getAtom(ly)->rx-getAtom(lx)->rx;
uvY=getAtom(ly)->ry-getAtom(lx)->ry;
bondLengthOld=sqrt(uvX*uvX+uvY*uvY);
if (bondLengthOld<0.01) bondLengthOld=1;
uvX=uvX/bondLengthOld;
uvY=uvY/bondLengthOld;
};
for (i=0; irx=(xCenterOld+(getAtom(i)->rx-xCenterOld)/bondLengthOld);
getAtom(i)->ry=(yCenterOld+(getAtom(i)->ry-yCenterOld)/bondLengthOld);
};
};
i=0;
if (atomClean>=1) while (irx=xCenterOld+(getAtom(dsATN[i])->rx-xCenterOld)/bondLengthOld;
getAtom(dsATN[i])->ry=yCenterOld+(getAtom(dsATN[i])->ry-yCenterOld)/bondLengthOld;
break;
}
case 1:
case 2:
if (atomDefine[dsATN[i]] == 0)
{
k1=dsNA1[i];
k=getAtom(k1)->nb;
nb=0;
ux=0;
uy=0;
ux1=0;
uy1=0;
//bond direction calculation}
for (j=0; jac[j]]>0)
{
k2=getAtom(k1)->ac[j];
nb=nb+1; //number of already cleaned atoms}
ux=ux+(getAtom(k1)->rx-getAtom(k2)->rx);
uy=uy+(getAtom(k1)->ry-getAtom(k2)->ry);
if (dsTP[i]==1) for (l=0; lnb; l++) if (atomDefine[getAtom(k2)->ac[l]]>0)
{
ux1=ux1+(getAtom(k2)->rx-getAtom(getAtom(k2)->ac[l])->rx);
uy1=uy1+(getAtom(k2)->ry-getAtom(getAtom(k2)->ac[l])->rx);
};
};
if (dsTP[i]==1) //chain fragment
{
if ((abs(ux) <= 0.00001) && (abs(uy) <= 0.00001))
{
bnEx=-1;
for (j=0; jat[0];
if (n1 == k1) n1=getBond(n)->at[1];
if (n1 == dsATN[i]) bnEx=n;
if (bnEx >= 0) break;
};
test= (bnEx >= 0);
if (test) test=threeBondResolve(k1,bnEx,ux,uy,&bk);
if (! test)
{
ux=ux1;
uy=uy1;
};
};
if ((ux==0) && (uy==0)) ux=1;
fi=(k-nb-1)*PI/(double)k;
//Addition for fluorine chain fragments...
isChainFour=false;
n=0;
mm1=-1;
mm2=-1;
mAny=-1;
if ((k == 4) && (getAtom(k1)->na == 6)) for (j=0; jnb; j++)
{
n1=getAtom(k1)->ac[j];
if (atomDefine[n1] == 0)
{
mAny=n1;
if (getAtom(n1)->nb == 1) n++;
else
{
if (mm1 == -1) mm1=n1;
else mm2=n1;
};
};
};
if ((mm1 == -1) && (n == 3))
{
mm1=mAny;
n--;
};
isChainFour=(n == 2) && (mm1 >= 0);
//End addition
isCycle=false;
if ((nb == 2) && ((k == 4) || (k == 5)))
{
n=0;
for (j=0; jdb > 1)
{
n1=getBond(k2)->at[0];
if (n1 == k1) n1=getBond(k2)->at[1];
if (atomDefine[n1] != 0) n++;
};
};
isCycle=(n == 2);
};
if (isChainFour)
{
n=0;
fi=PI/3;
ux1= ux*cos(fi)+uy*sin(fi);
uy1=-ux*sin(fi)+uy*cos(fi);
cf=sqrt(ux1*ux1+uy1*uy1);
if (cf != 0)
{
ux1=ux1/cf;
uy1=uy1/cf;
};
getAtom(mm1)->rx=getAtom(k1)->rx+ux1; //coordinates
getAtom(mm1)->ry=getAtom(k1)->ry+uy1;
atomDefine[mm1]=1;
if (mm2 >= 0)
{
fi=-PI/3;
ux1= ux*cos(fi)+uy*sin(fi);
uy1=-ux*sin(fi)+uy*cos(fi);
cf=sqrt(ux1*ux1+uy1*uy1);
if (cf != 0)
{
ux1=ux1/cf;
uy1=uy1/cf;
};
getAtom(mm2)->rx=getAtom(k1)->rx+ux1; //coordinates
getAtom(mm2)->ry=getAtom(k1)->ry+uy1; //coordinates
atomDefine[mm2]=1;
};
ux=0;
uy=0; //New cosines....
for (j=0; jnb; j++) if (atomDefine[getAtom(k1)->ac[j]] > 0)
{
k2=getAtom(k1)->ac[j];
ux=ux+(getAtom(k1)->rx-getAtom(k2)->rx);
uy=uy+(getAtom(k1)->ry-getAtom(k2)->ry);
};
fi=PI/6;
for (j=0; jnb; j++)
{
n1=getAtom(k1)->ac[j];
if (atomDefine[n1] == 0)
{
ux1= ux*cos(fi)+uy*sin(fi);
uy1=-ux*sin(fi)+uy*cos(fi);
cf=sqrt(ux1*ux1+uy1*uy1);
if (cf != 0)
{
ux1=ux1/cf;
uy1=uy1/cf;
};
getAtom(n1)->rx=getAtom(k1)->rx+ux1; //coordinates}
getAtom(n1)->ry=getAtom(k1)->ry+uy1; //coordinates}
fi=-fi;
atomDefine[n1]=1;
};
};
}
else if (isCycle)
{
if (k == 4) fi=PI/6;
else fi=PI/3;
ux1= ux*cos(fi)+uy*sin(fi);
uy1=-ux*sin(fi)+uy*cos(fi);
cf=sqrt(ux1*ux1+uy1*uy1);
if (cf != 0)
{
ux1=ux1/cf;
uy1=uy1/cf;
};
getAtom(dsATN[i])->rx=getAtom(k1)->rx+ux1; //coordinates
getAtom(dsATN[i])->ry=getAtom(k1)->ry+uy1; //coordinates
atomDefine[dsATN[i]]=1;
for (j=0; jnb; j++)
{
k2=getAtom(dsNA1[i])->ac[j];
if (atomDefine[k2] == 0)
{
ux1=ux*cos(fi)-uy*sin(fi);
uy1=ux*sin(fi)+uy*cos(fi);
if (cf != 0)
{
ux1=ux1/cf;
uy1=uy1/cf;
};
getAtom(k2)->rx=getAtom(k1)->rx+ux1;
getAtom(k2)->ry=getAtom(k1)->ry+uy1;
fi=0;
atomDefine[k2]=1;
};
};
}
else
{
if (bk[dsNA1[i]].nb == 2) //two-connected fragment
{
//Search for triple bond or for two double-bonds
n1=bk[dsNA1[i]].adjusted[0];
n2=bk[dsNA1[i]].adjusted[1];
if ((getBond(n1)->tb == 3) || (getBond(n2)->tb == 3)) k=3;
else if ((getBond(n1)->tb == 2) && (getBond(n2)->tb == 2))
{
if (getAtom(dsNA1[i])->na == 6) k=3;
};
};
//Two-conncted fragment like pyrophosphate
if ((k== 2) && (getAtom(dsNA1[i])->na != 6))
{
n1=getAtom(dsNA1[i])->ac[0];
n2=getAtom(dsNA1[i])->ac[1];
if ((getAtom(n1)->nb >= 4) && (getAtom(n2)->nb >= 4) && (getAtom(n1)->na != 6) && (getAtom(n2)->na != 6)) k=3;
};
//End pyrophosphate
if (k==2) //120 degrees fragment}
{
if ((ux1==0) && (uy1==0)) ux1=1;
fi=PI/3;
cf=uy*ux1-ux*uy1;
if (cf != 0) fi=fi*cf/abs(cf);
};
ux1=ux*cos(fi)+uy*sin(fi);
uy1=-ux*sin(fi)+uy*cos(fi);
cf=sqrt(ux1*ux1+uy1*uy1);
if (cf != 0)
{
ux1=ux1/cf;
uy1=uy1/cf;
};
getAtom(dsATN[i])->rx=getAtom(k1)->rx+ux1; //coordinates
getAtom(dsATN[i])->ry=getAtom(k1)->ry+uy1; //coordinates
atomDefine[dsATN[i]]=1;
};
}
else //cyclic fragment}
{
if ((ux==0) && (uy==0)) ux=1;
fi=(k-nb-2)*PI/(double)k;
ux1=ux*cos(fi)+uy*sin(fi);
uy1=-ux*sin(fi)+uy*cos(fi);
cf=sqrt(ux1*ux1+uy1*uy1);
if (cf != 0)
{
ux1=ux1/cf;
uy1=uy1/cf;
};
nb=dsSC[i];
cs=nb+1;
cf=1/(2*sin(PI/(double)cs));
ux=getAtom(dsNA1[i])->rx+cf*ux1;
uy=getAtom(dsNA1[i])->ry+cf*uy1;
fi=2*PI/(double)cs;
ux1=getAtom(dsNA1[i])->rx-ux;
uy1=getAtom(dsNA1[i])->ry-uy;
//coordinates of all atoms for the cycle under study are calculated}
for (j=0; jrx=ux+ux1*cos((j+1)*fi)+uy1*sin((j+1)*fi);
getAtom(dsATN[i+j-0])->ry=uy-ux1*sin((j+1)*fi)+uy1*cos((j+1)*fi);
atomDefine[dsATN[i+j-0]]=1;
};
i=i+nb-1;
};
break;
}
else break;
case 3:
case 4:
{
twoAtomUnitVector(dsNA1[i],dsNA2[i],ux,uy,atomDefine);
//calculation of an optimal side to add new fragment
ux1=getAtom(dsNA1[i])->rx-getAtom(dsNA2[i])->rx;
uy1=getAtom(dsNA1[i])->ry-getAtom(dsNA2[i])->ry;
if (dsTP[i]==3) //angle calc. for condenced cycle}
{
nb=dsSC[i];
cs=nb+2;
fi=sqrt(ux1*ux1+uy1*uy1);
cf=fi/(2*sin(PI/(double)cs)/cos(PI/(double)cs));
add=0;
}
else //angle calc. for polycycle
{
r=sqrt(ux1*ux1+uy1*uy1);
add=(int)ceil(r);
nb=dsSC[i];
cs=nb+2+add;
cf=r/(2*sin(PI*(nb+1)/(double)cs));
r=r/2.0;
cf=sqrt(cf*cf-r*r);
};
ux=(getAtom(dsNA1[i])->rx+getAtom(dsNA2[i])->rx)/2.0+ux*cf;
uy=(getAtom(dsNA1[i])->ry+getAtom(dsNA2[i])->ry)/2.0+uy*cf;
ux1=getAtom(dsNA1[i])->rx-ux;
uy1=getAtom(dsNA1[i])->ry-uy;
fi=2*PI/(double)cs;
ux2=ux+ux1*cos((1.0+add)*fi)+uy1*sin((1.0+add)*fi);
uy2=uy-ux1*sin((1.0+add)*fi)+uy1*cos((1.0+add)*fi);
if ((abs(getAtom(dsNA2[i])->rx-ux2)<0.01) && (abs(getAtom(dsNA2[i])->ry-uy2)<0.01)) fi=-fi;
//FAtom's coordinates calculation
for (j=0; jrx=ux+ux1*cos((j+1)*fi)+uy1*sin((j+1)*fi);
getAtom(dsATN[i+j-0])->ry=uy-ux1*sin((j+1)*fi)+uy1*cos((j+1)*fi);
atomDefine[dsATN[i+j-0]]=1;
}
i=i+nb-1;
break;
}
}
i++;
}
bondLengthNew=0;
//Rescaling and shift of structure
for (i=0; irx;
yCenterNew=yCenterNew+getAtom(listAtomClean[i])->ry;
};
xCenterNew=xCenterNew/(double)atomClean;
yCenterNew=yCenterNew/(double)atomClean;
bondLengthNew=0.15*bondLengthOld;
//IOPT[7]-controlles, whether or not the atom's shifts should be created, if coordinates of pair of atoms are identical
if (spn==3) //Rescaling and shift coordinates for group (CODE=3)
{
xCenterNew=getAtom(sCHA1)->rx;
yCenterNew=getAtom(sCHA1)->ry;
ux=getAtom(atomSecond)->rx-getAtom(sCHA1)->rx;
uy=getAtom(atomSecond)->ry-getAtom(sCHA1)->ry;
r=sqrt(ux*ux+uy*uy);
ux=ux/r;
uy=uy/r;
c=ux*uvX+uy*uvY;
s=ux*uvY-uy*uvX;
for (i=0; irx-xCenterNew;
uy1=getAtom(listAtomClean[i])->ry-yCenterNew;
getAtom(listAtomClean[i])->rx=c*ux1-s*uy1;
getAtom(listAtomClean[i])->ry=s*ux1+c*uy1;
};
xCenterNew=0;
yCenterNew=0;
};
if (spn != 4) for (i=0; irx=getAtom(listAtomClean[i])->rx-xCenterNew+xCenterOld;
getAtom(listAtomClean[i])->ry=getAtom(listAtomClean[i])->ry-yCenterNew+yCenterOld;
};
};
void TSimpleMolecule::getMolfile(std::ostream & data)
{
char buff[BUFF_SIZE];
TSingleAtom * sa;
TSingleBond * sb;
int charge,bondType,stereoType;
data<nc)
{
case 1:
charge = 3;
break;
case 2:
charge = 2;
break;
case 3:
charge = 1;
break;
case -1:
charge = 5;
break;
case -2:
charge = 6;
break;
case -3:
charge = 7;
break;
default:
charge=0;
break;
}
snprintf(buff, BUFF_SIZE, "%10.4f%10.4f%10.4f %-3s%2d%3d%3d%3d%3d",
sa->rx, sa->ry, 0.0, (aSymb[sa->na]).c_str(), 0,charge,0,0,0);
data << buff << endl;
};
for (int i=0; itb;
stereoType=0;
if (bondType == 9)
{
bondType=1;
stereoType=1;
}
else if (bondType == 10)
{
bondType=1;
stereoType=6;
}
else if (bondType == 11)
{
bondType=1;
stereoType=4;
};
snprintf(buff, BUFF_SIZE, "%3d%3d%3d%3d%3d%3d",(sb->at[0]+1), (sb->at[1]+1), bondType, stereoType, 0, 0);
data << buff << endl;
};
};
//*******************************************************************************
//Below routines from ChainRotate-flipping acyclic bonds and enlarging bonds to get fine picture
//*******************************************************************************
double TSimpleMolecule::atomDistanceMetric(int an)
{
int i, n;
double r, rr;
double x1, y1, x2, y2, d, result;
if (getAtom(an)->nb == 0) return 0;
result=0.01;
n=getAtom(an)->ac[0];
x1=getAtom(an)->rx-getAtom(n)->rx;
y1=getAtom(an)->ry-getAtom(n)->ry;
rr=sqrt(x1*x1+y1*y1);
for (i=0; irx-getAtom(n)->rx;
y2=getAtom(i)->ry-getAtom(n)->ry;
d=rr*sqrt(x2*x2+y2*y2);
if (d == 0) r=0;
else r=(x1*x2+y1*y2)/d;
if (r > 0) result=result+r;
};
return result;
};
double xDistPoint(double x1, double y1, double x2, double y2, double x0, double y0)
{
//The function finds distance between FAtom AN and bond BN (including sign).
// The bond is treated as segment, not as straight line!}
double d, r, r1, yMin, yMax, xMin, xMax, xx, yy, result;
if (y1 < y2)
{
yMin=y1;
yMax=y2;
}
else
{
yMin=y2;
yMax=y1;
};
xx=x1-x2;
yy=y1-y2;
r1=sqrt(xx*xx+yy*yy);
yMin=yMin-0.1*r1;
yMax=yMax+0.1*r1;
d=y2-y1;
if (abs(d) < 1E-8)
{
result=1E9;
return result;
};
if ((y0 > yMin) && (y0 < yMax))
{
r=x1+(y0-y1)*(x2-x1)/d;
if (x1 > x2)
{
xMin=x2;
xMax=x1;
}
else
{
xMin=x1;
xMax=x2;
};
xMin=xMin-0.1*r1;
xMax=xMax+0.1*r1;
if (r < xMin) r=xMin;
if (r > xMax) r=xMax;
result=r-x0;
}
else result=1E9;
return result;
};
bool overlapped(double x1A, double y1A, double x2A, double y2A,
double x1B, double y1B, double x2B, double y2B, double delta)
{
double a1, b1, c1, a2, b2, c2, r, cX, cY, x, y, r1, r2;
double xMin, xMax, yMin, yMax;
bool result=false;
r=y2A-y1A;
if (abs(r) > 1E-9)
{
a1=1/r;
cY=-y1A/r;
}
else
{
a1=1E9;
cY=-y1A*1E9;
if (r < 0)
{
a1=-a1;
cY=-cY;
};
};
r=x2A-x1A;
if (abs(r) > 1E-9)
{
b1=1/r;
cX=x1A/r;
}
else
{
b1=1E9;
cX=x1A*1E9;
if (r < 0)
{
b1=-b1;
cX=-cX;
};
};
b1=-b1;
c1=cX+cY;
r=y2B-y1B;
if (abs(r) > 1E-9)
{
a2=1/r;
cY=-y1B/r;
}
else
{
a2=1E9;
cY=-y1B*1E9;
if (r < 0)
{
a2=-a2;
cY=-cY;
};
};
r=x2B-x1B;
if (abs(r) > 1E-9)
{
b2=1/r;
cX=x1B/r;
}
else
{
b2=1E9;
cX=x1B*1E9;
if (r < 0)
{
b2=-b2;
cX=-cX;
};
};
b2=-b2;
c2=cX+cY;
r1=b1*c2-b2*c1;
r2=a1*b2-a2*b1;
if (abs(r2) > 1E-9) y=r1/r2;
else
{
y=1E9;
if (r1 < 0) y=-y;
};
r1=c1*a2-c2*a1;
r2=a1*b2-a2*b1;
if (abs(r2) > 1E-9) x=r1/r2;
else
{
x=1E9;
if (r1 < 0) x=-x;
};
if (x1A < x2A)
{
xMin=x1A;
xMax=x2A;
}
else
{
xMin=x2A;
xMax=x1A;
};
if (y1A < y2A)
{
yMin=y1A;
yMax=y2A;
}
else
{
yMin=y2A;
yMax=y1A;
};
xMin=xMin-delta;
xMax=xMax+delta;
yMin=yMin-delta;
yMax=yMax+delta;
result=((x >= xMin) && (x <= xMax) && (y >= yMin) && (y <= yMax));
if (result)
{
if (x1B < x2B)
{
xMin=x1B;
xMax=x2B;
}
else
{
xMin=x2B;
xMax=x1B;
};
if (y1B < y2B)
{
yMin=y1B;
yMax=y2B;
}
else
{
yMin=y2B;
yMax=y1B;
};
xMin=xMin-delta;
xMax=xMax+delta;
yMin=yMin-delta;
yMax=yMax+delta;
result=((x >= xMin) && (x <= xMax) && (y >= yMin) && (y <= yMax));
};
if (! result) result=(abs(xDistPoint(x1A,y1A,x2A,y2A,x1B,y1B)) < delta);
if (! result) result=(abs(xDistPoint(x1A,y1A,x2A,y2A,x2B,y2B)) < delta);
if (! result) result=(abs(xDistPoint(x1B,y1B,x2B,y2B,x1A,y1A)) < delta);
if (! result) result=(abs(xDistPoint(x1B,y1B,x2B,y2B,x2A,y2A)) < delta);
return result;
};
bool TSimpleMolecule::bondsOverlapped(int bN1, int bN2, double delta)
{
double x1A,y1A,x2A,y2A,x1B,y1B,x2B,y2B;
bool result;
x1A=getAtom(getBond(bN1)->at[0])->rx;
y1A=getAtom(getBond(bN1)->at[0])->ry;
x2A=getAtom(getBond(bN1)->at[1])->rx;
y2A=getAtom(getBond(bN1)->at[1])->ry;
x1B=getAtom(getBond(bN2)->at[0])->rx;
y1B=getAtom(getBond(bN2)->at[0])->ry;
x2B=getAtom(getBond(bN2)->at[1])->rx;
y2B=getAtom(getBond(bN2)->at[1])->ry;
result=false;
if (((x1A>(x1B+delta)) && (x2A>(x1B+delta)) && (x1A>(x2B+delta)) && (x2A>(x2B+delta))) ||
((x1A<(x1B-delta)) && (x2A<(x1B-delta)) && (x1A<(x2B-delta)) && (x2A<(x2B-delta))) ||
((y1A>(y1B+delta)) && (y2A>(y1B+delta)) && (y1A>(y2B+delta)) && (y2A>(y2B+delta))) ||
((y1A<(y1B-delta)) && (y2A<(y1B-delta)) && (y1A<(y2B-delta)) && (y2A<(y2B-delta)))) return result;
result=overlapped(x1A,y1A,x2A,y2A,x1B,y1B,x2B,y2B,delta);
return result;
};
int TSimpleMolecule::hasOverlapped(double delta, bool findFirst)
{
int i, j;
bool test;
double r,xx,yy;
int result=0;
for (i=1; i<(nBonds()-1); i++) for (j=i+1; jat[0] == getBond(j)->at[0]) || (getBond(i)->at[0] == getBond(j)->at[1]) ||
(getBond(i)->at[1] == getBond(j)->at[0]) || (getBond(i)->at[1] == getBond(j)->at[1]);
if (! test) if (bondsOverlapped(i,j,delta))
{
result++;
if (findFirst) return result;
};
};
for (i=0; i<(nAtoms()-1); i++) for (j=i+1; jrx-getAtom(j)->rx;
yy=getAtom(i)->ry-getAtom(j)->ry;
r=sqrt(xx*xx+yy*yy);
if (r < (2*delta))
{
result++;
if (findFirst) return result;
};
};
return result;
};
bool TSimpleMolecule::checkOverlapped()
{
bool result;
result=hasOverlapped(averageBondLength()/32,true)>0;
return result;
};
double TSimpleMolecule::averageBondLength()
{
double result=0;
if (nBonds() == 0) return result;
for (int i=0; ilist1(listarSize());
double r, xc, yc, xo, yo, xn, yn;
int i;
int nB1;
if (cHB < 0) return;
test=makeFragment(nB1,list1,getBond(cHB)->at[1],getBond(cHB)->at[0]);
if (nB1 > 1)
{
//One of the atoms haven't neighbours-flip unavalable
cHA1=getBond(cHB)->at[0];
cHA2=getBond(cHB)->at[1];
xc=getAtom(cHA2)->rx-getAtom(cHA1)->rx; //Axes direction calculation
yc=getAtom(cHA2)->ry-getAtom(cHA1)->ry;
r=sqrt(xc*xc+yc*yc);
xc=xc/r;
yc=yc/r;
xo=xc*xc-yc*yc;
yo=2*xc*yc;
for (i=0; irx-getAtom(cHA1)->rx;
yc=getAtom(n)->ry-getAtom(cHA1)->ry;
xn=xc*xo+yc*yo;
yn=xc*yo-yc*xo;
getAtom(n)->rx=getAtom(cHA1)->rx+xn;
getAtom(n)->ry=getAtom(cHA1)->ry+yn;
};
};
};
void TSimpleMolecule::bondEnlarge(int bN)
{
int nB;
double r;
std::vector list(listarSize());
int cHA1, cH1, cH2, n;
bool test;
double xc, yc, xc1, yc1;
int i;
for (i=0; iat[0];
test=makeFragment(nB,list,cHA1,getBond(bN)->at[1]);
if (list[0] == getBond(bN)->at[0]) //center definition
{
cH1=getBond(bN)->at[0];
cH2=getBond(bN)->at[1];
}
else
{
cH1=getBond(bN)->at[1];
cH2=getBond(bN)->at[2];
};
xc=getAtom(cH1)->rx-getAtom(cH2)->rx;
yc=getAtom(cH1)->ry-getAtom(cH2)->ry;
r=sqrt(xc*xc+yc*yc);
xc=xc/r;
yc=yc/r;
xc1=getAtom(cH2)->rx-getAtom(cH1)->rx;
yc1=getAtom(cH2)->ry-getAtom(cH1)->ry;
r=r*2;
for (i=0; irx=getAtom(n)->rx+xc1+r*xc;
getAtom(n)->ry=getAtom(n)->ry+yc1+r*yc;
};
};
bool compareAtoms(int a1, int a2, const std::vector *> aeqList)
{
std::vector * l1;
std::vector * l2;
int i;
bool result=false;
if ((a1 < 0) || (a2 < 0) || (a1 >= aeqList.size()) || (a2 >= aeqList.size())) return result;
l1 = (std::vector *)(aeqList.at(a1));
l2 = (std::vector *)(aeqList.at(a2));
if ((l1 == NULL) || (l2 == NULL)) return result;
if (l1->size() != l2->size()) return result;
result=true;
for (i=0; isize(); i++) if ((*l1)[i] != (*l2)[i])
{
result=false;
break;
};
return result;
};
int TSimpleMolecule::fragmentSecond(int sphere, int att, int secAt, const std::vector a,
const std::vector b, const neigbourlist bk, std::vector& wSphere)
{
/*Generate a longinteger number, which is characterize fragment with atom
CHA in center. Up to second neigbour's sphere are took into account. Array
A contains the atom's codes, generated by ALLATATOM, array B-bond's codes,
generated by BONDCONVERSION*/
int i,j,k,n,i1,i2,i3,jj;
std::vector aDist(listarSize());
std::vector aList(listarSize());
std::vector atomoBond(listarSize());
std::vector * aPrev [3];
bool test,testOK;
int w2;
int l2,l3,tl1,tl2;
std::vector ab(listarSize());
int result=0;
// String s;
if (nAtoms()==0) return result;
for (j=0; j<3; j++) aPrev[j]=new std::vector(listarSize());
for (i=0; i 0) for (j=0; jat[0];
if (i2 == i1) i2=getBond(i3)->at[1];
if ((aDist[i2] >= k) && (aDist[i2] <= 65700))
{
//if the neighbour has not been added yet to list}
aDist[i2]=k; //Mark neighbour's sphere number
jj=0;
test=true;
for (jj=1; jj<=3; jj++)
{
if (((*aPrev[jj-1])[i2] == -1) || (jj == 3))
{
(*aPrev[jj-1])[i2]=i1;
break;
};
};
w2=a[i2];
w2=w2 << 6;
w2=w2+b[i3];
w2=w2 ^ atomoBond[i2]; //atomoBond[I2]:=AtomoBond[I2] xor W2; !!!!!!!
atomoBond[i2]=w2;
};
};
};
if (secAt < 0) testOK=(k==sphere);
else testOK=((k>=sphere) && (aDist[secAt] < 65700));
if (testOK) test=false;
}; //end WHILE
// At this point I have sphere numbers in Adist, corresponding AtomoBond word, number of atom(s), from
//which the desirable atom were generated
for (i=0; i=1; i1--)
{
n=0;
for (i=0; i 0)
{
i2=0;
for (i=0; i= 0)
{
tl1=ab[aList[i]];
tl2=atomoBond[(*aPrev[j-1])[aList[i]]]; // [Aprev[J][AList[I]]];
tl2=tl2 << 9;
tl1=tl1 ^ tl2;
ab[aList[i]]=tl1;
};
};
//Sorting
if (n > 1) for (i=0; i<(n-1); i++) for (j=i+1; j 1) i2=15/(n-1);
l2=ab[aList[0]];
if (n > 1) for (i=1; inc;
if (l3 != 0) l2=-l2;
for (i=0; i& equivalenceList, bool isTopologyOnly)
{
//AllAboutCycles must be called early
std::vector a(listarSize());
std::vector b(listarSize());
TSimpleMolecule * em;
int i,j,n;
neigbourlist bk;
std::vector