LVector LTransform::operator*(const LVector rhs) const { if (_orderIn != rhs.getOrder()) FormatAndThrow<>() << "Order mismatch between LTransform [" << _orderIn << "] and LVector [" << rhs.getOrder() << "]"; boost::shared_ptr<tmv::Vector<double> > out(new tmv::Vector<double>(sizeOut())); *out = (*_m) * rhs.rVector(); return LVector(_orderOut, out); }
STARTDECL(gl_createtexture) (Value &mat) { TestGL(); LVector *cols = mat.vval; int x = cols->len; if (x && cols->at(0).type == V_VECTOR) { int y = cols->at(0).vval->len; if (y) { auto buf = new byte4[x * y]; memset(buf, 0, x * y * 4); for (int i = 0; i < x; i++) if (cols->at(i).type == V_VECTOR) { LVector *row = cols->at(i).vval; for (int j = 0; j < min(y, row->len); j++) { buf[j * x + i] = quantizec(ValueTo<float3>(row->at(j))); } } mat.DECRT(); uint id = CreateTexture((uchar *)buf, x, y); delete[] buf; return Value((int)id); } } mat.DECRT(); return Value(0); }
void makePlane(GeometryBatch &batch, float width, int divisions, bool normals, bool uvs, const LColor *color) { float dx = width / divisions, dy = 0, dz = -width / divisions; float x0 = -width / 2.0f, y0 = 0.0f, z0 = width / 2.0f; LPoint p0(x0, y0, z0); LVector dp(dx, dy, dz); batch.init(GL_TRIANGLE_STRIP, "plane"); for (int strip = 0; strip < divisions; ++strip) { LVector index = LVector(0,0,strip); for (int x = 0; x < divisions+1; ++x) { index.setX(x); LVector index1 = index + LVector(0,0,1); LPoint pb = p0 + index * dp; LPoint pt = p0 + index1 * dp; if (x == 0 && strip > 0 && strip < divisions) { batch.ps.push_back(pt); } batch.ps.push_back(pt); batch.ps.push_back(pb); if (x == divisions && strip < divisions-1) { batch.ps.push_back(pb); } } } if (normals) { batch.ns.assign(batch.ps.size(), LNormal(0,1,0)); } if (uvs) { std::cout << "Plane UV not implemented\n"; } if (color) { batch.cs.assign(batch.ps.size(), *color); } // cout << "plane vertices\n"; // ostream_iterator<LPoint> osi(cout, "\n"); // copy(batch.ps.begin(), batch.ps.end(), osi); }
void ShapeletFitImage(double sigma, LVector& bvec, const BaseImage<T>& image, double image_scale, const Position<double>& center) { // TODO: It would be nice to be able to fit this with an arbitrary WCS to fit in // sky coordinates. For now, just use the image_scale. dbg<<"Start ShapeletFitImage:\n"; xdbg<<"sigma = "<<sigma<<std::endl; xdbg<<"bvec = "<<bvec<<std::endl; xdbg<<"center = "<<center<<std::endl; double scale = image_scale / sigma; xdbg<<"scale = "<<scale<<std::endl; const int nx = image.getXMax() - image.getXMin() + 1; const int ny = image.getYMax() - image.getYMin() + 1; xdbg<<"nx,ny = "<<nx<<','<<ny<<std::endl; const int npts = nx * ny; xdbg<<"npts = "<<npts<<std::endl; tmv::Vector<double> x(npts); tmv::Vector<double> y(npts); tmv::Vector<double> I(npts); int i=0; for (int ix = image.getXMin(); ix <= image.getXMax(); ++ix) { for (int iy = image.getYMin(); iy <= image.getYMax(); ++iy,++i) { x[i] = (ix - center.x) * scale; y[i] = (iy - center.y) * scale; I[i] = image(ix,iy); } } xxdbg<<"x = "<<x<<std::endl; xxdbg<<"y = "<<y<<std::endl; xxdbg<<"I = "<<I<<std::endl; tmv::Matrix<double> psi(npts,bvec.size()); LVector::basis(x.view(),y.view(),psi.view(),bvec.getOrder(),sigma); // I = psi * b // TMV solves this by writing b = I/psi. // We use QRP in case the psi matrix is close to singular (although it shouldn't be). psi.divideUsing(tmv::QRP); bvec.rVector() = I/psi; xdbg<<"Done FitImage: bvec = "<<bvec<<std::endl; }
int main(int argc, char *argv[]) { // Parameters to set: // columns for necessary input: int idCol; int segIdCol; int raCol; int decCol; int magCol; int bgCol; int rCol; // half-light radius (pix) int aCol, bCol, paCol; // WC observed ellipse int g1Col; int g2Col; int fwdColStart; int fwdColEnd; // The fit: int order; double maskSigma; // Input files string fitsName; string catName; string psfName; int psfOrder; string weightName; string wcsName; string segmentationName; int segmentationPadding; string weightScaleKey; string fluxScaleKey; // Data properties double sky; //double rn; //double gain; int stampSize; // GL interpolation of missing values double maxBadPixels; int interpolationOrder; double maxBadFlux; Pset parameters; { const int def=PsetMember::hasDefault; const int low=PsetMember::hasLowerBound; const int up=PsetMember::hasUpperBound; const int lowopen = low | PsetMember::openLowerBound; const int upopen = up | PsetMember::openUpperBound; parameters.addMemberNoValue("FILES:",0, "Input data"); parameters.addMember("fitsName", &fitsName, def, "Image FITS file", "set0001.fit"); parameters.addMember("catName", &catName, def, "Input SExtractor catalog", "set0001.scat"); parameters.addMember("psfName", &psfName, def, "Input PSFEx file", "model.txt"); parameters.addMember("psfOrder", &psfOrder, def | low, (std::string("Maximum order of polynomial psf variation used; ")+ std::string("-1 for order of PSFEx model")).c_str(), -1, -1); parameters.addMember("weightName", &weightName, def, "Input weight map proportional to inverse variance", "weight.fit"); parameters.addMember("wcsName", &wcsName, def, "World coordinate header file", "wcs.txt"); parameters.addMember("weightScaleKey", &weightScaleKey, def, "Scaling factor for weight map (e.g. from Swarp) keyword in WCS header", "WTSCALE"); // This is the scale that transforms weight proportional to 1/sig^2 to weights EQUAL to // 1/sig^2 of the respective single frame. // Note that single frame rescaling is happening on top of this on both the science and // weight frames parameters.addMember("fluxScaleKey", &fluxScaleKey, def, "Scaling factor for flux (e.g. from WCS header) keyword in WCS header", "FLXSCALE"); parameters.addMember("segmentationName", &segmentationName, def, "segmentation map", "segment.fits"); parameters.addMember("segmentationPadding", &segmentationPadding, def | low, "padding around segmentation maps [pix]", 0, 0); parameters.addMember("stampSize", &stampSize, def | low, "Pixel size of img postage stamps", 64, 3); parameters.addMemberNoValue("DATA PROPERTIES:",0, "Input data"); parameters.addMember("sky", &sky, def, "sky level", 0.); //parameters.addMember("rn", &rn, def | low, // "Read noise, i.e. RMS at 0 ADU", 1000., 0.); //parameters.addMember("gain", &gain, def | low, // "Gain, e/ADU for Poissson, 0 for no Poisson", 1., 0.); parameters.addMemberNoValue("FDNT:",0, "Fitting parameters:"); parameters.addMember("order", &order, def, "FDNT GL-fit order (0 for FFT)", 0); parameters.addMember("maskSigma", &maskSigma, def, "GL and FDNT mask sigma (-1 auto)", -1. /*4.*/); // changed 21.11.12 parameters.addMemberNoValue("CATALOG TRANSLATION:",0, "Columns holding input data"); parameters.addMember("idCol", &idCol, def | low, "Object ID", 1, 1); parameters.addMember("segIdCol", &segIdCol, def | low, "Object ID in segmentation map; determined automatically if 0", 1, 0); parameters.addMember("raCol", &raCol, def | low, "RA centroid", 2, 1); parameters.addMember("decCol", &decCol, def | low, "DEC centroid", 3, 1); parameters.addMember("magCol", &magCol, def | low, "Magnitude", 4, 1); parameters.addMember("bgCol", &bgCol, def | low, "photometric background flux (zero if bgCol==0)", 5, 0); parameters.addMember("rCol", &rCol, def | low, "Half-light radius (in pixels)", 6, 1); parameters.addMember("g1Col", &g1Col, def | low, "g1 shape estimate (use native shape if 0)", 7, 0); parameters.addMember("g2Col", &g2Col, def | low, "g2 shape estimate (use native shape if 0)", 8, 0); parameters.addMember("aCol", &aCol, def | low, "Major axis (in WC)", 7, 1); parameters.addMember("bCol", &bCol, def | low, "Minor axis (in WC)", 8, 1); parameters.addMember("paCol", &paCol, def | low, "Position angle (in WC)", 9, 1); parameters.addMember("fwdColStart", &fwdColStart, def | low, "first forwarded column from input catalog", 0, 1); parameters.addMember("fwdColEnd", &fwdColEnd, def | low, "last forwarded column from input catalog", 0, 1); parameters.addMember("maxBadPixels", &maxBadPixels, def, "Maximum fraction of bad pixels in postage stamp", 0.1); parameters.addMember("maxBadFlux", &maxBadFlux, def, "Maximum fraction of model flux in bad pixels", 0.05); parameters.addMember("interpolationOrder", &interpolationOrder, def, "GL order for bad pixel interpolation", 4); } parameters.setDefault(); try { for (int i=1; i<argc; i++) { // Open & read all specified input files ifstream ifs(argv[i]); if (!ifs) { cerr << "Can't open file " << argv[i] << endl; exit(1); } try { parameters.setStream(ifs); } catch (std::runtime_error &m) { cerr << "In file " << argv[i] << ":" << endl; quit(m,1); } } // ... and from stdin try { parameters.setStream(cin); } catch (std::runtime_error &m) { cerr << "In stdin:" << endl; quit(m,1); } cerr << "# " << stringstuff::taggedCommandLine(argc, argv) << endl; parameters.dump(cerr); // (1) Read the PSF PSFExModel *model; try { model = new PSFExModel(psfName.c_str()); } catch (PSFExError &e) { cerr << "Error reading PSFEx model: " << e.what() << "; exiting." << endl; exit(1); } catch (...) { cerr << "Error reading PSFEx model; exiting." << endl; exit(1); } if (!model->selfTest(1, 3, psfOrder)) { // this is a very lenient self-test cerr << "PSFEx model did not pass self test; exiting." << endl; exit(1); } cerr << "reading image " << flush; // (2) Open image Image<> sci; FITSImage<> fits(fitsName); sci = fits.extract(); cerr << ", header " << flush; // (3) Read astrometry img::ImageHeader h; ifstream mapfs(wcsName.c_str()); if (!mapfs) { cerr << "Could not open astrometry file " << wcsName << "; trying FITS header in science frame" << endl; h = *(sci.header()); } else { h = img::HeaderFromStream(mapfs); } SCAMPMap *fullmap = new SCAMPMap(h,0); double xw, yw; fullmap->toWorld(0,0,xw,yw); #ifdef DEBUGFDNTPSFEX cerr << "# WCS " << xw << " " << yw << " is the (0,0) pixel WC w.r.t. the TP" << endl; #endif cerr << ", weight " << flush; // (4) Open weight image and read weight scale Image<> wt; FITSImage<> wtfits(weightName); wt = wtfits.extract(); cerr << "read, " << flush; HdrRecordBase* weightScaleRecord = h.find(weightScaleKey); double weightScale = 1.0; if (weightScaleRecord) weightScale = atof(weightScaleRecord->getValueString().c_str()); else cerr << "WARNING: weight scale key not found in header; assuming weight scale is 1.0\n"; cerr << "SCAMP weight scale: " << weightScale << endl; HdrRecordBase* fluxScaleRecord = h.find(fluxScaleKey); double fluxScale = 1.0; if (fluxScaleRecord) fluxScale = atof(fluxScaleRecord->getValueString().c_str()); else cerr << "WARNING: flux scale key not found in header; assuming flux scale is 1.0\n"; cerr << "SCAMP flux scale: " << fluxScale << endl; cerr << "reading segmentation map" << endl; Image<> seg; FITSImage<> fitsseg(segmentationName.c_str()); seg = fitsseg.extract(); // (5) rescale weight map Bounds<int> chip_bounds = sci.getBounds(); Bounds<int> safe_chip_bounds = chip_bounds; safe_chip_bounds.addBorder(-2); // the inverse variance scales with flux in the following way: weightScale = weightScale / (fluxScale*fluxScale); for (int iy=chip_bounds.getYMin(); iy<=chip_bounds.getYMax(); iy++) for (int ix=chip_bounds.getXMin(); ix<=chip_bounds.getXMax(); ix++) { // weight map just rescaled sky inverse-variance: wt(ix,iy) = wt(ix,iy) * weightScale; sci(ix,iy) = sci(ix,iy) * fluxScale; } // initialize sums UnweightedShearEstimator se; int ngood=0; int nfail=0; int nfail_post=0; int nfail_postmeas=0; int nfail_badpix=0; int nfail_bpgl=0; int nfail_bpff=0; int nfail_fdnt=0; int nfail_seg=0; // (6) Loop through objects int nread=MAX(idCol, raCol); nread = MAX(nread, decCol); nread = MAX(nread, segIdCol); nread = MAX(nread, rCol); nread = MAX(nread, aCol); nread = MAX(nread, bCol); nread = MAX(nread, paCol); nread = MAX(nread, bgCol); nread = MAX(nread, g1Col); nread = MAX(nread, g2Col); nread = MAX(nread, fwdColEnd); vector<string> readvals(nread); ifstream ccat(catName.c_str()); if (!ccat) { cerr << "Error opening catalog file " << catName << endl; exit(1); } string buffer; tmv::SymMatrix<double> covE(2); cout << "# id x_pix y_pix eta1 eta2 sig1 sig2 cov12 mu egFix fdFlags " << "considered_success forwarded_column" << endl; while (stringstuff::getlineNoComment(ccat, buffer)) { // all objects /* cerr << "######################################################" << endl << "// (a) Acquire info of object " << flush; */ istringstream iss(buffer); for (int i=0; i<nread; i++) iss >> readvals[i]; if (!iss) { cerr << "Bad catalog input line: " << buffer; exit(1); } string id = readvals[idCol-1]; //cerr << id << endl; double ra0 = atof(readvals[raCol-1].c_str()); double dec0 = atof(readvals[decCol-1].c_str()); double a_wc = atof(readvals[aCol-1].c_str()); double b_wc = atof(readvals[bCol-1].c_str()); double pa_wc = atof(readvals[paCol-1].c_str()); double r_pix = atof(readvals[rCol-1].c_str()); // FLUX_RADIUS in pixels, not wcs double bg = 0.; if (bgCol > 0) bg = atof(readvals[bgCol-1].c_str()); string fwd = ""; if (fwdColStart <= fwdColEnd && fwdColEnd > 0) { for (int i=max(1,fwdColStart); i<=fwdColEnd; i++) { fwd += readvals[i-1]; fwd += " "; } } double x_wc, y_wc; // tangent plane coordinates double x_pix, y_pix; fullmap->toWorld(x_pix, y_pix, x_wc, y_wc); #ifdef DEBUGFDNTPSFEX cerr << "(a) processing object at (RA,dec)=(" << ra0 << "," << dec0 << ")=(" << x_wc << "," << y_wc << ") " << "(x,y)=(" << x_pix << "," << y_pix << ")" << endl; #endif // deproject spherical coordinates to xi (x_wc) and eta (y_wc) SphericalICRS point(ra0*DEGREE, dec0*DEGREE); TangentPlane tp(point, fullmap->projection()); tp.getLonLat(x_wc, y_wc); x_wc /= DEGREE; y_wc /= DEGREE; try { //cerr << "# object at WCS " << x_wc << " " << y_wc << endl; // DEBUG fullmap->toPix(x_wc, y_wc, x_pix, y_pix); } catch (AstrometryError& e) { cerr << e.what() << endl; cerr << "(b) processing object at (RA,dec)=(" << ra0 << "," << dec0 << ")" << endl; cerr << "toPix failure" << endl; exit(0); } if (!safe_chip_bounds.includes(int(x_pix), int(y_pix))) continue; cerr << "######################################################" << endl << "// (a) Acquire info of object " << id << endl << "# object at WCS " << x_wc << " " << y_wc << endl; // DEBUG #ifdef DEBUGFDNTPSFEX cerr << "processing object at (RA,dec)=(" << ra0 << "," << dec0 << ")=(" << x_wc << "," << y_wc << ") " << "(x,y)=(" << x_pix << "," << y_pix << ")" << endl; #endif #ifdef DEBUGFDNTPSFEX cerr << "// (b) get the Jacobian of coordinate transformation at that position" << endl; #endif Matrix22 J = fullmap->dWorlddPix(x_pix,y_pix); double rescale = sqrt(fabs(J(0,0)*J(1,1)-J(0,1)*J(1,0))); // distorted approximate pixel scale: how much the scales are enlarged by WC transform #ifdef DEBUGFDNTPSFEX cerr << "rescaling by " << rescale << endl; cerr << "// (c) get PSF model at the position" << endl; #endif // generate model PSF at this location model->fieldPosition(x_pix, y_pix); // model now holds the psf model at this position cerr << "flux before normalization: " << model->sb()->getFlux() << endl; model->setFlux(1.0); // FWHM is twice the half-light radius for Gaussian psf, scaled to world coords double ee50psf = model->getFWHM()/2.*rescale; Ellipse psfBasis(0., 0., log(ee50psf/1.17)); // generate PSF image in WC SBDistort psfWCS(*(model->sb()),J(0,0),J(0,1),J(1,0),J(1,1)); cerr << "dWorld/dPix " << J; // J comes with its own endl cerr << ee50psf << endl; // sets flux of basis correctly to have flux normalization after distortion psfWCS.setFlux(1.); double dx = ee50psf / 2.35; // magic 4.7 factor from PSFEx cerr << "drawing psf postage stamp with dx=" << dx << endl; Image<> ipsf = psfWCS.draw(dx); // Measure PSF GL size & significance Image<> psfwt(ipsf.getBounds()); psfwt = pow(1e-5/dx, -2.); psfBasis.setMu( psfBasis.getMu() - log(dx)); GLSimple<> gl(ipsf, psfwt, psfBasis, 4); if (!gl.solve()) { cerr << "# Failed measuring psf, flags " << gl.getFlags() << "; ignoring object" << endl; continue; } psfBasis = gl.getBasis(); psfBasis.setMu( psfBasis.getMu() + log(dx)); #ifdef DEBUGFDNTPSFEX cerr << "# PSF e and GL sigma: " << psfBasis.getS() << " " << exp(psfBasis.getMu()) << endl; #endif PSFInformation psfinfo(psfWCS, psfBasis); #ifdef DEBUGFDNTPSFEX cerr << "// (d) Starting ellipse of galaxy" << endl; #endif double e1start = (a_wc*a_wc-b_wc*b_wc)/(a_wc*a_wc+b_wc*b_wc); double e2start = e1start * sin(2*pa_wc*PI/180.); e1start *= cos(2*pa_wc*PI/180.); cerr << "SExtractor ellipse r = " << r_pix*rescale << ", e = " << e1start << "," << e2start << endl; // all in wcs pixel coordinates Ellipse sexE(e1start, e2start, log(r_pix*rescale), x_wc, y_wc); Shear initShear; Ellipse initE; double g1_wc; double g2_wc; if (g1Col > 0 && g2Col > 0) { // read in g1, g2 (if available) g1_wc = atof(readvals[g1Col-1].c_str()); g2_wc = atof(readvals[g2Col-1].c_str()); double gabs = sqrt(g1_wc*g1_wc+g2_wc*g2_wc); if (gabs > 0.95) { // sanitize shear g1_wc=g1_wc*0.95/gabs; g2_wc=g2_wc*0.95/gabs; } initShear.setG1G2(g1_wc, g2_wc); initShear.getE1E2(e1start, e2start); initE = Ellipse(e1start, e2start, log(r_pix*rescale), x_wc, y_wc); // all in wcs } else if (g1Col <= 0 && g2Col <= 0) { // approximate g1, g2 with native shape (if g1, g2 not available) initE = sexE; } else { cerr << "g1Col / g2Col specification inconsistent, exiting" << endl; exit(2); } /* cerr << "starting ellipse r = " << r_pix*rescale << ", e = " << e1start << ", " << e2start << endl; */ #ifdef DEBUGFDNTPSFEX cerr << "// (e) building FitExposure" << endl; #endif FitExposure<>* fep; #ifdef DEBUGFDNTPSFEX cerr << "// get the postage stamp" << endl; #endif int xi0 = x_pix-stampSize/2; if (xi0 < chip_bounds.getXMin()) xi0 = chip_bounds.getXMin(); if ((xi0 + stampSize+1) > chip_bounds.getXMax()) xi0 = chip_bounds.getXMax() - stampSize - 1; int yi0 = y_pix-stampSize / 2; if (yi0 < chip_bounds.getYMin()) yi0 = chip_bounds.getYMin(); if ((yi0 + stampSize+1) > chip_bounds.getYMax()) yi0 = chip_bounds.getYMax() - stampSize - 1; #ifdef DEBUGFDNTPSFEX cerr << "// " << xi0 << " " << xi0+stampSize-1 << " " << yi0 << " " << yi0+stampSize-1 << endl; cerr << "// hopefully inside x=" << chip_bounds.getXMin() << ".." << chip_bounds.getXMax() << ", y=" << chip_bounds.getYMin() << ".." << chip_bounds.getYMax() << endl; #endif Bounds<int> stamp(xi0,xi0+stampSize-1, yi0, yi0+stampSize-1); cerr << "set bounds" << endl; Image<float> scistamp = sci.subimage(stamp).duplicate(); cerr << "sci bounds" << endl; Image<float> wtstamp = wt.subimage(stamp).duplicate(); cerr << "wt bounds" << endl; Image<float> segstamp = seg.subimage(stamp).duplicate(); cerr << "seg bounds" << endl; Image<double> xwstamp(stamp); Image<double> ywstamp(stamp); int segId = 0; if (segIdCol > 0) segId = atoi(readvals[segIdCol-1].c_str()); else { bool badSegID=false; // check a small square region for (int dx=0; dx<=1; dx++) { for (int dy=0; dy<=1; dy++) { //cerr << int(x_pix) + dx << " " << int(y_pix) + dy << endl; int dsegId = seg(int(x_pix)+dx, int(y_pix)+dy); if (!segId && dsegId) { segId = dsegId; } else if (dsegId && segId!=dsegId) { badSegID = true; } } } if (badSegID) { cerr << "# fail: could not get segmentation id for " << id << endl; #ifdef CHECKPLOTS ipsf.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_psf_badseg.fits",ipsf); wtstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_wt_badseg.fits",wtstamp); scistamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_sci_badseg.fits",scistamp); segstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_seg_badseg.fits",segstamp); #endif nfail++; nfail_seg++; continue; } } cerr << "got segid" << endl; try { for (int iy=stamp.getYMin(); iy<=stamp.getYMax(); iy++) { for (int ix=stamp.getXMin(); ix<=stamp.getXMax(); ix++) { double dxw,dyw; fullmap->toWorld(ix,iy,dxw,dyw); xwstamp(ix,iy) = dxw; ywstamp(ix,iy) = dyw; if (segstamp(ix,iy) && segstamp(ix,iy)!=segId) { //it's another object! for (int iiy=max(stamp.getYMin(),iy-segmentationPadding); iiy<=min(stamp.getYMax(),iy+segmentationPadding); iiy++) for (int iix=max(stamp.getXMin(),ix-segmentationPadding); iix<=min(stamp.getXMax(),ix+segmentationPadding); iix++) wtstamp(iix,iiy)=0.; } } } fep = new FitExposure<>(scistamp, wtstamp, xwstamp, ywstamp, 0, sky+bg); // stack background with sky-subtracted single frames == // photometric local background in stack flux scale } catch (...) { cerr << "# fail: could not get postage stamp for " << id << endl; nfail++; nfail_post++; delete fep; continue; } #ifdef DEBUGFDNTPSFEX cerr << "// (f) checking bad pixels" << endl; #endif double meanweight=0.; vector< Position<int> > bp = fep->badPixels(meanweight); cerr << "mean weight: " << meanweight << endl; if (bp.size()>maxBadPixels*stampSize*stampSize) { cerr << "# fail: " << id << " has too many bad pixels" << endl; #ifdef CHECKPLOTS ipsf.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_psf_badpix.fits",ipsf); wtstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_wt_badpix.fits",wtstamp); scistamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_sci_badpix.fits",scistamp); segstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_seg_badpix.fits",segstamp); #endif nfail++; nfail_badpix++; delete fep; continue; } #ifdef DEBUGFDNTPSFEX // residual image (science image with the GL model subtracted) Image<float> glstamp = sci.subimage(stamp).duplicate(); #endif // has bad pixels, but not too many to begin with: do GL interpolation if (bp.size() > 0) { #ifdef DEBUGFDNTPSFEX cerr << "# trying to interpolate " << bp.size() << " bad pixels" << endl; cerr << sexE << " " << interpolationOrder << endl; #endif GLSimple<> gal(*fep, sexE, interpolationOrder); if (!gal.solve()) { cerr << "# fail: GL fit failed for " << id << endl; #ifdef CHECKPLOTS ipsf.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_psf_bpgl.fits",ipsf); wtstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_wt_bpgl.fits",wtstamp); scistamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_sci_bpgl.fits",scistamp); segstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_seg_bpgl.fits",segstamp); #endif nfail++; nfail_bpgl++; delete fep; continue; } LVector bvec = gal.getB(); double fluxModel = bvec.flux(); Ellipse basis = gal.getBasis(); double missingFlux=0.; double scaleFactor = exp(basis.getMu()); for (vector< Position<int> >::iterator it=bp.begin(); it<bp.end(); it++) { LVector psi(bvec.getOrder()); Position<double> xunit = basis.inv(Position<double>(xwstamp((*it).x,(*it).y), ywstamp((*it).x,(*it).y))); psi.fillBasis(xunit.x, xunit.y, scaleFactor); scistamp((*it).x,(*it).y)=bvec.dot(psi); wtstamp((*it).x,(*it).y)=meanweight; // The interpolated pixel is assumed to have the mean weight of the good pixels; // this makes sense because in the Fourier code homogeneous uncertainties are // assumed missingFlux += scistamp((*it).x,(*it).y); scistamp((*it).x,(*it).y)+=sky+bg; } missingFlux *= rescale*rescale; // scale flux with coordinate system #ifdef DEBUGFDNTPSFEX for (int iy=stamp.getYMin(); iy<=stamp.getYMax(); iy++) { for (int ix=stamp.getXMin(); ix<=stamp.getXMax(); ix++) { LVector psi(bvec.getOrder()); Position<double> xunit = basis.inv(Position<double>(xwstamp(ix,iy), ywstamp(ix,iy))); psi.fillBasis(xunit.x, xunit.y, scaleFactor); glstamp(ix,iy) -= bvec.dot(psi); } } cerr << "# fluxModel = " << fluxModel << endl; cerr << "# scaleFactor = " << scaleFactor << endl; cerr << "# missingFlux = " << missingFlux << endl; #endif if (missingFlux/fluxModel > maxBadFlux) { cerr << "# fail: bad pixels in " << id << " have too high flux fraction" << endl; #ifdef CHECKPLOTS ipsf.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_psf_bpff.fits",ipsf); wtstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_wt_bpff.fits",wtstamp); scistamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_sci_bpff.fits",scistamp); segstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_seg_bpff.fits",segstamp); glstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_glr_bpff.fits",glstamp); #endif nfail++; nfail_bpff++; delete fep; continue; } } #ifdef DEBUGFDNTPSFEX cerr << "// (g) running FDNT..." << flush; #endif FDNT<> fd(*fep, psfinfo, initE, order); fd.setMaskSigma(maskSigma); fd.GLAll(); bool success = fd.prepare(); if (success) cerr << " success!" << endl; else cerr << " failed." << endl; #ifdef DEBUGFDNTPSFEX cerr << "// (h) evaluating FDNT" << endl; #endif Shear targetS = fd.getBasis().getS(); cerr << targetS << endl; double prob; tmv::SymMatrix<double> covE(2,2); if (success) { cerr << "making the actual measurement" << endl; try { targetS = fd.shape2(prob, covE); // THIS IS THE ACTUAL MEASUREMENT!! } catch (...) { cerr << "an error occurred" << endl; } cerr << "made the actual measurement" << endl; // ??? Make flag mask an input parameter ??? success = !(fd.getFlags() & (DidNotConverge + Singularity + OutOfBounds + TooLarge + UnderSampled + TooElliptical + GLFailure)); } double eta1, eta2; targetS.getEta1Eta2(eta1, eta2); double egFix = 0.; double sig1 = 0., sig2 = 0.; double cov12 = 0.; if (success) { try { egFix = fd.shrinkResponse(targetS); cerr << "got shrink response" << endl; sig1 = sqrt(covE(0,0)); sig2 = sqrt(covE(1,1)); cov12 = covE(0,1); se.add(targetS, egFix, sig1, sig2); cerr << "good " << targetS << " " << egFix << " " << sig1 << " " << sig2 << endl; ngood++; } catch (...) { cerr << "an error occured on previously successful measurement" << endl; nfail++; nfail_postmeas++; success=false; } #ifdef CHECKPLOTS ipsf.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_psf_good.fits",ipsf); wtstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_wt_good.fits",wtstamp); scistamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_sci_good.fits",scistamp); segstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_seg_good.fits",segstamp); Image<> filter1 = fd.drawFilter1(targetS,initE); Image<> filter2 = fd.drawFilter2(targetS,initE); filter1.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_f1_good.fits",filter1); filter2.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_f2_good.fits",filter2); if (bp.size()>0) { glstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_glr_good.fits",glstamp); } #endif } else { cerr << "# fail: some obscure thing in FDNT::prepare() happens for " << id << ", flags " << fd.getFlags() << endl; stringstream flags; flags << fd.getFlags(); #ifdef CHECKPLOTS ipsf.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_psf_fdnt_"+flags.str()+".fits",ipsf); wtstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_wt_fdnt_"+flags.str()+".fits",wtstamp); scistamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_sci_fdnt_"+flags.str()+".fits",scistamp); segstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_seg_fdnt_"+flags.str()+".fits",segstamp); if (bp.size()>0) { glstamp.shift(1,1); FITSImage<>::writeToFITS("check_"+id+"_glr_fdnt_"+flags.str()+".fits",glstamp); } #endif nfail++; nfail_fdnt++; } double mu = fd.getBasis().getMu(); cout << id << " " << ra0 << " " << dec0 << " " << x_pix << " " << y_pix //<< " " << mag << " " << eta1 << " " << eta2 << " " << sig1 << " " << sig2 << " " << cov12 << " " << mu << " " << egFix << " " << fd.getFlags() << " " << success << " " << fwd << endl; delete fep; } delete model; delete fullmap; // Print out mean shear estimate Shear S(se); double g1, g2, sig1, sig2; S.getG1G2(g1,g2); se.sigmaE(sig1,sig2, false); cout << fixed << setprecision(6); // Approximate the reduced-shear error as 1/2 of the distortion error cout << "# Means: " << g1 << " +- " << sig1/2 << " " << g2 << " +- " << sig2/2 << endl; cout << "# Failed / good " << nfail << " / " << ngood << endl; cout << "# Reasons for failure:\n# " << nfail_post << "\t couldn't get postage stamp\n# " << nfail_badpix << "\t had too many bad pixels\n# " << nfail_bpgl << "\t couldn't GL-interpolate bad pixels\n# " << nfail_bpff << "\t had too much flux in bad pixels\n# " << nfail_postmeas << "\t failed after measurement\n# " << nfail_fdnt << "\t had some error in FDNT\n# " << nfail_seg << "\t had ambiguous segmentation information\n"<< endl; } catch (std::runtime_error &m) { cerr << m.what() << endl; quit(m,1); } }
SBShapelet::SBShapeletImpl::SBShapeletImpl(double sigma, const LVector& bvec, const GSParamsPtr& gsparams) : SBProfileImpl(gsparams), _sigma(sigma), _bvec(bvec.copy()) {}
void DesignWidget::drawFloor(LBFloor *drawnFloor) { if(drawnFloor == NULL) return; if( !(drawnFloor -> isItDrawn) ) return; LField *helpField; if(drawnFloor -> hasChild()) helpField = (LField*)drawnFloor -> child; else return; //break this while, when last field of actual floor is drawn while(1) { //Okay, little mess. We have new state: connectingFields //this complicates following code (before drawing floors other than actual one) //if another state will appear, rebuild of following "if" will be needed //for now: check if field is pointed only if ... //TODO: VERY BAD WAY ... CHANGE IT! //following 'if' is for checking what state we actualy have //maybe there's a better way than making OR with desired states if(*(GC -> appState) == none || *(GC -> appState) == editingField || *(GC->appState) == definingStairs) if(drawnFloor == GC -> actualFloor) { //check if field is pointed with mouse if(helpField->isPointIn(LVector(mouseV.x, 0.0f, mouseV.z))) { isFieldPointed = true; GC -> cameraKid -> position = helpField->centerPoint; GC -> cameraKid -> position.y = GC -> actualFloor -> height; //if new field is not being defined right now if(!cornerIndex) { //pointedFieldID = helpField->ID; pointedField = helpField; setDrawStyle(stylePointedField); } } else { if(*(GC -> appState) == editingField) setDrawStyle(inactive); else setDrawStyle(drawStyleField); } if(helpField == GC->chosenField) setDrawStyle(styleChosenField); QPolygon drawField; LField *drawnField = new LField(*helpField); for(int a = 0; a < 4; a++) { //for scaling with mouse wheel // drawnField->corners[a].mulMatrix(globalMatrix); } drawField << QPoint(drawnField->corners[0].x, drawnField->corners[0].z) << QPoint(drawnField->corners[1].x,drawnField->corners[1].z) << QPoint(drawnField->corners[2].x,drawnField->corners[2].z) << QPoint(drawnField->corners[3].x,drawnField->corners[3].z); painter->drawPolygon(drawField); }//(if drawnFloor == GC -> actualFloor) //draw parts of "connectingFields" state if(*(GC -> appState) == connectingFields) { } ///////////////////////////////////////////// //PART FOR EVERY FLOOR (not only actual) : ///////////////////////////////////////////// //draw Normals setDrawStyle(normal); for(int cntN = 0; cntN < 4; cntN++) { int x1 = helpField->corners[cntN].x + helpField->vectors[cntN].x/2; int z1 = helpField->corners[cntN].z + helpField->vectors[cntN].z/2; int x2 = x1 + helpField->cornersN[cntN].x*10.0f; int z2 = z1 + helpField->cornersN[cntN].z*10.0f; painter -> drawLine(x1, z1, x2, z2); } ///////////////////////////////////////// //draw walls with defined passages if(drawnFloor == GC -> actualFloor) setDrawStyle(drawStyleWall); else setDrawStyle(wallInactive); for(int cnt = 0; cnt < 4; cnt++) { int a, b; a = cnt; if(cnt == 3) b = 0; else b = a + 1; LVector wallVector = helpField -> corners[b] - helpField -> corners[a]; float wallLength = wallVector.Length(); //points for drawing lines defining wall parts LVector pointA, pointB; pointA = helpField -> corners[a]; if(helpField -> passageTree[a] -> hasChild()) { lbpassage *helpPassage = (lbpassage*)(helpField -> passageTree[a] -> child); while(1) { //multiply wall's vector by ratio of passage's point distance and Wall's length pointB = helpField -> corners[a] + wallVector * (helpPassage -> d1 / wallLength); painter -> drawLine(pointA.x, pointA.z, pointB.x, pointB.z); pointA = helpField -> corners[a] + wallVector * (helpPassage -> d2 / wallLength); if( ! helpPassage -> isLast()) { helpPassage = (lbpassage*)(helpPassage -> next); } //last passage else { break; } } } //draw last wall part (draw whole wall if we don't have passages yet) pointB = helpField -> corners[b]; painter -> drawLine(pointA.x, pointA.z, pointB.x, pointB.z); } ///////////////////////////// if(helpField -> isLast()) break; else helpField = (LField*)helpField -> next; ///////////////////////////// } }
void DesignWidget::drawBreakingHole() { //TODO: check what things can be calculated only once (once after choosing wall part) /* As in drawWallParts: "drawWallParts() is invoked for many appStates, but works for them almost is the same way. So first prepare variables needed to make prope things depending on appState. Inheritance from one class (lbhelpersbase) is helpful - lbStairsHelper and lbwallhelper have the same variables." */ /* if(HB == SH) { field1 = GC->stairsBottom; field2 = GC->stairsTop; } else if(HB == &WH) { field1 = chosenField; field2 = chosenField2; }*/ if(GC -> isPassWithDoors) { setDrawStyle(drawStyleHighlightPartsD); } else { setDrawStyle(drawStyleHighlightParts); } painter -> drawLine(HB->passageA.x, HB->passageA.z, HB->passageB.x, HB->passageB.z); LVector temp = HB->passageB - HB->passageA; LVector multiplied = LVector(0.0f, 1.0f, 0.0f); LVector normal1 = temp^multiplied; normal1.normalize(); //reportWidget -> setText (QString::number(normal1.x)+QString::number(normal1.z)); // reportWidget -> setText(QString::number(MH.pointLineDistance // (1,1,2,2,2,1))); float pointDistance = MH.pointLineDistance(HB->passageA.x, HB->passageA.z, HB->passageA.x + normal1.x, HB->passageA.z + normal1.z, mouseV.x, mouseV.z); // reportWidget -> setText(QString::number(MH.pointLineDistance(WH.passageA.x, WH.passageA.z, WH.passageA.x + normal1.x, WH.passageA.z + normal1.z, mouseV.x, mouseV.z))); float passLength = temp.Length(); LVector mouseVec; mouseVec.x = mouseV.x - HB->passageA.x; mouseVec.z = mouseV.z - HB->passageA.z; //setting distPointer for the first time if(HB->distPointer == NULL) { HB->distPointer = &(HB->dist1); HB->pointPointer = &(HB->point1); } //check 2 conditions: mouse is pointing farther than passageA or passageB //(problem was, that equations is showing distance from both sides of wall part) //is mouse pointing outside passageA? if((-temp) % mouseVec >= 0) { *(HB->pointPointer) = HB->passageA; // printSuccess(QString::number(0)); *(HB->distPointer) = 0; // printInfo("vec!"); } else //is mouse poining outside passageB? if(pointDistance > passLength) { *(HB->pointPointer) = HB->passageB; // printSuccess(QString::number(temp.Length())); *(HB->distPointer) = temp.Length(); // printError("distance!"); } //mouse is geometrically betweeen passageA and passageB else { HB->pointPointer->x = HB->passageA.x + temp.x*pointDistance/passLength; HB->pointPointer->z = HB->passageA.z + temp.z*pointDistance/passLength; // printSuccess(QString::number(pointDistance)); *(HB->distPointer) = pointDistance; // printSuccess("middle!"); } setDrawStyle(drawStyleBigPoint); HB->drawPassagePoints(painter); /////////// DRAW DISTANCES /////////////// drawDistPoints(HB->passageA, HB->point1,0.0f, 0.0f, 15.0f); if(HB -> distPointer == &(HB -> dist2)) { drawDistPoints(HB->passageB, HB->point2, 0.0f, 0.0f, -15.0f); drawDistPoints(HB->point1,HB->point2,0.0f, -15.0f, 0.0f); } /////////// DRAW DISTANCES /////////////// }
float ReportParticle(const b2ParticleSystem *, int i, const b2Vec2 &, const b2Vec2 &, float) { v->Push(vm, Value(i)); return v->len == v->maxl ? -1.0f : 1.0f; }