/*
FILE:     ndb_to_pdb.C
*/
/*
VERSION:  1.600
*/
/*
DATE:     2/3/2005
*/
/*
  Comments and Questions to: sw-help@rcsb.rutgers.edu
*/
/*
COPYRIGHT 1999-2005 Rutgers - The State University of New Jersey

This software is provided WITHOUT WARRANTY OF MERCHANTABILITY OR
FITNESS FOR A PARTICULAR PURPOSE OR ANY OTHER WARRANTY, EXPRESS OR
IMPLIED.  RUTGERS MAKE NO REPRESENTATION OR WARRANTY THAT THE
SOFTWARE WILL NOT INFRINGE ANY PATENT, COPYRIGHT OR OTHER
PROPRIETARY RIGHT.

The user of this software shall indemnify, hold harmless and defend
Rutgers, its governors, trustees, officers, employees, students,
agents and the authors against any and all claims, suits,
losses, liabilities, damages, costs, fees, and expenses including
reasonable attorneys' fees resulting from or arising out of the
use of this software.  This indemnification shall include, but is
not limited to, any and all claims alleging products liability.
*/
/*
               PDB SOFTWARE LICENSE AGREEMENT

BY CLICKING THE ACCEPTANCE BUTTON OR INSTALLING OR USING 
THIS "SOFTWARE, THE INDIVIDUAL OR ENTITY LICENSING THE  
SOFTWARE ("LICENSEE") IS CONSENTING TO BE BOUND BY AND IS 
BECOMING A PARTY TO THIS AGREEMENT.  IF LICENSEE DOES NOT 
AGREE TO ALL OF THE TERMS OF THIS AGREEMENT
THE LICENSEE MUST NOT INSTALL OR USE THE SOFTWARE.

1. LICENSE AGREEMENT

This is a license between you ("Licensee") and the Protein Data Bank (PDB) 
at Rutgers, The State University of New Jersey (hereafter referred to 
as "RUTGERS").   The software is owned by RUTGERS and protected by 
copyright laws, and some elements are protected by laws governing 
trademarks, trade dress and trade secrets, and may be protected by 
patent laws. 

2. LICENSE GRANT

RUTGERS grants you, and you hereby accept, non-exclusive, royalty-free 
perpetual license to install, use, modify, prepare derivative works, 
incorporate into other computer software, and distribute in binary 
and source code format, or any derivative work thereof, together with 
any associated media, printed materials, and on-line or electronic 
documentation (if any) provided by RUTGERS (collectively, the "SOFTWARE"), 
subject to the following terms and conditions: (i) any distribution 
of the SOFTWARE shall bind the receiver to the terms and conditions 
of this Agreement; (ii) any distribution of the SOFTWARE in modified 
form shall clearly state that the SOFTWARE has been modified from 
the version originally obtained from RUTGERS.  

2. COPYRIGHT; RETENTION OF RIGHTS.  

The above license grant is conditioned on the following: (i) you must 
reproduce all copyright notices and other proprietary notices on any 
copies of the SOFTWARE and you must not remove such notices; (ii) in 
the event you compile the SOFTWARE, you will include the copyright 
notice with the binary in such a manner as to allow it to be easily 
viewable; (iii) if you incorporate the SOFTWARE into other code, you 
must provide notice that the code contains the SOFTWARE and include 
a copy of the copyright notices and other proprietary notices.  All 
copies of the SOFTWARE shall be subject to the terms of this Agreement.  

3. NO MAINTENANCE OR SUPPORT; TREATMENT OF ENHANCEMENTS 

RUTGERS is under no obligation whatsoever to: (i) provide maintenance 
or support for the SOFTWARE; or (ii) to notify you of bug fixes, patches, 
or upgrades to the features, functionality or performance of the 
SOFTWARE ("Enhancements") (if any), whether developed by RUTGERS 
or third parties.  If, in its sole discretion, RUTGERS makes an 
Enhancement available to you and RUTGERS does not separately enter 
into a written license agreement with you relating to such bug fix, 
patch or upgrade, then it shall be deemed incorporated into the SOFTWARE 
and subject to this Agreement. You are under no obligation whatsoever 
to provide any Enhancements to RUTGERS or the public that you may 
develop over time; however, if you choose to provide your Enhancements 
to RUTGERS, or if you choose to otherwise publish or distribute your 
Enhancements, in source code form without contemporaneously requiring 
end users or RUTGERS to enter into a separate written license agreement 
for such Enhancements, then you hereby grant RUTGERS a non-exclusive,
royalty-free perpetual license to install, use, modify, prepare
derivative works, incorporate into the SOFTWARE or other computer
software, distribute, and sublicense your Enhancements or derivative
works thereof, in binary and source code form.

4. FEES.  There is no license fee for the SOFTWARE.  If Licensee
wishes to receive the SOFTWARE on media, there may be a small charge
for the media and for shipping and handling.  Licensee is
responsible for any and all taxes.

5. TERMINATION.  Without prejudice to any other rights, Licensor
may terminate this Agreement if Licensee breaches any of its terms
and conditions.  Upon termination, Licensee shall destroy all
copies of the SOFTWARE.

6. PROPRIETARY RIGHTS.  Title, ownership rights, and intellectual
property rights in the Product shall remain with RUTGERS.  Licensee 
acknowledges such ownership and intellectual property rights and will 
not take any action to jeopardize, limit or interfere in any manner 
with RUTGERS' ownership of or rights with respect to the SOFTWARE.  
The SOFTWARE is protected by copyright and other intellectual 
property laws and by international treaties.  Title and related 
rights in the content accessed through the SOFTWARE is the property 
of the applicable content owner and is protected by applicable law.  
The license granted under this Agreement gives Licensee no rights to such
content.

7. DISCLAIMER OF WARRANTY.  THE SOFTWARE IS PROVIDED FREE OF 
CHARGE, AND, THEREFORE, ON AN "AS IS" BASIS, WITHOUT WARRANTY OF 
ANY KIND, INCLUDING WITHOUT LIMITATION THE WARRANTIES THAT IT 
IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE 
OR NON-INFRINGING.  THE ENTIRE RISK AS TO THE QUALITY AND 
PERFORMANCE OF THE SOFTWARE IS BORNE BY LICENSEE.  SHOULD THE 
SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, THE LICENSEE AND NOT 
LICENSOR ASSUMES THE ENTIRE COST OF ANY SERVICE AND REPAIR.  
THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF 
THIS AGREEMENT.  NO USE OF THE PRODUCT IS AUTHORIZED HEREUNDER 
EXCEPT UNDER THIS DISCLAIMER.

8. LIMITATION OF LIABILITY.  TO THE MAXIMUM EXTENT PERMITTED BY
APPLICABLE LAW,  IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY 
INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 
OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, INCLUDING, 
WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK 
STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL 
OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF ADVISED OF THE
POSSIBILITY THEREOF. 
*/
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "_maxit.h"
#include "util.h"
#include "erf_category.h"
#include "erf_util.h"
#include "ndb_misclib.h"

typedef struct {
     int oper_id;
     int num_chain;
     char chain[50][3];
} NCS_COR;

typedef struct {
        char biol_id[4];
} _BIOL_ID;

#define NUM_TML 6

static const char *tml_token[NUM_TML] = { "RFTPOS", "RFMPOS", "RFLPOS", "RFTTHR", "RFMTHR", "RFLTHR" };
static const char *tml_type[NUM_TML] = { "tight positional", "medium positional", "loose positional",
              "tight thermal", "medium thermal", "loose thermal"};

static void print_null_remark_value(One_Card_Info_Format *newCard,
             const int fieldLength, const int fieldJustification);
static void print_space_between_remark_field(One_Card_Info_Format *newCard,
             REMARKS *Remark, const int field_no);
static void get_remark_field_format(char *FieldFormat, REMARKS *Remark,
             const int field_no);
static void clean_descriptor(char *string, char *ec);
static void delete_space_between_string(char *string);
static float cal_min_distance(_MOLECULE *mol, _ATOM *atom);
static float cal_dist(_ATOM *atom_a, _ATOM *atom_b);
static int check_align(const int Remark_No, REMARK_FIELD *FieldList);
#ifdef SUN_OS
#ifdef __cplusplus
extern "C" {
#endif
#endif
static int biol_id_compare(const void *biol1, const void *biol2);
#ifdef SUN_OS
#ifdef __cplusplus
}
#endif
#endif

void _MAXIT::ndb_to_pdb_general(const int remark)
{
       int i, j, k, len, Auth_Token, token_id[6], sym1[4], sym2[4];
       char buff1[12], buff2[12];
       One_Card_Info_Format *pCard = NULL, *qCard = NULL;

       token_id[0] = find_card_id("TLSGRO");
       token_id[1] = find_card_id("TLSRNG");
       j = 0;
       pCard = _CardInfo[token_id[0]].Head();
       while (pCard) {
            i = 0;
            qCard = _CardInfo[token_id[1]].Head();
            while (qCard) {
                 if (!strcmp(qCard->Field(1), pCard->Field(1))) i++;
                 qCard = qCard->Next();
            }
            pCard->AddElementToField(i, 2);
            j++;
            pCard = pCard->Next();
       }

       token_id[0] = find_card_id("NCSGRO");
       token_id[1] = find_card_id("CCPNCS");
       k = 0;
       pCard = _CardInfo[token_id[0]].Head();
       while (pCard) {
            i = 0;
            qCard = _CardInfo[token_id[1]].Head();
            while (qCard) {
                 if (!strcmp(qCard->Field(1), pCard->Field(1))) {
                      if (atoi(qCard->Field(6)) > i) i = atoi(qCard->Field(6));
                 }
                 qCard = qCard->Next();
            }
            pCard->AddElementToField(i, 2);
            k++;
            pCard = pCard->Next();
       }

       token_id[0] = find_card_id("NCSTLS");
       pCard = _CardInfo[token_id[0]].Head();
       if (!pCard) pCard = _CardInfo[token_id[0]].add_a_new_card(NdbToken[token_id[0]], 0);
       pCard->AddElementToField(k, 1);
       pCard->AddElementToField(j, 2);

       Auth_Token = find_card_id("TMLPTL");
       if (Auth_Token >= 0 && _CardInfo[Auth_Token].Head()) {
            for (i = 0; i < NUM_TML; i++) {
                 token_id[i] = find_card_id(tml_token[i]);
                 if (token_id[i] < 0) continue;
                 pCard = _CardInfo[token_id[i]].Head();
                 while (pCard) pCard = _CardInfo[token_id[i]].delete_a_card(pCard);
            }
            pCard = _CardInfo[Auth_Token].Head();
            while (pCard) {
                 pCard->CleanStringField(6);
                 for (i = 0; i < NUM_TML; i++) {
                      if (!strcmp(pCard->Field(6), tml_type[i])) break;
                 }
                 if (i < NUM_TML) {
                      qCard = _CardInfo[token_id[i]].add_a_new_card(NdbToken[token_id[i]], 0);
                      for (j = 1; j < qCard->NumField(); j++) {
                           if (j == 2 && !strcmp(pCard->Field(j), ""))
                                qCard->AddElementToField(" ", j);
                           else qCard->AddElementToField(pCard->Field(j), j);
                      }
                 }
                 pCard = pCard->Next();
            }
       }

       Auth_Token = find_card_id("TLSRNG");
       if (Auth_Token >= 0 && _CardInfo[Auth_Token].Head()) {
            pCard = _CardInfo[Auth_Token].Head();
            while (pCard) {
                 if (!strcmp(pCard->Field(2), "")) pCard->AddElementToField(" ", 2);
                 if (!strcmp(pCard->Field(4), "")) pCard->AddElementToField(" ", 4);
                 pCard = pCard->Next();
            }
       }

       Auth_Token = find_card_id("CCPNCS");
       if (Auth_Token >= 0 && _CardInfo[Auth_Token].Head()) {
            pCard = _CardInfo[Auth_Token].Head();
            while (pCard) {
                 if (!strcmp(pCard->Field(2), "")) pCard->AddElementToField(" ", 2);
                 if (!strcmp(pCard->Field(4), "")) pCard->AddElementToField(" ", 4);
                 pCard = pCard->Next();
            }
       }

       Auth_Token = find_card_id("SITELS");
       if (Auth_Token >= 0 && _CardInfo[Auth_Token].Head()) {
            pCard = _CardInfo[Auth_Token].Head();
            while (pCard) {
                 if (!strcmp(pCard->Field(3), ""))
                      pCard = _CardInfo[Auth_Token].delete_a_card(pCard);
                 else pCard = pCard->Next();
            }
       }

       ndb_to_pdb_processing_authors();
       ndb_to_pdb_processing_shelx_and_tnt();
       ndb_to_pdb_processing_synchrotron();
       ndb_to_pdb_proc_header();
       replace_pdb_compnd_source_card();
       ndb_to_pdb_get_remarks(remark); 

       get_cispep_cards();

       token_id[0] = SSBOND_TOKEN-1; sym1[0] = 10; sym2[0] = 11;
       token_id[1] = LINK_TOKEN-1;   sym1[1] = 13; sym2[1] = 14;
       token_id[2] = HYDBND_TOKEN-1; sym1[2] = 18; sym2[2] = 19;
       token_id[3] = SLTBRG_TOKEN-1; sym1[3] = 13; sym2[3] = 14;
       for (i = 0; i < 4; i++) {
            pCard = _CardInfo[token_id[i]].Head();
            while (pCard) {
                 strcpy(buff1, pCard->Field(sym1[i]));
                 if (strcmp(buff1, "")) {
                      k = 0;
                      len = strlen(buff1);
                      for (j = 0; j < len; j++) {
                           if (buff1[j] == '_') continue;
                           buff2[k] = buff1[j];
                           k++;
                      }
                      buff2[k] = '\0';
                      pCard->AddElementToField(buff2, sym1[i]);
                 }
                 strcpy(buff1, pCard->Field(sym2[i]));
                 if (strcmp(buff1, "")) {
                      k = 0;
                      len = strlen(buff1);
                      for (j = 0; j < len; j++) {
                           if (buff1[j] == '_') continue;
                           buff2[k] = buff1[j];
                           k++;
                      }
                      buff2[k] = '\0';
                      pCard->AddElementToField(buff2, sym2[i]);
                 }
                 pCard = pCard->Next();
            }
       }
       Auth_Token = find_card_id("CAVEAT");
       pCard = _CardInfo[Auth_Token].Head();
       if (pCard && _CardInfo[PDBFIL_TOKEN-1].Head()) {
            while (pCard) {
                 pCard->AddElementToField(_CardInfo[PDBFIL_TOKEN-1].Head()->Field(1), 2);
                 pCard = pCard->Next();
            }
       }
}

void _MAXIT::ndb_to_pdb_processing_authors()
{
       int Author_Token = find_card_id("AUTHOR");
       int Auth_Token = find_jrnl_id("AUTH");

       char buffer[1000];
       One_Card_Info_Format *pCard = _JrnlCardInfo[Auth_Token].Head();
       while (pCard) {
            strcpy(buffer, pCard->Field(4));
            delete_space_between_string(buffer);
            pCard->AddElementToField(buffer, 4);
            pCard = pCard->Next();
       }

       pCard = _CardInfo[Author_Token].Head();
       while (pCard) {
            strcpy(buffer, pCard->Field(2));
            delete_space_between_string(buffer);
            pCard->AddElementToField(buffer, 2);
            pCard = pCard->Next();
       }

       if (_JrnlCardInfo[Auth_Token].Head() && !_CardInfo[Author_Token].Head() &&
           strcmp(_JrnlCardInfo[Auth_Token].Head()->Field(4), "")) {
            pCard = _CardInfo[Author_Token].add_a_new_card(NdbToken[Author_Token], 0);
            pCard->AddElementToField(_JrnlCardInfo[Auth_Token].Head()->Field(4), 2);
       }
}

void _MAXIT::ndb_to_pdb_processing_shelx_and_tnt()
{
       One_Card_Info_Format *pCard = NULL, *qCard = NULL, *rCard = NULL, *tCard = NULL;
       int RNOCUT_TOKEN = find_card_id("RNOCUT");

       pCard = _CardInfo[REFMET_TOKEN-1].Head();
       if (pCard) {
            if (!strncasecmp(pCard->Field(3), "SHELX", 5)) {
                 qCard = _CardInfo[RFACTR_TOKEN-1].Head();
                 if (qCard) {
                      rCard = _CardInfo[RNOCUT_TOKEN].Head();
                      if (rCard) {
                           if (!strcmp(rCard->Field(1), ""))
                                rCard->AddElementToField(qCard->Field(8), 1);
                           if (!strcmp(rCard->Field(2), ""))
                                rCard->AddElementToField(qCard->Field(7), 2);
                      } else {
                           rCard = _CardInfo[RNOCUT_TOKEN].
                                 add_a_new_card(NdbToken[RNOCUT_TOKEN], 0);
                           rCard->AddElementToField(qCard->Field(8), 1);
                           rCard->AddElementToField(qCard->Field(7), 2);
                      }
                 }

                 tCard = _CardInfo[FREERF_TOKEN-1].Head();
                 if (qCard && tCard) {
                      rCard = _CardInfo[RNOCUT_TOKEN].Head();
                      if (rCard) {
                           if (!strcmp(rCard->Field(3), ""))
                                rCard->AddElementToField(tCard->Field(1), 3);
                           if (!strcmp(rCard->Field(4), ""))
                                rCard->AddElementToField(tCard->Field(3), 4);
                           if (!strcmp(rCard->Field(5), ""))
                                rCard->AddElementToField(tCard->Field(4), 5);
                      } else {
                           rCard = _CardInfo[RNOCUT_TOKEN].
                                 add_a_new_card(NdbToken[RNOCUT_TOKEN], 0);
                           rCard->AddElementToField(tCard->Field(1), 3);
                           rCard->AddElementToField(tCard->Field(3), 4);
                           rCard->AddElementToField(tCard->Field(4), 5);
                      }
                 }
            } else if (!strncasecmp(pCard->Field(3), "TNT", 3) ||
                       !strncasecmp(pCard->Field(3), "NUCLSQ", 6) ||
                       !strncasecmp(pCard->Field(3), "PROLSQ", 6)) {
                 qCard = _CardInfo[RFACTR_TOKEN-1].Head();
                 if (qCard) {
                      if (!strcmp(qCard->Field(4), "") ||
                          fabs(atof(qCard->Field(4))) < 0.1) {
                           rCard = _CardInfo[RNOCUT_TOKEN].Head();
                           if (rCard) {
                                if (!strcmp(rCard->Field(1), ""))
                                     rCard->AddElementToField(qCard->Field(8), 1);
                           } else {
                                rCard = _CardInfo[RNOCUT_TOKEN].
                                      add_a_new_card(NdbToken[RNOCUT_TOKEN], 0);
                                rCard->AddElementToField(qCard->Field(8), 1);
                           }
                      }
                 }
            }
       }
}

