// $Id: mmdb_rwbrook.cpp $ // ================================================================= // // CCP4 Coordinate Library: support of coordinate-related // functionality in protein crystallography applications. // // Copyright (C) Eugene Krissinel 2000-2008. // // This library is free software: you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License version 3, modified in accordance with the provisions // of the license to address the requirements of UK law. // // You should have received a copy of the modified GNU Lesser // General Public License along with this library. If not, copies // may be downloaded from http://www.ccp4.ac.uk/ccp4license.php // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // ================================================================= // // 16.09.13 <-- Date of Last Modification. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ----------------------------------------------------------------- // // **** Module : MMDB_RWBrook // ~~~~~~~~~ // **** Project : MacroMolecular Data Base (MMDB), "new rwbrook" // ~~~~~~~~~ // **** Functions : mmdb_f_init_ ( initializer ) // ~~~~~~~~~~~ mmdb_f_quit_ ( disposer ) // autoserials_ ( switch to the autoserials regime ) // setreadcoords_ ( switch for reading coordinates ) // simrwbrook_ ( simulates old RWBROOK printout ) // mmdb_f_openl_ ( associates a unit with a file ) // mmdb_f_open_ ( associates a unit with a file ) // mmdb_f_copy_ ( copies contents of units ) // mmdb_f_delete_ ( deletes part of a unit ) // mmdb_f_settype_ ( changes type of file and r/w mode ) // mmdb_f_setname_ ( changes file name ) // mmdb_f_write_ ( writes a data structure into file ) // mmdb_f_close_ ( closes and disposes a data str-re ) // mmdb_f_advance_ ( advances the internal pointer ) // mmdb_f_rewd_ ( sets internal pointer on the top ) // mmdb_f_bksp_ ( shifts int-l pointer 1 atom back ) // mmdb_f_atom_ ( reads/writes atom properties ) // mmdb_f_coord_ ( reads/writes atom coordinates ) // mmdb_f_setcell_ ( sets the crystal cell parameters ) // mmdb_f_wbspgrp_ ( sets the space group ) // mmdb_f_rbspgrp_ ( gets the space group ) // mmdb_f_wbcell_ ( sets the crystal cell parameters ) // mmdb_f_rbcell_ ( gets the crystal cell parameters ) // mmdb_f_rbcelln_ ( gets the crystal cell parameters ) // mmdb_f_rbrcel_ ( gets the recipricol cell ) // mmdb_f_rborf_ ( returns or fill transf. matrices ) // mmdb_f_orthmat_ ( calc. standard othogonalisations ) // mmdb_f_cvanisou_ ( converts between cryst-c units ) // mmdb_f_wremark_ ( writes a remark statement ) // mmdb_f_setter // mmdb_f_sethet // mmdb_f_getnofncsmates_ // rberrstop_ ( error messenger ) // rbcheckerr_ ( a simple error messenger ) // // (C) E. Krissinel 2000-2013 // // ================================================================= // #include "string.h" #include "stdlib.h" #include "math.h" #include "mmdb_rwbrook.h" #include "mmdb_manager.h" #include "mmdb_tables.h" #include "hybrid_36.h" // ========================== Channel =========================== DefineClass(Channel) class Channel { public : int nUnit; // unit number int nType; // unit type: 0- PDB; 1- CIF; 2- binary int nRead; // 0: input, 1: output mmdb::PManager MMDBManager; // MMDB manager mmdb::pstr FName; // file name int fPos; // "position" in the file int ErrCode; // error code of last operation bool FAutoSer; // autoserials flag for reading PDB bool FReadCoords; // flag to read coordinate section bool FSimRWBROOK; // flag to simulate old RWBROOK's printout Channel (); ~Channel(); void Dispose(); void Init (); void SetFileType ( mmdb::pstr FType ); void SetFileName ( mmdb::pstr FileName, int FNameLen ); void IdentifyFile( mmdb::pstr ExistingFName ); bool EndOfFile (); mmdb::PAtom * GetAtomArray(); mmdb::PAtom GetAtomI ( int index ); mmdb::PCryst GetCryst (); bool areCrystMatrices(); void Frac2Orth ( mmdb::realtype x, mmdb::realtype y, mmdb::realtype z, mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz ); void Orth2Frac ( mmdb::realtype x, mmdb::realtype y, mmdb::realtype z, mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz ); void Cryst2Orth ( mmdb::rvector U ); void Orth2Cryst ( mmdb::rvector U ); int SetCell ( mmdb::realtype cell_a, mmdb::realtype cell_b, mmdb::realtype cell_c, mmdb::realtype cell_alpha, mmdb::realtype cell_beta, mmdb::realtype cell_gamma, int OrthCode ); int PutCell ( mmdb::realtype cell_a, mmdb::realtype cell_b, mmdb::realtype cell_c, mmdb::realtype cell_alpha, mmdb::realtype cell_beta, mmdb::realtype cell_gamma, int OrthCode ); int SetSpGroup ( mmdb::pstr spGroup ); int GetSpGroup ( mmdb::pstr spGroup ); int GetCell ( mmdb::realtype & cell_a, mmdb::realtype & cell_b, mmdb::realtype & cell_c, mmdb::realtype & cell_alpha, mmdb::realtype & cell_beta, mmdb::realtype & cell_gamma, mmdb::realtype & cell_v, int & OrthCode ); int GetRCell ( mmdb::realtype & cell_as, mmdb::realtype & cell_bs, mmdb::realtype & cell_cs, mmdb::realtype & cell_alphas, mmdb::realtype & cell_betas, mmdb::realtype & cell_gammas, mmdb::realtype & cell_vs ); int GetNumberOfNCSMates(); // Returns the number of // NCS mates not given in // the file (iGiven==0) void MakeCoordStructure(); void Read (); void Write(); void GetInputBuffer ( mmdb::pstr Line, int & count ); protected : void TranslateError(); }; Channel::Channel() { Init(); } Channel::~Channel() { Dispose(); } void Channel::Init() { nUnit = -1; nType = -1; nRead = 0; MMDBManager = NULL; FName = NULL; ErrCode = 0; fPos = 0; FAutoSer = false; FReadCoords = true; FSimRWBROOK = false; } void Channel::Dispose() { if (MMDBManager) delete MMDBManager; if (FName) delete[] FName; MMDBManager = NULL; FName = NULL; nUnit = -1; nType = -1; nRead = 0; ErrCode = 0; fPos = 0; } void Channel::SetFileType ( mmdb::pstr FType ) { switch (FType[0]) { default : case ' ' : if (nRead==0) nType = -1; // auto at reading else if (MMDBManager) nType = MMDBManager->GetFileType(); // auto at writing else nType = -1; break; case 'P' : nType = 0; break; // PDB case 'C' : nType = 1; break; // CIF case 'B' : nType = 2; break; // BIN } } void Channel::IdentifyFile ( mmdb::pstr ExistingFName ) { if (nType==-1) { if (ExistingFName) { if (mmdb::isMMDBBIN(ExistingFName)==0) nType = 2; else if (mmdb::isPDB(ExistingFName,mmdb::io::GZM_CHECK,true)==0) nType = 0; else if (mmdb::mmcif::isCIF(ExistingFName)==0) nType = 1; else nType = -2; // unidentified } else { if (MMDBManager) { if (MMDBManager->GetFileType()<0) nType = 0; // PDB else nType = MMDBManager->GetFileType(); // same as it was on last input } else nType = 0; } } } void Channel::SetFileName ( mmdb::pstr FileName, int FNameLen ) { if (FName) delete[] FName; FName = new char[FNameLen+1]; strncpy ( FName,FileName,FNameLen ); FName[FNameLen] = char(0); } void Channel::MakeCoordStructure() { if (MMDBManager) MMDBManager->Delete ( mmdb::MMDBFCM_All ); else { MMDBManager = new mmdb::Manager(); MMDBManager->SetFlag ( mmdb::MMDBF_AllowDuplChainID ); } } int Channel::GetNumberOfNCSMates() { // Returns the number of NCS mates not given in the file (iGiven==0) if (!MMDBManager) return RWBERR_NoData; return MMDBManager->GetNumberOfNCSMates(); } void Channel::Read() { int RC; ErrCode = -2; if (!FName) return; MakeCoordStructure(); IdentifyFile ( FName ); if (FAutoSer) MMDBManager->SetFlag ( mmdb::MMDBF_AutoSerials ); else MMDBManager->RemoveFlag ( mmdb::MMDBF_AutoSerials ); if (FReadCoords) MMDBManager->RemoveFlag ( mmdb::MMDBF_NoCoordRead ); else MMDBManager->SetFlag ( mmdb::MMDBF_NoCoordRead ); if (FSimRWBROOK) MMDBManager->SetFlag ( mmdb::MMDBF_SimRWBROOK ); else MMDBManager->RemoveFlag ( mmdb::MMDBF_SimRWBROOK ); MMDBManager->SetFlag ( mmdb::MMDBF_IgnoreDuplSeqNum | mmdb::MMDBF_IgnoreBlankLines | mmdb::MMDBF_IgnoreRemarks | mmdb::MMDBF_IgnoreNonCoorPDBErrors | mmdb::MMDBF_AllowDuplChainID ); switch (nType) { default : nType = 0; // nType=-2: unidentified: try PDB case 0 : ErrCode = MMDBManager->ReadPDBASCII ( FName ); break; case 1 : ErrCode = MMDBManager->ReadCIFASCII ( FName ); break; case 2 : ErrCode = MMDBManager->ReadMMDBF ( FName ); break; } if (ErrCode==0) { RC = MMDBManager->CrystReady(); switch (RC) { case mmdb::CRRDY_NoTransfMatrices : ErrCode = RWBERR_NoMatrices; break; case mmdb::CRRDY_Unchecked : ErrCode = RWBERR_NoCheck; break; case mmdb::CRRDY_Ambiguous : ErrCode = RWBERR_Disagreement; break; case mmdb::CRRDY_NoCell : ErrCode = RWBERR_NoCellParams; break; default : ; } } fPos = 0; // begining of the file TranslateError(); } void Channel::Write() { ErrCode = -3; if ((!MMDBManager) || (!FName)) return; IdentifyFile ( FName ); switch (nType) { default : nType = 0; // nType=-2: unidentified: make PDB case 0 : ErrCode = MMDBManager->WritePDBASCII ( FName ); break; case 1 : ErrCode = MMDBManager->WriteCIFASCII ( FName ); break; case 2 : ErrCode = MMDBManager->WriteMMDBF ( FName ); break; } // we do not change fPos here! TranslateError(); } void Channel::TranslateError() { switch (ErrCode) { case mmdb::Error_CantOpenFile : ErrCode = RWBERR_CantOpenFile; break; case mmdb::Error_UnrecognizedInteger : ErrCode = RWBERR_WrongInteger; break; case mmdb::Error_NoData : ErrCode = RWBERR_NotACIFFile; break; case mmdb::Error_WrongModelNo : ErrCode = RWBERR_WrongModelNo; break; case mmdb::Error_DuplicatedModel : ErrCode = RWBERR_DuplicatedModel; break; case mmdb::Error_ForeignFile : ErrCode = RWBERR_ForeignFile; break; case mmdb::Error_WrongEdition : ErrCode = RWBERR_WrongEdition; break; case mmdb::Error_ATOM_Unrecognized : ErrCode = RWBERR_ATOM_Unrecognd; break; case mmdb::Error_ATOM_AlreadySet : ErrCode = RWBERR_ATOM_AlreadySet; break; case mmdb::Error_ATOM_NoResidue : ErrCode = RWBERR_ATOM_NoResidue; break; case mmdb::Error_ATOM_Unmatch : ErrCode = RWBERR_ATOM_Unmatch; break; case mmdb::Error_NotACIFFile : ErrCode = RWBERR_NotACIFFile; break; case mmdb::Error_UnrecognCIFItems : ErrCode = RWBERR_UnrecognCIFItems; break; case mmdb::Error_MissingCIFField : ErrCode = RWBERR_MissingCIFField; break; case mmdb::Error_EmptyCIFLoop : ErrCode = RWBERR_EmptyCIFLoop; break; case mmdb::Error_UnexpEndOfCIF : ErrCode = RWBERR_UnexpEndOfCIF; break; case mmdb::Error_MissgCIFLoopField : ErrCode = RWBERR_MissgCIFLoopField; break; case mmdb::Error_NotACIFStructure : ErrCode = RWBERR_NotACIFStructure; break; case mmdb::Error_NotACIFLoop : ErrCode = RWBERR_NotACIFLoop; break; case mmdb::Error_UnrecognizedReal : ErrCode = RWBERR_WrongReal; break; case mmdb::Error_Ok : ErrCode = RWBERR_Ok; break; case mmdb::Error_WrongChainID : ErrCode = RWBERR_WrongChainID; break; case mmdb::Error_WrongEntryID : ErrCode = RWBERR_WrongEntryID; break; case mmdb::Error_SEQRES_serNum : ErrCode = RWBERR_SEQRES_serNum; break; case mmdb::Error_SEQRES_numRes : ErrCode = RWBERR_SEQRES_numRes; break; case mmdb::Error_SEQRES_extraRes : ErrCode = RWBERR_SEQRES_exraRes; break; case mmdb::Error_NCSM_Unrecognized : ErrCode = RWBERR_NCSM_Unrecogn; break; case mmdb::Error_NCSM_AlreadySet : ErrCode = RWBERR_NCSM_AlreadySet; break; case mmdb::Error_NCSM_WrongSerial : ErrCode = RWBERR_NCSM_WrongSerial; break; case mmdb::Error_NCSM_UnmatchIG : ErrCode = RWBERR_NCSM_UnmatchIG; break; case mmdb::Error_NoModel : ErrCode = RWBERR_NoModel; break; case mmdb::Error_NoSheetID : ErrCode = RWBERR_NoSheetID; break; case mmdb::Error_WrongSheetID : ErrCode = RWBERR_WrongSheetID; break; case mmdb::Error_WrongStrandNo : ErrCode = RWBERR_WrongStrandNo; break; case mmdb::Error_WrongNumberOfStrands : ErrCode = RWBERR_WrongNofStrands; break; case mmdb::Error_WrongSheetOrder : ErrCode = RWBERR_WrongSheetOrder; break; case mmdb::Error_HBondInconsistency : ErrCode = RWBERR_HBondInconsis; break; case mmdb::Error_EmptyResidueName : ErrCode = RWBERR_EmptyResidueName; break; case mmdb::Error_DuplicateSeqNum : ErrCode = RWBERR_DuplicateSeqNum; break; case mmdb::Error_NoLogicalName : ErrCode = RWBERR_NoLogicalName; break; case mmdb::Error_GeneralError1 : ErrCode = RWBERR_GeneralError1; break; default : ; } } bool Channel::EndOfFile() { int nA; if (MMDBManager) { nA = MMDBManager->GetNumberOfAtoms(); if (fPos>nA) { fPos = nA+1; return true; } } else return true; return false; } mmdb::PAtom * Channel::GetAtomArray() { if (MMDBManager) return MMDBManager->GetAtomArray(); else return NULL; } mmdb::PAtom Channel::GetAtomI ( int index ) { // returns index-th atom, as counted from the // top of file if (MMDBManager) return MMDBManager->GetAtomI ( index ); else return NULL; } mmdb::PCryst Channel::GetCryst() { if (MMDBManager) return MMDBManager->GetCrystData(); else return NULL; } bool Channel::areCrystMatrices() { if (MMDBManager) return MMDBManager->isTransfMatrix(); else return false; } void Channel::Frac2Orth ( mmdb::realtype x, mmdb::realtype y, mmdb::realtype z, mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz ) { if (MMDBManager) MMDBManager->Frac2Orth ( x,y,z,xx,yy,zz ); else { xx = x; yy = y; zz = z; } } void Channel::Orth2Frac ( mmdb::realtype x, mmdb::realtype y, mmdb::realtype z, mmdb::realtype & xx, mmdb::realtype & yy, mmdb::realtype & zz ) { if (MMDBManager) MMDBManager->Orth2Frac ( x,y,z,xx,yy,zz ); else { xx = x; yy = y; zz = z; } } void Channel::Cryst2Orth ( mmdb::rvector U ) { if (MMDBManager) MMDBManager->GetCrystData()->Cryst2Orth ( U ); } void Channel::Orth2Cryst ( mmdb::rvector U ) { if (MMDBManager) MMDBManager->GetCrystData()->Orth2Cryst ( U ); } int Channel::PutCell ( mmdb::realtype cell_a, mmdb::realtype cell_b, mmdb::realtype cell_c, mmdb::realtype cell_alpha, mmdb::realtype cell_beta, mmdb::realtype cell_gamma, int OrthCode ) { if (MMDBManager) { mmdb::PCryst cryst = MMDBManager->GetCrystData(); cryst->PutCell ( cell_a,cell_b,cell_c, cell_alpha,cell_beta,cell_gamma, OrthCode ); if ((cell_a!=0.0) || (OrthCode>0)) { if (cryst->CellCheck & mmdb::CCHK_Disagreement) return RWBERR_Disagreement; if (cryst->CellCheck & mmdb::CCHK_NoOrthCode) return RWBERR_NoOrthCode; if (cryst->CellCheck & mmdb::CCHK_Unchecked) return RWBERR_NoCheck; } return RWBERR_Ok; } else return RWBERR_NoFile; } int Channel::SetCell ( mmdb::realtype cell_a, mmdb::realtype cell_b, mmdb::realtype cell_c, mmdb::realtype cell_alpha, mmdb::realtype cell_beta, mmdb::realtype cell_gamma, int OrthCode ) { if (MMDBManager) { mmdb::PCryst cryst = MMDBManager->GetCrystData(); cryst->SetCell ( cell_a,cell_b,cell_c, cell_alpha,cell_beta,cell_gamma, OrthCode ); if (cryst->CellCheck & mmdb::CCHK_Disagreement) return RWBERR_Disagreement; if (cryst->CellCheck & mmdb::CCHK_NoOrthCode) return RWBERR_NoOrthCode; if (cryst->CellCheck & mmdb::CCHK_Unchecked) return RWBERR_NoCheck; return RWBERR_Ok; } else return RWBERR_NoFile; } int Channel::SetSpGroup ( mmdb::pstr spGroup ) { if (MMDBManager) { MMDBManager->SetSpaceGroup(spGroup); return RWBERR_Ok; } else return RWBERR_NoFile; } int Channel::GetSpGroup ( mmdb::pstr spGroup ) { if (MMDBManager) { mmdb::PCryst cryst = MMDBManager->GetCrystData(); if (cryst->WhatIsSet & mmdb::CSET_SpaceGroup) strcpy ( spGroup,cryst->spaceGroup ); else strcpy ( spGroup," " ); return RWBERR_Ok; } else return RWBERR_NoFile; } int Channel::GetCell ( mmdb::realtype & cell_a, mmdb::realtype & cell_b, mmdb::realtype & cell_c, mmdb::realtype & cell_alpha, mmdb::realtype & cell_beta, mmdb::realtype & cell_gamma, mmdb::realtype & cell_v, int & OrthCode ) { if (MMDBManager) { mmdb::PCryst cryst = MMDBManager->GetCrystData(); cell_a = cryst->a; cell_b = cryst->b; cell_c = cryst->c; cell_alpha = cryst->alpha; cell_beta = cryst->beta; cell_gamma = cryst->gamma; cell_v = cryst->Vol; OrthCode = cryst->NCode; if (!(cryst->WhatIsSet & mmdb::CSET_CellParams)) return RWBERR_NoCellParams; if (!(cryst->WhatIsSet & mmdb::CSET_Transforms)) return RWBERR_NoCheck; // if (MMDBManager->Cryst.CellCheck & mmdb::CCHK_NoOrthCode) // return RWBERR_NoOrthCode; return RWBERR_Ok; } else return RWBERR_NoFile; } int Channel::GetRCell ( mmdb::realtype & cell_as, mmdb::realtype & cell_bs, mmdb::realtype & cell_cs, mmdb::realtype & cell_alphas, mmdb::realtype & cell_betas, mmdb::realtype & cell_gammas, mmdb::realtype & cell_vs ) { if (MMDBManager) { mmdb::PCryst cryst = MMDBManager->GetCrystData(); cryst->GetRCell ( cell_as,cell_bs,cell_cs, cell_alphas,cell_betas,cell_gammas, cell_vs ); if (!(cryst->WhatIsSet & mmdb::CSET_CellParams)) return RWBERR_NoCellParams; if (!(cryst->WhatIsSet & mmdb::CSET_Transforms)) return RWBERR_NoCheck; return RWBERR_Ok; } else return RWBERR_NoFile; } void Channel::GetInputBuffer ( mmdb::pstr Line, int & count ) { if (MMDBManager) MMDBManager->GetInputBuffer ( Line,count ); else { strcpy ( Line,"" ); count = -1; } } // ======================== static data =========================== static int nChannels; // number of channels in processing static PChannel * channel; // array of channels in processing static bool FAutoSer; // flag to automatically generate // serial numbers at reading PDB files static bool FReadCoords; // flag to read coordinates; if set to // false, only the header of PDB file // is read static bool FSimRWBROOK; // flag to simulate old RWBROOK printout // as closely as possible static char LastFunc[80]; // name of the last called function static int LastUnit; // number of the last unit called static int LastRC; // last return code static int LastSer; // last serial number kept for // certain warnings // ======================== RWBrook API =========================== FORTRAN_SUBR ( MMDB_F_INIT, mmdb_f_init,(),(),() ) { mmdb::InitMatType(); nChannels = 0; channel = NULL; strcpy ( LastFunc,"MMDB_F_Init" ); LastUnit = -1; LastRC = 0; LastSer = 0; FAutoSer = false; FReadCoords = true; FSimRWBROOK = false; } FORTRAN_SUBR ( MMDB_F_QUIT, mmdb_f_quit,(),(),() ) { int i; for (i=0;inUnit==iUnit) return i; } return -1; } int MakeChannel ( int iUnit ) { // If iUnit-th unit already exists, it is // reinitialized. Otherwise the function looks // for a not used channel, and if there is one, // associates the new iUnit-th unit with it. // If there is no unused channels, the new one // is created and the new iUnit-th unit is // associated with it. // Returns serial number of the channel // associated with the newly reinitialized // or created unit. int i,m; PChannel * channel1; m = GetChannel ( iUnit ); if (m>=0) { // such channel already exists channel[m]->Dispose(); // clear it first channel[m]->Init(); // reinitialize it channel[m]->nUnit = iUnit; return m; } for (i=0;inUnit = iUnit; return m; } FORTRAN_SUBR ( MMDB_F_OPEN, mmdb_f_open, ( // lengths-at-end list mmdb::machine::fpstr FName, // file name mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT" mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " " int * iUnit, // channel number int * iRet, // returns error code int FName_len, // fortran-hidden length of FName int RWStat_len, // fortran-hidden length of RWStat int FType_len // fortran-hidden length of FType ), ( // lengths-in-structure list mmdb::machine::fpstr FName, mmdb::machine::fpstr RWStat, mmdb::machine::fpstr FType, int * iUnit, int * iRet ), ( // lengths-follow list mmdb::machine::fpstr FName, int FName_len, mmdb::machine::fpstr RWStat, int RWStat_len, mmdb::machine::fpstr FType, int FType_len, int * iUnit, int * iRet ) ) { UNUSED_ARGUMENT(RWStat_len); UNUSED_ARGUMENT(FType_len); int k; char L[500]; #ifdef WIN32 mmdb::GetStrTerWin32File ( L,FTN_STR(FName),0,sizeof(L),FTN_LEN(FName) ); #else mmdb::GetStrTer ( L,FTN_STR(FName),0,sizeof(L),FTN_LEN(FName) ); #endif strcpy ( LastFunc,"MMDB_F_Open" ); LastUnit = *iUnit; if (*iUnit==0) { // generate unit number *iUnit = 1; do { k = GetChannel ( *iUnit ); if (k>=0) *iUnit = *iUnit+1; } while (k>=0); } // create channel k = MakeChannel ( *iUnit ); if (k>=0) { if (FTN_STR(RWStat)[0]=='I') { channel[k]->nRead = 0; channel[k]->FAutoSer = FAutoSer; channel[k]->FReadCoords = FReadCoords; channel[k]->FSimRWBROOK = FSimRWBROOK; } else channel[k]->nRead = 1; // store file name channel[k]->SetFileName ( L,sizeof(L) ); // store unit type channel[k]->SetFileType ( FTN_STR(FType) ); channel[k]->IdentifyFile( L ); if (FSimRWBROOK) { switch (channel[k]->nType) { default : printf ( " unknown-format" ); break; case 0 : printf ( " PDB" ); break; case 1 : printf ( " mmCIF" ); break; case 2 : printf ( " MMDB BINARY" ); } printf ( " file is being opened on unit %i",*iUnit ); if (FTN_STR(RWStat)[0]=='I') printf ( " for INPUT.\n\n" ); else printf ( " for OUTPUT.\n\n" ); } if (FTN_STR(RWStat)[0]=='I') { channel[k]->Read(); *iRet = channel[k]->ErrCode; } else { channel[k]->MakeCoordStructure(); channel[k]->fPos = 1; *iRet = RWBERR_Ok; } } else *iRet = RWBERR_NoChannel; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_OPENL, mmdb_f_openl, ( // lengths-at-end list mmdb::machine::fpstr LName, // logical name mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT" mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " " int * iUnit, // channel number int * iRet, // returns error code int LName_len, // fortran-hidden length of LName int RWStat_len, // fortran-hidden length of RWStat int FType_len // fortran-hidden length of FType ), ( // lengths-in-structure list mmdb::machine::fpstr LName, mmdb::machine::fpstr RWStat, mmdb::machine::fpstr FType, int * iUnit, int * iRet ), ( // lengths-follow list mmdb::machine::fpstr LName, int LName_len, mmdb::machine::fpstr RWStat, int RWStat_len, mmdb::machine::fpstr FType, int FType_len, int * iUnit, int * iRet ) ) { char L[200]; mmdb::pstr S; char_struct(FName) strcpy ( LastFunc,"MMDB_F_Openl" ); mmdb::GetStrTer ( L,FTN_STR(LName),0,sizeof(L),FTN_LEN(LName) ); S = getenv ( L ); if (S) { fill_char_struct(FName,S) } else if (FTN_STR(RWStat)[0]=='O') { // The user may not have assigned a logical // for output, so that the program should write file "XYZOUT". This // is allowed as a convenience when user is not really interested // in output file. fill_char_struct(FName,L) } else { *iRet = RWBERR_NoLogicalName; return; } printf ( "\n Logical name: %s File name: %s\n",L,FName ); FORTRAN_CALL ( MMDB_F_OPEN, mmdb_f_open, ( FName,RWStat,FType,iUnit,iRet, FName_len,RWStat_len,FType_len ), ( &FName,RWStat,FType,iUnit,iRet ), ( FName,FName_len,RWStat,RWStat_len, FType,FType_len,iUnit,iRet ) ); } FORTRAN_SUBR ( MMDB_F_COPY, mmdb_f_copy, ( // lengths-at-end list int * iUnit1, // destination unit int * iUnit2, // source unit int * copyKey, // copy key: // = 1 copy all // = 2 copy all except coordinates // = 3 copy title section only // = 4 copy crystallographic // section only // = 5 copy coordinate section only // any other value does not do anything int * iRet // return code: // =0 if success // =RWBERR_NoChannel if a unit // does not exist ), ( // lengths-in-structure list int * iUnit1, int * iUnit2, int * copyKey, int * iRet ), ( // lengths-follow list int * iUnit1, int * iUnit2, int * copyKey, int * iRet ) ) { int k1,k2; mmdb::COPY_MASK copyMask; strcpy ( LastFunc,"MMDB_F_Copy" ); LastUnit = *iUnit1; k1 = GetChannel ( LastUnit ); if (k1>=0) { if (channel[k1]->MMDBManager) { LastUnit = *iUnit2; k2 = GetChannel ( LastUnit ); if (k2>=0) { if (channel[k2]->MMDBManager) { switch (*copyKey) { case 1 : copyMask = mmdb::MMDBFCM_All; break; case 2 : copyMask = mmdb::MMDBFCM_Top; break; case 3 : copyMask = mmdb::MMDBFCM_Title; break; case 4 : copyMask = mmdb::MMDBFCM_Cryst; break; case 5 : copyMask = mmdb::MMDBFCM_Coord; break; default : copyMask = mmdb::MMDBFCM_None; } channel[k1]->MMDBManager->Copy ( channel[k2]->MMDBManager, copyMask ); *iRet = RWBERR_Ok; } else *iRet = RWBERR_NoFile; } else *iRet = RWBERR_NoChannel; } else *iRet = RWBERR_NoFile; } else *iRet = RWBERR_NoChannel; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_DELETE, mmdb_f_delete, ( // lengths-at-end list int * iUnit, // unit number; *iUnit<=0 means // "the last mentioned unit" int * delKey, // delete key: // = 1 delete all // = 2 delete all except coordinates // = 3 delete title section only // = 4 delete crystallographic // section only // = 5 delete coordinate section only // any other value does not do anything int * iRet // return code: // =0 if success // =RWBERR_NoChannel if a unit // does not exist // =RWBERR_NoFile if a unit // was not opened ), ( // lengths-in-structure list int * iUnit, int * delKey, int * iRet ), ( // lengths-follow list int * iUnit, int * delKey, int * iRet ) ) { int k; mmdb::word delMask; strcpy ( LastFunc,"MMDB_F_Delete" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k>=0) { if (channel[k]->MMDBManager) { switch (*delKey) { case 1 : delMask = mmdb::MMDBFCM_All; break; case 2 : delMask = mmdb::MMDBFCM_Top; break; case 3 : delMask = mmdb::MMDBFCM_Title; break; case 4 : delMask = mmdb::MMDBFCM_Cryst; break; case 5 : delMask = mmdb::MMDBFCM_Coord; break; default : delMask = 0x0000; } channel[k]->MMDBManager->Delete ( delMask ); *iRet = RWBERR_Ok; } else *iRet = RWBERR_NoFile; } else *iRet = RWBERR_NoChannel; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_SETTYPE, mmdb_f_settype, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::fpstr FType, // "PDB", "CIF", "BIN" or " " mmdb::machine::fpstr RWStat, // "INPUT" or "OUTPUT" int * iRet, // returns -1 if unit not found, // otherwise 0 int FType_len, // fortran-hidden length of FType int RWStat_len // fortran-hidden length of RWStat ), ( // lengths-in-structure list int * iUnit, mmdb::machine::fpstr FType, mmdb::machine::fpstr RWStat, int * iRet ), ( // length-follow list int * iUnit, mmdb::machine::fpstr FType, int FType_len, mmdb::machine::fpstr RWStat, int RWStat_len, int * iRet ) ) { UNUSED_ARGUMENT(FType_len); UNUSED_ARGUMENT(RWStat_len); int k; strcpy ( LastFunc,"MMDB_F_SetType" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k>=0) { // store unit type channel[k]->SetFileType ( FTN_STR(FType) ); // store unit mode if (FTN_STR(RWStat)[0]=='I') channel[k]->nRead = 0; else channel[k]->nRead = 1; *iRet = RWBERR_Ok; } else *iRet = RWBERR_NoChannel; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_SETNAME, mmdb_f_setname, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::fpstr FName, // file name int * iRet, // returns -1 if unit not found, // otherwise 0 int FName_len // fortran-hidden length of FName ), ( // lengths-in-structure list int * iUnit, mmdb::machine::fpstr FName, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::fpstr FName, int FName_len, int * iRet ) ) { int k; strcpy ( LastFunc,"MMDB_F_SetName" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) *iRet = RWBERR_NoChannel; else { // store file name channel[k]->SetFileName ( FTN_STR(FName),FTN_LEN(FName) ); *iRet = RWBERR_Ok; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_WRITE, mmdb_f_write, ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ) ) { int k; strcpy ( LastFunc,"MMDB_F_Write" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) *iRet = RWBERR_NoChannel; else { channel[k]->Write(); *iRet = channel[k]->ErrCode; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_CLOSE, mmdb_f_close, ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ) ) { int k; strcpy ( LastFunc,"MMDB_F_Close" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) *iRet = RWBERR_NoChannel; else if (channel[k]->nRead==1) { channel[k]->Write(); *iRet = channel[k]->ErrCode; if (!(*iRet)) { delete channel[k]; channel[k] = NULL; } } else { delete channel[k]; channel[k] = NULL; *iRet = RWBERR_Ok; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_ADVANCE, mmdb_f_advance, ( // lengths-at-end list int * iUnit, // unit number int * iOut, // output echo file int * iTer, // FLAG =1, return iRet=1 if 'ter' card found // =0, do not return on 'ter' card int * iRet // =0 if normal return // =1 if return on 'ter' card (iTer=1) // =2 if return on end of file // =3 if return on 'hetatm' card // =RWBERR_NoChannel if unit does not exist // =RWBERR_NoAdvance if pointer was not // advanced ), ( // lengths-in-structure list int * iUnit, int * iOut, int * iTer, int * iRet ), ( // lengths-follow list int * iUnit, int * iOut, int * iTer, int * iRet ) ) { UNUSED_ARGUMENT(iOut); int k; mmdb::PAtom atom; strcpy ( LastFunc,"mmdb_f_advance" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k<0) *iRet = RWBERR_NoChannel; else if (channel[k]->nRead==0) { // in the input file, try to get pointer on the next atom do { channel[k]->fPos++; // advance the pointer on Atom array if (channel[k]->EndOfFile()) { atom = NULL; break; } atom = channel[k]->GetAtomI ( channel[k]->fPos ); if (atom) { if ((atom->Ter) && (*iTer==0)) { // ignore 'ter' card if iTer is set to 0 atom = NULL; } } } while (!atom); if (!atom) *iRet = 2; // no atom found == end of file else if (atom->Ter) *iRet = 1; // 'ter' card encountered else if (atom->Het) *iRet = 3; // 'hetatm' card encountered else *iRet = 0; // advance ok; normal return } else { // in the output file, just advance the pointer if (channel[k]->fPos==0) { channel[k]->fPos++; *iRet = 0; } else { atom = channel[k]->GetAtomI ( channel[k]->fPos ); if (atom) { // the previous atom was set -- advance the pointer channel[k]->fPos++; *iRet = 0; } else // no atom was set; make no advancement *iRet = RWBERR_NoAdvance; } } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_REWD, mmdb_f_rewd, ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ) ) { int k; strcpy ( LastFunc,"MMDB_F_Rewd" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k>=0) { channel[k]->fPos = 0; if (channel[k]->nRead!=0) *iRet = RWBWAR_RewOutput; else *iRet = RWBERR_Ok; } else *iRet = RWBERR_NoChannel; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_BKSP, mmdb_f_bksp, ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ) ) { int k; strcpy ( LastFunc,"MMDB_F_BkSp" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k>=0) { *iRet = RWBERR_Ok; if (channel[k]->fPos==0) *iRet |= RWBWAR_FileTop; else channel[k]->fPos--; if (channel[k]->nRead!=0) *iRet |= RWBWAR_RewOutput; } else *iRet = RWBERR_NoChannel; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_SEEK, mmdb_f_seek, ( // lengths-at-end list int * iUnit, // unit number int * fPos, // position to set int * iRet // return code: // 0 Ok // 1 'ter' card met // 2 end of file // 3 'hetatm' card met // <0 error: // RWBERR_NoChannel // iUnit was not // initialized // RWBERR_EmptyPointer // fPos-th position ), ( // lengths-in-structure list int * iUnit, int * fPos, int * iRet ), ( // lengths-follow list int * iUnit, int * fPos, int * iRet ) ) { int k; mmdb::PAtom atom; strcpy ( LastFunc,"MMDB_F_Seek" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k<0) *iRet = RWBERR_NoChannel; else { // set the pointer channel[k]->fPos = mmdb::IMax(0,*fPos); if (*fPos==0) *iRet = RWBWAR_FileTop; else *iRet = RWBERR_Ok; if (channel[k]->nRead==0) { // in the input file, check the end-of-file state // and analyze the atom if (channel[k]->EndOfFile()) *iRet = 2; atom = channel[k]->GetAtomI ( channel[k]->fPos ); if (!atom) *iRet = RWBERR_EmptyPointer; // empty place else if (atom->Ter) *iRet = 1; // 'ter' card encountered else if (atom->Het) *iRet = 3; // 'hetatm' card encountered } // in the output file, there is nothing to do } LastRC = *iRet; } void Make_AN_ID_IZ ( mmdb::PAtom atom, mmdb::pstr AtNam, int AtNam_L, mmdb::pstr ID, int ID_L, int * IZ, int * iRet ) { char chrg[10]; int i,k; if (atom->Ter) { mmdb::strcpy_ns ( AtNam,mmdb::pstr(" "),AtNam_L ); mmdb::strcpy_ns ( ID ,mmdb::pstr(" "),ID_L ); *IZ = 7; } else { if (atom->name[0]==' ') mmdb::strcpy_ns ( AtNam,&(atom->name[1]),4 ); else mmdb::strcpy_ns ( AtNam,atom->name,4 ); // first try to identify the atom with the element name mmdb::strcpy_ns ( ID,atom->element,ID_L ); // not more than ID_L symbols // from element until but not including // the terminated null are copied into // ID, and the latter is padded with // spaces up to the length of ID_L if (ID_L>3) { // if length permits, add ID with atom charge // (always 2 symbols). atom->GetAtomCharge(chrg); ID[2] = chrg[0]; ID[3] = chrg[1]; } k = 0; while ((kelement[0]!=mmdb::ElementName[k][0]) || (atom->element[1]!=mmdb::ElementName[k][1]))) k++; if (k>=mmdb::nElementNames) { // no match for atom ID -- make sure to set it blank mmdb::strcpy_ns ( ID,mmdb::pstr(" "),ID_L ); // try to identify the atom using the atom name k = 0; while ((kname[0]!=mmdb::ElementName[k][0]) || (atom->name[1]!=mmdb::ElementName[k][1]))) k++; // try to identify a heteroatom i = 0; while ((i=mmdb::nElementNames)) { if ((atom->name[0]==mmdb::HydAtomName[i][0]) && (atom->name[1]==mmdb::HydAtomName[i][1])) k = 0; i++; } if (k>=mmdb::nElementNames) { // unknown or ambiguous formfactor k = -1; if ((atom->name[0]==' ') && (atom->name[1]=='A')) k = 6; if (k==-1) *iRet |= RWBWAR_UnkFormFactor; else *iRet |= RWBWAR_AmbFormFactor; } } *IZ = k+1; if (*IZ==0) mmdb::strcpy_ns ( ID,mmdb::pstr(" "),ID_L ); else { if (ID_L>3) { if (ID[0]==' ') { if ((AtNam[2]=='+') || (AtNam[2]=='-')) { ID[2] = AtNam[2]; ID[3] = AtNam[3]; } } else if ((ID[2]!='+') && (ID[2]!='-')) { ID[2] = ' '; ID[3] = ' '; } } mmdb::strcpy_ns ( ID,mmdb::ElementName[k],mmdb::IMin(2,ID_L) ); } } } FORTRAN_SUBR ( MMDB_F_ATOM, mmdb_f_atom, ( // lengths-at-end list int * iUnit, // unit number int * iSer, // atom serial number mmdb::machine::fpstr AtNam, // atom name (left justified) mmdb::machine::fpstr ResNam, // residue name mmdb::machine::fpstr ChnNam, // chain name int * iResN, // residue number as an integer mmdb::machine::fpstr ResNo, // residue number as character (input only) mmdb::machine::fpstr InsCod, // the insertion code mmdb::machine::fpstr AltCod, // the alternate conformation code mmdb::machine::fpstr segID, // segment ID int * IZ, // atomic number (input only, returned as // 7 from ambiguous atoms) mmdb::machine::fpstr ID, // atomic ID related to atomic number // (element symbol right justified), plus // the ionic state +2, +3 etc.. // int * iRet, // returns // RWBERR_NoChannel if iUnit was not // initialized // RWBERR_EmptyPointer if atom was not // advanced // RWBERR_Error1 internal error #1 // RWBERR_Error2 internal error #2 // RWBERR_Error3 internal error #3 // // >=0 : success, warning flags: // RWBWAR_WrongSerial if serial number // differs from the position // number in the file // RWBWAR_UnkFormFactor unknown formfactor // RWBWAR_AmbFormFactor ambiguous formfactor // int AtNam_len, // fortran-hidden length of AtNam int ResNam_len, // fortran-hidden length of ResNam int ChnNam_len, // fortran-hidden length of ChnNam int ResNo_len, // fortran-hidden length of ResNo int InsCod_len, // fortran-hidden length of InsCod int AltCod_len, // fortran-hidden length of AltCod int segID_len, // fortran-hidden length of SegID int ID_len // fortran-hidden length of ID ), ( // lengths-in-structure list int * iUnit, int * iSer, mmdb::machine::fpstr AtNam, mmdb::machine::fpstr ResNam, mmdb::machine::fpstr ChnNam, int * iResN, mmdb::machine::fpstr ResNo, mmdb::machine::fpstr InsCod, mmdb::machine::fpstr AltCod, mmdb::machine::fpstr segID, int * IZ, mmdb::machine::fpstr ID, int * iRet ), ( // lengths-follow list int * iUnit, int * iSer, mmdb::machine::fpstr AtNam, int AtNam_len, mmdb::machine::fpstr ResNam, int ResNam_len, mmdb::machine::fpstr ChnNam, int ChnNam_len, int * iResN, mmdb::machine::fpstr ResNo, int ResNo_len, mmdb::machine::fpstr InsCod, int InsCod_len, mmdb::machine::fpstr AltCod, int AltCod_len, mmdb::machine::fpstr segID, int segID_len, int * IZ, mmdb::machine::fpstr ID, int ID_len, int * iRet ) ) { int k,RC; mmdb::ChainID chainID; mmdb::ResName resName; mmdb::InsCode insCode; mmdb::AtomName atomName; mmdb::AltLoc altLoc; mmdb::SegID sgID; mmdb::Element element; mmdb::PAtom atom; char charge[10]; strcpy ( LastFunc,"MMDB_F_Atom" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } *iRet = RWBERR_Ok; if (channel[k]->nRead==0) { // reading the atom characteristics atom = channel[k]->GetAtomI ( channel[k]->fPos ); if (!atom) { // atom position was not advanced properly *iRet = RWBERR_EmptyPointer; LastRC = *iRet; return; } *iSer = atom->serNum; if (*iSer!=channel[k]->fPos) *iRet |= RWBWAR_WrongSerial; LastSer = *iSer; Make_AN_ID_IZ ( atom,FTN_STR(AtNam),FTN_LEN(AtNam), FTN_STR(ID),FTN_LEN(ID),IZ,iRet ); if (atom->residue) { mmdb::strcpy_ns ( FTN_STR(ResNam),atom->residue->name,FTN_LEN(ResNam) ); *iResN = atom->residue->seqNum; mmdb::PutInteger ( FTN_STR(ResNo),*iResN,mmdb::IMin(4,FTN_LEN(ResNo)) ); mmdb::strcpy_ns ( FTN_STR(InsCod),atom->residue->insCode,FTN_LEN(InsCod) ); mmdb::strcpy_ns ( &(FTN_STR(ResNo)[4]),FTN_STR(InsCod),FTN_LEN(ResNo)-4 ); mmdb::strcpy_ns ( FTN_STR(ChnNam),atom->GetChainID(),FTN_LEN(ChnNam) ); } else { mmdb::strcpy_ns ( FTN_STR(ResNam),mmdb::pstr(" "),FTN_LEN(ResNam) ); mmdb::strcpy_ns ( FTN_STR(ChnNam),mmdb::pstr(" ") ,FTN_LEN(ChnNam) ); *iResN = 0; mmdb::strcpy_ns ( FTN_STR(ResNo) ,mmdb::pstr("0") ,FTN_LEN(ResNo) ); mmdb::strcpy_ns ( FTN_STR(InsCod),mmdb::pstr(" ") ,FTN_LEN(InsCod) ); } mmdb::strcpy_ns ( FTN_STR(AltCod),atom->altLoc,FTN_LEN(AltCod) ); mmdb::strcpy_ns ( FTN_STR(segID) ,atom->segID ,FTN_LEN(segID) ); } else { // storing the atom characteristics if (!channel[k]->MMDBManager) { *iRet = RWBERR_Error1; // should never happen LastRC = *iRet; return; } mmdb::GetStrTer ( chainID,FTN_STR(ChnNam),1,sizeof(chainID),FTN_LEN(ChnNam) ); mmdb::GetStrTer ( resName,FTN_STR(ResNam),3,sizeof(resName),FTN_LEN(ResNam) ); mmdb::GetStrTer ( insCode,FTN_STR(InsCod),1,sizeof(insCode),FTN_LEN(InsCod) ); mmdb::GetStrTer ( altLoc ,FTN_STR(AltCod),1,sizeof(altLoc) ,FTN_LEN(AltCod) ); mmdb::GetStrTer ( sgID ,FTN_STR(segID) ,4,sizeof(sgID) ,FTN_LEN(segID) ); element[0] = FTN_STR(ID)[0]; element[1] = FTN_STR(ID)[1]; element[2] = char(0); if (FTN_LEN(ID)>3) { charge [0] = FTN_STR(ID)[2]; charge [1] = FTN_STR(ID)[3]; charge [2] = char(0); } else charge [0] = char(0); if (FTN_STR(ID)[0]==' ') { atomName[0] = char(0); // if ((FTN_STR(AtNam)[1]=='H') || // ((FTN_STR(AtNam)[1]=='D') && (FTN_STR(ID)[2]=='D'))) { // int i = 0; // while ((iMMDBManager->PutAtom ( channel[k]->fPos,*iSer, atomName,resName,chainID,*iResN, insCode,altLoc,sgID,element ); if (RC) { *iRet = RWBERR_Error2; // should never happen LastRC = *iRet; return; } mmdb::DelSpaces ( charge ); if (charge[0]) { atom = channel[k]->GetAtomI ( channel[k]->fPos ); if (!atom) { *iRet = RWBERR_EmptyPointer; // should never be so LastRC = *iRet; return; } atom->SetCharge ( charge ); } if (*iSer!=channel[k]->fPos) { *iRet |= RWBWAR_WrongSerial; // this is not the right thing at all atom = channel[k]->GetAtomI ( channel[k]->fPos ); if (!atom) { *iRet = RWBERR_EmptyPointer; // should never be so LastRC = *iRet; return; } // atom->serNum = *iSer; // - we allow for a mess in serials } LastSer = *iSer; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_SETTER, mmdb_f_setter, ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ) ) { int k; mmdb::PAtom atom; strcpy ( LastFunc,"MMDB_F_SetTer" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } atom = channel[k]->GetAtomI ( channel[k]->fPos ); *iRet = RWBERR_Ok; if (!atom) { *iRet = RWBERR_EmptyPointer; // atom position was not advanced properly LastRC = *iRet; return; } atom->Ter = true; atom->WhatIsSet |= mmdb::ASET_Coordinates; } FORTRAN_SUBR ( MMDB_F_SETHET, mmdb_f_sethet, ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ), ( int * iUnit, int * iRet ) ) { int k; mmdb::PAtom atom; strcpy ( LastFunc,"MMDB_F_SetHet" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } atom = channel[k]->GetAtomI ( channel[k]->fPos ); *iRet = RWBERR_Ok; if (!atom) { *iRet = RWBERR_EmptyPointer; // atom position was not advanced properly LastRC = *iRet; return; } atom->Het = true; atom->WhatIsSet |= mmdb::ASET_Coordinates; } FORTRAN_SUBR ( MMDB_F_GETHET, mmdb_f_gethet, ( int * iUnit, int * isHet, int * iRet ), ( int * iUnit, int * isHet, int * iRet ), ( int * iUnit, int * isHet, int * iRet ) ) { int k; mmdb::PAtom atom; strcpy ( LastFunc,"MMDB_F_GetHet" ); LastUnit = *iUnit; *isHet = 0; // no HETATM record k = GetChannel ( *iUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } atom = channel[k]->GetAtomI ( channel[k]->fPos ); *iRet = RWBERR_Ok; if (!atom) { *iRet = RWBERR_EmptyPointer; // atom position was not advance properly LastRC = *iRet; return; } if (atom->Het) *isHet = 1; // HETATM } // ------------------------------------------------------------------ // mmdb_f_getnofncsmates_(..) returns the number of NCS mates not // given in the file (iGiven=0). // // Negative returns N<0 mean an error. // // FORTRAN equivalent: subroutine MMDB_F_GetNofNCSMates ( iUnit,N ) // ~~~~~~~~~~~~~~~~~~~ integer iUnit,N FORTRAN_SUBR ( MMDB_F_GETNOFNCSMATES, mmdb_f_getnofncsmates, ( int * iUnit, int * N ), ( int * iUnit, int * N ), ( int * iUnit, int * N ) ) { int k; strcpy ( LastFunc,"mmdb_f_getnofncsmates" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k<0) { *N = RWBERR_NoChannel; LastRC = *N; return; } *N = channel[k]->GetNumberOfNCSMates(); return; } FORTRAN_SUBR ( MMDB_F_COPYATOM, mmdb_f_copyatom, ( int * iUnit1, int * iUnit2, int * iRet ), ( int * iUnit1, int * iUnit2, int * iRet ), ( int * iUnit1, int * iUnit2, int * iRet ) ) { int k1,k2,RC; mmdb::PAtom atom; strcpy ( LastFunc,"mmdb_f_copyatom" ); LastUnit = *iUnit1; k1 = GetChannel ( *iUnit1 ); if (k1<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } k2 = GetChannel ( *iUnit2 ); if (k2<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } atom = channel[k1]->GetAtomI ( channel[k1]->fPos ); *iRet = RWBERR_Ok; if (!atom) { *iRet = RWBERR_EmptyPointer; // atom position was not advanced // properly LastRC = *iRet; return; } RC = channel[k2]->MMDBManager->PutAtom ( channel[k2]->fPos,atom, atom->serNum ); if (RC) { *iRet = RWBERR_Error2; // should never happen LastRC = *iRet; return; } LastSer = atom->serNum; } FORTRAN_SUBR ( MMDB_F_COORD, mmdb_f_coord, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::fpstr XFlag, // "F" or "O" flag for the fractional // or orthogonal coordinates x,y,z // for output files XFlag may also be // set to "HF" or "HO", where "F" and // "O" have the same meaning as before // and "H" indicates that the atom // should be marked as heteroatom mmdb::machine::fpstr BFlag , // "F" or "O" flag for temperature // factor in fractional or orthogonal // Us mmdb::machine::apireal * x, // x-coordinate mmdb::machine::apireal * y, // y-coordinate mmdb::machine::apireal * z, // z-coordinate mmdb::machine::apireal * occ, // occupancy mmdb::machine::apireal * BIso, // isotropic temperature factor mmdb::machine::apireal * U, // array(6) of the anisotr. t-factor int * iRet, // returns // RWBERR_NoChannel if iUnit was not // initialized // RWBERR_EmptyPointer if atom was not // advanced // RWBERR_NoMatrices if transformation // matrices are // undefined // RWBERR_NoCoordinates if coordinates were // not set in the atom // // >=0 : success, warning flags: // RWBERR_NoOccupancy if occupancy was // not set in the atom // RWBERR_NoTempFactor if temp. factor was // not set in the atom // int XFlag_len, // fortran-hidden length of XFlag int BFlag_len // fortran-hidden length of BFlag ), ( // lengths-in-structure list int * iUnit, mmdb::machine::fpstr XFlag, mmdb::machine::fpstr BFlag, mmdb::machine::apireal * x, mmdb::machine::apireal * y, mmdb::machine::apireal * z, mmdb::machine::apireal * occ, mmdb::machine::apireal * BIso, mmdb::machine::apireal * U, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::fpstr XFlag, int XFlag_len, mmdb::machine::fpstr BFlag, int BFlag_len, mmdb::machine::apireal * x, mmdb::machine::apireal * y, mmdb::machine::apireal * z, mmdb::machine::apireal * occ, mmdb::machine::apireal * BIso, mmdb::machine::apireal * U, int * iRet ) ) { UNUSED_ARGUMENT(XFlag_len); UNUSED_ARGUMENT(BFlag_len); mmdb::realtype AU[6]; mmdb::realtype xx,yy,zz; int k,i,m; mmdb::PAtom atom; strcpy ( LastFunc,"MMDB_F_Coord" ); LastUnit = *iUnit; k = GetChannel ( *iUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } atom = channel[k]->GetAtomI ( channel[k]->fPos ); *iRet = RWBERR_Ok; if (!atom) { *iRet = RWBERR_EmptyPointer; // atom position was not advanced properly LastRC = *iRet; return; } if ((FTN_STR(XFlag)[0]=='H') || (FTN_STR(XFlag)[0]=='h')) m = 1; else m = 0; if (channel[k]->nRead==0) { // reading the atomic coordinates if (atom->Ter) { *x = 0.0; *y = 0.0; *z = 0.0; *occ = 1.0; *BIso = 1.0; U[0] = 1.0; U[1] = 0.0; U[2] = 0.0; U[3] = 0.0; U[4] = 0.0; U[5] = 0.0; } else { if (atom->WhatIsSet & mmdb::ASET_Coordinates) { if ((FTN_STR(XFlag)[m]=='F') || (FTN_STR(XFlag)[m]=='f')) { // receive fractional coordinates if (channel[k]->areCrystMatrices()) { channel[k]->Orth2Frac ( atom->x,atom->y,atom->z,xx,yy,zz ); *x = (mmdb::machine::apireal)xx; *y = (mmdb::machine::apireal)yy; *z = (mmdb::machine::apireal)zz; } else { *x = (mmdb::machine::apireal)atom->x; *y = (mmdb::machine::apireal)atom->y; *z = (mmdb::machine::apireal)atom->z; *iRet = RWBERR_NoMatrices; } } else { // receive orthogonal coordinates *x = (mmdb::machine::apireal)atom->x; *y = (mmdb::machine::apireal)atom->y; *z = (mmdb::machine::apireal)atom->z; } } else { *x = 0.0; *y = 0.0; *z = 0.0; *iRet = RWBERR_NoCoordinates; } // calculate isotropic Uf from Uo, and convert it // if necessary if (atom->WhatIsSet & mmdb::ASET_Anis_tFac) { AU[0] = atom->u11; // this intermediate array is AU[1] = atom->u22; // required because of possible AU[2] = atom->u33; // type difference between AU[3] = atom->u12; // 'mmdb::machine::apireal' and 'realtype' AU[4] = atom->u13; AU[5] = atom->u23; *BIso = (mmdb::machine::apireal)(8.0*mmdb::Pi*mmdb::Pi*(AU[0]+AU[1]+AU[2])/3.0); if ((FTN_STR(BFlag)[0]=='F') || (FTN_STR(BFlag)[0]=='f')) { if (channel[k]->areCrystMatrices()) channel[k]->Orth2Cryst ( AU ); else if (*iRet==RWBERR_Ok) *iRet = RWBERR_NoMatrices; } for (i=0;i<6;i++) U[i] = (mmdb::machine::apireal)AU[i]; } else { for (i=0;i<6;i++) U[i] = 0.0; if (atom->WhatIsSet & mmdb::ASET_tempFactor) U[0] = (mmdb::machine::apireal)atom->tempFactor; else if (*iRet>=RWBERR_Ok) *iRet |= RWBWAR_NoTempFactor; *BIso = U[0]; } // get occupancy now if (atom->WhatIsSet & mmdb::ASET_Occupancy) *occ = (mmdb::machine::apireal)atom->occupancy; else { *occ = 0.0; if (*iRet>=RWBERR_Ok) *iRet |= RWBWAR_NoOccupancy; } } } else { // storing the atomic coordinates if (atom->Ter) { atom->x = 0.0; atom->y = 0.0; atom->z = 0.0; atom->WhatIsSet |= mmdb::ASET_Coordinates; atom->occupancy = 1.0; atom->tempFactor = 1.0; atom->u11 = 0.0; atom->u22 = 0.0; atom->u33 = 0.0; atom->u12 = 0.0; atom->u13 = 0.0; atom->u23 = 0.0; } else { if ((FTN_STR(XFlag)[m]=='F') || (FTN_STR(XFlag)[m]=='f')) { // convert fractional coordinates if (channel[k]->areCrystMatrices()) { xx = *x; yy = *y; zz = *z; channel[k]->Frac2Orth ( xx,yy,zz,atom->x,atom->y,atom->z ); atom->WhatIsSet |= mmdb::ASET_Coordinates; } else { atom->x = *x; atom->y = *y; atom->z = *z; *iRet = RWBERR_NoMatrices; atom->WhatIsSet &= ~mmdb::ASET_Coordinates; } } else { // store orthogonal coordinates atom->x = *x; atom->y = *y; atom->z = *z; atom->WhatIsSet |= mmdb::ASET_Coordinates; } atom->Het = (m>0); // calculate isotropic Uf from Uo, and convert it // if necessary if ((U[1]!=0.0) || (U[2]!=0.0)) { for (i=0;i<6;i++) AU[i] = U[i]; if ((FTN_STR(BFlag)[0]=='F') || (FTN_STR(BFlag)[0]=='f')) { if (channel[k]->areCrystMatrices()) channel[k]->Cryst2Orth ( AU ); else *iRet = RWBERR_NoMatrices; } *BIso = (mmdb::machine::apireal)(8.0*mmdb::Pi*mmdb::Pi*(AU[0]+AU[1]+AU[2])/3.0); atom->tempFactor = *BIso; atom->u11 = AU[0]; atom->u22 = AU[1]; atom->u33 = AU[2]; atom->u12 = AU[3]; atom->u13 = AU[4]; atom->u23 = AU[5]; atom->WhatIsSet |= mmdb::ASET_tempFactor | mmdb::ASET_Anis_tFac; } else { *BIso = U[0]; atom->tempFactor = *BIso; atom->u11 = 0.0; atom->u22 = 0.0; atom->u33 = 0.0; atom->u12 = 0.0; atom->u13 = 0.0; atom->u23 = 0.0; atom->WhatIsSet |= mmdb::ASET_tempFactor; } // store occupancy now atom->occupancy = *occ; atom->WhatIsSet |= mmdb::ASET_Occupancy; } } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_SETCELL, mmdb_f_setcell, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::apireal * a, // cell parameter a, angstroms mmdb::machine::apireal * b, // cell parameter b, angstroms mmdb::machine::apireal * c, // cell parameter c, angstroms mmdb::machine::apireal * alpha, // cell parameter alpha, degrees mmdb::machine::apireal * beta, // cell parameter beta, degrees mmdb::machine::apireal * gamma, // cell parameter gamma, degrees int * ArgNCode, // orthogonalization code, 1-6 int * iRet // return code: // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // RWBERR_Disagreement if a // disagreement in // cell parameters // was found // RWBERR_NoOrthCode if no // orthogonalization // code was found // RWBERR_NoCheck if check // of cell parameters // has failed. // The last three returns would // rather indicate a programming // error in mmdb_rwbrook.cpp ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * a, mmdb::machine::apireal * b, mmdb::machine::apireal * c, mmdb::machine::apireal * alpha, mmdb::machine::apireal * beta, mmdb::machine::apireal * gamma, int * ArgNCode, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * a, mmdb::machine::apireal * b, mmdb::machine::apireal * c, mmdb::machine::apireal * alpha, mmdb::machine::apireal * beta, mmdb::machine::apireal * gamma, int * ArgNCode, int * iRet ) ) { int k; strcpy ( LastFunc,"MMDB_F_SetCell" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) *iRet = RWBERR_NoChannel; else *iRet = channel[k]->SetCell ( *a,*b,*c,*alpha,*beta,*gamma, *ArgNCode ); LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_WBSPGRP, mmdb_f_wbspgrp, ( // lengths-at-end list int * iUnit, // unit number; *iUnit<=0 means // "the last mentioned unit" mmdb::machine::fpstr spGroup, // space group int * iRet, // return code: // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed int spGroup_len // fortran-hidden length of spGroup ), ( // lengths-in-structure list int * iUnit, mmdb::machine::fpstr spGroup, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::fpstr spGroup, int spGroup_len, int * iRet ) ) { int k; mmdb::SymGroup spaceGroup; strcpy ( LastFunc,"MMDB_F_WBSpGrp" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) *iRet = RWBERR_NoChannel; else { // GetStrTer ( spaceGroup,FTN_STR(spGroup),0, // sizeof(spaceGroup),FTN_LEN(spGroup) ); mmdb::strcpy_ncss(spaceGroup,FTN_STR(spGroup),mmdb::IMin(FTN_LEN(spGroup), sizeof(spaceGroup)-1) ); *iRet = channel[k]->SetSpGroup ( spaceGroup ); } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_RBSPGRP, mmdb_f_rbspgrp, ( // lengths-at-end list int * iUnit, // unit number; *iUnit<=0 means // "the last mentioned unit" mmdb::machine::fpstr spGroup, // space group int * iRet, // return code: // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed int spGroup_len // fortran-hidden length of spGroup ), ( // lengths-in-structure list int * iUnit, mmdb::machine::fpstr spGroup, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::fpstr spGroup, int spGroup_len, int * iRet ) ) { int k; char SpaceGroup[100]; strcpy ( LastFunc,"MMDB_F_RBSpGrp" ); if (*iUnit>0) LastUnit = *iUnit; SpaceGroup[0] = char(0); k = GetChannel ( LastUnit ); if (k<0) *iRet = RWBERR_NoChannel; else *iRet = channel[k]->GetSpGroup ( SpaceGroup ); // all extra "superficial spaces" are killed in the following mmdb::CutSpaces ( SpaceGroup,mmdb::SCUTKEY_BEGEND ); mmdb::strcpy_ns ( FTN_STR(spGroup),SpaceGroup,FTN_LEN(spGroup) ); LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_WBCELL , mmdb_f_wbcell, ( // lengths-at-end list int * iUnit, // unit number; *iUnit<=0 means // "the last mentioned unit" mmdb::machine::apireal * ArgCell, // array to accept the cell parameters // if ArgCell(1) is set to 0, then // the cell does not change int * ArgNCode, // orthogonalisation code // if ArgNCode is set to 0, then // the orthogonalisation matrices // do not change int * iRet // return code // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * ArgCell, int * ArgNCode, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * ArgCell, int * ArgNCode, int * iRet ) ) { int k; strcpy ( LastFunc,"MMDB_F_WBCell" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) *iRet = RWBERR_NoChannel; else *iRet = channel[k]->PutCell ( ArgCell[0],ArgCell[1],ArgCell[2], ArgCell[3],ArgCell[4],ArgCell[5], *ArgNCode ); LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_RBCELL, mmdb_f_rbcell, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::apireal * celld, // array to accept the cell parameters mmdb::machine::apireal * cvol, // returns the cell volume int * iRet // return code // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // RWBERR_Parameters if the // cell parameters // were not set // RWBERR_NoOrthCode if no // orthogonalization // code was found // RWBERR_NoCheck if check // of cell parameters // has failed. // The last three returns would // rather indicate a programming // error in mmdb_rwbrook.cpp ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * celld, mmdb::machine::apireal * cvol, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * celld, mmdb::machine::apireal * cvol, int * iRet ) ) { mmdb::realtype p[6]; mmdb::realtype v; int k,i,nc; strcpy ( LastFunc,"MMDB_F_RBCell" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } *iRet = channel[k]->GetCell ( p[0],p[1],p[2],p[3],p[4],p[5],v,nc ); if (*iRet==RWBERR_Ok) { for (i=0;i<6;i++) celld[i] = (mmdb::machine::apireal)p[i]; *cvol = (mmdb::machine::apireal)v; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_RBCELLN, mmdb_f_rbcelln, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::apireal * celld, // array to accept the cell parameters mmdb::machine::apireal * cvol, // returns the cell volume int * ArgNCode, // returns the orthogonalization code, 1-6 int * iRet // return code // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // RWBERR_Parameters if the // cell parameters // were not set // RWBERR_NoOrthCode if no // orthogonalization // code was found // RWBERR_NoCheck if check // of cell parameters // has failed. // The last three returns would // rather indicate a programming // error in mmdb_rwbrook.cpp ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * celld, mmdb::machine::apireal * cvol, int * ArgNCode, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * celld, mmdb::machine::apireal * cvol, int * ArgNCode, int * iRet ) ) { mmdb::realtype p[6]; mmdb::realtype v; int k,i,nc; strcpy ( LastFunc,"MMDB_F_RBCellN" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } *iRet = channel[k]->GetCell ( p[0],p[1],p[2],p[3],p[4],p[5],v,nc ); if (*iRet==RWBERR_Ok) { for (i=0;i<6;i++) celld[i] = (mmdb::machine::apireal)p[i]; *cvol = (mmdb::machine::apireal)v; *ArgNCode = nc; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_RBRCEL, mmdb_f_rbrcel, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::apireal * rcell, // array to accept the reciprocal // cell parameters mmdb::machine::apireal * rvol, // returns the reciprocal cell volume int * iRet // return code // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // RWBERR_Parameters if the // cell parameters // were not set // RWBERR_NoOrthCode if no // orthogonalization // code was found // RWBERR_NoCheck if check // of cell parameters // has failed. // The last three returns would // rather indicate a programming // error in mmdb_rwbrook.cpp ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * rcell, mmdb::machine::apireal * rvol, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * rcell, mmdb::machine::apireal * rvol, int * iRet ) ) { mmdb::realtype p[6]; mmdb::realtype v; int k,i; strcpy ( LastFunc,"MMDB_F_RBRCel" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } *iRet = channel[k]->GetRCell ( p[0],p[1],p[2],p[3],p[4],p[5],v ); if (*iRet==RWBERR_Ok) { for (i=0;i<6;i++) rcell[i] = (mmdb::machine::apireal)p[i]; *rvol = (mmdb::machine::apireal)v; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_RBORF, mmdb_f_rborf, ( // lengths-at-end list int * iUnit, // unit number mmdb::machine::apireal * RO, // array for orthogonalising matrix mmdb::machine::apireal * RF, // array for fractionalising matrix int * LCode, // buffer for orthogonalisation code int * iRet // return code: // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // RWBERR_NoMatrices if the // orthogonalisation // matrices were not // calculated ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * RO, mmdb::machine::apireal * RF, int * LCode, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * RO, mmdb::machine::apireal * RF, int * LCode, int * iRet ) ) { int i,j,k,l; mmdb::PCryst Cryst; strcpy ( LastFunc,"MMDB_F_RBORF" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } Cryst = channel[k]->GetCryst(); if (Cryst==NULL) { *iRet = RWBERR_NoFile; LastRC = *iRet; return; } *iRet = RWBERR_Ok; l = 0; if (RO[0]<=0.0000000001) { for (j=0;j<4;j++) for (i=0;i<4;i++) { RF[l] = (mmdb::machine::apireal)Cryst->RF[i][j]; RO[l] = (mmdb::machine::apireal)Cryst->RO[i][j]; l++; } *LCode = Cryst->NCode; if (!(Cryst->WhatIsSet & mmdb::CSET_Transforms)) *iRet = RWBERR_NoMatrices; } else { for (j=0;j<4;j++) for (i=0;i<4;i++) { Cryst->RF[i][j] = RF[l]; Cryst->RO[i][j] = RO[l]; l++; } Cryst->NCode = *LCode; Cryst->WhatIsSet |= mmdb::CSET_Transforms; } LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_ORTHMAT, mmdb_f_orthmat, ( // lengths-at-end list int * iUnit, // unit number; *iUnit<=0 means // "the last mentioned unit" mmdb::machine::apireal * Cell, // array of cell parameters: // Cell(1) - a Cell(4) - alpha // Cell(2) - b Cell(5) - beta // Cell(3) - c Cell(6) - gamma mmdb::machine::apireal * Vol, // returns cell volume mmdb::machine::apireal * RRR, // array (3,3,6), returns // orthogonalisation matrices int * iRet // return code: // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // RWBERR_NoMatrices if the // orthogonalisation // matrices were not // calculated ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * Cell, mmdb::machine::apireal * Vol, mmdb::machine::apireal * RRR, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * Cell, mmdb::machine::apireal * Vol, mmdb::machine::apireal * RRR, int * iRet ) ) { int i,j,k,l,m; mmdb::PCryst Cryst; mmdb::realtype CelDel; strcpy ( LastFunc,"MMDB_F_OrthMat" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } Cryst = channel[k]->GetCryst(); if (Cryst==NULL) { *iRet = RWBERR_NoFile; LastRC = *iRet; return; } CelDel = 0.0; if (Cell[0]>0.0) { if ((Cryst->WhatIsSet & mmdb::CSET_CellParams)==mmdb::CSET_CellParams) { CelDel = fabs((Cell[0]-Cryst->a)/Cell[0]); if (Cell[1]!=0.0) CelDel = mmdb::RMax(CelDel,fabs((Cell[1]-Cryst->b)/Cell[1])); if (Cell[2]!=0.0) CelDel = mmdb::RMax(CelDel,fabs((Cell[2]-Cryst->c)/Cell[2])); if (Cell[3]!=0.0) CelDel = mmdb::RMax(CelDel,fabs((Cell[3]-Cryst->alpha)/Cell[3])); if (Cell[4]!=0.0) CelDel = mmdb::RMax(CelDel,fabs((Cell[4]-Cryst->beta )/Cell[4])); if (Cell[5]!=0.0) CelDel = mmdb::RMax(CelDel,fabs((Cell[5]-Cryst->gamma)/Cell[5])); if (FSimRWBROOK && (CelDel>0.01)) printf ( "\n Inconsistency in Cell Dimensions" " - replacing old:\n" " Old cell: " "%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f\n" " New cell: " "%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f\n", Cryst->a,Cryst->b,Cryst->c, Cryst->alpha,Cryst->beta,Cryst->gamma, Cell[0],Cell[1],Cell[2],Cell[3],Cell[4],Cell[5] ); } Cryst->a = Cell[0]; Cryst->b = Cell[1]; Cryst->c = Cell[2]; Cryst->alpha = Cell[3]; Cryst->beta = Cell[4]; Cryst->gamma = Cell[5]; Cryst->WhatIsSet |= mmdb::CSET_CellParams; } else { Cell[0] = (mmdb::machine::apireal)Cryst->a; Cell[1] = (mmdb::machine::apireal)Cryst->b; Cell[2] = (mmdb::machine::apireal)Cryst->c; Cell[3] = (mmdb::machine::apireal)Cryst->alpha; Cell[4] = (mmdb::machine::apireal)Cryst->beta; Cell[5] = (mmdb::machine::apireal)Cryst->gamma; } if ((Cryst->WhatIsSet & mmdb::CSET_CellParams)!=mmdb::CSET_CellParams) { *iRet = RWBERR_NoCellParams; LastRC = *iRet; return; } *iRet = RWBERR_Ok; // Cryst->CalcOrthMatrices(); <-- old version, changed 09.01.2004 Cryst->CalcCoordTransforms(); Cryst->WhatIsSet |= mmdb::CSET_Transforms; if (CelDel>0.01) *Vol = -(mmdb::machine::apireal)Cryst->Vol; else *Vol = (mmdb::machine::apireal)Cryst->Vol; l = 0; for (j=0;j<3;j++) for (i=0;i<3;i++) for (m=0;m<6;m++) RRR[l++] = (mmdb::machine::apireal)Cryst->RR[m][j][i]; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_CVANISOU, mmdb_f_cvanisou, ( // lengths-at-end list int * iUnit, // unit number; *iUnit<=0 means // "the last mentioned unit" mmdb::machine::apireal * U, // array of coordinates to convert int * iFlag, // =0: convert from fract. to orthog. // =1: convert from orthog. to fract. int * iRet // return code: // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // RWBERR_NoMatrices if the // orthogonalisation // matrices were not // calculated ), ( // lengths-in-structure list int * iUnit, mmdb::machine::apireal * U, int * iFlag, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::apireal * U, int * iFlag, int * iRet ) ) { int k,i; mmdb::PCryst Cryst; mmdb::realtype U1[6]; strcpy ( LastFunc,"MMDB_F_CVAnisou" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } Cryst = channel[k]->GetCryst(); if (Cryst==NULL) { *iRet = RWBERR_NoFile; LastRC = *iRet; return; } *iRet = RWBERR_Ok; for (i=0;i<6;i++) U1[i] = U[i]; if (iFlag==0) { if (!Cryst->Cryst2Orth(U1)) *iRet = RWBERR_NoMatrices; } else { if (!Cryst->Orth2Cryst(U1)) *iRet = RWBERR_NoMatrices; } if (*iRet==RWBERR_Ok) for (i=0;i<6;i++) U[i] = (mmdb::machine::apireal)U1[i]; LastRC = *iRet; } FORTRAN_SUBR ( MMDB_F_WREMARK, mmdb_f_wremark, ( // lengths-at-end list int * iUnit, // unit number; *iUnit<=0 means // "the last mentioned unit" mmdb::machine::fpstr Line, // line to be added int * iRet, // return code: // RWBERR_Ok - success // RWBERR_NoChannel if unit // iUnit was not // initialized // RWBERR_NoFile if unit // has been disposed // other return codea are those // returned by xyzopen1_(..) int Line_len // fortran-hidden length of Line ), ( // lengths-in-structure list int * iUnit, mmdb::machine::fpstr Line, int * iRet ), ( // lengths-follow list int * iUnit, mmdb::machine::fpstr Line, int Line_len, int *iRet ) ) { int k; char S[500]; strcpy ( LastFunc,"MMDB_F_WRemark" ); if (*iUnit>0) LastUnit = *iUnit; k = GetChannel ( LastUnit ); if (k<0) { *iRet = RWBERR_NoChannel; LastRC = *iRet; return; } if (channel[k]->MMDBManager) { mmdb::GetStrTer ( S,FTN_STR(Line),FTN_LEN(Line),sizeof(S),FTN_LEN(Line) ); *iRet = channel[k]->MMDBManager->PutPDBString ( S ); } else *iRet = RWBERR_NoFile; LastRC = *iRet; } /* FORTRAN_SUBR ( RBRINV, rbrinv, ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ), ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ), ( mmdb::machine::apireal * A, mmdb::machine::apireal * AI ) ) { mat44 A1,AI1; int i,j,k; k = 0; for (j=0;j<4;j++) for (i=0;i<4;i++) A1[j][i] = A[k++]; Mat4Inverse ( A1,AI1 ); k = 0; for (j=0;j<4;j++) for (i=0;i<4;i++) AI[k++] = AI1[j][i]; } */ /* FORTRAN_SUBR ( RES3TO1, res3to1, ( // lengths-at-end list mmdb::machine::fpstr ResNm3, // 3-char name, 4th char // will be set blank mmdb::machine::fpstr ResNm1, // 1-char name int ResNm3_len, // fortran-hidden length of ResNm3 int ResNm1_len // fortran-hidden length of ResNm3 ), ( // lengths-in-structure list mmdb::machine::fpstr ResNm3, mmdb::machine::fpstr ResNm1 ), ( // lengths-follow list mmdb::machine::fpstr ResNm3, int ResNm3_len, mmdb::machine::fpstr ResNm1, int ResNm1_len ) ) { int i; if (FTN_STR(ResNm3)[0]==' ') { for (i=0;i=0) printf ( " *** file : %s\n",channel[k]->FName ); for (i=0;i0) printf ( " *** position %i, serial number %i\n", channel[k]->fPos,LastSer ); else printf ( " *** position unavailable, serial number %i\n", LastSer ); } } if (!Msg) printf ( " *** warning: unknown warning code" ); return; } else Msg = MSG_Unknown; } if ((k>=0) && ( ((*iRet<=RWBERR_WrongInteger) && (*iRet>=RWBERR_DuplicatedModel)) || ((*iRet<=RWBERR_ATOM_Unrecognd) && (*iRet>=RWBERR_ATOM_Unmatch)) || ((*iRet<=RWBERR_NoData) && (*iRet>=RWBERR_DuplicateSeqNum)) )) channel[k]->GetInputBuffer ( ErrLine,lcount ); printf ( " \n *** RWBROOK error: point code unit function\n" ); printf ( " *** %5i %4i %4i %s\n",*iPlace,*iRet, *iUnit,LastFunc ); k = GetChannel(*iUnit); if (k>=0) printf ( " *** file : %s\n",channel[k]->FName ); printf ( " *** reason : %s\n",Msg ); if (lcount>=0) printf ( " *** at input line #%i:\n" " %s\n",lcount,ErrLine ); else if (lcount==-1) printf ( " *** at taking the following data from CIF:\n" " %s\n",ErrLine ); if (*iStop==0) { // will stop it printf ( " *** Execution stopped.\n \n" ); FORTRAN_CALL ( MMDB_F_QUIT, mmdb_f_quit,(),(),() ); // xyzquit_(); exit(0); } else // just warn, but no guarantee that it will not crash printf ( " *** continue running, may crash ...\n \n" ); } FORTRAN_SUBR ( RBCHECKERR, rbcheckerr, ( // lengths-at-end list int * iPlace, // (unique) identificator inside an application int * iStop // if 0 then stop if error ), ( // lengths-in-structure list int * iPlace, int * iStop ), ( // lengths-follow list int * iPlace, int * iStop ) ) { FORTRAN_CALL ( RBERRSTOP, rberrstop, ( iPlace,&LastRC,&LastUnit,iStop ), ( iPlace,&LastRC,&LastUnit,iStop ), ( iPlace,&LastRC,&LastUnit,iStop ) ); } /* hybrid-36 encoder: converts integer value to string result iwidth: must be 4 (e.g. for residue sequence numbers) or 5 (e.g. for atom serial numbers) value: integer value to be converted strval: char array containing string result */ FORTRAN_SUBR ( HY36ENCODE_F, hy36encode_f, (const int *iwidth, int *value, mmdb::machine::fpstr strval, int strval_len), (const int *iwidth, int *value, mmdb::machine::fpstr strval), (const int *iwidth, int *value, mmdb::machine::fpstr strval, int strval_len)) { unsigned width; char result[6]; width = (unsigned) *iwidth; if (hy36encode(width, *value, result)) { printf("problem in hy36encode_f! \n"); } mmdb::strcpy_ns(FTN_STR(strval),result,FTN_LEN(strval)); } /* hybrid-36 decoder: converts string s to integer result iwidth: must be 4 (e.g. for residue sequence numbers) or 5 (e.g. for atom serial numbers) strval: string to be converted value: integer holding the conversion result */ FORTRAN_SUBR ( HY36DECODE_F, hy36decode_f, (const int *iwidth, mmdb::machine::fpstr strval, int *value, int strval_len), (const int *iwidth, mmdb::machine::fpstr strval, int *value), (const int *iwidth, mmdb::machine::fpstr strval, int strval_len, int *value)) { UNUSED_ARGUMENT(strval); unsigned width; size_t length = FTN_LEN(strval); char* s; width = (unsigned) *iwidth; s = (char *) malloc((length+1)*sizeof(char)); s[length] = '\0'; if (hy36decode(width, s, width, value)) { printf("problem in hy36decode_f! \n"); } }