1 // $Id: superpose.cpp $
2 //  =================================================================
3 //
4 //   SUPERPOSE: Protein structure superposition based on SSM
5 //   algorithm. Please cite:
6 //
7 //   For pairwise alignment:
8 //     E. Krissinel & K. Henrick (2004) Acta Cryst. D60, 2256-2268.
9 //
10 //   For multiple alignment:
11 //     Krissinel, E. and Henrick, K.
12 //     Multiple Alignment of Protein Structures in Three Dimensions.
13 //     Computational Life Sciences, First International Symposium,
14 //     CompLife 2005, Konstanz, Germany, September 25-27, 2005, 67-78.
15 //     Proceedings Editors: Michael R. Berthold, Robert C. Glen,
16 //     Kay Diederichs, Oliver Kohlbacher, Ingrid Fischer.
17 //     ISBN: 978-3-540-29104-6 (Print) 978-3-540-31726-5
18 //
19 //   Copyright (C) Eugene Krissinel 2002-2013.
20 //
21 //   This library is free software: you can redistribute it and/or
22 //   modify it under the terms of the GNU Lesser General Public
23 //   License version 3, modified in accordance with the provisions
24 //   of the license to address the requirements of UK law.
25 //
26 //   You should have received a copy of the modified GNU Lesser
27 //   General Public License along with this library. If not, copies
28 //   may be downloaded from http://www.ccp4.ac.uk/ccp4license.php
29 //
30 //   This program is distributed in the hope that it will be useful,
31 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
32 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33 //   GNU Lesser General Public License for more details.
34 //
35 // =================================================================
36 //
37 //    18.09.13   <--  Date of Last Modification.
38 //                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39 //  ----------------------------------------------------------------
40 //
41 //  **** Module  :  Superpose <implementation>
42 //       ~~~~~~~~~
43 //  **** Project :  SUPERPOSE
44 //       ~~~~~~~~~
45 //  **** Functions:  main
46 //       ~~~~~~~~~~  printInstructions
47 //                   readCoorFile
48 //
49 //  E. Krissinel, 2003-2013
50 //
51 // =================================================================
52 //
53 
54 #include <string.h>
55 
56 #include "ssm/ssm_align.h"
57 #include "sup_pairwise.h"
58 #include "sup_multiple.h"
59 #include "sup_defs.h"
60 
61 #ifdef _ccp4_
62 
63 #include "ccp4/ccp4_parser.h"
64 #include "ccp4/ccp4_general.h"
65 #include "ccp4/ccp4_program.h"
66 
67 using namespace CCP4;
68 
69 #endif
70 
71 
72 #ifdef _emulate_ccp4_
73 
ccp4ProgramName(cpstr)74 void ccp4ProgramName ( cpstr ) {}
75 
ccp4_banner()76 void ccp4_banner() {
77 printf (
78 "<B><FONT COLOR=\"#FF0000\"><!--SUMMARY_BEGIN-->\n"
79 "<html> <!-- CCP4 HTML LOGFILE -->\n"
80 "<hr>\n"
81 "<!--SUMMARY_END--></FONT></B>\n"
82 "<B><FONT COLOR=\"#FF0000\"><!--SUMMARY_BEGIN-->\n"
83 "<pre>\n"
84 "\n"
85 " ###############################################################\n"
86 " ###############################################################\n"
87 " ###############################################################\n"
88 " ### CCP4 6.3: SUPERPOSE                version 6.3 :         ##\n"
89 " ###############################################################\n"
90 " User: Eugene  Run date: 21/10/2012 Run time: 06:53:30 \n"
91 "\n"
92 "\n"
93 " Please reference: Collaborative Computational Project, Number 4. 1994.\n"
94 " \"The CCP4 Suite: Programs for Protein Crystallography\". Acta Cryst. D50, 760-763.\n"
95 " as well as any specific reference in the program write-up.\n"
96 "\n"
97 "<!--SUMMARY_END--></FONT></B>\n"
98 "\n" );
99 }
100 
ccperror(int,cpstr)101 void ccperror ( int, cpstr ) {}
102 
103 #define _ccp4_
104 
105 #endif
106 
107 
printInstructions(char * argv0)108 void printInstructions ( char *argv0 )  {
109 
110   printf (
111     "\n"
112 #ifdef _ccp4_
113     "$TEXT:Warning: $$ Wrong or no input $$\n"
114 #endif
115     " Protein Structure Superposition\n"
116     " -------------------------------\n"
117     " v." superpose_version " from " superpose_date " built with SSM v.%i.%i.%i, "
118     "MMDB v.%i.%i.%i\n"
119     "\n"
120     " USAGE:\n"
121     "\n"
122     " %s q.pdb [-s CIDQ] t1.pdb [-s CID1] ... tN.pdb [-s CIDN] [-o foo_out.pdb]\n"
123     "\n"
124     " where  q.pdb  is the Query structure to which transformation applied,\n"
125     "        ti.pdb is the ith fixed Target structure,\n"
126     "        [-s CIDi] are optional selection strings in MMDB convention, and\n"
127     "        [-o foo_out.pdb] is optional output file specification.\n"
128     " If more than one target is specified, multiple structure alignment\n"
129     " is calculated.\n"
130     "   Instead of using asterisks '*' for selecting all atoms, '-all'\n"
131     " may be used, such that\n"
132     "\n"
133     " %s q.pdb -s * t.pdb -s * foo_out.pdb\n"
134     "\n"
135     " and \n"
136     "\n"
137     " %s q.pdb -s -all t.pdb -s -all foo_out.pdb\n"
138     "\n"
139     " are equivalent.\n"
140 #ifdef _ccp4_
141     "$$\n"
142 #endif
143     ,ssm::MAJOR_VERSION,ssm::MINOR_VERSION,ssm::MICRO_VERSION,
144      mmdb::MAJOR_VERSION,mmdb::MINOR_VERSION,mmdb::MICRO_VERSION,
145      argv0,argv0,argv0
146    );
147 
148 }
149 
150 
readCoorFile(mmdb::pstr FName,mmdb::RPManager MMDB)151 int  readCoorFile ( mmdb::pstr FName, mmdb::RPManager MMDB )  {
152 char              S[500];
153 int               lcount;
154 mmdb::ERROR_CODE  rc;
155 
156   if (!MMDB)  MMDB = new mmdb::Manager();
157 
158   MMDB->SetFlag ( mmdb::MMDBF_PrintCIFWarnings       |
159                   mmdb::MMDBF_IgnoreNonCoorPDBErrors |
160                   mmdb::MMDBF_IgnoreDuplSeqNum );
161 
162   rc = MMDB->ReadCoorFile ( FName );
163   MMDB->PDBCleanup ( mmdb::PDBCLEAN_ELEMENT_STRONG );
164 
165   if (rc) {
166     printf ( " ***** ERROR #%i READ:\n\n %s\n\n",
167              rc,mmdb::GetErrorDescription(rc) );
168     MMDB->GetInputBuffer ( S,lcount );
169     if (lcount>=0)
170       printf ( "       LINE #%i:\n%s\n\n",lcount,S );
171     else if (lcount==-1)
172       printf ( "       CIF ITEM: %s\n\n",S );
173     delete MMDB;
174     MMDB = NULL;
175     return 1;
176   } else  {
177     switch (MMDB->GetFileType())  {
178       case mmdb::MMDB_FILE_PDB    : printf ( " PDB"         );  break;
179       case mmdb::MMDB_FILE_CIF    : printf ( " mmCIF"       );  break;
180       case mmdb::MMDB_FILE_Binary : printf ( " MMDB binary" );  break;
181       default : printf ( " Unknown (report as a bug!)" );
182     }
183     printf ( " file %s has been read in.\n",FName );
184   }
185 
186   return 0;
187 
188 }
189 
selectAtoms(mmdb::PManager M,char ** argv,int & argNo,mmdb::pstr & sel,int & selHnd)190 int selectAtoms ( mmdb::PManager M, char ** argv, int & argNo,
191                   mmdb::pstr & sel, int & selHnd )  {
192 int  nSel;
193 
194   selHnd = 0;
195   sel    = NULL;
196 
197   if (!strcasecmp(argv[argNo],"-s"))  {
198     argNo++;
199     mmdb::CreateCopy ( sel,argv[argNo] );
200     if (!strcmp(sel,"-all"))
201       mmdb::CreateCopy ( sel,"*" );
202     selHnd = M->NewSelection();
203     M->Select ( selHnd,mmdb::STYPE_ATOM,sel,mmdb::SKEY_NEW );
204     nSel = M->GetSelLength ( selHnd );
205     if (nSel<=0)  {
206       printf ( " *** Selection string '%s' does not cover "
207                "any atoms.\n",argv[argNo] );
208       return 1;
209     }
210     printf ( " ... %i atoms selected using CID '%s'\n",
211              nSel,argv[argNo] );
212     argNo++;
213   } else
214     mmdb::CreateCopy ( sel,"*" );
215 
216   return 0;
217 
218 }
219 
220 
221 /*
222 void CrystReadyState ( PCMMDBManager M, pstr S )  {
223 int CRRDY = M->CrystReady();
224 
225   S[0] = char(0);
226 
227   if (CRRDY==CRRDY_Complete)
228     strcpy ( S,"Complete" );
229   if (CRRDY==CRRDY_NoTransfMatrices)
230     strcpy ( S,"No transormation matrices" );
231   if (CRRDY==CRRDY_Unchecked)
232     strcpy ( S,"Unchecked" );
233   if (CRRDY==CRRDY_Ambiguous)
234     strcpy ( S,"Ambiguous" );
235   if (CRRDY==CRRDY_NoCell)
236     strcpy ( S,"No cell" );
237   if (CRRDY==CRRDY_NoSpaceGroup)
238     strcpy ( S,"No space group" );
239 
240   if (!S[0])  {
241 
242     if (CRRDY<0)
243       sprintf ( S,"Unknown code %i",CRRDY );
244     else  {
245       if (CRRDY & CRRDY_NotPrecise)
246         strcat ( S,"Not precise;" );
247       if (CRRDY & CRRDY_isTranslation)
248         strcat ( S,"Has translation;" );
249       if (CRRDY & CRRDY_NoOrthCode)
250         strcat ( S,"No orthogonalisation code;" );
251     }
252 
253   }
254 
255 }
256 */
257 
main(int argc,char ** argv,char ** env)258 int main ( int argc, char ** argv, char ** env )  {
259 UNUSED_ARGUMENT(env);
260 mmdb::PPManager M;
261 mmdb::psvector  name;
262 mmdb::psvector  selstring;
263 mmdb::pstr      fileout;
264 mmdb::ivector   selHnd;
265 int             argNo,i,nStructures,rc;
266 
267 #ifdef _ccp4_
268   ccp4ProgramName ( "SUPERPOSE" );
269   ccp4_banner();
270 #endif
271 
272   if (argc<=1)  {
273 #ifdef _ccp4_
274     printf ( "<!--SUMMARY_BEGIN-->\n" );
275 #endif
276     printInstructions ( argv[0] );
277 #ifdef _ccp4_
278     printf ( "<!--SUMMARY_END-->\n" );
279     ccperror ( 1,"No input" );
280 #endif
281     return 1;
282   }
283 
284 #ifdef _ccp4_
285   printf ( "<!--SUMMARY_BEGIN-->\n" );
286 #endif
287   if ((!strcmp(argv[1],"-?")) || (!strcasecmp(argv[1],"-help")) ||
288       (!strcasecmp(argv[1],"--help")))  {
289     printInstructions ( argv[0] );
290 #ifdef _ccp4_
291     printf ( "<!--SUMMARY_END-->\n" );
292     ccperror ( 2,"Wrong input" );
293 #endif
294     return 2;
295   }
296 
297   printf ( "\n"
298     " Superpose v." superpose_version " from " superpose_date " "
299                                         "(based on SSM algorithm)\n"
300     " ---------------------------------------------------------\n\n"
301    );
302 
303   mmdb::InitMatType();
304   ssm::InitGraph();
305 
306   printf (
307   " ================================================================\n"
308          );
309 
310   M = new mmdb::PManager[argc];
311   mmdb::GetVectorMemory ( name     ,argc,0 );
312   mmdb::GetVectorMemory ( selstring,argc,0 );
313   mmdb::GetVectorMemory ( selHnd   ,argc,0 );
314   for (i=0;i<argc;i++)  {
315     M        [i] = NULL;
316     name     [i] = NULL;
317     selstring[i] = NULL;
318     selHnd   [i] = 0;
319   }
320   fileout     = NULL;
321   nStructures = 0;
322 
323   argNo = 1;
324   rc    = 0;
325   while ((argNo<argc) && (!rc))  {
326     if (!strcasecmp(argv[argNo],"-o"))  {
327       argNo++;
328       if (argNo<argc)
329         mmdb::CreateCopy ( fileout,argv[argNo++] );
330     } else  {
331       mmdb::CreateCopy ( name[nStructures],argv[argNo] );
332       if (readCoorFile(argv[argNo++],M[nStructures]))
333         rc = 3;
334       else if (argNo<argc)  {
335         if (selectAtoms(M[nStructures],argv,argNo,
336                 selstring[nStructures],selHnd[nStructures]))
337           rc = 4;
338       } else
339         mmdb::CreateCopy ( selstring[nStructures],"*" );
340       nStructures++;
341     }
342   }
343 
344   if (!rc)  {
345 
346     printf (
347   " ================================================================\n"
348       "\n" );
349 
350 #ifdef _ccp4_
351     printf ( "<!--SUMMARY_END-->\n" );
352 #endif
353 
354     if (nStructures<2)  {
355       printf ( " *** too few structures on input (%i).\n",nStructures );
356 #ifdef _ccp4_
357       ccperror ( rc,"Wrong input" );
358 #endif
359     } else if (nStructures==2)
360       rc = pairwise_superposition ( M,name,selHnd,fileout );
361     else
362       rc = multiple_superposition ( M,selstring,name,selHnd,
363                                     nStructures,fileout );
364 
365   }
366 #ifdef _ccp4_
367     else  {
368       printf ( "<!--SUMMARY_END-->\n" );
369       ccperror ( rc,"Wrong input" );
370   }
371 #endif
372 
373   for (i=0;i<argc;i++)  {
374     if (M[i])          delete   M[i];
375     if (selstring[i])  delete[] selstring[i];
376     if (name[i])       delete[] name[i];
377   }
378   delete[] M;
379   mmdb::FreeVectorMemory ( selstring,0 );
380   mmdb::FreeVectorMemory ( name     ,0 );
381   mmdb::FreeVectorMemory ( selHnd   ,0 );
382   if (fileout)  delete[] fileout;
383 
384 #ifdef _ccp4_
385   if (nStructures<=2)
386     printf ( "$TEXT:Reference: $$Please cite$$\n"
387     " E. Krissinel and K. Henrick (2004). Secondary-structure matching (SSM),\n"
388     " a new tool for fast protein structure alignment in three dimensions.\n"
389     " Acta Cryst. D60, 2256-2268.\n"
390     "<a href=\"http://www.ebi.ac.uk/msd-srv/ssm/papers/ssm_reprint.pdf\">"
391     "PDF</a>\n$$\n" );
392   else
393     printf ( "$TEXT:Reference: $$Please cite$$\n"
394     " E. Krissinel and K. Henrick (2005). Multiple Alignment of Protein\n"
395     " Structures in Three Dimensions. In: M.R. Berthold et.al. (Eds.):\n"
396     " CompLife 2005, LNBI 3695, 67-78. Springer-Verlag Berlin Heidelberg.\n"
397     "<a href=\"http://www.ebi.ac.uk/msd-srv/ssm/papers/ssm-ma.pdf\">"
398     "PDF</a>\n$$\n" );
399   ccperror ( 0,"Normal termination" );
400 #else
401   printf ( "\n"
402   " ----------------------------------------------------------------\n"
403     "\n"
404     " Please cite:\n" );
405   if (nStructures<=2)
406     printf (
407     " E. Krissinel and K. Henrick (2004). Secondary-structure matching (SSM),\n"
408     " a new tool for fast protein structure alignment in three dimensions.\n"
409     " Acta Cryst. D60, 2256-2268.\n\n" );
410   else
411     printf (
412     " E. Krissinel and K. Henrick (2005). Multiple Alignment of Protein\n"
413     " Structures in Three Dimensions. In: M.R. Berthold et.al. (Eds.):\n"
414     " CompLife 2005, LNBI 3695, 67-78. Springer-Verlag Berlin Heidelberg.\n\n"
415            );
416 #endif
417 
418   return 0;
419 
420 }
421 
422