Exemple #1
0
/* interpolate Ne data near time t to latitude qdlat */
double
interp_ne(const time_t t, const double qdlat, const satdata_mag *data)
{
  double t_cdf = satdata_timet2epoch(t);
  double Ne;

  if (t_cdf >= data->t[0] && t_cdf <= data->t[data->n - 1])
    {
      int idx = (int) bsearch_double(data->t, t_cdf, 0, data->n - 1);
      int half_window = 15; /* number of minutes in half time window */
      int idx1 = GSL_MAX(0, idx - half_window*60*2);
      int idx2 = GSL_MIN(data->n - 1, idx + half_window*60*2);
      int qidx;
      
      if (data->qdlat[idx1] < data->qdlat[idx2])
        qidx = (int) bsearch_double(data->qdlat, qdlat, idx1, idx2);
      else
        qidx = (int) bsearch_desc_double(data->qdlat, qdlat, idx1, idx2);

      Ne = interp1d(data->qdlat[qidx], data->qdlat[qidx + 1],
                    data->ne[qidx], data->ne[qidx + 1], qdlat);
    }
  else
    Ne = 0.0;

  return Ne;
}
/* 
 * binary search a sorted double array 'arr' of size 'n'. if found,
 * the 'loc' pointer has the address of 'ele' and the return 
 * value is TRUE. otherwise, the return value is FALSE and 'loc' 
 * points to the 'should have been' location
 */
int bsearch_double(double *arr, int n, double ele, double **loc)
{
	if(n < 0)
		fatal("wrong index in binary search\n");

	if(n == 0) {
		*loc = arr;
		return FALSE;
	}

	if(eq(arr[n/2], ele)) {
		*loc = &arr[n/2];
		return TRUE;
	} else if (arr[n/2] < ele) {
		return bsearch_double(&arr[n/2+1], (n-1)/2, ele, loc);
	} else
		return bsearch_double(arr, n/2, ele, loc);

}
/* 
 * binary search and insert an element into a partially sorted
 * double array if not already present. returns FALSE if present
 */
int bsearch_insert_double(double *arr, int n, double ele)
{
	double *loc;
	int i;

	/* element found - nothing more left to do	*/
	if (bsearch_double(arr, n, ele, &loc))
		return FALSE;
	else {
		for(i=n-1; i >= (loc-arr); i--)
			arr[i+1] = arr[i];
		arr[loc-arr] = ele;	
	}
	return TRUE;
}
Exemple #4
0
int
fill_dens(magdata *mdata, const satdata_lp *dens_data)
{
  int s = 0;
  size_t i;

  /* initialize ne array */
  for (i = 0; i < mdata->n; ++i)
    mdata->ne[i] = 0.0;

  for (i = 0; i < mdata->n; ++i)
    {
      double t = mdata->t[i];
      size_t idx;
      double dt, ne;
      double t0, t1;

      if (t < dens_data->t[0] || t > dens_data->t[dens_data->n - 1])
        continue;

      idx = bsearch_double(dens_data->t, t, 0, dens_data->n);

      t0 = dens_data->t[idx];
      t1 = dens_data->t[idx + 1];

      dt = t1 - t0;
      dt /= 1000.0; /* convert to s */

      /* check for data gaps in PLP measurements */
      if (fabs(dt) > 30.0)
        continue;

      ne = interp1d(t0, t1, dens_data->ne[idx], dens_data->ne[idx + 1], t);

      mdata->ne[i] = ne;
    }

  return s;
}
Exemple #5
0
/* 
 * create a non-uniform grid-like floorplan equivalent to this.
 * this function is mainly useful when using the HotSpot block
 * model to model floorplans of drastically differing aspect
 * ratios and granularity. an example for such a floorplan
 * would be the standard ev6 floorplan that comes with HotSpot,
 * where the register file is subdivided into say 128 entries.
 * the HotSpot block model could result in inaccuracies while
 * trying to model such floorplans of differing granularity.
 * if such inaccuracies occur, use this function to create an 
 * equivalent floorplan that can be modeled accurately in 
 * HotSpot. 'map', if non-NULL, is an output parameter to store 
 * the 2-d array allocated by the function.
 */
