IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 21, 2005, 5:00:14 PM (20 years ago)
Author:
Paul Price
Message:

Mask and weight input and output

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/archive/scripts/src/phase2/pmFPARead.c

    r5371 r5564  
    1717
    1818// Read a FITS extension into a chip
    19 static bool readExtension(pmPixelData *pixelData, // Pixel data into which to read
     19static bool readExtension(p_pmHDU *hdu, // Pixel data into which to read
    2020                          psFits *fits  // The FITS file from which to read
    2121    )
    2222{
    23     const char *extName = pixelData->extname; // Extension name
     23    const char *extName = hdu->extname; // Extension name
    2424
    2525    psTrace(__func__, 7, "Moving to extension %s...\n", extName);
     
    9595
    9696    // Update the HDU with the new data
    97     pixelData->images = pixels;
    98     pixelData->header = header;
     97    hdu->images = pixels;
     98    hdu->header = header;
    9999
    100100    // XXX: Insert mask and weight reading here
     
    105105// Portion out an image into the cell
    106106static bool generateReadouts(pmCell *cell, // The cell that gets its bits
    107                              pmPixelData *data // Pixel data, containing image, mask, weights
     107                             p_pmHDU *hdu // Pixel data, containing image, mask, weights
    108108    )
    109109{
    110     psArray *images = data->images;     // Array of images (each of which is a readout)
    111     psArray *masks = data->masks;       // Array of masks (one for each readout)
     110    psArray *images = hdu->images;      // Array of images (each of which is a readout)
     111    psArray *masks = hdu->masks;        // Array of masks (one for each readout)
    112112    // Iterate over each of the image planes
    113113    for (int i = 0; i < images->n; i++) {
     
    118118        }
    119119
    120         pmReadout *readout = pmReadoutAlloc(cell, image, mask, 0,0,0,0,1,1);
     120        pmReadout *readout = pmReadoutAlloc(cell, image, mask, 0,0,1,1);
    121121        psFree(readout);                // This seems silly, but the alloc registers it with the cell, so we
    122122                                        // don't have to do anything with it.  Perhaps we should change
     
    137137    )
    138138{
    139     pmPixelData *pixelData = NULL;      // Pixel data from FITS file
     139    p_pmHDU *hdu = NULL;        // Pixel data from FITS file
    140140
    141141    // Read the PHU, if required
     
    152152    // Read in....
    153153    psTrace(__func__, 1, "Working on FPA...\n");
    154     if (fpa->data) {
    155         pixelData= fpa->data;
    156         psTrace(__func__, 3, "Reading pixels from extension %s into FPA.\n", pixelData->extname);
    157         if (! readExtension(pixelData, fits)) {
    158             psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", pixelData->extname);
     154    if (fpa->hdu) {
     155        hdu = fpa->hdu;
     156        psTrace(__func__, 3, "Reading pixels from extension %s into FPA.\n", hdu->extname);
     157        if (! readExtension(hdu, fits)) {
     158            psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", hdu->extname);
    159159            return false;
    160160        }
     
    174174        psTrace(__func__, 2, "Reading in chip %d...\n", i);
    175175
    176         if (chip->data) {
    177             pixelData = chip->data;
    178             psTrace(__func__, 3, "Reading pixels from extension %s into chip %d.\n", pixelData->extname, i);
    179             if (! readExtension(pixelData, fits)) {
    180                 psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", pixelData->extname);
     176        if (chip->hdu) {
     177            hdu = chip->hdu;
     178            psTrace(__func__, 3, "Reading pixels from extension %s into chip %d.\n", hdu->extname, i);
     179            if (! readExtension(hdu, fits)) {
     180                psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n", hdu->extname);
    181181                return false;
    182182            }
     
    196196            psTrace(__func__, 3, "Reading in cell %d...\n", j);
    197197
    198             if (cell->data) {
    199                 pixelData = cell->data;
    200                 psTrace(__func__, 5, "Reading pixels from extension %s into cell %d.\n", pixelData->extname,
     198            if (cell->hdu) {
     199                hdu = cell->hdu;
     200                psTrace(__func__, 5, "Reading pixels from extension %s into cell %d.\n", hdu->extname,
    201201                        j);
    202                 if (! readExtension(pixelData, fits)) {
     202                if (! readExtension(hdu, fits)) {
    203203                    psError(PS_ERR_IO, false, "Unable to read pixels from extension %s\n",
    204                             pixelData->extname);
     204                            hdu->extname);
    205205                    return false;
    206206                }
     
    210210            psTrace(__func__, 5, "Allocating readouts for chip %d cell %d...\n",
    211211                    i, j);
    212             generateReadouts(cell, pixelData);
     212            generateReadouts(cell, hdu);
    213213        }
    214214    }
     
    216216    return true;
    217217}
     218
     219// Translate a name from the configuration file, containing something like "%a_%d" to a real value
     220psString p_pmFPATranslateName(psString name, // The name to translate
     221                              pmCell *cell // The cell for which to translate
     222    )
     223{
     224    // %a is the FPA.NAME
     225    // %b is the CHIP.NAME
     226    // %c is the CELL.NAME
     227    // %d is the chip number
     228    // %e if the cell number
     229    // %f is the extension name
     230
     231    psString translation = psMemIncrRefCounter(name); // The translated string
     232    char *temp = NULL;                  // Temporary string
     233
     234    pmChip *chip = cell->parent;        // Chip of interest
     235    pmFPA *fpa = chip->parent;          // FPA of interest
     236
     237    // FPA.NAME
     238    if (temp = strstr(translation, "%a")) {
     239        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     240        // and there's not much of it anyway...
     241        psFree(translation);
     242        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     243        psString fpaName = psMetadataLookupString(NULL, fpa->concepts, "FPA.NAME"); // The value of FPA.NAME
     244        psStringAppend(&translation, "%s%s", fpaName, temp + 2);
     245        // So "translation" now contains the first part, the replaced string, and the last part.
     246    }
     247
     248    // CHIP.NAME
     249    if (temp = strstr(translation, "%b")) {
     250        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     251        // and there's not much of it anyway...
     252        psFree(translation);
     253        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     254        psString chipName = psMetadataLookupString(NULL, chip->concepts, "CHIP.NAME"); // CHIP.NAME's value
     255        psStringAppend(&translation, "%s%s", chipName, temp + 2);
     256        // So "translation" now contains the first part, the replaced string, and the last part.
     257    }
     258
     259    // CELL.NAME
     260    if (temp = strstr(translation, "%c")) {
     261        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     262        // and there's not much of it anyway...
     263        psFree(translation);
     264        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     265        psString cellName = psMetadataLookupString(NULL, cell->concepts, "CELL.NAME"); // CELL.NAME's value
     266        psStringAppend(&translation, "%s%s", cellName, temp + 2);
     267        // So "translation" now contains the first part, the replaced string, and the last part.
     268    }
     269
     270    // Chip number
     271    if (temp = strstr(translation, "%d")) {
     272        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     273        // and there's not much of it anyway...
     274        psFree(translation);
     275        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     276        // Search for the pointer to get the chip number
     277        int chipNum = -1;
     278        psArray *chips = fpa->chips;    // The array of chips
     279        for (int i = 0; i < chips->n && chipNum < 0; i++) {
     280            if (chips->data[i] == chip) {
     281                chipNum = i;
     282            }
     283        }
     284        if (chipNum < 0) {
     285            psError(PS_ERR_IO, true, "Unable to find chip to get name: %s\n", name);
     286            // Try to muddle on by leaving the number out
     287            psStringAppend(&translation, "%s", temp + 2);
     288        } else {
     289            psStringAppend(&translation, "%d%s", chipNum, temp + 2);
     290        }
     291        // So "translation" now contains the first part, the replaced string, and the last part.
     292    }
     293
     294    // Cell number
     295    if (temp = strstr(translation, "%e")) {
     296        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     297        // and there's not much of it anyway...
     298        psFree(translation);
     299        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     300        // Search for the pointer to get the cell number
     301        int cellNum = -1;
     302        psArray *cells = chip->cells;   // The array of cells
     303        for (int i = 0; i < cells->n && cellNum < 0; i++) {
     304            if (cells->data[i] == cell) {
     305                cellNum = i;
     306            }
     307        }
     308        if (cellNum < 0) {
     309            psError(PS_ERR_IO, true, "Unable to find cell to get name: %s\n", name);
     310            // Try to muddle on by leaving the number out
     311            psStringAppend(&translation, "%s", temp + 2);
     312        } else {
     313            psStringAppend(&translation, "%d%s", cellNum, temp + 2);
     314        }
     315        // So "translation" now contains the first part, the replaced string, and the last part.
     316    }
     317
     318    // Extension name
     319    if (temp = strstr(translation, "%f")) {
     320        // This is not particularly friendly to the memory allocation, but the cache should make it OK,
     321        // and there's not much of it anyway...
     322        psFree(translation);
     323        translation = psStringNCopy(name, strlen(name) - strlen(temp)); // Copy first part of string
     324        const char *extname = NULL;
     325        if (cell->hdu) {
     326            extname = cell->hdu->extname;
     327        } else if (chip->hdu) {
     328            extname = chip->hdu->extname;
     329        } else if (fpa->hdu) {
     330            extname = fpa->hdu->extname;
     331        }
     332        psStringAppend(&translation, "%s%s", extname, temp + 2);
     333        // So "translation" now contains the first part, the replaced string, and the last part.
     334    }
     335
     336    return translation;
     337}
     338
     339// Read a mask into the FPA
     340bool pmFPAReadMask(pmFPA *fpa,          // FPA to read into
     341                   psFits *source       // Source FITS file (for the original data)
     342    )
     343{
     344    const psMetadata *camera = fpa->camera; // Camera configuration for FPA
     345    bool mdok = false;                  // Status of MD lookup
     346
     347    // Get the required information from the camera configuration
     348    psMetadata *supps = psMetadataLookupMD(&mdok, camera, "SUPPLEMENTARY"); // Rules for supplementary data
     349    if (! mdok || ! supps) {
     350        psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
     351        return false;
     352    }
     353    psString sourceType = psMetadataLookupString(&mdok, supps, "MASK.SOURCE"); // Type of source: EXT | FILE
     354    if (! mdok || strlen(sourceType) <= 0) {
     355        psError(PS_ERR_IO, false, "Unable to find MASK.SOURCE in SUPPLEMENTARY section of camera "
     356                "configuration!\n");
     357        return false;
     358    }
     359    psString name = psMetadataLookupString(&mdok, supps, "MASK.NAME"); // Name of mask
     360    if (! mdok || strlen(sourceType) <= 0) {
     361        psError(PS_ERR_IO, false, "Unable to find MASK.NAME in SUPPLEMENTARY section of camera "
     362                "configuration!\n");
     363        return false;
     364    }
     365
     366    // Go through the FPA to each cell/readout to get the mask
     367    p_pmHDU *hdu = fpa->hdu;            // The HDU into which we will read the mask
     368    psArray *chips = fpa->chips;        // Array of chips
     369    for (int chipNum = 0; chipNum < chips->n; chipNum++) {
     370        pmChip *chip = chips->data[chipNum]; // The current chip of interest
     371        if (chip->valid) {
     372            if (chip->hdu) {
     373                hdu = chip->hdu;
     374            }
     375            psArray *cells = chip->cells;       // Array of cells
     376            for (int cellNum = 0; cellNum < cells->n; cellNum++) {
     377                pmCell *cell = cells->data[cellNum]; // The current cell of interest
     378                if (cell->valid) {
     379                    if (cell->hdu) {
     380                        hdu = cell->hdu;
     381                    }
     382
     383                    // Now, need to find out where to get the pixels
     384                    psFits *maskSource = source;        // Source of mask image
     385                    if (strcasecmp(sourceType, "FILE") == 0) {
     386                        // Source is a file (with optional extension, e.g., "myMaskFile.fits:thisExt"
     387                        psString filenameExt = p_pmFPATranslateName(name, cell);
     388                        char *colon = strchr(filenameExt, ':'); // Pointer to a colon in the filename-extn
     389                        psString filename = NULL; // The filename
     390                        psString extname = NULL;// The extenstion name
     391                        if (colon) {
     392                            filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
     393                            if (strlen(colon) > 1) {
     394                                extname = psStringCopy(colon + 1);
     395                            }
     396                        } else {
     397                            filename = psMemIncrRefCounter(filenameExt);
     398                        }
     399                       
     400                        maskSource = psFitsAlloc(filename);
     401                        if (extname) {
     402                            if (! psFitsMoveExtName(maskSource, extname)) {
     403                                psLogMsg(__func__, PS_LOG_WARN, "Unable to find extension %s to read mask.\n",
     404                                         extname);
     405                                return false;
     406                            }
     407                        }
     408                        psFree(filename);
     409                        psFree(extname);
     410                        psFree(filenameExt);
     411                    } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
     412                        // Source is an extension in the original file
     413                        psString extname = p_pmFPATranslateName(name, cell);
     414                        psFitsMoveExtName(maskSource, extname);
     415                    }
     416                   
     417                    // We've arrived where the pixels are.  Now we need to read them in.
     418                    psMetadata *header = psFitsReadHeader(NULL, maskSource); // The header
     419                    bool mdStatus = false;
     420                    int nAxis = psMetadataLookupS32(&mdStatus, header, "NAXIS");
     421                    if (!mdStatus) {
     422                        psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header for "
     423                                 "mask (%s)!\n", name);
     424                    }
     425                    if (nAxis != 2 && nAxis != 3) {
     426                        psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into "
     427                                 "a single image anyway.\n");
     428                    }
     429           
     430                    int numPlanes = 1;  // Number of planes
     431                    if (nAxis == 3) {
     432                        numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
     433                        if (!mdStatus) {
     434                            psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
     435                            // Try to proceed by taking only the first plane
     436                            numPlanes = 1;
     437                        }
     438                        if (numPlanes != 1 && numPlanes != cell->readouts->n) {
     439                            psError(PS_ERR_IO, false, "Number of masks (%d) does not match number of "
     440                                    "readouts (%d)\n", numPlanes, cell->readouts->n);
     441                            // Try to proceed by taking only the first plane
     442                            numPlanes = 1;
     443                        }
     444                    }
     445
     446                    hdu->masks = psArrayAlloc(hdu->images->n);
     447                   
     448                    // Read each plane into the array
     449                    psArray *readouts = cell->readouts; // The array of readouts
     450                    for (int i = 0; i < hdu->masks->n; i++) {
     451                        psImage *mask = NULL; // The mask to be added
     452                        if (i < numPlanes) {
     453                            // Read the mask from the file
     454                            psTrace(__func__, 9, "Reading plane %d\n", i);
     455                            psRegion region = {0, 0, 0, 0};
     456                            mask = psFitsReadImage(NULL, maskSource, region, i);
     457                        } else {
     458                            // One mask in the file is provided for all planes in the original image
     459                            psTrace(__func__, 9, "Copying plane 0 into plane %d\n", i);
     460                            psImage *original = hdu->masks->data[0];
     461                            mask = psImageCopy(NULL, original, original->type.type);
     462                        }
     463                        hdu->masks->data[0] = mask;
     464                        pmReadout *readout = readouts->data[i];
     465                        readout->mask = mask;
     466                        // Check the dimensions
     467                        // XXX: Perhaps this check should be against the CELL.TRIMSEC, not the image size?
     468                        if (mask->numCols < readout->image->numCols ||
     469                            mask->numRows < readout->image->numRows)
     470                        {
     471                            psError(PS_ERR_IO, false, "Mask size (%dx%d) not compatible with image (%dx%d)\n",
     472                                    mask->numCols, mask->numRows, readout->image->numCols,
     473                                    readout->image->numRows);
     474                            return false;
     475                        }
     476                    } // Iterating over readouts
     477                } // Valid cells
     478            } // Iterating over cells
     479        } // Valid chips
     480    } // Iterating over chips
     481
     482    return true;
     483}
     484
     485
     486// Read a mask into the FPA
     487// This is just a copy of the above pmFPAReadMask, replacing "mask" with "weight" throughout.
     488bool pmFPAReadWeight(pmFPA *fpa,        // FPA to read into
     489                     psFits *source     // Source FITS file (for the original data)
     490    )
     491{
     492    const psMetadata *camera = fpa->camera; // Camera configuration for FPA
     493    bool mdok = false;                  // Status of MD lookup
     494
     495    // Get the required information from the camera configuration
     496    psMetadata *supps = psMetadataLookupMD(&mdok, camera, "SUPPLEMENTARY"); // Rules for supplementary data
     497    if (! mdok || ! supps) {
     498        psError(PS_ERR_IO, false, "Unable to find SUPPLEMENTARY in camera configuration!\n");
     499        return false;
     500    }
     501    psString sourceType = psMetadataLookupString(&mdok, supps, "WEIGHT.SOURCE"); // Type of source: EXT | FILE
     502    if (! mdok || strlen(sourceType) <= 0) {
     503        psError(PS_ERR_IO, false, "Unable to find WEIGHT.SOURCE in SUPPLEMENTARY section of camera "
     504                "configuration!\n");
     505        return false;
     506    }
     507    psString name = psMetadataLookupString(&mdok, supps, "WEIGHT.NAME"); // Name of weight
     508    if (! mdok || strlen(sourceType) <= 0) {
     509        psError(PS_ERR_IO, false, "Unable to find WEIGHT.NAME in SUPPLEMENTARY section of camera "
     510                "configuration!\n");
     511        return false;
     512    }
     513
     514    // Go through the FPA to each cell/readout to get the weight
     515    p_pmHDU *hdu = fpa->hdu;            // The HDU into which we will read the weight
     516    psArray *chips = fpa->chips;        // Array of chips
     517    for (int chipNum = 0; chipNum < chips->n; chipNum++) {
     518        pmChip *chip = chips->data[chipNum]; // The current chip of interest
     519        if (chip->valid) {
     520            if (chip->hdu) {
     521                hdu = chip->hdu;
     522            }
     523            psArray *cells = chip->cells;       // Array of cells
     524            for (int cellNum = 0; cellNum < cells->n; cellNum++) {
     525                pmCell *cell = cells->data[cellNum]; // The current cell of interest
     526                if (cell->valid) {
     527                    if (cell->hdu) {
     528                        hdu = cell->hdu;
     529                    }
     530
     531                    // Now, need to find out where to get the pixels
     532                    psFits *weightSource = source;      // Source of weight image
     533                    if (strcasecmp(sourceType, "FILE") == 0) {
     534                        // Source is a file (with optional extension, e.g., "myWeightFile.fits:thisExt"
     535                        psString filenameExt = p_pmFPATranslateName(name, cell);
     536                        char *colon = strchr(filenameExt, ':'); // Pointer to a colon in the filename-extn
     537                        psString filename = NULL; // The filename
     538                        psString extname = NULL;// The extenstion name
     539                        if (colon) {
     540                            filename = psStringNCopy(filenameExt, strlen(filenameExt) - strlen(colon));
     541                            if (strlen(colon) > 1) {
     542                                extname = psStringCopy(colon + 1);
     543                            }
     544                        } else {
     545                            filename = psMemIncrRefCounter(filenameExt);
     546                        }
     547                       
     548                        weightSource = psFitsAlloc(filename);
     549                        if (extname) {
     550                            if (! psFitsMoveExtName(weightSource, extname)) {
     551                                psLogMsg(__func__, PS_LOG_WARN, "Unable to find extension %s to read "
     552                                         "weight.\n", extname);
     553                                return false;
     554                            }
     555                        }
     556                        psFree(filename);
     557                        psFree(extname);
     558                        psFree(filenameExt);
     559                    } else if (strncasecmp(sourceType, "EXT", 3) == 0) {
     560                        // Source is an extension in the original file
     561                        psString extname = p_pmFPATranslateName(name, cell);
     562                        psFitsMoveExtName(weightSource, extname);
     563                    }
     564                   
     565                    // We've arrived where the pixels are.  Now we need to read them in.
     566                    psMetadata *header = psFitsReadHeader(NULL, weightSource); // The header
     567                    bool mdStatus = false;
     568                    int nAxis = psMetadataLookupS32(&mdStatus, header, "NAXIS");
     569                    if (!mdStatus) {
     570                        psLogMsg(__func__, PS_LOG_WARN, "There is no NAXIS keyword in the FITS header for "
     571                                 "weight (%s)!\n", name);
     572                    }
     573                    if (nAxis != 2 && nAxis != 3) {
     574                        psLogMsg(__func__, PS_LOG_WARN, "Image is not 2- or 3-dimensional --- reading into "
     575                                 "a single image anyway.\n");
     576                    }
     577           
     578                    int numPlanes = 1;  // Number of planes
     579                    if (nAxis == 3) {
     580                        numPlanes = psMetadataLookupS32(&mdStatus, header, "NAXIS3");
     581                        if (!mdStatus) {
     582                            psError(PS_ERR_IO, false, "Unable to read NAXIS3 for 3-dimensional image!\n");
     583                            // Try to proceed by taking only the first plane
     584                            numPlanes = 1;
     585                        }
     586                        if (numPlanes != 1 && numPlanes != cell->readouts->n) {
     587                            psError(PS_ERR_IO, false, "Number of weights (%d) does not match number of "
     588                                    "readouts (%d)\n", numPlanes, cell->readouts->n);
     589                            // Try to proceed by taking only the first plane
     590                            numPlanes = 1;
     591                        }
     592                    }
     593
     594                    hdu->weights = psArrayAlloc(hdu->images->n);
     595                   
     596                    // Read each plane into the array
     597                    psArray *readouts = cell->readouts; // The array of readouts
     598                    for (int i = 0; i < hdu->weights->n; i++) {
     599                        psImage *weight = NULL; // The weight to be added
     600                        if (i < numPlanes) {
     601                            // Read the weight from the file
     602                            psTrace(__func__, 9, "Reading plane %d\n", i);
     603                            psRegion region = {0, 0, 0, 0};
     604                            weight = psFitsReadImage(NULL, weightSource, region, i);
     605                        } else {
     606                            // One weight in the file is provided for all planes in the original image
     607                            psTrace(__func__, 9, "Copying plane 0 into plane %d\n", i);
     608                            psImage *original = hdu->weights->data[0];
     609                            weight = psImageCopy(NULL, original, original->type.type);
     610                        }
     611                        hdu->weights->data[0] = weight;
     612                        pmReadout *readout = readouts->data[i];
     613                        readout->weight = weight;
     614                        // Check the dimensions
     615                        // XXX: Perhaps this check should be against the CELL.TRIMSEC, not the image size?
     616                        if (weight->numCols < readout->image->numCols ||
     617                            weight->numRows < readout->image->numRows)
     618                        {
     619                            psError(PS_ERR_IO, false, "Weight size (%dx%d) not compatible with image "
     620                                    "(%dx%d)\n", weight->numCols, weight->numRows, readout->image->numCols,
     621                                    readout->image->numRows);
     622                            return false;
     623                        }
     624                    } // Iterating over readouts
     625                } // Valid cells
     626            } // Iterating over cells
     627        } // Valid chips
     628    } // Iterating over chips
     629
     630    return true;
     631}
Note: See TracChangeset for help on using the changeset viewer.