void _MAXIT::ndb_to_pdb_processing_synchrotron()
{
       char  site[100], beamline[1000];
       One_Card_Info_Format *pCard = NULL, *qCard = NULL;

       pCard = _CardInfo[DTMETH_TOKEN-1].Head();
       while (pCard) {
            if (!strcasecmp(pCard->Field(4), "SYNCHROTRON")) {
                 strcpy(pCard->Field(1), "Y");
                 qCard = _CardInfo[RADIAT_TOKEN-1].Head();
                 while (qCard) {
                      if (!strcmp(pCard->Field(NdbToken[DTMETH_TOKEN-1].SeqField-1),
                                  qCard->Field(NdbToken[RADIAT_TOKEN-1].SeqField-1)))
                           break;
                      qCard = qCard->Next();
                 }

                 site[0] = '\0'; beamline[0] = '\0';
                 if (qCard) {
                      qCard->UpperCaseField(5);
                      separation_string_base_word(qCard->Field(5), site, 
                                     beamline, "BEAMLINE");
                 }

                 if (strcmp(site, "") || strcmp(beamline, "")) {
                      qCard = _CardInfo[DTMEAS_TOKEN-1].Head();
                      while (qCard) {
                           if (!strcmp(pCard->Field(NdbToken[DTMETH_TOKEN-1].SeqField-1),
                                       qCard->Field(NdbToken[DTMEAS_TOKEN-1].SeqField-1)))
                                break;
                           qCard = qCard->Next();
                      }

                      if (qCard == NULL) {
                           qCard = _CardInfo[DTMEAS_TOKEN-1].
                                     add_a_new_card(NdbToken[DTMEAS_TOKEN-1], 0);
                           qCard->AddElementToField(
                              pCard->Field(NdbToken[DTMETH_TOKEN-1].SeqField-1),
                                           NdbToken[DTMEAS_TOKEN-1].SeqField-1);
                      }
                      qCard->AddElementToField(site, 2);
                      qCard->AddElementToField(beamline, 3);
                 }
            } else pCard->AddElementToField("N", 1);
            pCard = pCard->Next();
       }

       pCard = _CardInfo[DTMETH_TOKEN-1].Head();
       while (pCard) {
            if (!strcasecmp(pCard->Field(4), "SYNCHROTRON")) {
                 qCard = _CardInfo[DTMEAS_TOKEN-1].Head();
                 while (qCard) {
                      if (!strcmp(qCard->Field(6), pCard->Field(6))) break;
                      qCard = qCard->Next();
                 }
                 if (qCard)
                      pCard->AddElementToField(qCard->Field(2), 4);
                 else pCard->AddElementToField("", 4);

                 qCard = _CardInfo[RADIAT_TOKEN-1].Head();
                 while (qCard) {
                      if (!strcmp(qCard->Field(1), pCard->Field(6))) break;
                      qCard = qCard->Next();
                 } 
                 if (qCard) qCard->AddElementToField("", 5);
            }
            pCard = pCard->Next();
       }

       pCard = _CardInfo[DTWAVE_TOKEN-1].Head();
       if (_CardInfo[WAVLEN_TOKEN-1].Head() == NULL && pCard) {
            beamline[0] = '\0';
            while (pCard) {
                 strcat(beamline, pCard->Field(3));
                 if (pCard->Next()) strcat(beamline, ", ");
                 pCard = pCard->Next();
            }
            if (strcmp(beamline, "")) {
                 qCard = _CardInfo[WAVLEN_TOKEN-1].
                             add_a_new_card(NdbToken[WAVLEN_TOKEN-1], 0);
                 qCard->AddElementToField(beamline, 3);
            }
       }

       pCard = _CardInfo[WAVLEN_TOKEN-1].Head();
       while (pCard) {
            if (!strcmp(pCard->Field(2), "") && strcmp(pCard->Field(3), ""))
                 pCard->AddElementToField(pCard->Field(3), 2);
            pCard = pCard->Next();
       }
}

void _MAXIT::ndb_to_pdb_proc_header()
{
       One_Card_Info_Format *pCard = NULL, *qCard = NULL;

       pCard = _CardInfo[HEADER_TOKEN-1].Head();
       if (pCard == NULL) return;
       qCard = _CardInfo[PDBFIL_TOKEN-1].Head();
       if (qCard) pCard->AddElementToField(qCard->Field(1), 3);
       else {
            qCard = _CardInfo[NDBFIL_TOKEN-1].Head();
            if (qCard) pCard->AddElementToField(qCard->Field(1), 3);
       }

       if (!strcmp(pCard->Field(1), NDB_DNA_TEXT))
            pCard->AddElementToField("DEOXYRIBONUCLEIC ACID", 1);
       else if (!strcmp(pCard->Field(1), NDB_RNA_TEXT))
            pCard->AddElementToField("RIBONUCLEIC ACID", 1);
       else if (!strcmp(pCard->Field(1), NDB_T_RNA_TEXT))
            pCard->AddElementToField("AMINO-ACID TRANSPORT", 1);
}

void _MAXIT::replace_pdb_compnd_source_card()
{
       int i, found, entity_to_serialno[100];
       int SerialNo = 0; 
       int compndSerialNo = 0;
       int sourceSerialNo = 0;
       int nsource_Nat = 0;
       int nsource_Gen = 0;
       int nsource_Syn = 0;
       int isSynthetic = GEN;
       char ec_number[800], buffer[800], buffer1[800];
       One_Card_Info_Format *pCard = NULL, *qCard = NULL, *rCard = NULL;
       One_Card_Info_Format *compndCard = NULL, *sourceCard = NULL;

       for (i = 0; i < 100; i++) entity_to_serialno[i] = 0;

       pCard = _CardInfo[SOURCE_TOKEN-1].Head();
       while (pCard) pCard = _CardInfo[SOURCE_TOKEN-1].delete_a_card(pCard); 
       pCard = _CardInfo[COMPND_TOKEN-1].Head();
       while (pCard) pCard = _CardInfo[COMPND_TOKEN-1].delete_a_card(pCard); 

       pCard = _CardInfo[SEQIFO_TOKEN-1].Head();
       while (pCard) {
            qCard = _CardInfo[STBIOL_TOKEN-1].Head();
            if (qCard) {
                while (qCard) {
                     if (!strcmp(pCard->Field(2), qCard->Field(12))) {
                          if (strcmp(qCard->Field(15), ""))
                               pCard->AddElementToField(qCard->Field(15), 1);
                          else pCard->AddElementToField(qCard->Field(1), 1);
                          break;
                     }
                     qCard = qCard->Next();
                }
            } else {
                for (i = 0; i < _n_stbiol; i++) {
                     if (!_stbiol[i]) continue;
                     if (_stbiol[i]->NDB_Strand_ID == pCard->Field(2)) {
                          pCard->AddElementToField(_stbiol[i]->order, 1);
                          break;
                     }
                }
            }
            pCard = pCard->Next();
       }
       _CardInfo[SEQIFO_TOKEN-1].reorder_cards(1, INTEGER_COMPARE, ASCENT);

       while (PdbSource_Nat[nsource_Nat].pdbname &&
              strcmp(PdbSource_Nat[nsource_Nat].pdbname, "")) {
            if (PdbSource_Nat[nsource_Nat].NdbTokenId <= 0)
                 PdbSource_Nat[nsource_Nat].NdbTokenId =
                    find_card_id(PdbSource_Nat[nsource_Nat].NdbTokenName)+1;
            nsource_Nat++;
       }

       while (PdbSource_Gen[nsource_Gen].pdbname &&
              strcmp(PdbSource_Gen[nsource_Gen].pdbname, "")) {
            if (PdbSource_Gen[nsource_Gen].NdbTokenId <= 0)
                 PdbSource_Gen[nsource_Gen].NdbTokenId =
                    find_card_id(PdbSource_Gen[nsource_Gen].NdbTokenName)+1;
            nsource_Gen++;
       }

       while (PdbSource_Syn[nsource_Syn].pdbname &&
              strcmp(PdbSource_Syn[nsource_Syn].pdbname, "")) {
            if (PdbSource_Syn[nsource_Syn].NdbTokenId <= 0)
                 PdbSource_Syn[nsource_Syn].NdbTokenId =
                    find_card_id(PdbSource_Syn[nsource_Syn].NdbTokenName)+1;
            nsource_Syn++;
       }

       pCard = _CardInfo[SEQIFO_TOKEN-1].Head();
       while (pCard) {
            qCard = _CardInfo[ENTITY_TOKEN-1].Head();
            while (qCard && strcmp(qCard->Field(1), pCard->Field(9)))
                 qCard = qCard->Next();
            if (!qCard || strcasecmp(qCard->Field(2), "POLYMER")) {
                 pCard = pCard->Next();
                 continue;
            }

            ec_number[0] = '\0';
            if (!entity_to_serialno[atoi(qCard->Field(1))]) {
                 sprintf(buffer, "MOL_ID: %d", ++SerialNo);
                 add_compnd_card(buffer, ++compndSerialNo);
                 entity_to_serialno[atoi(qCard->Field(1))] = SerialNo;
                
                 found = FALSE;
                 rCard = _CardInfo[ENTDES_TOKEN-1].Head();
                 while (rCard && strcmp(rCard->Field(1), qCard->Field(1)))
                     rCard = rCard->Next();
                 if (rCard && strcmp(rCard->Field(3), "")) {
                      found = TRUE;
                      if (!strncasecmp(rCard->Field(3), "PROTEIN", 7)) {
                           strcpy(buffer1, rCard->Field(3));
                           clean_descriptor(buffer1, ec_number);
                           sprintf(buffer, "MOLECULE: %s", buffer1);
                      } else sprintf(buffer, "MOLECULE: %s", rCard->Field(3));
                 } 
  
                 if (!found) {
                      rCard = _CardInfo[PROTEI_TOKEN-1].Head();
                      while (rCard && strcmp(rCard->Field(1), qCard->Field(1)))
                          rCard = rCard->Next();
                      if (rCard) {
                           found = TRUE;
                           sprintf(buffer, "MOLECULE: %s", rCard->Field(3));
                      }
                 }
  
                 if (!found) strcpy(buffer, "MOLECULE: ");
                 ndb_set_string_to_upper(buffer);
                 add_compnd_card(buffer, ++compndSerialNo);
  
                 if (strcmp(pCard->Field(3), ""))
                      sprintf(buffer, "CHAIN: %s", pCard->Field(3));
                 else sprintf(buffer, "CHAIN: %s", "NULL");
                 add_compnd_card(buffer, ++compndSerialNo);
 
                 rCard = _CardInfo[FRAGMT_TOKEN-1].Head();
                 while (rCard && strcmp(rCard->Field(1), qCard->Field(1)))
                      rCard = rCard->Next();
                 if (rCard && strcmp(rCard->Field(3), "")) {
                      sprintf(buffer, "FRAGMENT: %s", rCard->Field(3));
                      ndb_set_string_to_upper(buffer);
                      add_compnd_card(buffer, ++compndSerialNo);
                 }

                 rCard = _CardInfo[ENTNAM_TOKEN-1].Head();
                 while (rCard && strcmp(rCard->Field(1), qCard->Field(1)))
                      rCard = rCard->Next();
                 if (rCard && strcmp(rCard->Field(3), "")) {
                      sprintf(buffer, "SYNONYM: %s", rCard->Field(3));
                      ndb_set_string_to_upper(buffer);
                      add_compnd_card(buffer, ++compndSerialNo);
                 }

                 found = FALSE;
                 rCard = _CardInfo[ECNUM_TOKEN-1].Head();
                 while (rCard && strcmp(rCard->Field(1), qCard->Field(1)))
                      rCard = rCard->Next();
                 if (rCard && strcmp(rCard->Field(2), "")) {
                      sprintf(buffer, "EC: %s", rCard->Field(2));
                      add_compnd_card(buffer, ++compndSerialNo);
                      found = TRUE;
                 }
                 if (!found && strcmp(ec_number, "")) {
                      sprintf(buffer, "EC: %s", ec_number);
                      add_compnd_card(buffer, ++compndSerialNo);
                 }

                 if (!strcasecmp(qCard->Field(3), "NAT")) {
                      isSynthetic = NAT;
                 } else {
                      add_compnd_card("ENGINEERED: YES", ++compndSerialNo);
                      isSynthetic = GEN;
                      if (!strcasecmp(qCard->Field(3), "SYN")) isSynthetic = SYN;
                 }
  
                 found = FALSE;
                 rCard = _CardInfo[ENTMUT_TOKEN-1].Head();
                 while (rCard && strcmp(rCard->Field(1), qCard->Field(1)))
                     rCard = rCard->Next();
                 if (rCard && strcmp(rCard->Field(3), "")) {
                      add_compnd_card("MUTATION: YES", ++compndSerialNo);
                      found = TRUE;
                 }
                 rCard = _CardInfo[ENTAIL_TOKEN-1].Head();
                 while (rCard && strcmp(rCard->Field(1), qCard->Field(1)))
                      rCard = rCard->Next();
                 if (rCard && strcmp(rCard->Field(3), "")) {
                      sprintf(buffer, "OTHER_DETAILS: %s", rCard->Field(3));
                      ndb_set_string_to_upper(buffer);
                      add_compnd_card(buffer, ++compndSerialNo);
                 }
  
                 if (isSynthetic == GEN)
                      ndb_to_pdb_get_source_card(SerialNo, atoi(qCard->Field(1)),
                         isSynthetic, &sourceSerialNo, nsource_Gen, PdbSource_Gen);
                 else if (isSynthetic == SYN)
                      ndb_to_pdb_get_source_card(SerialNo, atoi(qCard->Field(1)),
                         isSynthetic, &sourceSerialNo, nsource_Syn, PdbSource_Syn);
                 else if (isSynthetic == NAT)
                      ndb_to_pdb_get_source_card(SerialNo, atoi(qCard->Field(1)),
                         isSynthetic, &sourceSerialNo, nsource_Nat, PdbSource_Nat);
            } else {
                 compndCard = _CardInfo[COMPND_TOKEN-1].Head();
                 while (compndCard) {
                 if (strstr(compndCard->Field(2), "MOL_ID:") &&
                     atoi(&compndCard->Field(2)[8]) ==
                     entity_to_serialno[atoi(pCard->Field(9))] && compndCard->Next() &&
                     compndCard->Next()->Next() && 
                     !strncmp(compndCard->Next()->Next()->Field(2), "CHAIN", 5))
                      break;
                      compndCard = compndCard->Next();
                 }
                 if (compndCard && compndCard->Next()) {
                      compndCard = compndCard->Next()->Next();
                      if (compndCard != NULL) {
                           compndCard->AttachToField(", ", 2);
                           compndCard->AttachToField(pCard->Field(3), 2);
                      }
                 }
            }
            pCard = pCard->Next();
       }

       compndCard = _CardInfo[COMPND_TOKEN-1].Head();
       while (compndCard && compndCard != _CardInfo[COMPND_TOKEN-1].Tail()) {
            strcpy(buffer, compndCard->Field(2));
            for (i = strlen(buffer) - 1; i >= 0; i--) 
                 if (buffer[i] != ' ') break;
            if (buffer[i] != ';') sprintf(&buffer[i+1], ";");
            compndCard->AddElementToField(buffer, 2);
            compndCard = compndCard->Next();
       }
       sourceCard = _CardInfo[SOURCE_TOKEN-1].Head();
       while (sourceCard && sourceCard != _CardInfo[SOURCE_TOKEN-1].Tail()) {
            strcpy(buffer, sourceCard->Field(2));
            for (i = strlen(buffer) - 1; i >= 0; i--) 
                 if (buffer[i] != ' ') break;
            if (buffer[i] != ';') sprintf(&buffer[i+1], ";");
            sourceCard->AddElementToField(buffer, 2);
            sourceCard = sourceCard->Next();
       }
       compndCard = _CardInfo[COMPND_TOKEN-1].Head();
       if (compndCard == NULL) {
            compndCard = _CardInfo[COMPND_TOKEN-1].
                       add_a_new_card(NdbToken[COMPND_TOKEN-1], 0);
            compndCard->AddElementToField("NULL", 2);
       }
       sourceCard = _CardInfo[SOURCE_TOKEN-1].Head();
       if (sourceCard == NULL) {
            sourceCard = _CardInfo[SOURCE_TOKEN-1].
                       add_a_new_card(NdbToken[SOURCE_TOKEN-1], 0);
            sourceCard->AddElementToField("NULL", 2);
       }
}

void _MAXIT::add_compnd_card(const char *value, const int serialNo)
{
       One_Card_Info_Format *compndCard =
          _CardInfo[COMPND_TOKEN-1].add_a_new_card(NdbToken[COMPND_TOKEN-1], 0);
       compndCard->AddElementToField(value, 2);
       compndCard->AddElementToField(serialNo, 3);
}

void _MAXIT::ndb_to_pdb_get_source_card(const int serialno, const int entityId, 
              const int isSynthetic, int *sourceSerialNo, const int nsource,
              PDB_Source_Format *PdbSource)
{
       One_Card_Info_Format *sourceCard =
            _CardInfo[SOURCE_TOKEN-1].add_a_new_card(NdbToken[SOURCE_TOKEN-1], 0); 
       char buffer[800];
       sprintf(buffer, "MOL_ID: %d", serialno);
       sourceCard->AddElementToField(buffer, 2);
       sourceCard->AddElementToField(++(*sourceSerialNo), 3);

       if (isSynthetic == SYN) {
            sourceCard = _CardInfo[SOURCE_TOKEN-1].
                   add_a_new_card(NdbToken[SOURCE_TOKEN-1], 0);
            sourceCard->AddElementToField("SYNTHETIC: YES", 2);
            sourceCard->AddElementToField(++(*sourceSerialNo), 3);
       }

       for (int i = 0; i < nsource; i++) {
            if (PdbSource[i].NdbTokenId != 0 && PdbSource[i].NdbTokenId <= MxTokens) {
                 One_Card_Info_Format *pCard = _CardInfo[PdbSource[i].NdbTokenId-1].Head();
                 while (pCard) {
                      if (strcmp(pCard->Field(PdbSource[i].NdbFieldNo-1), "") &&
                           atoi(pCard->Field(1)) == entityId) break;
          	      pCard = pCard->Next();
                 }
                 if (pCard) {
                      sourceCard = _CardInfo[SOURCE_TOKEN-1].
                             add_a_new_card(NdbToken[SOURCE_TOKEN-1], 0);
                      sprintf(buffer, "%s: %s", PdbSource[i].pdbname,
                                pCard->Field(PdbSource[i].NdbFieldNo-1));
                      sourceCard->AddElementToField(buffer, 2);
                      sourceCard->AddElementToField(++(*sourceSerialNo), 3);
                 }
            }
       }
}

