Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
histogram.cpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2016 Finnish Meteorological Institute
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22#include <unistd.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <errno.h>
27#include <string.h>
28#include "histogram.h"
29
30void Histogram1D::save(const char* filename) const {
31
32 double* tempbuf;
33 tempbuf = new double[num_bins];
34 // MPI Reduce the histograms
35 MPI_Allreduce(bins, tempbuf, num_bins, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
36
37 int fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY,0644);
38 if(!fd || fd == -1) {
39 ERROR("unable to write histogram file %s: %s\n", filename, strerror(errno));
40 return;
41 }
42
43 for(ssize_t remain=sizeof(double) * num_bins; remain > 0;) {
44 remain -= write(fd, ((char*)tempbuf) + remain - sizeof(double) * num_bins, remain);
45 }
46
47 close(fd);
48}
49
50void Histogram1D::saveAscii(const char* filename) const {
51
52 FILE* f = fopen(filename, "w");
53 if(!f) {
54 ERROR("unable to write histogram file %s: %s\n", filename, strerror(errno));
55 return;
56 }
57
58 /* Generic histograms can only be written without bin bound specifiers.
59 * (Because how would we know them?) */
60 for(unsigned int i = 0; i < num_bins; i++) {
61 fprintf(f, "%lf\n", bins[i]);
62 }
63
64 fclose(f);
65}
66
67void LinearHistogram1D::saveAscii(const char* filename) const {
68
69 FILE* f = fopen(filename, "w");
70 if(!f) {
71 ERROR("unable to write histogram file %s: %s\n", filename, strerror(errno));
72 return;
73 }
74
75 /* Linear histograms are written with the center bin coordinate as
76 * first field */
77 for(unsigned int i = 0; i < num_bins; i++) {
78 fprintf(f, "%lf %lf\n", low + (i + .5) * (high - low) / num_bins, bins[i]);
79 }
80
81 fclose(f);
82}
83
84void Histogram1D::load(const char* filename) {
85 int fd = open(filename, O_RDONLY);
86 int ret;
87 if(!fd || fd==-1) {
88 ERROR("unable to open histogram file %s for reading: %s\n", filename, strerror(errno));
89 return;
90 }
91
92 /* TODO: Check filesize */
93 size_t size = sizeof(double) * num_bins;
94
95 for(ssize_t remain=size; remain > 0;) {
96 ret = read(fd, ((char*)bins) + remain - size, remain);
97 if(ret == 0 || !ret) {
98 /* TODO: Proper errorhandling here. */
99 break;
100 }
101 }
102
103 close(fd);
104}
105
106void Histogram2D::save(const char* filename) const {
107
108 double* tempbuf;
109 int num_bins_tot = num_bins[0] * num_bins[1];
110 tempbuf = new double[num_bins_tot];
111 // MPI Reduce the histograms
112 MPI_Allreduce(bins, tempbuf, num_bins_tot, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
113
114 int fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY,0644);
115 if(!fd || fd == -1) {
116 ERROR("unable to write histogram file %s: %s\n", filename, strerror(errno));
117 return;
118 }
119
120 size_t size = sizeof(double) * num_bins_tot;
121
122 for(ssize_t remain=size; remain > 0;) {
123 remain -= write(fd, ((char*)tempbuf) + remain - size, remain);
124 }
125
126 close(fd);
127}
128
129void Histogram2D::load(const char* filename) {
130 int fd = open(filename, O_RDONLY);
131 int ret;
132 if(!fd || fd == -1) {
133 ERROR("unable to open histogram file %s for reading: %s\n", filename, strerror(errno));
134 return;
135 }
136
137 /* TODO: Check filesize */
138 size_t size = sizeof(double) * num_bins[0] * num_bins[1];
139
140 for(ssize_t remain=size; remain > 0;) {
141 ret = read(fd, ((char*)bins) + remain - size, remain);
142 if(ret == 0 || !ret) {
143 /* TODO: Proper errorhandling here. */
144 ERROR("Read error: %s.\n", strerror(errno));
145 break;
146 }
147 remain -= ret;
148 }
149
150 close(fd);
151}
152
153void Histogram3D::save(const char* filename) const {
154
155 double* tempbuf;
156 int num_bins_tot = num_bins[0] * num_bins[1] * num_bins[2];
157 tempbuf = new double[num_bins_tot];
158 // MPI Reduce the histograms
159 MPI_Allreduce(bins, tempbuf, num_bins_tot, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
160
161 int fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644);
162 if(!fd || fd == -1) {
163 ERROR("unable to write histogram file %s: %s\n", filename, strerror(errno));
164 return;
165 }
166
167 size_t size = sizeof(float) * num_bins_tot;
168
169 for(ssize_t remain=size; remain > 0;) {
170 remain -= write(fd, ((char*)tempbuf) + remain - size, remain);
171 }
172
173 close(fd);
174}
175
176void Histogram3D::load(const char* filename) {
177 int fd = open(filename, O_RDONLY);
178 int ret;
179 if(!fd || fd == -1) {
180 ERROR("unable to open histogram file %s for reading: %s\n", filename, strerror(errno));
181 return;
182 }
183
184 /* TODO: Check filesize */
185 size_t size = sizeof(float) * num_bins[0] * num_bins[1] * num_bins[2];
186
187 for(ssize_t remain=size; remain > 0;) {
188 ret = read(fd, ((char*)bins) + remain - size, remain);
189 if(ret == 0 || !ret) {
190 /* TODO: Proper errorhandling here. */
191 ERROR("Read error: %s.\n", strerror(errno));
192 break;
193 }
194 remain -= ret;
195 }
196
197 close(fd);
198}
199
200void LinearHistogram2D::writeBovAscii(const char* filename, int index, const char* datafilename) {
201
202 FILE* f = fopen(filename, "w");
203 if(!f) {
204 ERROR("unable to write BOV ascii file %s: %s\n", filename, strerror(errno));
205 return;
206 }
207
208 fprintf(f, "TIME: %i\n", index);
209 fprintf(f, "DATA_FILE: %s\n", datafilename);
210 fprintf(f, "DATA_SIZE: %lu %lu 1\n", num_bins[0], num_bins[1]);
211 fprintf(f, "DATA_FORMAT: DOUBLE\nVARIABLE: f\nDATA_ENDIAN: LITTLE\nCENTERING: zonal\n");
212 fprintf(f, "BRICK_ORIGIN: %lf %lf 0\n", low[0], low[1]);
213 fprintf(f, "BRICK_SIZE: %lf %lf 1\n", high[0] - low[0], high[1] - low[1]);
214 fprintf(f, "DATA_COMPONENTS: 1\n");
215
216 fclose(f);
217}
218
219void LinearHistogram3D::writeBovAscii(const char* filename, int index, const char* datafilename) {
220
221 FILE* f = fopen(filename, "w");
222 if(!f) {
223 ERROR("unable to write BOV ascii file %s: %s\n", filename, strerror(errno));
224 return;
225 }
226
227 fprintf(f, "TIME: %i\n", index);
228 fprintf(f, "DATA_FILE: %s\n", datafilename);
229 fprintf(f, "DATA_SIZE: %lu %lu %lu\n", num_bins[0], num_bins[1], num_bins[2]);
230 fprintf(f, "DATA_FORMAT: FLOAT\nVARIABLE: f\nDATA_ENDIAN: LITTLE\nCENTERING: zonal\n");
231 fprintf(f, "BRICK_ORIGIN: %lf %lf %lf\n", low[0], low[1], low[2]);
232 fprintf(f, "BRICK_SIZE: %lf %lf %lf\n", high[0] - low[0], high[1] - low[1], high[2] - low[2]);
233 fprintf(f, "DATA_COMPONENTS: 1\n");
234
235 fclose(f);
236}
237
238void LinearHistogram3D::readBov(const char* filename) {
239 char buffer[256];
240 char datafilename[256];
241 Vec3d size;
242 bool filenameread=false;
243 FILE* f = fopen(filename, "r");
244 if(!f) {
245 ERROR("unable to read BOV ascii file %s: %s\n", filename, strerror(errno));
246 return;
247 }
248
249 while(!feof(f)) {
250 if(!fgets(buffer, 256, f)) {
251 break;
252 }
253
254 // Parse line data
255 if(!strncmp("DATA_FILE:", buffer, 10)) {
256 sscanf(buffer, "DATA_FILE: %s\n", datafilename);
257 filenameread = true;
258 continue;
259 }
260 if(!strncmp("BRICK_ORIGIN:", buffer, 13)) {
261 Vec3d l;
262 sscanf(buffer, "BRICK_ORIGIN: %lf %lf %lf", &l[0], &l[1], &l[2]);
263 low=l;
264 continue;
265 }
266 if(!strncmp("BRICK_SIZE:", buffer, 11)) {
267 Vec3d s;
268 sscanf(buffer, "BRICK_SIZE: %lf %lf %lf\n", &s[0], &s[1], &s[2]);
269 size = s;
270 high=low + size;
271 continue;
272 }
273 }
274
275 if(!filenameread) {
276 ERROR("BOV file %s did not contain a DATA_FILE statement!\n", filename);
277 fclose(f);
278 return;
279 }
280
281 // Load the actual histogram data from the data file
282 load(datafilename);
283 fclose(f);
284}
285
286/* --- Arithmetic operators for adding and/or substracting Histograms --- */
287
289 /* Check precondition: Both Histograms have to be same size and energy range */
290 if(num_bins[0] != other.num_bins[0] ||
291 num_bins[1] != other.num_bins[1] ||
292 low[0] != other.low[0] || low[1] != other.low[1] ||
293 high[0] != other.high[0] || high[1] != other.high[1]) {
294 ERROR("Attempted arithmetic on LinearHistogram2D with different bounds.\n");
295 return;
296 }
297
298 for(size_t j=0; j<num_bins[1]; j++) {
299 for(size_t i=0; i<num_bins[0]; i++) {
300 bins[j * num_bins[0] + i] += other.bins[j * num_bins[0] +i];
301 }
302 }
303}
304
306 /* Check precondition: Both Histograms have to be same size and energy range */
307 if(num_bins[0] != other.num_bins[0] ||
308 num_bins[1] != other.num_bins[1] ||
309 low[0] != other.low[0] || low[1] != other.low[1] ||
310 high[0] != other.high[0] || high[1] != other.high[1]) {
311 ERROR("Attempted arithmetic on LinearHistogram2D with different bounds.\n");
312 return;
313 }
314
315 for(size_t j=0; j<num_bins[1]; j++) {
316 for(size_t i=0; i<num_bins[0]; i++) {
317 bins[j * num_bins[0] + i] -= other.bins[j * num_bins[0] +i];
318 }
319 }
320}
321
323 /* Check precondition: Both Histograms have to be same size and energy range */
324 if(num_bins[0] != other.num_bins[0] ||
325 num_bins[1] != other.num_bins[1] ||
326 low[0] != other.low[0] || low[1] != other.low[1] ||
327 high[0] != other.high[0] || high[1] != other.high[1]) {
328 ERROR("Attempted arithmetic on LogHistogram2D with different bounds.\n");
329 return;
330 }
331
332 for(size_t j=0; j<num_bins[1]; j++) {
333 for(size_t i=0; i<num_bins[0]; i++) {
334 bins[j * num_bins[0] + i] += other.bins[j * num_bins[0] +i];
335 }
336 }
337}
338
340 /* Check precondition: Both Histograms have to be same size and energy range */
341 if(num_bins[0] != other.num_bins[0] ||
342 num_bins[1] != other.num_bins[1] ||
343 low[0] != other.low[0] || low[1] != other.low[1] ||
344 high[0] != other.high[0] || high[1] != other.high[1]) {
345 ERROR("Attempted arithmetic on LogHistogram2D with different bounds.\n");
346 return;
347 }
348
349 for(size_t j=0; j<num_bins[1]; j++) {
350 for(size_t i=0; i<num_bins[0]; i++) {
351 bins[j * num_bins[0] + i] -= other.bins[j * num_bins[0] +i];
352 }
353 }
354}
fclose(file)
for i
Definition Dispersion.m:24
double * bins
Definition histogram.h:74
virtual void saveAscii(const char *filename) const
Definition histogram.cpp:50
void save(const char *filename) const
Definition histogram.cpp:30
void load(const char *filename)
Definition histogram.cpp:84
size_t num_bins
Definition histogram.h:73
size_t num_bins[2]
Definition histogram.h:173
void load(const char *filename)
void save(const char *filename) const
double * bins
Definition histogram.h:174
size_t num_bins[3]
Definition histogram.h:421
void load(const char *filename)
float * bins
Definition histogram.h:422
void save(const char *filename) const
virtual void saveAscii(const char *filename) const
Definition histogram.cpp:67
LinearHistogram2D(size_t n[2], Vec2d _low, Vec2d _high)
Definition histogram.h:181
void operator+=(LinearHistogram2D &other)
void operator-=(LinearHistogram2D &other)
void writeBovAscii(const char *filename, int index, const char *datafilename)
void readBov(const char *filename)
void writeBovAscii(const char *filename, int index, const char *datafilename)
void operator-=(LogHistogram2D &other)
void operator+=(LogHistogram2D &other)
LogHistogram2D(size_t n[2], Vec2d _low, Vec2d _high)
Definition histogram.h:350
const int j
#define Vec3d
Definition histogram.h:28
#define ERROR(format,...)
Definition histogram.h:32
Logger & write(Logger &logger)
Definition logger.cpp:193
#define index(i, j, k)