libatomprobe
Library for Atom Probe Tomography (APT) computation
kd-example.cpp
Go to the documentation of this file.
1 /* kd-example.cpp: Sample program for spatial searching (eg Nearest Neighbour)
2  * Copyright (C) 2014 Daniel Haley
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #include <iostream>
18 #include <cstdlib>
19 #include <sys/time.h>
20 
21 #include "atomprobe/atomprobe.h"
22 
23 using namespace std;
24 using namespace AtomProbe;
25 
26 unsigned int progress=0;
27 
28 #define TIME_START() timeval TIME_DEBUG_t; gettimeofday(&TIME_DEBUG_t,NULL);
29 #define TIME_END() float TIME_DELTA; {timeval TIME_DEBUG_tend; gettimeofday(&TIME_DEBUG_tend,NULL); \
30 TIME_DELTA=(TIME_DEBUG_tend.tv_sec - TIME_DEBUG_t.tv_sec) + ((float)TIME_DEBUG_tend.tv_usec-(float)TIME_DEBUG_t.tv_usec)/1.0e6;}
31 
32 
33 #ifndef M_PI
34 #define M_PI 3.141596254
35 #endif
36 
37 bool callback()
38 {
39  static unsigned int lastProgress=0;
40  if(lastProgress < progress)
41  {
42  cerr << ".";
43  lastProgress=progress+1;
44  }
45 
46  return true;
47 }
48 
49 int main()
50 {
51 
52  vector<IonHit> ions;
53 
54  unsigned int NUM_IONS=50000;
55  const float SCALE=100;
56  //initialise random number generator using
57  // current system time
58  srand(time(NULL));
59 
60 
61  ions.resize(NUM_IONS);
62  for(unsigned int ui=0;ui<NUM_IONS;ui++)
63  {
64 
65  float xyzm[4];
66  xyzm[0] = SCALE*((float)rand()/RAND_MAX-0.5);
67  xyzm[1] = SCALE*((float)rand()/RAND_MAX-0.5);
68  xyzm[2] = SCALE*((float)rand()/RAND_MAX-0.5);
69  xyzm[3] = SCALE*((float)rand()/RAND_MAX-0.5);
70  ions[ui].setHit(xyzm);
71  }
72 
73 
74  K3DTreeExact kdExact;
75 
76  //set progress callback
77  kdExact.setCallback(callback);
78  kdExact.setProgressPointer(&progress);
79  //set data - note that the ions will be taken by the tree by default.
80  // - this can be overridden. See docs for K3DTreeExact::resetPts
81  kdExact.resetPts(ions);
82 
83  cerr << "Building tree with " << NUM_IONS/(float)1000000 << " M ions..." << endl << " |";
84 
85  {
86  TIME_START();
87  //build tree
88  kdExact.build();
89 
90  TIME_END();
91  cerr << "| done, in " << TIME_DELTA << " seconds" << endl;
92  }
93 
94  BoundCube bc;
95  kdExact.getBoundCube(bc);
96 
97  //1NN search
98  {
99  TIME_START();
100 
101  cerr << "Finding all 1NNs...";
102 
103  //In parallel (if enabled), find all first NNs.
104  // if setTag = false, this does not modify the tree, so is safe to call in parallel
105  #pragma omp parallel for
106  for(size_t ui=0;ui<kdExact.size();ui++)
107  {
108  //find the nearest pt, but do not tag it
109  kdExact.findNearestUntagged(kdExact.getPtRef(ui),bc,false);
110  }
111  TIME_END();
112  cerr << "done, in " << TIME_DELTA << " seconds" << endl;
113 
114 
115  }
116 
117  //radius search, slow
118  const float SEARCH_RAD=4;
119  const float SIDE_RATIO= SEARCH_RAD/SCALE;
120  const float REL_VOLUME =4.0/3.0*M_PI*SIDE_RATIO*SIDE_RATIO*SIDE_RATIO*100.0;
121  cerr << "In a cube containing " << kdExact.size() << "points, of side length " << SCALE << endl;
122  cerr << " finding pts within " << SEARCH_RAD << "distance. (" << REL_VOLUME << "\% of points)" <<endl;
123  {
124 
125 
126  cerr << "Slow query" << endl;
127  double nPts=0;
128  TIME_START();
129  for(size_t ui=0;ui<kdExact.size();ui++)
130  {
131  vector<size_t> result;
132  kdExact.findUntaggedInRadius(kdExact.getPtRef(ui),bc,SEARCH_RAD,result);
133  nPts+=result.size();
134 
135  result.clear();
136  }
137  TIME_END();
138 
139 
140  cerr << " Average :" << nPts/(double)kdExact.size() << " pts around each other pt. Took ";
141  cerr << TIME_DELTA << " seconds" << endl;
142  }
143 
144  //radius search, fast
145  {
146  cerr << "Faster (bulk) query" << endl;
147  double nPts=0;
148  TIME_START();
149  for(size_t ui=0;ui<kdExact.size();ui++)
150  {
151  vector<size_t> result;
152  kdExact.ptsInSphere(kdExact.getPtRef(ui),SEARCH_RAD,result);
153  nPts+=result.size();
154 
155  result.clear();
156  }
157  TIME_END();
158 
159 
160  cerr << " Average :" << nPts/(double)kdExact.size() << " pts around each other pt. Took ";
161  cerr << TIME_DELTA << " seconds" << endl;
162  }
163 }
164 
#define TIME_START()
Definition: kd-example.cpp:28
void getBoundCube(BoundCube &b)
obtain the bounding rectangular prism volume for all elements in the KD tree
const unsigned int NUM_IONS
Definition: KDTest.cpp:26
void setProgressPointer(unsigned int *p)
bool callback()
Definition: kd-example.cpp:37
STL namespace.
3D specific KD tree
Definition: K3DTree-exact.h:54
void findUntaggedInRadius(const Point3D &queryPt, const BoundCube &b, float radius, std::vector< size_t > &result)
Find untagged points within a given radius.
void setCallback(bool(*cb)(void))
#define M_PI
Definition: kd-example.cpp:34
const float SCALE
Definition: KDTest.cpp:27
const float SEARCH_RAD
Definition: KDTest.cpp:28
Helper class to define a bounding cube.
Definition: boundcube.h:29
void resetPts(std::vector< Point3D > &pts, bool clear=true)
Supply points to KD tree. Ouput vector will be erased if clear=true.
bool build()
Build the KD tree using the previously supplied points.
int main()
Definition: kd-example.cpp:49
unsigned int progress
Definition: kd-example.cpp:26
size_t findNearestUntagged(const Point3D &queryPt, const BoundCube &b, bool tag=true)
Find the nearest "untagged" point&#39;s internal index.
#define TIME_END()
Definition: kd-example.cpp:29
const Point3D & getPtRef(size_t index) const
void ptsInSphere(const Point3D &origin, float radius, std::vector< size_t > &pts) const