void _MAXIT::add_remark_90()
{
       One_Card_Info_Format *pCard = _CardInfo[REMARK_TOKEN-1].Head();
       while (pCard) {
            One_Card_Info_Format *pRemarkCard = _CardInfo[PREMRK_TOKEN-1].
                   add_a_new_card(NdbToken[PREMRK_TOKEN-1], 0);
            pRemarkCard->AddElementToField(pCard->Field(1), 1);
            pRemarkCard->AddElementToField(pCard->Field(2), 2);
            pCard = _CardInfo[REMARK_TOKEN-1].delete_a_card(pCard);
       }

       for (int remark_no = 2; remark_no <= 999; remark_no++) {
            if (remark_no == 90)
                 ndb_to_pdb_get_general_remark(Num_Remark_90, Remark_90, 0, 0, 0, 0);
            else ndb_to_pdb_get_remark_from_premark(remark_no);
       }
}

void _MAXIT::ndb_to_pdb_get_remarks(const int remark)
{
       int Num_RemarkNo = 0, RemarkNo[20], RMKSKP_TOKEN, i, j, len;
       int is_electron_microscopy = 0;
       int is_powder_diffration = 0;
       int exist_DNA = 0, CMRNST_TOKEN, RCSBID_TOKEN;
       int IsInosine = 0, is_skip, exist, remark_no, card_id, SOLEXP_TOKEN;
       char buff[82], buff1[10], *p;
       _CHAIN *chain = NULL;
       One_Card_Info_Format *pCard = NULL, *qCard = NULL;

       if (_molecules && _num_mol) {
            chain = _molecules[0]->GetFirstChain();
            while (chain) {
                 if (chain->chain_type() == ATOMN_TOKEN) {
                      exist_DNA = 1;
                      if (chain->na_type() != ATOMN_TYPE_DNA_ONLY) {
                           exist_DNA = 0;
                           break;
                      }
                 }
                 chain = _molecules[0]->GetNextChain();
            }
       }

       SOLEXP_TOKEN = find_card_id("SOLEXP");
       CMRNST_TOKEN = find_card_id("CMRNST");
       RCSBID_TOKEN = find_card_id("RCSBID");

       for (i = 0; i < 20; i++) RemarkNo[i] = 0;
       
       pCard = _CardInfo[PROCES_TOKEN-1].Head();
       if (pCard && !strcasecmp(pCard->Field(5), "OSAKA")) {
            pCard->AddElementToField("PDBJ", 5);
       }

       if (_CardInfo[PROCES_TOKEN-1].Head() &&
          (_CardInfo[PROCES_TOKEN-1].Head()->Field(7)[0] == 'Y' ||
           _CardInfo[PROCES_TOKEN-1].Head()->Field(7)[0] == 'y')) {
            RemarkNo[0] = 500;
            RemarkNo[1] = 525;
            Num_RemarkNo = 2;
       }
       RMKSKP_TOKEN = find_card_id("RMKSKP");
       if (_CardInfo[RMKSKP_TOKEN].Head() &&
           strcmp(_CardInfo[RMKSKP_TOKEN].Head()->Field(1), "")) {
            strcpy(buff, _CardInfo[RMKSKP_TOKEN].Head()->Field(1));
            if (buff[0] == 'Y' || buff[0] == 'y') {
                 RemarkNo[0] = 500;
                 RemarkNo[1] = 525;
                 Num_RemarkNo = 2;
            } else {
                 len = strlen(buff);
                 for (i = 0; i < len; i++) {
                      if (buff[i] == ',') buff[i] = ' ';
                 }
                 ndb_clean_string(buff);
                 p = get_word(buff, buff1);
                 RemarkNo[Num_RemarkNo++] = atoi(buff1);
                 while (p) {
                      p = get_word(p, buff1);
                      RemarkNo[Num_RemarkNo++] = atoi(buff1);
                 }
            }
       }

       calculate_all_contact(5.0, 1);
       get_molecule_topology();
       get_ebi_validate_contact();
       get_ebi_validate_bond();
       get_ebi_validate_angle();
       get_ebi_validate_torsion();
       get_ebi_validate_peptide_omega();

       if (_experiment_type & EXPERIMENT_TYPE_NMR ||
           _experiment_type & EXPERIMENT_TYPE_MODEL)
            ndb_to_pdb_processing_nmr_remarks();
       if ((_experiment_type & EXPERIMENT_TYPE_NMR) ||
           (_experiment_type & EXPERIMENT_TYPE_MODEL)) {
            pCard = _CardInfo[REFMET_TOKEN-1].Head();
            while (pCard) {
                 if (!strcmp(pCard->Field(4), "")) {
                      pCard->UpperCaseField(3);
                      for (i = 0; i < Max_Refinement_Programs; i++)
                           if (strstr(pCard->Field(3),
                                   Refinement_programs[i].Program)) break;
                      if (i != Max_Refinement_Programs)
                           pCard->AddElementToField(Refinement_programs[i].Author, 4);
                 }
                 pCard = pCard->Next();
            }
       }
       pCard = _CardInfo[EXPDTA_TOKEN-1].Head();
       if (pCard) {
            if (strstr(pCard->Field(2), "ELECTRON MICROSCOPY") ||
                strstr(pCard->Field(2), "CRYO-EM RECONSTRUCTION"))
                 is_electron_microscopy = 1;
            if (strstr(pCard->Field(2), "POWDER DIFFRACTION"))
                 is_powder_diffration = 1;
       }

       for (remark_no = 2; remark_no <= 999; remark_no++) {
            is_skip = 0;
            for (i = 0; i < Num_RemarkNo; i++) {
                 if (remark_no == RemarkNo[i]) {
                      is_skip = 1;
                      break;
                 }
            }
            if (is_skip) continue;

            if (find_user_defined_remark(remark_no)) continue;

            if (remark_no == 2) {
                 if ((_experiment_type & EXPERIMENT_TYPE_XRAY) ||
                     (_experiment_type & EXPERIMENT_TYPE_NEUTRON) ||
                     (_experiment_type & EXPERIMENT_TYPE_CRYO_EM) ||
                     (_experiment_type & EXPERIMENT_TYPE_FIBER) ||
                     (_experiment_type & EXPERIMENT_TYPE_ELECTRON)) {
                      pCard = _CardInfo[RFACTR_TOKEN-1].Head();
                      if (!pCard) pCard = _CardInfo[RFACTR_TOKEN-1].
                              add_a_new_card(NdbToken[RFACTR_TOKEN-1], 0);
                      qCard = _CardInfo[CMRNST_TOKEN].Head();
                      if (qCard && strcmp(qCard->Field(3), "") &&
                          !strcmp(pCard->Field(6), ""))
                           pCard->AddElementToField(qCard->Field(3), 6);
                      ndb_to_pdb_get_general_remark(1, &Remark_2, 0, 0, 0, 0);
                 } else ndb_to_pdb_get_general_remark(1, &Remark_2_NMR, 0, 0, 0, 0);
            } else if (remark_no == 3) {
                 if ((_experiment_type & EXPERIMENT_TYPE_NMR) ||
                     (_experiment_type & EXPERIMENT_TYPE_MODEL))
                      ndb_to_pdb_get_general_remark(Num_Remark_3_NMR, Remark_3_NMR,
                                       0, 0, 0, 0);
                 else if (_experiment_type & EXPERIMENT_TYPE_CRYO_EM)
                      ndb_to_pdb_get_general_remark(Num_Remark_3_Cryo_Em,
                                     Remark_3_Cryo_Em, 0, 0, 0, 0);
                 else if (_experiment_type & EXPERIMENT_TYPE_SOLN_SCT) {
                      for (i = 0; i < Remark_3_Solution.Remarks_No; i++) {
                           ndb_to_pdb_get_general_remark(Remark_3_Solution.num_remarks[i],
                                 Remark_3_Solution.remarks[i], 0, 0, 0, 0);
                      }
                 } else if (_experiment_type != EXPERIMENT_TYPE_BASIC) {
                      ndb_to_pdb_get_group_remarks();
                 }
            } else if (remark_no == 4) {
                 ndb_to_pdb_get_general_remark(Num_Remark_4, Remark_4, 0, 0, 0, 0);
            } else if (remark_no == 100) {
                 if (_CardInfo[NDBPRO_TOKEN-1].Head() &&
                      strcmp(_CardInfo[NDBPRO_TOKEN-1].Head()->Field(4), "")) {
                      if (!strcmp(_CardInfo[NDBFIL_TOKEN-1].Head()->Field(1),
                                  _CardInfo[PDBFIL_TOKEN-1].Head()->Field(1)) &&
                           strcmp(_CardInfo[RCSBID_TOKEN].Head()->Field(1), "") &&
                           strcmp(_CardInfo[RCSBID_TOKEN].Head()->Field(1),
                                  _CardInfo[NDBFIL_TOKEN-1].Head()->Field(1))) {
                           _CardInfo[NDBFIL_TOKEN-1].Head()->AddElementToField(
                                _CardInfo[RCSBID_TOKEN].Head()->Field(1), 1);
                      }
                      if (!strncmp(_CardInfo[NDBFIL_TOKEN-1].Head()->Field(1), "RCSB", 4))
                           ndb_to_pdb_get_general_remark(Num_Remark_100_RCSB,
                                   Remark_100_RCSB, 0, 0, 0, 0);
                      else ndb_to_pdb_get_general_remark(Num_Remark_100,
                                   Remark_100, 0, 0, 0, 0);
                 } else ndb_to_pdb_get_remark_from_premark(100);
            } else if (remark_no == 101) {
                 exist = ndb_to_pdb_get_remark_from_premark(101);
                 if (!exist) {
/*
                      pCard = _CardInfo[MODIFB_TOKEN-1].Head();
                      while (pCard) {
                           if (pCard->Field(9)[0] != '+' && strcmp(pCard->Field(9), "I")) {
                                sprintf(buff, "+%s", pCard->Field(9));
                                pCard->AddElementToField(buff, 9);
                                strcpy(pCard->Field(9), buff);
                           }
                           pCard = pCard->Next();
                      }
*/
                      pCard = _CardInfo[MODIFB_TOKEN-1].Head();
                      if (pCard)
                           ndb_to_pdb_get_general_remark(1, &Remark_101, 0, 0, 0, 0); 
                 }
            } else if (remark_no == 102) {
                 if (exist_DNA) {
                      if (_CardInfo[MISMAT_TOKEN-1].Head()) {
                           ndb_to_pdb_get_general_remark(1, &Remark_102, 0, 0, 0, 0);  
                      } else ndb_to_pdb_get_remark_from_premark(102);
                 }
            } else if (remark_no == 103) {
                 IsInosine = 0;
                 pCard = _CardInfo[MODIFB_TOKEN-1].Head();
                 while (pCard) {
                      if (!res_name_cmp(pCard->Field(5), "I")) {
                           IsInosine = 1;
                           break;
                      }
                      pCard = pCard->Next();
                 }
                 if (exist_DNA || IsInosine)
                      ndb_to_pdb_get_general_remark(Num_Remark_103, Remark_103, 1, 0, 1, 0);
            } else if (remark_no == 104) {
                 if (IsInosine)
                      ndb_to_pdb_get_general_remark(1, &Remark_104, 0, 0, 1, 0);
            } else if (remark_no == 105) {
                 exist = 0;
                 pCard = _CardInfo[SEQIFO_TOKEN-1].Head();
                 while (pCard != NULL) {
                      if (!strcmp(pCard->Field(5), "NA")) {
                           exist = 1; break;
                      }
                      pCard = pCard->Next();
                 }
                 if (exist) {
                      exist = ndb_to_pdb_get_remark_from_premark(105);
                      if (!exist) ndb_to_pdb_get_general_remark(Num_Remark_105,
                                     Remark_105, 0, 0, 0, 0);
                 }
            } else if (remark_no == 106) {
#if 0
                 exist = ndb_to_pdb_get_remark_from_premark(106);
                 if (!exist /* && IsInosine == FALSE && _CardInfo[MISMAT_TOKEN-1].Head() == NULL */ ) {
                      pCard = _CardInfo[BSPAIR_TOKEN-1].Head();
                      while (pCard) {
                           if (!strcmp(pCard->Field(11), "WATSON-CRICK")) break;
                           pCard = pCard->Next();
                      }
                      if (pCard) ndb_to_pdb_get_general_remark(Num_Remark_106,
                                       Remark_106, 0, 0, 0, 0);
                 }
#endif
            } else if (remark_no == 200) {
                 if (_experiment_type & EXPERIMENT_TYPE_XRAY && !is_powder_diffration)
                      ndb_to_pdb_get_general_remark(Num_Remark_200, Remark_200, 0, 0, 0, 0);
            } else if (remark_no == 210) {
                 if (_experiment_type & EXPERIMENT_TYPE_NMR)
                      ndb_to_pdb_get_general_remark(Num_Remark_210, Remark_210, 0, 0, 0, 0);
            } else if (remark_no == 215 ) {
                 if  (_experiment_type & EXPERIMENT_TYPE_NMR)
                      ndb_to_pdb_get_general_remark(Num_Remark_215, Remark_215, 0, 0, 0, 0);
            } else if (remark_no == 220) {
                 if (_experiment_type & EXPERIMENT_TYPE_MODEL)
                      ndb_to_pdb_get_general_remark(Num_Remark_220, Remark_220, 0, 0, 0, 0);
            } else if (remark_no == 225) {
                 if (_experiment_type & EXPERIMENT_TYPE_MODEL)
                      ndb_to_pdb_get_general_remark(Num_Remark_225, Remark_225, 0, 0, 0, 0);
            } else if (remark_no == 230) {
                 if (_experiment_type & EXPERIMENT_TYPE_NEUTRON)
                      ndb_to_pdb_get_general_remark(Num_Remark_230, Remark_230, 0, 0, 0, 0);
            } else if (remark_no == 240) {
                 if (_experiment_type & EXPERIMENT_TYPE_ELECTRON)
                      ndb_to_pdb_get_general_remark(Num_Remark_240, Remark_240, 0, 0, 0, 0);
            } else if (remark_no == 245) {
                 if (_experiment_type & EXPERIMENT_TYPE_CRYO_EM)
                      ndb_to_pdb_get_general_remark(Num_Remark_245, Remark_245, 0, 0, 0, 0);
            } else if (remark_no == 247) {
                 if (_experiment_type & EXPERIMENT_TYPE_CRYO_EM)
                      ndb_to_pdb_get_general_remark(Num_Remark_247, Remark_247, 0, 0, 0, 0);
            } else if (remark_no == 250) {
                 if (is_electron_microscopy || is_powder_diffration)
                      ndb_to_pdb_get_remark_from_premark(250);
                 else if ((_experiment_type & EXPERIMENT_TYPE_BASIC) ||
                          (_experiment_type & EXPERIMENT_TYPE_FIBER))
                      ndb_to_pdb_get_general_remark(Num_Remark_250, Remark_250, 0, 0, 0, 0);
            } else if (remark_no == 265) {
                 if (_experiment_type & EXPERIMENT_TYPE_SOLN_SCT) {
                      if (SOLEXP_TOKEN >= 0) {
                           pCard = _CardInfo[SOLEXP_TOKEN].Head();
                           while (pCard) {
                                if (!strcmp(pCard->Field(2), "THEORETICAL MODELLING"))
                                     pCard = _CardInfo[SOLEXP_TOKEN].delete_a_card(pCard);
                                else pCard = pCard->Next();
                           }
                      }
                      for (i = 0; i < Remark_265.Remarks_No; i++) {
                           if (strcmp(Remark_265.TokenName[i], "")) {
                                card_id = find_card_id(Remark_265.TokenName[i]);
                                if (card_id == -1) continue;
                                pCard = _CardInfo[card_id].Head();
                                if (!pCard) continue;
                           }
                           j = 0;
                           if (Remark_265.repeat[i]) j = 1;
                           ndb_to_pdb_get_general_remark(Remark_265.num_remarks[i],
                                 Remark_265.remarks[i], j, 0, 0, 1);
                      }
                 }
            } else if (remark_no == 280) {
                 if (_experiment_type & EXPERIMENT_TYPE_XRAY ||
                     _experiment_type & EXPERIMENT_TYPE_NEUTRON)
                      ndb_to_pdb_get_remark_280_crystal();
            } else if (remark_no == 290) {
                 if (_experiment_type & EXPERIMENT_TYPE_XRAY ||
                     _experiment_type & EXPERIMENT_TYPE_NEUTRON ||
                     is_electron_microscopy)
                      ndb_to_pdb_get_remark_290();
            } else if (remark_no == 300) {
                 if (is_electron_microscopy) {
                      if (!ndb_to_pdb_get_remark_from_premark(300)) {
                           if (_experiment_type & EXPERIMENT_TYPE_CRYO_EM) {
                                ndb_to_pdb_get_remark_300();
                                for (i = 0; i < Remark_Cryo_Em_300.Remarks_No; i++) {
                                     j = 0;
                                     if (Remark_Cryo_Em_300.repeat[i]) j = 1;
                                     ndb_to_pdb_get_general_remark(Remark_Cryo_Em_300.num_remarks[i],
                                           Remark_Cryo_Em_300.remarks[i], j, 0, 0, 0);
                                }
                           }
                      }
                 } else if (_experiment_type & EXPERIMENT_TYPE_XRAY ||
                          _experiment_type & EXPERIMENT_TYPE_NEUTRON ||
                          _experiment_type & EXPERIMENT_TYPE_ELECTRON) {
                      if (!ndb_to_pdb_get_remark_300())
                           ndb_to_pdb_get_remark_from_premark(300);
                 } else if (_experiment_type & EXPERIMENT_TYPE_CRYO_EM) {
                      ndb_to_pdb_get_remark_300();
                      for (i = 0; i < Remark_Cryo_Em_300.Remarks_No; i++) {
                           j = 0;
                           if (Remark_Cryo_Em_300.repeat[i]) j = 1;
                           ndb_to_pdb_get_general_remark(Remark_Cryo_Em_300.num_remarks[i],
                                 Remark_Cryo_Em_300.remarks[i], j, 0, 0, 0);
                      }
                 }
            } else if (remark_no == 350) {
                 if (is_electron_microscopy) {
                      exist = ndb_to_pdb_get_remark_from_premark(350);
                      if (!exist) ndb_to_pdb_get_remark_350();
                 } else if (_experiment_type & EXPERIMENT_TYPE_XRAY ||
                          _experiment_type & EXPERIMENT_TYPE_NEUTRON ||
                          _experiment_type & EXPERIMENT_TYPE_ELECTRON) {
                      if (!ndb_to_pdb_get_remark_350())
                           ndb_to_pdb_get_remark_from_premark(350);
                 }
            } else if (remark_no == 375) {
                 if (_experiment_type & EXPERIMENT_TYPE_XRAY ||
                     _experiment_type & EXPERIMENT_TYPE_NEUTRON)
                      ndb_to_pdb_get_remark_375();
            } else if (remark_no == 465) ndb_to_pdb_get_remark_465();
            else if (remark_no == 470)   ndb_to_pdb_get_remark_470();
            else if (remark_no == 500) {
                 ndb_to_pdb_get_remark_500(remark);
                 rms_deviation_of_bonds();
                 rms_deviation_of_angles();
                 outside_torsions();
                 non_cis_trans_torsions();
            } else if (remark_no == 525) {
                 ndb_to_pdb_get_remark_525();
            } else if (remark_no == 800) {
                 exist = ndb_to_pdb_get_remark_from_premark(800);
                 if (!exist)
                      ndb_to_pdb_get_general_remark(Num_Remark_800, Remark_800, 1, 0, 0, 0);
            } else if (remark_no == 900) {
                 if (_CardInfo[RENTRY_TOKEN-1].Head()) {
                      construct_remark_900();
                 } else ndb_to_pdb_get_remark_from_premark(900);
            } else ndb_to_pdb_get_remark_from_premark(remark_no);
       }
}

