OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
LaserProfile.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: LaserProfile.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.3.4.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: LaserProfile
10 //
11 // ------------------------------------------------------------------------
12 
14 #include "Utility/Inform.h"
17 
18 #include <boost/filesystem.hpp>
19 
20 #include <fstream>
21 #include <iostream>
22 #include <cmath>
23 
24 //#define TESTLASEREMISSION
25 
26 extern Inform *gmsg;
27 
28 LaserProfile::LaserProfile(const std::string &fileName,
29  const std::string &imageName,
30  double intensityCut,
31  short flags):
32  sizeX_m(0),
33  sizeY_m(0),
34  hist2d_m(NULL),
35  rng_m(NULL),
36  pdf_m(NULL),
37  centerMass_m(0.0),
38  standardDeviation_m(0.0){
39 
40  unsigned short *image = readFile(fileName, imageName);
41  // saveData("originalLaserProfile", image);
42 
43  if (flags & FLIPX) flipX(image);
44  if (flags & FLIPY) flipY(image);
45  if (flags & ROTATE90) {
46  swapXY(image);
47  flipX(image);
48  }
49  if (flags & ROTATE180) {
50  flipX(image);
51  flipY(image);
52  }
53  if (flags & ROTATE270) {
54  swapXY(image);
55  flipY(image);
56  }
57 
58  filterSpikes(image);
59  normalizeProfileData(intensityCut, image);
61  // saveData("processedLaserProfile", image);
62  fillHistrogram(image);
63 
64  delete[] image;
65 
66  setupRNG();
67 
68 #ifdef TESTLASEREMISSION
69  saveHistogram();
70  sampleDist();
71 #endif
72 
73  printInfo();
74 }
75 
77  gsl_histogram2d_pdf_free(pdf_m);
78  gsl_histogram2d_free(hist2d_m);
79  gsl_rng_free(rng_m);
80 }
81 
82 unsigned short * LaserProfile::readFile(const std::string &fileName,
83  const std::string &imageName) {
84  namespace fs = boost::filesystem;
85  if (!fs::exists(fileName)) {
86  throw OpalException("LaserProfile::readFile",
87  "given file '" + fileName + "' does not exist");
88  }
89 
90  size_t npos = fileName.find_last_of('.');
91  std::string ext = fileName.substr(npos + 1);
92 
93  unsigned short *image;
94  if (ext == "pgm") {
95  image = readPGMFile(fileName);
96  } else {
97  image = readHDF5File(fileName, imageName);
98  }
99 
100  return image;
101 }
102 
103 unsigned short * LaserProfile::readPGMFile(const std::string &fileName) {
104  PortableGraymapReader reader(fileName);
105 
106  sizeX_m = reader.getWidth();
107  sizeY_m = reader.getHeight();
108 
109  unsigned short *image = new unsigned short[sizeX_m * sizeY_m];
110  unsigned int idx = 0;
111  for (unsigned int i = 0; i < sizeX_m; ++ i) {
112  for (unsigned int j = 0; j < sizeY_m; ++ j, ++ idx) {
113  image[idx] = reader.getPixel(j, i);
114  }
115  }
116 
117  return image;
118 }
119 
120 unsigned short * LaserProfile::readHDF5File(const std::string &fileName,
121  const std::string &imageName) {
122 
123  hid_t h5 = H5Fopen(fileName.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
124  hid_t group = H5Gopen2 (h5, imageName.c_str(), H5P_DEFAULT);
125 
126  if (group < 0) {
127  throw OpalException("LaserProfile::readFile",
128  "given image name '" + imageName + "' does not exist");
129  }
130 
131  hsize_t dim[2];
132  hid_t dataSet = H5Dopen2 (group, "CameraData", H5P_DEFAULT);
133 
134  if (dataSet < 0) {
135  throw OpalException("LaserProfile::readFile",
136  "data set 'CameraData' does not exist");
137  }
138 
139  hid_t dataSetSpace = H5Dget_space(dataSet);
140  H5Sget_simple_extent_dims(dataSetSpace, dim, NULL);
141  hid_t filespace = H5Screate_simple(2, dim, NULL);
142 
143  sizeX_m = dim[0];
144  sizeY_m = dim[1];
145 
146  hsize_t startHyperslab[] = {0, 0};
147  hsize_t blockCount[] = {sizeX_m, sizeY_m};
148 
149  H5Sselect_hyperslab(filespace, H5S_SELECT_SET, startHyperslab, NULL, blockCount, NULL);
150 
151  unsigned short *image = new unsigned short [sizeX_m * sizeY_m];
152  hid_t mem = H5Screate_simple(2, blockCount, NULL);
153 
154  H5Dread(dataSet, H5T_NATIVE_USHORT, mem, filespace, H5P_DEFAULT, image);
155 
156  H5Sclose(mem);
157  H5Sclose(filespace);
158  H5Dclose(dataSetSpace);
159  H5Dclose(dataSet);
160  H5Gclose(group);
161  H5Fclose(h5);
162 
163  return image;
164 }
165 
166 void LaserProfile::flipX(unsigned short *image) {
167  unsigned int col2 = sizeX_m - 1;
168  for (unsigned int col1 = 0; col1 < col2; ++ col1, -- col2) {
169 
170  unsigned int pixel1 = col1 * sizeY_m;
171  unsigned int pixel2 = col2 * sizeY_m;
172  for (unsigned int row = 0; row < sizeY_m; ++ row) {
173  std::swap(image[pixel1 ++], image[pixel2 ++]);
174  }
175  }
176 }
177 
178 void LaserProfile::flipY(unsigned short *image) {
179  for (unsigned int col = 0; col < sizeX_m; ++ col) {
180 
181  unsigned int pixel1 = col * sizeY_m;
182  unsigned int pixel2 = (col + 1) * sizeY_m - 1;
183 
184  unsigned int row2 = sizeY_m - 1;
185  for (unsigned int row1 = 0; row1 < row2; ++ row1, -- row2) {
186  std::swap(image[pixel1 ++], image[pixel2 --]);
187  }
188  }
189 }
190 
191 void LaserProfile::swapXY(unsigned short *image) {
192  unsigned short *copy = new unsigned short [sizeX_m * sizeY_m];
193  for (unsigned int col = 0; col < sizeX_m; ++ col) {
194  for (unsigned int row = 0; row < sizeY_m; ++ row) {
195  unsigned int pixel1 = col * sizeY_m + row;
196  unsigned int pixel2 = row * sizeX_m + col;
197 
198  copy[pixel2] = image[pixel1];
199  }
200  }
201 
202  for (unsigned int pixel = 0; pixel < sizeX_m * sizeY_m; ++ pixel) {
203  image[pixel] = copy[pixel];
204  }
205 
206  delete[] copy;
207 
208  std::swap(sizeX_m, sizeY_m);
209 }
210 
211 void LaserProfile::filterSpikes(unsigned short *image) {
212  hsize_t idx = sizeY_m + 1;
213  hsize_t idxN = idx - sizeY_m;
214  hsize_t idxNW = idxN - 1, idxNE = idxN + 1;
215  hsize_t idxW = idx - 1, idxE = idx + 1;
216  hsize_t idxS = idx + sizeY_m;
217  hsize_t idxSW = idxS - 1, idxSE = idxS + 1;
218 
219  for (hsize_t i = 1; i < sizeX_m - 1; ++ i) {
220  for (hsize_t j = 1; j < sizeY_m - 1; ++ j) {
221 
222  if (image[idx] > 0) {
223  if (image[idxNW] == 0 &&
224  image[idxN] == 0 &&
225  image[idxNE] == 0 &&
226  image[idxW] == 0 &&
227  image[idxE] == 0 &&
228  image[idxSW] == 0 &&
229  image[idxS] == 0 &&
230  image[idxSE] == 0) {
231 
232  image[idx] = 0;
233  }
234  }
235 
236  ++ idxNW; ++ idxN; ++ idxNE;
237  ++ idxW; ++ idx; ++ idxE;
238  ++ idxSW; ++ idxS; ++ idxSE;
239  }
240  }
241 }
242 
243 void LaserProfile::normalizeProfileData(double intensityCut, unsigned short *image) {
244  unsigned short int profileMax = getProfileMax(image);
245 
246  unsigned int pixel = 0;
247  for (unsigned int col = 0; col < sizeX_m; ++ col) {
248  for(unsigned int row = 0; row < sizeY_m; ++ row, ++ pixel) {
249  double val = (double(image[pixel]) / profileMax - intensityCut) / (1.0 - intensityCut);
250 
251  val = std::max(0.0, val);
252  image[pixel] = std::floor(val * profileMax + 0.5);
253  }
254  }
255 }
256 
257 void LaserProfile::computeProfileStatistics(unsigned short *image) {
258  double totalMass = 0.0;
259  centerMass_m = Vector_t(0.0);
261 
262  unsigned int pixel = 0;
263  for(unsigned int col = 0; col < sizeX_m; ++ col) {
264  for(unsigned int row = 0; row < sizeY_m; ++ row, ++ pixel) {
265  double val = image[pixel];
266 
267  centerMass_m(0) += val * col;
268  centerMass_m(1) += val * row;
269  standardDeviation_m(0) += val * col*col;
270  standardDeviation_m(1) += val * row*row;
271  totalMass += val;
272  }
273  }
274 
275  centerMass_m /= totalMass;
276  standardDeviation_m(0) = sqrt(standardDeviation_m(0) / totalMass -
277  centerMass_m(0)*centerMass_m(0));
278  standardDeviation_m(1) = sqrt(standardDeviation_m(1) / totalMass -
279  centerMass_m(1)*centerMass_m(1));
280 }
281 
282 void LaserProfile::fillHistrogram(unsigned short *image) {
283  unsigned int histSizeX = sizeX_m;
284  unsigned int histSizeY = sizeY_m;
285  double histRangeX = histSizeX / standardDeviation_m(0) / 2;
286  double histRangeY = histSizeY / standardDeviation_m(1) / 2;
287  double binSizeX = 1.0 / standardDeviation_m(0);
288  double binSizeY = 1.0 / standardDeviation_m(1);
289 
290  hist2d_m = gsl_histogram2d_alloc(histSizeX, histSizeY);
291  gsl_histogram2d_set_ranges_uniform(hist2d_m,
292  -histRangeX, histRangeX,
293  -histRangeY, histRangeY);
294 
295 
296  unsigned int pixel = 0;
297  for (unsigned int col = 0; col < sizeX_m; ++ col) {
298  double x = (col - 0.5 * sizeX_m) / standardDeviation_m(0);
299  x = x + 0.5 * binSizeX;
300  // std::cout << "x = " << x << std::endl;
301 
302  for (unsigned int row = 0; row < sizeY_m; ++ row, ++ pixel) {
303  double val = image[pixel];
304  double y = -(row - 0.5 * sizeY_m) / standardDeviation_m(1);
305  y = y + 0.5 * binSizeY;
306  // if (col == 0)
307  // std::cout << "y = " << y << std::endl;
308 
309  gsl_histogram2d_accumulate(hist2d_m, x, y, val);
310  }
311  }
312  saveHistogram();
313 }
314 
316  unsigned int histSizeX = hist2d_m->nx, histSizeY = hist2d_m->ny;
317 
318  gsl_rng_env_setup();
319 
320  const gsl_rng_type *T = gsl_rng_default;
321  rng_m = gsl_rng_alloc(T);
322 
323  pdf_m = gsl_histogram2d_pdf_alloc(histSizeX, histSizeY);
324  gsl_histogram2d_pdf_init(pdf_m, hist2d_m);
325 }
326 
328  INFOMSG(level3 << "* **********************************************************************************\n");
329  INFOMSG("* LASER PROFILE \n");
330  INFOMSG("* size = " << sizeX_m << " x " << sizeY_m << " pixels \n");
331  INFOMSG("* center of mass: x = " << centerMass_m(0) << ", y = " << centerMass_m(1) << "\n");
332  INFOMSG("* standard deviation: x = " << standardDeviation_m(0) << ", y = " << standardDeviation_m(1) << "\n");
333  INFOMSG("* **********************************************************************************" << endl);
334 }
335 
336 void LaserProfile::saveData(const std::string &fname, unsigned short *image) {
337  std::ofstream out("data/" + fname + ".pgm");
338  out << "P2" << std::endl;
339  out << sizeX_m << " " << sizeY_m << std::endl;
340  out << getProfileMax(image) << std::endl;
341 
342  for (unsigned int j = 0; j < sizeY_m; ++ j) {
343  for (unsigned int i = 0; i < sizeX_m; ++ i) {
344  out << image[i * sizeY_m + j] << " ";
345  }
346  out << std::endl;
347  }
348 }
349 
351  FILE *fh = fopen("data/LaserHistogram.dat", "w");
352  gsl_histogram2d_fprintf(fh, hist2d_m, "%g", "%g");
353  fclose(fh);
354 }
355 
357  std::ofstream fh("data/LaserEmissionSampled.dat");
358  double x, y;
359 
360  for(int i = 0; i < 1000000; i++) {
361  getXY(x, y);
362  fh << x << "\t" << y << "\n";
363  }
364 
365  fh.close();
366 }
367 
368 void LaserProfile::getXY(double &x, double &y) {
369  double u = gsl_rng_uniform(rng_m);
370  double v = gsl_rng_uniform(rng_m);
371  gsl_histogram2d_pdf_sample(pdf_m, u, v, &x, &y);
372 }
373 
374 unsigned short LaserProfile::getProfileMax(unsigned short *image) {
375  unsigned int numberPixels = sizeX_m * sizeY_m;
376 
377  unsigned short maxIntensity = 0;
378 
379  for(unsigned int i = 0; i < numberPixels; i++) {
380  if(image[i] > maxIntensity)
381  maxIntensity = image[i];
382  }
383 
384  return maxIntensity;
385 }
LaserProfile(const std::string &fileName, const std::string &imageName, double intensityCut, short flags)
void flipY(unsigned short *image)
void getXY(double &x, double &y)
unsigned short getPixel(unsigned int i, unsigned int j) const
void saveData(const std::string &fname, unsigned short *image)
void filterSpikes(unsigned short *image)
Definition: rbendmap.h:8
void flipX(unsigned short *image)
unsigned int getHeight() const
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Inform * gmsg
Definition: Main.cpp:21
unsigned short * readHDF5File(const std::string &fileName, const std::string &imageName)
FRONT * fs
Definition: hypervolume.cpp:59
unsigned int getWidth() const
hsize_t sizeX_m
Definition: LaserProfile.h:62
gsl_rng * rng_m
Definition: LaserProfile.h:64
unsigned short getProfileMax(unsigned short *image)
Vector_t standardDeviation_m
Definition: LaserProfile.h:68
#define INFOMSG(msg)
Definition: IpplInfo.h:397
void fillHistrogram(unsigned short *image)
unsigned short * readFile(const std::string &fileName, const std::string &imageName)
unsigned short * readPGMFile(const std::string &fileName)
Vector_t centerMass_m
Definition: LaserProfile.h:67
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
void normalizeProfileData(double intensityCut, unsigned short *image)
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
void swapXY(unsigned short *image)
hsize_t sizeY_m
Definition: LaserProfile.h:62
gsl_histogram2d_pdf * pdf_m
Definition: LaserProfile.h:65
void saveHistogram()
gsl_histogram2d * hist2d_m
Definition: LaserProfile.h:63
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
void computeProfileStatistics(unsigned short *image)
Definition: Inform.h:41
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:816
Inform & endl(Inform &inf)
Definition: Inform.cpp:42