ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/xyz2pov/src/xyz2pov.c
Revision: 508
Committed: Tue Apr 29 15:21:34 2003 UTC (21 years, 2 months ago) by mmeineke
Content type: text/plain
File size: 13210 byte(s)
Log Message:
added some stuff, and forgot to update. who knows whats different now.

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