int _MAXIT::find_user_defined_remark(const int remark_no)
{
       char buffer[61], *p;
       int found = 0;
       int PDBRMK_TOKEN = find_card_id("PDBRMK");
       if (PDBRMK_TOKEN < 0) return found;
       One_Card_Info_Format *pCard = _CardInfo[PDBRMK_TOKEN].Head();
       while (pCard) {
            if (atoi(pCard->Field(1)) == remark_no) {
                 found = 1;
                 p = pCard->Field(3);
                 while (p) {
                      p = get_max_length_word(p, buffer, 60);
                      One_Card_Info_Format *newCard = _CardInfo[REMARK_TOKEN-1].
                            add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(remark_no, 1);
                      newCard->AddElementToField(buffer, 2);
                 }
            }
            pCard = pCard->Next();
       }
       return found;
}

void _MAXIT::ndb_to_pdb_get_group_remarks()
{
       int card_id, ContNo = 1, one_flag = 1, i;
       int program = 0;
       char buffer[80], buff[80], *p;
       GROUP_REMARKS *group_remark = NULL;
       One_Card_Info_Format *pCard = NULL, *newCard = NULL;

       pCard = _CardInfo[REFMET_TOKEN-1].Head();
       if (pCard) {
            if (strlen(pCard->Field(3)) < 80) {
                 strcpy(buffer, pCard->Field(3));
                 ndb_set_string_to_upper(buffer);
                 if (strstr(buffer, "CNS") ||
                     strstr(buffer, "CNX"))
                      program = 1;
                 else if (strstr(buffer, "NUCLSQ"))
                      program = 2;
                 else if (strstr(buffer, "PROLSQ") ||
                          strstr(buffer, "PROFFT") ||
                          strstr(buffer, "CCP4") ||
                          strstr(buffer, "PROTEIN") ||
                          strstr(buffer, "RESTRAIN") ||
                          strstr(buffer, "GPRLSA"))
                      program = 3;
                 else if (strstr(buffer, "REFMAC 5"))
                      program = 5;
                 else if (strstr(buffer, "REFMAC"))
                      program = 4;
                 else if (strstr(buffer,"TNT"))
                      program = 6;
                 else if (strstr(buffer,"SHELX"))
                      program = 7;
            }

            if (pCard->Next()) {
                 one_flag = 0;
                 ContNo = 1;
            } else one_flag = 1;

            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(3, 1);
            newCard->AddElementToField("REFINEMENT.", 2);

            while (pCard) {
                 if (strcmp(pCard->Field(3), "") && strlen(pCard->Field(3)) < 63) {
                      pCard->UpperCaseField(3);
                      newCard = _CardInfo[REMARK_TOKEN-1].
                                  add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(3, 1);

                      if (one_flag) sprintf(buffer, "  %s     : %s",
                                   "PROGRAM", pCard->Field(3));
                      else sprintf(buffer, "  %s %-3d : %s", "PROGRAM",
                                    ContNo, pCard->Field(3));
                      newCard->AddElementToField(buffer, 2);

                      for (i = 0; i < Max_Refinement_Programs; i++) {
                           if (strstr(pCard->Field(3), Refinement_programs[i].Program)) {
                                if (!strcmp(Refinement_programs[i].Program, "O")) {
                                     if (!strcmp(pCard->Field(3), "O")) break;
                                } else break;
                           }
                      }

                      if (i != Max_Refinement_Programs) {
                           newCard = _CardInfo[REMARK_TOKEN-1].
                                add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                           newCard->AddElementToField(3, 1);
                           p = get_max_length_word(Refinement_programs[i].Author, buff, 42);
                           if (!strcmp(buff, "?")) strcpy(buff, "NULL");
                           if (one_flag)
                                sprintf(buffer, "  %s     : %s", "AUTHORS", buff);
                           else sprintf(buffer, "  %s %-3d : %s", "AUTHORS", ContNo, buff);
                           newCard->AddElementToField(buffer, 2);
                           while (p) {
                                p = get_max_length_word(p, buff, 42);
                                if (!strcmp(buff, "?")) strcpy(buff, "NULL");
                                newCard = _CardInfo[REMARK_TOKEN-1].
                                          add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                                newCard->AddElementToField(3, 1);
                                sprintf(buffer, "  %s     : %s", "       ", buff);
                                newCard->AddElementToField(buffer, 2);
                           }
                      }
                 }
                 ContNo++;
                 pCard = pCard->Next();
            }
       }

       if (!program || program == 1) {
            pCard = _CardInfo[RFACTR_TOKEN-1].Head();
            if (pCard && !strcmp(pCard->Field(10), ""))
                 pCard->AddElementToField(pCard->Field(7), 10);
            pCard = _CardInfo[NCSMOD_TOKEN-1].Head();
            if (!pCard) {
                 pCard = _CardInfo[NCSMOD_TOKEN-1].
                          add_a_new_card(NdbToken[NCSMOD_TOKEN-1], 0);
                 pCard->AddElementToField(1, 1);
            }
            pCard = _CardInfo[XFILES_TOKEN-1].Tail();
            if (!pCard) {
                 pCard = _CardInfo[XFILES_TOKEN-1].
                          add_a_new_card(NdbToken[XFILES_TOKEN-1], 0);
                 pCard->AddElementToField(1, 1);
            } else {
                 for (i = 1; i < pCard->NumField(); i++) {
                      if (strcmp(pCard->Field(i), "")) break;
                 }
                 if (i < pCard->NumField()) {
                      i = atoi(pCard->Field(1)) + 1;
                      pCard = _CardInfo[XFILES_TOKEN-1].
                               add_a_new_card(NdbToken[XFILES_TOKEN-1], 0);
                      pCard->AddElementToField(i, 1);
                 }
            }
       }
       group_remark = group_remarks[program];
       for (i = 0; i < group_remark->Remarks_No; i++) {
            if (strcmp(group_remark->TokenName[i], "")) {
                 card_id = find_card_id(group_remark->TokenName[i]);
                 if (card_id == -1) continue;
                 pCard = _CardInfo[card_id].Head();
                 while (pCard) {
                      ndb_to_pdb_get_general_remark(group_remark->num_remarks[i],
                             group_remark->remarks[i], 0, 
                             atoi(pCard->Field(group_remark->repeat[i]-1)), 0, 0);
                      pCard = pCard->Next();
                 }
            } else if (group_remark->repeat[i] < 0)
                 ndb_to_pdb_get_general_remark(group_remark->num_remarks[i],
                            group_remark->remarks[i], 1, 0, 0, 0);
            else ndb_to_pdb_get_general_remark(group_remark->num_remarks[i],
                            group_remark->remarks[i], 0, 0, 0, 0);
       }
}

void _MAXIT::ndb_to_pdb_get_general_remark(const int num_remarks, REMARKS *Remarks,
          const int repeat, const int index, const int IsInosine, const int space)
{
       int i, j, card_id = -1, found, *single = NULL;
       One_Card_Info_Format *pCard = NULL, *newCard = NULL;

       for (i = 0; i < num_remarks; i++) {
            card_id = -1;
            for (j = 0; j < Remarks[i].NumField; j++) {
                 if (!strcmp(Remarks[i].FieldList[j].TokenName, "") && 
                              Remarks[i].FieldList[j].FieldId == 0 &&
                              Remarks[i].FieldList[j].FieldWidth == 0)
                      Remarks[i].FieldList[j].FieldWidth = 
                          strlen(Remarks[i].FieldList[j].Text);
                 if (strcmp(Remarks[i].FieldList[j].TokenName, "") && card_id == -1)
                      card_id = find_card_id(Remarks[i].FieldList[j].TokenName);
            }
       }
       if (repeat && card_id != -1) {
            found = 0;
            pCard = _CardInfo[card_id].Head();
            while (pCard) {
                 if (IsInosine && (card_id == BSPAIR_TOKEN-1 &&
                     (!strcmp(pCard->Field(11), "WATSON-CRICK") ||
                      !strcmp(pCard->Field(5), "") ||
                      !strcmp(pCard->Field(9), "")) ||
                     card_id == MODIFB_TOKEN-1 &&
                     res_name_cmp(pCard->Field(5), "I")) ||
                    !IsInosine && card_id == MODIFB_TOKEN-1 &&
                    !res_name_cmp(pCard->Field(5), "I")) {
                      pCard = pCard->Next();
                      continue;
                 }
                 found = 1;
                 break;
            }
            
            if (found) {
                 newCard = _CardInfo[REMARK_TOKEN-1].
                           add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                 newCard->AddElementToField(Remarks->Remark_No, 1);
            }
            single = new int[num_remarks];
            for (i = 0; i < num_remarks; i++) single[i] = 1;
            pCard = _CardInfo[card_id].Head();
            while (pCard) {
                 if (IsInosine && (card_id == BSPAIR_TOKEN-1 &&
                     (!strcmp(pCard->Field(11), "WATSON-CRICK") ||
                      !strcmp(pCard->Field(5), "") ||
                      !strcmp(pCard->Field(9), "")) ||
                     card_id == MODIFB_TOKEN-1 &&
                     res_name_cmp(pCard->Field(5), "I")) ||
                    !IsInosine && card_id == MODIFB_TOKEN-1 &&
                    !res_name_cmp(pCard->Field(5), "I")) {
                      pCard = pCard->Next();
                      continue;
                 }
                 if (space && pCard != _CardInfo[card_id].Head()) {
                      newCard = _CardInfo[REMARK_TOKEN-1].
                                add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(Remarks->Remark_No, 1);
                 }
                 for (i = 0; i < num_remarks; i++) {
                      if (Remarks[i].NumField == 1) {
                           if (single[i]) {
                                ndb_to_pdb_get_general_remark(&Remarks[i], pCard);
                                single[i] = 0;
                           }
                      } else ndb_to_pdb_get_general_remark(&Remarks[i], pCard);
                 }
                 pCard = pCard->Next();
            }
            delete [] single; single = NULL;
       } else {
            newCard = _CardInfo[REMARK_TOKEN-1].
                      add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(Remarks->Remark_No, 1);
            for (i = 0; i < num_remarks; i++) {
                 card_id = -1;
                 for (j = 0; j < Remarks[i].NumField; j++) {
                      if (strcmp(Remarks[i].FieldList[j].TokenName, ""))
                           card_id = find_card_id(Remarks[i].FieldList[j].TokenName);
                      if (card_id != -1) break;
                 }
                 if ((Remarks[i].Multiple_Treatment || index) && card_id != -1) {
                      pCard = _CardInfo[card_id].Head();
                      while (pCard) {
                           if (IsInosine && (card_id == BSPAIR_TOKEN-1 &&
                               (!strcmp(pCard->Field(11), "WATSON-CRICK") ||
                                !strcmp(pCard->Field(5), "") ||
                                !strcmp(pCard->Field(9), "")) ||
                               card_id == MODIFB_TOKEN-1 &&
                               res_name_cmp(pCard->Field(5), "I")) ||
                              !IsInosine && card_id == MODIFB_TOKEN-1 &&
                              !res_name_cmp(pCard->Field(5), "I")) {
                                pCard = pCard->Next();
                                continue;
                           }
                           if (!index || index && atoi(pCard->Field(1)) == index) {
                                ndb_to_pdb_get_general_remark(&Remarks[i], pCard);
                           }
                           pCard = pCard->Next();
                      }
                 } else ndb_to_pdb_get_general_remark(&Remarks[i]);
            }
       }
}

void _MAXIT::ndb_to_pdb_get_general_remark(REMARKS *Remark)
{
       int i, card_id, field_no, align, serial_no_field;
       char bigstring[100000], FieldFormat[80];
       double temp_double;
       One_Card_Info_Format *newCard = NULL, *pCard = NULL;

       newCard = _CardInfo[REMARK_TOKEN-1].
                    add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
       newCard->AddElementToField(Remark->Remark_No, 1);
       for (i = 0; i < Remark->NumField; i++) {
            if (!strcmp(Remark->FieldList[i].TokenName, "") &&
                !strcmp(Remark->FieldList[i].Text, "")) continue;

            align = check_align(Remark->Remark_No, &(Remark->FieldList[i]));
            get_remark_field_format(FieldFormat, Remark, i);
            memset(bigstring, 0, 10000);

            if (strcmp(Remark->FieldList[i].TokenName, "") &&
                Remark->FieldList[i].FieldId) {
                 card_id = find_card_id(Remark->FieldList[i].TokenName);
                 field_no = Remark->FieldList[i].FieldId-1;
                 pCard = NULL;
                 if (card_id != -1) pCard = _CardInfo[card_id].Head();
                 if (pCard) {
                      if (pCard->Next() &&
                         (card_id == EXPDTA_TOKEN-1 || card_id == XFILES_TOKEN-1 ||
                          card_id == find_card_id("DIFPTL") ||
                          card_id == DTMEAS_TOKEN-1 || card_id == PHVAL_TOKEN-1 ||
                          card_id == CRMETH_TOKEN-1 || card_id == DTMETH_TOKEN-1 || 
                          card_id == RADIAT_TOKEN-1 || card_id == DTWAVE_TOKEN-1 ||
                          card_id == WAVLEN_TOKEN-1 || card_id == DTTEMP_TOKEN-1)) {
                           serial_no_field = NdbToken[card_id].SeqField - 1;
                           if (card_id == find_card_id("DTWAVE")) serial_no_field = 2;
                           while (pCard) {
                                if (strcmp(pCard->Field(field_no), ""))
                                     strcat(bigstring, pCard->Field(field_no));
                                else if (!strcmp(bigstring, ""))
                                     strcat(bigstring, "NULL");
                                if (pCard->Next() && strcmp(pCard->Next()->Field(field_no), "")) {
                                     if (serial_no_field > 0 &&
                                        !strcmp(pCard->Field(serial_no_field),
                                           pCard->Next()->Field(serial_no_field)))
                                          strcat(bigstring, ", ");
                                     else strcat(bigstring, "; ");
                                }
                                pCard = pCard->Next();
                           }
                      } else if (strcmp(pCard->Field(field_no), "")) {
                           if (Remark->FieldList[i].FieldType < 3) {
                                temp_double = atof(pCard->Field(field_no));
                                if (Remark->Special_Treatment == PDB_REMARK_R_VALUE)
                                     temp_double = temp_double / 100.0;
                                sprintf(bigstring, FieldFormat, temp_double);
                           } else {
                                if (card_id != HEADER_TOKEN-1 || (field_no+1) != 2)
                                     sprintf(bigstring, FieldFormat, pCard->Field(field_no));
                           }
                      }
                 }
            } else sprintf(bigstring, FieldFormat, Remark->FieldList[i].Text);

            ndb_to_pdb_print_remark_value(bigstring, newCard, Remark, i, align);
       }
}

void _MAXIT::ndb_to_pdb_get_general_remark(REMARKS *Remark, One_Card_Info_Format *pCard)
{
       int i, field_no, align;
       char bigstring[10000], FieldFormat[80];
       double temp_double;
       One_Card_Info_Format *newCard = NULL;

       newCard = _CardInfo[REMARK_TOKEN-1].
                    add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
       newCard->AddElementToField(Remark->Remark_No, 1);
       for (i = 0; i < Remark->NumField; i++) {
            get_remark_field_format(FieldFormat, Remark, i);
            memset(bigstring, 0, 10000);

            align = check_align(Remark->Remark_No, &(Remark->FieldList[i]));

            if (strcmp(Remark->FieldList[i].TokenName, "") &&
                Remark->FieldList[i].FieldId) {
                 field_no = Remark->FieldList[i].FieldId-1;
                 if (strcmp(pCard->Field(field_no), "")) {
                      if (Remark->FieldList[i].FieldType < 3) {
                           temp_double = atof(pCard->Field(field_no));
                           sprintf(bigstring, FieldFormat, temp_double);
                      } else sprintf(bigstring, FieldFormat, pCard->Field(field_no));
                 }
            } else sprintf(bigstring, FieldFormat, Remark->FieldList[i].Text);
            ndb_to_pdb_print_remark_value(bigstring, newCard, Remark, i, align);
       }
}

