/[MITgcm]/MITgcm_contrib/high_res_cube/utils/average_fields.cpp
ViewVC logotype

Contents of /MITgcm_contrib/high_res_cube/utils/average_fields.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Sat Feb 19 15:42:13 2005 UTC (20 years, 4 months ago) by edhill
Branch: MAIN
CVS Tags: HEAD
Error occurred while calculating annotation data.
 o initial check-in

1 /*
2 * Average fields:
3 *
4 * This program averages n input files and outputs the result. It
5 * assumes that the inputs are all in single-precision IEEE-BE ("big
6 * endian") format. Internally, the averaging is done in IEEE double
7 * precision and the final result is converted back into IEEE-BE
8 * immediately before being written.
9 */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/mman.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20
21 #include <iostream>
22 #include <fstream>
23 #include <string>
24
25 #define uint32 unsigned int
26
27 #define BUF_SIZE 65536
28 #define htonl(A) ((((uint32)(A) & 0xff000000) >> 24) | \
29 (((uint32)(A) & 0x00ff0000) >> 8) | \
30 (((uint32)(A) & 0x0000ff00) << 8) | \
31 (((uint32)(A) & 0x000000ff) << 24))
32 #define bswap32(A) ( ((uint32)(A) >> 24) | \
33 (((uint32)(A) & 0x00ff0000) >> 8) | \
34 (((uint32)(A) & 0x0000ff00) << 8) | \
35 ((uint32)(A) << 24) )
36
37 int
38 main( int argc, char** argv )
39 {
40 char buff[BUF_SIZE];
41 int i;
42 int nbytes;
43 using namespace std;
44 struct stat st;
45 void * vptr;
46 double * dptr;
47 float * fptr;
48 uint32 u32;
49
50 if (argc < 4) {
51 cerr << "\nError: at least three file names must be supplied." << endl;
52 exit(1);
53 }
54
55 string fname(argv[1]);
56 stat(fname.c_str(), &st);
57 nbytes = st.st_size;
58 cout << "The file \"" << fname
59 << "\" has size: " << nbytes << " bytes" << endl;
60 int ndouble = nbytes/4;
61
62 dptr = new double[ndouble];
63 if (dptr == NULL) {
64 cerr << "\nError: unable to allocate sufficient memory." << endl;
65 exit(1);
66 }
67 for (int j=0; j<ndouble; j++) {
68 dptr[j] = 0.0;
69 }
70
71 for (i=1; i<(argc-1); i++) {
72 cout << " arg " << i << " is " << argv[i] << endl;
73
74 stat(argv[i], &st);
75 if (st.st_size != nbytes) {
76 cerr << "\nError: files size does not agree for file \""
77 << argv[i] << "\"." << endl;
78 exit(1);
79 }
80 int fd;
81 if ((fd = open(argv[i], O_RDONLY)) == -1) {
82 cerr << "\nError: can't open() file \"" << argv[i] << "\"." << endl;
83 exit(1);
84 }
85 vptr = mmap( (void *)0, (size_t)(nbytes),
86 PROT_READ, MAP_PRIVATE, fd, 0 );
87 if (vptr == NULL) {
88 cerr << "\nError: can't mmap() the file \"" << argv[i] << "\"." << endl;
89 exit(1);
90 }
91
92 // Average the fields
93 unsigned int * uip = (unsigned int *)(vptr);
94 for (int j=0; j<ndouble; j++) {
95 u32 = *uip;
96 unsigned int i32s = bswap32(u32);
97 float flt = *((float *)(&i32s));
98 // cout << " flt = " << flt << endl;
99 dptr[j] += double(flt);
100 uip++;
101 }
102
103 munmap(vptr, (size_t)(nbytes));
104 }
105
106 double denom = 1.0/double(argc - 2);
107 fptr = new float[ndouble];
108 for (int j=0; j<ndouble; j++) {
109 float flt = (float(denom * dptr[j]));
110 unsigned int i32s = bswap32(*((unsigned int *)(&flt)));
111 fptr[j] = *((float *)(&i32s));
112 }
113 i = argc - 1;
114 int fdo;
115 if ((fdo = open(argv[i], (O_CREAT | O_WRONLY),
116 (S_IRUSR | S_IWUSR))) == -1) {
117 cerr << "\nError: can't open() file \"" << argv[i] << "\"." << endl;
118 exit(1);
119 }
120 char * aptr = (char *)(fptr);
121 size_t inc_bytes_out;
122 size_t tot_bytes_out = 0;
123 bool write_needed = true;
124 while (write_needed) {
125 inc_bytes_out = write(fdo, (void *)(aptr + tot_bytes_out),
126 (size_t)(nbytes - tot_bytes_out));
127 tot_bytes_out += inc_bytes_out;
128 if ((inc_bytes_out == 0) && (fdo != -1))
129 write_needed = false;
130 }
131
132 delete[] dptr;
133 delete[] fptr;
134 return 0;
135 }

  ViewVC Help
Powered by ViewVC 1.1.22