source: util/VibrAlyzer.c@ 2f6525

Last change on this file since 2f6525 was 6c96f4, checked in by Frederik Heber <heber@…>, 17 years ago

lots of small changes

-1 as either freq_start or freq_step lets VibrAlyzer determine necessary start and step values automatically by considering smallest and greatest possible determinably frequencies. Used start and step values are printed.
In parsing temperatures and timesteps counter-1 instead of counter was used as array index.
outer loop over frequency was done in a overly-correct manner (extra j for the loop, now we calculate freq_end and check for that.
command line values of start and step are now multiplied with 2*2*M_PI, so that they match ranges in the plot later.
Parsing of values was checked and is correct.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/* Molecular Vibrations Analyser - VibrAlyzer
2 *
3 * This programme fourier transforms input from ESPACK (temperature output)
4 * in order to make the automated retrieval of vibrational frequencies possible.
5*/
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10
11/** Main routine.
12 * The routine needs a file name to be read as the temperature file, and also
13 * a frequency range (start and steps). Standard one-dimensional fourier-trans-
14 * formation via a simple discrete integration over the given values from the
15 * file is performed and the result returned on stdout.
16 * \param argc parameter count
17 * \param **argv array of parameter (array of chars)
18 * \return error code
19*/
20int main(int argc, char **argv)
21{
22 FILE *temperature_file; // file with temperature values
23 double *time_steps, *temperatures; // contain data value pairs
24 int counter; // keeps track of data pairs array size
25 double freq_start, freq_step, freq_end; // frequency start and step width (end determined by number of points in temp.file)
26 char *filename; // filename of temp.file
27 char line[255]; // line buffer for parsing the temperature file
28 int i; // runtime variable
29 double result, iresult; // temporary result value for fourier transformation
30 double frequency; // current frequency during dumb O(N^2) integration
31 double gauge; // conversion to atomic units for time axis
32
33 // Check for needed arguments
34 if (argc < 4) {
35 printf("Molecular Vibrations Analyser - VibrAlyzer\n\n");
36 printf("Usage: %s <time gauge> <freq.step> <temperature file>\n", argv[0]);
37 printf("\t<time gauge>\tConversion factor from step count to atomic time\n");
38 printf("\t<freq.start>\tstart of frequency for fourier transform in atomic units\n");
39 printf("\t<freq.step>\tstep width of frequency for fourier transform in atomic units\n");
40 printf("\t<temperature file>\tfile with (time step, temperature)-pairs\n");
41 exit(1);
42 } else {
43 gauge = atof(argv[1]);
44 freq_start = atof(argv[2]);
45 freq_step = atof(argv[3]);
46 filename = argv[4];
47 }
48
49 // read in file into buffer array
50 temperature_file=fopen(filename, "r");
51 if (temperature_file == NULL) { // check whether file could be opened
52 printf("Could not open temperature file named '%s'!\n", filename);
53 exit(255);
54 }
55 // check number of pairs
56 counter=0;
57 while (fgets(line,255, temperature_file)) {
58 sscanf(line,"%lg %lg", &result, &iresult);
59 counter++;
60 }
61 // ... allocate ...
62 time_steps = malloc(counter*sizeof(double));
63 temperatures = malloc(counter*sizeof(double));
64 fclose(temperature_file);
65 // ... and parse in
66 temperature_file=fopen(filename, "r");
67 counter=0;
68 while (fgets(line,255, temperature_file)) {
69 sscanf(line,"%lg %lg", &time_steps[counter], &temperatures[counter]);
70 //fprintf(stderr, "%lg\t%lg\n", time_steps[counter], temperatures[counter]);
71 counter++;
72 }
73 // auto-set good values for start and step based on step range
74 if ((freq_start == -1) || (freq_step == -1)) {
75 // we cannot detect frequencies above twice a time step and not below half the time range
76 freq_start = 1./(fabs(time_steps[counter-1] - time_steps[0])*gauge);
77 freq_step = ( 1./(fabs(time_steps[1] - time_steps[0])*gauge) - 1./(fabs(time_steps[counter-1] - time_steps[0])*gauge) )/counter;
78 fprintf(stderr, "Using %lg and frequency start and %lg as step size.\n", freq_start/(2.*2.*M_PI), freq_step/(2.*2.*M_PI));
79 } else {
80 freq_start *= (2.*2.*M_PI);
81 freq_step *= (2.*2.*M_PI);
82 }
83
84 // for debugging only: print read values
85 //for(i=0;i<(counter-1);i++) {
86 // printf("%lg\t%lg\n",time_steps[i],temperatures[i]);
87 //}
88
89 printf("#frequency(a.u.)\tcos\tsin");
90 // discretely integrate over desired frequency range
91 freq_end = freq_start+freq_step*counter-1;
92 for(frequency = freq_start;frequency < freq_end;frequency += freq_step) {
93 result = iresult = 0.;
94 for(i=0;i<(counter-1);i++) {
95 result += temperatures[i] * cos(frequency * time_steps[i]*gauge);
96 iresult += temperatures[i] * sin(frequency * time_steps[i]*gauge);
97 }
98 // NOTE: It is by definition freq over 2*pi, however as the temperature curve counts double (there are two
99 // standstills, one at the perihel one at the aphel!) we insert this factor to make the plots automatically
100 // have the correct frequency!
101 printf("%lg\t%lg\t%lg\n",frequency/(2.*2.*M_PI),result/(counter-1),iresult/(counter-1));
102 }
103
104 // dis'alloc and end
105 exit(0);
106}
Note: See TracBrowser for help on using the repository browser.