void _MAXIT::ndb_to_pdb_print_remark_value(char *value, One_Card_Info_Format *newCard,
               REMARKS *Remark, const int field_no, const int align)
{
       int str_len, FieldLen, length, max_length, k, align_tmp, tmp_len;
       char *p = NULL, buffer[80], *tmp;;

       print_space_between_remark_field(newCard, Remark, field_no);
       str_len = strlen(newCard->Field(2));
       FieldLen = NdbToken[REMARK_TOKEN-1].FieldList[2].FieldWidth + 1;
       if (strcmp(value, "")) {
            if (FieldLen > ((int) strlen(value) + str_len + 1))
                 newCard->AttachToField(value, 2);
            else {
                 max_length = FieldLen - (str_len + 2);
                 p = get_max_length_word(value, buffer, max_length);
                 newCard->AttachToField(buffer, 2);
                 length = strlen(Remark->FieldList[0].Text) +
                                 Remark->FieldList[0].FieldStCol;
                 align_tmp = 0;
                 if (align) {
                      max_length = FieldLen - length - 1;
                      align_tmp = 1;
                      tmp = p;
                      tmp_len = 0;
                      while (tmp) {
                           tmp = get_word(tmp, buffer);
                           if ((int) strlen(buffer) > tmp_len)
                                tmp_len = strlen(buffer);
                      }
                      if (tmp_len > (max_length - 1)) {
                           max_length = FieldLen - 3;
                           align_tmp = 0;
                      }
                 } else max_length = FieldLen - 3;
                 while (p) {
                      p = get_max_length_word(p, buffer, max_length);
                      newCard = _CardInfo[REMARK_TOKEN-1].
                          add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(Remark->Remark_No, 1);
                      if (align_tmp) {
                           for (k = 0; k < length; k++)
                                newCard->AttachToField(" ", 2);
                           newCard->AttachToField(buffer, 2);
                      } else {
                           newCard->AddElementToField(" ", 2);
                           newCard->AttachToField(buffer, 2);
                      }
                 }
            }
       } else print_null_remark_value(newCard, Remark->FieldList[field_no].FieldWidth,
                            Remark->FieldList[field_no].FieldJustification);

       if (Remark->Remark_No > 100 && Remark->Remark_No != 103 &&
           Remark->Remark_No != 105 && Remark->Remark_No != 106 &&
           field_no == Remark->NumField-1 && Remark->Remark_No != 200 && 
           Remark->Remark_No != 210 && Remark->Remark_No != 215 &&
           Remark->Remark_No != 220 && Remark->Remark_No != 225 &&
           Remark->Remark_No != 230 && Remark->Remark_No != 240 &&
           Remark->Remark_No != 245 && Remark->Remark_No != 247 &&
           Remark->Remark_No != 265 &&
           Remark->Remark_No != 280 && Remark->Remark_No != 300 &&
           Remark->Remark_No != 350 && Remark->Remark_No != 375 &&
           Remark->Remark_No != 465 && Remark->Remark_No != 470 &&
           Remark->Remark_No != 500 && Remark->Remark_No != 525 &&
           Remark->Remark_No != 800 && Remark->Remark_No != 900) {
            strcpy(buffer, newCard->Field(2));
            ndb_strip_trailing_blanks(buffer);
            strcat(buffer, ".");
            newCard->AddElementToField(buffer, 2);
       }
}

int _MAXIT::ndb_to_pdb_get_remark_from_premark(const int remarkNo)
{
       int exist;
       char line[100], *p;
       One_Card_Info_Format *pCard = NULL, *newCard = NULL;

       if (remarkNo == 550) return 0;
       pCard = _CardInfo[PREMRK_TOKEN-1].Head();
       while (pCard) {
            if (atoi(pCard->Field(1)) == remarkNo) break;
            pCard = pCard->Next();
       }
       if (pCard == NULL) return 0;

       if (remarkNo == 5) {
            newCard = pCard;
            exist = 0;
            while (newCard && atoi(newCard->Field(1))  == remarkNo) {
                 if (strstr(newCard->Field(2), "LAYER 1 RELEASE")) {
                      exist = 1;
                      break;
                 }
                 newCard = newCard->Next();
            }
            if (exist) return 0;
       }

       while (pCard) {
            if (atoi(pCard->Field(1)) == remarkNo) {
                 newCard = _CardInfo[REMARK_TOKEN-1].
                         add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                 newCard->AddElementToField(remarkNo, 1);
                 strcpy(line, pCard->Field(2));
                 p = strstr(line, "N/A");
                 if (p) sprintf(p, "%s", "NULL");
                 p = strstr(line, " NONE");
                 if (p) sprintf(p, "%s", " NULL");
                 p = strstr(line, ":NONE");
                 if (p) sprintf(p, "%s", ": NULL");
                 newCard->AddElementToField(line, 2);
            }
            pCard = pCard->Next();
       }
       return 1;
}

void _MAXIT::ndb_to_pdb_get_remark_280_crystal() 
{
       int card_id, len;
       char buffer[5000];
       One_Card_Info_Format *pCard = NULL, *qCard = NULL;

       card_id = find_card_id("CRDTLS");
       if (_CardInfo[card_id].Head() == NULL && _CardInfo[CRSOLU_TOKEN-1].Head()) {
            pCard = _CardInfo[CRSOLU_TOKEN-1].Head();
            memset(buffer, 0, 5000);
            while (pCard) {
                 if (!strcmp(pCard->Field(3), "1") &&
                      strcasecmp(pCard->Field(4), "WATER")) {
                       len = strlen(buffer);
                       if (len) sprintf(&buffer[len], ", %s", pCard->Field(4));
                       else strcpy(buffer, pCard->Field(4));
                 }
                 pCard = pCard->Next();
            }
            if (strcmp(buffer, "")) {
                 pCard = _CardInfo[card_id].add_a_new_card(NdbToken[card_id], 0);
                 pCard->AddElementToField(buffer, 2);
            }
       }
       pCard = _CardInfo[card_id].Head();
       if (pCard) {
            qCard = pCard->Next();
            while (qCard) {
                 if (strcmp(qCard->Field(2), "")) {
                      if (strcmp(pCard->Field(2), "")) {
                           len = strlen(pCard->Field(2));
                           if (pCard->Field(2)[len - 1] == '.')
                                pCard->AttachToField(" ", 2);
                           else pCard->AttachToField(". ", 2);
                      }
                      pCard->AttachToField(qCard->Field(2), 2);
                 }
                 qCard = qCard->Next();
            }
       }
       ndb_to_pdb_get_general_remark(Num_Remark_280, Remark_280, 0, 0, 0, 0);
}

void _MAXIT::ndb_to_pdb_get_remark_290()
{
       int i, j, k, lineNo, card_id, field_no;
       double result[3][3], tr[3];
       char FieldFormat[80], tmpString[80], buffer[80];
       One_Card_Info_Format *newCard = NULL, *pCard = NULL;
       NDBCELLCONST *cell = _cell;

       if (cell == NULL) return;

       for (j = 0; j < Num_Remark_290; j++) {
            for (i = 0; i < Remark_290[j].NumField; i++) 
                 if (!strcmp(Remark_290[j].FieldList[i].TokenName, "") && 
                             Remark_290[j].FieldList[i].FieldId == 0 &&
                             Remark_290[j].FieldList[i].FieldWidth == 0)
                      Remark_290[j].FieldList[i].FieldWidth = 
                             strlen(Remark_290[j].FieldList[i].Text);

            lineNo = 1;
            if (Remark_290[j].Special_Treatment == PDB_REMARK_NNNMMM_SYMOP)
                 lineNo = cell->nop;
            else if (Remark_290[j].Special_Treatment == PDB_REMARK_XYZT) 
                 lineNo = cell->nop * 3;
      
            for (k = 0; k < lineNo; k++) {
                 newCard = _CardInfo[REMARK_TOKEN-1].
                            add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                 newCard->AddElementToField(Remark_290[j].Remark_No, 1);
                 if (Remark_290[j].Special_Treatment == PDB_REMARK_XYZT &&
                     k % 3 == 0)
                      ndb_get_symmetry_matrix(cell, k/3, 0, 0, 0, result, tr);
                 for (i = 0; i < Remark_290[j].NumField; i++) {
                      print_space_between_remark_field(newCard, &Remark_290[j], i);
                      get_remark_field_format(FieldFormat, &Remark_290[j], i);
                      if (strcmp(Remark_290[j].FieldList[i].TokenName,"") ||
                                 Remark_290[j].FieldList[i].FieldId != 0) {
                           card_id = find_card_id(Remark_290[j].FieldList[i].TokenName);
                           field_no = Remark_290[j].FieldList[i].FieldId-1;

                           if (!strcmp(Remark_290[j].FieldList[i].Text,"NNNMMM")) {
                                sprintf(tmpString, "%d%d%d%d", k+1, 5, 5, 5);
                                sprintf(buffer, FieldFormat, tmpString);
                                newCard->AttachToField(buffer, 2);
                           } else if (!strcmp(Remark_290[j].FieldList[i].Text,
                                         "SYMOP")) {
                                memset(tmpString, 0, MxStrLen);
                                ndb_get_symmetry_operation_name(cell, k, 0, 0, 0,
                                             tmpString);
                                newCard->AttachToField(tmpString, 2);
                           } else if (!strcmp(Remark_290[j].FieldList[i].Text,
                                           "SMTRY")) {
                                sprintf(tmpString, "%s%d",
                                       Remark_290[j].FieldList[i].Text, k % 3 + 1);
                                sprintf(buffer, FieldFormat, tmpString);
                                newCard->AttachToField(buffer, 2);
                           } else if (!strcmp(Remark_290[j].FieldList[i].Text, "Serial_No")) {
                                sprintf(buffer, FieldFormat, (double) (k / 3 + 1));
                                newCard->AttachToField(buffer, 2);
                           } else if (!strcmp(Remark_290[j].FieldList[i].Text, "X")) { 
                                sprintf(buffer, FieldFormat, result[k%3][0]);
                                newCard->AttachToField(buffer, 2);
                           } else if (!strcmp(Remark_290[j].FieldList[i].Text, "Y")) {
                                sprintf(buffer, FieldFormat, result[k%3][1]);
                                newCard->AttachToField(buffer, 2);
                           } else if (!strcmp(Remark_290[j].FieldList[i].Text, "Z")) {
                                sprintf(buffer, FieldFormat, result[k%3][2]);
                                newCard->AttachToField(buffer, 2);
                           } else if (!strcmp(Remark_290[j].FieldList[i].Text, "T")) {
                                sprintf(buffer, FieldFormat, tr[k%3]);
                                newCard->AttachToField(buffer, 2);
                           } else if (card_id == -1 || card_id > MxTokens ||
                              field_no < 0 || field_no >  NdbToken[card_id].NumField)
                                print_null_remark_value(newCard, 
                                   Remark_290[j].FieldList[i].FieldWidth,
                                   Remark_290[j].FieldList[i].FieldJustification);
                           else {
                                pCard = _CardInfo[card_id].Head();
                                if (pCard && (strcmp(pCard->Field(field_no), "") ||
                                    !strcmp(Remark_290[j].FieldList[i].TokenName,
                                       "CRYST1") && strcmp(pCard->Field(7), ""))) {
                                     if (!strcmp(pCard->Field(field_no), "") &&
                                        !strcmp(Remark_290[j].FieldList[i].TokenName,
                                         "CRYST1") && strcmp(pCard->Field(7), ""))
                                          field_no = 7;
                                     sprintf(buffer, FieldFormat, pCard->Field(field_no));
                                     newCard->AttachToField(buffer, 2);
                                } else print_null_remark_value(newCard, 
                                    Remark_290[j].FieldList[i].FieldWidth,
                                    Remark_290[j].FieldList[i].FieldJustification);
                           }
                      } else {
                           sprintf(buffer, FieldFormat, Remark_290[j].FieldList[i].Text);
                           newCard->AttachToField(buffer, 2);
                      }
                 }
            }
       }
}

int _MAXIT::ndb_to_pdb_get_remark_300()
{
       int num_chn = 0, card_id, n_biol = 0, i = 0;
       _BIOL_ID BIOL[200];
       _CHAIN *chain = NULL;
       One_Card_Info_Format *pCard = NULL, *stBiolCard = NULL;
       NDBCELLCONST *cell = _cell;

       if (_num_mol == 0 || _molecules == NULL) return 0;

       if (cell == NULL) return 0;

       card_id = find_card_id("CHAINS");
       pCard = _CardInfo[card_id].add_a_new_card(NdbToken[card_id], 0);
       chain = _molecules[0]->GetFirstChain();
       while (chain) {
            if (chain->chain_type() == ATOMP_TOKEN ||
                chain->chain_type() == ATOMN_TOKEN) num_chn++;
            chain = _molecules[0]->GetNextChain();
       }
       if (num_chn) pCard->AddElementToField(num_chn, 2);

       if (check_virus_ncs_remark_300()) {
            pCard = _CardInfo[card_id].Head();
            while (pCard) pCard = _CardInfo[card_id].delete_a_card(pCard);
            return 1;
       }

       stBiolCard = _CardInfo[STBIOL_TOKEN-1].Head();
       while (stBiolCard) {
            for (i = 0; i < n_biol; i++) {
                 if (!strcmp(BIOL[i].biol_id, stBiolCard->Field(2))) break;
            }
            if (i == n_biol) {
                 strcpy(BIOL[i].biol_id, stBiolCard->Field(2));
                 n_biol++;
            }
            stBiolCard = stBiolCard->Next();
       }
       if (n_biol > 1) qsort((void *) BIOL, n_biol, sizeof(_BIOL_ID), biol_id_compare);

       for (i = 0; i < n_biol; i++) {
            if (i == 0) pCard->AddElementToField(BIOL[i].biol_id, 3);
            else {
                 pCard->AttachToField(", ", 3);
                 pCard->AttachToField(BIOL[i].biol_id, 3);
            }
       }

       if (_experiment_type & EXPERIMENT_TYPE_XRAY ||
           _experiment_type & EXPERIMENT_TYPE_NEUTRON)
            ndb_to_pdb_get_general_remark(Num_Remark_300, Remark_300, 0, 0, 0, 0);
       else ndb_to_pdb_get_general_remark(Num_Remark_300_NMR, Remark_300_NMR, 0, 0, 0, 0);

       pCard = _CardInfo[card_id].Head();
       while (pCard) pCard = _CardInfo[card_id].delete_a_card(pCard);

       return 1;
}

int _MAXIT::ndb_to_pdb_get_remark_350()
{
       typedef struct {
              char asym_id[3];
              char pdb_id[500];
              int  n_symmetry;
              char symmetry[100][10];
              int  label;
       } BIOL_UNIT;

       BIOL_UNIT biol_unit[500];
       int n_biol = 0, i, j, k, l, t, len, serialNo, n_unit;
       int op1, op2, opno, lx, ly, lz, field_no;
       char FieldFormat[80], buffer[100], *p;
       _BIOL_ID BIOL[200];
       double result[3][3], tr[3];
       One_Card_Info_Format *stBiolCard = NULL, *pCard = NULL, *newCard = NULL;
       NDBCELLCONST *cell = _cell;

       if (_num_mol == 0 || _molecules == NULL) return 0;

       if (cell == NULL) return 0;

       if (check_virus_ncs_remark_350()) return 1;

       stBiolCard = _CardInfo[STBIOL_TOKEN-1].Head();
       while (stBiolCard) {
            for (i = 0; i < n_biol; i++) {
                 if (!strcmp(BIOL[i].biol_id, stBiolCard->Field(2))) break;
            }
            if (i == n_biol) {
                 strcpy(BIOL[i].biol_id, stBiolCard->Field(2));
                 n_biol++;
            }
            stBiolCard = stBiolCard->Next();
       }
       if (n_biol > 1) qsort((void *) BIOL, n_biol, sizeof(_BIOL_ID), biol_id_compare);

       ndb_to_pdb_get_general_remark(Num_Remark_350, Remark_350, 0, 0, 0, 0);

       serialNo = 0;
       for (l = 0; l < n_biol; l++) {
            n_unit = 0;
            stBiolCard = _CardInfo[STBIOL_TOKEN-1].Head();
            while (stBiolCard) {
                 if (!strcmp(stBiolCard->Field(2), BIOL[l].biol_id)) {
                      if (!strcmp(stBiolCard->Field(4), NDB_BASE_SYMMETRY) &&
                           strcmp(stBiolCard->Field(13), "")) {
                           strcpy(biol_unit[n_unit].asym_id, stBiolCard->Field(3));
                           strcpy(biol_unit[n_unit].pdb_id, stBiolCard->Field(13));
                           strcpy(biol_unit[n_unit].symmetry[0], stBiolCard->Field(4));
                           biol_unit[n_unit].n_symmetry = 1;
                           biol_unit[n_unit].label = 1;
                           pCard = stBiolCard->Next();
                           while (pCard) {
                                if (strcmp(pCard->Field(4), NDB_BASE_SYMMETRY) &&
                                   !strcmp(pCard->Field(3), stBiolCard->Field(3))) {
                                     for (i = 0; i < biol_unit[n_unit].n_symmetry; i++)
                                          if (!strcmp(biol_unit[n_unit].symmetry[i],
                                                    pCard->Field(4))) break;
                                     if (i == biol_unit[n_unit].n_symmetry) {
                                          op1 = atoi(pCard->Field(4));
                                          for (i = biol_unit[n_unit].n_symmetry - 1;
                                                 i >= 0; i--) {
                                               op2 = atoi(biol_unit[n_unit].symmetry[i]);
                                               if (op1 > op2) break;
                                          }
                                          for (j = biol_unit[n_unit].n_symmetry - 1;
                                                   j >= (i + 1); j--) {
                                               strcpy(biol_unit[n_unit].symmetry[j+1],
                                                      biol_unit[n_unit].symmetry[j]);
                                          }
                                          strcpy(biol_unit[n_unit].symmetry[i+1],
                                                 pCard->Field(4));
                                          biol_unit[n_unit].n_symmetry++;
                                     }
                                }
                                pCard = pCard->Next();
                           }
                           n_unit++;
                      }
                 }
                 stBiolCard = stBiolCard->Next();
            }

            for (i = 0; i < n_unit - 1; i++) {
                 if (!biol_unit[i].label) continue;
                 for (j = i + 1; j < n_unit; j++) {
                      if (!biol_unit[j].label) continue;
                      if (biol_unit[i].n_symmetry != biol_unit[j].n_symmetry)
                           continue;
                      for (k = 0; k < biol_unit[i].n_symmetry; k++) {
                           if (strcmp(biol_unit[i].symmetry[k],
                                      biol_unit[j].symmetry[k])) break;
                      }
                      if (k == biol_unit[i].n_symmetry) {
                           biol_unit[j].label = 0;
                           if (!strstr(biol_unit[i].pdb_id, biol_unit[j].pdb_id)) {
                                strcat(biol_unit[i].pdb_id, ", ");
                                strcat(biol_unit[i].pdb_id, biol_unit[j].pdb_id);
                           }
                      }
                 }
            }

            newCard = _CardInfo[REMARK_TOKEN-1].
                             add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(350, 1);
            sprintf(buffer, "BIOMOLECULE: %s", BIOL[l].biol_id);
            newCard->AddElementToField(buffer, 2);

            for (i = 0; i < n_unit; i++) {
                 if (!biol_unit[i].label) continue;
                 p = get_max_length_word(biol_unit[i].pdb_id, FieldFormat, 28);
                 sprintf(buffer, "APPLY THE FOLLOWING TO CHAINS: %s", FieldFormat);
                 newCard = _CardInfo[REMARK_TOKEN-1].
                                  add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                 newCard->AddElementToField(350, 1);
                 newCard->AddElementToField(buffer, 2);
                 while (p) {
                      p = get_max_length_word(p, buffer, 58);
                      newCard = _CardInfo[REMARK_TOKEN-1].
                                     add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(350, 1);
                      newCard->AddElementToField(buffer, 2);
                 }

                 for (t = 0; t < biol_unit[i].n_symmetry; t++) {
                      serialNo++;
                      opno = atoi(biol_unit[i].symmetry[t])-1;
                      len = strlen(biol_unit[i].symmetry[t]);
                      for (j = 0; j < len; j++) {
                           if (biol_unit[i].symmetry[t][j] == '_') break;
                      }
                      lx = biol_unit[i].symmetry[t][j+1] - '5';
                      ly = biol_unit[i].symmetry[t][j+2] - '5';
                      lz = biol_unit[i].symmetry[t][j+3] - '5';
                 
                      ndb_get_symmetry_matrix(cell, opno, lx, ly, lz, result, tr);
                      for (k = 0; k < 3; k++) {
                           newCard = _CardInfo[REMARK_TOKEN-1].
                                  add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                           newCard->AddElementToField(Remark_SYMMA.Remark_No, 1);
                           for (j = 0; j < Remark_SYMMA.NumField; j++) {
                                print_space_between_remark_field(newCard, &Remark_SYMMA, j); 
                                get_remark_field_format(FieldFormat, &Remark_SYMMA, j);
                                field_no = Remark_SYMMA.FieldList[j].FieldId-1;
                                if (!strcmp("BIOMT", Remark_SYMMA.FieldList[j].Text))
                                     sprintf(buffer, "%s%d", Remark_SYMMA.FieldList[j].Text, k + 1);
                                else if (field_no == 1)
                                     sprintf(buffer, FieldFormat, (double) serialNo);
                                else if (j != Remark_SYMMA.NumField - 1)
                                     sprintf(buffer, FieldFormat, result[k][j-2]);
                                else sprintf(buffer, FieldFormat, tr[k]);
                                newCard->AttachToField(buffer, 2);
                           }
                      }
                 }
            }
       }

       return 1;
}

