More selection unit tests for variables and fixes.
[alexxy/gromacs.git] / src / gromacs / gmxlib / copyrite.c
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  * 
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * GROningen Mixture of Alchemy and Childrens' Stories
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #ifdef GMX_THREAD_MPI
40 #include <thread_mpi.h>
41 #endif
42
43 /* This file is completely threadsafe - keep it that way! */
44
45 #include <string.h>
46 #include <ctype.h>
47 #include "sysstuff.h"
48 #include "smalloc.h"
49 #include "string2.h"
50 #include "macros.h"
51 #include <time.h>
52 #include "random.h"
53 #include "statutil.h"
54 #include "copyrite.h"
55 #include "strdb.h"
56 #include "futil.h"
57
58 static void pr_two(FILE *out,int c,int i)
59 {
60   if (i < 10)
61     fprintf(out,"%c0%1d",c,i);
62   else
63     fprintf(out,"%c%2d",c,i);
64 }
65
66 void pr_difftime(FILE *out,double dt)
67 {
68   int    ndays,nhours,nmins,nsecs;
69   gmx_bool   bPrint,bPrinted;
70
71   ndays = dt/(24*3600);
72   dt    = dt-24*3600*ndays;
73   nhours= dt/3600;
74   dt    = dt-3600*nhours;
75   nmins = dt/60;
76   dt    = dt-nmins*60;
77   nsecs = dt;
78   bPrint= (ndays > 0);
79   bPrinted=bPrint;
80   if (bPrint) 
81     fprintf(out,"%d",ndays);
82   bPrint=bPrint || (nhours > 0);
83   if (bPrint) {
84     if (bPrinted)
85       pr_two(out,'d',nhours);
86     else 
87       fprintf(out,"%d",nhours);
88   }
89   bPrinted=bPrinted || bPrint;
90   bPrint=bPrint || (nmins > 0);
91   if (bPrint) {
92     if (bPrinted)
93       pr_two(out,'h',nmins);
94     else 
95       fprintf(out,"%d",nmins);
96   }
97   bPrinted=bPrinted || bPrint;
98   if (bPrinted)
99     pr_two(out,':',nsecs);
100   else
101     fprintf(out,"%ds",nsecs);
102   fprintf(out,"\n");
103 }
104
105
106 gmx_bool be_cool(void)
107 {
108   /* Yes, it is bad to check the environment variable every call,
109    * but we dont call this routine often, and it avoids using 
110    * a mutex for locking the variable...
111    */
112 #ifdef GMX_FAHCORE
113   /*be uncool*/
114   return FALSE;
115 #else
116   return (getenv("GMX_NO_QUOTES") == NULL);
117 #endif
118 }
119
120 void space(FILE *out, int n)
121 {
122   fprintf(out,"%*s",n,"");
123 }
124
125 void f(char *a)
126 {
127     int i;
128     int len=strlen(a);
129     
130     for(i=0;i<len;i++)
131         a[i]=~a[i]; 
132 }
133
134 static void sp_print(FILE *out,const char *s)
135 {
136   int slen;
137   
138   slen=strlen(s);
139   space(out,(80-slen)/2);
140   fprintf(out,"%s\n",s);
141 }
142
143 static void ster_print(FILE *out,const char *s)
144 {
145   int  slen;
146   char buf[128];
147   
148   snprintf(buf,128,":-)  %s  (-:",s);
149   slen=strlen(buf);
150   space(out,(80-slen)/2);
151   fprintf(out,"%s\n",buf);
152 }
153
154
155 static void pukeit(const char *db,const char *defstring, char *retstring, 
156                    int retsize, int *cqnum)
157 {
158   FILE *fp;
159   char **help;
160   int  i,nhlp;
161   int  seed;
162  
163   if (be_cool() && ((fp = low_libopen(db,FALSE)) != NULL)) {
164     nhlp=fget_lines(fp,&help);
165     /* for libraries we can use the low-level close routines */
166     ffclose(fp);
167     seed=time(NULL);
168     *cqnum=nhlp*rando(&seed);
169     if (strlen(help[*cqnum]) >= STRLEN)
170       help[*cqnum][STRLEN-1] = '\0';
171     strncpy(retstring,help[*cqnum],retsize);
172     f(retstring);
173     for(i=0; (i<nhlp); i++)
174       sfree(help[i]);
175     sfree(help);
176   }
177   else 
178     strncpy(retstring,defstring,retsize);
179 }
180
181 void bromacs(char *retstring, int retsize)
182 {
183   int dum;
184
185   pukeit("bromacs.dat",
186          "Groningen Machine for Chemical Simulation",
187          retstring,retsize,&dum);
188 }
189
190 void cool_quote(char *retstring, int retsize, int *cqnum)
191 {
192   char *tmpstr;
193   char *s,*ptr;
194   int tmpcq,*p;
195   
196   if (cqnum!=NULL)
197     p = cqnum;
198   else
199     p = &tmpcq;
200   
201   /* protect audience from explicit lyrics */
202   snew(tmpstr,retsize+1);
203   pukeit("gurgle.dat","Thanx for Using GROMACS - Have a Nice Day",
204          tmpstr,retsize-2,p);
205
206   if ((ptr = strchr(tmpstr,'_')) != NULL) {
207     *ptr='\0';
208     ptr++;
209     sprintf(retstring,"\"%s\" %s",tmpstr,ptr);
210   }
211   else {
212     strcpy(retstring,tmpstr);
213   }
214   sfree(tmpstr);
215 }
216
217 void CopyRight(FILE *out,const char *szProgram)
218 {
219   static const char * CopyrightText[] = {
220              "Written by Emile Apol, Rossen Apostolov, Herman J.C. Berendsen,",
221              "Aldert van Buuren, Pär Bjelkmar, Rudi van Drunen, Anton Feenstra, ",
222              "Gerrit Groenhof, Peter Kasson, Per Larsson, Pieter Meulenhoff, ",
223              "Teemu Murtola, Szilard Pall, Sander Pronk, Roland Schulz, ",
224              "Michael Shirts, Alfons Sijbers, Peter Tieleman,\n",
225              "Berk Hess, David van der Spoel, and Erik Lindahl.\n",
226              "Copyright (c) 1991-2000, University of Groningen, The Netherlands.",
227              "Copyright (c) 2001-2010, The GROMACS development team at",
228              "Uppsala University & The Royal Institute of Technology, Sweden.",
229              "check out http://www.gromacs.org for more information.\n"
230   };
231
232   static const char * GPLText[] = {
233               "This program is free software; you can redistribute it and/or",
234               "modify it under the terms of the GNU General Public License",
235               "as published by the Free Software Foundation; either version 2",
236               "of the License, or (at your option) any later version."
237   };
238
239   /* Dont change szProgram arbitrarily - it must be argv[0], i.e. the 
240    * name of a file. Otherwise, we won't be able to find the library dir.
241    */
242 #define NCR (int)asize(CopyrightText)
243 #ifdef GMX_FAHCORE
244 #define NGPL 0 /*FAH has an exception permission from GPL to allow digital signatures in Gromacs*/
245 #else
246 #define NGPL (int)asize(GPLText)
247 #endif
248
249   char buf[256],tmpstr[1024];
250   int i;
251
252 #ifdef GMX_FAHCORE
253   set_program_name("Gromacs");
254 #else
255   set_program_name(szProgram);
256 #endif
257
258   ster_print(out,"G  R  O  M  A  C  S");
259   fprintf(out,"\n");
260   
261   bromacs(tmpstr,1023);
262   sp_print(out,tmpstr); 
263   fprintf(out,"\n");
264
265   ster_print(out,GromacsVersion());
266   fprintf(out,"\n");
267
268   /* fprintf(out,"\n");*/
269
270   /* sp_print(out,"PLEASE NOTE: THIS IS A BETA VERSION\n");
271   
272   fprintf(out,"\n"); */
273
274   for(i=0; (i<NCR); i++) 
275     sp_print(out,CopyrightText[i]);
276   for(i=0; (i<NGPL); i++)
277     sp_print(out,GPLText[i]);
278
279   fprintf(out,"\n");
280
281   snprintf(buf,256,"%s",Program());
282 #ifdef GMX_DOUBLE
283   strcat(buf," (double precision)");
284 #endif
285   ster_print(out,buf);
286   fprintf(out,"\n");
287 }
288
289
290 void thanx(FILE *fp)
291 {
292   char cq[1024];
293   int  cqnum;
294
295   /* protect the audience from suggestive discussions */
296   cool_quote(cq,1023,&cqnum);
297   
298   if (be_cool()) 
299     fprintf(fp,"\ngcq#%d: %s\n\n",cqnum,cq);
300   else
301     fprintf(fp,"\n%s\n\n",cq);
302 }
303
304 typedef struct {
305   const char *key;
306   const char *author;
307   const char *title;
308   const char *journal;
309   int volume,year;
310   const char *pages;
311 } t_citerec;
312
313 void please_cite(FILE *fp,const char *key)
314 {
315   static const t_citerec citedb[] = {
316     { "Allen1987a",
317       "M. P. Allen and D. J. Tildesley",
318       "Computer simulation of liquids",
319       "Oxford Science Publications",
320       1, 1987, "1" },
321     { "Berendsen95a",
322       "H. J. C. Berendsen, D. van der Spoel and R. van Drunen",
323       "GROMACS: A message-passing parallel molecular dynamics implementation",
324       "Comp. Phys. Comm.",
325       91, 1995, "43-56" },
326     { "Berendsen84a",
327       "H. J. C. Berendsen, J. P. M. Postma, A. DiNola and J. R. Haak",
328       "Molecular dynamics with coupling to an external bath",
329       "J. Chem. Phys.",
330       81, 1984, "3684-3690" },
331     { "Ryckaert77a",
332       "J. P. Ryckaert and G. Ciccotti and H. J. C. Berendsen",
333       "Numerical Integration of the Cartesian Equations of Motion of a System with Constraints; Molecular Dynamics of n-Alkanes",
334       "J. Comp. Phys.",
335       23, 1977, "327-341" },
336     { "Miyamoto92a",
337       "S. Miyamoto and P. A. Kollman",
338       "SETTLE: An Analytical Version of the SHAKE and RATTLE Algorithms for Rigid Water Models",
339       "J. Comp. Chem.",
340       13, 1992, "952-962" },
341     { "Cromer1968a",
342       "D. T. Cromer & J. B. Mann",
343       "X-ray scattering factors computed from numerical Hartree-Fock wave functions",
344       "Acta Cryst. A",
345       24, 1968, "321" },
346     { "Barth95a",
347       "E. Barth and K. Kuczera and B. Leimkuhler and R. D. Skeel",
348       "Algorithms for Constrained Molecular Dynamics",
349       "J. Comp. Chem.",
350       16, 1995, "1192-1209" },
351     { "Essmann95a",
352       "U. Essmann, L. Perera, M. L. Berkowitz, T. Darden, H. Lee and L. G. Pedersen ",
353       "A smooth particle mesh Ewald method",
354       "J. Chem. Phys.",
355       103, 1995, "8577-8592" },
356     { "Torda89a",
357       "A. E. Torda and R. M. Scheek and W. F. van Gunsteren",
358       "Time-dependent distance restraints in molecular dynamics simulations",
359       "Chem. Phys. Lett.",
360       157, 1989, "289-294" },
361     { "Tironi95a",
362       "I. G. Tironi and R. Sperb and P. E. Smith and W. F. van Gunsteren",
363       "Generalized reaction field method for molecular dynamics simulations",
364       "J. Chem. Phys",
365       102, 1995, "5451-5459" },
366     { "Hess97a",
367       "B. Hess and H. Bekker and H. J. C. Berendsen and J. G. E. M. Fraaije",
368       "LINCS: A Linear Constraint Solver for molecular simulations",
369       "J. Comp. Chem.",
370       18, 1997, "1463-1472" },
371     { "Hess2008a",
372       "B. Hess",
373       "P-LINCS: A Parallel Linear Constraint Solver for molecular simulation",
374       "J. Chem. Theory Comput.",
375       4, 2008, "116-122" },
376     { "Hess2008b",
377       "B. Hess and C. Kutzner and D. van der Spoel and E. Lindahl",
378       "GROMACS 4: Algorithms for highly efficient, load-balanced, and scalable molecular simulation",
379       "J. Chem. Theory Comput.",
380       4, 2008, "435-447" },
381     { "Hub2010",
382       "J. S. Hub, B. L. de Groot and D. van der Spoel",
383       "g_wham - A free weighted histogram analysis implementation including robust error and autocorrelation estimates",
384       "J. Chem. Theory Comput.",
385       6, 2010, "3713-3720"}, 
386     { "In-Chul99a",
387       "Y. In-Chul and M. L. Berkowitz",
388       "Ewald summation for systems with slab geometry",
389       "J. Chem. Phys.",
390       111, 1999, "3155-3162" },
391     { "DeGroot97a",
392       "B. L. de Groot and D. M. F. van Aalten and R. M. Scheek and A. Amadei and G. Vriend and H. J. C. Berendsen",
393       "Prediction of Protein Conformational Freedom From Distance Constrains",
394       "Proteins",
395       29, 1997, "240-251" },
396     { "Spoel98a",
397       "D. van der Spoel and P. J. van Maaren and H. J. C. Berendsen",
398       "A systematic study of water models for molecular simulation. Derivation of models optimized for use with a reaction-field.",
399       "J. Chem. Phys.",
400       108, 1998, "10220-10230" },
401     { "Wishart98a",
402       "D. S. Wishart and A. M. Nip",
403       "Protein Chemical Shift Analysis: A Practical Guide",
404       "Biochem. Cell Biol.",
405       76, 1998, "153-163" },
406     { "Maiorov95",
407       "V. N. Maiorov and G. M. Crippen",
408       "Size-Independent Comparison of Protein Three-Dimensional Structures",
409       "PROTEINS: Struct. Funct. Gen.",
410       22, 1995, "273-283" },
411     { "Feenstra99",
412       "K. A. Feenstra and B. Hess and H. J. C. Berendsen",
413       "Improving Efficiency of Large Time-scale Molecular Dynamics Simulations of Hydrogen-rich Systems",
414       "J. Comput. Chem.",
415       20, 1999, "786-798" },
416     { "Timneanu2004a",
417       "N. Timneanu and C. Caleman and J. Hajdu and D. van der Spoel",
418       "Auger Electron Cascades in Water and Ice",
419       "Chem. Phys.",
420       299, 2004, "277-283" },
421     { "Pascal2011a",
422       "T. A. Pascal and S. T. Lin and W. A. Goddard III",
423       "Thermodynamics of liquids: standard molar entropies and heat capacities of common solvents from 2PT molecular dynamics",
424       "Phys. Chem. Chem. Phys.",
425       13, 2011, "169-181" },
426     { "Caleman2011b",
427       "C. Caleman and M. Hong and J. S. Hub and L. T. da Costa and P. J. van Maaren and D. van der Spoel",
428       "Force Field Benchmark 1: Density, Heat of Vaporization, Heat Capacity, Surface Tension and Dielectric Constant of 152 Organic Liquids",
429       "Submitted",
430       0, 2011, "" },
431     { "Lindahl2001a",
432       "E. Lindahl and B. Hess and D. van der Spoel",
433       "GROMACS 3.0: A package for molecular simulation and trajectory analysis",
434       "J. Mol. Mod.",
435       7, 2001, "306-317" },
436     { "Wang2001a",
437       "J. Wang and W. Wang and S. Huo and M. Lee and P. A. Kollman",
438       "Solvation model based on weighted solvent accessible surface area",
439       "J. Phys. Chem. B",
440       105, 2001, "5055-5067" },
441     { "Eisenberg86a",
442       "D. Eisenberg and A. D. McLachlan",
443       "Solvation energy in protein folding and binding",
444       "Nature",
445       319, 1986, "199-203" },
446     { "Eisenhaber95",
447       "Frank Eisenhaber and Philip Lijnzaad and Patrick Argos and Chris Sander and Michael Scharf",
448       "The Double Cube Lattice Method: Efficient Approaches to Numerical Integration of Surface Area and Volume and to Dot Surface Contouring of Molecular Assemblies",
449       "J. Comp. Chem.",
450       16, 1995, "273-284" },
451     { "Hess2002",
452       "B. Hess, H. Saint-Martin and H.J.C. Berendsen",
453       "Flexible constraints: an adiabatic treatment of quantum degrees of freedom, with application to the flexible and polarizable MCDHO model for water",
454       "J. Chem. Phys.",
455       116, 2002, "9602-9610" },
456     { "Hetenyi2002b",
457       "Csaba Hetenyi and David van der Spoel",
458       "Efficient docking of peptides to proteins without prior knowledge of the binding site.",
459       "Prot. Sci.",
460       11, 2002, "1729-1737" },
461     { "Hess2003",
462       "B. Hess and R.M. Scheek",
463       "Orientation restraints in molecular dynamics simulations using time and ensemble averaging",
464       "J. Magn. Res.",
465       164, 2003, "19-27" },
466     { "Rappe1991a",
467       "A. K. Rappe and W. A. Goddard III",
468       "Charge Equillibration for Molecular Dynamics Simulations",
469       "J. Phys. Chem.",
470       95, 1991, "3358-3363" },
471     { "Mu2005a",
472       "Y. Mu, P. H. Nguyen and G. Stock",
473       "Energy landscape of a small peptide revelaed by dihedral angle principal component analysis",
474       "Prot. Struct. Funct. Bioinf.",
475       58, 2005, "45-52" },
476     { "Okabe2001a",
477       "T. Okabe and M. Kawata and Y. Okamoto and M. Mikami",
478       "Replica-exchange {M}onte {C}arlo method for the isobaric-isothermal ensemble",
479       "Chem. Phys. Lett.",
480       335, 2001, "435-439" },
481     { "Hukushima96a",
482       "K. Hukushima and K. Nemoto",
483       "Exchange Monte Carlo Method and Application to Spin Glass Simulations",
484       "J. Phys. Soc. Jpn.",
485       65, 1996, "1604-1608" },
486     { "Tropp80a",
487       "J. Tropp",
488       "Dipolar Relaxation and Nuclear Overhauser effects in nonrigid molecules: The effect of fluctuating internuclear distances",
489       "J. Chem. Phys.",
490       72, 1980, "6035-6043" },
491     { "Bultinck2002a",
492        "P. Bultinck and W. Langenaeker and P. Lahorte and F. De Proft and P. Geerlings and M. Waroquier and J. P. Tollenaere",
493       "The electronegativity equalization method I: Parametrization and validation for atomic charge calculations",
494       "J. Phys. Chem. A",
495       106, 2002, "7887-7894" },
496     { "Yang2006b",
497       "Q. Y. Yang and K. A. Sharp",
498       "Atomic charge parameters for the finite difference Poisson-Boltzmann method using electronegativity neutralization",
499       "J. Chem. Theory Comput.",
500       2, 2006, "1152-1167" },
501     { "Spoel2005a",
502       "D. van der Spoel, E. Lindahl, B. Hess, G. Groenhof, A. E. Mark and H. J. C. Berendsen",
503       "GROMACS: Fast, Flexible and Free",
504       "J. Comp. Chem.",
505       26, 2005, "1701-1719" },
506     { "Spoel2006b",
507       "D. van der Spoel, P. J. van Maaren, P. Larsson and N. Timneanu",
508       "Thermodynamics of hydrogen bonding in hydrophilic and hydrophobic media",
509       "J. Phys. Chem. B",
510       110, 2006, "4393-4398" },
511     { "Spoel2006d",
512       "D. van der Spoel and M. M. Seibert",
513       "Protein folding kinetics and thermodynamics from atomistic simulations",
514       "Phys. Rev. Letters",
515       96, 2006, "238102" },
516     { "Palmer94a",
517       "B. J. Palmer",
518       "Transverse-current autocorrelation-function calculations of the shear viscosity for molecular liquids",
519       "Phys. Rev. E",
520       49, 1994, "359-366" },
521     { "Bussi2007a",
522       "G. Bussi, D. Donadio and M. Parrinello",
523       "Canonical sampling through velocity rescaling",
524       "J. Chem. Phys.",
525       126, 2007, "014101" },
526     { "Hub2006",
527       "J. S. Hub and B. L. de Groot",
528       "Does CO2 permeate through Aquaporin-1?",
529       "Biophys. J.",
530       91, 2006, "842-848" },
531     { "Hub2008",
532       "J. S. Hub and B. L. de Groot",
533       "Mechanism of selectivity in aquaporins and aquaglyceroporins",
534       "PNAS",
535       105, 2008, "1198-1203" },
536     { "Friedrich2009",
537       "M. S. Friedrichs, P. Eastman, V. Vaidyanathan, M. Houston, S. LeGrand, A. L. Beberg, D. L. Ensign, C. M. Bruns, and V. S. Pande",
538       "Accelerating Molecular Dynamic Simulation on Graphics Processing Units",
539       "J. Comp. Chem.",
540       30, 2009, "864-872" },
541     { "Engin2010",
542       "O. Engin, A. Villa, M. Sayar and B. Hess",
543       "Driving Forces for Adsorption of Amphiphilic Peptides to Air-Water Interface",
544       "J. Phys. Chem. B",
545       0, 2010, "???" },
546     { "Fritsch12",
547       "S. Fritsch, C. Junghans and K. Kremer",
548       "Adaptive molecular simulation study on structure formation of toluene around C60 using Gromacs",
549       "J. Chem. Theo. Comp.",
550       0, 2012, "doi:10.1021/ct200706f" },
551     { "Junghans10",
552       "C. Junghans and S. Poblete",
553       "A reference implementation of the adaptive resolution scheme in ESPResSo",
554       "Comp. Phys. Comm.",
555       181, 2010, "1449" },
556     { "Wang2010",
557       "H. Wang, F. Dommert, C.Holm",
558       "Optimizing working parameters of the smooth particle mesh Ewald algorithm in terms of accuracy and efficiency",
559       "J. Chem. Phys. B",
560       133, 2010, "034117" },
561     { "Kutzner2011",
562       "C. Kutzner and J. Czub and H. Grubmuller",
563       "Keep it Flexible: Driving Macromolecular Rotary Motions in Atomistic Simulations with GROMACS",
564       "J. Chem. Theory Comput.",
565       7, 2011, "1381-1393" },
566     { "Hoefling2011",
567       "M. Hoefling, N. Lima, D. Haenni, C.A.M. Seidel, B. Schuler, H. Grubmuller",
568       "Structural Heterogeneity and Quantitative FRET Efficiency Distributions of Polyprolines through a Hybrid Atomistic Simulation and Monte Carlo Approach",
569       "PLoS ONE",
570       6, 2011, "e19791" },
571     { "Hockney1988",
572       "R. W. Hockney and J. W. Eastwood",
573       "Computer simulation using particles",
574       "IOP, Bristol",
575       1, 1988, "1" },
576     { "Ballenegger2012",
577       "V. Ballenegger, J.J. Cerda, and C. Holm",
578       "How to Convert SPME to P3M: Influence Functions and Error Estimates",
579       "J. Chem. Theory Comput.",
580       8, 2012, "936-947" },
581     { "Garmay2012",
582       "Garmay Yu, Shvetsov A, Karelov D, Lebedev D, Radulescu A, Petukhov M, Isaev-Ivanov V",
583       "Correlated motion of protein subdomains and large-scale conformational flexibility of RecA protein filament",
584       "Journal of Physics: Conference Series",
585       340, 2012, "012094" }
586   };
587 #define NSTR (int)asize(citedb)
588   
589   int  j,index;
590   char *author;
591   char *title;
592 #define LINE_WIDTH 79
593   
594   if (fp == NULL)
595     return;
596
597   for(index=0; (index<NSTR) && (strcmp(citedb[index].key,key) != 0); index++)
598     ;
599   
600   fprintf(fp,"\n++++ PLEASE READ AND CITE THE FOLLOWING REFERENCE ++++\n");
601   if (index < NSTR) {
602     /* Insert newlines */
603     author = wrap_lines(citedb[index].author,LINE_WIDTH,0,FALSE);
604     title  = wrap_lines(citedb[index].title,LINE_WIDTH,0,FALSE);
605     fprintf(fp,"%s\n%s\n%s %d (%d) pp. %s\n",
606             author,title,citedb[index].journal,
607             citedb[index].volume,citedb[index].year,
608             citedb[index].pages);
609     sfree(author);
610     sfree(title);
611   }
612   else {
613     fprintf(fp,"Entry %s not found in citation database\n",key);
614   }
615   fprintf(fp,"-------- -------- --- Thank You --- -------- --------\n\n");
616   fflush(fp);
617 }
618
619 #ifdef USE_VERSION_H
620 /* Version information generated at compile time. */
621 #include "version.h"
622 #else
623 /* Fall back to statically defined version. */
624 static const char _gmx_ver_string[]="VERSION " VERSION;
625 #endif
626
627 /* This routine only returns a static (constant) string, so we use a 
628  * mutex to initialize it. Since the string is only written to the
629  * first time, there is no risk with multiple calls overwriting the
630  * output for each other.
631  */
632 const char *GromacsVersion()
633 {
634   return _gmx_ver_string;
635 }
636
637
638 void gmx_print_version_info(FILE *fp)
639 {
640     fprintf(fp, "Version:          %s\n", _gmx_ver_string);
641 #ifdef USE_VERSION_H
642     fprintf(fp, "GIT SHA1 hash:    %s\n", _gmx_full_git_hash);
643     /* Only print out the branch information if present.
644      * The generating script checks whether the branch point actually
645      * coincides with the hash reported above, and produces an empty string
646      * in such cases. */
647     if (_gmx_central_base_hash[0] != 0)
648     {
649         fprintf(fp, "Branched from:    %s\n", _gmx_central_base_hash);
650     }
651 #endif
652
653 #ifdef GMX_DOUBLE
654     fprintf(fp, "Precision:        double\n");
655 #else
656     fprintf(fp, "Precision:        single\n");
657 #endif
658
659 #ifdef GMX_THREAD_MPI
660     fprintf(fp, "Parallellization: thread_mpi\n");
661 #elif defined(GMX_MPI)
662     fprintf(fp, "Parallellization: MPI\n");
663 #else
664     fprintf(fp, "Parallellization: none\n");
665 #endif
666
667 #ifdef GMX_FFT_FFTPACK
668     fprintf(fp, "FFT Library:      fftpack\n");
669 #elif defined(GMX_FFT_FFTW3)
670     fprintf(fp, "FFT Library:      fftw3\n");
671 #elif defined(GMX_FFT_MKL)
672     fprintf(fp, "FFT Library:      MKL\n");
673 #else
674     fprintf(fp, "FFT Library:      unknown\n");
675 #endif
676
677 }