예제 #1
0
extern void
rayparticipate(			/* compute ray medium participation */
	RAY  *r
)
{
	COLOR	ce, ca;
	double	re, ge, be;

	if (intens(r->cext) <= 1./FHUGE)
		return;				/* no medium */
	re = r->rot*colval(r->cext,RED);
	ge = r->rot*colval(r->cext,GRN);
	be = r->rot*colval(r->cext,BLU);
	if (r->crtype & SHADOW) {		/* no scattering for sources */
		re *= 1. - colval(r->albedo,RED);
		ge *= 1. - colval(r->albedo,GRN);
		be *= 1. - colval(r->albedo,BLU);
	}
	setcolor(ce,	re<=FTINY ? 1. : re>92. ? 0. : exp(-re),
			ge<=FTINY ? 1. : ge>92. ? 0. : exp(-ge),
			be<=FTINY ? 1. : be>92. ? 0. : exp(-be));
	multcolor(r->rcol, ce);			/* path extinction */
	if (r->crtype & SHADOW || intens(r->albedo) <= FTINY)
		return;				/* no scattering */
	setcolor(ca,
		colval(r->albedo,RED)*colval(ambval,RED)*(1.-colval(ce,RED)),
		colval(r->albedo,GRN)*colval(ambval,GRN)*(1.-colval(ce,GRN)),
		colval(r->albedo,BLU)*colval(ambval,BLU)*(1.-colval(ce,BLU)));
	addcolor(r->rcol, ca);			/* ambient in scattering */
	srcscatter(r);				/* source in scattering */
}
예제 #2
0
파일: ambcomp.c 프로젝트: NREL/Radiance
static AMBHEMI *
samp_hemi(				/* sample indirect hemisphere */
	COLOR	rcol,
	RAY	*r,
	double	wt
)
{
	AMBHEMI	*hp;
	double	d;
	int	n, i, j;
					/* insignificance check */
	if (bright(rcol) <= FTINY)
		return(NULL);
					/* set number of divisions */
	if (ambacc <= FTINY &&
			wt > (d = 0.8*intens(rcol)*r->rweight/(ambdiv*minweight)))
		wt = d;			/* avoid ray termination */
	n = sqrt(ambdiv * wt) + 0.5;
	i = 1 + 5*(ambacc > FTINY);	/* minimum number of samples */
	if (n < i)
		n = i;
					/* allocate sampling array */
	hp = (AMBHEMI *)malloc(sizeof(AMBHEMI) + sizeof(AMBSAMP)*(n*n - 1));
	if (hp == NULL)
		error(SYSTEM, "out of memory in samp_hemi");
	hp->rp = r;
	hp->ns = n;
	hp->acol[RED] = hp->acol[GRN] = hp->acol[BLU] = 0.0;
	memset(hp->sa, 0, sizeof(AMBSAMP)*n*n);
	hp->sampOK = 0;
					/* assign coefficient */
	copycolor(hp->acoef, rcol);
	d = 1.0/(n*n);
	scalecolor(hp->acoef, d);
					/* make tangent plane axes */
	if (!getperpendicular(hp->ux, r->ron, 1))
		error(CONSISTENCY, "bad ray direction in samp_hemi");
	VCROSS(hp->uy, r->ron, hp->ux);
					/* sample divisions */
	for (i = hp->ns; i--; )
	    for (j = hp->ns; j--; )
		hp->sampOK += ambsample(hp, i, j, 0);
	copycolor(rcol, hp->acol);
	if (!hp->sampOK) {		/* utter failure? */
		free(hp);
		return(NULL);
	}
	if (hp->sampOK < hp->ns*hp->ns) {
		hp->sampOK *= -1;	/* soft failure */
		return(hp);
	}
	if (hp->sampOK < 64)
		return(hp);		/* insufficient for super-sampling */
	n = ambssamp*wt + 0.5;
	if (n > 8) {			/* perform super-sampling? */
		ambsupersamp(hp, n);
		copycolor(rcol, hp->acol);
	}
	return(hp);			/* all is well */
}
예제 #3
0
파일: source.c 프로젝트: Pizookies/Radiance
extern void
direct(					/* add direct component */
	RAY  *r,			/* ray that hit surface */
	srcdirf_t *f,			/* direct component coefficient function */
	void  *p			/* data for f */
)
{
	register int  sn;
	register CONTRIB  *scp;
	SRCINDEX  si;
	int  nshadcheck, ncnts;
	int  nhits;
	double  prob, ourthresh, hwt;
	RAY  sr;
			/* NOTE: srccnt and cntord global so no recursion */
	if (nsources <= 0)
		return;		/* no sources?! */
						/* potential contributions */
	initsrcindex(&si);
	for (sn = 0; srcray(&sr, r, &si); sn++) {
		if (sn >= maxcntr) {
			maxcntr = sn + MAXSPART;
			srccnt = (CONTRIB *)realloc((void *)srccnt,
					maxcntr*sizeof(CONTRIB));
			cntord = (CNTPTR *)realloc((void *)cntord,
					maxcntr*sizeof(CNTPTR));
			if ((srccnt == NULL) | (cntord == NULL))
				error(SYSTEM, "out of memory in direct");
		}
		cntord[sn].sndx = sn;
		scp = srccnt + sn;
		scp->sno = sr.rsrc;
						/* compute coefficient */
		(*f)(scp->coef, p, sr.rdir, si.dom);
		cntord[sn].brt = intens(scp->coef);
		if (cntord[sn].brt <= 0.0)
			continue;
#if SHADCACHE
						/* check shadow cache */
		if (si.np == 1 && srcblocked(&sr)) {
			cntord[sn].brt = 0.0;
			continue;
		}
#endif
		VCOPY(scp->dir, sr.rdir);
		copycolor(sr.rcoef, scp->coef);
						/* compute potential */
		sr.revf = srcvalue;
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		copycolor(scp->val, sr.rcol);
		cntord[sn].brt = bright(sr.rcol);
	}
						/* sort contributions */
	qsort(cntord, sn, sizeof(CNTPTR), cntcmp);
	{					/* find last */
		register int  l, m;

		ncnts = l = sn;
		sn = 0;
		while ((m = (sn + ncnts) >> 1) != l) {
			if (cntord[m].brt > 0.0)
				sn = m;
			else
				ncnts = m;
			l = m;
		}
	}
	if (ncnts == 0)
		return;		/* no contributions! */
                                                /* accumulate tail */
        for (sn = ncnts-1; sn > 0; sn--)
                cntord[sn-1].brt += cntord[sn].brt;
						/* compute number to check */
	nshadcheck = pow((double)ncnts, shadcert) + .5;
						/* modify threshold */
	ourthresh = shadthresh / r->rweight;
						/* test for shadows */
	for (nhits = 0, hwt = 0.0, sn = 0; sn < ncnts;
			hwt += (double)source[scp->sno].nhits /
				(double)source[scp->sno].ntests,
			sn++) {
						/* check threshold */
		if ((sn+nshadcheck>=ncnts ? cntord[sn].brt :
				cntord[sn].brt-cntord[sn+nshadcheck].brt)
				< ourthresh*bright(r->rcol))
			break;
		scp = srccnt + cntord[sn].sndx;
						/* test for hit */
		rayorigin(&sr, SHADOW, r, NULL);
		copycolor(sr.rcoef, scp->coef);
		VCOPY(sr.rdir, scp->dir);
		sr.rsrc = scp->sno;
						/* keep statistics */
		if (source[scp->sno].ntests++ > 0xfffffff0) {
			source[scp->sno].ntests >>= 1;
			source[scp->sno].nhits >>= 1;
		}
		if (localhit(&sr, &thescene) &&
				( sr.ro != source[scp->sno].so ||
				source[scp->sno].sflags & SFOLLOW )) {
						/* follow entire path */
			raycont(&sr);
			if (trace != NULL)
				(*trace)(&sr);	/* trace execution */
			if (bright(sr.rcol) <= FTINY) {
#if SHADCACHE
				if ((scp <= srccnt || scp[-1].sno != scp->sno)
						&& (scp >= srccnt+ncnts-1 ||
						    scp[1].sno != scp->sno))
					srcblocker(&sr);
#endif
				continue;	/* missed! */
			}
			rayparticipate(&sr);
			multcolor(sr.rcol, sr.rcoef);
			copycolor(scp->val, sr.rcol);
		} else if (trace != NULL &&
			(source[scp->sno].sflags & (SDISTANT|SVIRTUAL|SFOLLOW))
						== (SDISTANT|SFOLLOW) &&
				sourcehit(&sr) && rayshade(&sr, sr.ro->omod)) {
			(*trace)(&sr);		/* trace execution */
			/* skip call to rayparticipate() & scp->val update */
		}
						/* add contribution if hit */
		addcolor(r->rcol, scp->val);
		nhits++;
		source[scp->sno].nhits++;
	}
예제 #4
0
FoMo::RenderCube CGAL2D(FoMo::GoftCube goftcube, const double l, const int x_pixel, const int y_pixel, const int lambda_pixel, const double lambda_width)
{
//
// results is an array of at least dimension (x2-x1+1)*(y2-y1+1)*lambda_pixel and must be initialized to zero
//
// determine contributions per pixel

    typedef K::FT                                         Coord_type;
    typedef K::Point_2                                    Point;
    std::map<Point, Coord_type, K::Less_xy_2> peakmap, fwhmmap, losvelmap;
//        typedef CGAL::Data_access< std::map<Point, Coord_type, K::Less_xyz_3 > >  Value_access;

    int commrank;
#ifdef HAVEMPI
    MPI_Comm_rank(MPI_COMM_WORLD,&commrank);
#else
    commrank = 0;
#endif
    //FoMo::DataCube goftcube=object.datacube;
    FoMo::tgrid grid = goftcube.readgrid();
    int ng=goftcube.readngrid();

    // We will calculate the maximum image coordinates by projecting the grid onto the image plane
    // Rotate the grid over an angle -l (around z-axis), and -b (around y-axis)
    // Take the min and max of the resulting coordinates, those are coordinates in the image plane
    if (commrank==0) std::cout << "Rotating coordinates to POS reference... " << std::flush;
    std::vector<double> xacc, yacc, zacc;
    xacc.resize(ng);
    yacc.resize(ng);
    zacc.resize(ng);
    std::vector<double> gridpoint;
    gridpoint.resize(3);
    Point temporarygridpoint;
    // Define the unit vector along the line-of-sight: the LOS is along y
    std::vector<double> unit = {cos(l), sin(l)};
    // Read the physical variables
    FoMo::tphysvar peakvec=goftcube.readvar(0);//Peak intensity
    FoMo::tphysvar fwhmvec=goftcube.readvar(1);// line width, =1 for AIA imaging
    FoMo::tphysvar vx=goftcube.readvar(2);
    FoMo::tphysvar vy=goftcube.readvar(3);
    double losvelval;

// No openmp possible here
// Because of the insertions at the end of the loop, we get segfaults :(
    /*#ifdef _OPENMP
    #pragma omp parallel for
    #endif*/
    for (int i=0; i<ng; i++)
    {
        for (int j=0; j<2; j++)	gridpoint[j]=grid[j][i];
        xacc[i]=gridpoint[0]*cos(l)-gridpoint[1]*sin(l);// rotated grid
        yacc[i]=gridpoint[0]*sin(l)+gridpoint[1]*cos(l);
        temporarygridpoint=Point(grid[0][i],grid[1][i]); //position vector
        // also create the map function_values here
        std::vector<double> velvec = {vx[i], vy[i]};// velocity vector
        losvelval = inner_product(unit.begin(),unit.end(),velvec.begin(),0.0);//velocity along line of sight for position [i]/[ng]
        losvelmap[temporarygridpoint]=Coord_type(losvelval);
        peakmap[temporarygridpoint]=Coord_type(peakvec[i]);
        fwhmmap[temporarygridpoint]=Coord_type(fwhmvec[i]);
        /*		peakmap.insert(make_pair(temporarygridpoint,Coord_type(peakvec[i])));
        		fwhmmap.insert(make_pair(temporarygridpoint,Coord_type(fwhmvec[i])));
        		losvelmap.insert(make_pair(temporarygridpoint,Coord_type(losvelval)));*/
    }
    double minx=*(min_element(xacc.begin(),xacc.end()));
    double maxx=*(max_element(xacc.begin(),xacc.end()));
    double miny=*(min_element(yacc.begin(),yacc.end()));
    double maxy=*(max_element(yacc.begin(),yacc.end()));
    /*	Value_access peak=Value_access(peakmap);
    	Value_access fwhm=Value_access(fwhmmap);
    	Value_access losvel=Value_access(losvelmap);*/
    xacc.clear(); // release the memory
    yacc.clear();
    if (commrank==0) std::cout << "Done!" << std::endl;

    std::string chiantifile=goftcube.readchiantifile();
    double lambda0=goftcube.readlambda0();// lambda0=AIA bandpass for AIA imaging
    double lambda_width_in_A=lambda_width*lambda0/speedoflight;
    Delaunay_triangulation_2 DT=triangulationfrom2Ddatacube(goftcube);
    Delaunay_triangulation_2 * DTpointer=&DT;

    if (commrank==0) std::cout << "Building frame: " << std::flush;
    double x,y,z,intpolpeak,intpolfwhm,intpollosvel,lambdaval,tempintens;
    int li,lj,ind;
    Point p,nearest;
    Delaunay_triangulation_2::Vertex_handle v;
    Delaunay_triangulation_2::Locate_type lt;
    Delaunay_triangulation_2::Face_handle c;
    boost::progress_display show_progress(x_pixel*y_pixel);

    //initialize grids
    FoMo::tgrid newgrid;
    FoMo::tcoord xvec(x_pixel*lambda_pixel),yvec(x_pixel*lambda_pixel),lambdavec(x_pixel*lambda_pixel);
    newgrid.push_back(xvec);
    if (lambda_pixel > 1) newgrid.push_back(lambdavec);
    FoMo::tphysvar intens(x_pixel*lambda_pixel,0);

#ifdef _OPENMP
    #pragma omp parallel for schedule(dynamic) private (x,y,p,lt,li,v,nearest,intpolpeak,intpolfwhm,intpollosvel,lambdaval,tempintens,ind)
#endif
    for (int j=0; j<x_pixel; j++)
    {
#ifdef _OPENMP
        #pragma omp task
#endif
        for (int i=0; i<y_pixel; i++) // scanning through ccd
        {
            x = double(j)/(x_pixel-1)*(maxx-minx)+minx;
            y = double(i)/(y_pixel-1)*(maxy-miny)+miny;
            // calculate the interpolation in the original frame of reference
            // i.e. derotate the point using angles -l and -b
            p= {x*cos(l)+y*sin(l),-x*sin(l)+y*cos(l)};

            c=DTpointer->locate(p,lt,li);

            // Only look for the nearest point and interpolate, if the point p is inside the convex hull.
            if (lt!=Delaunay_triangulation_2::OUTSIDE_CONVEX_HULL)
            {
                // is this a critical operation?
                v=DTpointer->nearest_vertex(p,c);
                nearest=v->point();
                /* This is how it is done in the CGAL examples
                 			pair<Coord_type,bool> tmppeak=peak(nearest);
                			pair<Coord_type,bool> tmpfwhm=fwhm(nearest);
                			pair<Coord_type,bool> tmplosvel=losvel(nearest);
                			intpolpeak=tmppeak.first;
                			intpolfwhm=tmpfwhm.first;
                			intpollosvel=tmplosvel.first;*/
                intpolpeak=peakmap[nearest];
                intpolfwhm=fwhmmap[nearest];
                intpollosvel=losvelmap[nearest];
            }
            else
            {
                intpolpeak=0;
            }
            if (lambda_pixel>1)// spectroscopic study
            {
                for (int il=0; il<lambda_pixel; il++) // changed index from global variable l into il [D.Y. 17 Nov 2014]
                {
                    // lambda is made around lambda0, with a width of lambda_width
                    lambdaval=double(il)/(lambda_pixel-1)*lambda_width_in_A-lambda_width_in_A/2.;
                    tempintens=intpolpeak*exp(-pow(lambdaval-intpollosvel/speedoflight*lambda0,2)/pow(intpolfwhm,2)*4.*log(2.));
                    ind=j*lambda_pixel+il;//
                    newgrid[0][ind]=x;
                    newgrid[2][ind]=lambdaval+lambda0;
                    // this is critical, but with tasks, the ind is unique for each task, and no collision should occur
                    intens[ind]+=tempintens;// loop over z and lambda [D.Y 17 Nov 2014]
                }
            }

            if (lambda_pixel==1) // AIA imaging study. Algorithm not verified [DY 14 Nov 2014]
            {
                tempintens=intpolpeak;
                ind=j;
                newgrid[0][ind]=x;
                intens[ind]+=tempintens; // loop over z [D.Y 17 Nov 2014]
            }
            // print progress
            ++show_progress;
        }
    }
    if (commrank==0) std::cout << " Done! " << std::endl << std::flush;

    FoMo::RenderCube rendercube(goftcube);
    FoMo::tvars newdata;
    double pathlength=(maxy-miny)/(y_pixel-1);
    intens=FoMo::operator*(pathlength*1e8,intens); // assume that the coordinates are given in Mm, and convert to cm
    newdata.push_back(intens);
    rendercube.setdata(newgrid,newdata);
    rendercube.setrendermethod("CGAL2D");
    rendercube.setresolution(x_pixel,y_pixel,1,lambda_pixel,lambda_width);
    if (lambda_pixel == 1)
    {
        rendercube.setobservationtype(FoMo::Imaging);
    }
    else
    {
        rendercube.setobservationtype(FoMo::Spectroscopic);
    }
    return rendercube;
}
예제 #5
0
void PeakList::filterWeakPeaks(const Config* config, mass_t pmWith19, int peakDensity, bool removeGloballyWeak)
{
    if (numPeaks_<10)
        return;

    const mass_t maxMassToConsider = 10.0 + (pmWith19 > peaks_[numPeaks_-1].mass ?
                                     pmWith19 : peaks_[numPeaks_-1].mass);

    const mass_t windowSize		  = 0.5 * config->get_local_window_size();
    const int	 numPeaksInWindow = (peakDensity>0 ? peakDensity : config->get_max_number_peaks_per_local_window());
    const mass_t tolerance		  = config->getTolerance();

    vector<bool> keep_peaks(numPeaks_, false);
    vector<Peak> new_peaks;

    int maximalPeakIndex = numPeaks_ -1;

    // keep first peak and last peak
    keep_peaks[0]=true;
    if (peaks_[maximalPeakIndex].mass<maxMassToConsider)
        keep_peaks[maximalPeakIndex]=true;

    int min_idx=1;
    int max_idx=1;

    // check the rest of the peaks
    int i;
    for (i=1; i<maximalPeakIndex; i++)
    {
        mass_t peak_mass=peaks_[i].mass;
        mass_t min_mass=peaks_[min_idx].mass;
        mass_t max_mass=peaks_[max_idx].mass;

        if (peaks_[i].mass > maxMassToConsider)
            break;

        // advance min/max pointers
        while (peak_mass-min_mass > windowSize)
            min_mass=peaks_[++min_idx].mass;

        while (max_idx < maximalPeakIndex && max_mass - peak_mass <= windowSize)
            max_mass=peaks_[++max_idx].mass;

        if (max_mass - peak_mass > windowSize)
            max_idx--;

        // this peak might already be marked for keeping (isotpoic peak)
        if (keep_peaks[i])
            continue;

        // if there are less than the maximum number of peaks in the window, keep it.
        if (max_idx-min_idx < numPeaksInWindow)
        {
            keep_peaks[i]=true;
            continue;
        }

        // check if this is one of the top peaks in the window
        int higher_count=0;
        for (int j=min_idx; j<=max_idx; j++)
            if (peaks_[j].intensity > peaks_[i].intensity)
                higher_count++;

        if (higher_count < numPeaksInWindow)
        {
            keep_peaks[i]=true;
        }
    }


    if (pmWith19>0)
    {
        // look for b/y pairs
        //	mass_t pm_with_20 = (originalPmWith19_>0 ? correctedPmWith19_ : originalPmWith19_) +
        //						 MASS_PROTON ;
        mass_t pm_with_20 = pmWith19 + MASS_PROTON;

        mass_t pm_with_20_upper  = pm_with_20 + tolerance;
        mass_t pm_with_20_lower = pm_with_20 - tolerance;

        int f_idx =0;
        int b_idx = numPeaks_-1;
        while (f_idx<numPeaks_ && b_idx>=0)
        {
            if (! keep_peaks[f_idx])
            {
                f_idx++;
                continue;
            }

            while (b_idx>=0 && peaks_[f_idx].mass + peaks_[b_idx].mass > pm_with_20_upper )
                b_idx--;

            if (b_idx<0)
                break;

            mass_t mass_sum = peaks_[f_idx].mass + peaks_[b_idx].mass;
            if (mass_sum > pm_with_20_lower && mass_sum < pm_with_20_upper)
            {
                keep_peaks[f_idx]=true;
                keep_peaks[b_idx]=true;
            }
            f_idx++;
        }
    }

    // copy peaks
    int j=0;
    for (size_t i=0; i<numPeaks_; i++)
        if (keep_peaks[i] && peaks_[i].intensity>=0.001)
            peaks_[j++]=peaks_[i];
    numPeaks_ = j;

    // filter very low intensity peaks (without a window)
    if (removeGloballyWeak)
    {
        vector<intensity_t> intens(numPeaks_);
        for (size_t i=0; i<numPeaks_; i++)
            intens[i]=peaks_[i].intensity;
        sort(intens.begin(), intens.end());

        j=1;
        const intensity_t minIntensity = intens[(2*numPeaks_)/3] * 0.001;
        for (size_t i=1; i<numPeaks_; i++)
            if (peaks_[i].intensity > minIntensity)
                peaks_[j++]=peaks_[i];
        numPeaks_ = j;
    }


}
예제 #6
0
extern int
rayorigin(		/* start new ray from old one */
	RAY  *r,
	int  rt,
	const RAY  *ro,
	const COLOR rc
)
{
	double	rw, re;
						/* assign coefficient/weight */
	if (rc == NULL) {
		rw = 1.0;
		setcolor(r->rcoef, 1., 1., 1.);
	} else {
		rw = intens(rc);
		if (rc != r->rcoef)
			copycolor(r->rcoef, rc);
	}
	if ((r->parent = ro) == NULL) {		/* primary ray */
		r->rlvl = 0;
		r->rweight = rw;
		r->crtype = r->rtype = rt;
		r->rsrc = -1;
		r->clipset = NULL;
		r->revf = raytrace;
		copycolor(r->cext, cextinction);
		copycolor(r->albedo, salbedo);
		r->gecc = seccg;
		r->slights = NULL;
	} else {				/* spawned ray */
		if (ro->rot >= FHUGE) {
			memset(r, 0, sizeof(RAY));
			return(-1);		/* illegal continuation */
		}
		r->rlvl = ro->rlvl;
		if (rt & RAYREFL) {
			r->rlvl++;
			r->rsrc = -1;
			r->clipset = ro->clipset;
			r->rmax = 0.0;
		} else {
			r->rsrc = ro->rsrc;
			r->clipset = ro->newcset;
			r->rmax = ro->rmax <= FTINY ? 0.0 : ro->rmax - ro->rot;
		}
		r->revf = ro->revf;
		copycolor(r->cext, ro->cext);
		copycolor(r->albedo, ro->albedo);
		r->gecc = ro->gecc;
		r->slights = ro->slights;
		r->crtype = ro->crtype | (r->rtype = rt);
		VCOPY(r->rorg, ro->rop);
		r->rweight = ro->rweight * rw;
						/* estimate extinction */
		re = colval(ro->cext,RED) < colval(ro->cext,GRN) ?
				colval(ro->cext,RED) : colval(ro->cext,GRN);
		if (colval(ro->cext,BLU) < re) re = colval(ro->cext,BLU);
		re *= ro->rot;
		if (re > 0.1) {
			if (re > 92.) {
				r->rweight = 0.0;
			} else {
				r->rweight *= exp(-re);
			}
		}
	}
	rayclear(r);
	if (r->rweight <= 0.0)			/* check for expiration */
		return(-1);
	if (r->crtype & SHADOW)			/* shadow commitment */
		return(0);
	if (maxdepth <= 0 && rc != NULL) {	/* Russian roulette */
		if (minweight <= 0.0)
			error(USER, "zero ray weight in Russian roulette");
		if (maxdepth < 0 && r->rlvl > -maxdepth)
			return(-1);		/* upper reflection limit */
		if (r->rweight >= minweight)
			return(0);
		if (frandom() > r->rweight/minweight)
			return(-1);
		rw = minweight/r->rweight;	/* promote survivor */
		scalecolor(r->rcoef, rw);
		r->rweight = minweight;
		return(0);
	}
	return(r->rweight >= minweight && r->rlvl <= abs(maxdepth) ? 0 : -1);
}