void _MAXIT::ndb_to_pdb_get_remark_375()
{
       int i = 0, num = 0, len = 0;
       char buffer[70], chnid[5];
       _ATOM **atom = NULL;
       One_Card_Info_Format *newCard = NULL;

       if (_n_speical == 0 || _speical == NULL) return;

       ndb_to_pdb_get_general_remark(Num_Remark_375, Remark_375, 0, 0, 0, 0);
       for (i = 0; i < _n_speical; i++) {
            atom = _molecules[0]->find_ndb_atom(_speical[i]->a_atomtyp,
                      _speical[i]->a_chnid, _speical[i]->a_resnam,
                      _speical[i]->a_resnum, "", num);
            if (!atom) continue;

            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(375, 1);

            if (!strcmp(atom[0]->pdb_resnam(), "HOH")) 
                 sprintf(buffer, "%-4s ", "    ");
            else sprintf(buffer, "%-4s ", atom[0]->pdb_atmnam());

            len = strlen(buffer);
            sprintf(&buffer[len], "%3s ", atom[0]->pdb_resnam());
            
            len = strlen(buffer);
            strcpy(chnid, " ");
            if (strcmp(atom[0]->pdb_chnid(), ""))
                 strcpy(chnid, atom[0]->pdb_chnid());
            sprintf(&buffer[len], "%c", chnid[0]);

            len = strlen(buffer);
            sprintf(&buffer[len], "%4d", atom[0]->pdb_resnum());

            len = strlen(buffer);
            strcpy(chnid, " ");
            if (strcmp(atom[0]->ins_code(), ""))
                 strcpy(chnid, atom[0]->ins_code());
            sprintf(&buffer[len], "%c", chnid[0]);

            len = strlen(buffer);
            sprintf(&buffer[len], " %s",
                          " LIES ON A SPECIAL POSITION.");
            newCard->AddElementToField(buffer, 2);
            delete [] atom;
       }
}

void _MAXIT::ndb_to_pdb_get_remark_465()
{
       char mol_id[4], chain_id[2], insert_code[2], buffer[80];
       One_Card_Info_Format *pCard = NULL, *newCard = NULL;

       pCard = _CardInfo[MISRES_TOKEN-1].Head();
       if (pCard) ndb_to_pdb_get_general_remark(Num_Remark_465, Remark_465, 0, 0, 0, 0);
       while (pCard) {
            newCard = _CardInfo[REMARK_TOKEN-1].add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(465, 1);
            if (strcmp(pCard->Field(2), ""))
                 strcpy(mol_id, pCard->Field(2));
            else strcpy(mol_id, "   ");
            if (strcmp(pCard->Field(3), ""))
                 strcpy(chain_id, pCard->Field(3));
            else strcpy(chain_id, " ");
            if (strcmp(pCard->Field(6), ""))
                 strcpy(insert_code, pCard->Field(6));
            else strcpy(insert_code, " ");
            sprintf(buffer, "%3s %3s %c %5s%c", mol_id, pCard->Field(4),
                      chain_id[0], pCard->Field(5), insert_code[0]);
            newCard->AddElementToField(buffer, 2);
            pCard = pCard->Next();
       }
}

void _MAXIT::ndb_to_pdb_get_remark_470()
{
       int first = TRUE, first_residue = 0, num = 0;
       char head[20], model[5], buff[10], buffer[10], chnid = ' ', *p = NULL;
       char ins = ' ';
       One_Card_Info_Format *newCard = NULL;
       _CHAIN *chain = NULL;
       _RESIDUE *residue = NULL;
       for (int i = 0; i < _num_mol; i++) {
            chain = _molecules[i]->GetFirstChain();
            while (chain) {
                 if (chain->chain_type() != ATOMN_TOKEN &&
                     chain->chain_type() != ATOMP_TOKEN) {
                      chain = _molecules[i]->GetNextChain();
                      continue;
                 }
                 first_residue = 0;
                 residue = chain->GetFirstResidue();
                 while (residue) {
                      residue->find_missing_or_extra_atoms(chain->chain_type(),
                                  !first_residue, 0);
                      first_residue = 1;
                      if (!strcmp(residue->missing().Text(), "")) {
                           residue = chain->GetNextResidue();
                           continue;
                      }
                  
                      if (first) {
                           first = FALSE;
                           ndb_to_pdb_get_general_remark(Num_Remark_470, Remark_470, 0, 0, 0, 0);
                      }
     
                      head[0] = '\0';
                      model[0] = '\0';
                      if (_num_mol > 1) sprintf(model, "%3d", _molecules[i]->Mol_ID());
                      else strcpy(model, "   ");
                      ins = residue->GetFirstAtom()->ins_code()[0];
                      if (ins == '\0') ins = ' ';
                      chnid = chain->PDB_ChainID()[0];
                      if (chnid == '\0') chnid = ' ';
     
                      sprintf(head, "%3s %3s %c%4d%c   ", model,
                          residue->ResName(), chnid, residue->pdb_res_no(), ins);
     
                      num = 0;
                      newCard = _CardInfo[REMARK_TOKEN-1].
                                   add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(470, 1);
                      newCard->AddElementToField(head, 2);
     
                      p = residue->missing().Text();
                      if (p) ndb_clean_string(p);
                      while (p && strcmp(p, "")) {
                           if (num == 7) {
                                newCard = _CardInfo[REMARK_TOKEN-1].
                                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                                newCard->AddElementToField(470, 1);
                                newCard->AddElementToField(head, 2);
                                num = 0;
                           }
                           p = get_word(p, buff);
                           sprintf(buffer, "%-6s", buff);
                           newCard->AttachToField(buffer, 2);
                           num++;
                      }
                      residue = chain->GetNextResidue();
                 }
                 chain = _molecules[i]->GetNextChain();
            }
       }
}

void _MAXIT::ndb_to_pdb_get_remark_500(const int remark)
{
       int i, rowNo, exist_asym_close_contact = 0, exist_sym_close_contact = 0;
       int symmetry_op_2, dist_index;
       BTreeObj<_DIndex> _Index;
       CifString string;
       _DIndex _idx;
       ISTable *Table = NULL;

       if (!_CifObj) return;
       Table = _CifObj->GetTablePtr(_StructureId, "ebi_validate_contact");
       if (is_empty_table(Table)) return;

       rowNo = Table->GetNumRows();
       symmetry_op_2 = Table->GetColumnIndex("symmetry_op_2");
       dist_index = Table->GetColumnIndex("dist");
       _Index.Clear();
       for (i = 0; i < rowNo; i++) {
            Table->GetCell(string, symmetry_op_2, i);
            if (!strcasecmp(string.Text(), "1_555")) exist_asym_close_contact = 1;
            if (strcasecmp(string.Text(), "1_555")) exist_sym_close_contact = 1;
            Table->GetCell(string, dist_index, i);
            _idx.set_value(atof(string.Text()));
            _idx.set_pos(i);
            _Index.Add(_idx);
       }
       if (exist_asym_close_contact) {
            if (_experiment_type & EXPERIMENT_TYPE_MODEL ||
                _experiment_type & EXPERIMENT_TYPE_NMR)
                 ndb_to_pdb_get_general_remark(Num_Remark_500_NMR, Remark_500_NMR, 0, 0, 0, 0);
            else ndb_to_pdb_get_general_remark(Num_Remark_500_A, Remark_500_A, 0, 0, 0, 0);
            output_close_contact(Table, _Index, 0);
    
       }
       if (!remark && exist_sym_close_contact) {
            ndb_to_pdb_get_general_remark(Num_Remark_500_S, Remark_500_S, 0, 0, 0, 0);
            output_close_contact(Table, _Index, 1);
       }
}

void _MAXIT::ndb_to_pdb_get_remark_525()
{
       if (_n_waters == 0 || _waters == NULL) return;

       ndb_to_pdb_get_general_remark(Num_Remark_525, Remark_525, 0, 0, 0, 0);

       int num = 0, len = 0, i;;
       double dist = 0;
       _ATOM **atom = NULL;
       char buffer[70], chnid[5], ins_code[5];
       One_Card_Info_Format *newCard = NULL;

       for (i = 0; i < _n_waters; i++) {
            atom = _molecules[0]->find_ndb_atom(_waters[i]->a_atomtyp,
                      _waters[i]->a_chnid, _waters[i]->a_resnam,
                      _waters[i]->a_resnum, "", num);
            if (!atom) continue;

            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(525, 1);

            strcpy(chnid, " ");
            strcpy(ins_code, " ");
            if (strcmp(atom[0]->pdb_chnid(), ""))
                 strcpy(chnid, atom[0]->pdb_chnid());
            if (strcmp(atom[0]->ins_code(), ""))
                 strcpy(ins_code, atom[0]->ins_code());
            sprintf(buffer, "   %3s %c%4d%c", atom[0]->pdb_resnam(),
                      chnid[0], atom[0]->pdb_resnum(), ins_code[0]);
            
            dist = cal_min_distance(_molecules[0], atom[0]);
            delete [] atom;
            len = strlen(buffer);
            sprintf(&buffer[len], 
                    "       DISTANCE = %5.2f ANGSTROMS", dist);
            newCard->AddElementToField(buffer, 2);
       }
}

void _MAXIT::ndb_to_pdb_processing_nmr_remarks()
{
       int count = 0, i = 0;
       char buff[1000], program[1000], authors[1000];
       char maker[100], model[100], strengh[100], *p;
       One_Card_Info_Format *pCard = NULL, *qCard = NULL;

       pCard = _CardInfo[REFMET_TOKEN-1].Head();
       while (pCard) pCard = _CardInfo[REFMET_TOKEN-1].delete_a_card(pCard);
       pCard = _CardInfo[NMRECD_TOKEN-1].Head();
       while (pCard) pCard = _CardInfo[NMRECD_TOKEN-1].delete_a_card(pCard);
       pCard = _CardInfo[NMRSFT_TOKEN-1].Head();
       while (pCard) pCard = _CardInfo[NMRSFT_TOKEN-1].delete_a_card(pCard);

       pCard = _CardInfo[SFTWAR_TOKEN-1].Head();
       while (pCard) {
            if (!strcasecmp(pCard->Field(2), "refinement")) count++;
            pCard = pCard->Next();
       }
       program[0] = '\0'; authors[0] = '\0';
       i = 0;
       pCard = _CardInfo[SFTWAR_TOKEN-1].Head();
       while (pCard) {
            if (!strcasecmp(pCard->Field(2), "refinement")) {
                 i++; 
                 if (strcmp(pCard->Field(4), ""))
                      sprintf(buff, "%s %s", pCard->Field(3), pCard->Field(4));
                 else sprintf(buff, "%s", pCard->Field(3));
                 if (strcmp(program, "")) strcat(program, ", ");
                 strcat(program, buff);

                 if (count > 1)
                      sprintf(buff, "%s (%s)", pCard->Field(5), pCard->Field(3));
                 else strcpy(buff, pCard->Field(5));
                 if (strcmp(authors, "")) strcat(authors, ", ");
                 strcat(authors, buff);
            }
            pCard = pCard->Next();
       }
       pCard = _CardInfo[REFMET_TOKEN-1].add_a_new_card(NdbToken[REFMET_TOKEN-1], 0);
       pCard->AddElementToField(program, 3);
       pCard->AddElementToField(authors, 4);

       count = 0;
       pCard = _CardInfo[SFTWAR_TOKEN-1].Head();
       while (pCard) {
            if (strcasecmp(pCard->Field(2), "refinement")) count++;
            pCard = pCard->Next();
       }
       program[0] = '\0'; i = 0;
       pCard = _CardInfo[SFTWAR_TOKEN-1].Head();
       while (pCard) {
            if (strcasecmp(pCard->Field(2), "refinement")) {
                 i++;
                 if (strcmp(pCard->Field(4), ""))
                      sprintf(buff, "%s %s", pCard->Field(3), pCard->Field(4));
                 else sprintf(buff, "%s", pCard->Field(3));
                 if (!strstr(program, buff)) {
                      if (strcmp(program, "")) strcat(program, ", ");
                      strcat(program, buff);
                 }
            }
            pCard = pCard->Next();
       }
       pCard = _CardInfo[NMRSFT_TOKEN-1].add_a_new_card(NdbToken[NMRSFT_TOKEN-1], 0);
       pCard->AddElementToField(program, 2);

       pCard = _CardInfo[NMREXP_TOKEN-1].Head();
       program[0] = '\0';
       while (pCard) {
            if (!strstr(program, pCard->Field(3))) {
                 if (!strcmp(program, "")) strcpy(program, pCard->Field(3));
                 else {
                      strcat(program, ", ");
                      strcat(program, pCard->Field(3));
                 }
            }
            pCard = pCard->Next();
       }
       pCard = _CardInfo[NMRECD_TOKEN-1].add_a_new_card(NdbToken[NMRECD_TOKEN-1], 0);
       pCard->AddElementToField(program, 2);

       pCard = _CardInfo[NMRSPM_TOKEN-1].Head();
       if (pCard) {
            maker[0] = model[0] = strengh[0] = '\0';
            while (pCard) {
                 p = strstr(pCard->Field(4), "MHZ");
                 if (p == NULL) {
                      sprintf(buff, "%s MHZ", pCard->Field(4));
                      pCard->AddElementToField(buff, 4);
                 }
                 if (strcmp(pCard->Field(2), "") && !strstr(model, pCard->Field(2))) {
                      if (strcmp(model, "")) {
                           strcat(model, ", ");
                           strcat(model, pCard->Field(2));
                      } else strcpy(model, pCard->Field(2));
                 }
                 if (strcmp(pCard->Field(3), "") && !strstr(maker, pCard->Field(3))) {
                      if (strcmp(maker, "")) {
                           strcat(maker, ", ");
                           strcat(maker, pCard->Field(3));
                      } else strcpy(maker, pCard->Field(3));
                 }
                 if (strcmp(pCard->Field(4), "") && !strstr(strengh, pCard->Field(4))) {
                      if (strcmp(strengh, "")) {
                           strcat(strengh, ", ");
                           strcat(strengh, pCard->Field(4));
                      } else strcpy(strengh, pCard->Field(4));
                 }
                 pCard = pCard->Next();
            }
     
            pCard = _CardInfo[NMRSPM_TOKEN-1].Head();
            while (pCard) pCard = _CardInfo[NMRSPM_TOKEN-1].delete_a_card(pCard);
            pCard = _CardInfo[NMRSPM_TOKEN-1].add_a_new_card(NdbToken[NMRSPM_TOKEN-1], 0);
            pCard->AddElementToField(model, 2);
            pCard->AddElementToField(maker, 3);
            pCard->AddElementToField(strengh, 4);
       }

       pCard = _CardInfo[NMRSMP_TOKEN-1].Head();
       while (pCard) {
            if (strcmp(pCard->Field(7), "")) {
                 pCard->AttachToField(" ", 4);
                 pCard->AttachToField(pCard->Field(7), 4);
            }
            pCard = pCard->Next();
       }
       pCard = _CardInfo[NMRSMP_TOKEN-1].Head();
       if (pCard) {
            qCard = pCard->Next();
            if (qCard) {
                 for (i = 3; i < 7; i++) {
                      if (!strcmp(pCard->Field(i), ""))
                           pCard->AddElementToField("NULL", i);
                 }
            }
            while (qCard) {
                 for (i = 3; i < 7; i++) {
                      pCard->AttachToField("; ", i);
                      if (strcmp(qCard->Field(i), ""))
                           pCard->AttachToField(qCard->Field(i), i);
                      else pCard->AttachToField("NULL", i);
                 }
                 qCard = qCard->Next();
            }
       }

       int NMRSDT_TOKEN = find_card_id("NMRSDT");
       pCard = _CardInfo[NMRSDT_TOKEN].Head();
       if (pCard) {
            qCard = pCard->Next();
            if (qCard) {
                 if (!strcmp(pCard->Field(2), ""))
                      pCard->AddElementToField("NULL", 2);
            }
            while (qCard) {
                 pCard->AttachToField("; ", 2);
                 if (strcmp(qCard->Field(2), ""))
                      pCard->AttachToField(qCard->Field(2), 2);
                 else pCard->AttachToField("NULL", 2);
                 qCard = qCard->Next();
            }
       }
}

int _MAXIT::check_virus_ncs_remark_300()
{
       int n_ncs = 0, card_id, i;
       NCS_COR *ncs = NULL;

       card_id = find_card_id("NCSRMK");
       if (card_id < 0) return 0;

       One_Card_Info_Format *pCard = _CardInfo[card_id].Head();
       if (pCard == NULL) return 0;

       while (pCard) {
            for (i = 0; i < n_ncs; i++) {
                 if (ncs[i].oper_id == atoi(pCard->Field(2))) break;
            }
            if (i == n_ncs) {
                 n_ncs++;
                 ncs = (NCS_COR *) realloc(ncs, n_ncs * sizeof(NCS_COR));
                 ncs[i].oper_id = atoi(pCard->Field(2));
                 strcpy(ncs[i].chain[0], pCard->Field(4));
                 ncs[i].num_chain = 1;
            } else {
                 strcpy(ncs[i].chain[ncs[i].num_chain], pCard->Field(4));
                 ncs[i].num_chain++;
            }
            pCard = pCard->Next();
       }

       if (!n_ncs) return 0;

       ndb_to_pdb_get_general_remark(Num_Remark_300_VIRUS, Remark_300_VIRUS, 0, 0, 0, 0);

       if (ncs) free ((void *) ncs);
       return 1;
}

