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

# Content
1 #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
17 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 int regenerateBonds = 0; // boolean to regenearate bonds each frame
27
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
80 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 case 'r':
149 // -r => regenerate bonds
150
151 regenerateBonds = 1;
152 break;
153
154 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 initBondList();
205
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 " -r regenerate bond\n"
540 "\n",
541 program_name);
542 exit(8);
543 }