ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/xyz2pov/src/xyz2pov.c
Revision: 61
Committed: Thu Aug 1 21:12:33 2002 UTC (21 years, 11 months ago) by mmeineke
Content type: text/plain
File size: 12999 byte(s)
Log Message:
This commit was generated by cvs2svn to compensate for changes in r60, which
included commits to RCS files with non-trunk default branches.

File Contents

# User Rev Content
1 mmeineke 60 #include <stdio.h>
2     #include <stdlib.h>
3     #include <string.h>
4     #include <math.h>
5     #include <unistd.h>
6     #include <sys/types.h>
7     #include <sys/stat.h>
8    
9     #include "frameCount.h"
10     #include "atom_parser.h"
11     #include "pov_writer.h"
12    
13    
14     #define POV_DIR "./pov"
15    
16     struct linked_xyz{
17     struct coords *r;
18     struct linked_xyz *next;
19     };
20    
21     char *program_name; /*the name of the program */
22     int draw_bonds = 0; /* boolean to draw bonds or not */
23     int draw_hydrogens = 0; /*boolean to draw hydrogens */
24     int draw_atoms = 0; /*boolean to draw atoms */
25    
26     void usage(void);
27    
28     int main(argc, argv)
29     int argc;
30     char *argv[];
31     {
32    
33    
34     struct coords *out_coords;
35    
36     int i,j; /* loop counters */
37     mode_t dir_mode = S_IRWXU;
38    
39     int generate_header = 0; /* boolean for generating the pov ray header */
40     double big_x = 0;
41     double big_y = 0; /* lets me know the biggest x y and z */
42     double big_z = 0;
43     double small_x = 0;
44     double small_y = 0; /* lets me know the smallest x, y, z */
45     double small_z = 0;
46     double rsqr; /* the square of the diagonal */
47     double diagonal; /* the diagonal length of the sim box */
48    
49     unsigned int n_atoms; /*the number of atoms in each time step */
50     char read_buffer[120]; /*the line buffer for reading */
51     char *eof_test; /*ptr to see when we reach the end of the file */
52     char *foo; /*the pointer to the current string token */
53     FILE *in_file; /* the input file */
54     FILE *out_file; /*the output file */
55     char *out_prefix = NULL; /*the prefix of the output file */
56     int have_prefix = 0;
57     char out_name[500]; /*the output name */
58     char out_format[1000];
59     char *in_name = NULL; /*the name of the input file */
60     unsigned int n_out = 0; /*keeps track of which output file is being written*/
61     int done;
62     char current_flag;
63     int nFrames;
64     int nZeroes;
65     double count;
66    
67     struct linked_xyz *current_frame;
68     struct linked_xyz *temp_frame;
69    
70     unsigned int n_interpolate = 0; /* number of frames to interpolate */
71     double dx, dy, dz; /* temp variables for interpolating distances */
72    
73     char pov_dir[500]; /* the pov_dir */
74    
75     program_name = argv[0]; /*save the program name in case we need it*/
76    
77    
78     for( i = 1; i < argc; i++){
79    
80     if(argv[i][0] =='-'){
81    
82     // parse the option
83    
84     if(argv[i][1] == '-' ){
85    
86     // parse long word options
87    
88     fprintf( stderr,
89     "Invalid option \"%s\"\n", argv[i] );
90     usage();
91    
92     }
93    
94     else{
95    
96     // parse single character options
97    
98     done = 0;
99     j = 1;
100     current_flag = argv[i][j];
101     while( (current_flag != '\0') && (!done) ){
102    
103     switch(current_flag){
104    
105     case 'o':
106     // -o <prefix> => the output prefix.
107    
108     i++;
109     out_prefix = argv[i];
110     have_prefix = 1;
111     done = 1;
112     break;
113    
114     case 'i':
115     // -i <#> => the number to interpolate
116    
117     i++;
118     n_interpolate = atoi( argv[i] );
119     done = 1;
120     break;
121    
122     case 'H':
123     // -h => generate a pov-ray Header
124    
125     generate_header = 1;
126     break;
127    
128     case 'h':
129     // -h => draw Hydrogens
130    
131     draw_hydrogens = 1;
132     break;
133    
134     case 'b':
135     // -b => draw bonds
136    
137     draw_bonds = 1;
138     break;
139    
140     case 'a':
141     // -a => draw the atoms
142    
143     draw_atoms = 1;
144     break;
145    
146     default:
147    
148     (void)fprintf(stderr, "Bad option \"-%c\"\n", current_flag);
149     usage();
150     }
151     j++;
152     current_flag = argv[i][j];
153     }
154     }
155     }
156    
157     else{
158    
159     if( in_name != NULL ){
160     fprintf( stderr,
161     "Error at \"%s\", program does not currently support\n"
162     "more than one input file.\n"
163     "\n",
164     argv[i]);
165     usage();
166     }
167    
168     in_name = argv[i];
169     }
170     }
171    
172     if(in_name == NULL){
173     usage();
174     }
175    
176    
177    
178     in_file = fopen(in_name, "r");
179     if(in_file == NULL){
180     printf("Cannot open file: %s\n", in_name);
181     exit(8);
182     }
183    
184    
185    
186     if(access(POV_DIR, F_OK)){
187     /*create the pov directory*/
188     mkdir(POV_DIR, dir_mode);
189     }
190     strcpy(pov_dir, POV_DIR); strcat(pov_dir, "/");
191    
192    
193     // initialize atom type parser
194    
195     initializeParser();
196    
197     // count the number of frames
198    
199     printf( "Counting the number of frames..." );
200     fflush(stdout);
201    
202     nFrames = frameCount( in_name );
203    
204     printf( "done.\n"
205     "%d frames found\n",
206     nFrames);
207     fflush(stdout);
208    
209     // create the output string
210    
211     nZeroes = 1;
212     count = (double)( nFrames * (n_interpolate+1) );
213     while( count >= 10.0 ){
214     count /= 10.0;
215     nZeroes++;
216     }
217    
218     if(!have_prefix){
219     out_prefix = strtok(in_name, ".");
220     }
221    
222     sprintf( out_format, "%s%s%%0%dd.pov", pov_dir, out_prefix, nZeroes );
223    
224     // start reading the first frame
225    
226     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
227    
228     current_frame = (struct linked_xyz *)malloc(sizeof(struct linked_xyz));
229     current_frame->next = NULL;
230    
231    
232     while(eof_test != NULL){
233    
234     (void)sscanf(read_buffer, "%d", &n_atoms);
235     current_frame->r =
236     (struct coords *)calloc(n_atoms, sizeof(struct coords));
237    
238     /*read and toss the comment line */
239    
240     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
241     if(eof_test == NULL){
242     printf("error in reading file\n");
243     exit(8);
244     }
245    
246     for( i=0; i < n_atoms; i++){
247    
248     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
249     if(eof_test == NULL){
250     printf("error in reading file\n");
251     exit(8);
252     }
253    
254     foo = strtok(read_buffer, " ,;\t");
255     (void)strcpy(current_frame->r[i].name, foo); /*copy the atom name */
256    
257     /* next we grab the positions */
258    
259     foo = strtok(NULL, " ,;\t");
260     if(foo == NULL){
261     printf("error in reading file\n");
262     exit(8);
263     }
264     (void)sscanf(foo, "%lf",&current_frame->r[i].x);
265     if(current_frame->r[i].x > big_x) big_x = current_frame->r[i].x;
266     if(current_frame->r[i].x < small_x) small_x = current_frame->r[i].x;
267    
268    
269     foo = strtok(NULL, " ,;\t");
270     if(foo == NULL){
271     printf("error in reading file\n");
272     exit(8);
273     }
274     (void)sscanf(foo, "%lf", &current_frame->r[i].y);
275     if(current_frame->r[i].y > big_y) big_y = current_frame->r[i].y;
276     if(current_frame->r[i].y < small_y) small_y = current_frame->r[i].y;
277    
278    
279     foo = strtok(NULL, " ,;\t");
280     if(foo == NULL){
281     printf("error in reading file\n");
282     exit(8);
283     }
284     (void)sscanf(foo, "%lf", &current_frame->r[i].z);
285     if(current_frame->r[i].z > big_z) big_z = current_frame->r[i].z;
286     if(current_frame->r[i].z < small_z) small_z = current_frame->r[i].z;
287    
288     }
289    
290     if(n_interpolate && current_frame->next != NULL){
291    
292     temp_frame = current_frame->next;
293    
294     for(i = 0; i < n_interpolate; i++){
295    
296     /* open the new output file */
297    
298     sprintf(out_name, out_format, n_out );
299     out_file = fopen(out_name, "w");
300     n_out++;
301     if(out_file == NULL){
302     printf("error opening output file: %s\n", out_name);
303     exit(8);
304     }
305     (void)fprintf(out_file,
306     "// The following script was automatically generated by:\n"
307     "// xyz2pov Copyright 2001 by MATTHEW A. MEINEKE\n"
308     "\n"
309     "#include \"pov_header.pov\"\n"
310     "\n");
311    
312     out_coords =
313     (struct coords *)calloc(n_atoms, sizeof(struct coords));
314    
315     for(j=0; j < n_atoms; j++){
316     dx = current_frame->r[j].x - temp_frame->r[j].x;
317     dy = current_frame->r[j].y - temp_frame->r[j].y;
318     dz = current_frame->r[j].z - temp_frame->r[j].z;
319    
320     dx /= (double)(n_interpolate + 1);
321     dy /= (double)(n_interpolate + 1);
322     dz /= (double)(n_interpolate + 1);
323    
324     strcpy(out_coords[j].name, temp_frame->r[j].name);
325     out_coords[j].x = temp_frame->r[j].x + dx * (i+1);
326     out_coords[j].y = temp_frame->r[j].y + dy * (i+1);
327     out_coords[j].z = temp_frame->r[j].z + dz * (i+1);
328     }
329    
330     pov_write(out_file, out_coords, n_atoms, draw_hydrogens, draw_bonds,
331     draw_atoms);
332     free(out_coords);
333     (void)fclose(out_file);
334     }
335     }
336    
337     /* open the new output file */
338    
339     sprintf(out_name, out_format, n_out );
340     out_file = fopen(out_name, "w");
341     n_out++;
342     if(out_file == NULL){
343     printf("error opening output file: %s\n", out_name);
344     exit(8);
345     }
346     (void)fprintf(out_file,
347     "// The following script was automatically generated by:\n"
348     "// xyz2pov Copyright 2001 by MATTHEW A. MEINEKE\n"
349     "\n"
350     "#include \"pov_header.pov\"\n"
351     "\n");
352    
353     out_coords =
354     (struct coords *)calloc(n_atoms, sizeof(struct coords));
355    
356     for(i = 0; i < n_atoms; i++){
357     strcpy(out_coords[i].name, current_frame->r[i].name);
358     out_coords[i].x = current_frame->r[i].x;
359     out_coords[i].y = current_frame->r[i].y;
360     out_coords[i].z = current_frame->r[i].z;
361     }
362     pov_write(out_file, out_coords, n_atoms, draw_hydrogens, draw_bonds,
363     draw_atoms);
364     free(out_coords);
365    
366     (void)fclose(out_file);
367    
368     /*free up memory */
369    
370     temp_frame = current_frame->next;
371     current_frame->next = NULL;
372    
373     if(temp_frame != NULL){
374    
375     free(temp_frame->r);
376     free(temp_frame);
377     }
378    
379     /* make a new frame */
380    
381     temp_frame = (struct linked_xyz *)malloc(sizeof(struct linked_xyz));
382     temp_frame->next = current_frame;
383     current_frame = temp_frame;
384    
385     eof_test = fgets(read_buffer, sizeof(read_buffer), in_file);
386    
387     }
388    
389     (void)fclose(in_file);
390    
391    
392     if(generate_header){
393    
394     dx = big_x - small_x;
395     dy = big_y - small_y;
396     dz = big_z - small_z;
397    
398     rsqr = dx * dx + dy * dy + dz * dz;
399     diagonal = sqrt(rsqr);
400     diagonal *= 0.5;
401    
402     dx /= 2.0;
403     dy /= 2.0;
404     dz /= 2.0;
405    
406     dx += small_x;
407     dy += small_y;
408     dz += small_z;
409    
410    
411     /*note the y and z axis is exchanged for the different coordinate
412     system in pov-ray*/
413    
414    
415     out_file = fopen("pov_header.pov", "w");
416    
417     fprintf(out_file,
418     "// The following script was automatically generated by:\n"
419     "// xyz2pov Copyright 2001 by MATTHEW A. MEINEKE\n"
420     "\n"
421     "\n"
422     "background { rgb <1.0, 1.0, 1.0> }\n"
423     "\n"
424     "\n"
425     );
426    
427     fprintf(out_file,
428     "//******************************************************\n"
429     "// Declare the resolution, camera, and light sources.\n"
430     "//******************************************************\n"
431     "\n"
432     "// NOTE: if you plan to render at a different resoltion,\n"
433     "// be sure to update the following two lines to maintain\n"
434     "// the correct aspect ratio.\n"
435     "\n"
436     "#declare Width = 640.0;\n"
437     "#declare Height = 480.0;\n"
438     "#declare Ratio = Width / Height;\n"
439     "\n"
440     "#declare zoom = %lf;\n"
441     "\n"
442     "#declare ATOM_SPHERE_FACTOR = 0.2;\n"
443     "#declare BOND_RADIUS = 0.1;\n"
444     "\n"
445     "camera{\n"
446     " location < %lf, %lf, %lf - zoom>\n"
447     " right < Ratio , 0, 0>\n"
448     " look_at < %lf, %lf, %lf >\n"
449     "}\n"
450     "\n",
451     diagonal,
452     dx, dz, dy,
453     dx, dz, dy);
454    
455     fprintf(out_file,
456     "light_source{\n"
457     " < %lf, %lf, %lf - zoom >\n"
458     " rgb < 1.0, 1.0, 1.0 > }\n",
459     dx, dz, dy);
460    
461     fprintf(out_file,
462     "light_source{\n"
463     " < %lf - zoom , %lf + zoom, %lf - zoom >\n"
464     " rgb < 1.0, 1.0, 1.0 > }\n"
465     "\n"
466     "\n",
467     dx, dz, dy);
468    
469     fprintf(out_file,
470     "//************************************************************\n"
471     "// Set whether or not to rotate the system.\n"
472     "//\n"
473     "// To Rotate, set ROTATE to 1.0 (true),\n"
474     "// Then set the Euler Angles PHI, THETA, and PSI in degrees.\n"
475     "//************************************************************\n"
476     "\n"
477     "#declare ROTATE = 0.0;\n"
478     "#declare PHI = 0.0;\n"
479     "#declare THETA = 0.0;\n"
480     "#declare PSI = 0.0;\n"
481     "\n"
482     "#if(ROTATE)\n"
483     " #declare phi_r = radians(PHI);\n"
484     " #declare theta_r = radians(THETA);\n"
485     " #declare psi_r = radians(PSI);\n"
486     "\n"
487     " #declare A11 = cos(phi_r) * cos(psi_r) - sin(phi_r) * cos(theta_r) * sin(psi_r);\n"
488     " #declare A12 = sin(phi_r) * cos(psi_r) + cos(phi_r) * cos(theta_r) * sin(psi_r);\n"
489     " #declare A13 = sin(theta_r) * sin(psi_r);\n"
490     "\n"
491     " #declare A21 = -cos(phi_r) * sin(psi_r) - sin(phi_r) * cos(theta_r) * cos(psi_r);\n"
492     " #declare A22 = -sin(phi_r) * sin(psi_r) + cos(phi_r) * cos(theta_r) * cos(psi_r);\n"
493     " #declare A23 = sin(theta_r) * cos(psi_r);\n"
494     "\n"
495     " #declare A31 = sin(phi_r) * sin(theta_r);\n"
496     " #declare A32 = -cos(phi_r) * sin(theta_r);\n"
497     " #declare A33 = cos(theta_r);\n"
498     "\n"
499     "#end\n"
500     "\n");
501    
502    
503     make_header_macros(out_file);
504    
505     fclose(out_file);
506     }
507    
508     return 0;
509    
510     }
511    
512    
513    
514     /***************************************************************************
515     * prints out the usage for the command line arguments, then exits.
516     ***************************************************************************/
517    
518     void usage(){
519     (void)fprintf(stderr,
520     "The proper usage is: %s [options] <xyz_file>\n"
521     "\n"
522     "Options:\n"
523     "\n"
524     " -o <prefix> the output file prefix\n"
525     " -H generate a pov-ray header file\n"
526     " -i <#> number of frames to interpolate\n"
527     " -h draw hydrogens\n"
528     " -b draw bonds\n"
529     " -a draw atoms\n"
530     "\n",
531     program_name);
532     exit(8);
533     }