PSFEstimationwithCPSO
kippef.cpp
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 }
 All Classes Functions