| 1 | #include <stdio.h>
|
|---|
| 2 | #include <math.h>
|
|---|
| 3 | #include "pslib.h"
|
|---|
| 4 |
|
|---|
| 5 | double getTime(void)
|
|---|
| 6 | /* Gets the current time. Got this from Nick Kaiser's fetchpix.c */
|
|---|
| 7 | {
|
|---|
| 8 | struct timeval tv;
|
|---|
| 9 | gettimeofday(&tv, NULL);
|
|---|
| 10 | return(tv.tv_sec + 1.e-6 * tv.tv_usec);
|
|---|
| 11 | }
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 | int main(int argc, char **argv)
|
|---|
| 15 | {
|
|---|
| 16 | if (argc != 2) {
|
|---|
| 17 | fprintf(stderr, "Generates an image and FFTs it, outputting timing statistics.\n"
|
|---|
| 18 | "Usage: %s SIZE\n"
|
|---|
| 19 | "where SIZE is the size (in pixels) of the square image generated.\n"
|
|---|
| 20 | "\n", argv[0]);
|
|---|
| 21 | exit(EXIT_SUCCESS);
|
|---|
| 22 | }
|
|---|
| 23 | int size = atoi(argv[1]); // Size of image
|
|---|
| 24 | double startTime = getTime(); // Start time
|
|---|
| 25 |
|
|---|
| 26 | psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Seed RNG automagically.
|
|---|
| 27 | float yPeriod = psRandomUniform(rng) * size / 2.0;
|
|---|
| 28 | float xPeriod = psRandomUniform(rng) * size / 2.0;
|
|---|
| 29 | float xPhase = psRandomUniform(rng) * 2.0 * M_PI;
|
|---|
| 30 | float yPhase = psRandomUniform(rng) * 2.0 * M_PI;
|
|---|
| 31 | psFree(rng);
|
|---|
| 32 |
|
|---|
| 33 | // Generate the image
|
|---|
| 34 | psImage *image = psImageAlloc(size, size, PS_TYPE_F32);
|
|---|
| 35 | for (int j = 0; j < size; j++) {
|
|---|
| 36 | float yValue = 2.0 * M_PI / yPeriod * (float)j + yPhase;
|
|---|
| 37 | for (int i = 0; i < size; i++) {
|
|---|
| 38 | float xValue = 2.0 * M_PI / xPeriod * (float)i + xPhase;
|
|---|
| 39 | image->data.F32[j][i] = cos(xValue) * cos(yValue);
|
|---|
| 40 | }
|
|---|
| 41 | }
|
|---|
| 42 |
|
|---|
| 43 | // Write image out
|
|---|
| 44 | psFits *imageFile = psFitsAlloc("!image.fits");
|
|---|
| 45 | if (!psFitsWriteImage(imageFile, NULL, image, 0, NULL)) {
|
|---|
| 46 | psErrorStackPrint(stderr, "Unable to write image: input.fits\n");
|
|---|
| 47 | }
|
|---|
| 48 | psFree(imageFile);
|
|---|
| 49 | printf("%dx%d image (image.fits) constructed after %f sec.\n", size, size, getTime() - startTime);
|
|---|
| 50 |
|
|---|
| 51 | // Forward FFT
|
|---|
| 52 | psImage *fft = psImageFFT(NULL, image, PS_FFT_FORWARD);
|
|---|
| 53 | printf("%dx%d FFT image constructed after %f sec.\n", fft->numCols, fft->numRows, getTime() - startTime);
|
|---|
| 54 |
|
|---|
| 55 | // Inverse FFT
|
|---|
| 56 | psImage *back = psImageFFT(NULL, fft, PS_FFT_REVERSE | PS_FFT_REAL_RESULT);
|
|---|
| 57 | printf("%dx%d inverse FFT image constructed after %f sec.\n", back->numCols, back->numRows,
|
|---|
| 58 | getTime() - startTime);
|
|---|
| 59 | if (back->numRows != image->numRows || back->numCols != image->numCols) {
|
|---|
| 60 | printf("Sizes of original image (%dx%d) and end image (%dx%d) do not match!\n", image->numCols,
|
|---|
| 61 | image->numRows, back->numCols, back->numRows);
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | // Power spectrum
|
|---|
| 65 | psImage *power = psImagePowerSpectrum(NULL, fft);
|
|---|
| 66 | printf("%dx%d power spectrum constructed after %f sec.\n", power->numCols, power->numRows, getTime() - startTime);
|
|---|
| 67 |
|
|---|
| 68 | // Write out power spectrum
|
|---|
| 69 | psFits *powerFile = psFitsAlloc("!power.fits");
|
|---|
| 70 | if (!psFitsWriteImage(powerFile, NULL, power, 0, NULL)) {
|
|---|
| 71 | psErrorStackPrint(stderr, "Unable to write image: power.fits\n");
|
|---|
| 72 | }
|
|---|
| 73 | psFree(powerFile);
|
|---|
| 74 | printf("Power spectrum image written to power.fits after %f sec.\n", getTime() - startTime);
|
|---|
| 75 |
|
|---|
| 76 | // Subtract input and inverse FFT image and compare
|
|---|
| 77 | (void)psBinaryOp(back, back, "/", psScalarAlloc(size*size, PS_TYPE_F32));
|
|---|
| 78 | psImage *sub = (psImage*)psBinaryOp(NULL, back, "-", image);
|
|---|
| 79 | psFits *subFile = psFitsAlloc("!sub.fits");
|
|---|
| 80 | if (!psFitsWriteImage(subFile, NULL, sub, 0, NULL)) {
|
|---|
| 81 | psErrorStackPrint(stderr, "Unable to write image: sub.fits\n");
|
|---|
| 82 | }
|
|---|
| 83 | psFree(subFile);
|
|---|
| 84 |
|
|---|
| 85 | printf("%dx%d subtracted image constructed and written to sub.fits at %f sec.\n", size, size,
|
|---|
| 86 | getTime() - startTime);
|
|---|
| 87 |
|
|---|
| 88 | psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
|
|---|
| 89 | psImageStats(stats, sub, NULL, 0);
|
|---|
| 90 | printf("Subtracted image: mean = %g, stdev = %g\n", stats->sampleMean, stats->sampleStdev);
|
|---|
| 91 | psFree(stats);
|
|---|
| 92 |
|
|---|
| 93 | psFree(fft);
|
|---|
| 94 | psFree(power);
|
|---|
| 95 | psFree(back);
|
|---|
| 96 | psFree(sub);
|
|---|
| 97 | psFree(image);
|
|---|
| 98 | }
|
|---|