00001 #ifndef __DATASET_H__
00002 #define __DATASET_H__
00003
00004 #include <vuVector.h>
00005 #include <Utilities.h>
00006 #include <vuML.h>
00007 #include <Stats.h>
00008
00009 #include <assert.h>
00010
00011 #include <string>
00012 using namespace std;
00013
00014 #include <VVector.h>
00015 #include <VVectorFun.h>
00016 using namespace math;
00017
00018 #define MAX_NUM 2000000
00019
00020 enum GridType {CC, BCC};
00021
00023 class Dataset {
00024 public:
00025
00027 Dataset() {
00028 m_gridType = CC;
00029 m_dim[0] = 0;
00030 m_dim[1] = 0;
00031 m_dim[2] = 0;
00032 m_scaling = vuVector(1.);
00033 }
00034
00036 Dataset(GridType g) {
00037 m_gridType = g;
00038 m_dim[0] = 0;
00039 m_dim[1] = 0;
00040 m_dim[2] = 0;
00041 m_scaling = vuVector(1.);
00042 }
00043
00045 int getNumSamples() const {
00046 return m_dim[0] * m_dim[1] * m_dim[2];
00047 }
00048
00050 double& operator[](int i) {
00051 assert(i >= 0 && i < getNumSamples());
00052 return m_data[i];
00053 }
00054
00056 const double& operator[](int i) const {
00057 assert(i >= 0 && i < getNumSamples());
00058 return m_data[i];
00059 }
00060
00062 int getXDim() const { return m_dim[0]; }
00063
00065 int getYDim() const { return m_dim[1]; }
00066
00068 int getZDim() const { return m_dim[2]; }
00069
00071 Vector3i getDims() const { return Vector3i(m_dim); }
00072
00074 vuVector getScale() const { return m_scaling; }
00075
00077 GridType getGridType() const { return m_gridType; }
00078
00080 int lindex_cc(int x, int y, int z) const {
00081
00082 int xdim = getXDim();
00083 int ydim = getYDim();
00084 int zdim = getZDim();
00085
00086
00087 if ( x >= xdim ) x = xdim - 1;
00088 if ( x < 0 ) x = 0;
00089 if ( y >= ydim ) y = ydim - 1;
00090 if ( y < 0 ) y = 0;
00091 if ( z >= zdim ) z = zdim - 1;
00092 if ( z < 0 ) z = 0;
00093
00094 return x + y*xdim + z*xdim*ydim;
00095 }
00096
00098 int lindex_cc(const Vector3i& p) const { return this->lindex_cc(p[0], p[1], p[2]); }
00099
00101 Vector3i mindex_cc(int i) const {
00102 Vector3i mi;
00103 int x = getXDim();
00104 int y = getYDim();
00105 mi[0] = i % (x * y) % x;
00106 mi[1] = i % (x * y) / x;
00107 mi[2] = i / (x * y);
00108 return mi;
00109 }
00110
00112 static Vector3i index_bcc_to_cc(int x, int y, int z) {
00113
00114
00115
00116 assert( (ODD(x) && ODD(y) && ODD(z)) ||
00117 (EVEN(x) && EVEN(y) && EVEN(z)) );
00118
00119
00120 if ( ODD(z) ) {
00121 x--;
00122 y--;
00123 }
00124
00125
00126
00127 assert(EVEN(x) && EVEN(y));
00128 x >>= 1;
00129 y >>= 1;
00130
00131 return makeVec<int>(x, y, z);
00132 }
00133
00135 int lindex_bcc(const Vector3i& index_bcc) const {
00136 Vector3i index_cc = Dataset::index_bcc_to_cc(index_bcc[0], index_bcc[1], index_bcc[2]);
00137 return lindex_cc(index_cc);
00138 }
00139
00141 static Vector3i index_cc_to_bcc(int x, int y, int z) {
00142 x <<= 1;
00143 y <<= 1;
00144
00145
00146 if ( ODD(z) ) {
00147 x++;
00148 y++;
00149 }
00150
00151 assert( (ODD(x) && ODD(y) && ODD(z)) ||
00152 (EVEN(x) && EVEN(y) && EVEN(z)) );
00153
00154 return makeVec<int>(x, y, z);
00155 }
00156
00158 Vector3i mindex_bcc(int index) const {
00159 Vector3i index_cc = mindex_cc(index);
00160 return Dataset::index_cc_to_bcc(index_cc[0], index_cc[1], index_cc[2]);
00161 }
00162
00164 void print() const;
00165
00167 void read(const string& fullname);
00168
00170 void write(const string& outDir, const string& filename, const string& ext) const;
00171
00173 void setDim(int xdim, int ydim, int zdim) {
00174 m_dim[0] = xdim;
00175 m_dim[1] = ydim;
00176 m_dim[2] = zdim;
00177 assert(getNumSamples() <= MAX_NUM);
00178 }
00179
00181 void setGridType(GridType g) { m_gridType = g; }
00182
00184 void setScaling(const vuVector& s) { m_scaling = s; }
00185
00187 void copyAttribs(const Dataset& d);
00188
00190 static void whiteNoiseError(const Dataset& orig,
00191 const Dataset& noisy,
00192 double& mean,
00193 double& stdDev) {
00194 int numSamples = orig.getNumSamples();
00195 assert(numSamples == noisy.getNumSamples());
00196 assert(numSamples > 0 );
00197 double* diff = new double[numSamples];
00198
00199 int i;
00200 for ( i = 0; i < numSamples; i++ ) {
00201 diff[i] = orig.m_data[i] - noisy.m_data[i];
00202 }
00203
00204 mean = sampleMean(diff, numSamples);
00205 stdDev = sampleStdDev(diff, numSamples);
00206
00207 delete [] diff;
00208 diff = NULL;
00209 }
00210
00212 static void saltPepperError(const Dataset& orig,
00213 const Dataset& noisy,
00214 double& percentage) {
00215
00216
00217 int numSamples = orig.getNumSamples();
00218 assert(numSamples == noisy.getNumSamples());
00219 assert(numSamples > 0 );
00220
00221 int i;
00222 int numSalted = 0;
00223 for ( i = 0; i < numSamples; i++ ) {
00224 double nv = noisy.m_data[i];
00225 if ( orig.m_data[i] != nv ) {
00226 assert(EQUALS(nv, 0) || EQUALS(nv, MAX_INTENSITY));
00227 numSalted++;
00228 }
00229 }
00230
00231 percentage = double(numSalted)/double(numSamples);
00232 }
00233
00235
00238 static void denoiseErrorWithBoundaries(const Dataset& orig,
00239 const Dataset& denoised,
00240 double& mean,
00241 double& stdDev) {
00242 whiteNoiseError(orig, denoised, mean, stdDev);
00243 }
00244
00246 void getBoundingBox(Vector3i& min, Vector3i& max) const {
00247 min = Vector3i(0);
00248 if ( m_gridType == CC ) {
00249 max[0] = getXDim() - 1;
00250 max[1] = getYDim() - 1;
00251 max[2] = getZDim() - 1;
00252 }
00253 else {
00254 max[0] = getXDim()*2 - 1;
00255 max[1] = getYDim()*2 - 1;
00256 max[2] = getZDim() - 1;
00257 }
00258 }
00259
00261 bool isSampleInBoundary( int index, const double& filterRadius ) const {
00262 Vector3i min, max;
00263 getBoundingBox(min, max);
00264
00265 assert( filterRadius >= 0);
00266
00267 int padding = myCeil(filterRadius);
00268 min += padding;
00269 max -= padding;
00270
00271 Vector3i mindex;
00272 if ( m_gridType == CC ) {
00273 mindex = mindex_cc(index);
00274 }
00275 else {
00276 mindex = mindex_bcc(index);
00277 }
00278
00279 if ( mindex <= max && mindex >= min ) {
00280 return false;
00281 }
00282 return true;
00283 }
00284
00286
00291 static void denoiseErrorWithoutBoundaries(const Dataset& orig,
00292 const Dataset& denoised,
00293 double& mean,
00294 double& stdDev,
00295 const double& filterRadius) {
00296 int numSamples = orig.getNumSamples();
00297 assert(numSamples == denoised.getNumSamples());
00298 assert(numSamples > 0 );
00299 double* diff = new double[numSamples];
00300
00301 int i;
00302 int numSamplesSelected = 0;
00303 for ( i = 0; i < numSamples; i++ ) {
00304 if ( !orig.isSampleInBoundary(i, filterRadius) ) {
00305 diff[numSamplesSelected] = orig.m_data[i] - denoised.m_data[i];
00306 numSamplesSelected++;
00307 }
00308 }
00309
00310 mean = sampleMean(diff, numSamplesSelected);
00311 stdDev = sampleStdDev(diff, numSamplesSelected);
00312
00313 delete [] diff;
00314 diff = NULL;
00315 }
00316
00317 private:
00318
00319 void writeBytes(const string& outDir, const string& filename, const string& ext) const;
00320 void writeDoubles(const string& outDir, const string& filename) const;
00321 void readDoubles(const string& fullname);
00322
00323 GridType m_gridType;
00324 double m_data[MAX_NUM];
00325 int m_dim[3];
00326 vuVector m_scaling;
00327 };
00328
00329 #endif