Пример #1
0
double seg2segdistsq(int *x1, int *y1, int *x2, int *y2) {
	double d1 = distsq(x1[0], y1[0], x1[1], y1[1], x2[0], y2[0]);
	double d2 = distsq(x1[0], y1[0], x1[1], y1[1], x2[1], y2[1]);
	double d3 = distsq(x2[0], y2[0], x2[1], y2[1], x1[0], y1[0]);
	double d4 = distsq(x2[0], y2[0], x2[1], y2[1], x1[1], y1[1]);
	return min(min(d1, d2), min(d3, d4));
}
Пример #2
0
int KDTree::GetClosestFattyCell(float *pnt, KDTreeNode **nodeOut )
{
	 int dim = 0;
	// First, iterate along the path to the point, 
	// and find the one associated with this point
	// on the line
		struct KDTreeNode *n = m_Root;
	for (;;) {
		// Is this a leaf node
		if (n->pntidx >= 0) {
			*nodeOut = n;
			break;
		}
		if (n->key > pnt[dim]) 
				n = m_Root + n->leftIdx;
			else 
				n = m_Root + n->rightIdx;;
		dim = (dim + 1) % ndim;
	}
	int idx = (int)(n-m_Root);
	float ndistsq = distsq( pnt, points + idx*ndim );
		
	// Search for possible other nearest neighbors
	// by examining adjoining nodes whos children may
	// be closer
	CheckNeighborFattyCells(0, 0, pnt, ndistsq, nodeOut);
	return 0;
}
Пример #3
0
int KDTree::GetClosestPoint(float *pnt, int &idx, bool approx)
{
  int dim = 0;

  // First, iterate along the path to the point, 
  // and find the one associated with this point
  // on the line
	struct KDTreeNode *n = m_Root;
  idx = -1;
  for (;;) {
    // Is this a leaf node
    if (n->pntidx >= 0) {
      idx = n->pntidx;
      break;
    }
    if (n->key > pnt[dim]) 
			n = m_Root + n->leftIdx;
		else 
				n = m_Root + n->rightIdx;;
    dim = (dim + 1) % ndim;
  }
  // Are we getting an approximate value?
  if(approx == true) return 0;

  float ndistsq = distsq(pnt,points+idx*ndim);
	
  // Search for possible other nearest neighbors
  // by examining adjoining nodes whos children may
  // be closer
  check_border_distance(0, 0, pnt, ndistsq, idx);

  return 0;
}				// end of GetClosestPoint
Пример #4
0
int KDTree::GetClosestPoints(float *pnt, multimap< float, int > &sortedPoints, float &distancesquared )
{  int dim = 0;

  // First, iterate along the path to the point, 
  // and find the one associated with this point
  // on the line
	struct KDTreeNode *n = m_Root;
  int idx = -1;
  for (;;) {
    // Is this a leaf node
    if (n->pntidx >= 0) {
      idx = n->pntidx;
      break;
    }
    if (n->key > pnt[dim]) 
			n = m_Root + n->leftIdx;
		else 
			n = m_Root + n->rightIdx;;
    dim = (dim + 1) % ndim;
  }

  float ndistsq = distsq(pnt,points+idx*ndim);
  sortedPoints.insert( pair< float, int >( ndistsq, idx ) );
  // Search for possible other nearest neighbors
  // by examining adjoining nodes whos children may
  // be closer
  check_border_distance_sort(0, 0, pnt,  distancesquared, sortedPoints);

  return 0;
}			
Пример #5
0
double distsq_between_radecdeg(double ra1, double dec1,
                               double ra2, double dec2) {
    double xyz1[3];
    double xyz2[3];
    radecdeg2xyzarr(ra1, dec1, xyz1);
    radecdeg2xyzarr(ra2, dec2, xyz2);
    return distsq(xyz1, xyz2, 3);
}
/**
 This callback gets called when we've reached a node in the Y tree and
 a node in the X tree (one or both may be leaves), and it's time to
 look at individual data points.
 */