int _MAXIT::check_virus_ncs_remark_350()
{
       int n_ncs = 0, card_id, i, j, k, n, field_no, str_len;
       char FieldFormat[82], buffer[60];
       NCS_COR *ncs = NULL;
       One_Card_Info_Format *pCard = NULL, *newCard = NULL;

       card_id = find_card_id("NCSRMK");
       if (card_id < 0) return 0;

       pCard = _CardInfo[card_id].Head();
       if (pCard == NULL) return 0;

       while (pCard) {
            for (i = 0; i < n_ncs; i++) {
                 if (ncs[i].oper_id == atoi(pCard->Field(2))) break;
            }
            if (i == n_ncs) {
                 n_ncs++;
                 ncs = (NCS_COR *) realloc(ncs, n_ncs * sizeof(NCS_COR));
                 ncs[i].oper_id = atoi(pCard->Field(2));
                 strcpy(ncs[i].chain[0], pCard->Field(4));
                 ncs[i].num_chain = 1;
            } else {
                 strcpy(ncs[i].chain[ncs[i].num_chain], pCard->Field(4));
                 ncs[i].num_chain++;
            }
            pCard = pCard->Next();
       }

       if (!n_ncs) return 0;

       ndb_to_pdb_get_general_remark(Num_Remark_350, Remark_350, 0, 0, 0, 0);

       for (n = 0; n < n_ncs; n++) {
            if (!n) {
                 for (i = 0; i < 2; i++) {
                      newCard = _CardInfo[REMARK_TOKEN-1].
                                 add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(Remark_SYMMA_CHAIN[i].Remark_No, 1);
                      strcpy(buffer, "");
                      for (j = 0; j < Remark_SYMMA_CHAIN[i].NumField; j++) {
                           get_remark_field_format(FieldFormat,
                                    &Remark_SYMMA_CHAIN[i], j);
                           field_no = Remark_SYMMA_CHAIN[i].FieldList[j].FieldId-1;
                           str_len = strlen(buffer);
                           if (strcmp(Remark_SYMMA_CHAIN[i].FieldList[j].TokenName,
                                        "SYMMA") || field_no == 0) {
                                sprintf(&buffer[str_len], "%s",
                                    Remark_SYMMA_CHAIN[i].FieldList[j].Text);
                           } else {
                                for (k = 0; k < ncs[n].num_chain; k++) {
                                     str_len = strlen(buffer);
                                     if (k) sprintf(&buffer[str_len], ", %s",
                                                  ncs[n].chain[k]);
                                     else sprintf(&buffer[str_len], " %s",
                                                  ncs[n].chain[k]);
                                }
                           }
                      }
                      newCard->AddElementToField(buffer, 2);
                 }
            }
            double result[3][4];
            if (!get_matrix(result, ncs[n].oper_id)) continue;

            for (k = 0; k < 3; k++) {
                 newCard = _CardInfo[REMARK_TOKEN-1].
                          add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                 newCard->AddElementToField(Remark_SYMMA.Remark_No, 1);
                 for (j = 0; j < Remark_SYMMA.NumField; j++) {
                      print_space_between_remark_field(newCard, &Remark_SYMMA, j);
                      get_remark_field_format(FieldFormat, &Remark_SYMMA, j);
                      field_no = Remark_SYMMA.FieldList[j].FieldId-1;
                      if (!strcmp("BIOMT", Remark_SYMMA.FieldList[j].Text))
                           sprintf(buffer, "%s%d",
                               Remark_SYMMA.FieldList[j].Text, k + 1);
                      else if (field_no == 1)
                           sprintf(buffer, FieldFormat, (double) (n+1));
                      else if (j != Remark_SYMMA.NumField - 1)
                           sprintf(buffer, FieldFormat, result[k][j-2]);
                      else sprintf(buffer, FieldFormat, result[k][3]);
                      newCard->AttachToField(buffer, 2);
                 }
            }
       }

       if (ncs) free ((void *) ncs);
       return 1;
}

void _MAXIT::rms_deviation_of_bonds()
{
       int i, len, rowNo, auth_atom_id_1, auth_asym_id_1, auth_comp_id_1, auth_seq_id_1;
       int insert_id_1, auth_atom_id_2, auth_asym_id_2, auth_comp_id_2, auth_seq_id_2;
       int insert_id_2, bond_deviation, a_resnum, b_resnum, model_id, Mol_ID = 0;
       char buffer[80], a_atomtyp[5], b_atomtyp[5];
       CifString a_chnid, a_resnam, a_inscode, cifstring, b_chnid, b_resnam, b_inscode;
       float bond_length;
       ISTable *Table = NULL;
       One_Card_Info_Format *newCard = NULL;
       
       if (!_CifObj) return;
       Table = _CifObj->GetTablePtr(_StructureId, "ebi_validate_bond");
       if (is_empty_table(Table)) return;

       ndb_to_pdb_get_general_remark(Num_Remark_500_BOND, Remark_500_BOND, 0, 0, 0, 0);

       rowNo = Table->GetNumRows();
       model_id = Table->GetColumnIndex("model_id");
       auth_atom_id_1 = Table->GetColumnIndex("auth_atom_id_1");
       auth_asym_id_1 = Table->GetColumnIndex("auth_asym_id_1");
       auth_comp_id_1 = Table->GetColumnIndex("auth_comp_id_1");
       auth_seq_id_1 = Table->GetColumnIndex("auth_seq_id_1");
       insert_id_1 = Table->GetColumnIndex("insert_id_1");
       auth_atom_id_2 = Table->GetColumnIndex("auth_atom_id_2");
       auth_asym_id_2 = Table->GetColumnIndex("auth_asym_id_2");
       auth_comp_id_2 = Table->GetColumnIndex("auth_comp_id_2");
       auth_seq_id_2 = Table->GetColumnIndex("auth_seq_id_2");
       insert_id_2 = Table->GetColumnIndex("insert_id_2");
       bond_deviation = Table->GetColumnIndex("bond_deviation");
       for (i = 0; i < rowNo; i++) {
            get_value(a_chnid, Table, auth_asym_id_1, i);
            get_value(a_resnam, Table, auth_comp_id_1, i);
            get_value(cifstring, Table, auth_seq_id_1, i);
            a_resnum = atoi(cifstring.Text());
            get_value(a_inscode, Table, insert_id_1, i);
            get_value(cifstring, Table, auth_atom_id_1, i);
            print_atom_atomName_field("", 0, a_atomtyp, cifstring.Text(), a_resnam.Text(), 0);
            if (a_chnid == "") a_chnid.Copy(" ");
            if (a_inscode == "") a_inscode.Copy(" ");

            get_value(b_chnid, Table, auth_asym_id_2, i);
            get_value(b_resnam, Table, auth_comp_id_2, i);
            get_value(cifstring, Table, auth_seq_id_2, i);
            b_resnum = atoi(cifstring.Text());
            get_value(b_inscode, Table, insert_id_2, i);
            get_value(cifstring, Table, auth_atom_id_2, i);
            print_atom_atomName_field("", 0, b_atomtyp, cifstring.Text(), b_resnam.Text(), 0);
            if (b_chnid == "") b_chnid.Copy(" ");
            if (b_inscode == "") b_inscode.Copy(" ");

            get_value(cifstring, Table, bond_deviation, i);
            bond_length = atof(cifstring.Text());
            get_value(cifstring, Table, model_id, i);
            Mol_ID = atoi(cifstring.Text());

            if (_num_mol > 1)
                 sprintf(buffer, "%2d %3s %c%4d%c %4s   %3s %c%4d%c %4s", Mol_ID,
                   a_resnam.Text(), a_chnid.Text()[0], a_resnum, a_inscode.Text()[0], a_atomtyp,
                   b_resnam.Text(), b_chnid.Text()[0], b_resnum, b_inscode.Text()[0], b_atomtyp);
            else sprintf(buffer, "   %3s %c%4d%c %4s   %3s %c%4d%c %4s",
                   a_resnam.Text(), a_chnid.Text()[0], a_resnum, a_inscode.Text()[0], a_atomtyp,
                   b_resnam.Text(), b_chnid.Text()[0], b_resnum, b_inscode.Text()[0], b_atomtyp);
            len = strlen(buffer);
            sprintf(&buffer[len], "   %6.3f", bond_length);

            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(500, 1);
            newCard->AddElementToField(buffer, 2);
       }
}

void _MAXIT::rms_deviation_of_angles()
{
       int i, len, rowNo, auth_atom_id_1, auth_asym_id_2, auth_comp_id_2, auth_seq_id_2;
       int insert_id_2, auth_atom_id_2, auth_atom_id_3, resnum_2, model_id, Mol_ID = 0;
       int angle_deviation;
       char atomtyp_1[5], atomtyp_2[5], atomtyp_3[5], buffer[80];
       CifString cifstring, chnid_2, resnam_2, inscode_2;
       float angle_value;
       ISTable *Table = NULL;
       One_Card_Info_Format *newCard = NULL;
       
       if (!_CifObj) return;
       Table = _CifObj->GetTablePtr(_StructureId, "ebi_validate_angle");
       if (is_empty_table(Table)) return;

       ndb_to_pdb_get_general_remark(Num_Remark_500_ANGLE, Remark_500_ANGLE, 0, 0, 0, 0);

       rowNo = Table->GetNumRows();
       model_id = Table->GetColumnIndex("model_id");
       auth_atom_id_1 = Table->GetColumnIndex("auth_atom_id_1");
       auth_asym_id_2 = Table->GetColumnIndex("auth_asym_id_2");
       auth_comp_id_2 = Table->GetColumnIndex("auth_comp_id_2");
       auth_seq_id_2 = Table->GetColumnIndex("auth_seq_id_2");
       insert_id_2 = Table->GetColumnIndex("insert_id_2");
       auth_atom_id_2 = Table->GetColumnIndex("auth_atom_id_2");
       auth_atom_id_3 = Table->GetColumnIndex("auth_atom_id_3");
       angle_deviation = Table->GetColumnIndex("angle_deviation");
       for (i = 0; i < rowNo; i++) {
            get_value(chnid_2, Table, auth_asym_id_2, i);
            get_value(resnam_2, Table, auth_comp_id_2, i);
            get_value(cifstring, Table, auth_seq_id_2, i);
            resnum_2 = atoi(cifstring.Text());
            get_value(inscode_2, Table, insert_id_2, i);
            get_value(cifstring, Table, auth_atom_id_1, i);
            print_atom_atomName_field("", 0, atomtyp_1, cifstring.Text(), resnam_2.Text(), 0);
            get_value(cifstring, Table, auth_atom_id_2, i);
            print_atom_atomName_field("", 0, atomtyp_2, cifstring.Text(), resnam_2.Text(), 0);
            get_value(cifstring, Table, auth_atom_id_3, i);
            print_atom_atomName_field("", 0, atomtyp_3, cifstring.Text(), resnam_2.Text(), 0);
            get_value(cifstring, Table, angle_deviation, i);
            angle_value = atof(cifstring.Text());
            get_value(cifstring, Table, model_id, i);
            Mol_ID = atoi(cifstring.Text());

            if (chnid_2 == "") chnid_2.Copy(" ");
            if (inscode_2 == "") inscode_2.Copy(" ");

            if (_num_mol > 1)
                 sprintf(buffer, "%2d %3s %c%4d%c", Mol_ID, resnam_2.Text(), chnid_2.Text()[0],
                      resnum_2, inscode_2.Text()[0]);
            else sprintf(buffer, "   %3s %c%4d%c", resnam_2.Text(), chnid_2.Text()[0],
                      resnum_2, inscode_2.Text()[0]);
            len = strlen(buffer);
            sprintf(&buffer[len], " %4s - %4s - %4s ANGL. DEV. =%5.1f DEGREES",
                      atomtyp_1, atomtyp_2, atomtyp_3, angle_value); 
            
            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(500, 1);
            newCard->AddElementToField(buffer, 2);
       }
}

void _MAXIT::outside_torsions()
{
       int i, rowNo, model_id, auth_comp_id, auth_asym_id, auth_seq_id, insert_id;
       int phi_index, psi_index, Mol_ID, resnum;
       char buffer[80];
       CifString cifstring, resnam, chnid, inscode;
       float phi, psi;
       ISTable *Table = NULL;
       One_Card_Info_Format *newCard = NULL;

       if (!_CifObj) return;
       Table = _CifObj->GetTablePtr(_StructureId, "ebi_validate_torsion");
       if (is_empty_table(Table)) return;

       ndb_to_pdb_get_general_remark(Num_Remark_500_TORSION, Remark_500_TORSION, 0, 0, 0, 0);

       rowNo = Table->GetNumRows();
       model_id = Table->GetColumnIndex("model_id");
       auth_comp_id = Table->GetColumnIndex("auth_comp_id");
       auth_asym_id = Table->GetColumnIndex("auth_asym_id");
       auth_seq_id = Table->GetColumnIndex("auth_seq_id");
       insert_id = Table->GetColumnIndex("insert_id");
       phi_index = Table->GetColumnIndex("phi");
       psi_index = Table->GetColumnIndex("psi");
       for (i = 0; i < rowNo; i++) {
            get_value(cifstring, Table, model_id, i);
            Mol_ID = atoi(cifstring.Text());
            get_value(resnam, Table, auth_comp_id, i);
            get_value(chnid, Table, auth_asym_id, i);
            get_value(cifstring, Table, auth_seq_id, i);
            resnum = atoi(cifstring.Text());
            get_value(inscode, Table, insert_id, i);
            get_value(cifstring, Table, phi_index, i);
            phi = atof(cifstring.Text());
            get_value(cifstring, Table, psi_index, i);
            psi = atof(cifstring.Text());
 
            if (chnid == "") chnid.Copy(" ");
            if (inscode == "") inscode.Copy(" ");

            if (_num_mol > 1)
                 sprintf(buffer, "%2d %3s %c%4d%c    %7.2f   %7.2f", Mol_ID,
                     resnam.Text(), chnid.Text()[0], resnum, inscode.Text()[0], psi, phi);
            else sprintf(buffer, "   %3s %c%4d%c    %7.2f   %7.2f",
                     resnam.Text(), chnid.Text()[0], resnum, inscode.Text()[0], psi, phi);

            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(500, 1);
            newCard->AddElementToField(buffer, 2);
       }
}

void _MAXIT::non_cis_trans_torsions()
{
       int i, rowNo, model_id, auth_asym_id_1, auth_comp_id_1, auth_seq_id_1;
       int insert_id_1, auth_asym_id_2, auth_comp_id_2, auth_seq_id_2, insert_id_2;
       int omega_index, a_resnum, b_resnum, Mol_ID;
       char buffer[80];
       CifString a_chnid, a_resnam, a_inscode, b_chnid, b_resnam, b_inscode, cifstring;
       float omega;
       ISTable *Table = NULL;
       One_Card_Info_Format *newCard = NULL;

       if (!_CifObj) return;
       Table = _CifObj->GetTablePtr(_StructureId, "ebi_validate_peptide_omega");
       if (is_empty_table(Table)) return;

       ndb_to_pdb_get_general_remark(Num_Remark_500_NON_CIS, Remark_500_NON_CIS, 0, 0, 0, 0);

       rowNo = Table->GetNumRows();
       model_id = Table->GetColumnIndex("model_id");
       auth_asym_id_1 = Table->GetColumnIndex("auth_asym_id_1");
       auth_comp_id_1 = Table->GetColumnIndex("auth_comp_id_1");
       auth_seq_id_1 = Table->GetColumnIndex("auth_seq_id_1");
       insert_id_1 = Table->GetColumnIndex("insert_id_1");
       auth_asym_id_2 = Table->GetColumnIndex("auth_asym_id_2");
       auth_comp_id_2 = Table->GetColumnIndex("auth_comp_id_2");
       auth_seq_id_2 = Table->GetColumnIndex("auth_seq_id_2");
       insert_id_2 = Table->GetColumnIndex("insert_id_2");
       omega_index = Table->GetColumnIndex("omega");

       for (i = 0; i < rowNo; i++) {
            get_value(a_chnid, Table, auth_asym_id_1, i);
            get_value(a_resnam, Table, auth_comp_id_1, i);
            get_value(cifstring, Table, auth_seq_id_1, i);
            a_resnum = atoi(cifstring.Text());
            get_value(a_inscode, Table, insert_id_1, i);
            if (a_chnid == "") a_chnid.Copy(" ");
            if (a_inscode == "") a_inscode.Copy(" ");

            get_value(b_chnid, Table, auth_asym_id_2, i);
            get_value(b_resnam, Table, auth_comp_id_2, i);
            get_value(cifstring, Table, auth_seq_id_2, i);
            b_resnum = atoi(cifstring.Text());
            get_value(b_inscode, Table, insert_id_2, i);
            if (b_chnid == "") b_chnid.Copy(" ");
            if (b_inscode == "") b_inscode.Copy(" ");

            get_value(cifstring, Table, omega_index, i);
            omega = atof(cifstring.Text());
            get_value(cifstring, Table, model_id, i);
            Mol_ID = atoi(cifstring.Text());

            if (_num_mol > 1)
                 sprintf(buffer, "%3s %c %4d%c   %3s %c %4d%c       %3d      %7.2f",
                  a_resnam.Text(), a_chnid.Text()[0], a_resnum, a_inscode.Text()[0],
                  b_resnam.Text(), b_chnid.Text()[0], b_resnum, b_inscode.Text()[0],
                  Mol_ID, omega);
            else sprintf(buffer, "%3s %c %4d%c   %3s %c %4d%c                %7.2f",
                  a_resnam.Text(), a_chnid.Text()[0], a_resnum, a_inscode.Text()[0],
                  b_resnam.Text(), b_chnid.Text()[0], b_resnum, b_inscode.Text()[0], omega);

            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(500, 1);
            newCard->AddElementToField(buffer, 2);
       }
}

