3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
30 * For more info, check our website at http://www.gromacs.org
33 * Green Red Orange Magenta Azure Cyan Skyblue
67 enum { euSel
,euRect
, euTric
, euCompact
, euNR
};
69 static real
calc_isquared(int nmol
,rvec m_com
[],rvec m_shift
[],rvec clust_com
)
75 for(i
=0; (i
<nmol
); i
++) {
76 rvec_add(m_com
[i
],m_shift
[i
],m0
);
77 rvec_sub(m0
,clust_com
,dx
);
83 static void calc_pbc_cluster(int ecenter
,int nrefat
,t_topology
*top
,int ePBC
,
84 rvec x
[],atom_id index
[],
85 rvec clust_com
,matrix box
)
89 int m
,i
,j
,j0
,j1
,jj
,ai
,iter
,is
;
90 real fac
,Isq
,min_dist2
;
91 rvec dx
,ddx
,xtest
,xrm
,box_center
;
92 int nmol
,nmol_cl
,imol_center
;
95 rvec
*m_com
,*m_shift
,m0
;
98 calc_box_center(ecenter
,box
,box_center
);
100 /* Initiate the pbc structure */
101 memset(&pbc
,0,sizeof(pbc
));
102 set_pbc(&pbc
,ePBC
,box
);
104 /* Convert atom index to molecular */
106 molind
= top
->mols
.index
;
110 snew(bTmp
,top
->atoms
.nr
);
112 for(i
=0; (i
<nrefat
); i
++) {
113 /* Mark all molecules in the index */
116 /* Binary search assuming the molecules are sorted */
120 if (ai
< molind
[j0
+1])
122 else if (ai
>= molind
[j1
])
126 if (ai
< molind
[jj
+1])
134 /* Double check whether all atoms in all molecules that are marked are part
135 * of the cluster. Simultaneously compute the center of geometry.
137 min_dist2
= 10*sqr(trace(box
));
139 for(i
=0; (i
<nmol
); i
++) {
140 for(j
=molind
[i
]; (j
<molind
[i
+1]); j
++) {
141 if (bMol
[i
] && !bTmp
[j
])
142 gmx_fatal(FARGS
,"Molecule %d marked for clustering but not atom %d",
144 else if (!bMol
[i
] && bTmp
[j
])
145 gmx_fatal(FARGS
,"Atom %d marked for clustering but not molecule %d",
148 /* Compute center of geometry of molecule */
149 rvec_inc(m_com
[i
],x
[j
]);
153 /* Normalize center of geometry */
154 fac
= 1.0/(molind
[i
+1]-molind
[i
]);
155 for(m
=0; (m
<DIM
); m
++)
157 /* Determine which molecule is closest to the center of the box */
158 pbc_dx(&pbc
,box_center
,m_com
[i
],dx
);
159 if (iprod(dx
,dx
) < min_dist2
) {
160 min_dist2
= iprod(dx
,dx
);
169 fprintf(stderr
,"No molecules selected in the cluster\n");
171 } else if (imol_center
== -1) {
172 fprintf(stderr
,"No central molecules could be found\n");
177 /* First calculation is incremental */
178 clear_rvec(clust_com
);
180 for(i
=m
=0; (i
<nmol
); i
++) {
181 /* Check whether this molecule is part of the cluster */
183 if ((i
> 0) && (m
> 0)) {
184 /* Compute center of cluster by dividing by number of molecules */
185 svmul(1.0/m
,clust_com
,xrm
);
186 /* Distance vector between molecular COM and cluster */
187 pbc_dx(&pbc
,m_com
[i
],xrm
,dx
);
188 rvec_add(xrm
,dx
,xtest
);
189 /* xtest is now the image of m_com[i] that is closest to clust_com */
190 rvec_inc(clust_com
,xtest
);
191 rvec_sub(xtest
,m_com
[i
],m_shift
[i
]);
194 rvec_inc(clust_com
,m_com
[i
]);
199 assert(m
== nmol_cl
);
200 svmul(1/nmol_cl
,clust_com
,clust_com
);
201 put_atom_in_box(box
,clust_com
);
203 /* Now check if any molecule is more than half the box from the COM */
208 for(i
=0; (i
<nmol
) && !bChanged
; i
++) {
210 /* Sum com and shift from com */
211 rvec_add(m_com
[i
],m_shift
[i
],m0
);
212 pbc_dx(&pbc
,m0
,clust_com
,dx
);
213 rvec_add(clust_com
,dx
,xtest
);
214 rvec_sub(xtest
,m0
,ddx
);
215 if (iprod(ddx
,ddx
) > tol
) {
216 /* Here we have used the wrong image for contributing to the COM */
217 rvec_sub(xtest
,m_com
[i
],m_shift
[i
]);
218 for(j
=0; (j
<DIM
); j
++)
219 clust_com
[j
] += (xtest
[j
]-m0
[j
])/nmol_cl
;
224 Isq
= calc_isquared(nmol
,m_com
,m_shift
,clust_com
);
225 put_atom_in_box(box
,clust_com
);
227 if (bChanged
&& (iter
> 0))
228 printf("COM: %8.3f %8.3f %8.3f iter = %d Isq = %8.3f\n",
229 clust_com
[XX
],clust_com
[YY
],clust_com
[ZZ
],iter
,Isq
);
233 /* Now transfer the shift to all atoms in the molecule */
234 for(i
=0; (i
<nmol
); i
++) {
236 for(j
=molind
[i
]; (j
<molind
[i
+1]); j
++)
237 rvec_inc(x
[j
],m_shift
[i
]);
245 static void put_molecule_com_in_box(int unitcell_enum
,int ecenter
,
247 int natoms
,t_atom atom
[],
248 int ePBC
,matrix box
,rvec x
[])
252 rvec com
,new_com
,shift
,dx
,box_center
;
257 calc_box_center(ecenter
,box
,box_center
);
258 set_pbc(&pbc
,ePBC
,box
);
260 gmx_fatal(FARGS
,"There are no molecule descriptions. I need a tpr file for this pbc option.");
261 for(i
=0; (i
<mols
->nr
); i
++) {
265 for(j
=mols
->index
[i
]; (j
<mols
->index
[i
+1] && j
<natoms
); j
++) {
271 /* calculate final COM */
272 svmul(1.0/mtot
, com
, com
);
274 /* check if COM is outside box */
275 copy_rvec(com
,new_com
);
276 switch (unitcell_enum
) {
278 put_atoms_in_box(box
,1,&new_com
);
281 put_atoms_in_triclinic_unitcell(ecenter
,box
,1,&new_com
);
284 put_atoms_in_compact_unitcell(ePBC
,ecenter
,box
,1,&new_com
);
287 rvec_sub(new_com
,com
,shift
);
288 if (norm2(shift
) > 0) {
290 fprintf (debug
,"\nShifting position of molecule %d "
291 "by %8.3f %8.3f %8.3f\n", i
+1, PR_VEC(shift
));
292 for(j
=mols
->index
[i
]; (j
<mols
->index
[i
+1] && j
<natoms
); j
++) {
293 rvec_inc(x
[j
],shift
);
299 static void put_residue_com_in_box(int unitcell_enum
,int ecenter
,
300 int natoms
,t_atom atom
[],
301 int ePBC
,matrix box
,rvec x
[])
303 atom_id i
, j
, res_start
, res_end
, res_nat
;
307 rvec box_center
,com
,new_com
,shift
;
309 calc_box_center(ecenter
,box
,box_center
);
315 for(i
=0; i
<natoms
+1; i
++) {
316 if (i
== natoms
|| (presnr
!= atom
[i
].resind
&& presnr
!= NOTSET
)) {
317 /* calculate final COM */
319 res_nat
= res_end
- res_start
;
320 svmul(1.0/mtot
, com
, com
);
322 /* check if COM is outside box */
323 copy_rvec(com
,new_com
);
324 switch (unitcell_enum
) {
326 put_atoms_in_box(box
,1,&new_com
);
329 put_atoms_in_triclinic_unitcell(ecenter
,box
,1,&new_com
);
332 put_atoms_in_compact_unitcell(ePBC
,ecenter
,box
,1,&new_com
);
335 rvec_sub(new_com
,com
,shift
);
338 fprintf (debug
,"\nShifting position of residue %d (atoms %u-%u) "
339 "by %g,%g,%g\n", atom
[res_start
].resind
+1,
340 res_start
+1, res_end
+1, PR_VEC(shift
));
341 for(j
=res_start
; j
<res_end
; j
++)
342 rvec_inc(x
[j
],shift
);
347 /* remember start of new residue */
357 presnr
= atom
[i
].resind
;
362 static void center_x(int ecenter
,rvec x
[],matrix box
,int n
,int nc
,atom_id ci
[])
365 rvec cmin
,cmax
,box_center
,dx
;
368 copy_rvec(x
[ci
[0]],cmin
);
369 copy_rvec(x
[ci
[0]],cmax
);
370 for(i
=0; i
<nc
; i
++) {
372 for(m
=0; m
<DIM
; m
++) {
373 if (x
[ai
][m
] < cmin
[m
])
375 else if (x
[ai
][m
] > cmax
[m
])
379 calc_box_center(ecenter
,box
,box_center
);
381 dx
[m
] = box_center
[m
]-(cmin
[m
]+cmax
[m
])*0.5;
388 static void mk_filenm(char *base
,const char *ext
,int ndigit
,int file_nr
,
394 strcpy(out_file
,base
);
401 strncat(out_file
,"00000000000",ndigit
-nd
);
402 sprintf(nbuf
,"%d.",file_nr
);
403 strcat(out_file
,nbuf
);
404 strcat(out_file
,ext
);
407 void check_trn(const char *fn
)
409 if ((fn2ftp(fn
) != efTRJ
) && (fn2ftp(fn
) != efTRR
))
410 gmx_fatal(FARGS
,"%s is not a trj file, exiting\n",fn
);
413 #if (!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64)
414 void do_trunc(const char *fn
, real t0
)
426 gmx_fatal(FARGS
,"You forgot to set the truncation time");
428 /* Check whether this is a .trj file */
431 in
= open_trn(fn
,"r");
432 fp
= gmx_fio_getfp(in
);
434 fprintf(stderr
,"Sorry, can not trunc %s, truncation of this filetype is not supported\n",fn
);
438 fpos
= gmx_fio_ftell(in
);
440 while (!bStop
&& fread_trnheader(in
,&sh
,&bOK
)) {
441 fread_htrn(in
,&sh
,NULL
,NULL
,NULL
,NULL
);
446 fseeko(fp
,fpos
,SEEK_SET
);
448 fseek(fp
,fpos
,SEEK_SET
);
454 fprintf(stderr
,"Do you REALLY want to truncate this trajectory (%s) at:\n"
455 "frame %d, time %g, bytes %ld ??? (type YES if so)\n",
456 fn
,j
,t
,(long int)fpos
);
457 if(1 != scanf("%s",yesno
))
459 gmx_fatal(FARGS
,"Error reading user input");
461 if (strcmp(yesno
,"YES") == 0) {
462 fprintf(stderr
,"Once again, I'm gonna DO this...\n");
464 if(0 != truncate(fn
,fpos
))
466 gmx_fatal(FARGS
,"Error truncating file %s",fn
);
470 fprintf(stderr
,"Ok, I'll forget about it\n");
474 fprintf(stderr
,"Already at end of file (t=%g)...\n",t
);
481 int gmx_trjconv(int argc
,char *argv
[])
483 const char *desc
[] = {
484 "trjconv can convert trajectory files in many ways:[BR]",
485 "[BB]1.[bb] from one format to another[BR]",
486 "[BB]2.[bb] select a subset of atoms[BR]"
487 "[BB]3.[bb] change the periodicity representation[BR]",
488 "[BB]4.[bb] keep multimeric molecules together[BR]",
489 "[BB]5.[bb] center atoms in the box[BR]",
490 "[BB]6.[bb] fit atoms to reference structure[BR]",
491 "[BB]7.[bb] reduce the number of frames[BR]",
492 "[BB]8.[bb] change the timestamps of the frames ",
493 "([TT]-t0[tt] and [TT]-timestep[tt])[BR]",
494 "[BB]9.[bb] cut the trajectory in small subtrajectories according",
495 "to information in an index file. This allows subsequent analysis of",
496 "the subtrajectories that could, for example be the result of a",
497 "cluster analysis. Use option [TT]-sub[tt].",
498 "This assumes that the entries in the index file are frame numbers and",
499 "dumps each group in the index file to a separate trajectory file.[BR]",
500 "[BB]10.[bb] select frames within a certain range of a quantity given",
501 "in an [TT].xvg[tt] file.[PAR]",
502 "The program [TT]trjcat[tt] can concatenate multiple trajectory files.",
504 "Currently seven formats are supported for input and output:",
505 "[TT].xtc[tt], [TT].trr[tt], [TT].trj[tt], [TT].gro[tt], [TT].g96[tt],",
506 "[TT].pdb[tt] and [TT].g87[tt].",
507 "The file formats are detected from the file extension.",
508 "The precision of [TT].xtc[tt] and [TT].gro[tt] output is taken from the",
509 "input file for [TT].xtc[tt], [TT].gro[tt] and [TT].pdb[tt],",
510 "and from the [TT]-ndec[tt] option for other input formats. The precision",
511 "is always taken from [TT]-ndec[tt], when this option is set.",
512 "All other formats have fixed precision. [TT].trr[tt] and [TT].trj[tt]",
513 "output can be single or double precision, depending on the precision",
514 "of the trjconv binary.",
515 "Note that velocities are only supported in",
516 "[TT].trr[tt], [TT].trj[tt], [TT].gro[tt] and [TT].g96[tt] files.[PAR]",
517 "Option [TT]-app[tt] can be used to",
518 "append output to an existing trajectory file.",
519 "No checks are performed to ensure integrity",
520 "of the resulting combined trajectory file.[PAR]",
521 "Option [TT]-sep[tt] can be used to write every frame to a seperate",
522 ".gro, .g96 or .pdb file, default all frames all written to one file.",
523 "[TT].pdb[tt] files with all frames concatenated can be viewed with",
524 "[TT]rasmol -nmrpdb[tt].[PAR]",
525 "It is possible to select part of your trajectory and write it out",
526 "to a new trajectory file in order to save disk space, e.g. for leaving",
527 "out the water from a trajectory of a protein in water.",
528 "[BB]ALWAYS[bb] put the original trajectory on tape!",
529 "We recommend to use the portable [TT].xtc[tt] format for your analysis",
530 "to save disk space and to have portable files.[PAR]",
531 "There are two options for fitting the trajectory to a reference",
532 "either for essential dynamics analysis or for whatever.",
533 "The first option is just plain fitting to a reference structure",
534 "in the structure file, the second option is a progressive fit",
535 "in which the first timeframe is fitted to the reference structure ",
536 "in the structure file to obtain and each subsequent timeframe is ",
537 "fitted to the previously fitted structure. This way a continuous",
538 "trajectory is generated, which might not be the case when using the",
539 "regular fit method, e.g. when your protein undergoes large",
540 "conformational transitions.[PAR]",
541 "Option [TT]-pbc[tt] sets the type of periodic boundary condition",
543 "* [TT]mol[tt] puts the center of mass of molecules in the box.[BR]",
544 "* [TT]res[tt] puts the center of mass of residues in the box.[BR]",
545 "* [TT]atom[tt] puts all the atoms in the box.[BR]",
546 "* [TT]nojump[tt] checks if atoms jump across the box and then puts",
547 "them back. This has the effect that all molecules",
548 "will remain whole (provided they were whole in the initial",
549 "conformation), note that this ensures a continuous trajectory but",
550 "molecules may diffuse out of the box. The starting configuration",
551 "for this procedure is taken from the structure file, if one is",
552 "supplied, otherwise it is the first frame.[BR]",
553 "* [TT]cluster[tt] clusters all the atoms in the selected index",
554 "such that they are all closest to the center of mass of the cluster",
555 "which is iteratively updated. Note that this will only give meaningful",
556 "results if you in fact have a cluster. Luckily that can be checked",
557 "afterwards using a trajectory viewer. Note also that if your molecules",
558 "are broken this will not work either.[BR]",
559 "* [TT]whole[tt] only makes broken molecules whole.[PAR]",
560 "Option [TT]-ur[tt] sets the unit cell representation for options",
561 "[TT]mol[tt], [TT]res[tt] and [TT]atom[tt] of [TT]-pbc[tt].",
562 "All three options give different results for triclinc boxes and",
563 "identical results for rectangular boxes.",
564 "[TT]rect[tt] is the ordinary brick shape.",
565 "[TT]tric[tt] is the triclinic unit cell.",
566 "[TT]compact[tt] puts all atoms at the closest distance from the center",
567 "of the box. This can be useful for visualizing e.g. truncated",
568 "octahedrons. The center for options [TT]tric[tt] and [TT]compact[tt]",
569 "is [TT]tric[tt] (see below), unless the option [TT]-boxcenter[tt]",
570 "is set differently.[PAR]",
571 "Option [TT]-center[tt] centers the system in the box. The user can",
572 "select the group which is used to determine the geometrical center.",
573 "Option [TT]-boxcenter[tt] sets the location of the center of the box",
574 "for options [TT]-pbc[tt] and [TT]-center[tt]. The center options are:",
575 "[TT]tric[tt]: half of the sum of the box vectors,",
576 "[TT]rect[tt]: half of the box diagonal,",
577 "[TT]zero[tt]: zero.",
578 "Use option [TT]-pbc mol[tt] in addition to [TT]-center[tt] when you",
579 "want all molecules in the box after the centering.[PAR]",
580 "With [TT]-dt[tt] it is possible to reduce the number of ",
581 "frames in the output. This option relies on the accuracy of the times",
582 "in your input trajectory, so if these are inaccurate use the",
583 "[TT]-timestep[tt] option to modify the time (this can be done",
584 "simultaneously). For making smooth movies the program [TT]g_filter[tt]",
585 "can reduce the number of frames while using low-pass frequency",
586 "filtering, this reduces aliasing of high frequency motions.[PAR]",
587 "Using [TT]-trunc[tt] trjconv can truncate [TT].trj[tt] in place, i.e.",
588 "without copying the file. This is useful when a run has crashed",
589 "during disk I/O (one more disk full), or when two contiguous",
590 "trajectories must be concatenated without have double frames.[PAR]",
591 "[TT]trjcat[tt] is more suitable for concatenating trajectory files.[PAR]",
592 "Option [TT]-dump[tt] can be used to extract a frame at or near",
593 "one specific time from your trajectory.[PAR]",
594 "Option [TT]-drop[tt] reads an [TT].xvg[tt] file with times and values.",
595 "When options [TT]-dropunder[tt] and/or [TT]-dropover[tt] are set,",
596 "frames with a value below and above the value of the respective options",
597 "will not be written."
613 const char *pbc_opt
[epNR
+ 1] =
614 { NULL
, "none", "mol", "res", "atom", "nojump", "cluster", "whole",
618 const char *unitcell_opt
[euNR
+1] =
619 { NULL
, "rect", "tric", "compact", NULL
};
622 { ecSel
, ecTric
, ecRect
, ecZero
, ecNR
};
623 const char *center_opt
[ecNR
+1] =
624 { NULL
, "tric", "rect", "zero", NULL
};
630 efSel
, efNone
, efFit
, efFitXY
, efReset
, efResetXY
, efPFit
, efNR
632 const char *fit
[efNR
+ 1] =
633 { NULL
, "none", "rot+trans", "rotxy+transxy", "translation", "transxy",
634 "progressive", NULL
};
636 static bool bAppend
=FALSE
,bSeparate
=FALSE
,bVels
=TRUE
,bForce
=FALSE
,bCONECT
=FALSE
;
637 static bool bCenter
=FALSE
,bTer
=FALSE
;
638 static int skip_nr
=1,ndec
=3,nzero
=0;
639 static real tzero
=0,delta_t
=0,timestep
=0,ttrunc
=-1,tdump
=-1,split_t
=0;
640 static rvec newbox
= {0,0,0}, shift
= {0,0,0}, trans
= {0,0,0};
641 static char *exec_command
=NULL
;
642 static real dropunder
=0,dropover
=0;
643 static bool bRound
=FALSE
;
648 { "-skip", FALSE
, etINT
,
649 { &skip_nr
}, "Only write every nr-th frame" },
650 { "-dt", FALSE
, etTIME
,
652 "Only write frame when t MOD dt = first time (%t)" },
653 { "-round", FALSE
, etBOOL
,
654 { &bRound
}, "Round measurements to nearest picosecond"
656 { "-dump", FALSE
, etTIME
,
657 { &tdump
}, "Dump frame nearest specified time (%t)" },
658 { "-t0", FALSE
, etTIME
,
660 "Starting time (%t) (default: don't change)" },
661 { "-timestep", FALSE
, etTIME
,
663 "Change time step between input frames (%t)" },
664 { "-pbc", FALSE
, etENUM
,
666 "PBC treatment (see help text for full description)" },
667 { "-ur", FALSE
, etENUM
,
668 { unitcell_opt
}, "Unit-cell representation" },
669 { "-center", FALSE
, etBOOL
,
670 { &bCenter
}, "Center atoms in box" },
671 { "-boxcenter", FALSE
, etENUM
,
672 { center_opt
}, "Center for -pbc and -center" },
673 { "-box", FALSE
, etRVEC
,
675 "Size for new cubic box (default: read from input)" },
676 { "-trans", FALSE
, etRVEC
,
678 "All coordinates will be translated by trans. This "
679 "can advantageously be combined with -pbc mol -ur "
681 { "-shift", FALSE
, etRVEC
,
683 "All coordinates will be shifted by framenr*shift" },
684 { "-fit", FALSE
, etENUM
,
686 "Fit molecule to ref structure in the structure file" },
687 { "-ndec", FALSE
, etINT
,
689 "Precision for .xtc and .gro writing in number of "
691 { "-vel", FALSE
, etBOOL
,
692 { &bVels
}, "Read and write velocities if possible" },
693 { "-force", FALSE
, etBOOL
,
694 { &bForce
}, "Read and write forces if possible" },
695 #if (!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64)
696 { "-trunc", FALSE
, etTIME
,
698 "Truncate input trj file after this time (%t)" },
700 { "-exec", FALSE
, etSTR
,
702 "Execute command for every output frame with the "
703 "frame number as argument" },
704 { "-app", FALSE
, etBOOL
,
705 { &bAppend
}, "Append output" },
706 { "-split", FALSE
, etTIME
,
708 "Start writing new file when t MOD split = first "
710 { "-sep", FALSE
, etBOOL
,
712 "Write each frame to a separate .gro, .g96 or .pdb "
714 { "-nzero", FALSE
, etINT
,
716 "Prepend file number in case you use the -sep flag "
717 "with this number of zeroes" },
718 { "-ter", FALSE
, etBOOL
,
720 "Use 'TER' in pdb file as end of frame in stead of "
721 "default 'ENDMDL'" },
722 { "-dropunder", FALSE
, etREAL
,
723 { &dropunder
}, "Drop all frames below this value" },
724 { "-dropover", FALSE
, etREAL
,
725 { &dropover
}, "Drop all frames above this value" },
726 { "-conect", FALSE
, etBOOL
,
728 "Add conect records when writing pdb files. Useful "
729 "for visualization of non-standard molecules, e.g. "
730 "coarse grained ones" } };
731 #define NPA asize(pa)
735 int status
,ftp
,ftpin
=0,file_nr
;
738 rvec
*xmem
=NULL
,*vmem
=NULL
,*fmem
=NULL
;
739 rvec
*xp
=NULL
,x_shift
,hbox
,box_center
,dx
;
740 real xtcpr
, lambda
,*w_rls
=NULL
;
741 int m
,i
,d
,frame
,outframe
,natoms
,nout
,ncent
,nre
,newstep
=0,model_nr
;
746 t_atoms
*atoms
=NULL
,useatoms
;
748 atom_id
*index
,*cindex
;
752 int ifit
,irms
,my_clust
=-1;
753 atom_id
*ind_fit
,*ind_rms
;
754 char *gn_fit
,*gn_rms
;
755 t_cluster_ndx
*clust
=NULL
;
756 int *clust_status
=NULL
;
759 int ndrop
=0,ncol
,drop0
=0,drop1
=0,dropuse
=0;
761 real tshift
=0,t0
=-1,dt
=0.001,prec
;
762 bool bFit
,bFitXY
,bPFit
,bReset
;
764 bool bRmPBC
,bPBCWhole
,bPBCcomRes
,bPBCcomMol
,bPBCcomAtom
,bPBC
,bNoJump
,bCluster
;
765 bool bCopy
,bDoIt
,bIndex
,bTDump
,bSetTime
,bTPS
=FALSE
,bDTset
=FALSE
;
766 bool bExec
,bTimeStep
=FALSE
,bDumpFrame
=FALSE
,bSetPrec
,bNeedPrec
;
767 bool bHaveFirstFrame
,bHaveNextFrame
,bSetBox
,bSetUR
,bSplit
=FALSE
;
768 bool bSubTraj
=FALSE
,bDropUnder
=FALSE
,bDropOver
=FALSE
,bTrans
=FALSE
;
769 bool bWriteFrame
,bSplitHere
;
770 const char *top_file
,*in_file
,*out_file
=NULL
;
771 char out_file2
[256],*charpt
;
772 char *outf_base
=NULL
;
773 const char *outf_ext
=NULL
;
774 char top_title
[256],title
[256],command
[256],filemode
[5];
776 bool bWarnCompact
=FALSE
;
781 { efTRX
, "-f", NULL
, ffREAD
},
782 { efTRO
, "-o", NULL
, ffWRITE
},
783 { efTPS
, NULL
, NULL
, ffOPTRD
},
784 { efNDX
, NULL
, NULL
, ffOPTRD
},
785 { efNDX
, "-fr", "frames", ffOPTRD
},
786 { efNDX
, "-sub", "cluster", ffOPTRD
},
787 { efXVG
, "-drop","drop", ffOPTRD
}
789 #define NFILE asize(fnm)
791 CopyRight(stderr
,argv
[0]);
792 parse_common_args(&argc
,argv
,
793 PCA_CAN_BEGIN
| PCA_CAN_END
| PCA_CAN_VIEW
|
794 PCA_TIME_UNIT
| PCA_BE_NICE
,
795 NFILE
,fnm
,NPA
,pa
,asize(desc
),desc
,
798 top_file
= ftp2fn(efTPS
,NFILE
,fnm
);
801 /* Check command line */
802 in_file
=opt2fn("-f",NFILE
,fnm
);
805 #if (!defined WIN32 && !defined _WIN32 && !defined WIN64 && !defined _WIN64)
806 do_trunc(in_file
,ttrunc
);
810 /* mark active cmdline options */
811 bSetBox
= opt2parg_bSet("-box", NPA
, pa
);
812 bSetTime
= opt2parg_bSet("-t0", NPA
, pa
);
813 bSetPrec
= opt2parg_bSet("-ndec", NPA
, pa
);
814 bSetUR
= opt2parg_bSet("-ur", NPA
, pa
);
815 bExec
= opt2parg_bSet("-exec", NPA
, pa
);
816 bTimeStep
= opt2parg_bSet("-timestep", NPA
, pa
);
817 bTDump
= opt2parg_bSet("-dump", NPA
, pa
);
818 bDropUnder
= opt2parg_bSet("-dropunder", NPA
, pa
);
819 bDropOver
= opt2parg_bSet("-dropover", NPA
, pa
);
820 bTrans
= opt2parg_bSet("-trans",NPA
,pa
);
821 bSplit
= (split_t
!= 0);
823 /* parse enum options */
824 fit_enum
= nenum(fit
);
825 bFit
= (fit_enum
==efFit
|| fit_enum
==efFitXY
);
826 bFitXY
= fit_enum
==efFitXY
;
827 bReset
= (fit_enum
==efReset
|| fit_enum
==efResetXY
);
828 bPFit
= fit_enum
==efPFit
;
829 pbc_enum
= nenum(pbc_opt
);
830 bPBCWhole
= pbc_enum
==epWhole
;
831 bPBCcomRes
= pbc_enum
==epComRes
;
832 bPBCcomMol
= pbc_enum
==epComMol
;
833 bPBCcomAtom
= pbc_enum
==epComAtom
;
834 bNoJump
= pbc_enum
==epNojump
;
835 bCluster
= pbc_enum
==epCluster
;
836 bPBC
= pbc_enum
!=epNone
;
837 unitcell_enum
= nenum(unitcell_opt
);
838 ecenter
= nenum(center_opt
) - ecTric
;
840 /* set and check option dependencies */
841 if (bPFit
) bFit
= TRUE
; /* for pfit, fit *must* be set */
842 if (bFit
) bReset
= TRUE
; /* for fit, reset *must* be set */
845 nfitdim
= (fit_enum
==efFitXY
|| fit_enum
==efResetXY
) ? 2 : 3;
846 bRmPBC
= bFit
|| bPBCWhole
|| bPBCcomRes
|| bPBCcomMol
;
848 if (!(bPBCcomRes
|| bPBCcomMol
|| bPBCcomAtom
)) {
850 "WARNING: Option for unitcell representation (-ur %s)\n"
851 " only has effect in combination with -pbc %s, %s or %s.\n"
852 " Ingoring unitcell representation.\n\n",
853 unitcell_opt
[0],pbc_opt
[2],pbc_opt
[3],pbc_opt
[4]);
858 gmx_fatal(FARGS
,"PBC condition treatment does not work together with rotational fit.\n"
859 "Please do the PBC condition treatment first and then run trjconv in a second step\n"
860 "for the rotational fit.\n"
861 "First doing the rotational fit and then doing the PBC treatment gives incorrect\n"
864 /* set flag for pdbio to terminate frames at 'TER' (iso 'ENDMDL') */
867 /* ndec is in nr of decimal places, prec is a multiplication factor: */
869 for (i
=0; i
<ndec
; i
++)
872 bIndex
=ftp2bSet(efNDX
,NFILE
,fnm
);
875 /* Determine output type */
876 out_file
=opt2fn("-o",NFILE
,fnm
);
877 ftp
=fn2ftp(out_file
);
878 fprintf(stderr
,"Will write %s: %s\n",ftp2ext(ftp
),ftp2desc(ftp
));
879 bNeedPrec
= (ftp
==efXTC
|| ftp
==efGRO
);
881 /* check if velocities are possible in input and output files */
882 ftpin
=fn2ftp(in_file
);
883 bVels
= (ftp
==efTRR
|| ftp
==efTRJ
|| ftp
==efGRO
|| ftp
==efG96
)
884 && (ftpin
==efTRR
|| ftpin
==efTRJ
|| ftpin
==efGRO
|| ftpin
==efG96
||
887 if (bSeparate
|| bSplit
) {
888 outf_ext
= strrchr(out_file
,'.');
889 if (outf_ext
== NULL
)
890 gmx_fatal(FARGS
,"Output file name '%s' does not contain a '.'",out_file
);
891 outf_base
= strdup(out_file
);
892 outf_base
[outf_ext
- out_file
] = '\0';
895 bSubTraj
= opt2bSet("-sub",NFILE
,fnm
);
897 if ((ftp
!= efXTC
) && (ftp
!= efTRN
))
898 gmx_fatal(FARGS
,"Can only use the sub option with output file types "
900 clust
= cluster_index(NULL
,opt2fn("-sub",NFILE
,fnm
));
902 /* Check for number of files disabled, as FOPEN_MAX is not the correct
903 * number to check for. In my linux box it is only 16.
905 if (0 && (clust
->clust
->nr
> FOPEN_MAX
-4))
906 gmx_fatal(FARGS
,"Can not open enough (%d) files to write all the"
907 " trajectories.\ntry splitting the index file in %d parts.\n"
909 clust
->clust
->nr
,1+clust
->clust
->nr
/FOPEN_MAX
,FOPEN_MAX
);
911 snew(clust_status
,clust
->clust
->nr
);
912 snew(nfwritten
,clust
->clust
->nr
);
913 for(i
=0; (i
<clust
->clust
->nr
); i
++)
914 clust_status
[i
] = -1;
915 bSeparate
= bSplit
= FALSE
;
921 /* Determine whether to read a topology */
922 bTPS
= (ftp2bSet(efTPS
,NFILE
,fnm
) ||
923 bRmPBC
|| bReset
|| bPBCcomMol
||
924 (ftp
== efGRO
) || (ftp
== efPDB
) || bCONECT
);
926 /* Determine if when can read index groups */
927 bIndex
= (bIndex
|| bTPS
);
930 read_tps_conf(top_file
,top_title
,&top
,&ePBC
,&xp
,NULL
,top_box
,
931 bReset
|| bPBCcomRes
);
933 /* top_title is only used for gro and pdb,
934 * the header in such a file is top_title t= ...
935 * to prevent a double t=, remove it from top_title
937 if ((charpt
=strstr(top_title
," t= ")))
941 gc
= gmx_conect_generate(&top
);
944 /* get frame number index */
946 if (opt2bSet("-fr",NFILE
,fnm
)) {
947 printf("Select groups of frame number indices:\n");
948 rd_index(opt2fn("-fr",NFILE
,fnm
),1,&nrfri
,(atom_id
**)&frindex
,&frname
);
950 for(i
=0; i
<nrfri
; i
++)
951 fprintf(debug
,"frindex[%4d]=%4d\n",i
,frindex
[i
]);
954 /* get index groups etc. */
956 printf("Select group for %s fit\n",
957 bFit
?"least squares":"translational");
958 get_index(atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),
959 1,&ifit
,&ind_fit
,&gn_fit
);
963 gmx_fatal(FARGS
,"Need at least 2 atoms to fit!\n");
965 fprintf(stderr
,"WARNING: fitting with only 2 atoms is not unique\n");
969 printf("Select group for clustering\n");
970 get_index(atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),
971 1,&ifit
,&ind_fit
,&gn_fit
);
976 printf("Select group for centering\n");
977 get_index(atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),
978 1,&ncent
,&cindex
,&grpnm
);
980 printf("Select group for output\n");
981 get_index(atoms
,ftp2fn_null(efNDX
,NFILE
,fnm
),
982 1,&nout
,&index
,&grpnm
);
984 /* no index file, so read natoms from TRX */
985 if (!read_first_frame(oenv
,&status
,in_file
,&fr
,TRX_DONT_SKIP
))
986 gmx_fatal(FARGS
,"Could not read a frame from %s",in_file
);
991 for(i
=0;i
<natoms
;i
++)
1001 snew(w_rls
,atoms
->nr
);
1002 for(i
=0; (i
<ifit
); i
++)
1003 w_rls
[ind_fit
[i
]]=atoms
->atom
[ind_fit
[i
]].m
;
1005 /* Restore reference structure and set to origin,
1006 store original location (to put structure back) */
1008 rm_pbc(&(top
.idef
),ePBC
,atoms
->nr
,top_box
,xp
,xp
);
1009 copy_rvec(xp
[index
[0]],x_shift
);
1010 reset_x_ndim(nfitdim
,ifit
,ind_fit
,atoms
->nr
,NULL
,xp
,w_rls
);
1011 rvec_dec(x_shift
,xp
[index
[0]]);
1013 clear_rvec(x_shift
);
1015 if (bDropUnder
|| bDropOver
) {
1016 /* Read the xvg file with the drop values */
1017 fprintf(stderr
,"\nReading drop file ...");
1018 ndrop
= read_xvg(opt2fn("-drop",NFILE
,fnm
),&dropval
,&ncol
);
1019 fprintf(stderr
," %d time points\n",ndrop
);
1020 if (ndrop
== 0 || ncol
< 2)
1021 gmx_fatal(FARGS
,"Found no data points in %s",
1022 opt2fn("-drop",NFILE
,fnm
));
1027 /* Make atoms struct for output in GRO or PDB files */
1028 if ((ftp
== efGRO
) || ((ftp
== efG96
) && bTPS
) || (ftp
== efPDB
)) {
1029 /* get memory for stuff to go in pdb file */
1030 init_t_atoms(&useatoms
,atoms
->nr
,FALSE
);
1031 sfree(useatoms
.resinfo
);
1032 useatoms
.resinfo
= atoms
->resinfo
;
1033 for(i
=0;(i
<nout
);i
++) {
1034 useatoms
.atomname
[i
]=atoms
->atomname
[index
[i
]];
1035 useatoms
.atom
[i
]=atoms
->atom
[index
[i
]];
1036 useatoms
.nres
=max(useatoms
.nres
,useatoms
.atom
[i
].resind
+1);
1040 /* select what to read */
1041 if (ftp
==efTRR
|| ftp
==efTRJ
)
1046 flags
= flags
| TRX_READ_V
;
1048 flags
= flags
| TRX_READ_F
;
1050 /* open trx file for reading */
1051 bHaveFirstFrame
= read_first_frame(oenv
,&status
,in_file
,&fr
,flags
);
1053 fprintf(stderr
,"\nPrecision of %s is %g (nm)\n",in_file
,1/fr
.prec
);
1055 if (bSetPrec
|| !fr
.bPrec
)
1056 fprintf(stderr
,"\nSetting output precision to %g (nm)\n",1/prec
);
1058 fprintf(stderr
,"Using output precision of %g (nm)\n",1/prec
);
1061 if (bHaveFirstFrame
) {
1062 set_trxframe_ePBC(&fr
,ePBC
);
1067 tshift
=tzero
-fr
.time
;
1071 /* open output for writing */
1072 if ((bAppend
) && (gmx_fexist(out_file
))) {
1073 strcpy(filemode
,"a");
1074 fprintf(stderr
,"APPENDING to existing file %s\n",out_file
);
1076 strcpy(filemode
,"w");
1083 if (!bSplit
&& !bSubTraj
)
1084 trxout
= open_trx(out_file
,filemode
);
1089 if (( !bSeparate
&& !bSplit
) && !bSubTraj
)
1090 out
=ffopen(out_file
,filemode
);
1096 /* check if index is meaningful */
1097 for(i
=0; i
<nout
; i
++) {
1098 if (index
[i
] >= natoms
)
1099 gmx_fatal(FARGS
,"Index[%d] %d is larger than the number of atoms in the trajectory file (%d)",i
,index
[i
]+1,natoms
);
1100 bCopy
= bCopy
|| (i
!= index
[i
]);
1113 fprintf(gmx_fio_getfp(trxout
),"Generated by %s. #atoms=%d, a BOX is"
1114 " stored in this file.\n",Program(),nout
);
1116 /* Start the big loop over frames */
1123 /* Main loop over frames */
1131 /*if (frame >= clust->clust->nra)
1132 gmx_fatal(FARGS,"There are more frames in the trajectory than in the cluster index file\n");*/
1133 if (frame
>= clust
->maxframe
)
1136 my_clust
= clust
->inv_clust
[frame
];
1137 if ((my_clust
< 0) || (my_clust
>= clust
->clust
->nr
) ||
1138 (my_clust
== NO_ATID
))
1143 /* generate new box */
1145 for (m
=0; m
<DIM
; m
++)
1146 fr
.box
[m
][m
] = newbox
[m
];
1150 for(i
=0; i
<natoms
; i
++)
1151 rvec_inc(fr
.x
[i
],trans
);
1155 /* determine timestep */
1164 /* This is not very elegant, as one can not dump a frame after
1165 * a timestep with is more than twice as small as the first one. */
1166 bDumpFrame
= (fr
.time
> tdump
-0.5*dt
) && (fr
.time
<= tdump
+0.5*dt
);
1170 /* determine if an atom jumped across the box and reset it if so */
1171 if (bNoJump
&& (bTPS
|| frame
!=0)) {
1172 for(d
=0; d
<DIM
; d
++)
1173 hbox
[d
] = 0.5*fr
.box
[d
][d
];
1174 for(i
=0; i
<natoms
; i
++) {
1176 rvec_dec(fr
.x
[i
],x_shift
);
1177 for(m
=DIM
-1; m
>=0; m
--)
1179 while (fr
.x
[i
][m
]-xp
[i
][m
] <= -hbox
[m
])
1181 fr
.x
[i
][d
] += fr
.box
[m
][d
];
1182 while (fr
.x
[i
][m
]-xp
[i
][m
] > hbox
[m
])
1184 fr
.x
[i
][d
] -= fr
.box
[m
][d
];
1188 else if (bCluster
&& bTPS
) {
1191 calc_pbc_cluster(ecenter
,ifit
,&top
,ePBC
,fr
.x
,ind_fit
,com
,fr
.box
);
1195 /* Now modify the coords according to the flags,
1196 for normal fit, this is only done for output frames */
1198 rm_pbc(&(top
.idef
),ePBC
,natoms
,fr
.box
,fr
.x
,fr
.x
);
1200 reset_x_ndim(nfitdim
,ifit
,ind_fit
,natoms
,NULL
,fr
.x
,w_rls
);
1201 do_fit(natoms
,w_rls
,xp
,fr
.x
);
1204 /* store this set of coordinates for future use */
1205 if (bPFit
|| bNoJump
) {
1208 for(i
=0; (i
<natoms
); i
++) {
1209 copy_rvec(fr
.x
[i
],xp
[i
]);
1210 rvec_inc(fr
.x
[i
],x_shift
);
1215 /* see if we have a frame from the frame index group */
1216 for(i
=0; i
<nrfri
&& !bDumpFrame
; i
++)
1217 bDumpFrame
= frame
== frindex
[i
];
1218 if (debug
&& bDumpFrame
)
1219 fprintf(debug
,"dumping %d\n",frame
);
1222 ( ( !bTDump
&& !frindex
&& frame
% skip_nr
== 0 ) || bDumpFrame
);
1224 if (bWriteFrame
&& (bDropUnder
|| bDropOver
)) {
1225 while (dropval
[0][drop1
]<fr
.time
&& drop1
+1<ndrop
) {
1229 if (fabs(dropval
[0][drop0
] - fr
.time
)
1230 < fabs(dropval
[0][drop1
] - fr
.time
)) {
1235 if ((bDropUnder
&& dropval
[1][dropuse
] < dropunder
) ||
1236 (bDropOver
&& dropval
[1][dropuse
] > dropover
))
1237 bWriteFrame
= FALSE
;
1244 fr
.time
= tzero
+frame
*timestep
;
1250 fprintf(stderr
,"\nDumping frame at t= %g %s\n",
1251 output_env_conv_time(oenv
,fr
.time
),output_env_get_time_unit(oenv
));
1253 /* check for writing at each delta_t */
1254 bDoIt
=(delta_t
== 0);
1258 bDoIt
=bRmod(fr
.time
,tzero
, delta_t
);
1260 /* round() is not C89 compatible, so we do this: */
1261 bDoIt
=bRmod(floor(fr
.time
+0.5),floor(tzero
+0.5),
1262 floor(delta_t
+0.5));
1265 if (bDoIt
|| bTDump
) {
1266 /* print sometimes */
1267 if ( ((outframe
% SKIP
) == 0) || (outframe
< SKIP
) )
1268 fprintf(stderr
," -> frame %6d time %8.3f \r",
1269 outframe
,output_env_conv_time(oenv
,fr
.time
));
1272 /* Now modify the coords according to the flags,
1273 for PFit we did this already! */
1276 rm_pbc(&(top
.idef
),ePBC
,natoms
,fr
.box
,fr
.x
,fr
.x
);
1279 reset_x_ndim(nfitdim
,ifit
,ind_fit
,natoms
,NULL
,fr
.x
,w_rls
);
1281 do_fit_ndim(nfitdim
,natoms
,w_rls
,xp
,fr
.x
);
1283 for(i
=0; i
<natoms
; i
++)
1284 rvec_inc(fr
.x
[i
],x_shift
);
1288 center_x(ecenter
,fr
.x
,fr
.box
,natoms
,ncent
,cindex
);
1292 switch (unitcell_enum
) {
1294 put_atoms_in_box(fr
.box
,natoms
,fr
.x
);
1297 put_atoms_in_triclinic_unitcell(ecenter
,fr
.box
,natoms
,fr
.x
);
1300 warn
= put_atoms_in_compact_unitcell(ePBC
,ecenter
,fr
.box
,
1302 if (warn
&& !bWarnCompact
) {
1303 fprintf(stderr
,"\n%s\n",warn
);
1304 bWarnCompact
= TRUE
;
1310 put_residue_com_in_box(unitcell_enum
,ecenter
,
1311 natoms
,atoms
->atom
,ePBC
,fr
.box
,fr
.x
);
1314 put_molecule_com_in_box(unitcell_enum
,ecenter
,
1316 natoms
,atoms
->atom
,ePBC
,fr
.box
,fr
.x
);
1318 /* Copy the input trxframe struct to the output trxframe struct */
1320 frout
.natoms
= nout
;
1321 if (bNeedPrec
&& (bSetPrec
|| !fr
.bPrec
)) {
1333 for(i
=0; i
<nout
; i
++) {
1334 copy_rvec(fr
.x
[index
[i
]],frout
.x
[i
]);
1335 if (bVels
&& fr
.bV
) {
1336 copy_rvec(fr
.v
[index
[i
]],frout
.v
[i
]);
1338 if (bForce
&& fr
.bF
) {
1339 copy_rvec(fr
.f
[index
[i
]],frout
.f
[i
]);
1344 if (opt2parg_bSet("-shift",NPA
,pa
))
1345 for(i
=0; i
<nout
; i
++)
1346 for (d
=0; d
<DIM
; d
++)
1347 frout
.x
[i
][d
] += outframe
*shift
[d
];
1350 bSplitHere
= bSplit
&& bRmod(fr
.time
,tzero
, split_t
);
1353 /* round() is not C89 compatible, so we do this: */
1354 bSplitHere
= bSplit
&& bRmod(floor(fr
.time
+0.5),
1356 floor(split_t
+0.5));
1358 if (bSeparate
|| bSplitHere
)
1359 mk_filenm(outf_base
,ftp2ext(ftp
),nzero
,file_nr
,out_file2
);
1369 trxout
= open_trx(out_file2
,filemode
);
1372 if (my_clust
!= -1) {
1374 if (clust_status
[my_clust
] == -1) {
1375 sprintf(buf
,"%s.%s",clust
->grpname
[my_clust
],ftp2ext(ftp
));
1376 clust_status
[my_clust
] = open_trx(buf
,"w");
1379 else if (clust_status
[my_clust
] == -2)
1380 gmx_fatal(FARGS
,"File %s.xtc should still be open (%d open xtc files)\n""in order to write frame %d. my_clust = %d",
1381 clust
->grpname
[my_clust
],ntrxopen
,frame
,
1383 write_trxframe(clust_status
[my_clust
],&frout
,gc
);
1384 nfwritten
[my_clust
]++;
1385 if (nfwritten
[my_clust
] ==
1386 (clust
->clust
->index
[my_clust
+1]-
1387 clust
->clust
->index
[my_clust
])) {
1388 close_trx(clust_status
[my_clust
]);
1389 clust_status
[my_clust
] = -2;
1392 gmx_fatal(FARGS
,"Less than zero open xtc files!");
1397 write_trxframe(trxout
,&frout
,gc
);
1402 sprintf(title
,"Generated by trjconv : %s t= %9.5f",
1404 if (bSeparate
|| bSplitHere
)
1405 out
=ffopen(out_file2
,"w");
1408 write_hconf_p(out
,title
,&useatoms
,prec2ndec(frout
.prec
),
1409 frout
.x
,fr
.bV
?frout
.v
:NULL
,frout
.box
);
1412 fprintf(out
,"REMARK GENERATED BY TRJCONV\n");
1413 sprintf(title
,"%s t= %9.5f",top_title
,frout
.time
);
1414 /* if reading from pdb, we want to keep the original
1415 model numbering else we write the output frame
1416 number plus one, because model 0 is not allowed in pdb */
1417 if (ftpin
==efPDB
&& fr
.bStep
&& fr
.step
> model_nr
)
1421 write_pdbfile(out
,title
,&useatoms
,frout
.x
,
1422 frout
.ePBC
,frout
.box
,0,model_nr
,gc
);
1425 frout
.title
= title
;
1426 if (bSeparate
|| bTDump
) {
1427 frout
.bTitle
= TRUE
;
1429 frout
.bAtoms
= TRUE
;
1430 frout
.atoms
= &useatoms
;
1431 frout
.bStep
= FALSE
;
1432 frout
.bTime
= FALSE
;
1434 frout
.bTitle
= (outframe
== 0);
1435 frout
.bAtoms
= FALSE
;
1439 write_g96_conf(out
,&frout
,-1,NULL
);
1447 gmx_fatal(FARGS
,"DHE, ftp=%d\n",ftp
);
1449 if (bSeparate
|| bSplitHere
)
1452 /* execute command */
1455 sprintf(c
,"%s %d",exec_command
,file_nr
-1);
1456 /*fprintf(stderr,"Executing '%s'\n",c);*/
1457 #ifdef GMX_NO_SYSTEM
1458 printf("Warning-- No calls to system(3) supported on this platform.");
1459 printf("Warning-- Skipping execution of 'system(\"%s\")'.", c
);
1463 gmx_fatal(FARGS
,"Error executing command: %s",c
);
1471 bHaveNextFrame
=read_next_frame(oenv
,status
,&fr
);
1472 } while (!(bTDump
&& bDumpFrame
) && bHaveNextFrame
);
1475 if (!bHaveFirstFrame
|| (bTDump
&& !bDumpFrame
))
1476 fprintf(stderr
,"\nWARNING no output, "
1477 "last frame read at t=%g\n",fr
.time
);
1478 fprintf(stderr
,"\n");
1484 else if (out
!= NULL
)
1487 for(i
=0; (i
<clust
->clust
->nr
); i
++)
1488 if (clust_status
[i
] >= 0)
1489 close_trx(clust_status
[i
]);
1493 do_view(oenv
,out_file
,NULL
);