00001
00022 #include "DGVTransform.h"
00023
00024 DGVTransform::DGVTransform(QObject *parent) : QThread(parent)
00025 {
00026 reset();
00027 }
00028
00029 DGVTransform::~DGVTransform()
00030 {
00031 mutex.lock();
00032
00033 abort = true;
00034 if(isRunning())
00035 condition.wakeOne();
00036
00037 mutex.unlock();
00038
00039 wait();
00040 }
00041
00042 void DGVTransform::frt(DGVImage *image)
00043 {
00044 QMutexLocker locker(&mutex);
00045
00046 Array<imageType,2> bins;
00047 resultImage = new DGVImage;
00048
00049 if(image->data().cols() != image->data().rows())
00050 {
00051 cerr << "Transform ERROR: Data not correct size for FRT. Must be square. Size: " << image->data().rows() << "x" << image->data().cols() << endl;
00052 return;
00053 }
00054
00055 transform = FRT;
00056 inData = image->dataPtr();
00057 outData = &bins;
00058
00059 if (!isRunning())
00060 start();
00061 else
00062 condition.wakeOne();
00063
00064 if(alwaysWait)
00065 wait();
00066
00067 resultImage->setPixmap(bins);
00068
00069 emit resultAvailable(resultImage);
00070 }
00071
00072 void DGVTransform::frt(Array<imageType,2> &image)
00073 {
00074 QMutexLocker locker(&mutex);
00075
00076 if(image.cols() != image.rows())
00077 {
00078 cerr << "Transform ERROR: Data not correct size for FRT. Must be square. Size: " << image.rows() << "x" << image.cols() << endl;
00079 return;
00080 }
00081
00082 transform = FRT;
00083 inData = ℑ
00084 outData = &frtSpace;
00085
00086 if(!isRunning())
00087 start();
00088 else
00089 condition.wakeOne();
00090
00091 if(alwaysWait)
00092 wait();
00093 }
00094
00095 void DGVTransform::ifrt(DGVImage *bins)
00096 {
00098 Array<imageType,2> image;
00099
00100 transform = iFRT;
00101 RT.iFastRT(bins->data(),image);
00102
00103 DGVImage *resultImage = new DGVImage;
00104 resultImage->setPixmap(image);
00105
00106
00107 }
00108
00109 void DGVTransform::ifrt(Array<imageType,2> &bins)
00110 {
00111 QMutexLocker locker(&mutex);
00112
00113 transform = iFRT;
00114 inData = &bins;
00115 outData = &frtSpace;
00116
00117 if(!isRunning())
00118 start();
00119 else
00120 condition.wakeOne();
00121
00122 if(alwaysWait)
00123 wait();
00124 }
00125
00126 void DGVTransform::ifrtUnscaled(DGVImage *bins)
00127 {
00129 Array<imageType,2> image;
00130
00131 transform = iFRT_Unscaled;
00132 RT.iFastRT(bins->data(),image,false);
00133
00134 DGVImage *resultImage = new DGVImage;
00135 resultImage->setPixmap(image);
00136
00137
00138 }
00139
00140 void DGVTransform::ifrtUnscaled(Array<imageType,2> &bins)
00141 {
00142 QMutexLocker locker(&mutex);
00143
00144 transform = iFRT_Unscaled;
00145 inData = &bins;
00146 outData = &frtSpace;
00147
00148 if(!isRunning())
00149 start();
00150 else
00151 condition.wakeOne();
00152
00153 if(alwaysWait)
00154 wait();
00155 }
00156
00157 void DGVTransform::fft(Array<complex<imageType>,2> &image)
00158 {
00159 QMutexLocker locker(&mutex);
00160
00161 fftSpace.resize(image.rows(),image.cols());
00162
00163 transform = FFT;
00164 inComplexData = ℑ
00165 outComplexData = &fftSpace;
00166
00167 if(!isRunning())
00168 start();
00169 else
00170 condition.wakeOne();
00171
00172 if(alwaysWait)
00173 wait();
00174 }
00175
00176 void DGVTransform::ifft(Array<complex<imageType>,2> &kSpace)
00177 {
00178 QMutexLocker locker(&mutex);
00179
00180 fftSpace.resize(kSpace.rows(),kSpace.cols());
00181
00182 transform = iFFT;
00183 inComplexData = &kSpace;
00184 outComplexData = &fftSpace;
00185
00186 if(!isRunning())
00187 start();
00188 else
00189 condition.wakeOne();
00190
00191 if(alwaysWait)
00192 wait();
00193 }
00194
00195 void DGVTransform::fft_real(Array<imageType,2> &image)
00196 {
00197 QMutexLocker locker(&mutex);
00198
00199 fftSpace.resize(image.rows(),image.cols());
00200
00201 transform = FFT_Real;
00202 inData = ℑ
00203 outComplexData = &fftSpace;
00204
00205 if(!isRunning())
00206 start();
00207 else
00208 condition.wakeOne();
00209
00210 if(alwaysWait)
00211 wait();
00212 }
00213
00214 void DGVTransform::ifft_real(Array<complex<imageType>,2> &kSpace)
00215 {
00216 QMutexLocker locker(&mutex);
00217
00218 frtSpace.resize(kSpace.rows(),kSpace.cols());
00219
00220 transform = iFFT_Real;
00221 inComplexData = &kSpace;
00222 outData = &frtSpace;
00223
00224 if(!isRunning())
00225 start();
00226 else
00227 condition.wakeOne();
00228
00229 if(alwaysWait)
00230 wait();
00231 }
00232
00233 void DGVTransform::fft_1D(Array<complex<imageType>,1> &image)
00234 {
00235 QMutexLocker locker(&mutex);
00236
00237 fftSpace_1D.resize(image.size());
00238
00239 transform = FFT_1D;
00240 inComplexData_1D = ℑ
00241 outComplexData_1D = &fftSpace_1D;
00242
00243 if(!isRunning())
00244 start();
00245 else
00246 condition.wakeOne();
00247
00248 if(alwaysWait)
00249 wait();
00250 }
00251
00252 void DGVTransform::fft_1D(Array<complex<imageType>,2> &image)
00253 {
00254 QMutexLocker locker(&mutex);
00255
00256 fftSpace.resize(image.shape());
00257 fftSpace_1D.resize(image.cols());
00258
00259 transform = FFT_1D_Batch;
00260 inComplexData = ℑ
00261 outComplexData = &fftSpace;
00262
00263 if(!isRunning())
00264 start();
00265 else
00266 condition.wakeOne();
00267
00268 if(alwaysWait)
00269 wait();
00270 }
00271
00272 void DGVTransform::ifft_1D(Array<complex<imageType>,1> &kSpace)
00273 {
00274 QMutexLocker locker(&mutex);
00275
00276 fftSpace_1D.resize(kSpace.size());
00277
00278 transform = iFFT_1D;
00279 inComplexData_1D = &kSpace;
00280 outComplexData_1D = &fftSpace_1D;
00281
00282 if(!isRunning())
00283 start();
00284 else
00285 condition.wakeOne();
00286
00287 if(alwaysWait)
00288 wait();
00289 }
00290
00291 void DGVTransform::ifft_1D(Array<complex<imageType>,2> &kSpace)
00292 {
00293 QMutexLocker locker(&mutex);
00294
00295 fftSpace.resize(kSpace.shape());
00296 fftSpace_1D.resize(kSpace.cols());
00297
00298 transform = iFFT_1D_Batch;
00299 inComplexData = &kSpace;
00300 outComplexData = &fftSpace;
00301
00302 if(!isRunning())
00303 start();
00304 else
00305 condition.wakeOne();
00306
00307 if(alwaysWait)
00308 wait();
00309 }
00310
00311 void DGVTransform::fft_real_1D(Array<imageType,1> &image)
00312 {
00313 QMutexLocker locker(&mutex);
00314
00315 fftSpace_1D.resize(image.size());
00316
00317 transform = FFT_Real_1D;
00318 inData_1D = ℑ
00319 outComplexData_1D = &fftSpace_1D;
00320
00321 if(!isRunning())
00322 start();
00323 else
00324 condition.wakeOne();
00325
00326 if(alwaysWait)
00327 wait();
00328 }
00329
00330 void DGVTransform::fft_real_1D(Array<imageType,2> &image)
00331 {
00332 QMutexLocker locker(&mutex);
00333
00334 fftSpace.resize(image.shape());
00335 fftSpace_1D.resize(image.cols());
00336 frtSpace_1D.resize(image.cols());
00337
00338 transform = FFT_Real_1D_Batch;
00339 inData = ℑ
00340 outComplexData = &fftSpace;
00341
00342 if(!isRunning())
00343 start();
00344 else
00345 condition.wakeOne();
00346
00347 if(alwaysWait)
00348 wait();
00349 }
00350
00351 void DGVTransform::ifft_real_1D(Array<complex<imageType>,1> &kSpace)
00352 {
00353 QMutexLocker locker(&mutex);
00354
00355 frtSpace_1D.resize(kSpace.size());
00356
00357 transform = iFFT_Real_1D;
00358 inComplexData_1D = &kSpace;
00359 outData_1D = &frtSpace_1D;
00360
00361 if(!isRunning())
00362 start();
00363 else
00364 condition.wakeOne();
00365
00366 if(alwaysWait)
00367 wait();
00368 }
00369
00370 void DGVTransform::ifft_real_1D(Array<complex<imageType>,2> &kSpace)
00371 {
00372 QMutexLocker locker(&mutex);
00373
00374 frtSpace.resize(kSpace.shape());
00375 frtSpace_1D.resize(kSpace.cols());
00376 fftSpace_1D.resize(kSpace.cols());
00377
00378 transform = iFFT_Real_1D_Batch;
00379 inComplexData = &kSpace;
00380 outData = &frtSpace;
00381
00382 if(!isRunning())
00383 start();
00384 else
00385 condition.wakeOne();
00386
00387 if(alwaysWait)
00388 wait();
00389 }
00390
00391 void DGVTransform::radonSlices(Array<complex<imageType>,2> &kSpace)
00392 {
00393 QMutexLocker locker(&mutex);
00394
00395 fftSpace.resize(kSpace.shape());
00396
00397 transform = radonSlicing;
00398 inComplexData = &kSpace;
00399 outComplexData = &fftSpace;
00400
00401 if(!isRunning())
00402 start();
00403 else
00404 condition.wakeOne();
00405
00406 if(alwaysWait)
00407 wait();
00408 }
00409
00410 void DGVTransform::radonSlices(Array<imageType,2> &kSpace)
00411 {
00412 QMutexLocker locker(&mutex);
00413
00414 frtSpace.resize(kSpace.shape());
00415
00416 transform = radonSlicing_Real;
00417 inData = &kSpace;
00418 outData = &frtSpace;
00419
00420 if(!isRunning())
00421 start();
00422 else
00423 condition.wakeOne();
00424
00425 if(alwaysWait)
00426 wait();
00427 }
00428
00429 void DGVTransform::reset()
00430 {
00431 QMutexLocker locker(&mutex);
00432
00433 alwaysWait = false;
00434 abort = false;
00435 consoleAssigned = false;
00436 transform = None;
00437
00438 Fourier_1D.reset();
00439 Fourier.reset();
00440
00441 RT.setInitializer(0);
00442 RT.init();
00443 }
00444
00445 void DGVTransform::setConsole(DGVConsole *newConsole)
00446 {
00447 QMutexLocker locker(&mutex);
00448
00449 if(newConsole != NULL)
00450 {
00451 console = newConsole;
00452 consoleAssigned = true;
00453 }
00454 }
00455
00456 void DGVTransform::run()
00457 {
00458 QMutexLocker locker(&mutex);
00459
00460 QString strDuration;
00461 int duration = 0;
00462 QTime *timer = new QTime;
00463
00464 qApp->processEvents();
00465
00466 forever
00467 {
00468 if(abort)
00469 {
00470 delete timer;
00471 return;
00472 }
00473
00474 timer->start();
00475 switch(transform)
00476 {
00478 case FFT:
00479 Fourier.FFT(*inComplexData,*outComplexData);
00480
00481 emit resultAvailable(*outComplexData, "FFT-" + name);
00482 break;
00483 case iFFT:
00484 Fourier.iFFT(*inComplexData,*outComplexData);
00485
00486 emit resultAvailable(*outComplexData,"iFFT-" + name);
00487 break;
00488 case FFT_Real:
00489 Fourier.FFT_Real2Complex(*inData,*outComplexData);
00490
00491 emit resultAvailable(*outComplexData,"Real FFT-" + name);
00492 break;
00493 case iFFT_Real:
00494 Fourier.FFT_Complex2Real(*inComplexData,*outData);
00495
00496 emit resultAvailable(*outData,"Real iFFT-" + name);
00497 break;
00499 case FFT_1D:
00500 Fourier_1D.FFT(*inComplexData_1D,*outComplexData_1D);
00501
00502 emit resultAvailable(*outComplexData_1D,"1D FFT-" + name);
00503 break;
00504 case FFT_1D_Batch:
00505
00506
00507
00508 for(int j = 0; j < inComplexData->rows(); j ++)
00509 {
00510 fftSpace_1D = (*inComplexData)(j,Range::all());
00511
00512 Fourier_1D.FFT(fftSpace_1D,fftSpace_1D);
00513
00514 fftSpace(j,Range::all()) = fftSpace_1D;
00515 }
00516
00517 emit resultAvailable_1D(fftSpace,"1D FFTs-" + name);
00518 break;
00519 case iFFT_1D:
00520 Fourier_1D.iFFT(*inComplexData_1D,*outComplexData_1D);
00521
00522 emit resultAvailable(*outComplexData_1D,"1D iFFT-" + name);
00523 break;
00524 case iFFT_1D_Batch:
00525
00526
00527
00528 for(int j = 0; j < inComplexData->rows(); j ++)
00529 {
00530 fftSpace_1D = (*inComplexData)(j,Range::all());
00531
00532 Fourier_1D.iFFT(fftSpace_1D,fftSpace_1D);
00533
00534 fftSpace(j,Range::all()) = fftSpace_1D;
00535 }
00536
00537 emit resultAvailable_1D(fftSpace,"1D iFFTs-" + name);
00538 break;
00539 case FFT_Real_1D:
00540 Fourier_1D.FFT_Real2Complex(*inData_1D,*outComplexData_1D);
00541
00542 emit resultAvailable(*outComplexData_1D,"1D Real FFT-" + name);
00543 break;
00544 case FFT_Real_1D_Batch:
00545
00546
00547
00548 for(int j = 0; j < inData->rows(); j ++)
00549 {
00550 frtSpace_1D = (*inData)(j,Range::all());
00551
00552 Fourier_1D.FFT_Real2Complex(frtSpace_1D,fftSpace_1D);
00553
00554 fftSpace(j,Range::all()) = fftSpace_1D;
00555 }
00556
00557 emit resultAvailable_1D(fftSpace,"1D Real FFTs-" + name);
00558 break;
00559 case iFFT_Real_1D:
00560 Fourier_1D.FFT_Complex2Real(*inComplexData_1D,*outData_1D);
00561
00562 emit resultAvailable(*outData_1D,"1D Real iFFT-" + name);
00563 break;
00564 case iFFT_Real_1D_Batch:
00565
00566
00567
00568 for(int j = 0; j < inComplexData->rows(); j ++)
00569 {
00570 fftSpace_1D = (*inComplexData)(j,Range::all());
00571
00572 Fourier_1D.FFT_Complex2Real(fftSpace_1D,frtSpace_1D);
00573
00574 frtSpace(j,Range::all()) = frtSpace_1D;
00575 }
00576
00577 emit resultAvailable_1D(frtSpace,"1D Real iFFTs-" + name);
00578 break;
00580 case radonSlicing:
00581 RT.extractSlices(*inComplexData,*outComplexData);
00582
00583 emit resultAvailable_1D(*outComplexData,"Radon Slices-" + name);
00584 break;
00585 case radonSlicing_Real:
00586 RT.extractSlices(*inData,*outData);
00587
00588 emit resultAvailable_1D(*outData,"Radon Slices-" + name);
00589 break;
00591 case FRT:
00592 RT.FastRT(*inData,*outData);
00593
00594 emit resultAvailable(*outData,"FRT-" + name);
00595 break;
00596 case iFRT:
00597 RT.iFastRT(*inData,*outData);
00598
00599 emit resultAvailable(*outData,"iFRT-" + name);
00600 break;
00601 case iFRT_Unscaled:
00602 RT.iFastRT(*inData,*outData,false);
00603
00604 emit resultAvailable(*outData,"iFRT Unscaled-" + name);
00605 break;
00606 case None:
00607 cerr << "No Transform Selected, Results may be unexpected!" << endl;
00608 return;
00609 }
00610 duration = timer->elapsed();
00611
00612 if(consoleAssigned)
00613 console->printMessage("Transform took: " + strDuration.setNum(duration) + " ms");
00614 else
00615 cerr << ">| Solving Time Elapsed: " << duration << " ms" << endl;
00616
00617 qApp->processEvents();
00618
00619 condition.wait(&mutex);
00620 }
00621
00622 return;
00623 }