flp_t *flp_create_grid(flp_t *flp, int ***map)
{
	double x[MAX_UNITS], y[MAX_UNITS];
	int i, j, n, xsize=0, ysize=0, count=0, found, **ptr;
	flp_t *grid;

	/* sort the units' boundary co-ordinates	*/
	for(i=0; i < flp->n_units; i++) {
		double r, t;
		r = flp->units[i].leftx + flp->units[i].width;
		t = flp->units[i].bottomy + flp->units[i].height;
		if(bsearch_insert_double(x, xsize, flp->units[i].leftx))
			xsize++;
		if(bsearch_insert_double(y, ysize, flp->units[i].bottomy))
			ysize++;
		if(bsearch_insert_double(x, xsize, r))
			xsize++;
		if(bsearch_insert_double(y, ysize, t))
			ysize++;
	}

	/* 
	 * the grid formed by the lines from x and y arrays
	 * is our desired floorplan. allocate memory for it
	 */
	grid = (flp_t *) calloc (1, sizeof(flp_t));
	if(!grid)
		fatal("memory allocation error\n");
	grid->n_units = (xsize-1) * (ysize-1);	
	grid->units = (unit_t *) calloc (grid->n_units, sizeof(unit_t));
	grid->wire_density = (double **) calloc(grid->n_units, sizeof(double *));
	if (!grid->units || !grid->wire_density)
		fatal("memory allocation error\n");
	for (i=0; i < grid->n_units; i++) {
	  grid->wire_density[i] = (double *) calloc(grid->n_units, sizeof(double));
	  if (!grid->wire_density[i])
	  	fatal("memory allocation error\n");
	}
	/* mapping between blocks of 'flp' to those of 'grid'	*/
	ptr = (int **) calloc(flp->n_units, sizeof(int *));
	if (!ptr)
		fatal("memory allocation error\n");
	/* 
	 * ptr is a 2-d array with each row of possibly different
	 * length. the size of each row is stored in its first element.
	 * here, it is basically the mapping between 'flp' to 'grid'
	 * i.e., for each flp->unit, it stores the set of grid->units
	 * it maps to.
	 */
	for(i=0; i < flp->n_units; i++) {
		ptr[i] = (int *) calloc(grid->n_units+1, sizeof(int));
		if(!ptr[i])
	  		fatal("memory allocation error\n");
	}

	/* 
	 * now populate the 'grid' blocks and map the blocks 
	 * from 'flp' to 'grid'. for each block, identify the 
	 * intervening lines that chop it into grid cells and 
	 * assign the names of those cells from that of the 
	 * block
	 */
	for(i=0; i < flp->n_units; i++) {
		double *xstart, *xend, *ystart, *yend;
		double *ptr1, *ptr2;
		int grid_num=0;
		if (!bsearch_double(x, xsize, flp->units[i].leftx, &xstart))
			fatal("invalid sorted arrays\n");
		if (!bsearch_double(x, xsize, flp->units[i].leftx+flp->units[i].width, &xend))
			fatal("invalid sorted arrays\n");
		if (!bsearch_double(y, ysize, flp->units[i].bottomy, &ystart))
			fatal("invalid sorted arrays\n");
		if (!bsearch_double(y, ysize, flp->units[i].bottomy+flp->units[i].height, &yend))
			fatal("invalid sorted arrays\n");
		for(ptr1 = xstart; ptr1 < xend; ptr1++)
			for(ptr2 = ystart; ptr2 < yend; ptr2++) {
				/* add this grid block if it has not been added already	*/
				for(n=0, found=FALSE; n < count; n++) {
					if (grid->units[n].leftx == ptr1[0] && grid->units[n].bottomy == ptr2[0]) {
						found = TRUE;
						break;
					}
				}
				if(!found) {
					sprintf(grid->units[count].name, "%s_%d", flp->units[i].name, grid_num);
					grid->units[count].leftx = ptr1[0];
					grid->units[count].bottomy = ptr2[0];
					grid->units[count].width = ptr1[1]-ptr1[0];
					grid->units[count].height = ptr2[1]-ptr2[0];
				}
					/* map between position in 'flp' to that in 'grid'	*/
					ptr[i][++ptr[i][0]] = count;
					grid_num++;
					count++;
				}
			
	}


	/* sanity check	*/
	if(count != (xsize-1) * (ysize-1))
		fatal("mismatch in the no. of units\n");

	/* fill-in the wire densities	*/
	for(i=0; i < flp->n_units; i++)
		for(j=0; j < flp->n_units; j++) {
			int p, q;
			for(p=1; p <= ptr[i][0]; p++)
				for(q=1; q <= ptr[j][0]; q++)
					grid->wire_density[ptr[i][p]][ptr[j][q]] = flp->wire_density[i][j];
		}

	/* output the map	*/
	if (map)
		(*map) = ptr;
	else
		free_blkgrid_map(flp, ptr);
	
	return grid;
}
Exemple #6
0
int
track_smooth(const double alpha, satdata_mag *data, track_workspace *w)
{
    int s = 0;
    size_t i, j;

    for (i = 0; i < w->n; ++i)
    {
        track_data *tptr = &(w->tracks[i]);
        size_t sidx = tptr->start_idx;
        size_t eidx = tptr->end_idx;
        size_t idxs, idxn;
        size_t npts;

        if (tptr->satdir == 1)
        {
            idxn = bsearch_double(&data->qdlat[sidx], 55.0, 0, tptr->n - 1);
            idxs = bsearch_double(&data->qdlat[sidx], -55.0, 0, tptr->n - 1);

            npts = tptr->n - idxn;
            track_ema(alpha, &data->flags[sidx + idxn], &tptr->Bf[idxn], npts);
            track_ema(alpha, &data->flags[sidx + idxn], &tptr->Bx[idxn], npts);
            track_ema(alpha, &data->flags[sidx + idxn], &tptr->By[idxn], npts);
            track_ema(alpha, &data->flags[sidx + idxn], &tptr->Bz[idxn], npts);

            npts = idxs + 1;
            track_ema_reverse(alpha, &data->flags[sidx], tptr->Bf, npts);
            track_ema_reverse(alpha, &data->flags[sidx], tptr->Bx, npts);
            track_ema_reverse(alpha, &data->flags[sidx], tptr->By, npts);
            track_ema_reverse(alpha, &data->flags[sidx], tptr->Bz, npts);
        }
        else
        {
            idxn = bsearch_desc_double(&data->qdlat[sidx], 55.0, 0, tptr->n - 1);
            idxs = bsearch_desc_double(&data->qdlat[sidx], -55.0, 0, tptr->n - 1);

            npts = idxn + 1;
            track_ema_reverse(alpha, &data->flags[sidx], tptr->Bf, npts);
            track_ema_reverse(alpha, &data->flags[sidx], tptr->Bx, npts);
            track_ema_reverse(alpha, &data->flags[sidx], tptr->By, npts);
            track_ema_reverse(alpha, &data->flags[sidx], tptr->Bz, npts);

            npts = tptr->n - idxs;
            track_ema(alpha, &data->flags[sidx + idxs], &tptr->Bf[idxs], npts);
            track_ema(alpha, &data->flags[sidx + idxs], &tptr->Bx[idxs], npts);
            track_ema(alpha, &data->flags[sidx + idxs], &tptr->By[idxs], npts);
            track_ema(alpha, &data->flags[sidx + idxs], &tptr->Bz[idxs], npts);
        }

        /* recompute data arrays with smoothed residuals */
        for (j = sidx; j <= eidx; ++j)
        {
            double B_model[4];

            satdata_mag_model(j, B_model, data);

            SATDATA_VEC_X(data->B, j) = tptr->Bx[j - sidx] + B_model[0];
            SATDATA_VEC_Y(data->B, j) = tptr->By[j - sidx] + B_model[1];
            SATDATA_VEC_Z(data->B, j) = tptr->Bz[j - sidx] + B_model[2];
            data->F[j] = tptr->Bf[j - sidx] + B_model[3];
        }

        /* recompute residuals with smoothed data */
        track_calc_residuals(tptr, data);
    }

    return s;
} /* track_smooth() */
Exemple #7
0
size_t
track_init(satdata_mag *data, msynth_workspace *msynth_p, track_workspace *w)
{
    size_t nflagged = 0;
    size_t i = 0, j;

    w->data = data;

    while (i < data->n - 1)
    {
        int s;
        double lon_eq, t_eq, lt_eq;
        size_t sidx, eidx;
        track_data *tptr;

        s = satdata_mag_find_track(i, &eidx, data);
        if (s)
        {
#if TRACK_DEBUG
            fprintf(stderr, "track_init: no more tracks found in [%zu, %zu]\n", sidx, data->n - 1);
#endif
            break;
        }

        /* update index i for next loop */
        sidx = i;
        i = eidx + 1;

        /* check for equator crossing */
        if (data->latitude[sidx] * data->latitude[eidx] < 0.0)
        {
            size_t idx;
            time_t unix_time;

            /* there is an equator crossing, find time and longitude */

            if (data->latitude[eidx] > data->latitude[sidx])
                idx = bsearch_double(data->latitude, 0.0, sidx, eidx);
            else if (data->latitude[eidx] < data->latitude[sidx])
                idx = bsearch_desc_double(data->latitude, 0.0, sidx, eidx);

            /* sanity check we found equator crossing */
            assert(data->latitude[idx] * data->latitude[idx + 1] < 0.0);

            /* interpolate t, but not longitude due to wrapping effects */
            t_eq = interp1d(data->latitude[idx], data->latitude[idx + 1],
                            data->t[idx], data->t[idx + 1], 0.0);
            lon_eq = data->longitude[idx];

            /* compute local time */
            unix_time = satdata_epoch2timet(t_eq);
            lt_eq = get_localtime(unix_time, lon_eq * M_PI / 180.0);
        }
        else
        {
            /* no equator crossing */

#if TRACK_DEBUG
            fprintf(stderr, "track_init: flagging partial track [%zu, %zu]\n", sidx, eidx);
#endif
            nflagged += track_flag_data(sidx, eidx, data);
            continue;
        }

        /* compute main field along track in data->F_main */
        if (msynth_p)
            track_calc_mf(sidx, eidx, data, msynth_p);

        /* store this track information */
        tptr = &(w->tracks[w->n]);
        tptr->start_idx = sidx;
        tptr->end_idx = eidx;
        tptr->n = eidx - sidx + 1;
        tptr->t_eq = t_eq;
        tptr->lon_eq = lon_eq;
        tptr->lt_eq = lt_eq;
        tptr->nrms_scal = 0;
        tptr->nrms_vec = 0;
        tptr->flags = 0;
        tptr->k_ext = 0.0;
        tptr->meanalt = gsl_stats_mean(&(data->altitude[sidx]), 1, tptr->n);

        /* use index of track center to compute satellite direction */
        tptr->satdir = satdata_mag_satdir(sidx + tptr->n / 2, data);

        for (j = 0; j < 3; ++j)
            tptr->rms[j] = 0.0;

        assert(tptr->n > 0);

        /* compute and store along-track residuals */
        tptr->Bx = malloc(tptr->n * sizeof(double));
        tptr->By = malloc(tptr->n * sizeof(double));
        tptr->Bz = malloc(tptr->n * sizeof(double));
        tptr->Bf = malloc(tptr->n * sizeof(double));

        track_calc_residuals(tptr, data);

        if (++(w->n) >= w->ntot)
        {
            fprintf(stderr, "track_init: ntot not large enough: %zu\n", w->ntot);
            return nflagged;
        }
    }

#if TRACK_DEBUG
    fprintf(stderr, "track_init: found %zu tracks\n", w->n);
#endif

    return nflagged;
} /* track_init() */