libatomprobe
Library for Atom Probe Tomography (APT) computation
ionhit.cpp
Go to the documentation of this file.
1 /*
2  * ionhit.cpp - Ion event data class
3  * Copyright (C) 2014 D Haley
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
21 
24 
25 #ifdef _OPENMP
26 #include <omp.h>
27 #endif
28 using std::vector;
30 
31 #include <fstream>
32 #include <limits>
33 #include <utility>
34 
35 namespace AtomProbe
36 {
37 
39 {
40  //At this point I deliberately don't initialise the point class
41  //as in DEBUG mode, the point class will catch failure to init
42 }
43 
44 IonHit::IonHit(float *buffer) : massToCharge(buffer[3]), pos(buffer)
45 {
46 }
47 
48 IonHit::IonHit(float x, float y, float z, float m) : massToCharge(m), pos(x,y,z)
49 {
50 }
51 
52 IonHit::IonHit(const IonHit &obj2) : massToCharge(obj2.massToCharge), pos(obj2.pos)
53 {
54 }
55 
56 IonHit::IonHit(const Point3D &p, float newMass) : massToCharge(newMass), pos(p)
57 {
58 }
59 
60 void IonHit::setMassToCharge(float newMass)
61 {
62  massToCharge=newMass;
63 }
64 
66 {
67  return massToCharge;
68 }
69 
70 void IonHit::setPos(unsigned int idx, float value)
71 {
72  ASSERT(idx < 3);
73  pos[idx]=value;
74 }
75 
76 void IonHit::setPos(const Point3D &p)
77 {
78  pos=p;
79 }
80 
81 #ifdef __LITTLE_ENDIAN__
82 void IonHit::switchEndian()
83 {
84 
85  pos.switchEndian();
86  floatSwapBytes(&(massToCharge));
87 }
88 #endif
89 
90 const IonHit &IonHit::operator=(const IonHit &obj)
91 {
92  massToCharge=obj.massToCharge;
93  pos = obj.pos;
94 
95  return *this;
96 }
97 
98 bool IonHit::operator==(const IonHit &obj) const
99 {
100  return massToCharge==obj.massToCharge && pos == obj.pos;
101 
102 }
104 {
105  pos+=obj;
106  return *this;
107 }
108 
109 void IonHit::getPoints(const vector<IonHit> &ions, vector<Point3D> &p)
110 {
111  p.resize(ions.size());
112 #pragma omp parallel for
113  for(size_t ui=0;ui<ions.size();ui++)
114  p[ui] = ions[ui].getPosRef();
115 }
116 
118 {
119  return pos;
120 }
121 
123 {
124  return (std::isnan(massToCharge) || std::isnan(pos[0]) ||
125  std::isnan(pos[1]) || std::isnan(pos[2]));
126 }
127 
128 void IonHit::getCentroid(const std::vector<IonHit> &points,Point3D &centroid)
129 {
130  centroid=Point3D(0,0,0);
131  size_t nPoints=points.size();
132 #ifdef _OPENMP
133 
134  //Parallel version
135  //--
136  vector<Point3D> centroids(omp_get_max_threads(),Point3D(0,0,0));
137 #pragma omp parallel for
138  for(size_t ui=0;ui<nPoints;ui++)
139  centroids[omp_get_thread_num()]+=points[ui].getPos();
140 
141  for(size_t ui=0;ui<centroids.size();ui++)
142  centroid+=centroids[ui];
143  //--
144 
145 #else
146  for(unsigned int ui=0;ui<nPoints;ui++)
147  centroid+=points[ui].getPos();
148 #endif
149 
150  centroid*=1.0f/(float)nPoints;
151 }
152 
153 void IonHit::getBoundCube(const std::vector<IonHit> &points,BoundCube &b)
154 {
155  ASSERT(points.size());
156 
157  float bounds[3][2];
158  for(unsigned int ui=0;ui<3;ui++)
159  {
160  bounds[ui][0]=std::numeric_limits<float>::max();
161  bounds[ui][1]=-std::numeric_limits<float>::max();
162  }
163 
164  for(unsigned int ui=0; ui<points.size(); ui++)
165  {
166  Point3D p;
167  p=points[ui].getPos();
168  for(unsigned int uj=0; uj<3; uj++)
169  {
170  bounds[uj][0] = std::min(p.getValue(uj),bounds[uj][0]);
171  bounds[uj][1] = std::max(p.getValue(uj),bounds[uj][1]);
172  }
173  }
174 
175  b.setBounds(bounds[0][0],bounds[1][0],
176  bounds[2][0],bounds[0][1],
177  bounds[1][1],bounds[2][1]);
178 
179 }
180 
181 std::ostream& operator<<(std::ostream &stream, const IonHit &ion)
182 {
183  stream << "(" << ion.getPos()[0] << "," << ion.getPos()[1] << "," << ion.getPos()[2] << "," << ion.getMassToCharge() << ")";
184  return stream;
185 }
186 
187 
188 BoundCube IonHit::getIonDataLimits(const std::vector<IonHit> &points)
189 {
190  ASSERT(points.size());
191 
192  BoundCube b;
193  b.setInverseLimits();
194 #ifndef OPENMP
195  float bounds[3][2];
196  for(unsigned int ui=0;ui<3;ui++)
197  {
198  bounds[ui][0]=std::numeric_limits<float>::max();
199  bounds[ui][1]=-std::numeric_limits<float>::max();
200  }
201 
202  for(unsigned int ui=0; ui<points.size(); ui++)
203  {
204 
205  for(unsigned int uj=0; uj<3; uj++)
206  {
207  Point3D p;
208  p=points[ui].getPos();
209  if(p.getValue(uj) < bounds[uj][0])
210  bounds[uj][0] = p.getValue(uj);
211 
212  if(p.getValue(uj) > bounds[uj][1])
213  bounds[uj][1] = p.getValue(uj);
214  }
215  }
216 
217  b.setBounds(bounds[0][0],bounds[1][0],
218  bounds[2][0],bounds[0][1],
219  bounds[1][1],bounds[2][1]);
220 #else
221  // parallel version
222  vector<BoundCube> cubes;
223 
224  unsigned int nT=omp_get_max_threads();
225  cubes.resize(nT);
226  for(unsigned int ui=0;ui<cubes.size();ui++)
227  cube[ui].setInverseLimits();
228 
229  unsigned int tCount=1;
230  #pragma omp parallel for reduction(tCount|+)
231  for(unsigned int ui=0;ui<points.size();ui++)
232  {
233  Point3D p;
234  p=points[ui].getPos();
235  for(unsigned int uj=0;uj<3;uj++)
236  {
237  b.setBounds(uj,0,std::min(b.getBound(uj,0),p[uj]));
238  b.setBounds(uj,1,std::min(b.getBound(uj,0),p[uj]));
239  }
240  }
241 
242  for(unsigned int ui=0;ui<std::min(tCount,nT);ui++)
243  b.expand(cubes[ui]);
244 
245 #endif
246 
247  return b;
248 }
249 
250 
251 float IonHit::operator[](unsigned int ui) const
252 {
253  ASSERT(ui <= 3);
254  if (ui < 3)
255  return pos[ui];
256  else
257  return massToCharge;
258 }
259 
260 float &IonHit::operator[](unsigned int ui)
261 {
262  ASSERT(ui <=3);
263  if (ui < 3)
264  return pos[ui];
265  else
266  return massToCharge;
267 }
268 
269 
270 
271 bool EPOS_ENTRY::operator==(const EPOS_ENTRY &obj) const
272 {
273  if(massToCharge != obj.massToCharge)
274  return false;
275  if(x!=obj.x || y != obj.y || z !=obj.z)
276  return false;
277  if(timeOfFlight!= obj.timeOfFlight)
278  return false;
279  if(voltDC != obj.voltDC)
280  return false;
281  if(voltPulse!= obj.voltPulse)
282  return false;
283  if(xDetector!= obj.xDetector || yDetector!=obj.yDetector)
284  return false;
285  if(deltaPulse!= obj.deltaPulse)
286  return false;
287  if(hitMultiplicity!= obj.hitMultiplicity)
288  return false;
289 
290  return true;
291 
292 }
293 
294 
295 
296 #ifdef DEBUG
297 
298 bool testIonHit()
299 {
300  //test the boundcube function
301  vector<IonHit> h;
302  IonHit hit;
303  hit.setMassToCharge(1);
304 
305  for(size_t ui=0;ui<8;ui++)
306  {
307  hit.setPos(Point3D(ui&4 >> 2,ui&2 >> 1,ui&1));
308  h.push_back(hit);
309  }
310 
311  BoundCube bc;
312  IonHit::getBoundCube(h,bc);
313  TEST(bc.isValid(),"check boundcube");
314 
315 
316  return true;
317 }
318 
319 
320 
321 #endif
322 };
void setInverseLimits()
Set the cube to be "inside out" at the limits of numeric results;.
Definition: boundcube.cpp:94
float massToCharge
Definition: ionHit.h:118
float z
Definition: ionHit.h:118
Point3D getPos() const
Definition: ionhit.cpp:117
float voltDC
Definition: ionHit.h:123
int32_t hitMultiplicity
Definition: ionHit.h:131
const IonHit & operator=(const IonHit &obj)
Definition: ionhit.cpp:90
friend std::ostream & operator<<(std::ostream &stream, const IonHit &)
Output streaming operator. Users (x,y,z,m) as format for output.
Definition: ionhit.cpp:181
float voltPulse
Definition: ionHit.h:123
const Point3D & getPosRef() const
Definition: ionHit.h:65
#define TEST(f, g)
Definition: aptAssert.h:49
IonHit operator+(const Point3D &obj)
Definition: ionhit.cpp:103
void setPos(const Point3D &pos)
Definition: ionhit.cpp:76
A 3D point data class storage.
Definition: point3D.h:39
float y
Definition: ionHit.h:118
float operator[](unsigned int ui) const
Definition: ionhit.cpp:251
static void getPoints(const std::vector< IonHit > &ions, std::vector< Point3D > &pts)
Definition: ionhit.cpp:109
float timeOfFlight
timeOfFlight in ns. Correction status does not appear to be specified
Definition: ionHit.h:123
bool operator==(const IonHit &obj) const
Definition: ionhit.cpp:98
float yDetector
Definition: ionHit.h:125
static BoundCube getIonDataLimits(const std::vector< IonHit > &points)
Definition: ionhit.cpp:188
float getMassToCharge() const
Definition: ionhit.cpp:65
float xDetector
X and Y coordinates on the detector in mm, nominally uncorrected.
Definition: ionHit.h:125
Definition: ionHit.h:113
static void getBoundCube(const std::vector< IonHit > &p, BoundCube &b)
Definition: ionhit.cpp:153
void floatSwapBytes(float *inFloat)
Definition: endianTest.h:58
Helper class to define a bounding cube.
Definition: boundcube.h:29
bool operator==(const EPOS_ENTRY &obj) const
Definition: ionhit.cpp:271
void setMassToCharge(float newMassToCharge)
Definition: ionhit.cpp:60
This is a data holding class for POS file ions, from.
Definition: ionHit.h:36
#define ASSERT(f)
int32_t deltaPulse
Definition: ionHit.h:131
static void getCentroid(const std::vector< IonHit > &points, Point3D &centroid)
Definition: ionhit.cpp:128
float getValue(unsigned int ui) const
Get value of ith dimension (0, 1, 2)
Definition: point3D.h:98
float x
Definition: ionHit.h:118
void setBounds(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax)
Set the bounds by passing in minima and maxima of each dimension.
Definition: boundcube.cpp:49