static int UpdateHdr (char *output) { extern int status; Hdr phdr; /* primary header */ IODescPtr im; /* descriptor for output image */ int PutKeyBool (Hdr *, char *, Bool, char *); sprintf(MsgText, "Trying to open %s...",output); trlmessage (MsgText); initHdr (&phdr); /* Open input image in order to read its primary header. */ im = openUpdateImage (output, "", 0, &phdr); if (hstio_err()) { trlopenerr (output); closeImage(im); return (status = OPEN_FAILED); } if (PutKeyBool (&phdr, "ASN_PROD", True, "") ) { freeHdr (&phdr); trlerror ("Couldn't update ASN_PROD keyword in ASN table header"); return(status = KEYWORD_MISSING); } /* write out primary header */ if (putHeader (im)) status = HEADER_PROBLEM; if (hstio_err() || status) { trlreaderr (output); closeImage (im); return (status = OPEN_FAILED); } closeImage (im); /* Close the ASN table's primary header. */ freeHdr (&phdr); sprintf(MsgText, "Updated Global Header for %s...",output); trlmessage (MsgText); return (status); }
int LoadHdr (char *input, Hdr *phdr) { extern int status; IODescPtr im; /* descriptor for input image */ sprintf(MsgText, "Trying to open %s...",input); trlmessage (MsgText); /* Open input image in order to read its primary header. */ im = openInputImage (input, "", 0); if (hstio_err()) { trlopenerr (input); return (status = OPEN_FAILED); } initHdr (phdr); /* get primary header */ if (getHeader (im, phdr) ) status = HEADER_PROBLEM; if (hstio_err() || status) { trlreaderr (input); closeImage (im); freeHdr (phdr); return (status = OPEN_FAILED); } closeImage (im); sprintf(MsgText, "Read in Primary header from %s...",input); trlmessage (MsgText); return (status); }
int GetAsnTable (AsnInfo *asn) { /* Arguments: ** asn o: Association info structure */ extern int status; /* Local variables */ int i; /* loop index */ int nrows; /* number of rows in ASNTAB */ int col, row; /* loop indexes */ IRAFPointer tp; /* ASNTAB table pointer */ IRAFPointer colptr[NCOLS]; /* ASNTAB column pointers */ int numsp; /* number of sub-products in asn */ int posid; /* id of sub-product */ RowInfo *exp; /* Internal structure for table information */ int *spmems, *expmem; /* number of EXP for each sub-product */ int poslen; /* Length of memtype string minus POSID */ int prodid; /* id of product */ int expid; int defid; /* default position id for exposures */ int procprod; int maxspmems; /* max number of sub-product members */ char *word; Bool proddth; char spname_ext[SZ_CBUF+1]; /* Extension for sub-product */ char spname_ext_cte[SZ_CBUF+1]; /* Extension for sub-product */ char memtype[SZ_COLNAME+1]; char memsubtype[SZ_COLNAME+1]; /* ASNTAB column names */ char colname[NCOLS][SZ_COLNAME+1] = { "MEMNAME", "MEMTYPE", "MEMPRSNT" }; /* Function definitions */ void freeAsnInfo (AsnInfo *); int allocAsnInfo (AsnInfo *, int, int *); void trlopenerr (char *); void trlwarn (char *); char *lowcase (char *, char *); int MkName (char *, char *, char *, char *, char *, int); void initRowInfo (RowInfo *); int streq_ic (char *, char *); /* strings equal? (case insensitive) */ if (asn->debug) { sprintf (MsgText, "GetAsnTable: ASN_TABLE is %s",asn->asn_table); trlmessage (MsgText); } /* Open the ASN table */ tp = c_tbtopn (asn->asn_table, IRAF_READ_ONLY, 0); if (c_iraferr()) { trlopenerr (asn->asn_table); return (status = TABLE_ERROR); } /* Get pointers to columns in ASNTAB */ for (col=0; col < NCOLS; col++) { c_tbcfnd1 (tp, colname[col], &(colptr[col])); if (c_iraferr() || colptr[col] == 0) { sprintf (MsgText, "Can't find column %s in %s", colname[col], asn->asn_table); trlerror (MsgText); c_tbtclo (tp); return (status = COLUMN_NOT_FOUND); } } /* Find out how many rows are in ASNTAB */ nrows = 0; nrows = c_tbpsta (tp, TBL_NROWS); if (nrows <= 0) { sprintf (MsgText, "Invalid number of rows in %s", asn->asn_table); trlerror (MsgText); c_tbtclo (tp); return (status = TABLE_ERROR); } /* Initialize total number of members based on number of ** rows in table */ asn->numasn = nrows; poslen = 0; /* Allocate space for internal variables */ exp = NULL; exp = (RowInfo *)calloc(nrows, sizeof(RowInfo)); for (row = 0; row < nrows; row++) initRowInfo (&(exp[row])); /* Read each row of ASNTAB into a local structure */ for (row = 0; row < nrows; row++) { /* Get the MEMBER NAME in this row */ c_tbegtt (tp, colptr[0], row+1, exp[row].memname, SZ_CBUF); if (c_iraferr()) { sprintf (MsgText, "Can't read %s in row %d in %s", colname[0], row+1, asn->asn_table); trlerror (MsgText); c_tbtclo (tp); free (exp); return (status = ELEMENT_NOT_FOUND); } /* Convert to lowercase for use as a file name */ for (i = 0; i < strlen(exp[row].memname); i++) exp[row].memname[i] = tolower(exp[row].memname[i]); /* Get the TYPE in this row */ c_tbegtt (tp, colptr[1], row+1, exp[row].mtype, SZ_CBUF); if (c_iraferr()) { sprintf (MsgText, "Can't read %s in row %d in %s", colname[1], row+1, asn->asn_table); trlerror (MsgText); c_tbtclo (tp); free (exp); return (status = ELEMENT_NOT_FOUND); } /* Convert to lowercase for use later in routine. ** Also, if a value of MEMTYPE contains a UNDERLINE, then ** record conversion to DASH in trailer file and warn ** user to correct the value. */ lowcase (exp[row].type, exp[row].mtype); for (i = 0; i < strlen(exp[row].type); i++) { if (exp[row].type[i] == UNDERLINE_CHAR) { exp[row].type[i] = DASH_CHAR; sprintf(MsgText, "MEMTYPE %s in row %d was INVALID and needs to be corrected.", exp[row].mtype, row+1); trlwarn(MsgText); } } /* Get the STATUS in this row */ c_tbegtb (tp, colptr[2], row+1, &(exp[row].prsnt)); if (c_iraferr()) { sprintf (MsgText, "Can't read %s in row %d in %s", colname[2], row+1, asn->asn_table); trlerror (MsgText); c_tbtclo (tp); free (exp); return (status = ELEMENT_NOT_FOUND); } if (asn->debug) { sprintf (MsgText, "GetAsnTable: Read in row %d from ASN table", row); trlmessage (MsgText); } } /* ** Determine whether CRCORR or RPTOBS processing will be required ** by searching for MEMTYPE of EXP_CR* or EXP_RPT*, respectively. ** Once it is determined, go on to next step... */ for (row = 0; row < nrows; row++) { /* Check to see if we need to do CR-SPLIT combination ... */ if (strstr (exp[row].type, "-cr") != NULL) { asn->crcorr = PERFORM; asn->rptcorr = OMIT; poslen = CRLEN; break; /* ... or REPEAT-OBS combination ... */ } else if (strstr (exp[row].type, "-rp") != NULL) { asn->rptcorr = PERFORM; asn->crcorr = OMIT; poslen = RPTLEN; break; /* ... or neither at all */ } else { asn->rptcorr = OMIT; asn->crcorr = OMIT; poslen = DTHLEN; } } /* Default to always perform DRIZCORR step */ asn->dthcorr = PERFORM; if (asn->debug) { sprintf (MsgText, "GetAsnTable: CRCORR = %d, RPTCORR = %d", asn->crcorr,asn->rptcorr); trlmessage (MsgText); } /* Sort through the list figuring out which are input vs. output ** files, and see if any input files are missing. */ /* Initialize local variables */ numsp = 0; posid = 0; prodid = 0; proddth = False; defid = 1; /* Find out how many products/sub-products are in the association ** and determine the posid for each member. */ for (row = 0; row < nrows; row++) { memtype[0] = '\0'; memsubtype[0] = '\0'; /* As long as this is not the final product, ** count number of members in each product/sub-product...*/ if (strstr(exp[row].type,"prod-dth") != NULL) { exp[row].posid = 0; posid = 0; /* If we have a dither product listed, we want to eventually ** perform dither combining step... */ prodid++; proddth = True; /* We always want to produce a product, but if ** not set to PERFORM, then create an empty product... */ if (asn->dthcorr == OMIT) asn->dthcorr = DUMMY; } else { strcpy(memtype,exp[row].type); /* Let's start by breaking up the MEMTYPE string */ word = strtok(memtype,"-"); strcpy(memsubtype,word); /* The end of this second part of MEMTYPE has the POSID */ word = strtok(NULL,"\n"); /* If the last character of the memtype is a number or letter, ** convert to an integer value... */ if (streq_ic(word,"crj") || streq_ic(word,"rpt") || streq_ic(word,"crc") ) { posid = 1; } else { if (exp[row].prsnt || streq_ic(memsubtype,"prod")) { if (isalnum(word[poslen])) { /* Interpret the POSID from the second part ** of MEMTYPE */ posid=(int)strtol(&word[poslen],(char **)NULL,10); } else { /* Otherwise, assume it is a different pointing ** and assign an incremented position ID. After ** all, it is NOT a CR-SPLIT or RPT-OBS exposure.*/ posid = defid; defid++; } } } /* Keep track of how many sub-products there are based on ** POSID from MEMTYPE values */ if (posid > numsp) { if ((exp[row].prsnt && (strstr(memtype,"exp") != NULL)) || strstr(memtype,"prod") != NULL) { numsp++; } } exp[row].posid = posid; } if (asn->debug) { sprintf (MsgText, "GetAsnTable: Posid = %d for row %d",posid, row); trlmessage (MsgText); } /* If the member is missing, give a warning */ /* This implies that MEMPRSNT must be set to YES for EXP_* ** This is not fatal for WF3. Simply decrement tmembers. */ if (!exp[row].prsnt && strncmp(exp[row].type, "prod-",5) != 0) { sprintf (MsgText, "Member \"%s\" is not present", exp[row].memname); trlwarn (MsgText); asn->numasn--; /* Now flag row as being absent so it doesn't get passed ** along for further processing... */ exp[row].posid = MEMABSENT; } } if (asn->debug) { sprintf (MsgText, "GetAsnTable: NUMSP = %d, PRODID = %d",numsp, prodid); trlmessage (MsgText); } /* Check for existence of enough data to process */ if (asn->numasn < 1) { trlerror ("No data available for given assoc. table"); freeAsnInfo (asn); return (status = ERROR_RETURN); } /* Record the number of products found in association */ if (proddth) { asn->numprod = prodid; } else { /* If there are no PROD-DTH entries in ASN table, set ** numprod to 1 */ asn->numprod = prodid + 1; } /* Determine what elements should be processed based on ** initial input, either FULL or PARTIAL processing. */ procprod = 0; if (asn->process != FULL) { for (row=0; row < nrows; row++){ /* Look for entry with same name as input */ if (streq_ic(exp[row].memname, asn->rootname)) { /* We only want to process this product */ procprod = exp[row].posid; numsp = 1; } } } /* Allocate space to count number of exposures per sub-product ** with spmems[0] being reserved for final output product ** since POSID starts indexing at 1. */ spmems = (int *)calloc(numsp+1,sizeof(int)); expmem = (int *)calloc(numsp+1,sizeof(int)); /* Initialize arrays */ for (i=0; i <= numsp; i++) { spmems[i] = 0; expmem[i] = 0; } /* For each sub-product, ** identify each EXP that belongs to that posid and ** is present to be processed. */ for (row=0; row < nrows; row++) { if (strstr(exp[row].type, "exp-") && exp[row].posid > MEMABSENT) { if ((asn->process != FULL && exp[row].posid == procprod) || asn->process == FULL) { spmems[exp[row].posid]++; /* Exposure IDs will start at 1 to be consistent ** with POSID numbering. Initialize here, count later. */ expmem[exp[row].posid] = 1; } } } /* Allocate slots for all members in ASN info structure */ if (allocAsnInfo (asn, numsp, spmems)) { return (status = TABLE_ERROR); } asn->product[prodid].prodid = prodid; /* Reset prodid for filling ASN table */ prodid = 0; /* Copy summary information about ASN relationships to ASN structure. */ maxspmems = 0; asn->numsp = numsp; for (i=0; i <= numsp; i++) { asn->spmems[i] = spmems[i]; if (spmems[i] > maxspmems) maxspmems = spmems[i]; } /* If there aren't any sub-products with more than 1 member, then ** omit crcorr/rptcorr processing */ if ((maxspmems < 2) && asn->crcorr == PERFORM) { sprintf (MsgText, "No sub-product with more than 1 member; CRCORR will be skipped"); trlwarn (MsgText); asn->crcorr = DUMMY; } else if ((maxspmems < 2) && asn->rptcorr == PERFORM) { sprintf (MsgText, "No sub-product with more than 1 member; RPTCORR will be skipped"); trlwarn (MsgText); asn->rptcorr = DUMMY; } /* Copy information read-in into ASN structure now... */ for (row = 0; row < nrows; row++) { if (exp[row].posid != MEMABSENT) { if ((asn->process != FULL && exp[row].posid == procprod) || asn->process == FULL) { posid = exp[row].posid; /* Is this row the final product entry? */ if (strstr(exp[row].type, "prod-dth") != NULL) { strcpy (asn->product[prodid].name, exp[row].memname); strcpy (asn->product[prodid].mtype, exp[row].type); asn->product[prodid].prsnt = exp[row].prsnt; asn->product[prodid].numsp = numsp; asn->product[prodid].asnrow = row+1; /* Create full file name for this image */ if (MkName (exp[row].memname, "_raw", "_drz", "", asn->product[prodid].prodname, SZ_LINE)){ strcpy(asn->product[prodid].prodname, exp[row].memname); strcat (asn->product[prodid].prodname, "_drz.fits"); } /* Create full file name for this CTE image */ if (MkName (exp[row].memname, "_rac_tmp", "_drc", "", asn->product[prodid].prodname_cte, SZ_LINE)){ strcpy(asn->product[prodid].prodname_cte, exp[row].memname); strcat (asn->product[prodid].prodname_cte, "_drc.fits"); } /* Or, is this row an input exposure? */ } else if (strstr(exp[row].type, "exp-") != NULL) { if (exp[row].posid > MEMABSENT) { /* Internal counter for which exposure we want for ** a position */ expid = expmem[posid]; strcpy(asn->product[prodid].subprod[posid].exp[expid].name, exp[row].memname); strcpy(asn->product[prodid].subprod[posid].exp[expid].mtype, exp[row].type); asn->product[prodid].subprod[posid].exp[expid].prsnt = exp[row].prsnt; asn->product[prodid].subprod[posid].exp[expid].asnrow= row+1; /* Create full file name for this image */ if (MkName (exp[row].memname, "_raw", "_raw", "", asn->product[prodid].subprod[posid].exp[expid].expname, SZ_LINE)) { strcpy(asn->product[prodid].subprod[posid].exp[expid].expname, exp[row].memname); strcat(asn->product[prodid].subprod[posid].exp[expid].expname, "_raw.fits"); } /* Fill-in sub-product information for EXP-DTH ** exposures which don't create sub-products */ if (strstr(exp[row].type, "exp-dth") != NULL) { if (!MkName (exp[row].memname, "_raw", "_flt", "", asn->product[prodid].subprod[posid].spname, SZ_LINE) ) { strcpy(asn->product[prodid].subprod[posid].name, exp[row].memname); strcpy(asn->product[prodid].subprod[posid].mtype, exp[row].type); asn->product[prodid].subprod[posid].posid = exp[row].posid; } } /* Increment that counter for next exposure's id ** for this posid */ expmem[posid]++; } /* If neither, it must be a sub-product */ } else { if (spmems[posid] > 0) { strcpy(asn->product[prodid].subprod[posid].name, exp[row].memname); strcpy(asn->product[prodid].subprod[posid].mtype, exp[row].type); asn->product[prodid].subprod[posid].prsnt = exp[row].prsnt; asn->product[prodid].subprod[posid].asnrow = row+1; /* Create full file name for this image for ** DTHCORR input */ spname_ext[0] = '\0'; spname_ext_cte[0] = '\0'; if (asn->crcorr || asn->rptcorr) { strcpy (spname_ext, "_crj"); strcpy (spname_ext_cte,"_crc"); } else { strcpy (spname_ext, "_sfl"); strcpy (spname_ext_cte, "_sfl"); } if (MkName (exp[row].memname, "_raw", spname_ext, "", asn->product[prodid].subprod[posid].spname, SZ_LINE)) { strcpy(asn->product[prodid].subprod[posid].spname, exp[row].memname); strcat(asn->product[prodid].subprod[posid].spname, spname_ext); strcat(asn->product[prodid].subprod[posid].spname, ".fits"); } if (MkName (exp[row].memname, "_raw", spname_ext_cte, "", asn->product[prodid].subprod[posid].spname_cte, SZ_LINE)) { strcpy(asn->product[prodid].subprod[posid].spname_cte, exp[row].memname); strcat(asn->product[prodid].subprod[posid].spname_cte, spname_ext_cte); strcat(asn->product[prodid].subprod[posid].spname_cte, ".fits"); } asn->product[prodid].subprod[posid].numexp = spmems[posid]; asn->product[prodid].subprod[posid].posid = posid; } } } } /* Process only those exposures where MEMPRSNT == YES */ } /* Close the ASN table. We are done reading it in. */ c_tbtclo (tp); /* Clean up memory usage as well. */ free (spmems); free (expmem); free (exp); if (asn->debug) { trlmessage ("GetAsnTable: Info from ASN read into memory."); } /* Successful return */ return (status); }
int updateAsnTable (AsnInfo *asn, int prodid, int posid) { /* Arguments: ** asn i: association info structure ** prodid i: product id for member that needs to be updated ** posid i: position id for member that needs to be updated */ extern int status; /* Local variables */ int col; /* loop index */ IRAFPointer asn_tp; /* table pointers */ IRAFPointer colptr[NCOLS]; /* ASN table column pointers */ Bool prsnt; /* ASNTAB column names */ char colname[NCOLS][SZ_COLNAME+1] = { "MEMNAME", "MEMTYPE", "MEMPRSNT" }; /* Initialize the table column pointers */ for (col = 0; col < NCOLS; col++) colptr[col] = 0; /* Open the ASN table */ asn_tp = c_tbtopn (asn->asn_table, IRAF_READ_WRITE, 0); if (c_iraferr()) { trlopenerr (asn->asn_table); return (status = TABLE_ERROR); } /* Find the columns in the ASN table */ for (col=0; col < NCOLS; col++) { if (colptr[col] == 0) { c_tbcfnd1 (asn_tp, colname[col], &(colptr[col])); if (c_iraferr() || colptr[col] == 0) { sprintf (MsgText, "Can't find column %s in %s", colname[col], asn->asn_table); trlerror (MsgText); c_tbtclo (asn_tp); return (status = 1); } } } /* Value MEMPRSNT will be updated to... */ prsnt = True; /* Are we working with a Product or a subproduct... */ if (posid == 0) { /* Write the updated info for PRODUCT to the ASN table */ c_tbeptb (asn_tp, colptr[2], asn->product[prodid].asnrow, prsnt); } else { /* Write the updated info for SUB-PRODUCT to the ASN table */ c_tbeptb (asn_tp, colptr[2], asn->product[prodid].subprod[posid].asnrow, prsnt); } /* Close the ASN table */ c_tbtclo (asn_tp); /* Update ASN_PROD keyword to TRUE to signal successful ** creation of product/sub-product. */ if (UpdateHdr (asn->asn_table) ) { trlerror ("Couldn't update ASN table header"); return(status = KEYWORD_MISSING); } /* Successful return */ return (status); }