PageRenderTime 58ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/aquad/src/AquaFuncts.c

http://aquad.googlecode.com/
C | 2571 lines | 1698 code | 345 blank | 528 comment | 396 complexity | 1a393f9bbaef0351b360e5314d264c18 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. ** File: AquaFuncts.c
  3. **
  4. ** This file is part of the AQUA program suite, which is being
  5. ** developed in the NMR Spectroscopy Department, Bijvoet Center for
  6. ** Biomolecular Research, Utrecht.
  7. **
  8. **
  9. ** AUTHOR(S) : Ton Rullmann
  10. ** VERSION : 1.5.0
  11. ** DATE : Dec 18, 1997
  12. **
  13. ** This file contains miscellaneous functions dealing with
  14. ** among other things Aqua data types.
  15. */
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20. #include "Compiler.h"
  21. #include "General.h"
  22. #include "AquaMacros.h"
  23. #include "AquaTypes.h"
  24. #include "AquaData.h"
  25. /**************** function prototypes ****************/
  26. #include "AquaFuncts_cv.h"
  27. #include "AquaFuncts_io.h"
  28. #include "AquaStrucset.h"
  29. #include "AquaFiles.h"
  30. #include "MenuFuncts.h"
  31. #include "Functs.h"
  32. #include "AquaFuncts.h"
  33. static Atom *GuessAtom( Atom *at );
  34. static int CmpResidOfAtomptr( const void *a, const void *b );
  35. static Mol *ExpandAtoms( Atom *atoms, const int at_count, Mol *molptr );
  36. static Mol *MakeDefsMol( Atom *new_atoms, const int new_count, const Boolean makeres );
  37. /**************** globals ****************/
  38. extern Boolean iaf; /* import from Functs */
  39. extern int terseness; /* import from Functs */
  40. extern Card msg_string; /* import from Functs */
  41. char *project_name; /* export to main program and libs */
  42. #define max_MATCH 10
  43. static Atomptr MatchList[max_MATCH];
  44. static int find_atom_err; /* flag FindAtom2 -> WriteNotFoundAtom */
  45. /* BEGIN_EXTH */
  46. /**************** Check_General_Options ****************/
  47. /*
  48. ** Check the validity of the values of some general options against
  49. ** the allowed range
  50. */
  51. Boolean Check_General_Options ( void )
  52. {
  53. Boolean check = true;
  54. /* Terseness value [0-9] */
  55. if ( ( GetOptionIVal( opt_terseness ) < 0 ) ||
  56. ( GetOptionIVal( opt_terseness ) > 9 ) ) {
  57. check = false;
  58. printf("Option opt_terseness (%d) is outside it's bounds\n",GetOptionIVal(opt_terseness));
  59. }
  60. return ( check );
  61. }
  62. /**************** ProjectInit ****************/
  63. /*
  64. ** Get the project name from the environment variable AQUAPROJECT.
  65. */
  66. void ProjectInit( void )
  67. {
  68. project_name = GetVar( "AQUAPROJECT", false );
  69. if ( !project_name )
  70. {
  71. puts( " * Define a project name first!" );
  72. exit( 1 );
  73. }
  74. if ( terseness < 6 ) {
  75. printf( "Project name: %s\n", project_name );
  76. }
  77. return;
  78. }
  79. /**************** AquaDataFile ****************/
  80. /*
  81. ** Open Aqua data file <file> in the AQUADATADIR directory.
  82. */
  83. FILE *AquaDataFile( char *file )
  84. {
  85. FILE *fp;
  86. Filnam filnam;
  87. char *dir;
  88. /* the total length of the string should be checked against size_FILNAM */
  89. dir = GetVar( "AQUADATADIR", true );
  90. strcpy( filnam, dir );
  91. strcat( filnam, DIRSEP );
  92. strcat( filnam, file );
  93. if ( terseness < 6 ) {
  94. printf( "Now opening: %s\n", filnam );
  95. }
  96. if ( NOTOPENr( fp, filnam ) )
  97. {
  98. printf( " * Aqua data-file <%s> could not be opened\n", filnam );
  99. if ( !iaf )
  100. exit( 1 );
  101. return( NULL );
  102. }
  103. return( fp );
  104. }
  105. /**************** AquaFileName ****************/
  106. /*
  107. ** Generate an Aqua file name.
  108. ** The string is stored in <filnam> (which should contain at least
  109. ** size_FILNAM characters), and a pointer to it is returned.
  110. */
  111. char *AquaFileName( const Qtyp type, Typnam ident, char *filnam )
  112. {
  113. /* the total length of the string should be checked against size_FILNAM */
  114. strcpy( filnam, project_name );
  115. strcat( filnam, "_" );
  116. strcat( filnam, QtypSel( type ) );
  117. strcat( filnam, "_" );
  118. strcat( filnam, ident );
  119. strcat( filnam, FiltypExt( QtypFil( type ) ) );
  120. return( filnam );
  121. }
  122. /**************** OpenAquaFile ****************/
  123. /*
  124. ** Generate the name of an Aqua file of Qtyp <type> by inputting the "ident"
  125. ** (if <reuse> is false) or using the last input ident (if <reuse> is true)
  126. ** and calling AquaFileName,
  127. ** and open the file in mode <mode>.
  128. ** The return value is the file pointer, or null.
  129. ** <filnam> is the address of a string that receives the file name; it should
  130. ** contain at least size_FILNAM characters.
  131. */
  132. FILE *OpenAquaFile( const Qtyp type, char *mode, char *filnam, const Boolean reuse )
  133. {
  134. FILE *fp;
  135. Menu *oldmenu = NULL;
  136. static Typnam ident;
  137. char *filnam_temp;
  138. if ( !reuse )
  139. {
  140. oldmenu = SetOneMenu( "Give file identification string:" );
  141. MReadWord( ident );
  142. }
  143. filnam_temp = AquaFileName( type, ident, filnam );
  144. if ( terseness < 6 ) {
  145. if ( *mode == 'a' ) {
  146. printf( "Now (re)opening: %s\n", filnam_temp);
  147. } else {
  148. printf( "Now opening: %s\n", filnam_temp );
  149. }
  150. }
  151. if ( ( fp = fopen( filnam, mode ) ) == NULL )
  152. {
  153. printf( " * File <%s> could not be opened in mode <%s>\n", filnam, mode );
  154. if ( !iaf )
  155. exit( 1 );
  156. return( NULL );
  157. }
  158. if ( !reuse )
  159. ResetMenu( oldmenu );
  160. return( fp );
  161. }
  162. /**************** ReadAquaIDLines ****************/
  163. /*
  164. ** Read the standard Aqua identification lines.
  165. ** Returns true if successful, otherwise false.
  166. */
  167. Boolean ReadAquaIDLines( FILE *fp )
  168. {
  169. /***
  170. Card version;
  171. if ( fscanf( fp, "$ Aqua Version %s", version ) < 1 )
  172. {
  173. puts( " * This is not an Aqua file" );
  174. return( false );
  175. }
  176. if ( NOTEQ( version, aqua_version ) )
  177. {
  178. puts( " * This file was created by an old Aqua version" );
  179. return( false );
  180. }
  181. ***/
  182. float version;
  183. if ( fscanf( fp, "$ Aqua Version %f", &version ) < 1 )
  184. {
  185. puts( " * This is not an Aqua file" );
  186. return( false );
  187. }
  188. if ( version < aqua_versnum_comp )
  189. {
  190. puts( " * This file was created by an old Aqua version" );
  191. return( false );
  192. }
  193. else if ( version > aqua_versnum )
  194. {
  195. puts( " * This file was created by a future Aqua version" );
  196. exit( 1 );
  197. }
  198. FlushLine( fp );
  199. FlushLine( fp );
  200. return( true );
  201. }
  202. /**************** WriteAquaIDLines ****************/
  203. /*
  204. ** Write the standard Aqua identification lines
  205. */
  206. void WriteAquaIDLines( FILE *fp, const Qtyp qtype, Filnam filnam )
  207. {
  208. time_t tim;
  209. tim = time( NULL );
  210. fprintf( fp, "$ Aqua Version %s DATA: %s\n", aqua_version,
  211. QtypTxt( qtype ) );
  212. fprintf( fp, "$ FILE: %s CREATED: %s", filnam, ctime( &tim ) );
  213. }
  214. /**************** ProcessAquaLine ****************/
  215. /*
  216. ** Read until a non-blank line and process as standard Aqua header line.
  217. ** Format assumed:
  218. ** $ DESCRIPTOR: DATA
  219. ** The line is input stored at <line>.
  220. ** DESCRIPTOR and DATA are stored at <descr> and <inp>.
  221. ** These 3 first arguments should be pointers to non-overlapping
  222. ** character arrays of at least <size> bytes.
  223. ** The function returns NULL if an error occurs, otherwise <line>.
  224. */
  225. char *ProcessAquaLine( char *line, char *descr, char *inp,
  226. const int size, FILE *fp )
  227. {
  228. char *colptr;
  229. do
  230. if ( !ReadLine( line, size, fp ) )
  231. {
  232. puts( " * Error while reading" );
  233. return( NULL );
  234. }
  235. while
  236. ( IsEmptyStr( line ) );
  237. colptr = strchr( line, ':' );
  238. if ( *line != '$' || !colptr )
  239. {
  240. puts( " * Unexpected line encountered:" );
  241. puts( line );
  242. return( NULL );
  243. }
  244. strcpy( descr, FirstNonBlank( line+1 ) );
  245. strcpy( inp, FirstNonBlank( colptr+1 ) );
  246. if ( OptionTrue( opt_prtaq ) )
  247. printf( " read: %s\n", line );
  248. return( line );
  249. }
  250. /**************** QtypSel ****************/
  251. /*
  252. ** Return file selector string belonging to aqua type <type>
  253. */
  254. char *QtypSel( const Qtyp type )
  255. {
  256. unsigned int i;
  257. for ( i=0; i<size_aquarec; i++)
  258. if ( type == aquarec[i].type )
  259. return( aquarec[i].file_selector );
  260. return( aquarec[0].file_selector );
  261. }
  262. /**************** QtypTxt ****************/
  263. /*
  264. ** Return type text belonging to aqua type <type>
  265. */
  266. char *QtypTxt( const Qtyp type )
  267. {
  268. unsigned int i;
  269. for ( i=0; i<size_aquarec; i++)
  270. if ( type == aquarec[i].type )
  271. return( aquarec[i].type_text );
  272. return( aquarec[0].type_text );
  273. }
  274. /**************** QtypFil ****************/
  275. /*
  276. ** Return file type belonging to aqua type <type>
  277. */
  278. Filtyp QtypFil( const Qtyp type )
  279. {
  280. unsigned int i;
  281. for ( i=0; i<size_aquarec; i++)
  282. if ( type == aquarec[i].type )
  283. return( aquarec[i].file_type );
  284. return( aquarec[0].file_type );
  285. }
  286. /**************** FiltypNam ****************/
  287. /*
  288. ** Return name belonging to file type <type>
  289. */
  290. char *FiltypNam( const Filtyp type )
  291. {
  292. unsigned int i;
  293. for ( i=0; i<size_filerec; i++)
  294. if ( type == filerec[i].type )
  295. return( filerec[i].type_name );
  296. return( filerec[0].type_name );
  297. }
  298. /**************** FiltypLIBNam ****************/
  299. /*
  300. ** Return library name belonging to file type <type>
  301. */
  302. char *FiltypLIBNam( const Filtyp type )
  303. {
  304. switch ( type )
  305. {
  306. case pdb_type:
  307. return( "pdb" );
  308. case pdbn_type:
  309. return( "pdbn" );
  310. case pdbx_type:
  311. return( "pdbx" );
  312. case pdbm_type:
  313. return( "pdbm" );
  314. case biosym_type:
  315. return( "biosym" );
  316. default:
  317. return( "unknown" );
  318. }
  319. }
  320. /**************** FiltypExt ****************/
  321. /*
  322. ** Return file name extension belonging to file type <type>
  323. */
  324. char *FiltypExt( const Filtyp type )
  325. {
  326. unsigned int i;
  327. for ( i=0; i<size_filerec; i++)
  328. if ( type == filerec[i].type )
  329. return( filerec[i].extension );
  330. return( filerec[0].extension );
  331. }
  332. /**************** ContactRangeCount ****************/
  333. /*
  334. ** Return number of ContactRange types defined.
  335. */
  336. int ContactRangeCount( void )
  337. {
  338. return( size_contactrec );
  339. }
  340. /**************** ContactRangeNam ****************/
  341. /*
  342. ** Return name belonging to ContactRange type <type>.
  343. */
  344. char *ContactRangeNam( const ContactRange type )
  345. {
  346. unsigned int i;
  347. for ( i=0; i<size_contactrec; i++)
  348. if ( type == contactrec[i].type )
  349. return( contactrec[i].type_name );
  350. return( contactrec[0].type_name );
  351. }
  352. /**************** ContactRangeStarNam ****************/
  353. /*
  354. ** Return NMR-STAR name belonging to ContactRange type <type>.
  355. */
  356. char *ContactRangeStarNam( const ContactRange type )
  357. {
  358. unsigned int i;
  359. for ( i=0; i<size_contactrec; i++)
  360. if ( type == contactrec[i].type )
  361. return( contactrec[i].star_type_name );
  362. return( contactrec[0].star_type_name );
  363. }
  364. /**************** ContactRangeIndex ****************/
  365. /*
  366. ** Return index belonging to ContactRange type <type>.
  367. */
  368. int ContactRangeIndex( const ContactRange type )
  369. {
  370. unsigned int i;
  371. for ( i=0; i<size_contactrec; i++)
  372. if ( type == contactrec[i].type )
  373. return( i );
  374. return( -1 );
  375. }
  376. /**************** MapAtomsInSet ****************/
  377. /*
  378. ** For a strucset map the 'external' atom names to the
  379. ** 'internal' (Aqua) ones, or vice versa (determined by <how>).
  380. ** If needed, struc_mol's are created and a loop over them is performed.
  381. ** Cf. MapAtomsInDRestraints.
  382. */
  383. void MapAtomsInSet( Strucset *set, const int how, char *lib_nam )
  384. {
  385. char *fct_name = "MapAtomsInSet";
  386. Struc *strucptr;
  387. Mol *molptr = set->molecule;
  388. Filnam predef_nam;
  389. sprintf( msg_string, "preparing to map atom names in strucset <%s>",
  390. set->name );
  391. if ( terseness < 6 ) {
  392. STATUSm;
  393. }
  394. if ( set->mapped )
  395. {
  396. if ( terseness < 6 ) {
  397. STATUS( "atom names already mapped" );
  398. }
  399. return;
  400. }
  401. /* predefine the library name for use with the "whatif" option */
  402. strcpy( predef_nam, project_name );
  403. strcat( predef_nam, FiltypExt( atlib_type ) );
  404. /* DO THIS HERE ? >>>>>>>>>>>>>>>>>>>>>>>> */
  405. if ( EQn( lib_nam, "whatif", 6 ) && set->struc_count > 1 )
  406. set->onemap = false;
  407. /* use the unique molecule */
  408. if ( set->onemap )
  409. MapAtomsInMol( molptr, how, lib_nam, predef_nam );
  410. /* or use the model-dependent molecules */
  411. /* THE MAP IN set->molptr LOSES ITS MEANING */
  412. else
  413. {
  414. strucptr = set->fst_struc;
  415. while ( strucptr )
  416. {
  417. if ( !strucptr->struc_mol ) /* create if necessary */
  418. {
  419. strucptr->struc_mol = MolCreate( set->atom_count );
  420. MolCopy( strucptr->struc_mol, molptr );
  421. AddAtomSToMol( strucptr->struc_mol, molptr->atoms, molptr->atom_count,
  422. set->atom_count );
  423. }
  424. if ( set->struc_count != 1 ) /* name as given by whnamchk */
  425. sprintf( predef_nam, "%s_%03i%s", project_name,
  426. strucptr->struc_num, FiltypExt( atlib_type ) );
  427. MapAtomsInMol( strucptr->struc_mol, how, lib_nam, predef_nam );
  428. strucptr = strucptr->next_struc;
  429. }
  430. }
  431. set->mapped = true;
  432. }
  433. /**************** MapAtomsInMol ****************/
  434. /*
  435. ** Map the 'external' atom names to the 'internal' (Aqua) ones,
  436. ** or vice versa (determined by <how>).
  437. ** Cf. MapAtomsIn1DR.
  438. ** The library name <lib_nam> is derived from the coordinate file type,
  439. ** if it is "". Names are just copied if <lib_nam> is "copy" or "aqua".
  440. **
  441. ** Name guessing - as implemented in MapAtoms->FindAtom - is not performed.
  442. */
  443. void MapAtomsInMol( Mol *molptr, const int how, char *lib_nam_orig, Filnam predef_nam )
  444. {
  445. char *fct_name = "MapAtomsInMol";
  446. Mol *atmap_mol = NULL, *atmap_mol2 = NULL;
  447. FctFindAt Find = NULL;
  448. Strucset tmpSet;
  449. Card lib_nam;
  450. char *lib_nam1 = lib_nam, *lib_nam2;
  451. /* make a list of atom name pairs from a library file */
  452. /* the library name is derived from the coordinate file type, if it is "" */
  453. /* if the file type is "aqua", names will just be copied */
  454. /* was a combination of libraries specified? if so, split the name on the + character */
  455. strcpy( lib_nam, lib_nam_orig );
  456. if ( ( lib_nam2 = strchr( lib_nam, '+' ) ))
  457. {
  458. *lib_nam2 = '\0'; /* this sets lib_nam1 to a correct string */
  459. lib_nam2++;
  460. }
  461. /*
  462. printf( "first lib: <%s>\n", lib_nam1 );
  463. if ( lib_nam2 )
  464. printf( "second lib: <%s>\n", lib_nam2 );
  465. else
  466. puts( "no second lib" );
  467. */
  468. if ( NOTEQ( lib_nam1, "copy" ) && NOTEQ( lib_nam1, "aqua" ) )
  469. {
  470. if ( EQ( lib_nam1, "" ) )
  471. lib_nam1 = FiltypLIBNam( molptr->inp_filtyp );
  472. atmap_mol = ProcessAtomLIB( molptr, lib_nam1, predef_nam );
  473. }
  474. /* second library - handling same as in MapAtomsIn1DR */
  475. if ( lib_nam2 && atmap_mol )
  476. {
  477. if ( IsEmptyStr( lib_nam2 ) )
  478. lib_nam2 = FiltypLIBNam( molptr->inp_filtyp );
  479. /* lib_nam2 = GetLIBName( item_NONE ); */
  480. if ( ( atmap_mol2 = ProcessAtomLIB( molptr, lib_nam2, predef_nam ) ) )
  481. {
  482. StrucsetInit( &tmpSet, "allDefs", false );
  483. StrucsetCreate( &tmpSet, atmap_mol->atom_count + atmap_mol2->atom_count, 0 );
  484. AddAtomSToSet( &tmpSet, atmap_mol->atoms, atmap_mol->atom_count );
  485. AddAtomSToSet( &tmpSet, atmap_mol2->atoms, atmap_mol2->atom_count );
  486. DeleteMol( atmap_mol2 );
  487. if ( OptionTrue( opt_find2 ) )
  488. MakeResidues( &tmpSet, false ); /* cf. MakeDefsMol */
  489. atmap_mol = tmpSet.molecule;
  490. sprintf( msg_string, "%i atom name definitions active for present molecule",
  491. atmap_mol->atom_count );
  492. if ( terseness < 6 ) {
  493. STATUSm;
  494. }
  495. if ( OptionTrue( opt_prtlib ) )
  496. WriteFAtoms( stdout, atmap_mol->atoms, atmap_mol->atom_count );
  497. }
  498. }
  499. /* print what is going to happen */
  500. if ( !atmap_mol )
  501. {
  502. if ( terseness < 6 ) {
  503. if ( how == int_to_ext )
  504. STATUS( "copying internal to external atom names" );
  505. else
  506. STATUS( "copying external to internal atom names" );
  507. }
  508. }
  509. else
  510. {
  511. if ( how == int_to_ext )
  512. {
  513. if ( terseness < 6 ) {
  514. STATUS( "mapping internal to external atom names" );
  515. }
  516. if ( OptionTrue( opt_find2 ) )
  517. {
  518. if ( terseness < 6 ) {
  519. STATUS( "using routine FindAtom2" );
  520. }
  521. Find = FindAtom2;
  522. }
  523. else
  524. {
  525. if ( terseness < 6 ) {
  526. STATUS( "using routine FindAtom3" );
  527. }
  528. Find = FindAtom3;
  529. }
  530. }
  531. else
  532. {
  533. if ( terseness < 6 ) {
  534. STATUS( "mapping external to internal atom names" );
  535. }
  536. if ( OptionTrue( opt_find2 ) )
  537. {
  538. if ( terseness < 6 ) {
  539. STATUS( "using routine FindAtom2" );
  540. }
  541. Find = FindAtom2;
  542. }
  543. else
  544. {
  545. if ( terseness < 6 ) {
  546. STATUS( "using routine FindAtom3" );
  547. }
  548. Find = FindAtom3;
  549. }
  550. }
  551. }
  552. /* now do the mapping or copying */
  553. MapAtoms( molptr->atoms, molptr->atom_count, atmap_mol, how, false, Find );
  554. /* free the list again */
  555. if ( atmap_mol )
  556. DeleteMol( atmap_mol );
  557. }
  558. /**************** MapAtoms ****************/
  559. /*
  560. ** In <atoms> map the 'external' atom names to the 'internal' (Aqua)
  561. ** ones, or v.v., according to the names of the atoms appearing in <atmap_mol>.
  562. */
  563. void MapAtoms( Atom *atoms, int atom_count, Mol *atmap_mol,
  564. const int how, const Boolean guess, FctFindAt FindAtom )
  565. {
  566. Atom *atmap;
  567. Boolean err = false;
  568. int idx, find_which;
  569. if ( !atmap_mol )
  570. {
  571. /* if no list was made, just copy */
  572. if ( how == int_to_ext )
  573. {
  574. while ( atom_count-- )
  575. {
  576. memcpy( atoms->atom_ext, atoms->atom_int, size_ID );
  577. atoms++;
  578. }
  579. }
  580. else
  581. {
  582. while ( atom_count-- )
  583. {
  584. memcpy( atoms->atom_int, atoms->atom_ext, size_ID );
  585. atoms++;
  586. }
  587. }
  588. return;
  589. }
  590. /* if a list was made, use it to map */
  591. find_which = ( how == int_to_ext ? use_int : use_ext );
  592. while ( atom_count-- )
  593. {
  594. if ( !( atmap = FindAtom( &idx, atoms, atmap_mol, find_which, guess ) ) )
  595. {
  596. WriteNotFoundAtom( stdout, atoms, find_which, find_which );
  597. puts( "copying atom name instead" );
  598. if ( how == int_to_ext )
  599. memcpy( atoms->atom_ext, atoms->atom_int, size_ID );
  600. else
  601. memcpy( atoms->atom_int, atoms->atom_ext, size_ID );
  602. err = true;
  603. }
  604. else
  605. {
  606. if ( how == int_to_ext )
  607. memcpy( atoms->atom_ext, atmap->atom_ext, size_ID );
  608. else
  609. memcpy( atoms->atom_int, atmap->atom_int, size_ID );
  610. }
  611. atoms++;
  612. }
  613. if ( err )
  614. puts( " * One or more atoms could not be found in the AtomLIB" );
  615. }
  616. /**************** MapPtrAtoms ****************/
  617. /*
  618. ** In <atomptrs> map the 'external' atom names to the 'internal' (Aqua)
  619. ** ones, or v.v., according to the names of the atoms appearing in <atmap_mol>.
  620. */
  621. void MapPtrAtoms( Atomptr *atomptrs, int atom_count, Mol *atmap_mol,
  622. const int how, const Boolean guess, FctFindAt FindAtom )
  623. {
  624. Atom *atmap;
  625. Boolean err = false;
  626. int idx, find_which;
  627. if ( !atmap_mol )
  628. {
  629. /* if no list was made, just copy */
  630. if ( how == int_to_ext )
  631. {
  632. while ( atom_count-- )
  633. {
  634. memcpy( (*atomptrs)->atom_ext, (*atomptrs)->atom_int, size_ID );
  635. atomptrs++;
  636. }
  637. }
  638. else
  639. {
  640. while ( atom_count-- )
  641. {
  642. memcpy( (*atomptrs)->atom_int, (*atomptrs)->atom_ext, size_ID );
  643. atomptrs++;
  644. }
  645. }
  646. return;
  647. }
  648. /* if a list was made, use it to map */
  649. find_which = ( how == int_to_ext ? use_int : use_ext );
  650. while ( atom_count-- )
  651. {
  652. if ( !( atmap = FindAtom( &idx, *atomptrs, atmap_mol, find_which, guess ) ) )
  653. {
  654. WriteNotFoundAtom( stdout, *atomptrs, find_which, find_which );
  655. puts( "copying atom name instead" );
  656. if ( how == int_to_ext )
  657. memcpy( (*atomptrs)->atom_ext, (*atomptrs)->atom_int, size_ID );
  658. else
  659. memcpy( (*atomptrs)->atom_int, (*atomptrs)->atom_ext, size_ID );
  660. err = true;
  661. }
  662. else
  663. {
  664. if ( how == int_to_ext )
  665. memcpy( (*atomptrs)->atom_ext, atmap->atom_ext, size_ID );
  666. else
  667. memcpy( (*atomptrs)->atom_int, atmap->atom_int, size_ID );
  668. }
  669. atomptrs++;
  670. }
  671. if ( err )
  672. puts( " * One or more atoms could not be found in the AtomLIB" );
  673. }
  674. /**************** MakeResidues ****************/
  675. /*
  676. **
  677. */
  678. void MakeResidues( Strucset *set, Boolean sort )
  679. {
  680. char *fct_name = "MakeResidues";
  681. Mol *molptr;
  682. Atom *atoms;
  683. Atomptr *atomptrs, *list;
  684. Residue *residues;
  685. int *atomidxs, *list2;
  686. int i, j, idx, res_count, atom_count;
  687. char *res_id;
  688. molptr = set->molecule;
  689. atom_count = molptr->atom_count;
  690. /* make a list of pointers to the atoms */
  691. list = CREATE_NEW( Atomptr, atom_count );
  692. if ( !list )
  693. NOMEM( "atomptrs" );
  694. atomptrs = list;
  695. atoms = molptr->atoms;
  696. for ( i=0; i < atom_count; i++ )
  697. *atomptrs++ = atoms++;
  698. /* allocate a list of atom indices */
  699. list2 = CREATE_NEW( int, atom_count );
  700. if ( !list2 )
  701. NOMEM( "atomidxs" );
  702. /* make a unique residue ID name */
  703. atoms = molptr->atoms;
  704. for ( i=0; i < atom_count; i++ )
  705. MakeUniqResid( atoms++ );
  706. /* order the list on unique residue IDs */
  707. if ( sort )
  708. qsort( list, (size_t)atom_count, sizeof( Atomptr ), CmpResidOfAtomptr );
  709. /* now count the number of residues and set the new, sequential residue number */
  710. /* fill the atom index array */
  711. atomidxs = list2;
  712. atomptrs = list;
  713. atoms = *atomptrs;
  714. res_id = atoms->res_id;
  715. res_count = 1;
  716. for ( i=0; i < atom_count; i++ )
  717. {
  718. if ( NOTEQ( atoms->res_id, res_id ) )
  719. {
  720. res_id = atoms->res_id;
  721. res_count++;
  722. }
  723. atoms->res_num_new = res_count; /* sequential number, starting at 1 */
  724. for ( j=0; j < atom_count; j++ )
  725. {
  726. if ( atoms == &molptr->atoms[j] )
  727. {
  728. *atomidxs++ = j;
  729. break;
  730. }
  731. }
  732. atoms = *(++atomptrs);
  733. }
  734. /* make the residue list */
  735. sprintf( msg_string, "allocating %i residues in molecule of strucset <%s>",
  736. res_count, set->name );
  737. if ( terseness < 6 ) {
  738. STATUSm;
  739. }
  740. residues = CREATE_NEW( Residue, res_count );
  741. molptr->residues = residues;
  742. molptr->res_count = res_count;
  743. atomidxs = list2;
  744. atomptrs = list;
  745. atoms = *atomptrs;
  746. res_id = atoms->res_id;
  747. residues->res_num_new = atoms->res_num_new;
  748. residues->res_num_orig = atoms->res_num_orig;
  749. memcpy( residues->chain, atoms->chain, size_ID );
  750. memcpy( residues->res_nam, atoms->res_nam, size_ID );
  751. strcpy( residues->res_id, atoms->res_id );
  752. residues->res_insert = atoms->res_insert;
  753. residues->atomptrs = atomptrs;
  754. residues->atomidxs = atomidxs;
  755. for ( i=0; i < atom_count; i++ )
  756. {
  757. if ( NOTEQ( atoms->res_id, res_id ) )
  758. {
  759. residues++;
  760. res_id = atoms->res_id;
  761. residues->res_num_new = atoms->res_num_new;
  762. residues->res_num_orig = atoms->res_num_orig;
  763. memcpy( residues->chain, atoms->chain, size_ID );
  764. memcpy( residues->res_nam, atoms->res_nam, size_ID );
  765. strcpy( residues->res_id, atoms->res_id );
  766. residues->res_insert = atoms->res_insert;
  767. residues->atomptrs = atomptrs;
  768. residues->atomidxs = atomidxs;
  769. }
  770. residues->atom_count++;
  771. atoms = *(++atomptrs);
  772. ++atomidxs;
  773. }
  774. /* check */
  775. atoms = molptr->atoms;
  776. atomidxs = list2;
  777. atomptrs = list;
  778. for ( i=0; i < atom_count; i++ )
  779. {
  780. idx = *atomidxs++;
  781. if ( ( atoms + idx ) != *atomptrs++ )
  782. {
  783. ERROR( " * Atom index incorrect - code error" );
  784. exit( 1 );
  785. }
  786. }
  787. /* print */
  788. if ( OptionTrue( opt_prtres ) )
  789. WriteResidues( stdout, molptr->residues, molptr->res_count );
  790. }
  791. /**************** MakeUniqResid ****************/
  792. /*
  793. **
  794. */
  795. void MakeUniqResid( Atom *atom )
  796. {
  797. memcpy( atom->res_id, atom->chain, size_ID );
  798. sprintf( atom->res_id+size_ID, "%05d%c",
  799. atom->res_num_orig, atom->res_insert );
  800. memcpy( atom->res_id+size_ID+6, atom->res_nam, size_ID );
  801. *(atom->res_id+2*size_ID+6) = '\0';
  802. /*
  803. printf( "%s ", atom->res_id );
  804. PRINTID( atom->res_nam );
  805. putchar( '\n' );
  806. */
  807. }
  808. /**************** ReadUniqResid ****************/
  809. /*
  810. **
  811. */
  812. void ReadUniqResid( Atom *atom )
  813. {
  814. memcpy( atom->chain, atom->res_id, size_ID );
  815. memcpy( atom->res_nam, atom->res_id+size_ID+6, size_ID );
  816. if ( sscanf( atom->res_id+size_ID, "%5d%c",
  817. &atom->res_num_orig, &atom->res_insert ) < 2 )
  818. {
  819. printf( " * Cannot read from resid <%s>\n", atom->res_id );
  820. printf( " * Atom: " );
  821. WriteAtom( stdout, atom, use_both );
  822. putchar( '\n' );
  823. exit( 1 );
  824. }
  825. }
  826. /**************** WriteResidues ****************/
  827. /*
  828. **
  829. */
  830. void WriteResidues( FILE *fp, Residue *residues, const int count )
  831. {
  832. int i = 0;
  833. while ( i++ < count )
  834. {
  835. WriteResidue( fp, residues );
  836. fprintf( fp, "# atoms: %2i", residues->atom_count );
  837. fputs( ". first at: ", fp );
  838. WriteAtom( fp, *(residues->atomptrs), use_ext );
  839. fputs( ". last at: ", fp );
  840. WriteAtom( fp, *((residues->atomptrs)+residues->atom_count-1), use_ext );
  841. #ifdef DEBUG
  842. for ( j=0; j<residues->atom_count; j++ )
  843. fprintf( fp, " %i", residues->atomidxs[j] );
  844. #endif
  845. fputc( '\n', fp);
  846. residues++;
  847. }
  848. }
  849. /**************** CoordZero ****************/
  850. /*
  851. **
  852. */
  853. void CoordZero( Coord *v )
  854. {
  855. v->x = 0.F;
  856. v->y = 0.F;
  857. v->z = 0.F;
  858. }
  859. /**************** CoordAdd ****************/
  860. /*
  861. **
  862. */
  863. void CoordAdd( Coord *v, const Coord c )
  864. {
  865. v->x += c.x;
  866. v->y += c.y;
  867. v->z += c.z;
  868. }
  869. /**************** CoordDiv ****************/
  870. /*
  871. **
  872. */
  873. void CoordDiv( Coord *v, const int n )
  874. {
  875. v->x /= n;
  876. v->y /= n;
  877. v->z /= n;
  878. }
  879. /**************** FillAtom ****************/
  880. /*
  881. ** Fill an atom with data. Only one of the two names is set.
  882. **
  883. ** NOTE: in principle the new, sequential residue number could be found
  884. ** by going through the residue list, but for now comparisons will
  885. ** be based on the residue ID (cf. FindAtom).
  886. */
  887. Atom FillAtom( Resid res_id, ID res_nam, ID atom_nam, const int which )
  888. {
  889. /* char *fct_name = "FillAtom"; */
  890. Atom at;
  891. InitAtom( &at );
  892. if ( which == use_int )
  893. memcpy( at.atom_int, atom_nam, size_ID );
  894. if ( which == use_ext )
  895. memcpy( at.atom_ext, atom_nam, size_ID );
  896. memcpy( at.res_nam, res_nam, size_ID );
  897. strcpy( at.res_id, res_id );
  898. ReadUniqResid( &at );
  899. /*--at.res_num = at.res_num_orig; */
  900. /*
  901. STATUS("filling:");
  902. printf("%s ", res_id);
  903. PRINTIDv(res_nam);
  904. printf(" %i\n", at.res_num_orig);
  905. */
  906. return( at );
  907. }
  908. /**************** FindAtom1 ****************/
  909. /*
  910. ** Try to find an atom <at> in the external or internal (depending on <which>)
  911. ** atom name list of a molecule <molptr>.
  912. ** Residues are matched on 'res_id'.
  913. ** If <guess>, some name mappings are guessed (only for external names).
  914. ** The list index is returned in <idx>, and the corresponding atom in
  915. ** the function value.
  916. */
  917. Atom *FindAtom1( int *idx, Atom *at, Mol *molptr, const int which, const Boolean guess )
  918. {
  919. /* char *fct_name = "FindAtom1"; */
  920. int i = 0, count;
  921. /* int nmatch; */
  922. Atom *atoms, *match, *try_variable;
  923. atoms = molptr->atoms;
  924. count = molptr->atom_count;
  925. /* loop over all atoms and compare */
  926. #ifdef DEBUG
  927. STATUS( "trying to find:" );
  928. printf( " " );
  929. WriteAtom( stdout, at, use_both );
  930. putchar( '\n' );
  931. #endif
  932. while ( i < count )
  933. {
  934. #ifdef DEBUG
  935. printf( "looking at: " );
  936. WriteAtom( stdout, atoms, use_both );
  937. #endif
  938. /* match residue ID's */
  939. if ( EQ( atoms->res_id, at->res_id ) )
  940. {
  941. /* match atom names */
  942. if ( which == use_ext )
  943. {
  944. if ( EQID( atoms->atom_ext, at->atom_ext ) )
  945. break;
  946. }
  947. else if ( which == use_int )
  948. {
  949. if ( EQID( atoms->atom_int, at->atom_int ) )
  950. break;
  951. }
  952. }
  953. atoms++;
  954. i++;
  955. }
  956. *idx = i;
  957. /* found */
  958. if ( i < count )
  959. return( atoms );
  960. /* not found */
  961. if ( which == use_ext && guess )
  962. {
  963. /* derive a closely related name */
  964. if ( ( try_variable = GuessAtom( at ) ) == NULL )
  965. {
  966. /* find wildcard matches */
  967. #ifdef DEBUG
  968. FindAtomsWC( &nmatch, at, molptr, use_ext );
  969. #endif
  970. return( NULL );
  971. }
  972. /* try again */
  973. #ifdef DEBUG
  974. STATUS( "trying again with:" );
  975. printf( " " );
  976. WriteAtom( stdout, try_variable, use_both);
  977. putchar( '\n' );
  978. #endif
  979. match = FindAtom1( idx, try_variable, molptr, use_ext, false );
  980. if ( match )
  981. {
  982. printf( " External atom name remapped for: " );
  983. WriteAtom( stdout, at, use_ext );
  984. printf( " on: " );
  985. PRINTIDv( try_variable->atom_ext );
  986. putchar( '\n' );
  987. return( match );
  988. }
  989. else
  990. {
  991. /* find wildcard matches */
  992. #ifdef DEBUG
  993. FindAtomsWC( &nmatch, at, molptr, use_ext );
  994. #endif
  995. return( NULL );
  996. }
  997. }
  998. return( NULL );
  999. }
  1000. /**************** FindAtom2 ****************/
  1001. /*
  1002. ** New version of FindAtom1.
  1003. ** - Faster: makes use of residue list.
  1004. ** - Correct residue names where needed.
  1005. **
  1006. ** Try to find an atom <at> in the external or internal (depending on <which>)
  1007. ** atom name list of a molecule <molptr>.
  1008. ** Residues are matched on 'res_id'.
  1009. ** If <guess>, some name mappings are guessed (only for external names).
  1010. ** The list index is returned in <idx>, and the corresponding atom in
  1011. ** the function value.
  1012. **
  1013. ** If the residue list is scrambled (i.e. atoms belonging to one residue are
  1014. ** scattered across more than one entry in molptr->residues) the routine
  1015. ** fails (cf. comment in ExpandAtoms->MakeDefsMol).
  1016. */
  1017. Atom *FindAtom2( int *idx, Atom *theAtom, Mol *molptr, const int which,
  1018. const Boolean guess )
  1019. {
  1020. /* char *fct_name = "FindAtom2"; */
  1021. Atom *at = theAtom, *match, mod, *try_variable;
  1022. Atomptr *atomptrs;
  1023. Residue *res;
  1024. char *res_nam, *lastcharptr;
  1025. int *atomidxs, res_idx, count;
  1026. /* int nmatch; */
  1027. #ifdef DEBUG
  1028. STATUS( "trying to find:" );
  1029. printf( " " );
  1030. WriteAtom( stdout, at, use_both );
  1031. putchar( '\n' );
  1032. #endif
  1033. find_atom_err = 0;
  1034. /* find the residue; map Arg+ onto Arg etc. */
  1035. /*
  1036. (The mapping is necessary because the expanded AtomLIB definitions will
  1037. not contain Arg+ etc. (even though they exist in the unexpanded AtomLIB)
  1038. if the set (i.e. the PDB file) does not contain Arg+ etc.; the mapping
  1039. is only necessary to find the residue in the expanded AtomLIB.)
  1040. */
  1041. res_nam = at->res_nam;
  1042. res_idx = FindResidueIndexFromId( at->res_id, molptr );
  1043. if ( res_idx == -1 )
  1044. {
  1045. lastcharptr = LastNonBlank( at->res_nam, size_ID );
  1046. if ( *lastcharptr == '+' || *lastcharptr == '-' )
  1047. {
  1048. printf( " Residue name remapped for: " );
  1049. WriteAtom( stdout, at, which );
  1050. memcpy( &mod, at, sizeof( Atom ) );
  1051. at = &mod;
  1052. *LastNonBlank( at->res_nam, size_ID ) = ' ';
  1053. MakeUniqResid( at );
  1054. res_idx = FindResidueIndexFromId( at->res_id, molptr );
  1055. printf( " on: " );
  1056. PRINTIDv( at->res_nam );
  1057. putchar( '\n' );
  1058. }
  1059. }
  1060. if ( res_idx == -1 )
  1061. {
  1062. find_atom_err = 1;
  1063. return( NULL );
  1064. }
  1065. #ifdef DEBUG
  1066. sprintf( msg_string, "found residue index %i", res_idx );
  1067. STATUSm;
  1068. #endif
  1069. /* find the atom */
  1070. res = &molptr->residues[res_idx];
  1071. count = res->atom_count;
  1072. atomptrs = res->atomptrs;
  1073. atomidxs = res->atomidxs;
  1074. while ( count )
  1075. {
  1076. #ifdef DEBUG
  1077. printf( "looking at: " );
  1078. WriteAtom( stdout, *atomptrs, use_both );
  1079. printf( " index %i\n", *atomidxs );
  1080. #endif
  1081. if ( which == use_ext )
  1082. {
  1083. if ( EQID( (*atomptrs)->atom_ext, at->atom_ext ) )
  1084. {
  1085. *idx = *atomidxs;
  1086. break;
  1087. }
  1088. }
  1089. else if ( which == use_int )
  1090. {
  1091. if ( EQID( (*atomptrs)->atom_int, at->atom_int ) )
  1092. {
  1093. *idx = *atomidxs;
  1094. break;
  1095. }
  1096. }
  1097. atomptrs++;
  1098. atomidxs++;
  1099. count--;
  1100. }
  1101. /* found */
  1102. if ( count )
  1103. return( *atomptrs );
  1104. /* not found */
  1105. if ( which == use_ext && guess )
  1106. {
  1107. /* derive a closely related name */
  1108. if ( ( try_variable = GuessAtom( at ) ) == NULL )
  1109. {
  1110. /* find wildcard matches */
  1111. #ifdef DEBUG
  1112. FindAtomsWC( &nmatch, at, molptr, use_ext );
  1113. #endif
  1114. return( NULL );
  1115. }
  1116. /* try again */
  1117. #ifdef DEBUG
  1118. STATUS( "trying again with:" );
  1119. printf( " " );
  1120. WriteAtom( stdout, try_variable, use_both);
  1121. putchar( '\n' );
  1122. #endif
  1123. match = FindAtom2( idx, try_variable, molptr, use_ext, false );
  1124. if ( match )
  1125. {
  1126. printf( " External atom name remapped for: " );
  1127. WriteAtom( stdout, at, use_ext );
  1128. printf( " on: " );
  1129. PRINTIDv( try_variable->atom_ext );
  1130. putchar( '\n' );
  1131. return( match );
  1132. }
  1133. else
  1134. {
  1135. /* find wildcard matches */
  1136. #ifdef DEBUG
  1137. FindAtomsWC( &nmatch, at, molptr, use_ext );
  1138. #endif
  1139. return( NULL );
  1140. }
  1141. }
  1142. return( NULL );
  1143. }
  1144. /**************** FindAtom3 ****************/
  1145. /*
  1146. ** New version of FindAtom1.
  1147. ** Handles chain and residue number wildcards such as set by AtomLIB.
  1148. ** This routine captures the matching of wildcards that was formerly
  1149. ** handled by ExpandAtoms, and is meant to be used by MapAtoms/MapPtrAtoms
  1150. ** only.
  1151. ** Residue name variants (such as Arg+) must be explicitly present in the
  1152. ** molecule stored at <molptr> (i.e. in the AtomLIB).
  1153. ** In contrast to FindAtom2 the molecule does not have to contain a
  1154. ** residue list.
  1155. */
  1156. Atom *FindAtom3( int *idx, Atom *at, Mol *molptr, const int which,
  1157. const Boolean guess )
  1158. {
  1159. /* char *fct_name = "FindAtom3"; */
  1160. int i = 0, count;
  1161. /* int nmatch; */
  1162. Atom *atoms, *match, *try_variable;
  1163. atoms = molptr->atoms;
  1164. count = molptr->atom_count;
  1165. /* loop over all atoms and compare */
  1166. #ifdef DEBUG
  1167. STATUS( "trying to find:" );
  1168. printf( " " );
  1169. WriteAtom( stdout, at, use_both );
  1170. putchar( '\n' );
  1171. #endif
  1172. while ( i < count )
  1173. {
  1174. #ifdef DEBUG
  1175. printf( "looking at: " );
  1176. WriteAtom( stdout, atoms, use_both );
  1177. #endif
  1178. /* match residue and chain */
  1179. if ( NOTEQID( atoms->res_nam, at->res_nam ) )
  1180. {
  1181. atoms++;
  1182. i++;
  1183. continue;
  1184. }
  1185. if ( NOTEQID( atoms->chain, at->chain ) && atoms->chain[0] != '*' )
  1186. {
  1187. atoms++;
  1188. i++;
  1189. continue;
  1190. }
  1191. if ( atoms->res_num_orig == at->res_num_orig ||
  1192. atoms->res_num_orig == wild_RESNUM )
  1193. {
  1194. /* match atom names */
  1195. /* specific defs MUST come BEFORE wildcards in order to be found first */
  1196. if ( which == use_ext )
  1197. {
  1198. if ( EQID( atoms->atom_ext, at->atom_ext ) )
  1199. break;
  1200. }
  1201. else if ( which == use_int )
  1202. {
  1203. if ( EQID( atoms->atom_int, at->atom_int ) )
  1204. break;
  1205. }
  1206. }
  1207. atoms++;
  1208. i++;
  1209. }
  1210. *idx = i;
  1211. /* found */
  1212. if ( i < count )
  1213. return( atoms );
  1214. /* not found */
  1215. if ( which == use_ext && guess )
  1216. {
  1217. /* derive a closely related name */
  1218. if ( ( try_variable = GuessAtom( at ) ) == NULL )
  1219. {
  1220. /* find wildcard matches */
  1221. #ifdef DEBUG
  1222. FindAtomsWC( &nmatch, at, molptr, use_ext );
  1223. #endif
  1224. return( NULL );
  1225. }
  1226. /* try again */
  1227. #ifdef DEBUG
  1228. STATUS( "trying again with:" );
  1229. printf( " " );
  1230. WriteAtom( stdout, try_variable, use_both);
  1231. putchar( '\n' );
  1232. #endif
  1233. match = FindAtom3( idx, try_variable, molptr, use_ext, false );
  1234. if ( match )
  1235. {
  1236. printf( " External atom name remapped for: " );
  1237. WriteAtom( stdout, at, use_ext );
  1238. printf( " on: " );
  1239. PRINTIDv( try_variable->atom_ext );
  1240. putchar( '\n' );
  1241. return( match );
  1242. }
  1243. else
  1244. {
  1245. /* find wildcard matches */
  1246. #ifdef DEBUG
  1247. FindAtomsWC( &nmatch, at, molptr, use_ext );
  1248. #endif
  1249. return( NULL );
  1250. }
  1251. }
  1252. return( NULL );
  1253. }
  1254. /**************** TestFindAtom2 ****************/
  1255. /*
  1256. **
  1257. */
  1258. void TestFindAtom2( Mol *molptr )
  1259. {
  1260. char *fct_name = "TestFindAtom2";
  1261. int idx, count = molptr->atom_count;
  1262. Atom *atoms = molptr->atoms, *at;
  1263. STATUS( "entering" );
  1264. while ( count-- )
  1265. {
  1266. if ( ! ( at = FindAtom2( &idx, atoms, molptr, use_ext, true ) ) )
  1267. WriteNotFoundAtom( stdout, atoms, use_ext, use_both );
  1268. printf( "%i ", idx );
  1269. if ( at != molptr->atoms + idx )
  1270. {
  1271. puts( "error" );
  1272. WriteAtom( stdout, at, use_both ); putchar( '\n' );
  1273. WriteAtom( stdout, &atoms[idx], use_both ); putchar( '\n' );
  1274. }
  1275. else
  1276. putchar( '\n' );
  1277. atoms++;
  1278. }
  1279. STATUS( "leaving" );
  1280. }
  1281. /**************** FindAtomsWC ****************/
  1282. /*
  1283. ** Try to find an atom <at> in the external or internal (depending on <which>
  1284. ** atom name list of a molecule <molptr>,
  1285. ** matching UP TO a wildcard character # or *.
  1286. ** Residues are matched on 'res_id'.
  1287. ** The number of matches is returned in <nmatch>, and the address of an
  1288. ** Atomptr array in the function value.
  1289. */
  1290. Atomptr *FindAtomsWC( int *nmatch, Atom *at, Mol *molptr, const int which )
  1291. {
  1292. /* char *fct_name = "FindAtomsWC"; */
  1293. char *wc;
  1294. size_t len = 0;
  1295. char test[size_ID+1];
  1296. Atom *atoms;
  1297. Atomptr *match = MatchList;
  1298. int i=0, n=0;
  1299. int count;
  1300. atoms = molptr->atoms;
  1301. count = molptr->atom_count;
  1302. *nmatch = 0;
  1303. /* loop over all atoms and compare */
  1304. if ( which == use_ext )
  1305. {
  1306. strncpy( test, at->atom_ext, size_ID );
  1307. if ( ( wc = strpbrk( test, "#*" ) ) == NULL )
  1308. return( NULL );
  1309. len = (size_t)( wc - test );
  1310. }
  1311. else if ( which == use_int )
  1312. {
  1313. strncpy( test, at->atom_int, size_ID );
  1314. if ( ( wc = strpbrk( test, "#*" ) ) == NULL )
  1315. return( NULL );
  1316. len = (size_t)( wc - test );
  1317. }
  1318. while ( i < count )
  1319. {
  1320. /* match residue ID's -- assume unordered list */
  1321. if ( EQ( atoms->res_id, at->res_id ) )
  1322. {
  1323. /* match atom names */
  1324. if ( which == use_ext )
  1325. {
  1326. if ( EQn( atoms->atom_ext, at->atom_ext, len ) )
  1327. {
  1328. if ( ++n > max_MATCH )
  1329. {
  1330. puts( " * ERROR: max_MATCH too small" );
  1331. exit( 1 );
  1332. }
  1333. *match++ = atoms;
  1334. }
  1335. }
  1336. else if ( which == use_int )
  1337. {
  1338. if ( EQn( atoms->atom_int, at->atom_int, len ) )
  1339. {
  1340. if ( ++n > max_MATCH )
  1341. {
  1342. puts( " * ERROR: max_MATCH too small" );
  1343. exit( 1 );
  1344. }
  1345. *match++ = atoms;
  1346. }
  1347. }
  1348. }
  1349. atoms++;
  1350. i++;
  1351. }
  1352. *nmatch = n;
  1353. #ifdef DEBUG
  1354. if ( n ) {
  1355. STATUS( "found wildcard representations:" );
  1356. for ( i=0; i<n; i++ )
  1357. {
  1358. printf( " " );
  1359. WriteAtom( stdout, MatchList[i], use_both );
  1360. putchar('\n');
  1361. }
  1362. }
  1363. #endif
  1364. if ( n )
  1365. return( MatchList );
  1366. else
  1367. return( NULL );
  1368. }
  1369. /**************** WriteNotFoundAtom ****************/
  1370. /*
  1371. **
  1372. */
  1373. void WriteNotFoundAtom( FILE *fp, Atom *atom, const int find_which,
  1374. const int print_which )
  1375. {
  1376. if ( find_atom_err == 1 )
  1377. fputs( " Residue name not found: ", fp );
  1378. else
  1379. {
  1380. if ( find_which == use_ext )
  1381. fputs( " External atom name not found: ", fp );
  1382. if ( find_which == use_int )
  1383. fputs( " Internal atom name not found: ", fp );
  1384. }
  1385. WriteAtom( fp, atom, print_which );
  1386. fputc( '\n', fp );
  1387. }
  1388. /**************** FindResidueIndexFromNum ****************/
  1389. /*
  1390. ** Returns the index in the residues-array of the residue
  1391. ** for which the new residue number is <res_num>.
  1392. */
  1393. int FindResidueIndexFromNum( const int res_num, Mol *molptr )
  1394. {
  1395. int i = 0, count;
  1396. Residue *residues;
  1397. residues = molptr->residues;
  1398. count = molptr->res_count;
  1399. while ( i < count )
  1400. {
  1401. if ( res_num == residues->res_num_new )
  1402. return( i );
  1403. residues++;
  1404. i++;
  1405. }
  1406. return( -1 );
  1407. }
  1408. /**************** FindResidueIndexFromOrigNum ****************/
  1409. /*
  1410. ** Returns the index in the residues-array of the residue
  1411. ** for which the original residue number, chain id and insertion code are
  1412. ** <res_num>, <chain> and <insert>.
  1413. */
  1414. int FindResidueIndexFromOrigNum( const int res_num, ID chain, char insert,
  1415. Mol *molptr )
  1416. {
  1417. int i = 0, count;
  1418. Residue *residues;
  1419. residues = molptr->residues;
  1420. count = molptr->res_count;
  1421. while ( i < count )
  1422. {
  1423. if ( res_num == residues->res_num_orig &&
  1424. EQID( chain, residues->chain ) && insert == residues->res_insert )
  1425. return( i );
  1426. residues++;
  1427. i++;
  1428. }
  1429. return( -1 );
  1430. }
  1431. /**************** FindResidueIndexFromId ****************/
  1432. /*
  1433. ** Returns the residue index of the residue
  1434. ** for which the ID is <res_id>, by searching the residue list.
  1435. */
  1436. int FindResidueIndexFromId( Resid res_id, Mol *molptr )
  1437. {
  1438. int i = 0, count;
  1439. Residue *residues;
  1440. residues = molptr->residues;
  1441. count = molptr->res_count;
  1442. while ( i < count )
  1443. {
  1444. if ( EQ( res_id, residues->res_id ) )
  1445. return( i );
  1446. residues++;
  1447. i++;
  1448. }
  1449. return( -1 );
  1450. }
  1451. /**************** FindResidueNumFromId ****************/
  1452. /*
  1453. ** Returns the new residue number of the residue
  1454. ** for which the ID is <res_id>, by searching the residue list.
  1455. */
  1456. int FindResidueNumFromId( Resid res_id, Mol *molptr )
  1457. {
  1458. int i = 0, count;
  1459. Residue *residues;
  1460. residues = molptr->residues;
  1461. count = molptr->res_count;
  1462. while ( i < count )
  1463. {
  1464. if ( EQ( res_id, residues->res_id ) )
  1465. return( residues->res_num_new );
  1466. residues++;
  1467. i++;
  1468. }
  1469. return( -1 );
  1470. }
  1471. /**************** FindResidueNamFromId ****************/
  1472. /*
  1473. ** Returns the residue name of the residue for which the ID
  1474. ** is <res_id> (not comparing the part which corresponds to the residue name
  1475. ** of course...) by searching the residue list.
  1476. */
  1477. char *FindResidueNamFromId( Resid res_id, Mol *molptr )
  1478. {
  1479. int i = 0, count;
  1480. Residue *residues;
  1481. static char unk[size_ID+1] = "UNK ";
  1482. residues = molptr->residues;
  1483. count = molptr->res_count;
  1484. while ( i < count )
  1485. {
  1486. if ( EQn( res_id, residues->res_id, size_ID+6 ) )
  1487. return( residues->res_nam );
  1488. residues++;
  1489. i++;
  1490. }
  1491. return( unk );
  1492. }
  1493. /**************** InitAtomS ****************/
  1494. /*
  1495. **
  1496. */
  1497. void InitAtomS( Atom *atom, int count )
  1498. {
  1499. while ( count-- )
  1500. InitAtom( atom++ );
  1501. }
  1502. /**************** InitAtom ****************/
  1503. /*
  1504. **
  1505. */
  1506. void InitAtom( Atom *atom )
  1507. {
  1508. atom->res_num_new = 0;
  1509. atom->res_num_orig = 0;
  1510. Blank( atom->chain, size_ID );
  1511. Blank( atom->atom_int, size_ID );
  1512. Blank( atom->atom_ext, size_ID );
  1513. Blank( atom->atom_element_symbol, size_ID );
  1514. Blank( atom->res_nam, size_ID );
  1515. atom->res_insert = ' ';
  1516. *(atom->res_id) = '\0';
  1517. }
  1518. /**************** InitPsatomS ****************/
  1519. /*
  1520. **
  1521. */
  1522. void InitPsatomS( Psatom *psatom, int count )
  1523. {
  1524. while ( count-- )
  1525. InitPsatom( psatom++ );
  1526. }
  1527. /**************** InitPsatom ****************/
  1528. /*
  1529. **
  1530. */
  1531. void InitPsatom( Psatom *psatom )
  1532. {
  1533. psatom->pseudo_typ = 0;
  1534. psatom->num_form = 0;
  1535. psatom->res_num_orig = 0;
  1536. Blank( psatom->chain, size_ID );
  1537. Blank( psatom->res_nam, size_ID );
  1538. Blank( psatom->pseudo_nam, size_ID );
  1539. Blank( (char *)psatom->form_nam, size_ID*max_PSFORM );
  1540. psatom->res_insert = ' ';
  1541. *(psatom->res_id) = '\0';
  1542. }
  1543. /**************** GetLIBName ****************/
  1544. /*
  1545. ** Determine the library name for the AtomLIB to be used.
  1546. ** If option <option> has been set (i.e. <option> is not item_NONE and
  1547. ** the option value is not "none"), the routine uses the option value
  1548. ** instead of presenting a menu.
  1549. */
  1550. char *GetLIBName( const int option )
  1551. {
  1552. Menu *oldmenu;
  1553. int item;
  1554. char *name, *optval;
  1555. static MenuItem menulist[] =
  1556. {
  1557. { item_aqua, "aqua", none, on },
  1558. { item_disman, "disman", none, on },
  1559. { item_disgeo, "disgeo", none, on },
  1560. { item_diana, "diana", none, on },
  1561. { item_xplor, "xplor", none, on },
  1562. { item_xplori, "xplor-inv", none, on },
  1563. { item_biosym, "biosym", none, on },
  1564. { item_whatif, "whatif", none, on },
  1565. { item_local, "local", none, on },
  1566. { item_user, "user", none, on },
  1567. { item_copy, "copy", none, on },
  1568. { item_END, "end", none, on } /* same as in AquaWhat, AquaPseudo and AquaHow */
  1569. };
  1570. static Menu menu =
  1571. {
  1572. "GetLIBName menu", "format", "Give atom name format:",
  1573. sizeof(menulist)/sizeof(MenuItem)
  1574. };
  1575. oldmenu = SetMenu( &menu, menulist );
  1576. if ( option != item_NONE )
  1577. optval = GetOptionCVal( option ); /* use value of option */
  1578. /* OK if option menu has not been swapped */
  1579. else
  1580. optval = "none";
  1581. while ( true )
  1582. {
  1583. if ( EQ( optval, "none" ) )
  1584. item = ReadMenuItem();
  1585. else
  1586. item = FindMenuItem( optval );
  1587. switch ( item )
  1588. {
  1589. case item_aqua:
  1590. case item_disman:
  1591. case item_disgeo:
  1592. case item_diana:
  1593. case item_xplor:
  1594. case item_xplori:
  1595. case item_biosym:
  1596. case item_whatif:
  1597. case item_local:
  1598. case item_user:
  1599. case item_copy:
  1600. name = GetMenuItemKey( item );
  1601. ResetMenu( oldmenu );
  1602. return( name );
  1603. case item_END:
  1604. case item_NULL:
  1605. ResetMenu( oldmenu );
  1606. return( NULL );
  1607. default:
  1608. ProcessMenuError( menu_fatal );
  1609. break;
  1610. }
  1611. }
  1612. }
  1613. /**************** ProcessAtomLIB ****************/
  1614. /*
  1615. ** Read and process an AtomLIB i.e. a file with atom name mappings.
  1616. */
  1617. Mol *ProcessAtomLIB( Mol *molptr, char *lib_nam, Filnam predef )
  1618. {
  1619. char *fct_name = "ProcessAtomLIB";
  1620. char *usrnam = NULL;
  1621. Atom *atmap_list;
  1622. Mol *atmap_mol;
  1623. Filnam lib_filnam;
  1624. FILE *lib_fp = NULL;
  1625. Boolean done = false;
  1626. Menu *oldmenu;
  1627. int atmap_count;
  1628. if ( EQ( lib_nam, "user" ) || EQ( lib_nam, "local" ) || EQ( lib_nam, "whatif" ) )
  1629. /* user defined library in Aqua format */
  1630. {
  1631. oldmenu = SetOneMenu( "Give name of atom-library file (or - to end):" );
  1632. if ( EQ( lib_nam, "local" ) )
  1633. usrnam = "AtomLIB";
  1634. else if ( EQ( lib_nam, "whatif" ) )
  1635. usrnam = predef;
  1636. else
  1637. usrnam = GetOptionCVal( opt_atmlib ); /* use value of atomlib option */
  1638. /* OK if option menu has not been swapped */
  1639. while ( !done )
  1640. {
  1641. if ( !usrnam )
  1642. {
  1643. MReadWord( lib_filnam );
  1644. if ( *lib_filnam == '-' || strlen( lib_filnam ) == 0 )
  1645. {
  1646. ResetMenu( oldmenu );
  1647. return( NULL );
  1648. }
  1649. }
  1650. else
  1651. {
  1652. strcpy( lib_filnam, usrnam );
  1653. usrnam = NULL; /* to prevent infinite loop */
  1654. }
  1655. if ( terseness < 6 ) {
  1656. printf( "Now opening: %s\n", lib_filnam );
  1657. }
  1658. if ( ! ( done = OPENr( lib_fp, lib_filnam ) ) )
  1659. {
  1660. printf( " * atom-library file <%s> could not be opened\n", lib_filnam );
  1661. MError();
  1662. }
  1663. }
  1664. ResetMenu( oldmenu );
  1665. if ( terseness < 6 ) {
  1666. STATUS( "reading user AtomLIB" );
  1667. }
  1668. }
  1669. else
  1670. /* standard Aqua library from Aqua data directory */
  1671. {
  1672. strcpy( lib_filnam, "AtomLIB-" );
  1673. strcat( lib_filnam, lib_nam );
  1674. lib_fp = AquaDataFile( lib_filnam );
  1675. if ( !lib_fp )
  1676. return( NULL );
  1677. if ( terseness < 6 ) {
  1678. STATUS( "reading standard AtomLIB" );
  1679. }
  1680. }
  1681. atmap_list = ReadAtomLIB( lib_fp, &atmap_count );
  1682. if ( !atmap_list || atmap_count == 0 )
  1683. {
  1684. puts( " * Atom name definition list empty" );
  1685. return( NULL );
  1686. }
  1687. sprintf( msg_string, "%i atom name definitions read", atmap_count );
  1688. if ( terseness < 6 ) {
  1689. STATUSm;
  1690. }
  1691. if ( OptionTrue( opt_prtlib ) )
  1692. WriteFAtoms( stdout, atmap_list, atmap_count );
  1693. if ( !OptionTrue( opt_find2 ) )
  1694. return( MakeDefsMol( atmap_list, atmap_count, false ) );
  1695. /* expand the list from 'wildcard' residue numbers to individual residues */
  1696. if ( terseness < 6 ) {
  1697. STATUS( "generating definitions for present molecule" );
  1698. }
  1699. atmap_mol = ExpandAtoms( atmap_list, atmap_count, molptr );
  1700. free( atmap_list );
  1701. sprintf( msg_string, "%i atom name definitions active for present molecule",
  1702. atmap_mol->atom_count );
  1703. if ( terseness < 6 ) {
  1704. STATUSm;
  1705. }
  1706. if ( OptionTrue( opt_prtlib ) )
  1707. WriteFAtoms( stdout, atmap_mol->atoms, atmap_mol->atom_count );
  1708. return( atmap_mol );
  1709. }
  1710. /**************** ProcessStereoLIB ****************/
  1711. /*
  1712. ** Read and process a StereoLIB i.e. a file describing the "equivalent
  1713. ** atoms" in prochiral groups.
  1714. ** This routine is an analogue of ProcessPseudo.
  1715. ** The descriptions and data types are the same as for pseudo atoms.
  1716. */
  1717. Psatom *ProcessStereoLIB( int *stereo_count, Mol *molptr, char *lib )
  1718. {
  1719. char *usrnam = NULL, *fct_name = "ProcessStereoLIB";
  1720. char *lib_nam;
  1721. Psatom *stereo_list;
  1722. Filnam lib_filnam;
  1723. FILE *lib_fp = NULL;
  1724. Boolean done = false;
  1725. Menu *oldmenu;
  1726. lib_nam = GetLIBName( opt_rstinp );
  1727. if ( !lib_nam )
  1728. return( NULL ); /* no processing done */
  1729. if ( EQ( lib_nam, "user" ) )
  1730. /* type "user": user defined library in Aqua format */
  1731. {
  1732. oldmenu = SetOneMenu( "Give name of stereo-library file:" );
  1733. usrnam = GetOptionCVal( opt_sterlib ); /* use value of stereolib option */
  1734. /* OK if option menu has not been swapped */
  1735. while ( !done )
  1736. {
  1737. if ( !usrnam )
  1738. MReadWord( lib_filnam );
  1739. else
  1740. {
  1741. strcpy( lib_filnam, usrnam );
  1742. usrnam = NULL; /* to prevent infinite loop */
  1743. }
  1744. if ( terseness < 6 ) {
  1745. printf( "Now opening: %s\n", lib_filnam );
  1746. }
  1747. if ( ! ( done = OPENr( lib_fp, lib_filnam ) ) )
  1748. {
  1749. printf( " * stereo-library file <%s> could not be opened\n", lib_filnam );
  1750. MError();
  1751. }
  1752. }
  1753. ResetMenu( oldmenu );
  1754. if ( terseness < 6 ) {
  1755. STATUS( "Reading user StereoLIB" );
  1756. }
  1757. }
  1758. else
  1759. /* type "local", "diana", etc: standard Aqua library from Aqua data directory */
  1760. {
  1761. lib_fp = AquaDataFile( lib );
  1762. if ( !lib_fp )
  1763. exit( 1 );
  1764. if ( terseness < 6 ) {
  1765. STATUS( "Reading standard StereoLIB" );
  1766. }
  1767. }
  1768. stereo_list = ReadPseudoLIB( lib_fp, stereo_count );
  1769. if (

Large files files are truncated, but you can click here to view the full file