示例#1
0
文件: test_thr.c 项目: dlbeer/libdlb
int main(void)
{
	int my_count = 5;

	thr_mutex_init(&mutex);
	if (thr_event_init(&event) < 0) {
		report_syserr("thr_event_init");
		return -1;
	}

	thr_start(&worker, work_func, NULL);
	while (my_count) {
		thr_mutex_lock(&mutex);
		counter++;
		my_count--;
		printf("producer: counter++\n");
		thr_mutex_unlock(&mutex);
		thr_event_raise(&event);
		clock_wait(10);
	}
	thr_join(worker);

	test_timedwait();

	thr_event_destroy(&event);
	thr_mutex_destroy(&mutex);
	return 0;
}
示例#2
0
static int is_zip_file (char *filename, char *errstr) {
  FILE *fp;
  char buf[NMAGIC];
  int nread, rv;

  fp = fopen(filename, "rb");
  if(!fp) {
    report_syserr(errstr, "open: %s", filename);
    goto error;
  }

  /* Somewhat simplified method for detection of a zip file.  This tests
     for the signatures:
     PK\x03\x04  local file header (normal file)
     PK\x05\x06  end of central directory (empty file)
     PK\x07\x08  multi-volume archive
     which should cover most normal zip files, but strictly speaking we
     should detect zip format by seeking to end of file and backing up
     looking for the end of central directory record. */
  nread = fread(buf, 1, NMAGIC, fp);

  if(nread == NMAGIC &&
     (buf[0] == 'P' && buf[1] == 'K' &&
      ((buf[2] == '\x03' && buf[3] == '\x04') ||
       (buf[2] == '\x05' && buf[3] == '\x06') ||
       (buf[2] == '\x07' && buf[3] == '\x08'))))
    rv = 1;
  else if(ferror(fp))
    goto error;
  else
    rv = 0;

  fclose(fp);

  return(rv);

 error:

  return(-1);
}
示例#3
0
文件: parms.c 项目: mdwarfgeek/eb
int make_parms (struct fit_parms *par, FILE *ofp,
                struct fit_data *dlist, int ndata,
                int ldtype[2],
                double *vfix, int *varyfix, double *vsgfix,
                struct fit_pset_entry *pextra, int npextra,
                char *errstr) {

  double *v = (double *) NULL, *voff, *vscl, *vsg, *vtmp;
  double *vcov = (double *) NULL;
  int *vary = (int *) NULL;
  char **vnames = (char **) NULL, **vunits, **vtexsym;
  char *vnamesbuf = (char *) NULL, *vunitsbuf, *vtexsymbuf;
  int nparm;

  double hjdoff;

  int iaddband, naddband, nband;
  int *pj = (int *) NULL, *pldlin1, *pldlin2, *pldnon1, *pldnon2;
  int *pgenairm = (int *) NULL, *pgencm;

  int ipextra, ifound;

  int idat, meas, nmeastot, iseg;

  int iparm, jparm, nvaryf, nvarym;
  double nvaryflc, nvaryfrv;

  int ntmp;

  /* Init flags and compute median of input data */
  nmeastot = 0;

  for(idat = 0; idat < ndata; idat++) {
    /* Allocate buffer */
    dlist[idat].phitmp = (float *) malloc(2*dlist[idat].nmeas * sizeof(float));
    dlist[idat].resid = (double *) malloc(3*dlist[idat].nmeas * sizeof(double));
    dlist[idat].iflag
      = (unsigned char *) malloc(2*dlist[idat].nmeas * sizeof(unsigned char));

    if(!dlist[idat].phitmp || !dlist[idat].resid || !dlist[idat].iflag) {
      report_syserr(errstr, "malloc");
      goto error;
    }

    dlist[idat].ytmp = dlist[idat].phitmp + dlist[idat].nmeas;

    dlist[idat].m = dlist[idat].resid + dlist[idat].nmeas;
    dlist[idat].corr = dlist[idat].resid + 2*dlist[idat].nmeas;

    dlist[idat].iecl = dlist[idat].iflag + dlist[idat].nmeas;

    ntmp = 0;
    for(meas = 0; meas < dlist[idat].nmeas; meas++) {
      if(dlist[idat].yerr[meas] <= 0 &&
	 !(dlist[idat].obstype == OBS_RV && dlist[idat].fiterr))
	dlist[idat].iflag[meas] = 0;
      else
	dlist[idat].iflag[meas] = 1;
      
      dlist[idat].m[ntmp] = dlist[idat].y[meas];
      ntmp++;
    }

    dmedsig(dlist[idat].m, ntmp, &(dlist[idat].ymed), &(dlist[idat].ysig));

    tprintf(ofp, "Median %d: %.3f +/- %.3f\n",
            idat+1, dlist[idat].ymed, dlist[idat].ysig);

    nmeastot += dlist[idat].nmeas;
  }

  /* Subtract off T_0 initial guess to improve stability */
  hjdoff = vfix[EB_PAR_T0];  /* ref = first observation */

  vfix[EB_PAR_T0] -= hjdoff;
  for(idat = 0; idat < ndata; idat++)
    for(meas = 0; meas < dlist[idat].nmeas; meas++)
      if(dlist[idat].obstype != OBS_PRIOR)
	dlist[idat].hjd[meas] -= hjdoff;

  tprintf(ofp, "Subtracted HJD=%f\n", hjdoff);

  /* Count bands */
  naddband = 0;

  for(idat = 0; idat < ndata; idat++)
    if(dlist[idat].obstype == OBS_LC)
      naddband = MAX(dlist[idat].iband, naddband);

  nband = naddband+1;

  /* Figure out how many parameters there are */
  nparm = NPARFIX + 5*naddband;

  for(idat = 0; idat < ndata; idat++) {
    if(dlist[idat].obstype == OBS_LC) {
      if(dlist[idat].nseg > 0)
        nparm += dlist[idat].nseg;  /* zpt per segment */
      else
        nparm++;  /* for zpt */

      if(dlist[idat].fiterr)
	nparm++;

      if(dlist[idat].fitairm > 0)
	nparm++;

      if(dlist[idat].fitcm > 0)
	nparm++;
    }
    else if(dlist[idat].obstype == OBS_RV) {
      if(dlist[idat].fiterr)
	nparm++;
    }
  }

  /* Allocate master parameter vectors */
  v = (double *) malloc(5 * nparm * sizeof(double));
  vcov = (double *) malloc(nparm*nparm * sizeof(double));
  vary = (int *) malloc(nparm * sizeof(int));
  vnames = (char **) malloc(3 * nparm * sizeof(char *));
  vnamesbuf = (char *) malloc(3 * nparm * PARNAME_MAX * sizeof(char));
  pj = (int *) malloc(5 * naddband * sizeof(int));
  pgenairm = (int *) malloc(2 * nband * sizeof(int));
  if(!v || !vcov || !vary || !vnames || !vnamesbuf || !pj) {
    report_syserr(errstr, "malloc");
    goto error;
  }

  voff = v + nparm;
  vscl = v + 2*nparm;
  vsg  = v + 3*nparm;
  vtmp = v + 4*nparm;

  vunits = vnames + nparm;
  vunitsbuf = vnamesbuf + nparm * PARNAME_MAX;

  vtexsym = vnames + 2*nparm;
  vtexsymbuf = vnamesbuf + 2*nparm * PARNAME_MAX;

  pldlin1 = pj + naddband;
  pldlin2 = pj + 2*naddband;
  pldnon1 = pj + 3*naddband;
  pldnon2 = pj + 4*naddband;

  pgencm = pgenairm + nband;

  for(iparm = 0; iparm < nparm; iparm++) {
    vnames[iparm] = vnamesbuf + iparm * PARNAME_MAX;
    vunits[iparm] = vunitsbuf + iparm * PARNAME_MAX;
    vtexsym[iparm] = vtexsymbuf + iparm * PARNAME_MAX;
  }

  /* Pack master parameter vectors */
  for(iparm = 0; iparm < NPARFIX; iparm++) {
    v[iparm] = vfix[iparm];
    vary[iparm] = varyfix[iparm];
    strncpy(vnames[iparm], parnames[iparm], PARNAME_MAX);
    strncpy(vunits[iparm], parunits[iparm], PARNAME_MAX);
    strncpy(vtexsym[iparm], partexsym[iparm], PARNAME_MAX);

    vscl[iparm] = 1.0;
    voff[iparm] = 0;
    vsg[iparm] = vsgfix[iparm];
  }

  for(iaddband = 0; iaddband < naddband; iaddband++) {
    v[iparm] = vfix[EB_PAR_J];
    vary[iparm] = varyfix[EB_PAR_J];
    snprintf(vnames[iparm], PARNAME_MAX, "J_%d", iaddband+1);
    strncpy(vunits[iparm], parunits[EB_PAR_J], PARNAME_MAX);
    snprintf(vtexsym[iparm], PARNAME_MAX, "J_{%d}", iaddband+1);

    vscl[iparm] = 1.0;
    voff[iparm] = 0;
    vsg[iparm] = vsgfix[EB_PAR_J];

    pj[iaddband] = iparm;
    iparm++;

    v[iparm] = vfix[EB_PAR_LDLIN1];
    vary[iparm] = varyfix[EB_PAR_LDLIN1];
    snprintf(vnames[iparm], PARNAME_MAX, "mu_1_f%d", iaddband+1);
    strncpy(vunits[iparm], parunits[EB_PAR_LDLIN1], PARNAME_MAX);
    snprintf(vtexsym[iparm], PARNAME_MAX, "u_1_{{\\rm f}%d}", iaddband+1);

    vscl[iparm] = 1.0;
    voff[iparm] = 0;
    vsg[iparm] = vsgfix[EB_PAR_LDLIN1];

    pldlin1[iaddband] = iparm;
    iparm++;

    v[iparm] = vfix[EB_PAR_LDLIN2];
    vary[iparm] = varyfix[EB_PAR_LDLIN2];
    snprintf(vnames[iparm], PARNAME_MAX, "mu_2_f%d", iaddband+1);
    strncpy(vunits[iparm], parunits[EB_PAR_LDLIN2], PARNAME_MAX);
    snprintf(vtexsym[iparm], PARNAME_MAX, "u_2_{{\\rm f}%d}", iaddband+1);

    vscl[iparm] = 1.0;
    voff[iparm] = 0;
    vsg[iparm] = vsgfix[EB_PAR_LDLIN2];

    pldlin2[iaddband] = iparm;
    iparm++;

    v[iparm] = vfix[EB_PAR_LDNON1];
    vary[iparm] = varyfix[EB_PAR_LDNON1];
    snprintf(vnames[iparm], PARNAME_MAX, "mup_1_f%d", iaddband+1);
    strncpy(vunits[iparm], parunits[EB_PAR_LDNON1], PARNAME_MAX);
    snprintf(vtexsym[iparm], PARNAME_MAX, "u'_1_{{\\rm f}%d}", iaddband+1);

    vscl[iparm] = 1.0;
    voff[iparm] = 0;
    vsg[iparm] = vsgfix[EB_PAR_LDNON1];

    pldnon1[iaddband] = iparm;
    iparm++;

    v[iparm] = vfix[EB_PAR_LDNON2];
    vary[iparm] = varyfix[EB_PAR_LDNON2];
    snprintf(vnames[iparm], PARNAME_MAX, "mup_2_f%d", iaddband+1);
    strncpy(vunits[iparm], parunits[EB_PAR_LDNON2], PARNAME_MAX);
    snprintf(vtexsym[iparm], PARNAME_MAX, "u'_2_{{\\rm f}%d}", iaddband+1);

    vscl[iparm] = 1.0;
    voff[iparm] = 0;
    vsg[iparm] = vsgfix[EB_PAR_LDNON2];

    pldnon2[iaddband] = iparm;
    iparm++;
  }

  for(idat = 0; idat < ndata; idat++) {
    if(dlist[idat].obstype == OBS_LC) {
      dlist[idat].pnorm = iparm;  /* record this now */

      if(dlist[idat].nseg > 0) {
        for(iseg = 0; iseg < dlist[idat].nseg; iseg++) {
          v[iparm] = 1.0e-3;
          vary[iparm] = 1;
          snprintf(vnames[iparm], PARNAME_MAX, "z_%d_%d", idat+1, iseg+1);
          strncpy(vunits[iparm], "mag", PARNAME_MAX);
          snprintf(vtexsym[iparm], PARNAME_MAX, "z_{%d,%d}", idat+1, iseg+1);
          
          vscl[iparm] = 1.0;
          voff[iparm] = 0;
          vsg[iparm] = 1.0e-3;
          
          iparm++;
        }
      }
      else {
        v[iparm] = 1.0e-3;
        vary[iparm] = 1;
        snprintf(vnames[iparm], PARNAME_MAX, "z_%d", idat+1);
        strncpy(vunits[iparm], "mag", PARNAME_MAX);
        snprintf(vtexsym[iparm], PARNAME_MAX, "z_{%d}", idat+1);        
        
        vscl[iparm] = 1.0;
        voff[iparm] = 0;
        vsg[iparm] = 1.0e-3;
        
        iparm++;
      }      

      if(dlist[idat].fiterr) {
	v[iparm] = 1.0;  /* scale factor for LCs */
	vary[iparm] = 2;
	snprintf(vnames[iparm], PARNAME_MAX, "s_%d", idat+1);
	strncpy(vunits[iparm], "", PARNAME_MAX);
	snprintf(vtexsym[iparm], PARNAME_MAX, "s_{%d}", idat+1);

	vscl[iparm] = 1.0;
	voff[iparm] = 0;
	vsg[iparm] = 1.0e-2;

	dlist[idat].perrsc = iparm;
	iparm++;
      }
      if(dlist[idat].fitairm > 0) {
	v[iparm] = 0.001;
	vary[iparm] = 1;
	snprintf(vnames[iparm], PARNAME_MAX, "k_%d", idat+1);
	strncpy(vunits[iparm], "mag/airmass", PARNAME_MAX);
	snprintf(vtexsym[iparm], PARNAME_MAX, "k_{%d}", idat+1);

	vscl[iparm] = 1.0;
	voff[iparm] = 0;
	vsg[iparm] = 1.0e-3;

	dlist[idat].pairm = iparm;
	pgenairm[dlist[idat].iband] = iparm;

	iparm++;
      }
      else if(dlist[idat].fitairm < 0) {
	/* Use generic one in same filter */
	dlist[idat].pairm = pgenairm[dlist[idat].iband];
      }
      if(dlist[idat].fitcm > 0) {
	v[iparm] = 1.0;
	vary[iparm] = 1;
	snprintf(vnames[iparm], PARNAME_MAX, "c_%d", idat+1);
	strncpy(vunits[iparm], "", PARNAME_MAX);
	snprintf(vtexsym[iparm], PARNAME_MAX, "c_{%d}", idat+1);

	vscl[iparm] = 1.0;
	voff[iparm] = 0;
	vsg[iparm] = 1.0e-2;

	dlist[idat].pcm = iparm;
	pgencm[dlist[idat].iband] = iparm;

	iparm++;
      }
      else if(dlist[idat].fitcm < 0) {
	/* Use generic one in same filter */
	dlist[idat].pcm = pgencm[dlist[idat].iband];
      }
    }
    else if(dlist[idat].obstype == OBS_RV) {
      if(dlist[idat].fiterr) {
	v[iparm] = dlist[idat].errguess;  /* quadrature for RVs */
	vary[iparm] = 2;
	snprintf(vnames[iparm], PARNAME_MAX, "s_%d", idat+1);
	strncpy(vunits[iparm], "km/s", PARNAME_MAX);
	snprintf(vtexsym[iparm], PARNAME_MAX, "s_{%d}", idat+1);

	vscl[iparm] = 1.0;
	voff[iparm] = 0;
	vsg[iparm] = 1.0e-1;

	dlist[idat].perrsc = iparm;
	iparm++;
      }
    }
  }

  /* Update initial values etc for non-fixed parameter set
     (e.g. extra filters) */
  for(ipextra = 0; ipextra < npextra; ipextra++) {
    /* Lookup name */
    ifound = -1;
    for(iparm = 0; iparm < nparm; iparm++)
      if(!strcmp(pextra[ipextra].name, vnames[iparm])) {
	ifound = iparm;
	break;
      }

    if(ifound >= 0) {
      if(ifound == EB_PAR_COSI)
	v[ifound] = cos(pextra[ipextra].v * M_PI / 180.0);
      else
	v[ifound] = pextra[ipextra].v;
 
      vary[ifound] = pextra[ipextra].vary;
	  
      if(pextra[ipextra].havesig)
	vsgfix[ifound] = pextra[ipextra].sig;
    }
  }

  /* Check for LD2 = LD1 case; disable varying LD2 if it's on */
  if(ldtype[1] == LD_SAME) {
    v[EB_PAR_LDLIN2] = v[EB_PAR_LDLIN1];
    v[EB_PAR_LDNON2] = v[EB_PAR_LDNON1];
    vary[EB_PAR_LDLIN2] = 0;
    vary[EB_PAR_LDNON2] = 0;
    
    for(iaddband = 0; iaddband < naddband; iaddband++) {
      v[pldlin2[iaddband]] = v[pldlin1[iaddband]];
      v[pldnon2[iaddband]] = v[pldnon1[iaddband]];
      vary[pldlin2[iaddband]] = 0;
      vary[pldnon2[iaddband]] = 0;
    }
  }

  /* Figure out how many parameters we are varying */
  for(iparm = 0, nvaryf = 0, nvaryflc = 0, nvarym = 0; iparm < nparm; iparm++)
    switch(vary[iparm]) {
    case 1:
      nvaryf++;
      nvaryflc++;
    case 2:
      nvarym++;
      break;
    }

  nvaryflc++;  /* for normalization etc. */

  nvaryfrv = 0;
  if(vary[EB_PAR_Q] == 1)
    nvaryfrv++;
  if(vary[EB_PAR_ESINW] == 1)
    nvaryfrv += 0.5;        /* well, sort of */
  if(vary[PAR_KTOT] == 1)
    nvaryfrv++;
  if(vary[PAR_GAMMA] == 1)
    nvaryfrv++;

  nvaryflc -= nvaryfrv;

  /* Initial guess at covariance matrix: diagonal */
  for(iparm = 0; iparm < nparm; iparm++) {
    for(jparm = 0; jparm < iparm; jparm++)
      vcov[iparm*nparm+jparm] = 0;

    vcov[iparm*nparm+iparm] = vsg[iparm]*vsg[iparm];

    for(jparm = iparm+1; jparm < nparm; jparm++)
      vcov[iparm*nparm+jparm] = 0;
  }

  /* Fill in structure */
  par->dlist = dlist;
  par->ndata = ndata;
  par->nmeastot = nmeastot;

  par->vinit = v;
  par->voff = voff;
  par->vscl = vscl;
  par->vsg = vsg;
  par->vtmp = vtmp;
  par->vcov = vcov;
  par->nparm = nparm;

  par->vary = vary;
  par->nvaryflc = nvaryflc;
  par->nvaryfrv = nvaryfrv;
  par->nvaryf = nvaryf;
  par->nvarym = nvarym;

  par->vnames = vnames;
  par->vunits = vunits;
  par->vtexsym = vtexsym;

  par->ldtype = ldtype;

  par->hjdoff = hjdoff;

  par->nband = nband;
  par->naddband = naddband;

  par->pj = pj;
  par->pldlin1 = pldlin1;
  par->pldlin2 = pldlin2;
  par->pldnon1 = pldnon1;
  par->pldnon2 = pldnon2;

  return(0);

 error:

  return(-1);
}
示例#4
0
int lightcurves_append (struct buffer_info *buf, struct lc_mef *mefinfo,
			int noastrom, char *errstr) {
  struct lc_point *ptbuf = (struct lc_point *) NULL;
  float *medbuf = (float *) NULL;
  long nmedbuf;

  long star, meas, meas1, meas2, pt;

  int iseg, found, imr;

  /* Decide segments for all new points */
  for(pt = 0; pt < mefinfo->nf; pt++) {
    /* Have we seen this segment before? */
    found = -1;
    imr = mefinfo->nseg-1;
    for(iseg = 0; iseg < mefinfo->nseg; iseg++) {
      /* This test is a bit complicated.  The first part handles version
       * numbers, including a NULL = NULL comparison and then the numeric
       * comparison if not null.
       * The second bit handles meridian sides if that is enabled.
       */
      if(((!mefinfo->frames[pt].instvers && !mefinfo->segs[iseg].instvers) ||
	  (mefinfo->frames[pt].instvers && mefinfo->segs[iseg].instvers &&
	   mefinfo->frames[pt].instvers->iver == mefinfo->segs[iseg].instvers->iver)) &&
	 (!mefinfo->domerid || (mefinfo->frames[pt].iang == mefinfo->segs[iseg].iang)))
	found = iseg;

      /* Accumulate most recent on correct meridian side */
      if(!mefinfo->domerid || (mefinfo->frames[pt].iang == mefinfo->segs[iseg].iang))
	imr = iseg;
    }

    if(found < 0)
      found = imr;  /* assume most recent */

    mefinfo->frames[pt].iseg = found;
  }

  /* Allocate temporary workspace for calculating medians */
  nmedbuf = MAX(mefinfo->nf, mefinfo->nstars);

  ptbuf = (struct lc_point *) malloc(nmedbuf * sizeof(struct lc_point));
  medbuf = (float *) malloc(nmedbuf * sizeof(float));
  if(!ptbuf || !medbuf) {
    report_syserr(errstr, "malloc");
    goto error;
  }

  meas1 = (mefinfo->aperture ? mefinfo->aperture-1 : 0);
  meas2 = (mefinfo->aperture ? mefinfo->aperture : NFLUX);

  /* Apply polynomial correction if requested */
  if(mefinfo->degree >= 0) {
    if(verbose)
      printf(" Computing frame corrections\n");
    
    /* Compute 2-D correction for each frame */
    for(pt = 0; pt < mefinfo->nf; pt++) {
      /* Read in measurements for this frame */
      if(buffer_fetch_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
	goto error;
	
      for(meas = meas1; meas < meas2; meas++) {
	/* Apply any meridian flip offsets */
	if(mefinfo->domerid > 1) 
	  for(star = 0; star < mefinfo->nstars; star++) 
	    if(ptbuf[star].aper[meas].flux != 0.0)
	      ptbuf[star].aper[meas].flux -= mefinfo->stars[star].segs[mefinfo->frames[pt].iseg].corr[meas];

	/* Perform polynomial fit correction */
	if(systematic_fit(ptbuf, mefinfo, pt, meas, medbuf, mefinfo->degree,
			  &(mefinfo->frames[pt].sys[meas]), errstr))
	  goto error;
	
	/* Trap for no points in fit - discard in this case */
	if(mefinfo->frames[pt].sys[meas].npt > 0) {
	  /* Store frame RMS for normal aperture (meas = 0) */
	  if(meas == meas1) {
	    mefinfo->frames[pt].offset = mefinfo->frames[pt].sys[meas].medoff;
	    mefinfo->frames[pt].rms = mefinfo->frames[pt].sys[meas].sigoff;
	    mefinfo->frames[pt].extinc = mefinfo->frames[pt].sys[meas].coeff[0];
	    mefinfo->frames[pt].sigm = sqrtf(mefinfo->frames[pt].sys[meas].cov[0]);
	  }
	  
	  /* Perform polynomial fit correction */
	  if(systematic_apply_frame(ptbuf, mefinfo, pt, meas, errstr))
	    goto error;
	}
      }
      
      /* Write out corrected fluxes */
      if(buffer_put_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
	goto error;
    }
  }

#ifndef NOXY
  if(!noastrom) {
    if(verbose)
      printf(" Recomputing astrometric transformations\n");
    
    /* Compute positioning error for each frame */
    for(pt = 0; pt < mefinfo->nf; pt++) {
      /* Read in measurements for this frame */
      if(buffer_fetch_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
	goto error;
      
      /* Compute transformation to ref. system */
      if(xytoxy(ptbuf, mefinfo, mefinfo->frames[pt].tr, errstr))
	goto error;
    }
  }
#endif

  /* Free workspace */
  free((void *) ptbuf);
  ptbuf = (struct lc_point *) NULL;
  free((void *) medbuf);
  medbuf = (float *) NULL;

  return(0);

 error:
  if(ptbuf)
    free((void *) ptbuf);
  if(medbuf)
    free((void *) medbuf);

  return(1);
}
示例#5
0
int lightcurves (struct buffer_info *buf, struct lc_mef *mefinfo,
		 int norenorm, int noastrom, int niter, char *errstr) {
  struct lc_point *ptbuf = (struct lc_point *) NULL;
  float *medbuf1 = (float *) NULL;
#ifndef NOXY
  float *medbuf2;
#endif
  long nmedbuf;

  int iter, degree, doall;

  long star, meas, meas1, meas2, pt, opt1;
  int used;

  float medflux, sigflux;

  float medoff[NFLUX], sigoff[NFLUX];

  int iseg, found, haveref;
  float medref, corr;

  float *medsegbuf = (float *) NULL;
  float **medseg = (float **) NULL;
  int *nmedseg = (int *) NULL;

  /* Decide how many segments and allocate them */
  mefinfo->segs = (struct lc_segment *) NULL;
  mefinfo->nseg = 0;

  for(pt = 0; pt < mefinfo->nf; pt++) {
    /* Have we seen this segment before? */
    found = -1;
    for(iseg = 0; iseg < mefinfo->nseg; iseg++)
      /* This test is a bit complicated.  The first part handles version
       * numbers, including a NULL = NULL comparison and then the numeric
       * comparison if not null.
       * The second bit handles meridian sides if that is enabled.
       */
      if(((!mefinfo->frames[pt].instvers && !mefinfo->segs[iseg].instvers) ||
	  (mefinfo->frames[pt].instvers && mefinfo->segs[iseg].instvers &&
	   mefinfo->frames[pt].instvers->iver == mefinfo->segs[iseg].instvers->iver)) &&
	 (!mefinfo->domerid || (mefinfo->frames[pt].iang == mefinfo->segs[iseg].iang)))
	found = iseg;

    if(found < 0) {
      /* Add a new one */
      mefinfo->nseg++;
      mefinfo->segs = (struct lc_segment *) realloc(mefinfo->segs,
						    mefinfo->nseg * sizeof(struct lc_segment));
      if(!mefinfo->segs) {
	report_syserr(errstr, "realloc");
	goto error;
      }

      mefinfo->segs[mefinfo->nseg-1].instvers = mefinfo->frames[pt].instvers;
      mefinfo->segs[mefinfo->nseg-1].iang = mefinfo->frames[pt].iang;

      mefinfo->frames[pt].iseg = mefinfo->nseg-1;
    }
    else
      mefinfo->frames[pt].iseg = found;
  }

  for(star = 0; star < mefinfo->nstars; star++) {
    mefinfo->stars[star].segs = (struct lc_star_segment *) malloc(mefinfo->nseg * sizeof(struct lc_star_segment));
    if(!mefinfo->stars[star].segs) {
      report_syserr(errstr, "malloc");
      goto error;
    }

    /* Initialize correction to zero */
    for(iseg = 0; iseg < mefinfo->nseg; iseg++)
      for(meas = 0; meas < NFLUX; meas++)
	mefinfo->stars[star].segs[iseg].corr[meas] = 0;
  }

  /* Allocate temporary workspace for corrections */
  medsegbuf = (float *) malloc(mefinfo->nseg*mefinfo->nf * sizeof(float));
  medseg = (float **) malloc(mefinfo->nseg * sizeof(float *));
  nmedseg = (int *) malloc(mefinfo->nseg * sizeof(int));
  if(!medsegbuf || !medseg || !nmedseg) {
    report_syserr(errstr, "malloc");
    goto error;
  }

  for(iseg = 0; iseg < mefinfo->nseg; iseg++)
    medseg[iseg] = medsegbuf + iseg * mefinfo->nf;

  /* Allocate temporary workspace for calculating medians */
  nmedbuf = MAX(mefinfo->nf, mefinfo->nstars);

  ptbuf = (struct lc_point *) malloc(nmedbuf * sizeof(struct lc_point));
  medbuf1 = (float *) malloc(2 * nmedbuf * sizeof(float));
  if(!ptbuf || !medbuf1) {
    report_syserr(errstr, "malloc");
    goto error;
  }

#ifndef NOXY
  medbuf2 = medbuf1 + nmedbuf;
#endif

  meas1 = (mefinfo->aperture ? mefinfo->aperture-1 : 0);
  meas2 = (mefinfo->aperture ? mefinfo->aperture : NFLUX);

  /* Apply polynomial correction if requested */
  if(mefinfo->degree >= 0) {
    /* Iterate between computing object median and rms, and
     * successive frame corrections.  The polynomial fit
     * (if any) is only done on the last iteration, using
     * a simple constant for the others, so we don't
     * disappear up our own exhaust pipe.
     *
     * The purpose of the earlier iterations is to refine
     * the rms estimate used for weighting in the least
     * squares analysis, so that it reflects the actual
     * error in that object and not the frame-to-frame
     * offsets (which are the dominant effect otherwise
     * on data taken in non-photometric conditions).
     */
    for(iter = 0; iter < niter; iter++) {
      degree = (iter == niter-1 ? mefinfo->degree : 0);
      doall = (iter == niter-1 ? 1 : 0);

      if(verbose && isatty(1))
        printf("\r Processing iteration %d of %d",
               iter+1, niter);

      /* Compute per-object, per-segment median flux */
      for(star = 0; star < mefinfo->nstars; star++) {
        /* Do everything on the last iteration, otherwise only
           objects that can be comparison stars. */
        if(doall || mefinfo->stars[star].compok) {
          /* Read in measurements for this star */
          if(buffer_fetch_object(buf, ptbuf, 0, mefinfo->nf, star, errstr))
            goto error;
          
          for(meas = meas1; meas < meas2; meas++) {
            /* Apply last set of frame corrections */
            if(systematic_apply_star(ptbuf, mefinfo, star, meas, errstr))
              goto error;

            if(mefinfo->nseg > 1) {
              /* Compute segment medians */
              for(iseg = 0; iseg < mefinfo->nseg; iseg++)
                nmedseg[iseg] = 0;
              
              for(pt = 0; pt < mefinfo->nf; pt++)
                if(ptbuf[pt].aper[meas].flux != 0.0) {
                  iseg = mefinfo->frames[pt].iseg;
                  
                  *(medseg[iseg] + nmedseg[iseg]) = ptbuf[pt].aper[meas].flux;
                  nmedseg[iseg]++;
                }
              
              medref = 0;
              haveref = 0;
              
              for(iseg = 0; iseg < mefinfo->nseg; iseg++) {
                if(nmedseg[iseg] > 0) {
                  fmedsig(medseg[iseg], nmedseg[iseg], &medflux, &sigflux);
                  if(iseg == 0) {
                    medref = medflux;
                    haveref = 1;
                  }
                  
                  if(haveref)
                    corr = medflux - medref;
                  else
                    corr = 0;
                  
                  mefinfo->stars[star].segs[iseg].corr[meas] = corr;
                }
                else
                  mefinfo->stars[star].segs[iseg].corr[meas] = 0;
              }
            }
            else
              mefinfo->stars[star].segs[0].corr[meas] = 0;

            /* Compute global median, after correction */
            opt1 = 0;

            for(pt = 0; pt < mefinfo->nf; pt++)
              if(ptbuf[pt].aper[meas].flux != 0.0) {
                iseg = mefinfo->frames[pt].iseg;
                corr = mefinfo->stars[star].segs[iseg].corr[meas];

                medbuf1[opt1] = ptbuf[pt].aper[meas].flux - corr;
                opt1++;
              }
            
            fmedsig(medbuf1, opt1, &medflux, &sigflux);
            
            mefinfo->stars[star].medflux[meas] = medflux;
            mefinfo->stars[star].sigflux[meas] = sigflux;
          }
        }
      }

      for(meas = meas1; meas < meas2; meas++) {
	/* Compute and take off median correction in each segment - this
	 * forces any "common-mode" components present in every object to
	 * go into the frame corrections instead.
	 */
	for(iseg = 0; iseg < mefinfo->nseg; iseg++) {
	  /* Median correction */
	  opt1 = 0;
	  
	  for(star = 0; star < mefinfo->nstars; star++)
	    if(mefinfo->stars[star].medflux[meas] != 0.0 &&
	       mefinfo->stars[star].sigflux[meas] != 0.0 &&
               mefinfo->stars[star].compok)
	      /* Use only high s/n once we have the information */
	      if(iter == 0 ||
		 (mefinfo->stars[star].medflux[meas] >= mefinfo->sysllim &&
		  mefinfo->stars[star].medflux[meas] <= mefinfo->sysulim)) {
		medbuf1[opt1] = mefinfo->stars[star].segs[iseg].corr[meas];
		opt1++;
	      }
	  
	  if(opt1 > 0) {
	    fmedsig(medbuf1, opt1, &corr, (float *) NULL);
	    
	    if(verbose > 2)
	      printf("medcorr[%d]=%.4f\n", iseg, corr);
	    
	    /* Take it off */
	    for(star = 0; star < mefinfo->nstars; star++)
	      mefinfo->stars[star].segs[iseg].corr[meas] -= corr;
	  }
	}
      }

      /* Compute 2-D correction for each frame */
      for(pt = 0; pt < mefinfo->nf; pt++) {
	/* Read in measurements for this frame */
	if(buffer_fetch_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
	  goto error;
	
	for(meas = meas1; meas < meas2; meas++) {
	  /* Apply any meridian flip offsets */
	  if(mefinfo->domerid > 1)
	    for(star = 0; star < mefinfo->nstars; star++)
	      if(ptbuf[star].aper[meas].flux != 0.0)
		ptbuf[star].aper[meas].flux -= mefinfo->stars[star].segs[mefinfo->frames[pt].iseg].corr[meas];
	  
	  /* Compute polynomial fit correction */
	  if(systematic_fit(ptbuf, mefinfo, pt, meas, medbuf1, degree,
			    &(mefinfo->frames[pt].sys[meas]), errstr))
	    goto error;
	  
	  /* Trap for no points in fit - discard in this case */
	  if(mefinfo->frames[pt].sys[meas].npt > 0) {
	    /* Store frame RMS for normal aperture */
	    if(meas == meas1) {
	      mefinfo->frames[pt].offset = mefinfo->frames[pt].sys[meas].medoff;
	      mefinfo->frames[pt].rms = mefinfo->frames[pt].sys[meas].sigoff;
	      mefinfo->frames[pt].extinc = mefinfo->frames[pt].sys[meas].coeff[0];
	      mefinfo->frames[pt].sigm = sqrtf(mefinfo->frames[pt].sys[meas].cov[0]);
	    }

            /* Perform polynomial fit correction */
            if(doall) {
              if(systematic_apply_frame(ptbuf, mefinfo, pt, meas, errstr))
                goto error;
            }
          }    
        }

        if(doall) {
          /* Write out corrected fluxes */
          if(buffer_put_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
            goto error;
        }	    
      }
    }

    if(verbose && isatty(1))
      printf("\n");
  }
  
  if(!norenorm) {
    /* Compute per-object median flux */
    for(star = 0; star < mefinfo->nstars; star++) {
      /* Read in measurements for this star */
      if(buffer_fetch_object(buf, ptbuf, 0, mefinfo->nf, star, errstr))
	goto error;
      
      for(meas = meas1; meas < meas2; meas++) {
	/* Calculate median flux */
	opt1 = 0;
	for(pt = 0; pt < mefinfo->nf; pt++) {
	  if(ptbuf[pt].aper[meas].flux != 0.0 &&
	     ptbuf[pt].aper[meas].fluxvar != 0.0) {
	    medbuf1[opt1] = ptbuf[pt].aper[meas].flux;
	    opt1++;
	  }
	}
	
	fmedsig(medbuf1, opt1, &medflux, &sigflux);
	mefinfo->stars[star].medflux[meas] = medflux;
	mefinfo->stars[star].sigflux[meas] = sigflux;
      }
    }

    /* Compute median offset from reference system */
    for(meas = meas1; meas < meas2; meas++) {
      opt1 = 0;
      for(star = 0; star < mefinfo->nstars; star++)
	if(mefinfo->stars[star].medflux[meas] != 0.0 &&
	   mefinfo->stars[star].sigflux[meas] != 0.0 &&
	   mefinfo->stars[star].compok &&
	   mefinfo->stars[star].refmag >= mefinfo->sysllim &&
	   mefinfo->stars[star].refmag <= mefinfo->sysulim) {
	  medbuf1[opt1] = mefinfo->stars[star].medflux[meas] - mefinfo->stars[star].refmag;
	  opt1++;
	}
      
      fmedsig(medbuf1, opt1, &(medoff[meas]), &(sigoff[meas]));
      
      if(verbose)
	printf("  Aperture %ld calibration offset: %.3f %.3f\n",
	       meas+1, medoff[meas], sigoff[meas]);
    }
    
    /* Apply offset */
    for(pt = 0; pt < mefinfo->nf; pt++) {
      /* Read in measurements for this frame */
      if(buffer_fetch_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
	goto error;
      
      for(meas = meas1; meas < meas2; meas++)
	for(star = 0; star < mefinfo->nstars; star++)
	  if(ptbuf[star].aper[meas].flux != 0.0)
	    ptbuf[star].aper[meas].flux -= medoff[meas];
      
      /* Write out corrected fluxes */
      if(buffer_put_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
	goto error;
      
      mefinfo->frames[pt].extinc += medoff[meas1];
    }
  }

  /* Compute final per-object median flux in each aperture */
  for(star = 0; star < mefinfo->nstars; star++) {
    /* Read in measurements for this star */
    if(buffer_fetch_object(buf, ptbuf, 0, mefinfo->nf, star, errstr))
      goto error;
    
    used = 0;
    
    for(meas = meas1; meas < meas2; meas++) {
      /* Calculate median flux and set "used" flag for comparison stars */
      opt1 = 0;
      for(pt = 0; pt < mefinfo->nf; pt++) {
	if(ptbuf[pt].aper[meas].flux != 0.0 &&
	   ptbuf[pt].aper[meas].fluxvar != 0.0) {
	  medbuf1[opt1] = ptbuf[pt].aper[meas].flux;
	  opt1++;
	}
	if(ptbuf[pt].comp & (1 << meas))
	  used = 1;
      }
      
      fmedsig(medbuf1, opt1, &medflux, &sigflux);
      mefinfo->stars[star].medflux[meas] = medflux;
      mefinfo->stars[star].sigflux[meas] = sigflux;
    }
    
    mefinfo->stars[star].used += used;

#ifndef NOXY
    /* Calculate median x,y positions */
    for(iseg = 0; iseg < mefinfo->nseg; iseg++) {
      opt1 = 0;

      for(pt = 0; pt < mefinfo->nf; pt++) {
	if(ptbuf[pt].aper[0].flux != 0.0 &&
	   mefinfo->frames[pt].iseg == iseg) {
	  medbuf1[opt1] = ptbuf[pt].x;
	  medbuf2[opt1] = ptbuf[pt].y;
	  opt1++;
	}
      }
      
      if(opt1 > 0) {
	fmedsig(medbuf1, opt1,
                &(mefinfo->stars[star].segs[iseg].medx),
                &(mefinfo->stars[star].segs[iseg].sigx));
	fmedsig(medbuf2, opt1,
                &(mefinfo->stars[star].segs[iseg].medy),
                &(mefinfo->stars[star].segs[iseg].sigy));
      }
    }
#endif
  }

  /* Aperture correct and choose default aperture */
  if(chooseap(buf, mefinfo, ptbuf, medbuf1, norenorm, errstr))
    goto error;

  /* Extract median in chosen aperture */
  for(star = 0; star < mefinfo->nstars; star++) {
    mefinfo->stars[star].med = mefinfo->stars[star].medflux[mefinfo->stars[star].iap];
    mefinfo->stars[star].rms = mefinfo->stars[star].sigflux[mefinfo->stars[star].iap];
  }

#ifndef NOXY
  if(!noastrom) {
    if(verbose)
      printf(" Recomputing astrometric transformations\n");
    
    /* Compute positioning error for each frame */
    for(pt = 0; pt < mefinfo->nf; pt++) {
      /* Read in measurements for this frame */
      if(buffer_fetch_frame(buf, ptbuf, 0, mefinfo->nstars, pt, errstr))
	goto error;
      
      /* Compute transformation to ref. system */
      if(xytoxy(ptbuf, mefinfo, mefinfo->frames[pt].tr, errstr))
	goto error;
      
      /* OLD: */
      opt1 = 0;
      
      for(star = 0; star < mefinfo->nstars; star++)
	if(ptbuf[star].aper[0].flux > 0.0 &&              /* Has a flux measurement */
	   ptbuf[star].aper[0].fluxvar > 0.0 &&           /* And a reliable error */
	   ptbuf[star].aper[0].flux < mefinfo->sysulim && /* Not saturated */
	   mefinfo->stars[star].cls == -1) {              /* Stellar */
	  medbuf1[opt1] = ptbuf[star].x - mefinfo->stars[star].segs[mefinfo->frames[pt].iseg].medx;
	  medbuf2[opt1] = ptbuf[star].y - mefinfo->stars[star].segs[mefinfo->frames[pt].iseg].medy;
	  opt1++;
	}
      
      if(opt1 > 0) {
	fmedsig(medbuf1, opt1,
                &(mefinfo->frames[pt].xoff), &(mefinfo->frames[pt].xsig));
	fmedsig(medbuf2, opt1,
                &(mefinfo->frames[pt].yoff), &(mefinfo->frames[pt].ysig));
      }
    }
    
    /* Compute median positioning errors (should be zero) and rms */
    for(iseg = 0; iseg < mefinfo->nseg; iseg++) {
      opt1 = 0;
      
      for(pt = 0; pt < mefinfo->nf; pt++) {
	if(mefinfo->frames[pt].iseg == iseg) {
	  medbuf1[opt1] = mefinfo->frames[pt].xoff;
	  medbuf2[opt1] = mefinfo->frames[pt].yoff;
	  opt1++;
	}
      }
      
      fmedsig(medbuf1, opt1,
              &(mefinfo->segs[iseg].medxoff), &(mefinfo->segs[iseg].sigxoff));
      fmedsig(medbuf2, opt1,
              &(mefinfo->segs[iseg].medyoff), &(mefinfo->segs[iseg].sigyoff));
    }
  }
#endif

  /* Free workspace */
  free((void *) ptbuf);
  ptbuf = (struct lc_point *) NULL;
  free((void *) medbuf1);
  medbuf1 = (float *) NULL;
  free((void *) medsegbuf);
  medsegbuf = (float *) NULL;
  free((void *) medseg);
  medseg = (float **) NULL;
  free((void *) nmedseg);
  nmedseg = (int *) NULL;

  return(0);

 error:
  if(ptbuf)
    free((void *) ptbuf);
  if(medbuf1)
    free((void *) medbuf1);
  if(medsegbuf)
    free((void *) medsegbuf);
  if(medseg)
    free((void *) medseg);
  if(nmedseg)
    free((void *) nmedseg);

  return(1);
}
示例#6
0
int xytoxy (struct lc_point *data, struct lc_mef *mefinfo,
	    double tr[6], char *errstr) {
  double *wtbuf = (double *) NULL;
  float *tmpbufx = (float *) NULL, *tmpbufy;
  unsigned char *rejbuf = (unsigned char *) NULL;
  float satlim;

  long star, opt, nuse, nrej;
  double dx, dy, err;
  int iter, iap;

  float averrx, averry, averr;

  /* Init transformation */
  tr[0] = 1.0;
  tr[1] = 0.0;
  tr[2] = 0.0;
  tr[3] = 1.0;
  tr[4] = 0.0;
  tr[5] = 0.0;

  /* Allocate workspace */
  wtbuf = (double *) malloc(mefinfo->nstars * sizeof(double));
  tmpbufx = (float *) malloc(2 * mefinfo->nstars * sizeof(float));
  rejbuf = (unsigned char *) malloc(mefinfo->nstars * sizeof(unsigned char));
  if(!wtbuf || !tmpbufx || !rejbuf) {
    report_syserr(errstr, "malloc");
    goto error;
  }

  tmpbufy = tmpbufx + mefinfo->nstars;

  /* Decide initial weights and rejection */
  opt = 0;

  satlim = mefinfo->sysulim < 0.0 ?
    mefinfo->zp - mefinfo->satmag : mefinfo->sysulim;

  for(star = 0; star < mefinfo->nstars; star++) {
    iap = mefinfo->stars[star].iap;

    if(data[star].aper[iap].flux > 0.0 &&          /* Has a flux measurement */
       data[star].aper[iap].fluxvar > 0.0 &&       /* And a reliable error */
       mefinfo->stars[star].sigflux[iap] > 0 &&
       data[star].aper[iap].flux < satlim &&  /* Not saturated */
       mefinfo->stars[star].cls == -1) {   /* Is classified as stellar */
      wtbuf[star] = 1.0;
      rejbuf[star] = 0;
      opt++;
    }
    else {
      wtbuf[star] = 0.0;
      rejbuf[star] = 1;
    }
  }

  averr = 0;

  for(iter = 0; iter < NITER; iter++) {
    nuse = 0;

    if(iter > 0) {
      for(star = 0; star < mefinfo->nstars; star++)
	if(!rejbuf[star]) {
	  dx = dplate_tr_x(data[star].x, data[star].y, tr)
             - mefinfo->stars[star].x;
          dy = dplate_tr_y(data[star].x, data[star].y, tr)
             - mefinfo->stars[star].y;
	  err = sqrt(dx*dx+dy*dy);
	
	  if(err > NSIGMA * averr) {
	    wtbuf[star] = 0;
	    rejbuf[star] = 1;
	  }
	  else
	    nuse++;
	}
    }
    else {
      for(star = 0; star < mefinfo->nstars; star++)
	if(!rejbuf[star])
	  nuse++;
    }    

    if(nuse >= 3)
      dplate(data, offsetof(struct lc_point, x), sizeof(struct lc_point),
             data, offsetof(struct lc_point, y), sizeof(struct lc_point),
             mefinfo->stars, offsetof(struct lc_star, x), sizeof(struct lc_star),
             mefinfo->stars, offsetof(struct lc_star, y), sizeof(struct lc_star),
             wtbuf, 0, sizeof(double),
             mefinfo->nstars, 6, tr);
    else
      break;

    nuse = 0;
    nrej = 0;
    for(star = 0; star < mefinfo->nstars; star++) {
      if(rejbuf[star])
	nrej++;
      else {
        dx = dplate_tr_x(data[star].x, data[star].y, tr)
           - mefinfo->stars[star].x;
        dy = dplate_tr_y(data[star].x, data[star].y, tr)
           - mefinfo->stars[star].y;
	
	tmpbufx[nuse] = fabsf(dx);
	tmpbufy[nuse] = fabsf(dy);

	nuse++;
      }
    }
    
    fmedsig(tmpbufx, nuse, &averrx, (float *) NULL);
    fmedsig(tmpbufx, nuse, &averry, (float *) NULL);
    
    averrx *= 1.48;  /* converts to rms equivalent */
    averry *= 1.48;

    averr = sqrt(averrx*averrx + averry*averry);

    if(verbose > 2) {
      printf("Iteration %d Av error %.4f (%.4f %.4f) nfit %ld (rej %ld)\n",
	     iter+1, averr, averrx, averry, nuse, nrej);
    }
  }
示例#7
0
struct input_file *read_file_list (int argc, char **argv,
                                   int *nf_r, char *errstr) {
  struct input_file *list = (struct input_file *) NULL;

  FILE *fp = (FILE *) NULL;
  char line[16384], *av, *p, *s;

  int a, f, nf = 0;

#ifndef _WIN32
  glob_t gbuf;
  int rv, op;

  /* Init */
  gbuf.gl_pathv = (char **) NULL;
#endif

  int is_zip;

#ifdef ZIPSUPPORT
  zip_t *z = (zip_t *) NULL;
  zip_error_t ze;
  struct zip_stat sb;

  int zerrno;
  int ent, nent;
  const char *name;
  int namelen;

  zip_uint8_t opsys;
  zip_uint32_t extattr;
#endif

  /* Loop over arguments */
  for(a = 0; a < argc; a++) {
    av = argv[a];

    if(*av == '@') {  /* @list form */
      av++;  /* skip past the @ */

      is_zip = is_zip_file(av, errstr);
      if(is_zip < 0)
        goto error;

      if(is_zip) {
#ifdef ZIPSUPPORT
        z = zip_open(av, 0, &zerrno);
        if(!z) {
          zip_error_init_with_code(&ze, zerrno);
          report_err(errstr, "zip_open: %s: %s",
                     av, zip_error_strerror(&ze));
          zip_error_fini(&ze);
          goto error;
        }
        
        nent = zip_get_num_entries(z, 0);
        if(nent < 0) {
          report_err(errstr, "zip_get_num_entries: %s",
                     zip_strerror(z));
          goto error;
        }
        
        for(ent = 0; ent < nent; ent++) {
          if(zip_stat_index(z, ent, 0, &sb)) {
            report_err(errstr, "zip_stat_index(%d): %s\n",
                       ent, zip_strerror(z));
            goto error;
          }
          
          if(zip_file_get_external_attributes(z, ent, 0, &opsys, &extattr)) {
            report_err(errstr, "zip_get_external_attributes(%d): %s\n",
                       ent, zip_strerror(z));
            goto error;
          }
          
          name = sb.name;
          namelen = strlen(name);
          
          if((opsys != ZIP_OPSYS_AMIGA && extattr & 0x10) ||
             (namelen > 0 && name[namelen-1] == '/'))
            /* Is directory */
            continue;
          
          /* Otherwise, add to list */
          list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
          if(!list) {
            report_syserr(errstr, "realloc");
            goto error;
          }
          
          s = strdup(name);
          if(!s) {
            report_syserr(errstr, "strdup");
            goto error;
          }
          
          list[nf].filename = s;
          list[nf].ient = ent;
          list[nf].iarg = a;
          list[nf].arg = av;
          nf++;
        }
        
        if(zip_close(z)) {
          report_err(errstr, "zip_close: %s",
                     zip_strerror(z));
          goto error;
        }

        z = (zip_t *) NULL;
#else
        report_err(errstr, "not compiled with zip support");
        goto error;
#endif
      }
      else {
        fp = fopen(av, "r");
        if(!fp) {
          report_syserr(errstr, "open: %s", av);
          goto error;
        }
        
        while(fgets(line, sizeof(line), fp)) {
          p = sstrip(line);
          
          if(*p) {
            list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
            if(!list) {
              report_syserr(errstr, "realloc");
              goto error;
            }
            
            s = strdup(p);
            if(!s) {
              report_syserr(errstr, "strdup");
              goto error;
            }
            
            list[nf].filename = s;
            list[nf].ient = -1;
            list[nf].iarg = a;
            list[nf].arg = av;
            nf++;
          }
        }
        
        if(ferror(fp)) {
          report_syserr(errstr, "read: %s", av);
          goto error;
        }
        
        fclose(fp);
        fp = (FILE *) NULL;
      }
    }
    else {  /* glob or single filename */
#ifndef _WIN32
      rv = glob(av, 0, NULL, &gbuf);
      if(rv == 0) {  /* succeeded */
        /* Allocate block */
        list = (struct input_file *) realloc(list,
                                             (nf+gbuf.gl_pathc) * sizeof(struct input_file));
        if(!list) {
          report_syserr(errstr, "realloc");
          goto error;
        }

        /* Zero out the new pointers */
        memset(list+nf, 0, gbuf.gl_pathc * sizeof(struct input_file));

        /* Record so we know to free them */
        op = nf;

        nf += gbuf.gl_pathc;
        
        for(f = 0; f < gbuf.gl_pathc; f++) {
          s = strdup(gbuf.gl_pathv[f]);
          if(!s) {
            report_syserr(errstr, "strdup");
            goto error;
          }

          list[op].filename = s;
          list[op].ient = -1;
          list[op].iarg = a;
          list[op].arg = av;
          op++;
        }

        globfree(&gbuf);
        gbuf.gl_pathv = (char **) NULL;
      }
      else if(rv == GLOB_NOMATCH) {  /* no match */
#endif  /* _WIN32 */

        /* Assume it's a single entry. */
        list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
        if(!list) {
          report_syserr(errstr, "realloc");
          goto error;
        }
        
        s = strdup(av);
        if(!s) {
          report_syserr(errstr, "strdup");
          goto error;
        }
        
        list[nf].filename = s;
        list[nf].ient = -1;
        list[nf].iarg = a;
        list[nf].arg = av;
        nf++;
#ifndef _WIN32
      }
      else {
        report_err(errstr, "glob error: %s", av);
        goto error;
      }
#endif
    }
  }

  *nf_r = nf;

  return(list);

 error:
  if(fp)
    fclose(fp);

#ifndef _WIN32
  if(gbuf.gl_pathv)
    globfree(&gbuf);
#endif

#ifdef ZIPSUPPORT
  if(z) {
    zip_close(z);
    z = (zip_t *) NULL;
  }
#endif

  if(list) {
    for(f = 0; f < nf; f++)
      if(list[f].filename)
        free((void *) list[f].filename);

    free((void *) list);
  }

  return((struct input_file *) NULL);
}