void _MAXIT::output_close_contact(ISTable *Table, BTreeObj<_DIndex>& _Index, const int sym)
{
       int i = 0, j, ret = 1, auth_atom_id_1, auth_asym_id_1, auth_comp_id_1, auth_seq_id_1;
       int insert_id_1, auth_atom_id_2, auth_asym_id_2, auth_comp_id_2, auth_seq_id_2;
       int insert_id_2, symmetry_op_2, dist_index, a_resnum, b_resnum, num = 0, len = 0;
       char buffer[80], atomName[10];
       CifString a_atomtyp, a_chnid, a_resnam, a_inscode, cifstring;
       CifString b_atomtyp, b_chnid, b_resnam, b_inscode, symmetry;
       float dist;
       _ATOM **atom_a = NULL, **atom_b = NULL;
       _DIndex _idx;
       One_Card_Info_Format *newCard = NULL;

       auth_atom_id_1 = Table->GetColumnIndex("auth_atom_id_1");
       auth_asym_id_1 = Table->GetColumnIndex("auth_asym_id_1");
       auth_comp_id_1 = Table->GetColumnIndex("auth_comp_id_1");
       auth_seq_id_1 = Table->GetColumnIndex("auth_seq_id_1");
       insert_id_1 = Table->GetColumnIndex("insert_id_1");
       auth_atom_id_2 = Table->GetColumnIndex("auth_atom_id_2");
       auth_asym_id_2 = Table->GetColumnIndex("auth_asym_id_2");
       auth_comp_id_2 = Table->GetColumnIndex("auth_comp_id_2");
       auth_seq_id_2 = Table->GetColumnIndex("auth_seq_id_2");
       insert_id_2 = Table->GetColumnIndex("insert_id_2");
       symmetry_op_2 = Table->GetColumnIndex("symmetry_op_2");
       dist_index = Table->GetColumnIndex("dist");

       _Index.GoFirst();
       while (ret >= 0) {
            _idx = _Index.GetCurrData();
            i = _idx.pos();

            get_value(a_atomtyp, Table, auth_atom_id_1, i);
            get_value(a_chnid, Table, auth_asym_id_1, i);
            get_value(a_resnam, Table, auth_comp_id_1, i);
            get_value(cifstring, Table, auth_seq_id_1, i);
            a_resnum = atoi(cifstring.Text());
            get_value(a_inscode, Table, insert_id_1, i);
            get_value(b_atomtyp, Table, auth_atom_id_2, i);
            get_value(b_chnid, Table, auth_asym_id_2, i);
            get_value(b_resnam, Table, auth_comp_id_2, i);
            get_value(cifstring, Table, auth_seq_id_2, i);
            b_resnum = atoi(cifstring.Text());
            get_value(b_inscode, Table, insert_id_2, i);
            get_value(symmetry, Table, symmetry_op_2, i);
            get_value(cifstring, Table, dist_index, i);
            dist = atof(cifstring.Text());

            if (sym && symmetry == "1_555" ||
               !sym && symmetry != "1_555") {
                 ret = _Index.GoToNext();
                 continue;
            }
            strcpy(buffer, symmetry.Text());
            symmetry.Clear();
            len = strlen(buffer); 
            for (j = 0; j < len; j++) {
                 if (buffer[j] == '_') continue;
                 symmetry += buffer[j];
            }

            atom_a = _molecules[0]->find_pdb_atom(a_atomtyp.Text(), a_chnid.Text(),
                       a_resnam.Text(), a_resnum, a_inscode.Text(), num);
            atom_b = _molecules[0]->find_pdb_atom(b_atomtyp.Text(), b_chnid.Text(),
                       b_resnam.Text(), b_resnum, b_inscode.Text(), num);
            if (!atom_a || !atom_b) {
                 if (atom_a) delete [] atom_a;
                 if (atom_b) delete [] atom_b;
                 ret = _Index.GoToNext();
                 continue;
            }

            print_atom_atomName_field(atom_a[0]->atom_type(), 0, atomName,
                atom_a[0]->pdb_atmnam(), atom_a[0]->pdb_resnam(), atom_a[0]->align());
            sprintf(buffer, " %-4s  %-3s", atomName, atom_a[0]->pdb_resnam());
            len = strlen(buffer);
            strcpy(atomName, " ");
            if (strcmp(atom_a[0]->pdb_chnid(), ""))
                 strcpy(atomName, atom_a[0]->pdb_chnid());
            sprintf(&buffer[len], " %c  %4d", atomName[0], 
                          atom_a[0]->pdb_resnum());
            len = strlen(buffer);
            strcpy(atomName, " ");
            if (strcmp(atom_a[0]->ins_code(), ""))
                 strcpy(atomName, atom_a[0]->ins_code());
            sprintf(&buffer[len], "%c  ", atomName[0]);

            print_atom_atomName_field(atom_b[0]->atom_type(), 0, atomName,
                atom_b[0]->pdb_atmnam(), atom_b[0]->pdb_resnam(), atom_b[0]->align());
            len = strlen(buffer);
            sprintf(&buffer[len], " %-4s  %-3s", atomName,
                             atom_b[0]->pdb_resnam());
            len = strlen(buffer);
            strcpy(atomName, " ");
            if (strcmp(atom_b[0]->pdb_chnid(), ""))
                 strcpy(atomName, atom_b[0]->pdb_chnid());
            sprintf(&buffer[len], " %c  %4d", atomName[0],
                        atom_b[0]->pdb_resnum());
            len = strlen(buffer);
            strcpy(atomName, " ");
            if (strcmp(atom_b[0]->ins_code(), ""))
                 strcpy(atomName, atom_b[0]->ins_code());
            sprintf(&buffer[len], "%c", atomName[0]);

            if (atom_a) delete [] atom_a;
            if (atom_b) delete [] atom_b;

            len = strlen(buffer);
            if (!sym) sprintf(&buffer[len], "            %5.2f", dist);
            else sprintf(&buffer[len], "   %5s    %5.2f", symmetry.Text(), dist);

            newCard = _CardInfo[REMARK_TOKEN-1].
                       add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(500, 1);
            newCard->AddElementToField(buffer, 2);

            ret = _Index.GoToNext();
       }
}

void _MAXIT::get_cispep_cards()
{
       if (_n_torsion == 0 || _torsion == NULL) return;
       if (_torsionIndex.Root() < 0) return;

       int CISPEP_TOKEN = find_card_id("CISPEP");
       if (CISPEP_TOKEN == -1) return;
       _CardInfo[CISPEP_TOKEN].clear_Cards();
       
       _RESIDUE *residue = NULL;
       One_Card_Info_Format *pCard = NULL;
       _ATOM *atom = NULL;

       CifString index("OMEGA");
       int serial_no = 0;
       int ret = _torsionIndex.Seek(index);
       while (ret >= 0) {
            if (index != _torsionIndex.GetCurrData()) break;
            if (fabs(_torsion[ret]->val) > 30.0) {
                 ret = _torsionIndex.GoToNext();
                 continue;
            }

            residue = _molecules[0]->find_prev_residue(_torsion[ret]->ChainID,
                   _torsion[ret]->ResName, _torsion[ret]->ResNum,
                   _torsion[ret]->ins_code);
            if (!residue) {
                 ret = _torsionIndex.GoToNext();
                 continue;
            }

            serial_no++;
            pCard = _CardInfo[CISPEP_TOKEN].
                   add_a_new_card(NdbToken[CISPEP_TOKEN], 0);
            atom = residue->GetFirstAtom();
            pCard->AddElementToField(serial_no, 1);
            pCard->AddElementToField(residue->ResName(), 2);
            pCard->AddElementToField(_torsion[ret]->ChainID, 3);
            pCard->AddElementToField(atom->pdb_resnum(), 4);
            pCard->AddElementToField(atom->ins_code(), 5);
            pCard->AddElementToField(_torsion[ret]->ResName, 6);
            pCard->AddElementToField(_torsion[ret]->ChainID, 7);
            pCard->AddElementToField(_torsion[ret]->ResNum, 8);
            pCard->AddElementToField(_torsion[ret]->ins_code, 9);
            if (_num_mol > 1)
                 pCard->AddElementToField(_torsion[ret]->Mol_ID, 10);
            else pCard->AddElementToField(0, 10);
            pCard->AddElementToField(_torsion[ret]->val, 11);

            ret = _torsionIndex.GoToNext();
       }
}

void _MAXIT::construct_remark_900()
{
       int max_length = 60;
       char buffer[62], *p;
       One_Card_Info_Format *pCard = _CardInfo[RENTRY_TOKEN-1].Head();

       One_Card_Info_Format *newCard = _CardInfo[REMARK_TOKEN-1].
                  add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
       newCard->AddElementToField(900, 1);
       newCard = _CardInfo[REMARK_TOKEN-1].add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
       newCard->AddElementToField(900, 1);
       newCard->AddElementToField("RELATED ENTRIES", 2);
       while (pCard) {
            newCard = _CardInfo[REMARK_TOKEN-1].
                    add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
            newCard->AddElementToField(900, 1);
            sprintf(buffer, "RELATED ID: %s   RELATED DB: %s",
                     pCard->Field(3), pCard->Field(2));
            newCard->AddElementToField(buffer, 2);
            if (strcmp(pCard->Field(4), "")) {
                 pCard->CleanStringField(4);
                 p = get_max_length_word(pCard->Field(4), buffer, max_length);
                 newCard = _CardInfo[REMARK_TOKEN-1].
                         add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                 newCard->AddElementToField(900, 1);
                 newCard->AddElementToField(buffer, 2);
                 while (p) {
                      p = get_max_length_word(p, buffer, max_length);
                      newCard = _CardInfo[REMARK_TOKEN-1].
                              add_a_new_card(NdbToken[REMARK_TOKEN-1], 0);
                      newCard->AddElementToField(900, 1);
                      newCard->AddElementToField(buffer, 2);
                 }
            }
            pCard = pCard->Next();
       }
}

void _MAXIT::check_atom_number_count()
{
       if (_num_mol == 0) return;

       int card_id = find_card_id("ATNUMS");
       One_Card_Info_Format *pCard = _CardInfo[card_id].Head();
       if (pCard == NULL) {
            pCard = _CardInfo[card_id].add_a_new_card(NdbToken[card_id], 0);
            int atom_no = _molecules[0]->count_atom_no(ATOMP_TOKEN);
            pCard->AddElementToField(atom_no, 2);

            atom_no = _molecules[0]->count_atom_no(ATOMN_TOKEN);
            pCard->AddElementToField(atom_no, 3);

            atom_no = 0;
            atom_no += _molecules[0]->count_atom_no(HETAD_TOKEN);
            atom_no += _molecules[0]->count_atom_no(ATOMMN_TOKEN);
            atom_no += _molecules[0]->count_atom_no(ATOMMP_TOKEN);
            atom_no += _molecules[0]->count_atom_no(HETAC_TOKEN);
            atom_no += _molecules[0]->count_atom_no(HETAI_TOKEN);
            atom_no += _molecules[0]->count_atom_no(HETIC_TOKEN);
            atom_no += _molecules[0]->count_atom_no(HETAIN_TOKEN);
            atom_no += _molecules[0]->count_atom_no(ATOMS_TOKEN);
            pCard->AddElementToField(atom_no, 4);

            atom_no = _molecules[0]->count_atom_no(HETAS_TOKEN);
            pCard->AddElementToField(atom_no, 5);
       }
       if (!strcmp(pCard->Field(1), ""))
            pCard->AddElementToField("LAST", 1);
       if (!strcmp(pCard->Field(6), "")) {
            int atom_no = atoi(pCard->Field(2)) + atoi(pCard->Field(3))
                        + atoi(pCard->Field(4)) + atoi(pCard->Field(5));
            pCard->AddElementToField(atom_no, 6);
       }
}

void separation_string_base_word(char *old_string, char *str1,
               char *str2, const char *word)
{
       str1[0] = '\0';
       str2[0] = '\0';

       if (old_string == NULL) return;

       char *p = strstr(old_string, word);
       if (!p) strcpy(str1, old_string);

       if (!strcmp(old_string, "") || p == NULL) return;

       char *q = old_string;
       while (q < p) {
            *str1 = *q;
            str1++; q++;
       }
       *str1 = '\0';

       p += strlen(word);

       strcpy(str2, p);

       ndb_clean_string(str1);
       ndb_clean_string(str2);
}

static void print_null_remark_value(One_Card_Info_Format *newCard,
         const int fieldLength, const int fieldJustification)
{
       char fieldFormat[82], buffer[82];
       if (fieldJustification == PDB_REMARK_LEFT_JUSTIFIED)
            sprintf(fieldFormat, "%%-%ds", fieldLength);
       else sprintf(fieldFormat, "%%%ds", fieldLength);
       sprintf(buffer, fieldFormat, "NULL");
       newCard->AttachToField(buffer, 2);
}

static void print_space_between_remark_field(One_Card_Info_Format *newCard,
             REMARKS *Remark, const int field_no)
{
       char FieldFormat[82], buffer[82];
       if (field_no == 0) 
            sprintf(FieldFormat, "%%-%ds",
               Remark->FieldList[field_no].FieldStCol - 1);
       else sprintf(FieldFormat, "%%-%ds",
               Remark->FieldList[field_no].FieldStCol -
              (Remark->FieldList[field_no-1].FieldStCol +
               Remark->FieldList[field_no-1].FieldWidth));
       sprintf(buffer, FieldFormat, "");
       newCard->AttachToField(buffer, 2);
}

static void get_remark_field_format(char *FieldFormat, REMARKS *Remark,
             const int field_no)
{
       if (Remark->FieldList[field_no].FieldType >=3) {
            if (Remark->FieldList[field_no].FieldJustification == 
                  PDB_REMARK_LEFT_JUSTIFIED) 
                 sprintf(FieldFormat, "%%-%ds",
                     Remark->FieldList[field_no].FieldWidth);
            else sprintf(FieldFormat, "%%%ds",
                     Remark->FieldList[field_no].FieldWidth);
       } else {
            if (Remark->FieldList[field_no].FieldJustification == 
                  PDB_REMARK_LEFT_JUSTIFIED)
                 sprintf(FieldFormat, "%%-%d.%dlf", 
                     Remark->FieldList[field_no].FieldWidth,
                     Remark->FieldList[field_no].FieldPrec);
            else sprintf(FieldFormat, "%%%d.%dlf", 
                     Remark->FieldList[field_no].FieldWidth,
                     Remark->FieldList[field_no].FieldPrec);
       }
}

static void clean_descriptor(char *string, char *ec)
{
       ec[0] = '\0';
       char *q = ec;
       char *p = strstr(string, "PROTEIN (");
       if (p) strcpy(string, &string[9]);

       for (int i = strlen(string) - 1; i >= 0; i--) {
            if (string[i] == ')') { string[i] = '\0'; break; }
            else if (string[i] != ' ' && string[i] != '\0') break;
       }
       if ((p = strstr(string, "E.C."))) {
            if (*(p-1) == '(' && isdigit(*(p+4))) {
                *(p-1) = ' ';
                while (p) {
                     if (*p == ')') { *p = ' '; break; }
                     if (*p == '\0') break;
                     *q = *p; *p = ' ';
                     q++; p++;
                }
            }
            *q = '\0';
            strcpy(ec, &ec[4]);
       }
       ndb_clean_string(string);
}

static void delete_space_between_string(char *string)
{
       int str_len = strlen(string);
       for (int i = str_len - 1; i > 0; i--) {
            if (string[i] == ' ' &&
                string[i-1] == ',')
                 strcpy(&string[i], &string[i+1]);
       }
}

static float cal_min_distance(_MOLECULE *mol, _ATOM *atom)
{
       float min_distance = 100.0;
       double dist = 0;

       _RESIDUE *Residue = NULL;
       _ATOM *atom1 = NULL;
       _CHAIN *chain = mol->GetFirstChain();
       while (chain) {
            if (chain->chain_type() == HETAS_TOKEN ||
                chain->op() != 1) {
                 chain = mol->GetNextChain();
                 continue;
            }
            Residue = chain->GetFirstResidue();
            while (Residue) {
                 atom1 = Residue->GetFirstAtom();
                 while (atom1) {
                      dist = cal_dist(atom, atom1);
                      if (dist < min_distance) min_distance = dist;
                      atom1 = Residue->GetNextAtom();
                 }
                 Residue = chain->GetNextResidue();
            }
            chain = mol->GetNextChain();
       }
       return (min_distance);
}

static float cal_dist(_ATOM *atom_a, _ATOM *atom_b)
{
       float min_distance = 100.0;
       if (!atom_a || !atom_b || strcmp(atom_a->alt_loc(), "") &&
           strcmp(atom_b->alt_loc(), "") &&
           strcmp(atom_a->alt_loc(), atom_b->alt_loc()))
            return min_distance;

       if (!strcmp(atom_b->atom_type(), "N") ||
           !strcmp(atom_b->atom_type(), "O")) {
            float dist = (atom_a->orig().x - atom_b->orig().x) 
                        * (atom_a->orig().x - atom_b->orig().x)
                        + (atom_a->orig().y - atom_b->orig().y)
                        * (atom_a->orig().y - atom_b->orig().y)
                        + (atom_a->orig().z - atom_b->orig().z)
                        * (atom_a->orig().z - atom_b->orig().z);
            dist = sqrt(dist);
            if (dist > 5.0) {
                 if (dist < min_distance) min_distance = dist;
            }
       }
       return min_distance;
}

static int check_align(const int Remark_No, REMARK_FIELD *FieldList)
{
       int align = 1;
       if (!strcmp(FieldList->TokenName, "XFILE1") && FieldList->FieldId == 3 &&
                   Remark_No != 210 ||
           !strcmp(FieldList->TokenName, "DTMEA1") && FieldList->FieldId == 2 ||
           !strcmp(FieldList->TokenName, "XFILE2") && FieldList->FieldId == 2 ||
           !strcmp(FieldList->TokenName, "CRMET1") && FieldList->FieldId == 3 ||
           !strcmp(FieldList->TokenName, "REFREM") && FieldList->FieldId == 3 ||
           !strcmp(FieldList->TokenName, "CRDTLS") && FieldList->FieldId == 3 ||
           !strcmp(FieldList->TokenName, "CEMFIT") && FieldList->FieldId == 7 ||
           !strcmp(FieldList->TokenName, "CMRNST") && FieldList->FieldId == 7 ||
           !strcmp(FieldList->TokenName, "CMRNST") && FieldList->FieldId == 8 ||
           !strcmp(FieldList->TokenName, "EMSAMP") && FieldList->FieldId == 9 ||
           !strcmp(FieldList->TokenName, "EMDATA") && FieldList->FieldId == 19 ||
           !strcmp(FieldList->TokenName, "ASSEMB") && FieldList->FieldId == 7 ||
           !strcmp(FieldList->TokenName, "SOLMDL") && (FieldList->FieldId == 6 ||
                   FieldList->FieldId == 9))
            align = 0;
       return align;
}

static int biol_id_compare(const void *biol1, const void *biol2)
{
       return (atoi(((_BIOL_ID *) biol1)->biol_id) -
               atoi(((_BIOL_ID *) biol2)->biol_id));
}
