Changeset 5745
- Timestamp:
- Dec 7, 2005, 4:04:22 PM (20 years ago)
- Location:
- trunk/stac
- Files:
-
- 4 added
- 1 deleted
- 9 edited
-
Makefile.am (added)
-
autogen.sh (added)
-
configure.ac (added)
-
src/Makefile (deleted)
-
src/Makefile.am (added)
-
src/stac.c (modified) (2 diffs)
-
src/stacCheckMemory.c (modified) (6 diffs)
-
src/stacCombine.c (modified) (8 diffs)
-
src/stacInvertMaps.c (modified) (2 diffs)
-
src/stacRead.c (modified) (4 diffs)
-
src/stacScales.c (modified) (8 diffs)
-
src/stacTransform.c (modified) (5 diffs)
-
src/stacWrite.c (modified) (4 diffs)
-
src/sum.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/stac/src/stac.c
r5743 r5745 7 7 int main(int argc, char **argv) 8 8 { 9 double startTime = getTime(); 9 double startTime; 10 startTime = getTime(); 10 11 11 12 #if 0 … … 155 156 for (int i = 0; i < transformed->n; i++) { 156 157 char shiftName[MAXCHAR]; // Filename of shifted image 157 sprintf(shiftName, "%s.shift", config->inputs->data[i]);158 sprintf(shiftName, "%s.shift", (const char*)config->inputs->data[i]); 158 159 psFits *shiftFile = psFitsOpen(shiftName, "w"); 159 160 image = psImageCopy(NULL, transformed->data[i], PS_TYPE_F32); -
trunk/stac/src/stacCheckMemory.c
r5743 r5745 4 4 5 5 6 #define LEAKS "leaks.dat" // File to which to write leaks data6 #define LEAKS "leaks.dat" // File to which to write leaks data 7 7 8 8 … … 10 10 { 11 11 psLogMsg("stac.memoryPrint", PS_LOG_INFO, 12 "Memory block %d:\n"13 "\tFile %s, line %d, size %d\n"14 "\tPosts: %x %x %x\n",15 ptr->id, ptr->file, ptr->lineno, ptr->userMemorySize, ptr->startblock, ptr->endblock,16 *(void**)((int8_t *)(ptr + 1) + ptr->userMemorySize));12 "Memory block %d:\n" 13 "\tFile %s, line %d, size %d\n" 14 "\tPosts: %x %x %x\n", 15 ptr->id, ptr->file, ptr->lineno, ptr->userMemorySize, ptr->startblock, ptr->endblock, 16 *(void**)((int8_t *)(ptr + 1) + ptr->userMemorySize)); 17 17 return 0; 18 18 } … … 20 20 21 21 void stacMemoryProblem(const psMemBlock* ptr, ///< the pointer to the problematic memory block. 22 const char *file, ///< the file in which the problem originated23 psS32 lineno///< the line number in which the problem originated22 const char *file, ///< the file in which the problem originated 23 psS32 lineno ///< the line number in which the problem originated 24 24 ) 25 25 { 26 26 psLogMsg("stac.checkMemory.corruption", PS_LOG_WARN, 27 "Memory corruption detected in memBlock %d\n"28 "\tFile %s, line %d, size %d\n"29 "\tPosts: %x %x %x\n",30 ptr->id, file, lineno, ptr->userMemorySize, ptr->startblock, ptr->endblock,31 (ptr + 1 + ptr->userMemorySize));27 "Memory corruption detected in memBlock %d\n" 28 "\tFile %s, line %d, size %d\n" 29 "\tPosts: %x %x %x\n", 30 ptr->id, file, lineno, ptr->userMemorySize, ptr->startblock, ptr->endblock, 31 (ptr + 1 + ptr->userMemorySize)); 32 32 } 33 33 … … 36 36 void stacCheckMemory(void) 37 37 { 38 psMemBlock **leaks = NULL; // List of leaks39 FILE *leakFile; // File to write leaks to38 psMemBlock **leaks = NULL; // List of leaks 39 FILE *leakFile; // File to write leaks to 40 40 41 41 psTrace("stac.checkMemory", 1, "Checking for memory problems....\n"); … … 44 44 45 45 if ((leakFile = fopen(LEAKS, "w")) == NULL) { 46 fprintf(stderr, "Unable to open leaks file, %s\n", LEAKS);47 return;46 fprintf(stderr, "Unable to open leaks file, %s\n", LEAKS); 47 return; 48 48 } 49 49 … … 51 51 psTrace("stac.checkMemory", 1, "%d leaks found.\n", nLeaks); 52 52 for (int i = 0; i < nLeaks; i++) { 53 psLogMsg("stac.checkMemory.leaks", PS_LOG_WARN,54 "Memory leak detection: memBlock %d\n"55 "\tFile %s, line %d, size %d\n",56 leaks[i]->id, leaks[i]->file, leaks[i]->lineno, leaks[i]->userMemorySize);53 psLogMsg("stac.checkMemory.leaks", PS_LOG_WARN, 54 "Memory leak detection: memBlock %d\n" 55 "\tFile %s, line %d, size %d\n", 56 leaks[i]->id, leaks[i]->file, leaks[i]->lineno, leaks[i]->userMemorySize); 57 57 } 58 58 59 int nCorrupted = psMemCheckCorruption(false); // Number of corrupted 59 int nCorrupted; // Number of corrupted memory blocks 60 nCorrupted = psMemCheckCorruption(false); 60 61 psTrace("stac.checkMemory", 1, "%d memory blocks corrupted.\n", nCorrupted); 61 62 -
trunk/stac/src/stacCombine.c
r5743 r5745 8 8 #define ABS(x) ((x) >= 0 ? (x) : -(x)) 9 9 10 float stacCombineMean(psVector *values, // Values for which to take the mean11 psVector *errors,// Errors in the values12 psVector *masks// Masks for the values, 1 = don't use, 0 = use10 float stacCombineMean(psVector *values, // Values for which to take the mean 11 psVector *errors, // Errors in the values 12 psVector *masks // Masks for the values, 1 = don't use, 0 = use 13 13 ) 14 14 { … … 26 26 int num = values->n; 27 27 for (int i = 0; i < num; i++) { 28 if (! masks->data.U8[i]) {29 // "error" here is the variance30 sum += values->data.F32[i] / errors->data.F32[i];31 weights += 1.0 / errors->data.F32[i];32 }28 if (! masks->data.U8[i]) { 29 // "error" here is the variance 30 sum += values->data.F32[i] / errors->data.F32[i]; 31 weights += 1.0 / errors->data.F32[i]; 32 } 33 33 } 34 34 if (weights > 0.0) { 35 return (float)(sum/weights);35 return (float)(sum/weights); 36 36 } else { 37 return NAN;37 return NAN; 38 38 } 39 39 #endif … … 43 43 44 44 float stacCombineMedian(psVector *values, // Values for which to take the median 45 psVector *errors, // Errors in the values46 psVector *masks// Masks for the values, 0 = don't use, 1 = use45 psVector *errors, // Errors in the values 46 psVector *masks // Masks for the values, 0 = don't use, 1 = use 47 47 ) 48 48 { … … 56 56 57 57 58 bool stacCombine(psImage **combined, // The combined image for output59 psArray **rejected,// Array of rejection masks60 psArray *images,// Array of transformed images61 psArray *errors,// Array of transformed error images62 int nReject,// Number of rejection iterations63 psImage *region,// Region to combine64 psVector *saturated,// Saturation limits for each image65 psVector *bad,// Bad pixel limits for each image66 float reject// Rejection (k-sigma)58 bool stacCombine(psImage **combined, // The combined image for output 59 psArray **rejected, // Array of rejection masks 60 psArray *images, // Array of transformed images 61 psArray *errors, // Array of transformed error images 62 int nReject, // Number of rejection iterations 63 psImage *region, // Region to combine 64 psVector *saturated, // Saturation limits for each image 65 psVector *bad, // Bad pixel limits for each image 66 float reject // Rejection (k-sigma) 67 67 ) 68 68 { … … 76 76 assert(bad->n == images->n); 77 77 78 int nImages = images->n; // Number of images79 int numRows = ((psImage*)images->data[0])->numRows; // Image size78 int nImages = images->n; // Number of images 79 int numRows = ((psImage*)images->data[0])->numRows; // Image size 80 80 int numCols = ((psImage*)images->data[0])->numCols; // Image size 81 81 82 82 // Check dimensions for consistency 83 83 for (int i = 0; i < nImages; i++) { 84 psImage *image = (psImage *)images->data[i]; // The image85 psImage *error = (psImage *)errors->data[i]; // The error image86 87 assert(image->numCols == numCols && image->numRows == numRows);88 assert(error->numCols == numCols && error->numRows == numRows);84 psImage *image = (psImage *)images->data[i]; // The image 85 psImage *error = (psImage *)errors->data[i]; // The error image 86 87 assert(image->numCols == numCols && image->numRows == numRows); 88 assert(error->numCols == numCols && error->numRows == numRows); 89 89 } 90 90 91 91 // Check combined image 92 assert(!*combined || ((*combined)->numRows == numRows ) && ((*combined)->numCols == numCols));92 assert(!*combined || ((*combined)->numRows == numRows && (*combined)->numCols == numCols)); 93 93 if (*combined == NULL) { 94 *combined = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Combined image94 *combined = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Combined image 95 95 } 96 96 97 97 // Check area of interest 98 assert(!region || (region->numRows == numRows ) && (region->numCols == numCols));98 assert(!region || (region->numRows == numRows && region->numCols == numCols)); 99 99 100 100 psTrace("stac.combine", 1, "Combining images....\n"); … … 106 106 // Set up rejection masks 107 107 if (nReject > 0) { 108 if (*rejected == NULL) {109 // Allocate the rejection masks, if required110 *rejected = psArrayAlloc(nImages);111 } else {112 assert((*rejected)->n != nImages);113 }114 115 // Create and initialise rejection masks116 for (int i = 0; i < nImages; i++) {117 (*rejected)->data[i] = psImageAlloc(numCols, numRows, PS_TYPE_U8);118 for (int r = 0; r < numRows; r++) {119 for (int c = 0; c < numCols; c++) {120 ((psImage*)((*rejected)->data[i]))->data.U8[r][c] = 0;121 }122 }123 }108 if (*rejected == NULL) { 109 // Allocate the rejection masks, if required 110 *rejected = psArrayAlloc(nImages); 111 } else { 112 assert((*rejected)->n != nImages); 113 } 114 115 // Create and initialise rejection masks 116 for (int i = 0; i < nImages; i++) { 117 (*rejected)->data[i] = psImageAlloc(numCols, numRows, PS_TYPE_U8); 118 for (int r = 0; r < numRows; r++) { 119 for (int c = 0; c < numCols; c++) { 120 ((psImage*)((*rejected)->data[i]))->data.U8[r][c] = 0; 121 } 122 } 123 } 124 124 } 125 125 … … 127 127 // chi^2 image 128 128 psImage *chi2 = psImageAlloc(numCols, numRows, PS_TYPE_F32); 129 static int iteration = 0; // Number of times function has been called130 #endif 131 129 static int iteration = 0; // Number of times function has been called 130 #endif 131 132 132 for (int y = 0; y < numRows; y++) { 133 for (int x = 0; x < numCols; x++) {134 135 // Only combine those pixels requested136 if (!region || (region && region->data.U8[y][x])) {137 138 // Export pixels into the vector and get stats139 for (int i = 0; i < nImages; i++) {140 float pixel = ((psImage*)images->data[i])->data.F32[y][x];141 float delta = ((psImage*)errors->data[i])->data.F32[y][x]; // This is the variance!142 pixels->data.F32[i] = pixel;143 deltas->data.F32[i] = delta;144 if ((pixel >= saturated->data.F32[i]) || (pixel <= bad->data.F32[i]) ||145 (! isfinite(pixel)) || (! isfinite(delta))) {146 mask->data.U8[i] = (psU8)1; // Don't use!147 } else {148 mask->data.U8[i] = (psU8)0; // Use.149 }150 }151 152 float average = stacCombineMean(pixels, deltas, mask); // Combined value153 154 // We set the value BEFORE the rejection iteration because not all pixels that we reject155 // here will be rejected in the final cut.156 (*combined)->data.F32[y][x] = average;133 for (int x = 0; x < numCols; x++) { 134 135 // Only combine those pixels requested 136 if (!region || (region && region->data.U8[y][x])) { 137 138 // Export pixels into the vector and get stats 139 for (int i = 0; i < nImages; i++) { 140 float pixel = ((psImage*)images->data[i])->data.F32[y][x]; 141 float delta = ((psImage*)errors->data[i])->data.F32[y][x]; // This is the variance! 142 pixels->data.F32[i] = pixel; 143 deltas->data.F32[i] = delta; 144 if ((pixel >= saturated->data.F32[i]) || (pixel <= bad->data.F32[i]) || 145 (! isfinite(pixel)) || (! isfinite(delta))) { 146 mask->data.U8[i] = (psU8)1; // Don't use! 147 } else { 148 mask->data.U8[i] = (psU8)0; // Use. 149 } 150 } 151 152 float average = stacCombineMean(pixels, deltas, mask); // Combined value 153 154 // We set the value BEFORE the rejection iteration because not all pixels that we reject 155 // here will be rejected in the final cut. 156 (*combined)->data.F32[y][x] = average; 157 157 158 158 #ifdef TESTING 159 // Calculate chi^2160 chi2->data.F32[y][x] = 0.0;161 int numGoodPix = 0;162 for (int i = 0; i < nImages; i++) {163 if (! mask->data.U8[i]) {164 chi2->data.F32[y][x] += SQUARE(pixels->data.F32[i] - average) / deltas->data.F32[i];165 numGoodPix++;166 }167 }168 chi2->data.F32[y][x] /= (float)numGoodPix;169 #endif 170 171 // Rejection iterations172 bool keepGoing = true;// Keep going with rejection?173 for (int rejNum = 0; (rejNum < nReject) && keepGoing; rejNum++) {174 float max = 0.0;// Maximum deviation175 int maxIndex = -1;// Index of the maximum deviation176 for (int i = 0; i < nImages; i++) {177 if (!mask->data.U8[i] &&178 ((pixels->data.F32[i] - average) / sqrtf(deltas->data.F32[i]) > max)) {179 max = (pixels->data.F32[i] - average) / sqrtf(deltas->data.F32[i]);180 maxIndex = i;181 }182 }183 // Reject the pixel with the maximum deviation184 if (max > reject) {185 mask->data.U8[maxIndex] = 1;186 ((psImage*)((*rejected)->data[maxIndex]))->data.U8[y][x] += 1;187 // Re-do combination following rejection188 average = stacCombineMean(pixels, deltas, mask);189 } else {190 keepGoing = false;191 }192 }193 194 } // Pixels of interest195 196 }159 // Calculate chi^2 160 chi2->data.F32[y][x] = 0.0; 161 int numGoodPix = 0; 162 for (int i = 0; i < nImages; i++) { 163 if (! mask->data.U8[i]) { 164 chi2->data.F32[y][x] += SQUARE(pixels->data.F32[i] - average) / deltas->data.F32[i]; 165 numGoodPix++; 166 } 167 } 168 chi2->data.F32[y][x] /= (float)numGoodPix; 169 #endif 170 171 // Rejection iterations 172 bool keepGoing = true; // Keep going with rejection? 173 for (int rejNum = 0; (rejNum < nReject) && keepGoing; rejNum++) { 174 float max = 0.0; // Maximum deviation 175 int maxIndex = -1; // Index of the maximum deviation 176 for (int i = 0; i < nImages; i++) { 177 if (!mask->data.U8[i] && 178 ((pixels->data.F32[i] - average) / sqrtf(deltas->data.F32[i]) > max)) { 179 max = (pixels->data.F32[i] - average) / sqrtf(deltas->data.F32[i]); 180 maxIndex = i; 181 } 182 } 183 // Reject the pixel with the maximum deviation 184 if (max > reject) { 185 mask->data.U8[maxIndex] = 1; 186 ((psImage*)((*rejected)->data[maxIndex]))->data.U8[y][x] += 1; 187 // Re-do combination following rejection 188 average = stacCombineMean(pixels, deltas, mask); 189 } else { 190 keepGoing = false; 191 } 192 } 193 194 } // Pixels of interest 195 196 } 197 197 } // Iterating over output pixels 198 198 … … 200 200 // Write chi^2 image 201 201 iteration++; 202 char chiName[MAXCHAR]; // Filename of chi^2 image202 char chiName[MAXCHAR]; // Filename of chi^2 image 203 203 sprintf(chiName,"chi2_%d.fits",iteration); 204 204 psFits *chiFile = psFitsAlloc(chiName); 205 205 if (!psFitsWriteImage(chiFile, NULL, chi2 , 0)) { 206 psErrorStackPrint(stderr, "Unable to write image: %s\n", chiName);206 psErrorStackPrint(stderr, "Unable to write image: %s\n", chiName); 207 207 } 208 208 psTrace("stac.combine", 1, "Chi^2 image written to %s\n", chiName); -
trunk/stac/src/stacInvertMaps.c
r5743 r5745 9 9 10 10 psArray *stacInvertMaps(const psArray *maps, // Array of maps to invert 11 int outnx, int outny // Size of output image11 int outnx, int outny // Size of output image 12 12 ) 13 13 { 14 int nMaps = maps->n; // Number of maps14 int nMaps = maps->n; // Number of maps 15 15 psArray *inverted = psArrayAlloc(nMaps); // Array of inverted maps for output 16 16 … … 23 23 for (int mapNum = 0; mapNum < nMaps; mapNum++) { 24 24 25 psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[mapNum]; // Uninverted map26 // Check input27 assert(oldMap->x->nX == oldMap->x->nY && oldMap->y->nX == oldMap->y->nY &&28 oldMap->x->nX == oldMap->y->nX);29 int order = oldMap->x->nX + 1;// Polynomial order30 psTrace("stac.invertMaps", 4, "Generating order %d polynomial inverse transformation.\n", order);31 psPlaneTransform *newMap = psPlaneTransformAlloc(order + 1, order + 1);// Inverted map32 33 // Create fake polynomial to use in evaluation34 psPolynomial2D *fakePoly = psPolynomial2DAlloc(order, order, PS_POLYNOMIAL_ORD);35 for (int i = 0; i <order; i++) {36 for (int j = 0; j <order; j++) {37 fakePoly->coeff[i][j] = 1.0; // Set all coeffecients to 138 fakePoly->mask[i][j] = 1; // Mask all coefficients; unmask to evaluate39 }40 }41 42 // A grid of xin,yin --> xout,yout43 psVector *xIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);44 psVector *yIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);45 psVector *xOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);46 psVector *yOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32);47 48 // Create grid of points49 for (int yint = 0; yint < NUM_GRID; yint++) {50 inCoord->y = (float)(yint * outny) / (float)(NUM_GRID - 1);51 for (int xint = 0; xint < NUM_GRID; xint++) {52 inCoord->x = (float)(xint * outnx) / (float)(NUM_GRID - 1);53 54 (void)psPlaneTransformApply(outCoord, oldMap, inCoord);55 56 xOut->data.F32[yint*NUM_GRID + xint] = inCoord->x;57 yOut->data.F32[yint*NUM_GRID + xint] = inCoord->y;58 xIn->data.F32[yint*NUM_GRID + xint] = outCoord->x;59 yIn->data.F32[yint*NUM_GRID + xint] = outCoord->y;60 }61 }62 63 // Initialise the matrix and vectors64 int nCoeff = order * (order + 1) / 2; // Number of polynomial coefficients65 psImage *matrix = psImageAlloc(nCoeff, nCoeff, PS_TYPE_F64); // Matrix for solution66 psVector *xVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in x67 psVector *yVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in y68 for (int i = 0; i < nCoeff; i++) {69 for (int j = 0; j < nCoeff; j++) {70 matrix->data.F64[i][j] = 0.0;71 }72 xVector->data.F64[i] = 0.0;73 yVector->data.F64[i] = 0.0;74 }75 76 // Iterate over the grid points77 for (int g = 0; g < NUM_GRID*NUM_GRID; g++) {78 79 // Iterate over the polynomial coefficients, accumulating the matrix and vectors80 for (int i = 0, ijIndex = 0; i <order; i++) {81 for (int j = 0; j <order - i; j++, ijIndex++) {82 83 fakePoly->mask[i][j] = 0;84 double ijPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]);85 fakePoly->mask[i][j] = 1;86 87 for (int m = 0, mnIndex = 0; m <order; m++) {88 for (int n = 0; n <order - m; n++, mnIndex++) {89 90 fakePoly->mask[m][n] = 0;91 double mnPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]);92 fakePoly->mask[m][n] = 1;93 94 matrix->data.F64[ijIndex][mnIndex] += ijPoly * mnPoly;95 }96 }97 98 xVector->data.F64[ijIndex] += ijPoly * (double)xOut->data.F32[g];99 yVector->data.F64[ijIndex] += ijPoly * (double)yOut->data.F32[g];100 }101 } // Iterating over coefficients102 } // Iterating over grid points103 104 // Solution via LU Decomposition105 psVector *permutation = psVectorAlloc(nCoeff, PS_TYPE_F64); // Permutation vector for LU Decomposition106 psImage *luMatrix = psMatrixLUD(NULL, &permutation, matrix); // LU decomposed matrix107 psVector *xSolution = psMatrixLUSolve(NULL, luMatrix, xVector, permutation); // Solution in x108 psVector *ySolution = psMatrixLUSolve(NULL, luMatrix, yVector, permutation); // Solution in y109 110 // Stuff coefficients into transformation111 for (int i = 0, ijIndex = 0; i <order; i++) {112 for (int j = 0; j <order - i; j++, ijIndex++) {113 newMap->x->coeff[i][j] = xSolution->data.F64[ijIndex];114 newMap->y->coeff[i][j] = ySolution->data.F64[ijIndex];115 }116 }117 inverted->data[mapNum] = newMap;25 psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[mapNum]; // Uninverted map 26 // Check input 27 assert(oldMap->x->nX == oldMap->x->nY && oldMap->y->nX == oldMap->y->nY && 28 oldMap->x->nX == oldMap->y->nX); 29 int order = oldMap->x->nX; // Polynomial order 30 psTrace("stac.invertMaps", 4, "Generating order %d polynomial inverse transformation.\n", order); 31 psPlaneTransform *newMap = psPlaneTransformAlloc(order, order); // Inverted map 32 33 // Create fake polynomial to use in evaluation 34 psPolynomial2D *fakePoly = psPolynomial2DAlloc(order, order, PS_POLYNOMIAL_ORD); 35 for (int i = 0; i <= order; i++) { 36 for (int j = 0; j <= order; j++) { 37 fakePoly->coeff[i][j] = 1.0; // Set all coeffecients to 1 38 fakePoly->mask[i][j] = 1; // Mask all coefficients; unmask to evaluate 39 } 40 } 41 42 // A grid of xin,yin --> xout,yout 43 psVector *xIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 44 psVector *yIn = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 45 psVector *xOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 46 psVector *yOut = psVectorAlloc(NUM_GRID * NUM_GRID, PS_TYPE_F32); 47 48 // Create grid of points 49 for (int yint = 0; yint < NUM_GRID; yint++) { 50 inCoord->y = (float)(yint * outny) / (float)(NUM_GRID - 1); 51 for (int xint = 0; xint < NUM_GRID; xint++) { 52 inCoord->x = (float)(xint * outnx) / (float)(NUM_GRID - 1); 53 54 (void)psPlaneTransformApply(outCoord, oldMap, inCoord); 55 56 xOut->data.F32[yint*NUM_GRID + xint] = inCoord->x; 57 yOut->data.F32[yint*NUM_GRID + xint] = inCoord->y; 58 xIn->data.F32[yint*NUM_GRID + xint] = outCoord->x; 59 yIn->data.F32[yint*NUM_GRID + xint] = outCoord->y; 60 } 61 } 62 63 // Initialise the matrix and vectors 64 int nCoeff = (order + 1) * (order + 2) / 2; // Number of polynomial coefficients 65 psImage *matrix = psImageAlloc(nCoeff, nCoeff, PS_TYPE_F64); // Matrix for solution 66 psVector *xVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in x 67 psVector *yVector = psVectorAlloc(nCoeff, PS_TYPE_F64); // Vector for solution in y 68 for (int i = 0; i < nCoeff; i++) { 69 for (int j = 0; j < nCoeff; j++) { 70 matrix->data.F64[i][j] = 0.0; 71 } 72 xVector->data.F64[i] = 0.0; 73 yVector->data.F64[i] = 0.0; 74 } 75 76 // Iterate over the grid points 77 for (int g = 0; g < NUM_GRID*NUM_GRID; g++) { 78 79 // Iterate over the polynomial coefficients, accumulating the matrix and vectors 80 for (int i = 0, ijIndex = 0; i <= order; i++) { 81 for (int j = 0; j <= order - i; j++, ijIndex++) { 82 83 fakePoly->mask[i][j] = 0; 84 double ijPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]); 85 fakePoly->mask[i][j] = 1; 86 87 for (int m = 0, mnIndex = 0; m <= order; m++) { 88 for (int n = 0; n <= order - m; n++, mnIndex++) { 89 90 fakePoly->mask[m][n] = 0; 91 double mnPoly = psPolynomial2DEval(fakePoly, xIn->data.F32[g], yIn->data.F32[g]); 92 fakePoly->mask[m][n] = 1; 93 94 matrix->data.F64[ijIndex][mnIndex] += ijPoly * mnPoly; 95 } 96 } 97 98 xVector->data.F64[ijIndex] += ijPoly * (double)xOut->data.F32[g]; 99 yVector->data.F64[ijIndex] += ijPoly * (double)yOut->data.F32[g]; 100 } 101 } // Iterating over coefficients 102 } // Iterating over grid points 103 104 // Solution via LU Decomposition 105 psVector *permutation = psVectorAlloc(nCoeff, PS_TYPE_F64); // Permutation vector for LU Decomposition 106 psImage *luMatrix = psMatrixLUD(NULL, &permutation, matrix); // LU decomposed matrix 107 psVector *xSolution = psMatrixLUSolve(NULL, luMatrix, xVector, permutation); // Solution in x 108 psVector *ySolution = psMatrixLUSolve(NULL, luMatrix, yVector, permutation); // Solution in y 109 110 // Stuff coefficients into transformation 111 for (int i = 0, ijIndex = 0; i <= order; i++) { 112 for (int j = 0; j <= order - i; j++, ijIndex++) { 113 newMap->x->coeff[i][j] = xSolution->data.F64[ijIndex]; 114 newMap->y->coeff[i][j] = ySolution->data.F64[ijIndex]; 115 } 116 } 117 inverted->data[mapNum] = newMap; 118 118 119 119 #ifdef TESTING 120 // Print x coefficients121 psTrace("stac.invertMaps", 7, "x' = \n");122 for (int i = 0; i <order; i++) {123 for (int j = 0; j <order - i; j++) {124 psTrace("stac.invertMaps", 7, " %f x^%d y^%d\n", newMap->x->coeff[i][j], i, j);125 }126 }127 // Print y coefficients128 psTrace("stac.invertMaps", 7, "y' = \n");129 for (int i = 0; i <order; i++) {130 for (int j = 0; j <order - i; j++) {131 psTrace("stac.invertMaps", 7, " %f x^%d y^%d\n", newMap->y->coeff[i][j], i, j);132 }133 }120 // Print x coefficients 121 psTrace("stac.invertMaps", 7, "x' = \n"); 122 for (int i = 0; i <= order; i++) { 123 for (int j = 0; j <= order - i; j++) { 124 psTrace("stac.invertMaps", 7, " %f x^%d y^%d\n", newMap->x->coeff[i][j], i, j); 125 } 126 } 127 // Print y coefficients 128 psTrace("stac.invertMaps", 7, "y' = \n"); 129 for (int i = 0; i <= order; i++) { 130 for (int j = 0; j <= order - i; j++) { 131 psTrace("stac.invertMaps", 7, " %f x^%d y^%d\n", newMap->y->coeff[i][j], i, j); 132 } 133 } 134 134 #endif 135 135 136 136 #ifdef TESTING 137 // Go forward then backward138 double x = 123.4;139 double y = 432.1;140 psPlane *oldCoords = psAlloc(sizeof(psPlane));141 oldCoords->x = x;142 oldCoords->y = y;143 psPlane *newCoords = psPlaneTransformApply(NULL, oldMap, oldCoords);144 psTrace("stac.invertMaps.test", 5, "%f,%f --> %f,%f\n", x, y, newCoords->x, newCoords->y);145 (void)psPlaneTransformApply(oldCoords, newMap, newCoords);146 psTrace("stac.invertMaps.test", 5, "--------> %f,%f\n", oldCoords->x, oldCoords->y);147 psFree(newCoords);148 psFree(oldCoords);137 // Go forward then backward 138 double x = 123.4; 139 double y = 432.1; 140 psPlane *oldCoords = psAlloc(sizeof(psPlane)); 141 oldCoords->x = x; 142 oldCoords->y = y; 143 psPlane *newCoords = psPlaneTransformApply(NULL, oldMap, oldCoords); 144 psTrace("stac.invertMaps.test", 5, "%f,%f --> %f,%f\n", x, y, newCoords->x, newCoords->y); 145 (void)psPlaneTransformApply(oldCoords, newMap, newCoords); 146 psTrace("stac.invertMaps.test", 5, "--------> %f,%f\n", oldCoords->x, oldCoords->y); 147 psFree(newCoords); 148 psFree(oldCoords); 149 149 #endif 150 150 151 psFree(permutation);152 psFree(luMatrix);153 psFree(matrix);154 psFree(xVector);155 psFree(yVector);156 psFree(xSolution);157 psFree(ySolution);158 psFree(fakePoly);159 psFree(xIn);160 psFree(yIn);161 psFree(xOut);162 psFree(yOut);151 psFree(permutation); 152 psFree(luMatrix); 153 psFree(matrix); 154 psFree(xVector); 155 psFree(yVector); 156 psFree(xSolution); 157 psFree(ySolution); 158 psFree(fakePoly); 159 psFree(xIn); 160 psFree(yIn); 161 psFree(xOut); 162 psFree(yOut); 163 163 } 164 164 165 165 psFree(inCoord); 166 166 psFree(outCoord); 167 167 168 168 169 169 #if 0 170 // Can't handle higher order than linear yet171 assert(((psPlaneTransform*)maps->data[i])->x->nX == 2 &&172 ((psPlaneTransform*)maps->data[i])->x->nY == 2 &&173 ((psPlaneTransform*)maps->data[i])->y->nX == 2 &&174 ((psPlaneTransform*)maps->data[i])->y->nY == 2);175 psPlaneTransform *newMap = psPlaneTransformAlloc(2, 2); // Inverted map176 psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[i]; // Uninverted map177 178 // Now, simply do a 2x2 matrix inversion179 180 double a = oldMap->x->coeff[1][0];181 double b = oldMap->x->coeff[0][1];182 double c = oldMap->y->coeff[1][0];183 double d = oldMap->y->coeff[0][1];184 double e = oldMap->x->coeff[0][0];185 double f = oldMap->y->coeff[0][0];186 187 double invDet = 1.0 / (a * d - b * c); // Inverse of the determinant188 189 // Not entirely sure why this works, but it appears to do so.......................................190 newMap->x->coeff[1][0] = invDet * a;191 newMap->x->coeff[0][1] = - invDet * b;192 newMap->y->coeff[1][0] = - invDet * c;193 newMap->y->coeff[0][1] = invDet * d;194 195 newMap->x->coeff[0][0] = - invDet * (d * e + c * f);196 newMap->y->coeff[0][0] = - invDet * (b * e + a * f);170 // Can't handle higher order than linear yet 171 assert(((psPlaneTransform*)maps->data[i])->x->nX == 2 && 172 ((psPlaneTransform*)maps->data[i])->x->nY == 2 && 173 ((psPlaneTransform*)maps->data[i])->y->nX == 2 && 174 ((psPlaneTransform*)maps->data[i])->y->nY == 2); 175 psPlaneTransform *newMap = psPlaneTransformAlloc(2, 2); // Inverted map 176 psPlaneTransform *oldMap = (psPlaneTransform*)maps->data[i]; // Uninverted map 177 178 // Now, simply do a 2x2 matrix inversion 179 180 double a = oldMap->x->coeff[1][0]; 181 double b = oldMap->x->coeff[0][1]; 182 double c = oldMap->y->coeff[1][0]; 183 double d = oldMap->y->coeff[0][1]; 184 double e = oldMap->x->coeff[0][0]; 185 double f = oldMap->y->coeff[0][0]; 186 187 double invDet = 1.0 / (a * d - b * c); // Inverse of the determinant 188 189 // Not entirely sure why this works, but it appears to do so....................................... 190 newMap->x->coeff[1][0] = invDet * a; 191 newMap->x->coeff[0][1] = - invDet * b; 192 newMap->y->coeff[1][0] = - invDet * c; 193 newMap->y->coeff[0][1] = invDet * d; 194 195 newMap->x->coeff[0][0] = - invDet * (d * e + c * f); 196 newMap->y->coeff[0][0] = - invDet * (b * e + a * f); 197 197 #endif 198 198 -
trunk/stac/src/stacRead.c
r5743 r5745 124 124 psTrace("stac.read.map", 5, "Polynomial order: %d\n", order); 125 125 126 psPlaneTransform *map = psPlaneTransformAlloc(order + 1, order + 1); // The transformation126 psPlaneTransform *map = psPlaneTransformAlloc(order, order); // The transformation 127 127 // Set coefficient masks 128 for (int i = 0; i < order + 1; i++) {129 for (int j = 0; j < order + 1; j++) {128 for (int i = 0; i <= order; i++) { 129 for (int j = 0; j <= order; j++) { 130 130 if (i + j > order + 1) { 131 131 map->x->mask[i][j] = 1; … … 140 140 // Read x coefficients 141 141 psTrace("stac.read.map", 7, "x' = \n"); 142 for (int k = 0; k < order + 1; k++) {143 for (int j = 0; j < k + 1; j++) {142 for (int k = 0; k <= order; k++) { 143 for (int j = 0; j <= k; j++) { 144 144 int i = k - j; 145 145 if (fscanf(mapfp, "%lf", &map->x->coeff[i][j]) != 1) { … … 154 154 // Read y coefficients 155 155 psTrace("stac.read.maps", 7, "y' = \n"); 156 for (int k = 0; k < order + 1; k++) {157 for (int j = 0; j < k + 1; j++) {156 for (int k = 0; k <= order; k++) { 157 for (int j = 0; j <= k; j++) { 158 158 int i = k - j; 159 159 if (fscanf(mapfp, "%lf", &map->y->coeff[i][j]) != 1) { … … 188 188 } 189 189 // Read the file 190 sprintf(mapfile, "%s.map",filenames->data[i]);190 sprintf(mapfile, "%s.map", (const char*)filenames->data[i]); 191 191 maps->data[i] = stacReadMap(mapfile); 192 192 if (maps->data[i] == NULL) { -
trunk/stac/src/stacScales.c
r5743 r5745 6 6 #define SQUARE(x) ((x)*(x)) 7 7 8 #define SAMPLE 10 // Subsample rate for images8 #define SAMPLE 10 // Subsample rate for images 9 9 10 10 float stacBackground(const psImage *image, // Image for which to get the background 11 int sample// Sample in increments of this value11 int sample // Sample in increments of this value 12 12 ) 13 13 { … … 15 15 16 16 #if 1 17 int size = image->numCols * image->numRows; // Number of pixels in image18 int numSamples = size / sample; // Number of samples in image17 int size = image->numCols * image->numRows; // Number of pixels in image 18 int numSamples = size / sample; // Number of samples in image 19 19 psVector *values = psVectorAlloc(numSamples + 1, PS_TYPE_F32); // Vector containing sub-sample 20 psVector *mask = psVectorAlloc(numSamples + 1, PS_TYPE_U8); // Mask for sample21 22 int offset = 0; // Offset from start of the row23 int index = 0; // Sample number20 psVector *mask = psVectorAlloc(numSamples + 1, PS_TYPE_U8); // Mask for sample 21 22 int offset = 0; // Offset from start of the row 23 int index = 0; // Sample number 24 24 for (int row = 0; row < image->numRows; row++) { 25 // I'd cast this as a "for", but this makes it a bit easier to understand.26 int col = offset;27 while (col < image->numCols) {28 values->data.F32[index] = image->data.F32[row][col];29 if (isnan(values->data.F32[index])) {30 mask->data.U8[index] = 1;31 } else {32 mask->data.U8[index] = 0;33 }34 col += sample;35 index++;36 }37 offset = col - image->numCols;25 // I'd cast this as a "for", but this makes it a bit easier to understand. 26 int col = offset; 27 while (col < image->numCols) { 28 values->data.F32[index] = image->data.F32[row][col]; 29 if (isnan(values->data.F32[index])) { 30 mask->data.U8[index] = 1; 31 } else { 32 mask->data.U8[index] = 0; 33 } 34 col += sample; 35 index++; 36 } 37 offset = col - image->numCols; 38 38 } 39 39 … … 58 58 59 59 60 bool stacScales(psVector **scalesPtr, // Scales to return61 psVector **offsetsPtr,// Offsets to return62 const psArray *images,// Images on which to measure the scales and offsets63 const char *starFile,// File containing coordinates to photometer64 const char *starMapFile, // Map for coodinates to the common output frame65 float xMapDiff, float yMapDiff, // Difference from the map to apply (due to size difference)66 float aper// Aperture to use for photometry (radius)60 bool stacScales(psVector **scalesPtr, // Scales to return 61 psVector **offsetsPtr, // Offsets to return 62 const psArray *images, // Images on which to measure the scales and offsets 63 const char *starFile, // File containing coordinates to photometer 64 const char *starMapFile, // Map for coodinates to the common output frame 65 float xMapDiff, float yMapDiff, // Difference from the map to apply (due to size difference) 66 float aper // Aperture to use for photometry (radius) 67 67 ) 68 68 { … … 71 71 assert(images); 72 72 for (int i = 0; i < images->n; i++) { 73 psImage *image = images->data[i];74 assert(image->type.type == PS_TYPE_F32);73 psImage *image = images->data[i]; 74 assert(image->type.type == PS_TYPE_F32); 75 75 } 76 76 … … 78 78 psVector *offsets = NULL; // Offsets between images (ADU) 79 79 if (*scalesPtr) { 80 scales = *scalesPtr;81 assert(scales);82 assert(scales->n == images->n);83 assert(scales->type.type == PS_TYPE_F32);80 scales = *scalesPtr; 81 assert(scales); 82 assert(scales->n == images->n); 83 assert(scales->type.type == PS_TYPE_F32); 84 84 } else { 85 scales = psVectorAlloc(images->n, PS_TYPE_F32);86 *scalesPtr = scales;85 scales = psVectorAlloc(images->n, PS_TYPE_F32); 86 *scalesPtr = scales; 87 87 } 88 88 if (*offsetsPtr) { 89 offsets = *offsetsPtr;90 assert(offsets);91 assert(offsets->n == images->n);92 assert(offsets->type.type == PS_TYPE_F32);89 offsets = *offsetsPtr; 90 assert(offsets); 91 assert(offsets->n == images->n); 92 assert(offsets->type.type == PS_TYPE_F32); 93 93 } else { 94 offsets = psVectorAlloc(images->n, PS_TYPE_F32);95 *offsetsPtr = offsets;94 offsets = psVectorAlloc(images->n, PS_TYPE_F32); 95 *offsetsPtr = offsets; 96 96 } 97 97 … … 100 100 double startTime = getTime(); 101 101 for (int i = 0; i < images->n; i++) { 102 offsets->data.F32[i] = stacBackground(images->data[i], SAMPLE);103 psTrace("stac.scales", 5, "Background in image %d is %f\n", i, offsets->data.F32[i]);104 double time = getTime();105 psTrace("stac.scales", 10, "Took %f sec\n", time - startTime);106 startTime = time;102 offsets->data.F32[i] = stacBackground(images->data[i], SAMPLE); 103 psTrace("stac.scales", 5, "Background in image %d is %f\n", i, offsets->data.F32[i]); 104 double time = getTime(); 105 psTrace("stac.scales", 10, "Took %f sec\n", time - startTime); 106 startTime = time; 107 107 } 108 108 109 109 // Now the scales 110 110 if (starFile == NULL || starMapFile == NULL) { 111 psLogMsg("stac.scales", PS_LOG_INFO,112 "No coordinates available to set scales --- assuming all are identical.\n");113 for (int i = 0; i < images->n; i++) {114 scales->data.F32[i] = 1.0;115 psTrace("stac.scales", 5, "Scale for image %d is %f\n", i, scales->data.F32[i]);116 }111 psLogMsg("stac.scales", PS_LOG_INFO, 112 "No coordinates available to set scales --- assuming all are identical.\n"); 113 for (int i = 0; i < images->n; i++) { 114 scales->data.F32[i] = 1.0; 115 psTrace("stac.scales", 5, "Scale for image %d is %f\n", i, scales->data.F32[i]); 116 } 117 117 } else { 118 // Read star coordinates and map 119 psArray *starCoords = stacReadCoords(starFile); // Array of star coordinates 120 psPlaneTransform *starMap = stacReadMap(starMapFile); // Transformation for star coordinates 121 122 // Transform the stellar positions to match the transformed reference frame 123 psArray *starCoordsTransformed = psArrayAlloc(starCoords->n); // Transformed positions 124 // Fix up difference between map and output frame 125 starMap->x->coeff[0][0] -= xMapDiff; 126 starMap->y->coeff[0][0] -= yMapDiff; 127 for (int i = 0; i < starCoords->n; i++) { 128 starCoordsTransformed->data[i] = psPlaneTransformApply(NULL, starMap, starCoords->data[i]); 129 } 130 psFree(starMap); 131 132 psArray *stars = psArrayAlloc(images->n); // Array of stellar photometry vectors 133 psArray *masks = psArrayAlloc(images->n); // Array of masks for stars 134 135 // Set scales relative to the first image 136 scales->data.F32[0] = 1.0; 137 138 // Iterate over images 139 for (int i = 0; i < scales->n; i++) { 140 psImage *image = images->data[i]; // The image we're working with 141 142 float background = offsets->data.F32[i]; // Background in image 143 144 // Do photometry on transformed image i 145 psTrace("stac.scales", 3, "Doing photometry on image %d....\n", i); 146 psVector *photometry = psVectorAlloc(starCoords->n, PS_TYPE_F32); // Photometry of the stars 147 psVector *mask = psVectorAlloc(starCoords->n, PS_TYPE_U8); // Mask for the photometry 148 for (int j = 0; j < starCoordsTransformed->n; j++) { 149 psPlane *coords = starCoordsTransformed->data[j]; // The coordinates of the star 150 151 if (coords->x < aper || coords->y < aper || 152 coords->x + aper > image->numCols - 1 || 153 coords->y + aper > image->numRows) { 154 mask->data.U8[j] = 1; 155 } else { 156 // Sum flux within the aperture 157 float sum = 0.0; 158 int numPix = 0; 159 float aper2 = SQUARE(aper); 160 for (int y = (int)floorf(coords->y - aper); 161 y <= (int)ceilf(coords->y + aper); y++) { 162 for (int x = (int)floorf(coords->x - aper); 163 x <= (int)ceilf(coords->x + aper); x++) { 164 if (SQUARE((float)x + 0.5 - coords->x) + SQUARE((float)y + 0.5 - coords->y) <= 165 aper2) { 166 sum += image->data.F32[y][x]; 167 numPix++; 168 } 169 } 170 } 171 // Subtract background, renormalise to account for circular aperture 172 if (numPix > 0 && sum > 0) { 173 sum -= offsets->data.F32[i] * (float)numPix; 174 photometry->data.F32[j] = sum * M_PI * aper2 / (float)numPix; 175 if (photometry->data.F32[j] > 0 && finite(photometry->data.F32[j])) { 176 mask->data.U8[j] = 1; 177 psTrace("stac.scales", 8, "Star at %f,%f --> %f\n", coords->x, coords->y, sum); 178 } else { 179 mask->data.U8[j] = 0; 180 } 181 } else { 182 mask->data.U8[j] = 0; 183 } 184 } 185 } 186 stars->data[i] = photometry; 187 masks->data[i] = mask; 188 } 189 psFree(starCoords); 190 psFree(starCoordsTransformed); 191 192 // Get the scales 193 psVector *ref = stars->data[0]; // The reference photometry 194 psVector *refMask = masks->data[0]; // The reference mask 118 // Read star coordinates and map 119 psArray *starCoords = stacReadCoords(starFile); // Array of star coordinates 120 psPlaneTransform *starMap = stacReadMap(starMapFile); // Transformation for star coordinates 121 122 // Transform the stellar positions to match the transformed reference frame 123 psArray *starCoordsTransformed = psArrayAlloc(starCoords->n); // Transformed positions 124 // Fix up difference between map and output frame 125 starMap->x->coeff[0][0] -= xMapDiff; 126 starMap->y->coeff[0][0] -= yMapDiff; 127 for (int i = 0; i < starCoords->n; i++) { 128 starCoordsTransformed->data[i] = psPlaneTransformApply(NULL, starMap, starCoords->data[i]); 129 } 130 psFree(starMap); 131 132 psArray *stars = psArrayAlloc(images->n); // Array of stellar photometry vectors 133 psArray *masks = psArrayAlloc(images->n); // Array of masks for stars 134 135 // Set scales relative to the first image 136 scales->data.F32[0] = 1.0; 137 138 // Iterate over images 139 for (int i = 0; i < scales->n; i++) { 140 psImage *image = images->data[i]; // The image we're working with 141 142 // Do photometry on transformed image i 143 psTrace("stac.scales", 3, "Doing photometry on image %d....\n", i); 144 psVector *photometry = psVectorAlloc(starCoords->n, PS_TYPE_F32); // Photometry of the stars 145 psVector *mask = psVectorAlloc(starCoords->n, PS_TYPE_U8); // Mask for the photometry 146 for (int j = 0; j < starCoordsTransformed->n; j++) { 147 psPlane *coords = starCoordsTransformed->data[j]; // The coordinates of the star 148 149 if (coords->x < aper || coords->y < aper || 150 coords->x + aper > image->numCols - 1 || 151 coords->y + aper > image->numRows) { 152 mask->data.U8[j] = 1; 153 } else { 154 // Sum flux within the aperture 155 float sum = 0.0; 156 int numPix = 0; 157 float aper2 = SQUARE(aper); 158 for (int y = (int)floorf(coords->y - aper); 159 y <= (int)ceilf(coords->y + aper); y++) { 160 for (int x = (int)floorf(coords->x - aper); 161 x <= (int)ceilf(coords->x + aper); x++) { 162 if (SQUARE((float)x + 0.5 - coords->x) + SQUARE((float)y + 0.5 - coords->y) <= 163 aper2) { 164 sum += image->data.F32[y][x]; 165 numPix++; 166 } 167 } 168 } 169 // Subtract background, renormalise to account for circular aperture 170 if (numPix > 0 && sum > 0) { 171 sum -= offsets->data.F32[i] * (float)numPix; 172 photometry->data.F32[j] = sum * M_PI * aper2 / (float)numPix; 173 if (photometry->data.F32[j] > 0 && finite(photometry->data.F32[j])) { 174 mask->data.U8[j] = 1; 175 psTrace("stac.scales", 8, "Star at %f,%f --> %f\n", coords->x, coords->y, sum); 176 } else { 177 mask->data.U8[j] = 0; 178 } 179 } else { 180 mask->data.U8[j] = 0; 181 } 182 } 183 } 184 stars->data[i] = photometry; 185 masks->data[i] = mask; 186 } 187 psFree(starCoords); 188 psFree(starCoordsTransformed); 189 190 // Get the scales 191 psVector *ref = stars->data[0]; // The reference photometry 192 psVector *refMask = masks->data[0]; // The reference mask 195 193 #if 0 196 psStats *stats = psStatsAlloc(PS_STAT_CLIPPED_MEAN); // Statistics197 stats->clipSigma = 2.5;198 stats->clipIter = 3;194 psStats *stats = psStatsAlloc(PS_STAT_CLIPPED_MEAN); // Statistics 195 stats->clipSigma = 2.5; 196 stats->clipIter = 3; 199 197 #else 200 psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN); // Statistics201 #endif 202 for (int i = 1; i < scales->n; i++) {203 psVector *input = stars->data[i];// The comparison photometry204 psVector *inputMask = masks->data[i]; // The comparison mask205 206 psVector *compare = (psVector*)psBinaryOp(NULL, input, "/", ref);207 psVector *compareMask = (psVector*)psBinaryOp(NULL, inputMask, "*", refMask);208 (void)psBinaryOp(compareMask, psScalarAlloc(1, PS_TYPE_U8), "-", compareMask);198 psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN); // Statistics 199 #endif 200 for (int i = 1; i < scales->n; i++) { 201 psVector *input = stars->data[i]; // The comparison photometry 202 psVector *inputMask = masks->data[i]; // The comparison mask 203 204 psVector *compare = (psVector*)psBinaryOp(NULL, input, "/", ref); 205 psVector *compareMask = (psVector*)psBinaryOp(NULL, inputMask, "*", refMask); 206 (void)psBinaryOp(compareMask, psScalarAlloc(1, PS_TYPE_U8), "-", compareMask); 209 207 210 208 #if 0 211 psTrace("stac.scales", 9, "Getting scale for image %d...\n", i);212 for (int j = 0; j < compare->n; j++) {213 if (compareMask->data.U8[j] & 1) {214 psTrace("stac.scales", 9, "Bad star %d: %f %f --> %f %d\n", j, input->data.F32[j],215 ref->data.F32[j], compare->data.F32[j], compareMask->data.U8[j]);216 } else {217 psTrace("stac.scales", 9, "Good star %d: %f %f --> %f %d\n", j, input->data.F32[j],218 ref->data.F32[j], compare->data.F32[j], compareMask->data.U8[j]);219 }220 }221 #endif 222 223 psVectorStats(stats, compare, NULL, compareMask, 1);209 psTrace("stac.scales", 9, "Getting scale for image %d...\n", i); 210 for (int j = 0; j < compare->n; j++) { 211 if (compareMask->data.U8[j] & 1) { 212 psTrace("stac.scales", 9, "Bad star %d: %f %f --> %f %d\n", j, input->data.F32[j], 213 ref->data.F32[j], compare->data.F32[j], compareMask->data.U8[j]); 214 } else { 215 psTrace("stac.scales", 9, "Good star %d: %f %f --> %f %d\n", j, input->data.F32[j], 216 ref->data.F32[j], compare->data.F32[j], compareMask->data.U8[j]); 217 } 218 } 219 #endif 220 221 psVectorStats(stats, compare, NULL, compareMask, 1); 224 222 225 223 #if 0 226 scales->data.F32[i] = stats->clippedMean;224 scales->data.F32[i] = stats->clippedMean; 227 225 #else 228 scales->data.F32[i] = stats->sampleMedian;229 #endif 230 psTrace("stac.scales", 5, "Scale for image %d is %f\n", i, scales->data.F32[i]);231 psFree(compare);232 psFree(compareMask);233 }234 psFree(stats);235 236 psFree(stars);237 psFree(masks);226 scales->data.F32[i] = stats->sampleMedian; 227 #endif 228 psTrace("stac.scales", 5, "Scale for image %d is %f\n", i, scales->data.F32[i]); 229 psFree(compare); 230 psFree(compareMask); 231 } 232 psFree(stats); 233 234 psFree(stars); 235 psFree(masks); 238 236 } 239 237 … … 242 240 243 241 244 bool stacRescale(psArray *images, // Images to rescale245 psArray *errImages,// Variance images to rescale246 const psImage *mask,// Mask for pixels to scale247 const psVector *scales,// Scales for images248 const psVector *offsets // Offsets for images242 bool stacRescale(psArray *images, // Images to rescale 243 psArray *errImages, // Variance images to rescale 244 const psImage *mask, // Mask for pixels to scale 245 const psVector *scales,// Scales for images 246 const psVector *offsets // Offsets for images 249 247 ) 250 248 { … … 258 256 assert(offsets->type.type == PS_TYPE_F32); 259 257 for (int i = 0; i < images->n; i++) { 260 psImage *image = images->data[i]; // Image of interest261 assert(image->type.type == PS_TYPE_F32);262 assert(scales->data.F32[i] != 0);263 if (mask) {264 assert(mask->type.type == PS_TYPE_U8);265 assert(image->numCols == mask->numCols && image->numRows == mask->numRows);266 }267 if (errImages) {268 psImage *errImage = errImages->data[i];269 assert(errImage->type.type == PS_TYPE_F32);270 assert(errImage->numCols == image->numCols && errImage->numRows == image->numRows);271 }272 } 273 274 for (int i = 0; i < images->n; i++) { 275 psImage *image = images->data[i]; // Image to rescale276 psImage *errImage = NULL;// Variance image to rescale277 if (errImages) {278 errImage = errImages->data[i];279 }280 float scale = scales->data.F32[i]; // Scale to use281 float offset = offsets->data.F32[i]; // Offset to use282 for (int y = 0; y < image->numRows; y++) {283 for (int x = 0; x < image->numCols; x++) {284 if (!mask || mask->data.F32[y][x]) {285 image->data.F32[y][x] = (image->data.F32[y][x] - offset) / scale;286 if (errImage) {287 errImage->data.F32[y][x] /= SQUARE(scale);288 }289 }290 }291 }258 psImage *image = images->data[i]; // Image of interest 259 assert(image->type.type == PS_TYPE_F32); 260 assert(scales->data.F32[i] != 0); 261 if (mask) { 262 assert(mask->type.type == PS_TYPE_U8); 263 assert(image->numCols == mask->numCols && image->numRows == mask->numRows); 264 } 265 if (errImages) { 266 psImage *errImage = errImages->data[i]; 267 assert(errImage->type.type == PS_TYPE_F32); 268 assert(errImage->numCols == image->numCols && errImage->numRows == image->numRows); 269 } 270 } 271 272 for (int i = 0; i < images->n; i++) { 273 psImage *image = images->data[i]; // Image to rescale 274 psImage *errImage = NULL; // Variance image to rescale 275 if (errImages) { 276 errImage = errImages->data[i]; 277 } 278 float scale = scales->data.F32[i]; // Scale to use 279 float offset = offsets->data.F32[i]; // Offset to use 280 for (int y = 0; y < image->numRows; y++) { 281 for (int x = 0; x < image->numCols; x++) { 282 if (!mask || mask->data.F32[y][x]) { 283 image->data.F32[y][x] = (image->data.F32[y][x] - offset) / scale; 284 if (errImage) { 285 errImage->data.F32[y][x] /= SQUARE(scale); 286 } 287 } 288 } 289 } 292 290 } 293 291 -
trunk/stac/src/stacTransform.c
r5743 r5745 10 10 // Hacked the original ps_ImagePixelInterpolateBILINEAR_F32 to add variances 11 11 // i.e., to square the fractions when combining. 12 inline psF64 p_psImageErrorInterpolateBILINEAR_F32(const psImage* input, 13 float x, 14 float y, 15 const psImage* mask, 16 unsigned int maskVal,17 psF64 unexposedValue)12 inline psF64 p_psImageErrorInterpolateBILINEAR_F32(const psImage* input, 13 float x, 14 float y, 15 const psImage* mask, 16 unsigned int maskVal, 17 psF64 unexposedValue) 18 18 { 19 double floorX = floor((psF64)(x) - 0.5); 20 double floorY = floor((psF64)(y) - 0.5); 21 psF64 fracX = x - 0.5 - floorX; 22 psF64 fracY = y - 0.5 - floorY; 23 int intFloorX = (int) floorX; 24 int intFloorY = (int) floorY; 25 int lastX = input->numCols - 1; 26 int lastY = input->numRows - 1; 27 psF32 V00 ;28 psF32 V01 ;29 psF32 V10 ;30 psF32 V11 ;31 bool valid00 = false; 32 bool valid01 = false; 33 bool valid10 = false; 34 bool valid11 = false; 35 36 if (intFloorY >= 0 && intFloorY <= lastY) { 37 if (intFloorX >= 0 && intFloorX <= lastX) { 38 V00 = input->data.F32[intFloorY][intFloorX]; 39 valid00 = true;40 } 41 if (intFloorX >= -1 && intFloorX < lastX) { 42 V10 = input->data.F32[intFloorY][intFloorX+1]; 43 valid10 = true;44 } 45 } 46 if (intFloorY >= -1 && intFloorY < lastY) { 47 if (intFloorX >= 0 && intFloorX <= lastX) { 48 V01 = input->data.F32[intFloorY+1][intFloorX]; 49 valid01 = true;50 } 51 if (intFloorX >= -1 && intFloorX < lastX) { 52 V11 = input->data.F32[intFloorY+1][intFloorX+1]; 53 valid11 = true;54 } 55 } 56 57 /* cover likely case of all pixels being valid more efficiently */ 58 if (valid00 && valid10 && valid01 && valid11) { 59 /* formula from the ADD */ 19 double floorX = floor((psF64)(x) - 0.5); 20 double floorY = floor((psF64)(y) - 0.5); 21 psF64 fracX = x - 0.5 - floorX; 22 psF64 fracY = y - 0.5 - floorY; 23 int intFloorX = (int) floorX; 24 int intFloorY = (int) floorY; 25 int lastX = input->numCols - 1; 26 int lastY = input->numRows - 1; 27 psF32 V00 = 0.0; 28 psF32 V01 = 0.0; 29 psF32 V10 = 0.0; 30 psF32 V11 = 0.0; 31 bool valid00 = false; 32 bool valid01 = false; 33 bool valid10 = false; 34 bool valid11 = false; 35 36 if (intFloorY >= 0 && intFloorY <= lastY) { 37 if (intFloorX >= 0 && intFloorX <= lastX) { 38 V00 = input->data.F32[intFloorY][intFloorX]; 39 valid00 = true; 40 } 41 if (intFloorX >= -1 && intFloorX < lastX) { 42 V10 = input->data.F32[intFloorY][intFloorX+1]; 43 valid10 = true; 44 } 45 } 46 if (intFloorY >= -1 && intFloorY < lastY) { 47 if (intFloorX >= 0 && intFloorX <= lastX) { 48 V01 = input->data.F32[intFloorY+1][intFloorX]; 49 valid01 = true; 50 } 51 if (intFloorX >= -1 && intFloorX < lastX) { 52 V11 = input->data.F32[intFloorY+1][intFloorX+1]; 53 valid11 = true; 54 } 55 } 56 57 /* cover likely case of all pixels being valid more efficiently */ 58 if (valid00 && valid10 && valid01 && valid11) { 59 /* formula from the ADD */ 60 60 return V00*SQUARE((1.0-fracX)*(1.0-fracY)) + V10*SQUARE(fracX*(1.0-fracY)) + 61 V01*SQUARE(fracY*(1.0-fracX)) + V11*SQUARE(fracX*fracY);62 } 63 64 /* OK, at least one pixel is not valid - need to do it piecemeal */ 65 66 psF64 V0 ;67 bool valid0 = true; 68 if (valid00 && valid10) { 69 V0 = V00*SQUARE(1-fracX)+V10*SQUARE(fracX); 70 } else if (valid00) { 71 V0 = V00; 72 } else if (valid10) { 73 V0 = V10; 74 } else { 75 valid0 = false; 76 } 77 78 psF64 V1 ;79 bool valid1 = true; 80 if (valid01 && valid11) { 81 V1 = V01*SQUARE(1-fracX)+V11*SQUARE(fracX); 82 } else if (valid01) { 83 V1 = V01; 84 } else if (valid11) { 85 V1 = V11; 86 } else { 87 valid1 = false; 88 } 89 90 if (valid0 && valid1) { 91 return ( V0*SQUARE(1-fracY) + V1*SQUARE(fracY) ); 92 } else if (valid0) { 93 return V0; 94 } else if (valid1) { 95 return V1; 96 } 97 98 return unexposedValue; 61 V01*SQUARE(fracY*(1.0-fracX)) + V11*SQUARE(fracX*fracY); 62 } 63 64 /* OK, at least one pixel is not valid - need to do it piecemeal */ 65 66 psF64 V0 = 0.0; 67 bool valid0 = true; 68 if (valid00 && valid10) { 69 V0 = V00*SQUARE(1-fracX)+V10*SQUARE(fracX); 70 } else if (valid00) { 71 V0 = V00; 72 } else if (valid10) { 73 V0 = V10; 74 } else { 75 valid0 = false; 76 } 77 78 psF64 V1 = 0.0; 79 bool valid1 = true; 80 if (valid01 && valid11) { 81 V1 = V01*SQUARE(1-fracX)+V11*SQUARE(fracX); 82 } else if (valid01) { 83 V1 = V01; 84 } else if (valid11) { 85 V1 = V11; 86 } else { 87 valid1 = false; 88 } 89 90 if (valid0 && valid1) { 91 return ( V0*SQUARE(1-fracY) + V1*SQUARE(fracY) ); 92 } else if (valid0) { 93 return V0; 94 } else if (valid1) { 95 return V1; 96 } 97 98 return unexposedValue; 99 99 } 100 100 101 101 102 102 103 bool stacTransform(psArray **outputs, // Transformed images for output104 psArray **outErrors, // Transformed error images for output105 const psArray *images, // Array of images to be transformed106 const psArray *maps, // Array of polynomials that do the transformation107 const psArray *errors, // Array of error images to be transformed108 const psArray *masks, // Masks of input images109 const psImage *region, // Region of interest for transformation110 const psVector *scales, // Relative scales111 const psVector *offsets, // Relative offsets112 int outnx, int outny// Size of output images103 bool stacTransform(psArray **outputs, // Transformed images for output 104 psArray **outErrors, // Transformed error images for output 105 const psArray *images, // Array of images to be transformed 106 const psArray *maps, // Array of polynomials that do the transformation 107 const psArray *errors, // Array of error images to be transformed 108 const psArray *masks, // Masks of input images 109 const psImage *region, // Region of interest for transformation 110 const psVector *scales, // Relative scales 111 const psVector *offsets, // Relative offsets 112 int outnx, int outny // Size of output images 113 113 ) 114 114 { 115 int nImages = images->n; // Number of images115 int nImages = images->n; // Number of images 116 116 117 117 // Check input sizes … … 126 126 assert(!*outputs || (*outputs)->n == nImages); 127 127 if (*outputs == NULL) { 128 *outputs = psArrayAlloc(nImages);129 psTrace("stac.transform", 5, "Allocating space for transformed images, %dx%d\n", outnx, outny);130 for (int i = 0; i < nImages; i++) {131 (*outputs)->data[i] = psImageAlloc(outnx, outny, PS_TYPE_F32);132 psImageInit((*outputs)->data[i], 0.0);133 }128 *outputs = psArrayAlloc(nImages); 129 psTrace("stac.transform", 5, "Allocating space for transformed images, %dx%d\n", outnx, outny); 130 for (int i = 0; i < nImages; i++) { 131 (*outputs)->data[i] = psImageAlloc(outnx, outny, PS_TYPE_F32); 132 psImageInit((*outputs)->data[i], 0.0); 133 } 134 134 } 135 135 … … 137 137 assert(!errors || ! *outErrors || errors->n == (*outErrors)->n); 138 138 if (errors && (*outErrors == NULL)) { 139 *outErrors = psArrayAlloc(errors->n);140 psTrace("stac.transform", 5, "Allocating space for transformed error images, %dx%d\n", outnx, outny);141 for (int i = 0; i < nImages; i++) {142 (*outErrors)->data[i] = psImageAlloc(outnx, outny, PS_TYPE_F32);143 }139 *outErrors = psArrayAlloc(errors->n); 140 psTrace("stac.transform", 5, "Allocating space for transformed error images, %dx%d\n", outnx, outny); 141 for (int i = 0; i < nImages; i++) { 142 (*outErrors)->data[i] = psImageAlloc(outnx, outny, PS_TYPE_F32); 143 } 144 144 } 145 145 … … 147 147 assert(!masks || masks->n == nImages); 148 148 if (masks != NULL) { 149 for (int i = 0; i < nImages; i++) {150 psImage *image = images->data[i];151 psImage *mask = masks->data[i];152 assert(mask->numRows == image->numRows && mask->numCols == image->numCols);153 }149 for (int i = 0; i < nImages; i++) { 150 psImage *image = images->data[i]; 151 psImage *mask = masks->data[i]; 152 assert(mask->numRows == image->numRows && mask->numCols == image->numCols); 153 } 154 154 } 155 155 … … 162 162 // Iterate over the images 163 163 for (int n = 0; n < nImages; n++) { 164 psTrace("stac.transform", 1, "Transforming image %d....\n",n);165 166 // Pull out the various stuff we're working on167 psImage *image = images->data[n]; // The input image168 psPlaneTransform *map = maps->data[n]; // The map169 psImage *outImage = (*outputs)->data[n]; // The output image170 psImage *error = NULL; // The error image171 psImage *outError = NULL; // The output error image172 if (errors) {173 error = errors->data[n];174 outError = (*outErrors)->data[n];175 }176 float offset = 0.0;// Relative offset177 float scale = 1.0;// Relative scale178 if (offsets) {179 offset = offsets->data.F32[n];180 }181 if (scales) {182 scale = scales->data.F32[n];183 }184 185 // Mask186 psImage *mask = NULL;187 if (masks != NULL) {188 mask = masks->data[n];189 }190 191 // Iterate over the output image pixels192 for (int y = 0; y < outny; y++) {193 for (int x = 0; x < outnx; x++) {194 // Only transform those pixels requested195 if (!region || (region && region->data.U8[y][x])) {196 // Transform!197 sky->x = (double)x + 0.5;198 sky->y = (double)y + 0.5;199 (void)psPlaneTransformApply(detector, map, sky);200 201 // Change PS_INTERPOLATE_BILINEAR to best available technique.202 outImage->data.F32[y][x] = (psF32)psImagePixelInterpolate(image, detector->x,203 detector->y, mask, 1, NAN,204 PS_INTERPOLATE_BILINEAR);205 if (error) {206 // Error is actually the variance207 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error,208 detector->x,209 detector->y,210 mask, 1, NAN);211 }212 213 outImage->data.F32[y][x] = (outImage->data.F32[y][x] - offset) / scale;214 outImage->data.F32[y][x] = outImage->data.F32[y][x] / SQUARE(scale);215 216 } // Pixels of interest217 218 }219 } // Iterating over output pixels164 psTrace("stac.transform", 1, "Transforming image %d....\n",n); 165 166 // Pull out the various stuff we're working on 167 psImage *image = images->data[n]; // The input image 168 psPlaneTransform *map = maps->data[n]; // The map 169 psImage *outImage = (*outputs)->data[n]; // The output image 170 psImage *error = NULL; // The error image 171 psImage *outError = NULL; // The output error image 172 if (errors) { 173 error = errors->data[n]; 174 outError = (*outErrors)->data[n]; 175 } 176 float offset = 0.0; // Relative offset 177 float scale = 1.0; // Relative scale 178 if (offsets) { 179 offset = offsets->data.F32[n]; 180 } 181 if (scales) { 182 scale = scales->data.F32[n]; 183 } 184 185 // Mask 186 psImage *mask = NULL; 187 if (masks != NULL) { 188 mask = masks->data[n]; 189 } 190 191 // Iterate over the output image pixels 192 for (int y = 0; y < outny; y++) { 193 for (int x = 0; x < outnx; x++) { 194 // Only transform those pixels requested 195 if (!region || (region && region->data.U8[y][x])) { 196 // Transform! 197 sky->x = (double)x + 0.5; 198 sky->y = (double)y + 0.5; 199 (void)psPlaneTransformApply(detector, map, sky); 200 201 // Change PS_INTERPOLATE_BILINEAR to best available technique. 202 outImage->data.F32[y][x] = (psF32)psImagePixelInterpolate(image, detector->x, 203 detector->y, mask, 1, NAN, 204 PS_INTERPOLATE_BILINEAR); 205 if (error) { 206 // Error is actually the variance 207 outError->data.F32[y][x] = (psF32)p_psImageErrorInterpolateBILINEAR_F32(error, 208 detector->x, 209 detector->y, 210 mask, 1, NAN); 211 } 212 213 outImage->data.F32[y][x] = (outImage->data.F32[y][x] - offset) / scale; 214 outImage->data.F32[y][x] = outImage->data.F32[y][x] / SQUARE(scale); 215 216 } // Pixels of interest 217 218 } 219 } // Iterating over output pixels 220 220 221 221 } // Iterating over images -
trunk/stac/src/stacWrite.c
r5743 r5745 4 4 #include "stac.h" 5 5 6 bool stacWriteMap(const char *mapName, // Filename to write to7 psPlaneTransform *map// Map to write6 bool stacWriteMap(const char *mapName, // Filename to write to 7 psPlaneTransform *map // Map to write 8 8 ) 9 9 { … … 12 12 FILE *mapFile = fopen(mapName, "w"); 13 13 if (!mapFile) { 14 fprintf(stderr, "Unable to open map file: %s\n", mapName);15 return false;14 fprintf(stderr, "Unable to open map file: %s\n", mapName); 15 return false; 16 16 } 17 17 18 psPolynomial2D *xMap = map->x; // x transform19 psPolynomial2D *yMap = map->y; // y transform18 psPolynomial2D *xMap = map->x; // x transform 19 psPolynomial2D *yMap = map->y; // y transform 20 20 21 21 // A crucial limitation of the current system --- the order of each polynomial must be the same 22 22 assert(xMap->nX == xMap->nY && yMap->nX == yMap->nY && xMap->nX == yMap->nX); 23 int order = xMap->nX; // The polynomial order23 int order = xMap->nX; // The polynomial order 24 24 fprintf(mapFile, "%d\n", order); 25 25 26 26 // x coefficients 27 for (int k = 0; k < order + 1; k++) {28 for (int j = 0; j < k + 1; j++) {29 int i = k - j;30 if (xMap->mask[i][j]) {31 fprintf(mapFile, "0.0 ");32 } else {33 fprintf(mapFile, "%g ", xMap->coeff[i][j]);34 }35 }27 for (int k = 0; k <= order; k++) { 28 for (int j = 0; j <= k; j++) { 29 int i = k - j; 30 if (xMap->mask[i][j]) { 31 fprintf(mapFile, "0.0 "); 32 } else { 33 fprintf(mapFile, "%g ", xMap->coeff[i][j]); 34 } 35 } 36 36 } 37 37 fprintf(mapFile, "\n"); 38 38 39 39 // y coefficients 40 for (int k = 0; k < order + 1; k++) {41 for (int j = 0; j < k + 1; j++) {42 int i = k - j;43 if (yMap->mask[i][j]) {44 fprintf(mapFile, "0.0 ");45 } else {46 fprintf(mapFile, "%g ", yMap->coeff[i][j]);47 }48 }40 for (int k = 0; k <= order; k++) { 41 for (int j = 0; j <= k; j++) { 42 int i = k - j; 43 if (yMap->mask[i][j]) { 44 fprintf(mapFile, "0.0 "); 45 } else { 46 fprintf(mapFile, "%g ", yMap->coeff[i][j]); 47 } 48 } 49 49 } 50 50 fprintf(mapFile, "\n"); 51 51 52 52 fclose(mapFile); 53 53 … … 57 57 58 58 bool stacWriteMaps(const psArray *names, // Filenames of the input images (will add ".map") 59 const psArray *maps// Maps to write59 const psArray *maps // Maps to write 60 60 ) 61 61 { … … 65 65 66 66 for (int i = 0; i < names->n; i++) { 67 char mapName[MAXCHAR];// Filename of error image68 sprintf(mapName, "%s.map",names->data[i]);69 if (!stacWriteMap(mapName, maps->data[i])) {70 return false;71 }67 char mapName[MAXCHAR]; // Filename of error image 68 sprintf(mapName, "%s.map", (const char*)names->data[i]); 69 if (!stacWriteMap(mapName, maps->data[i])) { 70 return false; 71 } 72 72 } 73 73 -
trunk/stac/src/sum.c
r5743 r5745 8 8 int main(int argc, char *argv[]) 9 9 { 10 const char *programName = argv[0]; // Program name11 10 const char *outputName = argv[1]; // Output file name 12 11 psArray *inputNames = psArrayAlloc(argc-2);
Note:
See TracChangeset
for help on using the changeset viewer.
