Allolib  1.0
C++ Components For Interactive Multimedia
al_Voxels.hpp
1 /* Allocore --
2  Multimedia / virtual environment application class library
3 
4  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
5  Copyright (C) 2012. The Regents of the University of California.
6  All rights reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  Redistributions of source code must retain the above copyright notice,
12  this list of conditions and the following disclaimer.
13 
14  Redistributions in binary form must reproduce the above copyright
15  notice, this list of conditions and the following disclaimer in the
16  documentation and/or other materials provided with the distribution.
17 
18  Neither the name of the University of California nor the names of its
19  contributors may be used to endorse or promote products derived from
20  this software without specific prior written permission.
21 
22  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  POSSIBILITY OF SUCH DAMAGE.
33 
34 
35  File description:
36  Voxel Array Class for scientific volumetric data, containing
37  physical metadata
38 
39  Base structure utilizes 3D AlloArray class, with support for
40  MRC file format
41 
42  File author(s):
43  Matt Wright, 2015, matt@create.ucsb.edu
44  Kon Hyong Kim, 2014, konhyong@gmail.com
45 */
46 
47 #ifndef INCLUDE_ALLO_VOXELS_HPP
48 #define INCLUDE_ALLO_VOXELS_HPP
49 
50 #include <cmath>
51 #include <fstream>
52 #include <iostream>
53 #include <sstream>
54 #include <string>
55 #include <vector>
56 #include "al/core/types/al_Conversion.hpp"
57 #include "al/util/al_Array.hpp"
58 
59 namespace al {
60 
61 typedef int UnitsTy;
62 
63 enum VoxelUnits {
64  VOX_PICOMETERS = -12,
65  VOX_ANGSTROMS = -10,
66  VOX_NANOMETERS = -9,
67  VOX_MICROMETERS = -6,
68  VOX_MILLIMETERS = -3,
69  VOX_CENTIMETERS = -2,
70  VOX_METERS = 0,
71  VOX_KILOMETERS = 3
72 };
73 
74 enum MRCMode {
75  MRC_IMAGE_SINT8 = 0, // image : signed 8-bit bytes range -128 to 127
76  MRC_IMAGE_SINT16 = 1, // image : 16-bit halfwords
77  MRC_IMAGE_FLOAT32 = 2, // image : 32-bit reals
78  MRC_TRANSFORM_INT16 = 3, // transform : complex 16-bit integers
79  MRC_TRANSFORM_FLOAT32 = 4, // transform : complex 32-bit reals
80  MRC_IMAGE_UINT16 = 6 // image : unsigned 16-bit range 0 to 65535
81 };
82 
83 struct MRCHeader {
84  // @see http://bio3d.colorado.edu/imod/doc/mrc_format.txt
85 
86  int32_t nx; /* # of Columns */
87  int32_t ny; /* # of Rows */
88  int32_t nz; /* # of Sections. */
89  int32_t mode; /* given by #define MRC_MODE... */
90 
91  int32_t nxstart; /* Starting point of sub image. */
92  int32_t nystart;
93  int32_t nzstart;
94 
95  int32_t mx; /* Number of intervals along x,y,z*/
96  int32_t my;
97  int32_t mz;
98 
99  float xlen; /* cell dimensions in angstroms */
100  float ylen; /* - MRC2014 standard */
101  float zlen;
102 
103  float alpha; /* cell angles */
104  float beta;
105  float gamma;
106 
107  int32_t mapx; /* map coloumn 1=x,2=y,3=z. */
108  int32_t mapy; /* map row 1=x,2=y,3=z. */
109  int32_t mapz; /* map section 1=x,2=y,3=z. */
110 
111  float amin; /* Minimum pixel value */
112  float amax; /* Maximum pixel value */
113  float amean; /* Mean pixel value */
114 
115  int16_t ispg; /* image type */
116  int16_t nsymbt; /* space group number */
117 
118  /* IMOD-SPECIFIC */
119  int32_t next;
120  int16_t creatid; /* Used to be creator id, hvem = 1000, now 0 */
121  char blank[30];
122  int16_t nint;
123  int16_t nreal;
124  int16_t sub;
125  int16_t zfac;
126  float min2;
127  float max2;
128  float min3;
129  float max3;
130  int32_t imodStamp;
131  int32_t imodFlags;
132  int16_t idtype;
133  int16_t lens;
134  int16_t nd1; /* Devide by 100 to get float value. */
135  int16_t nd2;
136  int16_t vd1;
137  int16_t vd2;
138  float tiltangles[6]; /* 0,1,2 = original: 3,4,5 = current */
139 
140  /* MRC 2000 standard */
141  float origin[3];
142  char cmap[4]; /* Contains "MAP " for LE, " PAM" for BE */
143  char machinestamp[4]; /* Little Endian : 68 65 17 17 // Big Endian : 17 17 65
144  68 */
145  float rms; /* RMS deviation of densities from mean density */
146 
147  int32_t nlabl; // number of labels
148  char labels[10][80];
149 };
150 
154 class Voxels : public Array {
155  public:
156  Voxels() : Array() { init(1, 1, 1, VOX_METERS); }
157 
160  Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz, float sizex,
161  float sizey, float sizez, UnitsTy units)
162  : Array(1, ty, dimx, dimy, dimz) {
163  init(sizex, sizey, sizez, units);
164  }
165 
168  Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz, float sizex,
169  float sizey, float sizez)
170  : Array(1, ty, dimx, dimy, dimz) {
171  init(sizex, sizey, sizez, VOX_METERS);
172  }
173 
176  Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz,
177  float voxelsize, UnitsTy units)
178  : Array(1, ty, dimx, dimy, dimz) {
179  init(voxelsize, voxelsize, voxelsize, units);
180  }
181 
183  Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz)
184  : Array(1, ty, dimx, dimy, dimz) {
185  init(1, 1, 1, VOX_METERS);
186  }
187 
188  void init(float voxWidthX, float voxWidthY, float voxWidthZ, UnitsTy units) {
189  m_voxWidth[0] = voxWidthX;
190  m_voxWidth[1] = voxWidthY;
191  m_voxWidth[2] = voxWidthZ;
192  m_units = units;
193  }
194 
195  float getVoxWidth(unsigned int axis) const { return m_voxWidth[axis]; }
196  void setVoxWidth(unsigned int axis, float voxWidth) {
197  m_voxWidth[axis] = voxWidth;
198  }
199 
200  std::string printVoxWidth(unsigned int axis) {
201  std::ostringstream ss;
202  ss << m_voxWidth[axis] << " " << printUnits(m_units);
203 
204  return ss.str();
205  }
206 
207  UnitsTy getUnits() const { return m_units; }
208  void setUnits(UnitsTy units) { m_units = units; }
209 
210  std::string printUnits() { return printUnits(m_units); }
211 
212  const std::string printUnits(UnitsTy t) {
213  if (t == VOX_ANGSTROMS) {
214  return "angstroms";
215  } else if (t == VOX_NANOMETERS) {
216  return "nm";
217  } else if (t == VOX_MICROMETERS) {
218  return "µm";
219  } else if (t == VOX_MILLIMETERS) {
220  return "mm";
221  } else if (t == VOX_CENTIMETERS) {
222  return "cm";
223  } else {
224  std::ostringstream ss;
225  ss << "(m*10^" << t << ")";
226  return ss.str();
227  }
228  }
229 
230  // functions to support MRC
231  MRCHeader &parseMRC(const char *data);
232 
233  bool loadFromMRC(std::string filename, bool update = false);
234 
235  bool loadFromMRC(std::string filename, UnitsTy ty, float voxWidth);
236 
237  bool loadFromMRC(std::string filename, UnitsTy ty, float voxWidthX,
238  float voxWidthY, float voxWidthZ);
239 
240  // functions for loading from images
241  bool getdir(std::string dir, std::vector<std::string> &files);
242 
243  bool parseInfo(std::string dir, std::vector<std::string> &data);
244 
245  bool loadFromDirectory(std::string dir);
246 
247  // functions for slicing
248  bool linePlaneIntersection(const Vec3f &P0, const Vec3f &P1,
249  const Vec3f &planeCenter, const Vec3f &planeNormal,
250  Vec3f *intersection);
251 
252  std::vector<Vec3f> linspace(Vec3f a, Vec3f b, int n);
253 
254  Vec3f point2Dto3D(Vec3f Q, Vec3f H, Vec3f K, float u, float v);
255 
256  bool parallelLinespace(Vec3f p0, Vec3f p1, Vec3f p2, Vec3f p3,
257  std::vector<Vec3f> &list, std::vector<Vec3f> &list2,
258  float aDirection, float oDirection,
259  std::vector<Vec3f> &points);
260 
261  Array slice(Vec3f planeCenter, Vec3f planeNormal,
262  std::vector<Vec3f> &finalPointList);
263 
264  // mostly for saving partial changes into mrc header.
265  bool writeToMRC(std::string filename, MRCHeader &header);
266 
267  // write/read files for voxel class
268  bool writeToFile(std::string filename);
269 
270  bool loadFromFile(std::string filename);
271 
272  void print(FILE *fp = stdout);
273 
274  float min() const { return m_min; }
275 
276  float max() const { return m_max; }
277 
278  float mean() const { return m_mean; }
279 
280  float rms() const { return m_rms; }
281 
282  ~Voxels() {}
283 
284  protected:
285  UnitsTy m_units;
286  float m_voxWidth[3];
287  float m_min, m_max, m_mean, m_rms;
288 };
289 
290 } // namespace al
291 
292 #endif /* INCLUDE_ALLO_VOXELS_HPP */
Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz, float sizex, float sizey, float sizez)
Definition: al_Voxels.hpp:168
Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz)
Construct dimx x dimy x dimz voxel grid with every voxel 1m x 1m x 1m.
Definition: al_Voxels.hpp:183
Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz, float voxelsize, UnitsTy units)
Definition: al_Voxels.hpp:176
Voxels(AlloTy ty, uint32_t dimx, uint32_t dimy, uint32_t dimz, float sizex, float sizey, float sizez, UnitsTy units)
Definition: al_Voxels.hpp:160
Definition: al_App.hpp:23
Vec< 3, float > Vec3f
float 3-vector
Definition: al_Vec.hpp:59