/*************************************************************************\ * Read in truncation parameters from an input file or the command line. * * * * The light profile fitpar structure of each object stores two indices: * * fpar->inner[] and fpar->outer[]. The values inside the arrays * * correspond to the component number that truncates the light profile. * * For instance, if a light profile is being truncated on the inside * * by a radial truncation of component 7, then the light profile fitpars * * structure will have an entry where: fpar->inner[1] = 7 * * This is is useful because edge-on disks can have 2 inner and 2 outer * * truncations, so fpar->inner[1], fpar->inner[2], fpar->outer[1], and * * fpar->outer[2] will point to the truncation function components. * * * \*************************************************************************/ #include #include #include #include #include #include "structs.h" #define STRLEN 1000 void upcase (char *com); void read_trunc_pars (char *string, struct fitpars *fpar) { int ncomp; char tok[10], *com; char *p; com = strtok (string, " #\t"); upcase (com); /*******************************************************************\ * Extract the component numbers and store them in fpar->inner * * and fpar->outer. The first element of each is the number of * * of components that are involved. * \*******************************************************************/ if (strncmp (com, "TO", 2) == 0) { ncomp = 0; fpar->outer = (int *) calloc (OFFSET, sizeof(fpar->outer)); while ((p = strtok (NULL, " \t")) != NULL && p[0] != '#' && p[0] != '0' ) { ncomp++; fpar->outer = (int *) realloc (fpar->outer, (size_t)(sizeof (int) * (ncomp + OFFSET))); fpar->outer[ncomp] = atoi (p); }; fpar->outer[0] = ncomp; }; if (strncmp (com, "TI", 2) == 0) { ncomp = 0; fpar->inner = (int *) calloc (OFFSET, sizeof(fpar->inner)); while ((p = strtok (NULL, " \t")) != NULL && p[0] != '#' && p[0] != '0') { ncomp++; fpar->inner = (int *) realloc (fpar->inner, (size_t)(sizeof (int) * (ncomp + OFFSET))); fpar->inner[ncomp] = atoi (p); }; fpar->inner[0] = ncomp; }; } /****************************************************************************/ int assoc_trunc_comps (struct fitpars *fpar) { int check_err_assoc (struct fitpars *fpar); int istrunc (char *objtype); struct fitpars *trptr, *objptr; int comp, i, err = 0; objptr = trptr = fpar; err = check_err_assoc (fpar); while (trptr != NULL) { if (istrunc (trptr->objtype)) { objptr = fpar; trptr->outer = (int *) calloc (OFFSET, (size_t)(sizeof(trptr->outer))); trptr->outer[0] = 0; trptr->inner = (int *) calloc (OFFSET, (size_t)(sizeof(trptr->inner))); trptr->inner[0] = 0; /*-------------------------------------------------------\ | Cycle through object list to see if it is truncated | | by the right truncation component. | \-------------------------------------------------------*/ while (objptr != NULL) { if (!istrunc (objptr->objtype)) { /*-------------------\ | Outer truncation | \-------------------*/ if (objptr->outer != NULL) { for (i=1; i <= objptr->outer[0]; i++) { if (objptr->outer[i] == trptr->compnum) { trptr->outer[0] = trptr->outer[0] + 1; comp = trptr->outer[0]; trptr->outer = (int *) realloc (trptr->outer, (size_t)(sizeof (int) * (comp + OFFSET))); trptr->outer[comp] = objptr->compnum; }; }; }; /*-------------------\ | Inner truncation | \-------------------*/ if (objptr->inner != NULL) { for (i=1; i <= objptr->inner[0]; i++) { if (objptr->inner[i] == trptr->compnum) { trptr->inner[0] = trptr->inner[0] + 1; comp = trptr->inner[0]; trptr->inner = (int *) realloc (trptr->inner, (size_t)(sizeof (int) * (comp + OFFSET))); trptr->inner[comp] = objptr->compnum; }; }; }; }; objptr = objptr->next; }; }; trptr = trptr->next; }; return (err); } /*===========================================================================*\ * Check for errors in the truncation association, i.e. make sure that the * * component pointed to is actually a truncation function rather than * * another light profile, which would cause a very subtle error to occur. * \*===========================================================================*/ int check_err_assoc (struct fitpars *fpar) { int istrunc (char *objtype); struct fitpars *ptr1, *ptr2; int i, err = 0, comp = 0; ptr1 = fpar; while (ptr1 != NULL && err == 0) { comp++; if (ptr1->inner != NULL && !istrunc (ptr1->objtype)) { ptr2 = fpar; for (i=1; i <= ptr1->inner[1] - 1; i++) { if (ptr2->next != NULL) ptr2 = ptr2->next; }; if (!istrunc (ptr2->objtype)) err = comp; }; if (ptr1->outer != NULL && !istrunc(ptr1->objtype)) { ptr2 = fpar; for (i=1; i <= ptr1->outer[1] - 1; i++) { if (ptr2->next != NULL) ptr2 = ptr2->next; }; if (!istrunc(ptr2->objtype)) err = comp; }; ptr1 = ptr1->next; }; return (err); } /*===========================================================================*\ * Add the symbols "\" and/or "/" to the end of the object name to designate * * it as a truncated profile. * \*===========================================================================*/ void check_trunc (struct fitpars *fpar) { struct fitpars *hptr, *fptr; char *cptr; int i; while (fpar != NULL) { /*-------------------------------------------------------------\ | Define normalization type (see structs.h for explanation). | \-------------------------------------------------------------*/ if (index (fpar->objtype, '1') != NULL) fpar->normtype = 1; else if (index (fpar->objtype, '2') != NULL) fpar->normtype = 2; else if (index (fpar->objtype, '3') != NULL) fpar->normtype = 3; else fpar->normtype = 0; /*-------------------------------------------------------------\ | Now tag the object name with / or \ depending on what type | | of truncation is being performed on this object. | \-------------------------------------------------------------*/ if (fpar->normtype == 0) { cptr = strchr (fpar->objtype, ' '); if (fpar->inner != NULL) { fpar->normtype = 3; /* Normalized at the break radius. */ sprintf (cptr, "%i", 3); sprintf (fpar->objtype, "%s ", fpar->objtype); } else if (fpar->outer) { fpar->normtype = 1; /* Normalized at the central peak */ sprintf (cptr, "%i", 1); sprintf (fpar->objtype, "%s ", fpar->objtype); }; }; cptr = strchr (fpar->objtype, ' '); cptr++; if (fpar->inner != NULL) { for (i=1; i<= fpar->inner[0]; i++) { sprintf (cptr, "/"); cptr++; }; }; if (fpar->outer != NULL) { for (i=1; i<= fpar->outer[0]; i++) { sprintf (cptr, "\\"); cptr++; }; }; /*-------------------------------------------------------------\ | If the user specifies for total magnitude but the profile | | is being truncated, change the normalization to something | | else, because galfit can't do total magnitude for | | trucated profiles easily. | \-------------------------------------------------------------*/ fpar = fpar->next; }; } /*=========================================================================*\ * Check to see if the object type is a truncation function * \*=========================================================================*/ int istrunc (char *objtype) { if (strncmp (objtype, "radial", 6) == 0 || strncmp (objtype, "length", 6) == 0 || strncmp (objtype, "height", 6) == 0) return (1); else return (0); }