static void rs_handle_result(void* vparams,
							 kdtree_t* xtree, int xnode,
							 kdtree_t* ytree, int ynode) {
	int xl, xr, yl, yr;
	int x, y;
    rs_params* p = (rs_params*)vparams;
	int D = ytree->ndim;
	double checkd2;

	xl = kdtree_left (xtree, xnode);
	xr = kdtree_right(xtree, xnode);
	yl = kdtree_left (ytree, ynode);
	yr = kdtree_right(ytree, ynode);

	for (y=yl; y<=yr; y++) {
		void* py = kdtree_get_data(ytree, y);

		if (p->count_in_range) {
		  checkd2 = p->d2;
		} else {
		  p->nearest_d2[y] = MIN(p->nearest_d2[y], p->node_nearest_d2[ynode]);
		  checkd2 = p->nearest_d2[y];
		}
		
		// check if we can eliminate the whole x node for this y point...
        if (kdtree_node_point_mindist2_exceeds(xtree, xnode, py, checkd2))
		  continue;

		for (x=xl; x<=xr; x++) {
			double d2;
			void* px;
			if (p->notself && (y == x))
				continue;
			px = kdtree_get_data(xtree, x);
			d2 = distsq(px, py, D);

			if (p->count_in_range) {
			  if (d2 < p->d2) {
				p->count_in_range[y]++;
			  }
			}

            if (d2 > p->nearest_d2[y])
                continue;
            p->nearest_d2[y] = d2;
            p->nearest_ind[y] = x;
		}
	}
}
Пример #7
0
Файл: c.c Проект: noodles-v6/ACM
void convexhull() {
	int i,hix=-INF,loy=-INF,ix=-1;
	int atx,aty;
	double pi=2*acos(0),dir,a,best,bestd;
	point_t t;
	for(i=0;i<n;i++) if(hix<p[i].x || (hix==p[i].x && loy>p[i].y)) hix=p[i].x,loy=p[i].y,ix=i;
	t=p[0],p[0]=p[ix],p[ix]=t;
	hn=ix=0;
	dir=pi/2;
	do {
		atx=p[ix].x; aty=p[ix].y;
		h[hn++]=p[ix];
		best=1e100; bestd=1e100;
		ix=-1;
		for(i=0;i<n;i++) if(p[i].x!=atx || p[i].y!=aty) {
			a=atan2(p[i].y-aty,p[i].x-atx);
			while(a+EPS<dir) a+=2*pi;
			if(fabs(best-a)<EPS && bestd>distsq(p[i].x,p[i].y,atx,aty)) best=a,ix=i,bestd=distsq(p[i].x,p[i].y,atx,aty);
			else if(fabs(best-a)>=EPS && best>a) best=a,bestd=distsq(p[i].x,p[i].y,atx,aty),ix=i;
		}
		if(ix<0) puts("error");
		dir=best;
	} while(ix);
}
Пример #8
0
void printoctreesearchsphere(const std::string& str,
                             const double *xp,
                             const double *yp,
                             const double *zp,
                             const double& search_x,
                             const double& search_y,
                             const double& search_z,
                             const double& search_radius,
                             const std::deque<int>& nbrlist) 
{


 std::ofstream octreesearch_file;
 octreesearch_file.open(str.c_str());

  octreesearch_file<<"Number of neighbours detected are "<<nbrlist.size()                      <<std::endl;

  octreesearch_file<<"\n\nSearch point is "                  <<search_x<<"\t"
                                                         <<search_y<<"\t"
	                                                 <<search_z                           <<std::endl;
  octreesearch_file<<"Search Radius is "                 <<search_radius                      <<std::endl;


  octreesearch_file<<"\nIn the table below POSN indicates the position of the neighbours in the XYZ arrays used while building the octree.\n"<<std::endl;
  octreesearch_file<<"\n-------------------------------------------------------------------- " << std::endl;
  octreesearch_file<<"              OCTREE SEARCH NEIGHBOURS                     "               <<std::endl;
  octreesearch_file<<"\n------------------------------------------------------------------"    << std::endl;
  octreesearch_file<<"#\tPOSN\tXCD\tYCD\tZCD\t\tDISTANCE TO SEARCHPT"                       << std::endl;
  octreesearch_file<<"-------------------------------------------------------------------- "   << std::endl;      

  for (unsigned int i = 0; i < nbrlist.size(); ++i)
    {
          octreesearch_file << std::setprecision(3)
                << i <<"\t"
                << nbrlist[i]     <<"\t"
                << xp[nbrlist[i]] <<"\t"
                << yp[nbrlist[i]] <<"\t"
		<< zp[nbrlist[i]] <<"\t\t"
                << sqrt( distsq( xp[nbrlist[i]], yp[nbrlist[i]], zp[nbrlist[i]], search_x, search_y, search_z) )<<std::endl;
    }//end for
  octreesearch_file<<"-------------------------------------------------------------------- " << std::endl;

  octreesearch_file.close();

} 
Пример #9
0
int KDTree::CheckNeighborFattyCells( int nodeIdx, int dim,
				  float *pnt, float &cdistsq, KDTreeNode ** nodeOut )
{
	if(!nodeOut ||
		!(*nodeOut) )
		return 0;

	// Are we at a closer leaf node?  
	// If so, check the distance
	struct KDTreeNode *node = *nodeOut;
	if (node->pntidx >= 0) {
		float dsq = distsq(pnt, points+node->pntidx*ndim);
			if (dsq < cdistsq) {
			cdistsq = dsq;
			*nodeOut = node;
		}
		return 0;
	}

	// The distance squared along the current dimension between the
	// point and the key
	float ndistsq = 
		(node->key - pnt[dim])*(node->key - pnt[dim]);

	// If the distance squared from the key to the current value is 
	// greater than the nearest distance, we need only look
	// in one direction.
	if (ndistsq > cdistsq) {
		if (node->key > pnt[dim])
		CheckNeighborFattyCells(node->leftIdx, (dim + 1) % ndim, pnt, cdistsq, &node);
		else
		CheckNeighborFattyCells(node->rightIdx, (dim + 1) % ndim, pnt, cdistsq, &node);
	}
	// If the distance from the key to the current value is 
	// less than the nearest distance, we still need to look
	// in both directions.
	else {
		CheckNeighborFattyCells(node->leftIdx, (dim + 1) % ndim, pnt, cdistsq, &node);
		CheckNeighborFattyCells(node->rightIdx, (dim + 1) % ndim, pnt, cdistsq, &node);
	}
	return 0;

}
Пример #10
0
int KDTree::check_border_distance(int nodeIdx, int dim,
				  float *pnt, float &cdistsq, int &idx)
{
	if(nodeIdx < 0) return 0;

  // Are we at a closer leaf node?  
  // If so, check the distance
	struct KDTreeNode *node = m_Root+nodeIdx;
  if (node->pntidx >= 0) {
    float dsq = distsq(pnt, points+node->pntidx*ndim);
    if (dsq < cdistsq) {
      cdistsq = dsq;
      idx = node->pntidx;
    }
    return 0;
  }

  // The distance squared along the current dimension between the
  // point and the key
  float ndistsq = 
    (node->key - pnt[dim])*(node->key - pnt[dim]);

  // If the distance squared from the key to the current value is 
  // greater than the nearest distance, we need only look
  // in one direction.
  if (ndistsq > cdistsq) {
    if (node->key > pnt[dim])
      check_border_distance(node->leftIdx, (dim + 1) % ndim, pnt, cdistsq, idx);
    else
      check_border_distance(node->rightIdx, (dim + 1) % ndim, pnt, cdistsq, idx);
  }
  // If the distance from the key to the current value is 
  // less than the nearest distance, we still need to look
  // in both directions.
  else {
    check_border_distance(node->leftIdx, (dim + 1) % ndim, pnt, cdistsq, idx);
    check_border_distance(node->rightIdx, (dim + 1) % ndim, pnt, cdistsq, idx);
  }
  return 0;
} // end of check_border_distance
Пример #11
0
static void check_scale(quadbuilder_t* qb, pquad_t* pq) {
	double *sA, *sB;
	double s2;
	double Bx=0, By=0;
	double invscale;
	double ABx, ABy;
	Unused anbool ok;
	if (!(qb->check_scale_low || qb->check_scale_high))
		return;
	sA = qb->starxyz + pq->iA * 3;
	sB = qb->starxyz + pq->iB * 3;
	// s2: squared AB dist
	s2 = distsq(sA, sB, 3);
	pq->scale_ok = TRUE;
	if (qb->check_scale_low && s2 < qb->quadd2_low)
		pq->scale_ok = FALSE;
	if (pq->scale_ok && qb->check_scale_high && s2 > qb->quadd2_high)
		pq->scale_ok = FALSE;
	if (!pq->scale_ok) {
		qb->nbadscale++;
		return;
	}
	star_midpoint(pq->midAB, sA, sB);
	pq->scale_ok = TRUE;
	pq->staridA = qb->starinds[pq->iA];
	pq->staridB = qb->starinds[pq->iB];
	ok = star_coords(sA, pq->midAB, TRUE, &pq->Ay, &pq->Ax);
	assert(ok);
	ok = star_coords(sB, pq->midAB, TRUE, &By, &Bx);
	assert(ok);
	ABx = Bx - pq->Ax;
	ABy = By - pq->Ay;
	invscale = 1.0 / (ABx*ABx + ABy*ABy);
	pq->costheta = (ABy + ABx) * invscale;
	pq->sintheta = (ABy - ABx) * invscale;
	//nabok++;
}
Пример #12
0
void bruteforcesphere(const double *xp,
                      const double *yp,
                      const double *zp,
		               int  numpoints,
                      const double& search_x,
                      const double& search_y,
                      const double& search_z,
                      const double& radius,
                      std::deque<int>& nbrlist )
{

for (int i = 0; i <  numpoints; ++i)
  {
    double distance_squared_to_search_pt =  distsq( xp[i] , yp[i], zp[i], search_x, search_y, search_z);
   //Check if point lies within the sphere. Ensure that the point does not count itself as its own neighbour!
    if (    (distance_squared_to_search_pt < radius*radius) && (distance_squared_to_search_pt > 0)   )
      {
     	  	nbrlist.push_back(i);
      } 
    
  }//end for


}//end function bruteforce sphere.
Пример #13
0
// ************************************************************************
// Takes a line specified by a point and slope and
// returns the end points of the line segment that is inside
// a specified clipping rectangle.
// Assumes clip[0].x < clip[1].x and clip[0].y < clip[1].y
// Assumes the line passes through the clipping rectangle.
// ************************************************************************
void
extend_line(Fpoint origin,		// A point on the line
	    Fpoint slope,		// The slope of the line
	    Fpoint *clip,		// Two corners of clipping rectangle
	    Fpoint *endpts)		// Returns the two end points
{
    int i;
    int endindex = 0;
    // Prepare to find up to four end points.  (If the line passes
    // through two opposite corners of the clip rectangle, we find
    // each end point twice.)
    Fpoint end[4];

    // First, deal with special cases of vertical and horizontal lines.
    if (slope.x == 0){
	endpts[0].x = endpts[1].x = origin.x;
	endpts[0].y = clip[0].y;
	endpts[1].y = clip[1].y;
	return;
    }

    if (slope.y == 0){
	endpts[0].y = endpts[1].y = origin.y;
	endpts[0].x = clip[0].x;
	endpts[1].x = clip[1].x;
	return;
    }

    // Now deal with the general case.
    float xcut, ycut;
    for (i=0; i<2; i++){
	xcut = origin.x + (clip[i].y - origin.y) * slope.x / slope.y;
	if (xcut >= clip[0].x && xcut <= clip[1].x){
	    // Line crosses the y clip line between the x clip lines.
	    end[endindex].x = xcut;
	    end[endindex].y = clip[i].y;
	    endindex++;
	}
	ycut = origin.y + (clip[i].x - origin.x) * slope.y / slope.x;
	if (ycut >= clip[0].y && ycut <= clip[1].y){
	    end[endindex].x = clip[i].x;
	    end[endindex].y = ycut;
	    endindex++;
	}
    }
    if (endindex == 0){
	// Line does not intersect clip rectangle.
	msgerr_print("Internal error in extend_line()");
	end[0].x = end[0].y = 0;
    }
    endpts[0] = end[0];
    if (endindex <= 1){
	endpts[1] = endpts[0];
    }else{
	// We have found more than one end point.
	// We will return the first one, and the one that is farthest from
	// that one.
	float t;
	endpts[1] = end[1];
	float d = distsq(end[0], end[1]);
	for (i=2; i<endindex; i++){
	    if ( (t=distsq(end[0], end[i])) > d){
		d = t;
		endpts[1] = end[i];
	    }
	}
    }
    return;
}
Пример #14
0
int main(int argc, char** args) {
    int argchar;
	char* basename;
	char* outfn = NULL;
	index_t* index;
	quadfile* qf;
    rdlist_t* rdls;
	startree_t* skdt = NULL;
    anbool addradius = FALSE;
	int i;
    int radcolumn = -1;

    while ((argchar = getopt (argc, args, OPTIONS)) != -1)
        switch (argchar) {
        case 'R':
            addradius = TRUE;
            break;
		case 'r':
			outfn = optarg;
			break;
		case 'h':
			print_help(args[0]);
			exit(0);
		}

	if (!outfn || (optind == argc)) {
		print_help(args[0]);
		exit(-1);
	}

    rdls = rdlist_open_for_writing(outfn);
    if (!rdls) {
        fprintf(stderr, "Failed to open RDLS file %s for output.\n", outfn);
        exit(-1);
    }
    if (rdlist_write_primary_header(rdls)) {
        fprintf(stderr, "Failed to write RDLS header.\n");
        exit(-1);
    }

    if (addradius) {
        radcolumn = rdlist_add_tagalong_column(rdls, fitscolumn_double_type(),
                                               1, fitscolumn_double_type(),
                                               "QUADRADIUS", "deg");
    }

	for (; optind<argc; optind++) {
		//int Nstars;
        int dimquads;

		basename = args[optind];
		printf("Reading files with basename %s\n", basename);

		index = index_load(basename, 0, NULL);
		if (!index) {
			fprintf(stderr, "Failed to read index with base name \"%s\"\n", basename);
			exit(-1);
		}

		qf = index->quads;
        skdt = index->starkd;
        //Nstars = startree_N(skdt);
        
        if (rdlist_write_header(rdls)) {
            fprintf(stderr, "Failed to write new RDLS field header.\n");
            exit(-1);
        }

        dimquads = quadfile_dimquads(qf);

		printf("Reading quads...\n");
		for (i=0; i<qf->numquads; i++) {
			unsigned int stars[dimquads];
            double axyz[3], bxyz[3];
            double midab[3];
            double radec[2];
			if (!(i % 200000)) {
				printf(".");
				fflush(stdout);
			}
			quadfile_get_stars(qf, i, stars);
            startree_get(skdt, stars[0], axyz);
            startree_get(skdt, stars[1], bxyz);
            star_midpoint(midab, axyz, bxyz);
            xyzarr2radecdegarr(midab, radec);

            if (rdlist_write_one_radec(rdls, radec[0], radec[1])) {
                fprintf(stderr, "Failed to write a RA,Dec entry.\n");
                exit(-1);
            }

            if (addradius) {
                double rad = arcsec2deg(distsq2arcsec(distsq(midab, axyz, 3)));
                if (rdlist_write_tagalong_column(rdls, radcolumn, i, 1, &rad, 0)) {
                    fprintf(stderr, "Failed to write quad radius.\n");
                    exit(-1);
                }
            }
		}
		printf("\n");

		index_close(index);

        if (rdlist_fix_header(rdls)) {
            fprintf(stderr, "Failed to fix RDLS field header.\n");
            exit(-1);
        }

		rdlist_next_field(rdls);
	}

    if (rdlist_fix_primary_header(rdls) ||
        rdlist_close(rdls)) {
        fprintf(stderr, "Failed to close RDLS file.\n");
        exit(-1);
    }

	return 0;
}
Пример #15
0
int main(int argc, char** args) {
	int c;
	char* xylsfn = NULL;
	char* wcsfn = NULL;
	char* rdlsfn = NULL;

	xylist_t* xyls = NULL;
	rdlist_t* rdls = NULL;
	sip_t sip;
	int i, j;
	int W, H;
	//double xyzcenter[3];
	//double fieldrad2;
	double pixeljitter = 1.0;
    int loglvl = LOG_MSG;
	double wcsscale;

	char* bgfn = NULL;

	//double nsigma = 3.0;

	fits_use_error_system();

    while ((c = getopt(argc, args, OPTIONS)) != -1) {
        switch (c) {
		case 'I':
			bgfn = optarg;
			break;
		case 'j':
			pixeljitter = atof(optarg);
			break;
        case 'h':
			print_help(args[0]);
			exit(0);
		case 'r':
			rdlsfn = optarg;
			break;
		case 'x':
			xylsfn = optarg;
			break;
		case 'w':
			wcsfn = optarg;
			break;
        case 'v':
            loglvl++;
            break;
		}
	}
	if (optind != argc) {
		print_help(args[0]);
		exit(-1);
	}
	if (!xylsfn || !wcsfn || !rdlsfn) {
		print_help(args[0]);
		exit(-1);
	}
    log_init(loglvl);

	// read WCS.
	logmsg("Trying to parse SIP header from %s...\n", wcsfn);
	if (!sip_read_header_file(wcsfn, &sip)) {
		logmsg("Failed to parse SIP header from %s.\n", wcsfn);
	}
	// image W, H
	W = sip.wcstan.imagew;
	H = sip.wcstan.imageh;
	if ((W == 0.0) || (H == 0.0)) {
		logmsg("WCS file %s didn't contain IMAGEW and IMAGEH headers.\n", wcsfn);
		// FIXME - use bounds of xylist?
		exit(-1);
	}
	wcsscale = sip_pixel_scale(&sip);
	logmsg("WCS scale: %g arcsec/pixel\n", wcsscale);

	// read XYLS.
	xyls = xylist_open(xylsfn);
	if (!xyls) {
		logmsg("Failed to read an xylist from file %s.\n", xylsfn);
		exit(-1);
	}

	// read RDLS.
	rdls = rdlist_open(rdlsfn);
	if (!rdls) {
		logmsg("Failed to read an rdlist from file %s.\n", rdlsfn);
		exit(-1);
	}

	// Find field center and radius.
	/*
	 sip_pixelxy2xyzarr(&sip, W/2, H/2, xyzcenter);
	 fieldrad2 = arcsec2distsq(sip_pixel_scale(&sip) * hypot(W/2, H/2));
	 */

	{
        // (x,y) positions of field stars.
		double* fieldpix;
		int Nfield;
		double* indexpix;
		starxy_t* xy;
		rd_t* rd;
		int Nindex;

        xy = xylist_read_field(xyls, NULL);
        if (!xy) {
			logmsg("Failed to read xyls entries.\n");
			exit(-1);
        }
        Nfield = starxy_n(xy);
        fieldpix = starxy_to_xy_array(xy, NULL);
		logmsg("Found %i field objects\n", Nfield);

		// Project RDLS into pixel space.
        rd = rdlist_read_field(rdls, NULL);
        if (!rd) {
			logmsg("Failed to read rdls entries.\n");
			exit(-1);
        }
		Nindex = rd_n(rd);
		logmsg("Found %i indx objects\n", Nindex);
		indexpix = malloc(2 * Nindex * sizeof(double));
		for (i=0; i<Nindex; i++) {
			anbool ok;
			double ra = rd_getra(rd, i);
			double dec = rd_getdec(rd, i);
			ok = sip_radec2pixelxy(&sip, ra, dec, indexpix + i*2, indexpix + i*2 + 1);
			assert(ok);
		}

		logmsg("CRPIX is (%g,%g)\n", sip.wcstan.crpix[0], sip.wcstan.crpix[1]);

		/*

		 // ??
		 // Look for index-field pairs that are (a) close together; and (b) close to CRPIX.

		 // Split the image into 3x3, 5x5 or so, and in each, look for a
		 // (small) rotation and log(scale), then (bigger) shift, using histogram
		 // cross-correlation.

		 // Are the rotations and scales really going to be big enough that this
		 // is required, or can we get away with doing shift first, then fine-tuning
		 // rotation and scale?

		 {
		 // NxN blocks
		 int NB = 3;
		 int b;
		 // HACK - use histogram2d machinery to split image into blocks.
		 histogram2d* blockhist = histogram2d_new_nbins(0, W, NB, 0, H, NB);
		 int* fieldi = malloc(Nfield * sizeof(int));
		 int* indexi = malloc(Nindex * sizeof(int));
		 // rotation bins
		 int NR = 100;
		 // scale bins (ie, log(radius) bins)
		 double minrad = 1.0;
		 double maxrad = 200.0;
		 int NS = 100;
		 histogram2d* rsfield = histogram2d_new_nbins(-M_PI, M_PI, NR,
		 log(minrad), log(maxrad), NS);
		 histogram2d* rsindex = histogram2d_new_nbins(-M_PI, M_PI, NR,
		 log(minrad), log(maxrad), NS);
		 histogram2d_set_y_edges(rsfield, HIST2D_DISCARD);
		 histogram2d_set_y_edges(rsindex, HIST2D_DISCARD);

		 for (b=0; b<(NB*NB); b++) {
		 int bin;
		 int NF, NI;
		 double dx, dy;
		 NF = NI = 0;
		 for (i=0; i<Nfield; i++) {
		 bin = histogram2d_add(blockhist, fieldpix[2*i], fieldpix[2*i+1]);
		 if (bin != b)
		 continue;
		 fieldi[NF] = i;
		 NF++;
		 }

		 for (i=0; i<Nindex; i++) {
		 bin = histogram2d_add(blockhist, indexpix[2*i], indexpix[2*i+1]);
		 if (bin != b)
		 continue;
		 indexi[NI] = i;
		 NI++;
		 }
		 logmsg("bin %i has %i field and %i index stars.\n", b, NF, NI);

		 logmsg("histogramming field rotation/scale\n");
		 for (i=0; i<NF; i++) {
		 for (j=0; j<i; j++) {
		 dx = fieldpix[2*fieldi[i]] - fieldpix[2*fieldi[j]];
		 dy = fieldpix[2*fieldi[i]+1] - fieldpix[2*fieldi[j]+1];
		 histogram2d_add(rsfield, atan2(dy, dx), log(sqrt(dx*dx + dy*dy)));
		 }
		 }
		 logmsg("histogramming index rotation/scale\n");
		 for (i=0; i<NI; i++) {
		 for (j=0; j<i; j++) {
		 dx = indexpix[2*indexi[i]] - fieldpix[2*indexi[j]];
		 dy = indexpix[2*indexi[i]+1] - fieldpix[2*indexi[j]+1];
		 histogram2d_add(rsindex, atan2(dy, dx), log(sqrt(dx*dx + dy*dy)));
		 }
		 }


		 }
		 histogram2d_free(rsfield);
		 histogram2d_free(rsindex);
		 free(fieldi);
		 free(indexi);
		 histogram2d_free(blockhist);
		 }
		 */

		{
			double* fieldsigma2s = malloc(Nfield * sizeof(double));
			int besti;
			int* theta;
			double logodds;
			double Q2, R2;
			double qc[2];
			double gamma;

			// HACK -- quad radius-squared
			Q2 = square(100.0);
			qc[0] = sip.wcstan.crpix[0];
			qc[1] = sip.wcstan.crpix[1];
			// HACK -- variance growth rate wrt radius.
			gamma = 1.0;

			for (i=0; i<Nfield; i++) {
				R2 = distsq(qc, fieldpix + 2*i, 2);
				fieldsigma2s[i] = square(pixeljitter) * (1.0 + gamma * R2/Q2);
			}

			logodds = verify_star_lists(indexpix, Nindex,
										fieldpix, fieldsigma2s, Nfield,
										W*H,
										0.25,
										log(1e-100),
										log(1e100),
										&besti, NULL, &theta, NULL, NULL);

			logmsg("Logodds: %g\n", logodds);

			if (bgfn) {
				plot_args_t pargs;
				plotimage_t* img;
				cairo_t* cairo;
				char outfn[32];

				j = 0;
				
				plotstuff_init(&pargs);
				pargs.outformat = PLOTSTUFF_FORMAT_PNG;
				sprintf(outfn, "tweak-%03i.png", j);
				pargs.outfn = outfn;
				img = plotstuff_get_config(&pargs, "image");
				//img->format = PLOTSTUFF_FORMAT_JPG; // guess
				plot_image_set_filename(img, bgfn);
				plot_image_setsize(&pargs, img);
				plotstuff_run_command(&pargs, "image");
				cairo = pargs.cairo;
				// red circles around every field star.
				cairo_set_color(cairo, "red");
				for (i=0; i<Nfield; i++) {
					cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE,
										   fieldpix[2*i+0], fieldpix[2*i+1],
										   2.0 * sqrt(fieldsigma2s[i]));
					cairo_stroke(cairo);
				}
				// green crosshairs at every index star.
				cairo_set_color(cairo, "green");
				for (i=0; i<Nindex; i++) {
					cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR,
										   indexpix[2*i+0], indexpix[2*i+1],
										   3);
					cairo_stroke(cairo);
				}

				// thick white circles for corresponding field stars.
				cairo_set_line_width(cairo, 2);
				for (i=0; i<Nfield; i++) {
					if (theta[i] < 0)
						continue;
					cairo_set_color(cairo, "white");
					cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE,
										   fieldpix[2*i+0], fieldpix[2*i+1],
										   2.0 * sqrt(fieldsigma2s[i]));
					cairo_stroke(cairo);
					// thick cyan crosshairs for corresponding index stars.
					cairo_set_color(cairo, "cyan");
					cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR,
										   indexpix[2*theta[i]+0],
										   indexpix[2*theta[i]+1],
										   3);
					cairo_stroke(cairo);
					
				}

				plotstuff_output(&pargs);
			}


			free(theta);
			free(fieldsigma2s);
		}


		free(fieldpix);
		free(indexpix);
	}



	if (xylist_close(xyls)) {
		logmsg("Failed to close XYLS file.\n");
	}
	return 0;
}
Пример #16
0
int main(int argc, char** args) {
    int c;
    char* xylsfn = NULL;
    char* wcsfn = NULL;
    char* rdlsfn = NULL;
    char* plotfn = NULL;

    xylist_t* xyls = NULL;
    rdlist_t* rdls = NULL;
    sip_t sip;
    int i;
    int W, H;
    double pixeljitter = 1.0;
    int loglvl = LOG_MSG;
    double wcsscale;

    fits_use_error_system();

    while ((c = getopt(argc, args, OPTIONS)) != -1) {
        switch (c) {
        case 'p':
            plotfn = optarg;
            break;
        case 'j':
            pixeljitter = atof(optarg);
            break;
        case 'h':
            print_help(args[0]);
            exit(0);
        case 'r':
            rdlsfn = optarg;
            break;
        case 'x':
            xylsfn = optarg;
            break;
        case 'w':
            wcsfn = optarg;
            break;
        case 'v':
            loglvl++;
            break;
        }
    }
    if (optind != argc) {
        print_help(args[0]);
        exit(-1);
    }
    if (!xylsfn || !wcsfn || !rdlsfn) {
        print_help(args[0]);
        exit(-1);
    }
    log_init(loglvl);

    // read WCS.
    logmsg("Trying to parse SIP header from %s...\n", wcsfn);
    if (!sip_read_header_file(wcsfn, &sip)) {
        logmsg("Failed to parse SIP header from %s.\n", wcsfn);
    }
    // image W, H
    W = sip.wcstan.imagew;
    H = sip.wcstan.imageh;
    if ((W == 0.0) || (H == 0.0)) {
        logmsg("WCS file %s didn't contain IMAGEW and IMAGEH headers.\n", wcsfn);
        // FIXME - use bounds of xylist?
        exit(-1);
    }
    wcsscale = sip_pixel_scale(&sip);
    logmsg("WCS scale: %g arcsec/pixel\n", wcsscale);

    // read XYLS.
    xyls = xylist_open(xylsfn);
    if (!xyls) {
        logmsg("Failed to read an xylist from file %s.\n", xylsfn);
        exit(-1);
    }

    // read RDLS.
    rdls = rdlist_open(rdlsfn);
    if (!rdls) {
        logmsg("Failed to read an rdlist from file %s.\n", rdlsfn);
        exit(-1);
    }

    {
        // (x,y) positions of field stars.
        double* fieldpix;
        int Nfield;
        double* indexpix;
        starxy_t* xy;
        rd_t* rd;
        int Nindex;

        xy = xylist_read_field(xyls, NULL);
        if (!xy) {
            logmsg("Failed to read xyls entries.\n");
            exit(-1);
        }
        Nfield = starxy_n(xy);
        fieldpix = starxy_to_xy_array(xy, NULL);
        logmsg("Found %i field objects\n", Nfield);

        // Project RDLS into pixel space.
        rd = rdlist_read_field(rdls, NULL);
        if (!rd) {
            logmsg("Failed to read rdls entries.\n");
            exit(-1);
        }
        Nindex = rd_n(rd);
        logmsg("Found %i indx objects\n", Nindex);
        indexpix = malloc(2 * Nindex * sizeof(double));
        for (i=0; i<Nindex; i++) {
            anbool ok;
            double ra = rd_getra(rd, i);
            double dec = rd_getdec(rd, i);
            ok = sip_radec2pixelxy(&sip, ra, dec, indexpix + i*2, indexpix + i*2 + 1);
            assert(ok);
        }

        logmsg("CRPIX is (%g,%g)\n", sip.wcstan.crpix[0], sip.wcstan.crpix[1]);

        {
            double* fieldsigma2s = malloc(Nfield * sizeof(double));
            int besti;
            int* theta;
            double logodds;
            double Q2, R2;
            double qc[2];
            double gamma;

            // HACK -- quad radius-squared
            Q2 = square(100.0);
            qc[0] = sip.wcstan.crpix[0];
            qc[1] = sip.wcstan.crpix[1];
            // HACK -- variance growth rate wrt radius.
            gamma = 1.0;

            for (i=0; i<Nfield; i++) {
                R2 = distsq(qc, fieldpix + 2*i, 2);
                fieldsigma2s[i] = square(pixeljitter) * (1.0 + gamma * R2/Q2);
            }

            logodds = verify_star_lists(indexpix, Nindex,
                                        fieldpix, fieldsigma2s, Nfield,
                                        W*H,
                                        0.25,
                                        log(1e-100),
                                        log(1e100),
                                        &besti, NULL, &theta, NULL);

            logmsg("Logodds: %g\n", logodds);

            if (TRUE) {
                for (i=0; i<Nfield; i++) {
                    if (theta[i] < 0)
                        continue;
                    printf("%g %g %g %g\n", fieldpix[2*i+0], fieldpix[2*i+1],
                           rd_getra(rd, theta[i]), rd_getdec(rd, theta[i]));
                }
            }

            if (plotfn) {
                plot_args_t pargs;
                plotimage_t* img;
                cairo_t* cairo;

                plotstuff_init(&pargs);
                pargs.outformat = PLOTSTUFF_FORMAT_PNG;
                pargs.outfn = plotfn;
                img = plotstuff_get_config(&pargs, "image");
                img->format = PLOTSTUFF_FORMAT_JPG;
                plot_image_set_filename(img, "1.jpg");
                plot_image_setsize(&pargs, img);
                plotstuff_run_command(&pargs, "image");
                cairo = pargs.cairo;
                // red circles around every field star.
                cairo_set_color(cairo, "red");
                for (i=0; i<Nfield; i++) {
                    cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE,
                                           fieldpix[2*i+0], fieldpix[2*i+1],
                                           2.0 * sqrt(fieldsigma2s[i]));
                    cairo_stroke(cairo);
                }
                // green crosshairs at every index star.
                cairo_set_color(cairo, "green");
                for (i=0; i<Nindex; i++) {
                    cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR,
                                           indexpix[2*i+0], indexpix[2*i+1],
                                           3);
                    cairo_stroke(cairo);
                }

                // thick white circles for corresponding field stars.
                cairo_set_line_width(cairo, 2);
                for (i=0; i<Nfield; i++) {
                    if (theta[i] < 0)
                        continue;
                    cairo_set_color(cairo, "white");
                    cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_CIRCLE,
                                           fieldpix[2*i+0], fieldpix[2*i+1],
                                           2.0 * sqrt(fieldsigma2s[i]));
                    cairo_stroke(cairo);
                    // thick cyan crosshairs for corresponding index stars.
                    cairo_set_color(cairo, "cyan");
                    cairoutils_draw_marker(cairo, CAIROUTIL_MARKER_XCROSSHAIR,
                                           indexpix[2*theta[i]+0],
                                           indexpix[2*theta[i]+1],
                                           3);
                    cairo_stroke(cairo);
					
                }

                plotstuff_output(&pargs);
            }

            free(theta);
            free(fieldsigma2s);
        }

        free(fieldpix);
        free(indexpix);
    }



    if (xylist_close(xyls)) {
        logmsg("Failed to close XYLS file.\n");
    }
    return 0;
}
Пример #17
0
int main(int argc, char *argv[]) {
    int argchar;
	char* progname = argv[0];
	sl* infns = sl_new(16);
	char* outfnpat = NULL;
	char* racol = "RA";
	char* deccol = "DEC";
	char* tempdir = "/tmp";
	anbool gzip = FALSE;
	sl* cols = sl_new(16);
	int loglvl = LOG_MSG;
	int nside = 1;
	double margin = 0.0;
	int NHP;
	double md;
	char* backref = NULL;
	
	fitstable_t* intable;
	fitstable_t** outtables;

	char** myargs;
	int nmyargs;
	int i;

    while ((argchar = getopt (argc, argv, OPTIONS)) != -1)
        switch (argchar) {
		case 'b':
			backref = optarg;
			break;
		case 't':
			tempdir = optarg;
			break;
		case 'c':
			sl_append(cols, optarg);
			break;
		case 'g':
			gzip = TRUE;
			break;
		case 'o':
			outfnpat = optarg;
			break;
		case 'r':
			racol = optarg;
			break;
		case 'd':
			deccol = optarg;
			break;
		case 'n':
			nside = atoi(optarg);
			break;
		case 'm':
			margin = atof(optarg);
			break;
		case 'v':
			loglvl++;
			break;
        case '?':
            fprintf(stderr, "Unknown option `-%c'.\n", optopt);
        case 'h':
			printHelp(progname);
            return 0;
        default:
            return -1;
        }

	if (sl_size(cols) == 0) {
		sl_free2(cols);
		cols = NULL;
	}

	nmyargs = argc - optind;
	myargs = argv + optind;

	for (i=0; i<nmyargs; i++)
		sl_append(infns, myargs[i]);
	
	if (!sl_size(infns)) {
		printHelp(progname);
		printf("Need input filenames!\n");
		exit(-1);
	}
	log_init(loglvl);
	fits_use_error_system();

	NHP = 12 * nside * nside;
	logmsg("%i output healpixes\n", NHP);
	outtables = calloc(NHP, sizeof(fitstable_t*));
	assert(outtables);

	md = deg2dist(margin);

	/**
	 About the mincaps/maxcaps:

	 These have a center and radius-squared, describing the region
	 inside a small circle on the sphere.

	 The "mincaps" describe the regions that are definitely owned by a
	 single healpix -- ie, more than MARGIN distance from any edge.
	 That is, the mincap is the small circle centered at (0.5, 0.5) in
	 the healpix and with radius = the distance to the closest healpix
	 boundary, MINUS the margin distance.

	 Below, we first check whether a new star is within the "mincap"
	 of any healpix.  If so, we stick it in that healpix and continue.

	 Otherwise, we check all the "maxcaps" -- these are the healpixes
	 it could *possibly* be in.  We then refine with
	 healpix_within_range_of_xyz.  The maxcap distance is the distance
	 to the furthest boundary point, PLUS the margin distance.
	 */


	cap_t* mincaps = malloc(NHP * sizeof(cap_t));
	cap_t* maxcaps = malloc(NHP * sizeof(cap_t));
	for (i=0; i<NHP; i++) {
		// center
		double r2;
		double xyz[3];
		double* cxyz;
		double step = 1e-3;
		double v;
		double r2b, r2a;

		cxyz = mincaps[i].xyz;
		healpix_to_xyzarr(i, nside, 0.5, 0.5, mincaps[i].xyz);
		memcpy(maxcaps[i].xyz, cxyz, 3 * sizeof(double));
		logverb("Center of HP %i: (%.3f, %.3f, %.3f)\n", i, cxyz[0], cxyz[1], cxyz[2]);

		// radius-squared:
		// max is the easy one: max of the four corners (I assume)
		r2 = 0.0;
		healpix_to_xyzarr(i, nside, 0.0, 0.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		healpix_to_xyzarr(i, nside, 1.0, 0.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		healpix_to_xyzarr(i, nside, 0.0, 1.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		healpix_to_xyzarr(i, nside, 1.0, 1.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		logverb("  max distsq: %.3f\n", r2);
		logverb("  margin dist: %.3f\n", md);
		maxcaps[i].r2 = square(sqrt(r2) + md);
		logverb("  max cap distsq: %.3f\n", maxcaps[i].r2);
		r2a = r2;

		r2 = 1.0;
		r2b = 0.0;
		for (v=0; v<=1.0; v+=step) {
			healpix_to_xyzarr(i, nside, 0.0, v, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
			healpix_to_xyzarr(i, nside, 1.0, v, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
			healpix_to_xyzarr(i, nside, v, 0.0, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
			healpix_to_xyzarr(i, nside, v, 1.0, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
		}
		mincaps[i].r2 = square(MAX(0, sqrt(r2) - md));
		logverb("\nhealpix %i: min rad    %g\n", i, sqrt(r2));
		logverb("healpix %i: max rad    %g\n", i, sqrt(r2a));
		logverb("healpix %i: max rad(b) %g\n", i, sqrt(r2b));
		assert(r2a >= r2b);
	}

	if (backref) {
		fitstable_t* tab = fitstable_open_for_writing(backref);
		int maxlen = 0;
		char* buf;
		for (i=0; i<sl_size(infns); i++) {
			char* infn = sl_get(infns, i);
			maxlen = MAX(maxlen, strlen(infn));
		}
		fitstable_add_write_column_array(tab, fitscolumn_char_type(), maxlen,
										 "filename", NULL);
		fitstable_add_write_column(tab, fitscolumn_i16_type(), "index", NULL);
		if (fitstable_write_primary_header(tab) ||
			fitstable_write_header(tab)) {
			ERROR("Failed to write header of backref table \"%s\"", backref);
			exit(-1);
		}
		buf = malloc(maxlen+1);
		assert(buf);

		for (i=0; i<sl_size(infns); i++) {
			char* infn = sl_get(infns, i);
			int16_t ind;
			memset(buf, 0, maxlen);
			strcpy(buf, infn);
			ind = i;
			if (fitstable_write_row(tab, buf, &ind)) {
				ERROR("Failed to write row %i of backref table: %s = %i",
					  i, buf, ind);
				exit(-1);
			}
		}
		if (fitstable_fix_header(tab) ||
			fitstable_close(tab)) {
			ERROR("Failed to fix header & close backref table");
			exit(-1);
		}
		logmsg("Wrote backref table %s\n", backref);
		free(buf);
	}

	for (i=0; i<sl_size(infns); i++) {
		char* infn = sl_get(infns, i);
		char* originfn = infn;
		int r, NR;
		tfits_type any, dubl;
		il* hps = NULL;
		bread_t* rowbuf;
		int R;
		char* tempfn = NULL;
		char* padrowdata = NULL;
		int ii;

		logmsg("Reading input \"%s\"...\n", infn);

		if (gzip) {
			char* cmd;
			int rtn;
			tempfn = create_temp_file("hpsplit", tempdir);
			asprintf_safe(&cmd, "gunzip -cd %s > %s", infn, tempfn);
			logmsg("Running: \"%s\"\n", cmd);
			rtn = run_command_get_outputs(cmd, NULL, NULL);
			if (rtn) {
				ERROR("Failed to run command: \"%s\"", cmd);
				exit(-1);
			}
			free(cmd);
			infn = tempfn;
		}

		intable = fitstable_open(infn);
		if (!intable) {
			ERROR("Couldn't read catalog %s", infn);
			exit(-1);
		}
		NR = fitstable_nrows(intable);
		logmsg("Got %i rows\n", NR);

		any = fitscolumn_any_type();
		dubl = fitscolumn_double_type();

		fitstable_add_read_column_struct(intable, dubl, 1, 0, any, racol, TRUE);
		fitstable_add_read_column_struct(intable, dubl, 1, sizeof(double), any, deccol, TRUE);

		fitstable_use_buffered_reading(intable, 2*sizeof(double), 1000);

		R = fitstable_row_size(intable);
		rowbuf = buffered_read_new(R, 1000, NR, refill_rowbuffer, intable);

		if (fitstable_read_extension(intable, 1)) {
			ERROR("Failed to find RA and DEC columns (called \"%s\" and \"%s\" in the FITS file)", racol, deccol);
			exit(-1);
		}

		for (r=0; r<NR; r++) {
			int hp = -1;
			double ra, dec;
			int j;
			double* rd;
			void* rowdata;
			void* rdata;

			if (r && ((r % 100000) == 0)) {
			  logmsg("Reading row %i of %i\n", r, NR);
			}

			//printf("reading RA,Dec for row %i\n", r);
			rd = fitstable_next_struct(intable);
			ra = rd[0];
			dec = rd[1];

			logverb("row %i: ra,dec %g,%g\n", r, ra, dec);
			if (margin == 0) {
				hp = radecdegtohealpix(ra, dec, nside);
				logverb("  --> healpix %i\n", hp);
			} else {

				double xyz[3];
				anbool gotit = FALSE;
				double d2;
				if (!hps)
					hps = il_new(4);
				radecdeg2xyzarr(ra, dec, xyz);
				for (j=0; j<NHP; j++) {
					d2 = distsq(xyz, mincaps[j].xyz, 3);
					if (d2 <= mincaps[j].r2) {
						logverb("  -> in mincap %i  (dist %g vs %g)\n", j, sqrt(d2), sqrt(mincaps[j].r2));
						il_append(hps, j);
						gotit = TRUE;
						break;
					}
				}
				if (!gotit) {
					for (j=0; j<NHP; j++) {
						d2 = distsq(xyz, maxcaps[j].xyz, 3);
						if (d2 <= maxcaps[j].r2) {
							logverb("  -> in maxcap %i  (dist %g vs %g)\n", j, sqrt(d2), sqrt(maxcaps[j].r2));
							if (healpix_within_range_of_xyz(j, nside, xyz, margin)) {
								logverb("  -> and within range.\n");
								il_append(hps, j);
							}
						}
					}
				}

				//hps = healpix_rangesearch_radec(ra, dec, margin, nside, hps);

				logverb("  --> healpixes: [");
				for (j=0; j<il_size(hps); j++)
					logverb(" %i", il_get(hps, j));
				logverb(" ]\n");
			}

			//printf("Reading rowdata for row %i\n", r);
			rowdata = buffered_read(rowbuf);
			assert(rowdata);


			j=0;
			while (1) {
				if (hps) {
					if (j >= il_size(hps))
						break;
					hp = il_get(hps, j);
					j++;
				}
				assert(hp < NHP);
				assert(hp >= 0);

				if (!outtables[hp]) {
					char* outfn;
					fitstable_t* out;

					// MEMLEAK the output filename.  You'll live.
					asprintf_safe(&outfn, outfnpat, hp);
					logmsg("Opening output file \"%s\"...\n", outfn);
					out = fitstable_open_for_writing(outfn);
					if (!out) {
						ERROR("Failed to open output table \"%s\"", outfn);
						exit(-1);
					}
					// Set the output table structure.
					if (cols) {
					  fitstable_add_fits_columns_as_struct3(intable, out, cols, 0);
					} else
						fitstable_add_fits_columns_as_struct2(intable, out);

					if (backref) {
						tfits_type i16type;
						tfits_type i32type;
						// R = fitstable_row_size(intable);
						int off = R;
						i16type = fitscolumn_i16_type();
						i32type = fitscolumn_i32_type();
						fitstable_add_read_column_struct(out, i16type, 1, off,
														 i16type, "backref_file", TRUE);
						off += sizeof(int16_t);
						fitstable_add_read_column_struct(out, i32type, 1, off,
														 i32type, "backref_index", TRUE);
					}

					//printf("Output table:\n");
					//fitstable_print_columns(out);

					if (fitstable_write_primary_header(out) ||
						fitstable_write_header(out)) {
						ERROR("Failed to write output file headers for \"%s\"", outfn);
						exit(-1);
					}
					outtables[hp] = out;
				}

				if (backref) {
					int16_t brfile;
					int32_t brind;
					if (!padrowdata) {
						padrowdata = malloc(R + sizeof(int16_t) + sizeof(int32_t));
						assert(padrowdata);
					}
					// convert to FITS endian
					brfile = htons(i);
					brind  = htonl(r);
					// add backref data to rowdata
					memcpy(padrowdata, rowdata, R);
					memcpy(padrowdata + R, &brfile, sizeof(int16_t));
					memcpy(padrowdata + R + sizeof(int16_t), &brind, sizeof(int32_t));
					rdata = padrowdata;
				} else {
					rdata = rowdata;
				}

				if (cols) {
				  if (fitstable_write_struct_noflip(outtables[hp], rdata)) {
				    ERROR("Failed to copy a row of data from input table \"%s\" to output healpix %i", infn, hp);
				  }
				} else {
				  if (fitstable_write_row_data(outtables[hp], rdata)) {
				    ERROR("Failed to copy a row of data from input table \"%s\" to output healpix %i", infn, hp);
				  }
				}

				if (!hps)
					break;
			}
			if (hps)
				il_remove_all(hps);

		}
		buffered_read_free(rowbuf);
		// wack... buffered_read_free() just frees its internal buffer,
		// not the "rowbuf" struct itself.
		// who wrote this crazy code?  Oh, me of 5 years ago.  Jerk.
		free(rowbuf);

		fitstable_close(intable);
		il_free(hps);

		if (tempfn) {
			logverb("Removing temp file %s\n", tempfn);
			if (unlink(tempfn)) {
				SYSERROR("Failed to unlink() temp file \"%s\"", tempfn);
			}
			tempfn = NULL;
		}

		// fix headers so that the files are valid at this point.
		for (ii=0; ii<NHP; ii++) {
		  if (!outtables[ii])
		    continue;
		  off_t offset = ftello(outtables[ii]->fid);
		  if (fitstable_fix_header(outtables[ii])) {
		    ERROR("Failed to fix header for healpix %i after reading input file \"%s\"", ii, originfn);
		    exit(-1);
		  }
		  fseeko(outtables[ii]->fid, offset, SEEK_SET);
		}

		if (padrowdata) {
			free(padrowdata);
			padrowdata = NULL;
		}

	}

	for (i=0; i<NHP; i++) {
		if (!outtables[i])
			continue;
		if (fitstable_fix_header(outtables[i]) ||
			fitstable_fix_primary_header(outtables[i]) ||
			fitstable_close(outtables[i])) {
			ERROR("Failed to close output table for healpix %i", i);
			exit(-1);
		}
	}

	free(outtables);
	sl_free2(infns);
	sl_free2(cols);

	free(mincaps);
	free(maxcaps);

    return 0;
}
Пример #18
0
static void plot_constellations(cairo_t* cairo, plot_args_t* pargs, plotann_t* ann) {
	int i, N;
	double ra,dec,radius;
	double xyzf[3];
	// Find the field center and radius
	anwcs_get_radec_center_and_radius(pargs->wcs, &ra, &dec, &radius);
	logverb("Plotting constellations: field center %g,%g, radius %g\n",
			ra, dec, radius);
	radecdeg2xyzarr(ra, dec, xyzf);
	radius = deg2dist(radius);

	N = constellations_n();
	for (i=0; i<N; i++) {
		int j, k;
		// Find the approximate center and radius of this constellation
		// and see if it overlaps with the field.
		il* stars = constellations_get_unique_stars(i);
		double xyzj[3];
		double xyzc[3];
		double maxr2 = 0;
		dl* rds;
		xyzc[0] = xyzc[1] = xyzc[2] = 0.0;
		xyzj[0] = xyzj[1] = xyzj[2] = 0.0;
		for (j=0; j<il_size(stars); j++) {
			constellations_get_star_radec(il_get(stars, j), &ra, &dec);
			radecdeg2xyzarr(ra, dec, xyzj);
			for (k=0; k<3; k++)
				xyzc[k] += xyzj[k];
		}
		normalize_3(xyzc);
		for (j=0; j<il_size(stars); j++) {
			constellations_get_star_radec(il_get(stars, j), &ra, &dec);
			maxr2 = MAX(maxr2, distsq(xyzc, xyzj, 3));
		}
		il_free(stars);
		maxr2 = square(sqrt(maxr2) + radius);
		if (distsq(xyzf, xyzc, 3) > maxr2) {
			xyzarr2radecdeg(xyzc, &ra, &dec);
			logverb("Constellation %s (center %g,%g, radius %g) out of bounds\n",
					constellations_get_shortname(i), ra, dec,
					dist2deg(sqrt(maxr2) - radius));
			logverb("  dist from field center to constellation center is %g deg\n",
					distsq2deg(distsq(xyzf, xyzc, 3)));
			logverb("  max radius: %g\n", distsq2deg(maxr2));
			continue;
		}

        if (ann->constellation_pastel) {
            float r,g,b;
            xyzarr2radecdeg(xyzc, &ra, &dec);
            color_for_radec(ra, dec, &r,&g,&b);
            plotstuff_set_rgba2(pargs, r,g,b, 0.8);
            plotstuff_builtin_apply(cairo, pargs);
        }

		// Phew, plot it.
		if (ann->constellation_lines) {
			rds = constellations_get_lines_radec(i);
			logverb("Constellation %s: plotting %zu lines\n",
					constellations_get_shortname(i), dl_size(rds)/4);
			for (j=0; j<dl_size(rds)/4; j++) {
				double r1,d1,r2,d2;
				double r3,d3,r4,d4;
                double off = ann->constellation_lines_offset;
				r1 = dl_get(rds, j*4+0);
				d1 = dl_get(rds, j*4+1);
				r2 = dl_get(rds, j*4+2);
				d2 = dl_get(rds, j*4+3);
				if (anwcs_find_discontinuity(pargs->wcs, r1, d1, r2, d2,
											 &r3, &d3, &r4, &d4)) {
					logverb("Discontinuous: %g,%g -- %g,%g\n", r1, d1, r2, d2);
					logverb("  %g,%g == %g,%g\n", r3,d3, r4,d4);
                    plot_offset_line_rd(NULL, pargs, r1,d1,r3,d3, off, 0.);
                    plot_offset_line_rd(NULL, pargs, r4,d4,r2,d2, 0., off);
				} else {
                    plot_offset_line_rd(NULL, pargs, r1,d1,r2,d2, off, off);
				}
				plotstuff_stroke(pargs);
			}
			dl_free(rds);
		}

		if (ann->constellation_labels ||
			ann->constellation_markers) {
			// Put the label at the center of mass of the stars that
			// are in-bounds
			int Nin = 0;
			stars = constellations_get_unique_stars(i);
			xyzc[0] = xyzc[1] = xyzc[2] = 0.0;
			logverb("Labeling %s: %zu stars\n", constellations_get_shortname(i),
					il_size(stars));
			for (j=0; j<il_size(stars); j++) {
				constellations_get_star_radec(il_get(stars, j), &ra, &dec);
				if (!anwcs_radec_is_inside_image(pargs->wcs, ra, dec))
					continue;
				if (ann->constellation_markers)
					plotstuff_marker_radec(pargs, ra, dec);
				radecdeg2xyzarr(ra, dec, xyzj);
				for (k=0; k<3; k++)
					xyzc[k] += xyzj[k];
				Nin++;
			}
			logverb("  %i stars in-bounds\n", Nin);
			if (ann->constellation_labels && Nin) {
				const char* label;
				normalize_3(xyzc);
				xyzarr2radecdeg(xyzc, &ra, &dec);
				if (ann->constellation_labels_long)
					label = constellations_get_longname(i);
				else
					label = constellations_get_shortname(i);
				plotstuff_text_radec(pargs, ra, dec, label);
			}
			il_free(stars);
		}
	}
}
Пример #19
0
sip_t* tweak2(const double* fieldxy, int Nfield,
			  double fieldjitter,
			  int W, int H,
			  const double* indexradec, int Nindex,
			  double indexjitter,
			  const double* quadcenter, double quadR2,
			  double distractors,
			  double logodds_bail,
			  int sip_order,
			  int sip_invorder,
			  const sip_t* startwcs,
			  sip_t* destwcs,
			  int** newtheta, double** newodds,
			  double* crpix,
			  double* p_logodds,
			  int* p_besti,
			  int* testperm,
			  int startorder) {
	int order;
	sip_t* sipout;
	int* indexin;
	double* indexpix;
	double* fieldsigma2s;
	double* weights;
	double* matchxyz;
	double* matchxy;
	int i, Nin=0;
	double logodds = 0;
	int besti = -1;
	int* theta = NULL;
	double* odds = NULL;
	int* refperm = NULL;
	double qc[2];

	memcpy(qc, quadcenter, 2*sizeof(double));

	if (destwcs)
		sipout = destwcs;
	else
		sipout = sip_create();

	indexin = malloc(Nindex * sizeof(int));
	indexpix = malloc(2 * Nindex * sizeof(double));
	fieldsigma2s = malloc(Nfield * sizeof(double));
	weights = malloc(Nfield * sizeof(double));
	matchxyz = malloc(Nfield * 3 * sizeof(double));
	matchxy = malloc(Nfield * 2 * sizeof(double));

	// FIXME --- hmmm, how do the annealing steps and iterating up to
	// higher orders interact?

	assert(startwcs);
	memcpy(sipout, startwcs, sizeof(sip_t));

	logverb("tweak2: starting orders %i, %i\n", sipout->a_order, sipout->ap_order);

	if (!sipout->wcstan.imagew)
		sipout->wcstan.imagew = W;
	if (!sipout->wcstan.imageh)
		sipout->wcstan.imageh = H;

	logverb("Tweak2: starting from WCS:\n");
	if (log_get_level() >= LOG_VERB)
		sip_print_to(sipout, stdout);

	for (order=startorder; order <= sip_order; order++) {
		int step;
		int STEPS = 100;
		// variance growth rate wrt radius.
		double gamma = 1.0;
		//logverb("Starting tweak2 order=%i\n", order);

		for (step=0; step<STEPS; step++) {
			double iscale;
			double ijitter;
			double ra, dec;
			double R2;
			int Nmatch;
			int nmatch, nconf, ndist;
			double pix2;
			double totalweight;

			// clean up from last round (we do it here so that they're
			// valid when we leave the loop)
			free(theta);
			free(odds);
			free(refperm);

			// Anneal
			gamma = pow(0.9, step);
			if (step == STEPS-1)
				gamma = 0.0;
			logverb("Annealing: order %i, step %i, gamma = %g\n", order, step, gamma);
			
			debug("Using input WCS:\n");
			if (log_get_level() > LOG_VERB)
				sip_print_to(sipout, stdout);

			// Project reference sources into pixel space; keep the ones inside image bounds.
			Nin = 0;
			for (i=0; i<Nindex; i++) {
				anbool ok;
				double x,y;
				ra  = indexradec[2*i + 0];
				dec = indexradec[2*i + 1];
				ok = sip_radec2pixelxy(sipout, ra, dec, &x, &y);
				if (!ok)
					continue;
				if (!sip_pixel_is_inside_image(sipout, x, y))
					continue;
				indexpix[Nin*2+0] = x;
				indexpix[Nin*2+1] = y;
				indexin[Nin] = i;
				Nin++;
			}
			logverb("%i reference sources within the image.\n", Nin);
			//logverb("CRPIX is (%g,%g)\n", sip.wcstan.crpix[0], sip.wcstan.crpix[1]);

            if (Nin == 0) {
				sip_free(sipout);
				free(matchxy);
				free(matchxyz);
				free(weights);
				free(fieldsigma2s);
				free(indexpix);
				free(indexin);
                return NULL;
            }

			iscale = sip_pixel_scale(sipout);
			ijitter = indexjitter / iscale;
			//logverb("With pixel scale of %g arcsec/pixel, index adds jitter of %g pix.\n", iscale, ijitter);

			/* CHECK
			 for (i=0; i<Nin; i++) {
			 double x,y;
			 int ii = indexin[i];
			 sip_radec2pixelxy(sipout, indexradec[2*ii+0], indexradec[2*ii+1], &x, &y);
			 logverb("indexin[%i]=%i; (%.1f,%.1f) -- (%.1f,%.1f)\n",
			 i, ii, indexpix[i*2+0], indexpix[i*2+1], x, y);
			 }
			 */

			for (i=0; i<Nfield; i++) {
				R2 = distsq(qc, fieldxy + 2*i, 2);
				fieldsigma2s[i] = (square(fieldjitter) + square(ijitter)) * (1.0 + gamma * R2/quadR2);
			}

			if (order == 1 && step == 0 && TWEAK_DEBUG_PLOTS) {
				TWEAK_DEBUG_PLOT("init", W, H, Nfield, fieldxy, fieldsigma2s,
								 Nin, indexpix, *p_besti, *newtheta,
								 sipout->wcstan.crpix, testperm, qc);
			}

			/*
			 logodds = verify_star_lists(indexpix, Nin,
			 fieldxy, fieldsigma2s, Nfield,
			 W*H, distractors,
			 logodds_bail, HUGE_VAL,
			 &besti, &odds, &theta, NULL,
			 &testperm);
			 */

			pix2 = square(fieldjitter);
			logodds = verify_star_lists_ror(indexpix, Nin,
											fieldxy, fieldsigma2s, Nfield,
											pix2, gamma, qc, quadR2,
											W, H, distractors,
											logodds_bail, HUGE_VAL,
											&besti, &odds, &theta, NULL,
											&testperm, &refperm);

			logverb("Logodds: %g\n", logodds);
			verify_count_hits(theta, besti, &nmatch, &nconf, &ndist);
			logverb("%i matches, %i distractors, %i conflicts (at best log-odds); %i field sources, %i index sources\n", nmatch, ndist, nconf, Nfield, Nin);
			verify_count_hits(theta, Nfield-1, &nmatch, &nconf, &ndist);
			logverb("%i matches, %i distractors, %i conflicts (all sources)\n", nmatch, ndist, nconf);
			if (log_get_level() >= LOG_VERB) {
				matchobj_log_hit_miss(theta, testperm, besti+1, Nfield, LOG_VERB, "Hit/miss: ");
			}

			/*
			 logverb("\nAfter verify():\n");
			 for (i=0; i<Nin; i++) {
			 double x,y;
			 int ii = indexin[refperm[i]];
			 sip_radec2pixelxy(sipout, indexradec[2*ii+0], indexradec[2*ii+1], &x, &y);
			 logverb("indexin[%i]=%i; (%.1f,%.1f) -- (%.1f,%.1f)\n",
			 i, ii, indexpix[i*2+0], indexpix[i*2+1], x, y);
			 }
			 */

			if (TWEAK_DEBUG_PLOTS) {
				char name[32];
				sprintf(name, "o%is%02ipre", order, step);
				TWEAK_DEBUG_PLOT(name, W, H, Nfield, fieldxy, fieldsigma2s,
								 Nin, indexpix, besti, theta,
								 sipout->wcstan.crpix, testperm, qc);
			}

			Nmatch = 0;
			debug("Weights:");
			for (i=0; i<Nfield; i++) {
				double ra,dec;
				if (theta[i] < 0)
					continue;
				assert(theta[i] < Nin);
				int ii = indexin[refperm[theta[i]]];
				assert(ii < Nindex);
				assert(ii >= 0);

				ra  = indexradec[ii*2+0];
				dec = indexradec[ii*2+1];
				radecdeg2xyzarr(ra, dec, matchxyz + Nmatch*3);
				memcpy(matchxy + Nmatch*2, fieldxy + i*2, 2*sizeof(double));
				weights[Nmatch] = verify_logodds_to_weight(odds[i]);
				debug(" %.2f", weights[Nmatch]);
				Nmatch++;

				/*
				 logverb("match img (%.1f,%.1f) -- ref (%.1f, %.1f), odds %g, wt %.3f\n",
				 fieldxy[i*2+0], fieldxy[i*2+1],
				 indexpix[theta[i]*2+0], indexpix[theta[i]*2+1],
				 odds[i],
				 weights[Nmatch-1]);
				 double xx,yy;
				 sip_radec2pixelxy(sipout, ra, dec, &xx, &yy);
				 logverb("check: (%.1f, %.1f)\n", xx, yy);
				 */
			}
			debug("\n");

			if (Nmatch < 2) {
				logverb("No matches -- aborting tweak attempt\n");
				free(theta);
				sip_free(sipout);
				free(matchxy);
				free(matchxyz);
				free(weights);
				free(fieldsigma2s);
				free(indexpix);
				free(indexin);
				return NULL;
			}

			// Update the "quad center" to be the weighted average matched star posn.
			qc[0] = qc[1] = 0.0;
			totalweight = 0.0;
			for (i=0; i<Nmatch; i++) {
				qc[0] += (weights[i] * matchxy[2*i+0]);
				qc[1] += (weights[i] * matchxy[2*i+1]);
				totalweight += weights[i];
			}
			qc[0] /= totalweight;
			qc[1] /= totalweight;
			logverb("Moved quad center to (%.1f, %.1f)\n", qc[0], qc[1]);

            //
            sipout->a_order = sipout->b_order = order;
            sipout->ap_order = sipout->bp_order = sip_invorder;
            logverb("tweak2: setting orders %i, %i\n", sipout->a_order, sipout->ap_order);

            if (crpix) {
                tan_t temptan;
                logverb("Moving tangent point to given CRPIX (%g,%g)\n", crpix[0], crpix[1]);
                fit_tan_wcs_move_tangent_point_weighted(matchxyz, matchxy, weights, Nmatch,
                                                        crpix, &sipout->wcstan, &temptan);
                fit_tan_wcs_move_tangent_point_weighted(matchxyz, matchxy, weights, Nmatch,
                                                        crpix, &temptan, &sipout->wcstan);
            }

            int doshift = 1;
            fit_sip_wcs(matchxyz, matchxy, weights, Nmatch,
                        &(sipout->wcstan), order, sip_invorder,
                        doshift, sipout);

            debug("Got SIP:\n");
            if (log_get_level() > LOG_VERB)
                sip_print_to(sipout, stdout);
            sipout->wcstan.imagew = W;
            sipout->wcstan.imageh = H;
		}
	}

	//logverb("Final logodds: %g\n", logodds);

	// Now, recompute final logodds after turning 'gamma' on again (?)
	// FIXME -- this counts the quad stars in the logodds...
	{
		double gamma = 1.0;
		double iscale;
		double ijitter;
		double ra, dec;
		double R2;
		int nmatch, nconf, ndist;
		double pix2;

		free(theta);
		free(odds);
		free(refperm);
		gamma = 1.0;
		// Project reference sources into pixel space; keep the ones inside image bounds.
		Nin = 0;
		for (i=0; i<Nindex; i++) {
			anbool ok;
			double x,y;
			ra  = indexradec[2*i + 0];
			dec = indexradec[2*i + 1];
			ok = sip_radec2pixelxy(sipout, ra, dec, &x, &y);
			if (!ok)
				continue;
			if (!sip_pixel_is_inside_image(sipout, x, y))
				continue;
			indexpix[Nin*2+0] = x;
			indexpix[Nin*2+1] = y;
			indexin[Nin] = i;
			Nin++;
		}
		logverb("%i reference sources within the image.\n", Nin);

		iscale = sip_pixel_scale(sipout);
		ijitter = indexjitter / iscale;
		for (i=0; i<Nfield; i++) {
			R2 = distsq(qc, fieldxy + 2*i, 2);
			fieldsigma2s[i] = (square(fieldjitter) + square(ijitter)) * (1.0 + gamma * R2/quadR2);
		}

		pix2 = square(fieldjitter);
		logodds = verify_star_lists_ror(indexpix, Nin,
										fieldxy, fieldsigma2s, Nfield,
										pix2, gamma, qc, quadR2,
										W, H, distractors,
										logodds_bail, HUGE_VAL,
										&besti, &odds, &theta, NULL,
										&testperm, &refperm);
		logverb("Logodds: %g\n", logodds);
		verify_count_hits(theta, besti, &nmatch, &nconf, &ndist);
		logverb("%i matches, %i distractors, %i conflicts (at best log-odds); %i field sources, %i index sources\n", nmatch, ndist, nconf, Nfield, Nin);
		verify_count_hits(theta, Nfield-1, &nmatch, &nconf, &ndist);
		logverb("%i matches, %i distractors, %i conflicts (all sources)\n", nmatch, ndist, nconf);
		if (log_get_level() >= LOG_VERB) {
			matchobj_log_hit_miss(theta, testperm, besti+1, Nfield, LOG_VERB,
								  "Hit/miss: ");
		}

		if (TWEAK_DEBUG_PLOTS) {
			TWEAK_DEBUG_PLOT("final", W, H, Nfield, fieldxy, fieldsigma2s,
							 Nin, indexpix, besti, theta,
							 sipout->wcstan.crpix, testperm, qc);
		}
	}


	if (newtheta) {
		// undo the "indexpix" inside-image-bounds cut.
		(*newtheta) = malloc(Nfield * sizeof(int));
		for (i=0; i<Nfield; i++) {
			int nt;
			if (theta[i] < 0)
				nt = theta[i];
			else
				nt = indexin[refperm[theta[i]]];
			(*newtheta)[i] = nt;
		}
	}
	free(theta);
	free(refperm);

	if (newodds)
		*newodds = odds;
	else
		free(odds);

	logverb("Tweak2: final WCS:\n");
	if (log_get_level() >= LOG_VERB)
		sip_print_to(sipout, stdout);

	if (p_logodds)
		*p_logodds = logodds;
	if (p_besti)
		*p_besti = besti;

	free(indexin);
	free(indexpix);
	free(fieldsigma2s);
	free(weights);
	free(matchxyz);
	free(matchxy);

	return sipout;
}