PSFEstimationwithCPSO
|
00001 /* 00002 * kippef.cpp 00003 * 00004 * Created on: 27/05/2012 00005 * Author: Peter Frank Perroni (pfperroni@inf.ufpr.br) 00006 */ 00007 00008 #include "kippef.hpp" 00009 00010 using namespace std; 00011 00019 void run_cpso(CPSO *cpso, fits_result *result, int n_cycles){ 00020 TimeTracker **trackers = NULL; 00021 #ifdef _TRACK_TIME_ 00022 // Create the trackers. 00023 int num_trackers = 6; 00024 trackers = new TimeTracker*[num_trackers]; 00025 trackers[0] = new TimeTracker("cpso"); 00026 trackers[1] = new TimeTracker("cycles"); 00027 trackers[2] = new TimeTracker("generatePhase"); 00028 trackers[3] = new TimeTracker("fft"); 00029 trackers[4] = new TimeTracker("matrix-operations"); 00030 trackers[5] = new TimeTracker("reduction"); 00031 #endif 00032 00033 TRACK(trackers[0]->resume()) 00034 cpso->run(trackers, n_cycles); 00035 TRACK(trackers[0]->pause()) 00036 00037 // Collect the best values found. 00038 cpso->getBestCoefs(result->coefs); 00039 cpso->getBestPhase(result->phase_generated); 00040 cpso->getBestPsfe(result->psf_generated); 00041 cpso->getBestConvolvedObject(result->conobj); 00042 CPSO::invertPsf(result->psf_generated, result->psf_inverted, cpso->getImageSize()); 00043 cpso->calcDifference(trackers, result->conobj, result->img_diff); 00044 00045 #ifdef _TRACK_TIME_ 00046 // Print tracking information. 00047 cout << "Time spent per piece of code:\n"; 00048 for (int i = 0; i < num_trackers; i++) { 00049 trackers[i]->end(); 00050 trackers[i]->print(); 00051 delete trackers[i]; 00052 } 00053 delete[] trackers; 00054 cout << "Stabilization at cycle: " << cpso->getStableCycle() << endl; 00055 #endif 00056 } 00057 00077 void validate_psf_file(char *psfFileName, char *objFileName, char *imgFileName, double* zernikes, int* diffraction_mask, int *phase_mask, 00078 int n_zernikes, int image_size, int phase_size, double range){ 00079 int img_area = image_size * image_size; 00080 double *psf = new double[img_area]; 00081 double *obj = new double[img_area]; 00082 double *img = new double[img_area]; 00083 00084 // Read the files. 00085 read_fits_file(psfFileName, psf, img_area); 00086 read_fits_file(objFileName, obj, img_area); 00087 read_fits_file(imgFileName, img, img_area); 00088 00089 // Initialize the OpenCl environment. 00090 clFactory::startup(); 00091 00092 // Load the data to memory. 00093 CPSO *cpso = new CPSO(zernikes, phase_mask, diffraction_mask, phase_size, image_size, n_zernikes, range, 0, 0, 0, 0, 1, 1); 00094 cpso->set_images(obj, img); 00095 00096 // Execute the validation. 00097 FFT_TYPE ret = cpso->validatePsf(psf); 00098 cout << "Final Image Difference: = " << ret.x << " distance with " << ret.y << " different points." << endl; 00099 00100 // Release the OpenCl data. 00101 cpso->release(); 00102 cpso->clear_static_data(); 00103 cpso->finalize_cl(); 00104 00105 // Finalize the OpenCl environment. 00106 clFactory::shutdown(); 00107 00108 delete psf; 00109 delete obj; 00110 delete img; 00111 delete cpso; 00112 } 00113 00114 void nollTest(double* object, double* zernikes, int* diffraction_mask, 00115 int n_zernikes, int image_size, int phase_size, double range, int *phase_mask, 00116 char *object_filename, vector<int> *_devices){ 00117 00118 cout << "Starting Noll testing..." << endl; 00119 00120 // CPSO Startup. 00121 PsfEstimator::startup(1, zernikes, phase_mask, diffraction_mask, phase_size, image_size, n_zernikes, range, 1.25, 1, 0.5, 0.25, 1, 1, _devices); 00122 00123 int image_area = image_size * image_size; 00124 ostringstream *oss = new ostringstream(); 00125 CPSO *cpso = NULL; 00126 WORD *coefs = new WORD[n_zernikes]; 00127 WORD *artificial_image1 = new WORD[image_area]; 00128 WORD *artificial_image2 = new WORD[image_area]; 00129 WORD *psfNoll1 = new WORD[image_area]; 00130 WORD *psfNoll2 = new WORD[image_area]; 00131 WORD *psfNollInv1 = new WORD[image_area]; 00132 WORD *psfNollInv2 = new WORD[image_area]; 00133 WORD *phase1 = new WORD[image_area]; 00134 WORD *phase2 = new WORD[image_area]; 00135 00136 for(int i=0; i < n_zernikes; i++) coefs[i] = 0; 00137 coefs[(int)(rand() / (WORD)RAND_MAX) * (n_zernikes-1)] = CPSO::randNormalDistribution(0, range / 4); 00138 00139 // Generate a random image. 00140 cpso = PsfEstimator::getCPSO(object, object, coefs); 00141 cpso->runPsf(NULL, 1); 00142 cpso->saveFirstResult(); 00143 cpso->getBestCoefs(coefs); 00144 cpso->getBestConvolvedObject(artificial_image1); 00145 cpso->getBestPsfe(psfNoll1); 00146 cpso->getBestPhase(phase1); 00147 *oss << object_filename << "-noll-image-artificial.fits"; 00148 write_fits_file((char*)oss->str().c_str(), artificial_image1, image_size, image_size); 00149 oss->str(""); 00150 CPSO::invertPsf(psfNoll1, psfNollInv1, image_size); 00151 *oss << object_filename << "-noll-psfinv.fits"; 00152 write_fits_file((char*)oss->str().c_str(), psfNollInv1, image_size, image_size); 00153 oss->str(""); 00154 cpso->release(); 00155 00156 // Inverse the coefficients. 00157 for(int i=0; i < n_zernikes; i++) coefs[i] *= -1; 00158 00159 // Generate a new artificial image with the coefficients inverted. 00160 cpso = PsfEstimator::getCPSO(object, object, coefs); 00161 cpso->runPsf(NULL, 1); 00162 cpso->saveFirstResult(); 00163 cpso->getBestConvolvedObject(artificial_image2); 00164 cpso->getBestPsfe(psfNoll2); 00165 cpso->getBestPhase(phase2); 00166 *oss << object_filename << "-nollinv-image-artificial.fits"; 00167 write_fits_file((char*)oss->str().c_str(), artificial_image2, image_size, image_size); 00168 oss->str(""); 00169 CPSO::invertPsf(psfNoll2, psfNollInv2, image_size); 00170 *oss << object_filename << "-nollinv-psfinv.fits"; 00171 write_fits_file((char*)oss->str().c_str(), psfNollInv2, image_size, image_size); 00172 cpso->release(); 00173 00174 double sum = 0; 00175 for(int i=0; i < image_area; i++) sum += abs(psfNollInv1[i] - psfNollInv2[i]); 00176 printf("Difference: %lf", sum); 00177 00178 delete cpso; 00179 delete artificial_image1; 00180 delete artificial_image2; 00181 delete coefs; 00182 delete psfNoll1; 00183 delete psfNoll2; 00184 delete psfNollInv1; 00185 delete psfNollInv2; 00186 delete phase1; 00187 delete phase2; 00188 delete oss; 00189 00190 cout << "Noll testing done." << endl; 00191 } 00192 00222 void validate_psfcode(double* object, double* zernikes, int* diffraction_mask, 00223 int n_zernikes, int image_size, int phase_size, double range, int *phase_mask, 00224 char *object_filename, int n_validations, int rank_size, vector<int> *_devices, 00225 int poisson, int parallel){ 00226 00227 TimeTracker **trackers = NULL; 00228 #ifdef _TRACK_TIME_ 00229 // Create the trackers. 00230 TimeTracker tracker_estimation("single-estimation"); 00231 int num_trackers = 6; 00232 trackers = new TimeTracker*[num_trackers]; 00233 trackers[0] = new TimeTracker("cpso"); 00234 trackers[1] = new TimeTracker("cycles"); 00235 trackers[2] = new TimeTracker("generatePhase"); 00236 trackers[3] = new TimeTracker("fft"); 00237 trackers[4] = new TimeTracker("matrix-operations"); 00238 trackers[5] = new TimeTracker("reduction"); 00239 #endif 00240 00241 TRACK(trackers[0]->resume()) 00242 cout << "Starting validations..." << endl; 00243 00244 // CPSO Startup. 00245 PsfEstimator::startup(parallel, zernikes, phase_mask, diffraction_mask, phase_size, image_size, n_zernikes, range, 1.25, 1, 0.5, 0.25, 1, 1, _devices); 00246 00247 int size_fft = phase_size * phase_size; 00248 int image_area = image_size * image_size; 00249 WORD total_cost = 0; 00250 CPSO *cpso = NULL; 00251 // Validate the PSF reconstruction algorithm. 00252 omp_set_num_threads(parallel); 00253 #pragma omp parallel for shared(trackers, object, total_cost) \ 00254 firstprivate(n_validations, n_zernikes, image_area, size_fft, cpso) \ 00255 default(none) 00256 for(int i=0; i < n_validations; i++){ 00257 WORD *coefs = new WORD[n_zernikes]; 00258 WORD *conobj = new WORD[image_area]; 00259 cpso = PsfEstimator::getCPSO(object, object); 00260 // Calculates 1 random PSF and the artificial corrupted image. 00261 cpso->runPsf(trackers, 1); 00262 // Save the results. 00263 cpso->saveFirstResult(); 00264 cpso->getBestCoefs(coefs); 00265 cpso->getBestConvolvedObject(conobj); // Artificial Corrupted Image. 00266 cpso->release(); 00267 00268 // Convert to double, if necessary. 00269 #ifdef _DOUBLE_WORD_ 00270 double *artificial_image = conobj; 00271 #else 00272 double *artificial_image = new double[size_fft]; 00273 for(int j=0; j < image_area; j++) artificial_image[j] = conobj[j]; 00274 #endif 00275 00276 // Calculates how far it goes from the artificial corrupted image 00277 // by using the same coefficients and running 1 single time. 00278 cpso = PsfEstimator::getCPSO(object, artificial_image, coefs); 00279 cpso->run(trackers, 1); 00280 00281 // Sum the difference from the artificial image. 00282 #pragma omp critical (total_cost) 00283 total_cost += cpso->getGBestCost(); 00284 00285 cpso->release(); 00286 00287 delete coefs; 00288 delete conobj; 00289 #ifndef _DOUBLE_WORD_ 00290 delete artificial_image; 00291 #endif 00292 } 00293 // The Total Cost must be something really small (something between 0 and 2). 00294 cout << "Total difference for " << n_validations << " validations: " << total_cost << endl; 00295 00296 int best_pos, worst_pos; 00297 WORD best_costs[rank_size], worst_costs[rank_size], curr_cost; 00298 WORD *psf = new WORD[image_area]; 00299 WORD *phase = new WORD[size_fft]; 00300 WORD *image = new WORD[image_area]; 00301 WORD *coefs = new WORD[n_zernikes]; 00302 FFT_TYPE *object_fft = new FFT_TYPE[image_area]; 00303 FFT_TYPE *psf_fft = new FFT_TYPE[image_area]; 00304 FFT_TYPE *image_fft = new FFT_TYPE[image_area]; 00305 00306 WORD *best_artificial_psf = new WORD[image_area * rank_size]; 00307 WORD *best_artificial_phase = new WORD[size_fft * rank_size]; 00308 WORD *best_artificial_image = new WORD[image_area * rank_size]; 00309 WORD *best_coefs = new WORD[n_zernikes * rank_size]; 00310 WORD *best_psf = new WORD[image_area * rank_size]; 00311 WORD *best_phase = new WORD[size_fft * rank_size]; 00312 WORD *best_image = new WORD[image_area * rank_size]; 00313 WORD *best_imgdiff = new WORD[image_area * rank_size]; 00314 FFT_TYPE *best_artificial_psf_fft = new FFT_TYPE[image_area * rank_size]; 00315 FFT_TYPE *best_artificial_image_fft = new FFT_TYPE[image_area * rank_size]; 00316 FFT_TYPE *best_psf_fft = new FFT_TYPE[image_area * rank_size]; 00317 FFT_TYPE *best_image_fft = new FFT_TYPE[image_area * rank_size]; 00318 00319 WORD *worst_artificial_psf = new WORD[image_area * rank_size]; 00320 WORD *worst_artificial_phase = new WORD[size_fft * rank_size]; 00321 WORD *worst_artificial_image = new WORD[image_area * rank_size]; 00322 WORD *worst_coefs = new WORD[n_zernikes * rank_size]; 00323 WORD *worst_psf = new WORD[image_area * rank_size]; 00324 WORD *worst_phase = new WORD[size_fft * rank_size]; 00325 WORD *worst_image = new WORD[image_area * rank_size]; 00326 WORD *worst_imgdiff = new WORD[image_area * rank_size]; 00327 FFT_TYPE *worst_artificial_psf_fft = new FFT_TYPE[image_area * rank_size]; 00328 FFT_TYPE *worst_artificial_image_fft = new FFT_TYPE[image_area * rank_size]; 00329 FFT_TYPE *worst_psf_fft = new FFT_TYPE[image_area * rank_size]; 00330 FFT_TYPE *worst_image_fft = new FFT_TYPE[image_area * rank_size]; 00331 00332 #ifdef _TRACK_TIME_ 00333 double all_costs[n_validations], all_times[n_validations], all_stable_convergence[n_validations]; 00334 #endif 00335 00336 double *artificial_image = new double[size_fft]; 00337 00338 int i, j; 00339 for(i=0; i < rank_size; i++) best_costs[i] = WORD_MAX; 00340 memset(worst_costs, 0, rank_size * SIZEOF_WORD); 00341 00342 // Calculate the Hamming window. 00343 double *hamming = new double[image_area]; 00344 frac_hamming(hamming, 0.3, image_size, image_size); 00345 // Apply the Hamming window over the Object. 00346 double *object_hamming = new double[image_area]; 00347 for(j=0; j < image_area; j++) object_hamming[j] = object[j]; 00348 apply_window(object_hamming, hamming, image_area); 00349 00350 // Validate the PSF estimation method through CPSO. 00351 cout << "Making a complete search..." << endl; 00352 for(i=0; i < n_validations; i++){ 00353 // Calculates 1 random PSF and the artificial image. 00354 //-------------------------------------------------- 00355 cout << "Processing search #" << i << endl; 00356 // No image is used here, so just repeat the object as parameter. 00357 CPSO::generateNormalDistrRandomCoefs(coefs, n_zernikes, range); 00358 cpso = PsfEstimator::getCPSO(object, object, coefs); 00359 // No search is made, only a random PSF is applied over the object. 00360 cpso->runPsf(trackers, 1); 00361 // Save the results. 00362 cpso->saveFirstResult(); 00363 cpso->getObjectFFT(object_fft); 00364 cpso->getBestPhase(phase); 00365 cpso->getBestPsfe(psf); 00366 cpso->getBestPsfeFFT(psf_fft); 00367 cpso->getBestConvolvedObject(image); // Artificial Corrupted Image. 00368 cpso->release(); 00369 00370 // Add the Poisson Noise to the artificial image. 00371 if(poisson){ 00372 addPoissonNoise(image, image_size, image_size, poisson, 0); 00373 } 00374 00375 // Duplicate the values, converting to double if necessary. 00376 for(j=0; j < image_area; j++) artificial_image[j] = image[j]; 00377 00378 // Apply the Hamming window over the Image. 00379 apply_window(artificial_image, hamming, image_area); 00380 00381 // Try to find the same artificial corrupted image by making a complete search. 00382 //----------------------------------------------------------------------------- 00383 // Set the pool configuration for a complete search. 00384 TRACK(tracker_estimation.start()) 00385 PsfEstimator::resetPool(1.25, 1, 0.5, 0.25, 32, 3); 00386 cpso = PsfEstimator::getCPSO(object_hamming, artificial_image); 00387 cpso->setOriginalPsf(psf); 00388 cpso->run(trackers, 396); 00389 // Get the current final cost. 00390 curr_cost = cpso->getGBestCost(); 00391 00392 #ifdef _TRACK_TIME_ 00393 tracker_estimation.end(); 00394 all_costs[i] = curr_cost; 00395 all_times[i] = tracker_estimation.elapsedTime(); 00396 all_stable_convergence[i] = cpso->getStableCycle(); 00397 tracker_estimation.print(); 00398 #endif 00399 00400 // Print the coefs. 00401 cout << "Validation#" << i << endl << " Coefs used to create the artificial image: ["; 00402 cout << coefs[0]; 00403 for(j=1; j < n_zernikes; j++) cout << ", " << coefs[j]; 00404 cout << "]" << endl; 00405 cpso->getBestCoefs(coefs); 00406 cout << " Best coefs found during the CPSO search : ["; 00407 cout << coefs[0]; 00408 for(j=1; j < n_zernikes; j++) cout << ", " << coefs[j]; 00409 cout << "]" << endl; 00410 cout << "Stabilization at cycle: " << cpso->getStableCycle() << endl; 00411 00412 // Check if it's a good value. 00413 for(best_pos=-1, j=0; j < rank_size; j++){ 00414 if(curr_cost < best_costs[j]){ 00415 if(j < rank_size-1) memcpy(&best_costs[j+1], &best_costs[j], (rank_size-j-1)*SIZEOF_WORD); 00416 best_pos = j; 00417 break; 00418 } 00419 } 00420 // Check if it's a bad value. 00421 for(worst_pos=-1, j=0; j < rank_size; j++){ 00422 if(curr_cost > worst_costs[j]){ 00423 if(j < rank_size-1) memcpy(&worst_costs[j+1], &worst_costs[j], (rank_size-j-1)*SIZEOF_WORD); 00424 worst_pos = j; 00425 break; 00426 } 00427 } 00428 // Only read from device if it's a good or a bad value. 00429 if(best_pos != -1 || worst_pos != -1){ 00430 if(best_pos != -1){ 00431 best_costs[best_pos] = curr_cost; 00432 memcpy(&best_artificial_psf[image_area * best_pos], psf, image_area * SIZEOF_WORD); 00433 memcpy(&best_artificial_psf_fft[image_area * best_pos], psf_fft, image_area * SIZEOF_FFTTYPE); 00434 memcpy(&best_artificial_phase[size_fft * best_pos], phase, size_fft * SIZEOF_WORD); 00435 memcpy(&best_artificial_image[image_area * best_pos], image, image_area * SIZEOF_WORD); 00436 cpso->getImageFFT(&best_artificial_image_fft[image_area * best_pos]); 00437 cpso->getBestCoefs(&best_coefs[n_zernikes * best_pos]); 00438 cpso->getBestPsfe(&best_psf[image_area * best_pos]); 00439 cpso->getBestPsfeFFT(&best_psf_fft[image_area * best_pos]); 00440 cpso->getBestPhase(&best_phase[size_fft * best_pos]); 00441 cpso->getBestConvolvedObject(&best_image[image_area * best_pos]); 00442 cpso->getBestConvolvedObjectFFT(&best_image_fft[image_area * best_pos]); 00443 } 00444 // A value could be both good and bad at startup. 00445 if(worst_pos != -1){ 00446 worst_costs[worst_pos] = curr_cost; 00447 memcpy(&worst_artificial_psf[image_area * worst_pos], psf, image_area * SIZEOF_WORD); 00448 memcpy(&worst_artificial_psf_fft[image_area * worst_pos], psf_fft, image_area * SIZEOF_FFTTYPE); 00449 memcpy(&worst_artificial_phase[size_fft * worst_pos], phase, size_fft * SIZEOF_WORD); 00450 memcpy(&worst_artificial_image[image_area * worst_pos], image, image_area * SIZEOF_WORD); 00451 cpso->getImageFFT(&worst_artificial_image_fft[image_area * worst_pos]); 00452 cpso->getBestCoefs(&worst_coefs[n_zernikes * worst_pos]); 00453 cpso->getBestPsfe(&worst_psf[image_area * worst_pos]); 00454 cpso->getBestPsfeFFT(&worst_psf_fft[image_area * worst_pos]); 00455 cpso->getBestPhase(&worst_phase[size_fft * worst_pos]); 00456 cpso->getBestConvolvedObject(&worst_image[image_area * worst_pos]); 00457 cpso->getBestConvolvedObjectFFT(&worst_image_fft[image_area * worst_pos]); 00458 } 00459 // The calculation of the image difference MUST be made here because it will overwrite some device data. 00460 if(best_pos != -1){ 00461 cpso->calcDifference(trackers, &best_image[image_area * best_pos], &best_imgdiff[image_area * best_pos]); 00462 } 00463 if(worst_pos != -1){ 00464 cpso->calcDifference(trackers, &worst_image[image_area * worst_pos], &worst_imgdiff[image_area * worst_pos]); 00465 } 00466 } 00467 cpso->release(); 00468 // Return the pool configuration for only 1 particle. 00469 PsfEstimator::resetPool(1.25, 1, 0.5, 0.25, 1, 1); 00470 } 00471 00472 WORD psf_inv[image_area]; 00473 FFT_TYPE fft_psf_inv[image_area]; 00474 00475 // Save the results. 00476 ostringstream *oss = new ostringstream(); 00477 for(i=0; i < rank_size; i++){ 00478 // Save the Best values to file. 00479 *oss << object_filename << "-best-" << i << "-image-artificial.fits"; 00480 write_fits_file((char*)oss->str().c_str(), &best_artificial_image[image_area * i], image_size, image_size); 00481 oss->str(""); 00482 *oss << object_filename << "-best-" << i << "-psf-artificial.fits"; 00483 write_fits_file((char*)oss->str().c_str(), &best_artificial_psf[image_area * i], image_size, image_size); 00484 oss->str(""); 00485 *oss << object_filename << "-best-" << i << "-phase-artificial.fits"; 00486 write_fits_file((char*)oss->str().c_str(), &best_artificial_phase[image_area * i], phase_size, phase_size); 00487 oss->str(""); 00488 *oss << object_filename << "-best-" << i << "-image-calculated.fits"; 00489 write_fits_file((char*)oss->str().c_str(), &best_image[image_area * i], image_size, image_size); 00490 oss->str(""); 00491 *oss << object_filename << "-best-" << i << "-image-difference.fits"; 00492 write_fits_file((char*)oss->str().c_str(), &best_imgdiff[image_area * i], image_size, image_size); 00493 oss->str(""); 00494 *oss << object_filename << "-best-" << i << "-psf-calculated.fits"; 00495 write_fits_file((char*)oss->str().c_str(), &best_psf[image_area * i], image_size, image_size); 00496 oss->str(""); 00497 *oss << object_filename << "-best-" << i << "-phase-calculated.fits"; 00498 write_fits_file((char*)oss->str().c_str(), &best_phase[image_area * i], phase_size, phase_size); 00499 oss->str(""); 00500 *oss << object_filename << "-best-" << i << "-coefs-calculated.txt"; 00501 save_coefs((char*)oss->str().c_str(), &best_coefs[image_area * i], n_zernikes); 00502 oss->str(""); 00503 00504 *oss << object_filename << "-best-" << i << "-psfinv-artificial.fits"; 00505 CPSO::invertPsf(&best_artificial_psf[image_area * i], psf_inv, image_size); 00506 write_fits_file((char*)oss->str().c_str(), psf_inv, image_size, image_size); 00507 oss->str(""); 00508 *oss << object_filename << "-best-" << i << "-psfinv-calculated.fits"; 00509 CPSO::invertPsf(&best_psf[image_area * i], psf_inv, image_size); 00510 write_fits_file((char*)oss->str().c_str(), psf_inv, image_size, image_size); 00511 oss->str(""); 00512 *oss << object_filename << "-best-" << i << "-image-artificial-fft.fits"; 00513 CPSO::invertPsf(&best_artificial_image_fft[image_area * i], fft_psf_inv, image_size); 00514 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00515 oss->str(""); 00516 *oss << object_filename << "-best-" << i << "-image-calculated-fft.fits"; 00517 CPSO::invertPsf(&best_image_fft[image_area * i], fft_psf_inv, image_size); 00518 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00519 oss->str(""); 00520 *oss << object_filename << "-best-" << i << "-psf-artificial-fft.fits"; 00521 CPSO::invertPsf(&best_artificial_psf_fft[image_area * i], fft_psf_inv, image_size); 00522 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00523 oss->str(""); 00524 *oss << object_filename << "-best-" << i << "-psf-calculated-fft.fits"; 00525 CPSO::invertPsf(&best_psf_fft[image_area * i], fft_psf_inv, image_size); 00526 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00527 oss->str(""); 00528 00529 // Save the Worst values to file. 00530 *oss << object_filename << "-worst-" << i << "-image-artificial.fits"; 00531 write_fits_file((char*)oss->str().c_str(), &worst_artificial_image[image_area * i], image_size, image_size); 00532 oss->str(""); 00533 *oss << object_filename << "-worst-" << i << "-image-artificial-fft.fits"; 00534 write_fits_file((char*)oss->str().c_str(), &worst_artificial_image_fft[image_area * i], image_size, image_size); 00535 oss->str(""); 00536 *oss << object_filename << "-worst-" << i << "-psf-artificial.fits"; 00537 write_fits_file((char*)oss->str().c_str(), &worst_artificial_psf[image_area * i], image_size, image_size); 00538 oss->str(""); 00539 *oss << object_filename << "-worst-" << i << "-psf-artificial-fft.fits"; 00540 write_fits_file((char*)oss->str().c_str(), &worst_artificial_psf_fft[image_area * i], image_size, image_size); 00541 oss->str(""); 00542 *oss << object_filename << "-worst-" << i << "-phase-artificial.fits"; 00543 write_fits_file((char*)oss->str().c_str(), &worst_artificial_phase[image_area * i], phase_size, phase_size); 00544 oss->str(""); 00545 *oss << object_filename << "-worst-" << i << "-image-calculated.fits"; 00546 write_fits_file((char*)oss->str().c_str(), &worst_image[image_area * i], image_size, image_size); 00547 oss->str(""); 00548 *oss << object_filename << "-worst-" << i << "-image-calculated-fft.fits"; 00549 write_fits_file((char*)oss->str().c_str(), &worst_image_fft[image_area * i], image_size, image_size); 00550 oss->str(""); 00551 *oss << object_filename << "-worst-" << i << "-image-difference.fits"; 00552 write_fits_file((char*)oss->str().c_str(), &worst_imgdiff[image_area * i], image_size, image_size); 00553 oss->str(""); 00554 *oss << object_filename << "-worst-" << i << "-psf-calculated.fits"; 00555 write_fits_file((char*)oss->str().c_str(), &worst_psf[image_area * i], image_size, image_size); 00556 oss->str(""); 00557 *oss << object_filename << "-worst-" << i << "-phase-calculated.fits"; 00558 write_fits_file((char*)oss->str().c_str(), &worst_phase[image_area * i], phase_size, phase_size); 00559 oss->str(""); 00560 *oss << object_filename << "-worst-" << i << "-coefs-calculated.txt"; 00561 save_coefs((char*)oss->str().c_str(), &worst_coefs[image_area * i], n_zernikes); 00562 oss->str(""); 00563 00564 *oss << object_filename << "-worst-" << i << "-psfinv-artificial.fits"; 00565 CPSO::invertPsf(&worst_artificial_psf[image_area * i], psf_inv, image_size); 00566 write_fits_file((char*)oss->str().c_str(), psf_inv, image_size, image_size); 00567 oss->str(""); 00568 *oss << object_filename << "-worst-" << i << "-psfinv-calculated.fits"; 00569 CPSO::invertPsf(&worst_psf[image_area * i], psf_inv, image_size); 00570 write_fits_file((char*)oss->str().c_str(), psf_inv, image_size, image_size); 00571 oss->str(""); 00572 *oss << object_filename << "-worst-" << i << "-image-artificial-fft.fits"; 00573 CPSO::invertPsf(&worst_artificial_image_fft[image_area * i], fft_psf_inv, image_size); 00574 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00575 oss->str(""); 00576 *oss << object_filename << "-worst-" << i << "-image-calculated-fft.fits"; 00577 CPSO::invertPsf(&worst_image_fft[image_area * i], fft_psf_inv, image_size); 00578 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00579 oss->str(""); 00580 *oss << object_filename << "-worst-" << i << "-psf-artificial-fft.fits"; 00581 CPSO::invertPsf(&worst_artificial_psf_fft[image_area * i], fft_psf_inv, image_size); 00582 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00583 oss->str(""); 00584 *oss << object_filename << "-worst-" << i << "-psf-calculated-fft.fits"; 00585 CPSO::invertPsf(&worst_psf_fft[image_area * i], fft_psf_inv, image_size); 00586 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00587 oss->str(""); 00588 } 00589 // Save the Object's FFT. 00590 *oss << object_filename << "-object-fft.fits"; 00591 CPSO::invertPsf(object_fft, fft_psf_inv, image_size); 00592 write_fits_file((char*)oss->str().c_str(), fft_psf_inv, image_size, image_size); 00593 oss->str(""); 00594 00595 delete object_fft; 00596 delete artificial_image; 00597 delete oss; 00598 delete psf; 00599 delete psf_fft; 00600 delete phase; 00601 delete image; 00602 delete image_fft; 00603 delete object_hamming; 00604 delete coefs; 00605 delete best_artificial_psf; 00606 delete best_artificial_psf_fft; 00607 delete best_artificial_phase; 00608 delete best_artificial_image; 00609 delete best_artificial_image_fft; 00610 delete best_coefs; 00611 delete best_psf; 00612 delete best_psf_fft; 00613 delete best_phase; 00614 delete best_image; 00615 delete best_image_fft; 00616 delete best_imgdiff; 00617 delete worst_artificial_psf; 00618 delete worst_artificial_psf_fft; 00619 delete worst_artificial_phase; 00620 delete worst_artificial_image; 00621 delete worst_artificial_image_fft; 00622 delete worst_coefs; 00623 delete worst_psf; 00624 delete worst_psf_fft; 00625 delete worst_phase; 00626 delete worst_image; 00627 delete worst_image_fft; 00628 delete worst_imgdiff; 00629 00630 TRACK(trackers[0]->pause()) 00631 00632 #ifdef _TRACK_TIME_ 00633 // Print tracking information. 00634 cout << "Time spent per piece of code:" << endl; 00635 for (int i = 0; i < num_trackers; i++) { 00636 trackers[i]->end(); 00637 trackers[i]->print(); 00638 delete trackers[i]; 00639 } 00640 delete[] trackers; 00641 00642 cout << "* Statistics for Estimations:" << endl; 00643 cout << "- Time: avg.time=" << CPSO::calc_mean(all_times, n_validations) << 00644 ", std.dev.time=" << CPSO::calc_stddev(all_times, n_validations) << 00645 ", variance.time=" << CPSO::calc_variance(all_times, n_validations) << endl; 00646 cout << "- Fitness: avg.fitness=" << CPSO::calc_mean(all_costs, n_validations) << 00647 ", std.dev.fitness=" << CPSO::calc_stddev(all_costs, n_validations) << 00648 ", variance.fitness=" << CPSO::calc_variance(all_costs, n_validations) << endl; 00649 cout << "- Stabilization: avg.cycle=" << CPSO::calc_mean(all_stable_convergence, n_validations) << 00650 ", std.dev.cycle=" << CPSO::calc_stddev(all_stable_convergence, n_validations) << 00651 ", variance.cycle=" << CPSO::calc_variance(all_stable_convergence, n_validations) << endl; 00652 #endif 00653 } 00654 00672 void generate_random_images(double* object, double* zernikes, int* diffraction_mask, 00673 int n_zernikes, int image_size, int phase_size, double range, int *phase_mask, 00674 char *object_filename, int n_images, vector<int> *_devices, int poisson, int parallel){ 00675 00676 TimeTracker **trackers = NULL; 00677 #ifdef _TRACK_TIME_ 00678 // Create the trackers. 00679 int num_trackers = 6; 00680 trackers = new TimeTracker*[num_trackers]; 00681 trackers[0] = new TimeTracker("cpso"); 00682 trackers[1] = new TimeTracker("cycles"); 00683 trackers[2] = new TimeTracker("generatePhase"); 00684 trackers[3] = new TimeTracker("fft"); 00685 trackers[4] = new TimeTracker("matrix-operations"); 00686 trackers[5] = new TimeTracker("reduction"); 00687 #endif 00688 00689 TRACK(trackers[0]->resume()) 00690 cout << "Starting generation..." << endl; 00691 00692 // CPSO Startup. 00693 PsfEstimator::startup(parallel, zernikes, phase_mask, diffraction_mask, phase_size, image_size, n_zernikes, range, 1.25, 1, 0.5, 0.25, 1, 1, _devices); 00694 00695 int size_fft = phase_size * phase_size; 00696 int image_area = image_size * image_size; 00697 double *artificial_image = new double[image_area * n_images]; 00698 WORD *coefs = new WORD[n_zernikes * n_images]; 00699 CPSO *cpso = NULL; 00700 // Validate the PSF reconstruction algorithm. 00701 omp_set_num_threads(parallel); 00702 #pragma omp parallel for shared(trackers, object, artificial_image, coefs) \ 00703 firstprivate(n_images, n_zernikes, image_size, image_area, size_fft, range, cpso, poisson) \ 00704 default(none) 00705 for(int i=0; i < n_images; i++){ 00706 WORD *_coefs = new WORD[n_zernikes]; 00707 WORD *conobj = new WORD[image_area]; 00708 00709 CPSO::generateNormalDistrRandomCoefs(_coefs, n_zernikes, range); 00710 cpso = PsfEstimator::getCPSO(object, object, _coefs); 00711 // Calculates 1 random PSF and the artificial corrupted image. 00712 cpso->runPsf(trackers, 1); 00713 // Save the results. 00714 cpso->saveFirstResult(); 00715 cpso->getBestConvolvedObject(conobj); // Artificial Corrupted Image. 00716 cpso->release(); 00717 00718 // Add the Poisson Noise to the artificial image. 00719 if(poisson){ 00720 addPoissonNoise(conobj, image_size, image_size, poisson, 0); 00721 } 00722 00723 for(int j=0; j < size_fft; j++) artificial_image[(i*image_area) + j] = conobj[j]; 00724 for(int j=0; j < n_zernikes; j++) coefs[(i*n_zernikes) + j] = _coefs[j]; 00725 00726 delete _coefs; 00727 delete conobj; 00728 } 00729 00730 ostringstream oss; 00731 oss << object_filename << "-generated-" << n_images << "-artificial-images.fits"; 00732 writeFitsFile((char*)oss.str().c_str(), artificial_image, image_size, image_size, n_images); 00733 oss.str(""); 00734 oss << object_filename << "-generated-" << n_images << "-coefs-calculated.txt"; 00735 save_coefs((char*)oss.str().c_str(), coefs, n_zernikes, n_images); 00736 00737 // The Total Cost must be something really small (something between 0 and 2). 00738 cout << "Generation finished." << endl; 00739 00740 delete artificial_image; 00741 delete coefs; 00742 } 00743 00751 double rect_to_theta(double x, double y) { 00752 double theta; 00753 00754 if (x == 0) { 00755 if (y == 0) { 00756 theta = 0; 00757 } 00758 else if (y > 0) { 00759 theta = pi * 0.5; 00760 } 00761 else { 00762 theta = 1.5 * pi; 00763 } 00764 } 00765 else if(x < 0){ 00766 if (y == 0) { 00767 theta = pi; 00768 } 00769 else if (y > 0) { 00770 theta = pi - atan(-y / x); 00771 } 00772 else { 00773 theta = pi + atan(y / x); 00774 } 00775 } 00776 else if (x > 0 && y > 0) { 00777 theta = atan(y / x); 00778 } 00779 else { 00780 theta = 2.0 * pi - atan(-y / x); 00781 } 00782 00783 return theta; 00784 } 00785 00794 void gen_radial_values(double* array, double radius, int size_x) { 00795 double rr, x, y; 00796 double hhsize = size_x * 0.5; 00797 for (int i, j = 0; j < size_x; j++) { 00798 y = j - hhsize; 00799 for (i = 0; i < size_x; i++) { 00800 x = i - hhsize; 00801 rr = rect_to_r(x, y) / radius; 00802 if (rr <= 1) { 00803 array[j * size_x + i] = rr; 00804 } 00805 else { 00806 array[j * size_x + i] = 0; 00807 } 00808 } 00809 } 00810 } 00811 00818 void gen_angular_values(double* array, int size_x){ 00819 double x, y; 00820 double hsize = size_x * 0.5; 00821 for (int i, j = 0; j < size_x; j++) { 00822 y = j - hsize; 00823 for (i = 0; i < size_x; i++) { 00824 x = i - hsize; 00825 array[j * size_x + i] = rect_to_theta(x, y); 00826 } 00827 } 00828 } 00829 00835 double factorial_to(int n) { 00836 int fact = 1; 00837 for(; n > 1; n--) fact *= n; 00838 return fact; 00839 } 00840 00848 double zernike_radial(double r, int n, int m){ 00849 long double calc1, calc2, calc3; 00850 long double result = 0; 00851 int upper = ((n - m) / 2) + 1; 00852 for (int i = 0; i < upper; i++) { 00853 calc1 = pow(-1, i) * factorial_to(n - i); 00854 calc2 = factorial_to(i) * factorial_to(((n + m) / 2) - i) * factorial_to(((n - m) / 2) - i); 00855 calc3 = pow(r, n - (2.0 * i)); 00856 result += calc1 * calc3 / calc2; 00857 } 00858 return result; 00859 } 00860 00869 double zernike_angular(double theta, int n, int m, int evenOdd) { 00870 double result; 00871 if (m == 0) { 00872 result = sqrt(n + 1); 00873 } 00874 else if (evenOdd == 0) { 00875 result = sqrt(2.0) * sqrt(n + 1) * cos(m * theta); 00876 } 00877 else { 00878 result = sqrt(2.0) * sqrt(n + 1) * sin(m * theta); 00879 } 00880 return result; 00881 } 00882 00892 void gen_zernike_values(double *zernikes, double* rarray, double* tarray, int size_x, int nz) { 00893 double rad, ang; 00894 int evenOdd, n = 0, m = 0, size_fft = size_x * size_x; 00895 for (int k, j, i = 0; i < nz; i++) { 00896 translate_noll_index(i + 4, &n, &m); 00897 if (m < 0) { 00898 m = -m; 00899 evenOdd = 1; 00900 } 00901 else{ 00902 evenOdd = 0; 00903 } 00904 for (k = 0; k < size_x; k++) { 00905 for (j = 0; j < size_x; j++) { 00906 rad = zernike_radial(rarray[k * size_x + j], n, m); 00907 ang = zernike_angular(tarray[k * size_x + j], n, m, evenOdd); 00908 zernikes[(i * size_fft) + (k * size_x + j)] = rad * ang; 00909 } 00910 } 00911 } 00912 } 00913 00924 void translate_noll_index(int j, int *n, int *m) { 00925 if (j < 1) { 00926 fprintf(stderr, "ERROR: j=%i but it must be j>=1.\n", j); 00927 *n = -1; 00928 return; 00929 } 00930 00931 *n = 0; 00932 *m = 0; 00933 00934 if (j == 1) { 00935 return; 00936 } 00937 00938 int l, k = j; // some helpers 00939 00940 // for each n, there are n+1 possible values for m. 00941 // so what is n for the given j? 00942 for (l = 0; k > 0; l++) { 00943 k -= l; 00944 } 00945 *n = l - 2; // -2 here and not -1 because l++ 00946 // is also computed in the 'for' loop at the very end. 00947 00948 // what is the smallest j for this n? 00949 k = 1; 00950 for (l = 1; l < *n; l++) { 00951 k += (l + 1); 00952 } 00953 00954 // so how many m values must be missed out then? 00955 k = j - k; 00956 // even n start with m=0, uneven n start with m=1 00957 if (*n % 2 == 0) { 00958 *m = 0; 00959 } 00960 else { 00961 *m = 1; 00962 } 00963 00964 // increase m by 2 in every second step of k-1 overall steps 00965 // (-1, because the first step is already 00966 // done with setting the starting m) 00967 // (every second step, because in between 00968 // the sign is changed, what's to be considered 00969 // after this loop) 00970 for (l = 1; l < k; l++) { 00971 if (l % 2 == 0 && *n % 2 != 0) { 00972 *m += 2; 00973 } 00974 else if (l % 2 != 0 && *n % 2 == 0) { 00975 *m += 2; 00976 } 00977 } 00978 00979 // negative sign for uneven j 00980 if (j % 2 != 0) { 00981 *m = -*m; 00982 } 00983 } 00984 00993 void min_max_array(double *array, double *min, double *max, int size) { 00994 *max = *array; 00995 *min = *array; 00996 for (int i, j = 0; j < size; j++) { 00997 for (i = 0; i < size; i++) { 00998 if (array[j * size + i] > *max){ 00999 *max = array[j * size + i]; 01000 } 01001 if (array[j * size + i] < *min){ 01002 *min = array[j * size + i]; 01003 } 01004 } 01005 } 01006 } 01007 01015 void norm_zernikes(double *zernikes, int size, int nz) { 01016 double min, max, scale, sub; 01017 int size_fft = size * size; 01018 for (int k, j, i = 0; i < nz; i++) { 01019 min_max_array(&zernikes[i * size_fft], &min, &max, size); 01020 sub = (max + min) * 0.5; 01021 scale = (max - min) * 0.5; 01022 for (k = 0; k < size; k++) { 01023 for (j = 0; j < size; j++) { 01024 zernikes[(i * size_fft) + (k * size + j)] = (zernikes[(i * size_fft) + (k * size + j)] - sub) / scale; 01025 } 01026 } 01027 } 01028 } 01029 01039 void gen_circ_mask(int * mask, double radius, double x, double y, int size) { 01040 double dist; 01041 for (int i, j = 0; j < size; j++) { 01042 for (i = 0; i < size; i++) { 01043 dist = sqrt( pow(x - i, 2) + pow(y - j, 2) ); 01044 mask[j * size + i] = (dist <= radius); 01045 } 01046 } 01047 } 01048 01059 void gen_freq_mask(int* mask, double freq_cut, int size_x, int size_y) { 01060 double dist, y; 01061 for (int x, j = 0; j < size_y; j++) { 01062 y = (j > size_y / 2) ? size_y - j : j; 01063 for (x = 0; x < size_x; x++) { 01064 dist = sqrt(pow(x, 2) + pow(y, 2)); 01065 mask[j * size_x + x] = (dist <= freq_cut); 01066 } 01067 } 01068 } 01069 01070 long read_fits_file(char* filename, double* image, int sx, int sy) { 01071 return read_fits_file(filename, image, sx * sy); 01072 } 01073 01074 long read_fits_file(char* filename, double* image, int size) { 01075 return read_fits_file(filename, NULL, true, image, size, 1); 01076 } 01077 01078 long read_fits_file(char* filename, fitsfile *fptr, double* image, int sx, int sy, long firstByte) { 01079 return read_fits_file(filename, fptr, image, sx * sy, firstByte); 01080 } 01081 01082 long read_fits_file(char* filename, fitsfile *fptr, double* image, int size, long firstByte) { 01083 return read_fits_file(filename, fptr, false, image, size, firstByte); 01084 } 01085 01086 long read_fits_file(char* filename, fitsfile *fptr, bool closeFits, double* image, int size, long firstByte) { 01087 int status = 0; 01088 if (fptr == NULL && fits_open_file(&fptr, filename, READONLY, &status)){ 01089 printerror(status); 01090 return NULL; 01091 } 01092 01093 int anynull; 01094 double nullval = 0; 01095 fits_read_img(fptr, TDOUBLE, firstByte, size, &nullval, image, &anynull, &status); 01096 01097 if ((status || closeFits)){ 01098 if (fits_close_file(fptr, &status)){ 01099 printerror(status); 01100 } 01101 return -1; 01102 } 01103 01104 return firstByte; 01105 } 01106 01115 int fitsSize(char* filename) { 01116 fitsfile *fptr; 01117 int status = 0; 01118 if (fits_open_file(&fptr, filename, READONLY, &status)){ 01119 printerror(status); 01120 exit(1); 01121 } 01122 01123 int size; 01124 fits_read_key(fptr, TLONG, "NAXIS3", &size, NULL, &status); 01125 // A 2D file doesn't contain the key NAXIS3. 01126 if(status){ 01127 size = 1; 01128 status = 0; 01129 } 01130 01131 if (fits_close_file(fptr, &status)){ 01132 printerror(status); 01133 exit(1); 01134 } 01135 01136 return size; 01137 } 01138 01149 void writeFitsFile(char* filename, WORD* array, int sx, int sy) { 01150 // Ensure that the output file data type is always double, regardless the data type currently in use. 01151 int size = sx * sy; 01152 double _array[size]; 01153 // Convert the data from float to double, if necessary. 01154 for(int i=0; i < size; i++) _array[i] = array[i]; 01155 01156 writeFitsFile(filename, _array, sx, sy, 1); 01157 } 01158 01168 void writeFitsFile(char* filename, double* array, int sx, int sy, int sz) { 01169 remove(filename); 01170 01171 int status = 0; // initialize status before calling fitsio routines 01172 01173 // create new FITS files 01174 fitsfile *fptr; 01175 if (fits_create_file(&fptr, filename, &status)){ 01176 printerror(status); 01177 exit(1); 01178 } 01179 01180 int bitpix = -64; 01181 long naxis = (sz > 1) ? 3 : 2; // Specify the dimension of the image. 01182 long naxes[naxis]; 01183 naxes[0] = sx; naxes[1] = sy; 01184 if(sz > 1){ 01185 // Set the number of images in a 3D file. 01186 naxes[2] = sz; 01187 } 01188 01189 // Create an entry to the image in the FITS file. 01190 if (fits_create_img(fptr, bitpix, naxis, naxes, &status)){ 01191 printerror(status); 01192 } 01193 01194 // write the array to the FITS file 01195 long size = sx * sy * sz; 01196 if (fits_write_img(fptr, TDOUBLE, 1, size, array, &status)){ 01197 printerror(status); 01198 } 01199 01200 // close the file 01201 if (fits_close_file(fptr, &status)){ 01202 printerror(status); 01203 exit(1); 01204 } 01205 } 01206 01207 01211 void printerror(int status) { 01212 if (status) { 01213 fits_report_error(stderr, status); /* print error report */ 01214 exit(status); /* terminate program, return error status */ 01215 } 01216 } 01217 01227 void write_fits_file(char* filename, FFT_TYPE* array, int sx, int sy) { 01228 int area = sx*sy; 01229 WORD wArray[area]; 01230 for(int i=0; i < area; i++) wArray[i] = sqrt(array[i].x * array[i].x + array[i].y * array[i].y) / area; 01231 write_fits_file(filename, wArray, sx, sy); 01232 } 01233 01242 void write_fits_file(char* filename, WORD* array, int sx, int sy) { 01243 remove(filename); // Delete old file if it already exists 01244 01245 fitsfile *fptr; // pointer to the FITS file, defined in fitsio.h 01246 int status = 0; // initialize status before calling fitsio routines 01247 if (fits_create_file(&fptr, filename, &status)){ // create new FITS file 01248 printerror(status); // call printerror if error occurs 01249 } 01250 01251 int bitpix = -64; 01252 long naxis = 2; // 2-dimensional image 01253 long naxes[2] = {sx, sy}; 01254 if (fits_create_img(fptr, bitpix, naxis, naxes, &status)){ 01255 printerror(status); 01256 } 01257 01258 // Ensure that the output file data type is always double, regardless the data type currently in use. 01259 double *_array; 01260 #ifdef _DOUBLE_WORD_ 01261 _array = array; 01262 #else 01263 int sz = sx * sy; 01264 _array = new double[sz]; 01265 for(int i=0; i < sz; i++) _array[i] = array[i]; 01266 #endif 01267 01268 // write the array to the FITS file 01269 long fpixel = 1; // first pixel to write 01270 long nelements = naxes[0] * naxes[1]; // number of pixels to write 01271 if (fits_write_img(fptr, TDOUBLE, fpixel, nelements, _array, &status)){ 01272 printerror(status); 01273 } 01274 01275 #ifndef _DOUBLE_WORD_ 01276 delete _array; 01277 #endif 01278 01279 // close the file 01280 if (fits_close_file(fptr, &status)){ 01281 printerror(status); 01282 } 01283 } 01284 01292 void sum_3dfits_file(FitsManager *fitsManager, double *sum, int img_area){ 01293 fits_result *result; 01294 int j, n_images = fitsManager->size(); 01295 for(j=0; j < img_area; j++) sum[j] = 0; 01296 for(int i=0; i < n_images; i++){ 01297 if((result = fitsManager->nextImage()) == NULL){ 01298 continue; 01299 } 01300 for(j=0; j < img_area; j++){ 01301 sum[j] += result->image[j]; 01302 } 01303 } 01304 } 01305 01306 void copy_image(double *image_from, double *image_to, int img_area){ 01307 for(int i=0; i < img_area; i++){ 01308 image_to[i] = image_from[i]; 01309 } 01310 } 01311 01312 /* 01313 * Return a noise value from the specified distribution. 01314 */ 01315 int chooseNoiseFromTable(double *prob, int size) { 01316 int Low = 0; 01317 int Mid = (size - 1) / 2; 01318 int High = size - 1; 01319 int Random = 1 + rand() % (size - 1); 01320 01321 while (Low < High) { 01322 Mid = (Low + High) / 2; 01323 if (prob[Mid] * size < Random) 01324 Low = Mid + 1; 01325 else if (prob[Mid] * size > Random) 01326 High = Mid - 1; 01327 else 01328 Low = High = Mid; 01329 } 01330 01331 return Mid; 01332 } 01333 01344 void addPoissonNoise(WORD *image, int img_size, int prob_size, double variance, double mean) { 01345 double prob[prob_size]; 01346 double Prob[prob_size]; 01347 int img_area = img_size * img_size; 01348 01349 /* Initialize probability arrays */ 01350 prob[0] = exp(-variance); 01351 Prob[0] = 0; 01352 int i; 01353 for (i=1; i < prob_size; i++) { 01354 prob[i] = prob[i - 1] * variance / i; 01355 Prob[i] = Prob[i - 1] + (prob[i - 1] + prob[i]) / 2; 01356 } 01357 01358 /* Add noise to each point */ 01359 for (i=0; i < img_area; i++){ 01360 image[i] += chooseNoiseFromTable(Prob, prob_size) - variance + mean; 01361 } 01362 } 01363 01371 void save_coefs(char *file_name, WORD *coefs, int n_coefs){ 01372 save_coefs(file_name, coefs, n_coefs, 1); 01373 } 01374 01383 void save_coefs(char *file_name, WORD *coefs, int n_coefs, int n_rows){ 01384 if(coefs == NULL || n_coefs < 1 || n_rows < 1 || file_name == NULL) return; 01385 01386 FILE *fp = fopen(file_name, "w"); 01387 if (!fp) { 01388 cerr << "Failed to save coefs [" << file_name << "]." << std::endl; 01389 return; 01390 } 01391 01392 char val[100]; 01393 val[0] = '\0'; 01394 for(int j, i=0; i < n_rows; i++){ 01395 ftoa(coefs[i * n_coefs], val); 01396 fwrite(val, 1, strlen(val), fp); 01397 for(j=1; j < n_coefs; j++){ 01398 fwrite(", ", 1, 2, fp); 01399 ftoa(coefs[i * n_coefs + j], val); 01400 fwrite(val, 1, strlen(val), fp); 01401 } 01402 fwrite("\n", 1, 1, fp); 01403 } 01404 01405 fclose(fp); 01406 } 01407 01408 char *ftoa(float val, char *buffer){ 01409 sprintf(buffer, "%f", val); 01410 return buffer; 01411 } 01412 01419 void hamming(double *image, int img_area){ 01420 for(int i=0; i < img_area; i++){ 01421 image[i] = 0.53836 + 0.46164 * cos((2 * pi * i) / (img_area - 1)); 01422 } 01423 } 01424 01431 void hanning(double *image, int img_area){ 01432 for(int i=0; i < img_area; i++){ 01433 image[i] = 0.5 - 0.5 * cos((2 * pi * i) / (img_area)); 01434 } 01435 } 01436 01444 void apply_window(double *img, double *window, int img_area){ 01445 for(int i=0; i < img_area; i++) img[i] *= window[i]; 01446 } 01447 01458 void frac_hamming(double *window, float frac, int nx, int ny){ 01459 int nxf = 2 * (int)((frac*nx+1)/2); 01460 if(nxf <= 0){ 01461 for(int i=0; i < nx*ny; i++) window[i] = 1.0; 01462 } 01463 else{ 01464 // Calculate the window's row. 01465 int nxfh = nxf / 2; 01466 double Fx1[nxf]; 01467 hanning(Fx1, nxf); // defines Hamming window. 01468 double Fx[nx]; 01469 for(int i=0; i < nx; i++) Fx[i] = 1.0; 01470 for(int i=0; i < nxfh; i++) Fx[i] = Fx1[i]; 01471 for(int i=nxfh, j=nx-nxfh; i < nxf; i++, j++) Fx[j] = Fx1[i]; 01472 01473 // Calculate the window's column. 01474 int nyf = 2 * (int)((frac*ny+1)/2); 01475 int nyfh = nyf / 2; 01476 double Fy1[nyf]; 01477 hanning(Fy1, nyf); // defines Hamming window. 01478 double Fy[ny]; 01479 for(int i=0; i < ny; i++) Fy[i] = 1.0; 01480 for(int i=0; i < nyfh; i++) Fy[i] = Fy1[i]; 01481 for(int i=nyfh, j=ny-nyfh; i < nyf; i++, j++) Fy[j] = Fy1[i]; 01482 01483 // Generate the fractional window. 01484 for(int x, y=0; y < ny; y++){ 01485 for(x=0; x < nx; x++){ 01486 window[(y*nx)+x] = Fx[x] * Fy[y]; 01487 } 01488 } 01489 } 01490 } 01491 01499 void test_gpu(){ 01500 clFactory::startup(); 01501 char deviceName[1024]; 01502 01503 int i, sz = 10*1024; 01504 WORD chk_sum, arr[sz]; 01505 for(i=0; i < sz; i++) arr[i] = 1.0/sz; 01506 01507 cl_mem cl_values, cl_sum; 01508 cl_command_queue command_queue; 01509 cl_context context; 01510 kernel_set *kernels; 01511 01512 int n_devices = clFactory::getNumAvailableDevices(); 01513 clQueue *queue[n_devices]; 01514 for(i=0; i < n_devices; i++){ 01515 queue[i] = clFactory::getQueue(); 01516 command_queue = queue[i]->getCommandQueue(); 01517 context = queue[i]->getContext(); 01518 kernels = queue[i]->kernels; 01519 01520 clFactory::getDeviceName(queue[i], deviceName, 1024); 01521 printf("Validating Device [%s - Ptr %p]...\n", deviceName, queue[i]->getDevice()); 01522 01523 CREATE_BUFFER(context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, sz * SIZEOF_WORD, arr, cl_values); 01524 CREATE_BUFFER(context, CL_MEM_READ_WRITE, REDUCTION_NBLOCKS * SIZEOF_WORD, NULL, cl_sum); 01525 01526 CALL_KERNEL(command_queue, kernels->cl_reduce, REDUCTION_NBLOCKS*REDUCTION_BLOCKSZ, REDUCTION_BLOCKSZ, 4, 01527 {sizeof(cl_mem), (void*)&cl_values}, 01528 {sizeof(cl_mem), (void*)&cl_sum}, 01529 {REDUCTION_BLOCKSZ * SIZEOF_WORD, NULL}, 01530 {sizeof(cl_int), (void*)&sz} 01531 ); 01532 SYNC_QUEUE 01533 FINAL_REDUCTIONS(command_queue, cl_sum, chk_sum, 1); 01534 chk_sum = ((int)(chk_sum*1000000))/1000000.0f; // Remove the trailing decimals. 01535 01536 if(chk_sum == 1.0f){ 01537 printf("Device Ok.\n"); 01538 } 01539 else{ 01540 printf("Validation failed on Device [calculated %f instead of 1].\n", chk_sum); 01541 } 01542 01543 clReleaseMemObject(cl_values); 01544 clReleaseMemObject(cl_sum); 01545 } 01546 for(i=0; i < n_devices; i++){ 01547 clFactory::disposeQueue(queue[i]); 01548 } 01549 clFactory::shutdown(); 01550 } 01551 01555 void list_gpu(){ 01556 clFactory::startup(); 01557 01558 char deviceName[1024]; 01559 int n_devices = clFactory::getNumAvailableDevices(); 01560 clQueue *queue[n_devices]; 01561 int i; 01562 for(i=0; i < n_devices; i++){ 01563 queue[i] = clFactory::getQueue(); 01564 clFactory::getDeviceName(queue[i], deviceName, 1024); 01565 printf("[%i] %s\n", i+1, deviceName); 01566 } 01567 01568 for(i=0; i < n_devices; i++){ 01569 clFactory::disposeQueue(queue[i]); 01570 } 01571 clFactory::shutdown(); 01572 } 01573 01581 double rmsContrast(double* img, int width) { 01582 int i, area = width * width; 01583 double rms = 0.0, avg = 0; 01584 double max = 0; 01585 01586 for(i=0; i < area; i++){ 01587 max = (img[i]>max)?img[i]:max; 01588 avg += img[i]; 01589 } 01590 avg /= area; 01591 avg /= max; // Normalize the average. 01592 01593 double aux; 01594 for (i=0; i < area; i++) { 01595 aux = (img[i] / max) - avg; 01596 rms += aux * aux; 01597 } 01598 01599 return sqrt(rms / area); 01600 }