// -------------------------------------------------------------
// PetscNonlinearSolverImplementation::FormFunction
// -------------------------------------------------------------
PetscErrorCode
PetscNonlinearSolverImplementation::FormFunction(SNES snes, Vec x, Vec f, void *dummy)
{
  PetscErrorCode ierr(0);

  // Necessary C cast
  PetscNonlinearSolverImplementation *solver =
    (PetscNonlinearSolverImplementation *)dummy;

  // Apparently, you cannot count on x and f (like in FormJacobian())
  // being the same as those used to set up SNES, so the PETSc
  // solution and function vectors are wrapped temporarily for the
  // user function

  boost::scoped_ptr<Vector> 
    xtmp(new Vector(new PETScVectorImplementation(x, false)));

  boost::scoped_ptr<Vector> 
    ftmp(new Vector(new PETScVectorImplementation(f, false)));

  // Call the user-specified function (object) to form the RHS
  (solver->p_function)(*xtmp, *ftmp);

  xtmp.reset();
  ftmp.reset();

  return ierr;
}
Ejemplo n.º 2
0
void
save_for_merge(FILE *fp, get_func_t get, struct field *ftbl)
{
	FILE *mfp, *mfp1, *mfp2;

	if (fstack_count == MERGE_FNUM) {
		/* Must reduce the number of temporary files */
		mfp = ftmp();
		merge_sort_fstack(mfp, putrec, ftbl);
		/* Save output in next layer */
		if (fstack_1_count == MERGE_FNUM) {
			mfp1 = ftmp();
			memcpy(fstack, fstack_1, sizeof fstack);
			merge_sort_fstack(mfp1, putrec, ftbl);
			if (fstack_2_count == MERGE_FNUM) {
				/* More than 4096 files! */
				mfp2 = ftmp();
				memcpy(fstack, fstack_2, sizeof fstack);
				merge_sort_fstack(mfp2, putrec, ftbl);
				fstack_2[0].fp = mfp2;
				fstack_2_count = 1;
			}
			fstack_2[fstack_2_count].fp = mfp1;
			fstack_2[fstack_2_count].get = geteasy;
			fstack_2_count++;
			fstack_1_count = 0;
		}
		fstack_1[fstack_1_count].fp = mfp;
		fstack_1[fstack_1_count].get = geteasy;
		fstack_1_count++;
		fstack_count = 0;
	}

	fstack[fstack_count].fp = fp;
	fstack[fstack_count++].get = get;
}
Ejemplo n.º 3
0
void
merge_sort(FILE *outfp, put_func_t put, struct field *ftbl)
{
	int count = fstack_1_count + fstack_2_count;
	FILE *mfp;
	int i;

	if (count == 0) {
		/* All files in initial array */
		merge_sort_fstack(outfp, put, ftbl);
		return;
	}

	count += fstack_count;

	/* Too many files for one merge sort */
	for (;;) {
		/* Sort latest 16 files */
		i = count;
		if (i > MERGE_FNUM)
			i = MERGE_FNUM;
		while (fstack_count > 0)
			fstack[--i] = fstack[--fstack_count];
		while (i > 0 && fstack_1_count > 0)
			fstack[--i] = fstack_1[--fstack_1_count];
		while (i > 0)
			fstack[--i] = fstack_2[--fstack_2_count];
		if (count <= MERGE_FNUM) {
			/* Got all the data */
			fstack_count = count;
			merge_sort_fstack(outfp, put, ftbl);
			return;
		}
		mfp = ftmp();
		fstack_count = count > MERGE_FNUM ? MERGE_FNUM : count;
		merge_sort_fstack(mfp, putrec, ftbl);
		fstack[0].fp = mfp;
		fstack[0].get = geteasy;
		fstack_count = 1;
		count -= MERGE_FNUM - 1;
	}
}
Ejemplo n.º 4
0
Vector Rosen34(
	Fun           &F , 
	size_t         M , 
	const Scalar &ti , 
	const Scalar &tf , 
	const Vector &xi ,
	Vector       &e )
{
	CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;

	// check numeric type specifications
	CheckNumericType<Scalar>();

	// check simple vector class specifications
	CheckSimpleVector<Scalar, Vector>();

	// Parameters for Shampine's Rosenbrock method
	// are static to avoid recalculation on each call and 
	// do not use Vector to avoid possible memory leak
	static Scalar a[3] = {
		Scalar(0),
		Scalar(1),
		Scalar(3)   / Scalar(5)
	};
	static Scalar b[2 * 2] = {
		Scalar(1),
		Scalar(0),
		Scalar(24)  / Scalar(25),
		Scalar(3)   / Scalar(25)
	};
	static Scalar ct[4] = {
		Scalar(1)   / Scalar(2),
		- Scalar(3) / Scalar(2),
		Scalar(121) / Scalar(50),
		Scalar(29)  / Scalar(250)
	};
	static Scalar cg[3 * 3] = {
		- Scalar(4),
		Scalar(0),
		Scalar(0),
		Scalar(186) / Scalar(25),
		Scalar(6)   / Scalar(5),
		Scalar(0),
		- Scalar(56) / Scalar(125),
		- Scalar(27) / Scalar(125),
		- Scalar(1)  / Scalar(5)
	};
	static Scalar d3[3] = {
		Scalar(97) / Scalar(108),
		Scalar(11) / Scalar(72),
		Scalar(25) / Scalar(216)
	};
	static Scalar d4[4] = {
		Scalar(19)  / Scalar(18),
		Scalar(1)   / Scalar(4),
		Scalar(25)  / Scalar(216),
		Scalar(125) / Scalar(216)
	};
	CPPAD_ASSERT_KNOWN(
		M >= 1,
		"Error in Rosen34: the number of steps is less than one"
	);
	CPPAD_ASSERT_KNOWN(
		e.size() == xi.size(),
		"Error in Rosen34: size of e not equal to size of xi"
	);
	size_t i, j, k, l, m;             // indices

	size_t  n    = xi.size();         // number of components in X(t)
	Scalar  ns   = Scalar(double(M)); // number of steps as Scalar object
	Scalar  h    = (tf - ti) / ns;    // step size 
	Scalar  zero = Scalar(0);         // some constants
	Scalar  one  = Scalar(1);
	Scalar  two  = Scalar(2);

	// permutation vectors needed for LU factorization routine
	CppAD::vector<size_t> ip(n), jp(n);

	// vectors used to store values returned by F
	Vector E(n * n), Eg(n), f_t(n);
	Vector g(n * 3), x3(n), x4(n), xf(n), ftmp(n), xtmp(n), nan_vec(n);

	// initialize e = 0, nan_vec = nan
	for(i = 0; i < n; i++)
	{	e[i]       = zero;
		nan_vec[i] = nan(zero);
	}

	xf = xi;           // initialize solution
	for(m = 0; m < M; m++)
	{	// time at beginning of this interval
		Scalar t = ti * (Scalar(int(M - m)) / ns) 
		         + tf * (Scalar(int(m)) / ns);

		// value of x at beginning of this interval
		x3 = x4 = xf;

		// evaluate partial derivatives at beginning of this interval
		F.Ode_ind(t, xf, f_t);
		F.Ode_dep(t, xf, E);    // E = f_x
		if( hasnan(f_t) || hasnan(E) )
		{	e = nan_vec;
			return nan_vec;
		}

		// E = I - f_x * h / 2
		for(i = 0; i < n; i++)
		{	for(j = 0; j < n; j++)
				E[i * n + j] = - E[i * n + j] * h / two;
			E[i * n + i] += one;
		}

		// LU factor the matrix E
# ifndef NDEBUG
		int sign = LuFactor(ip, jp, E);
# else
		LuFactor(ip, jp, E);
# endif
		CPPAD_ASSERT_KNOWN(
			sign != 0,
			"Error in Rosen34: I - f_x * h / 2 not invertible"
		);

		// loop over integration steps
		for(k = 0; k < 3; k++)
		{	// set location for next function evaluation
			xtmp = xf; 
			for(l = 0; l < k; l++)
			{	// loop over previous function evaluations
				Scalar bkl = b[(k-1)*2 + l];
				for(i = 0; i < n; i++)
				{	// loop over elements of x
					xtmp[i] += bkl * g[i*3 + l] * h;
				}
			}
			// ftmp = F(t + a[k] * h, xtmp)
			F.Ode(t + a[k] * h, xtmp, ftmp); 
			if( hasnan(ftmp) )
			{	e = nan_vec;
				return nan_vec;
			}

			// Form Eg for this integration step
			for(i = 0; i < n; i++)
				Eg[i] = ftmp[i] + ct[k] * f_t[i] * h;
			for(l = 0; l < k; l++)
			{	for(i = 0; i < n; i++)
					Eg[i] += cg[(k-1)*3 + l] * g[i*3 + l];
			}

			// Solve the equation E * g = Eg
			LuInvert(ip, jp, E, Eg);

			// save solution and advance x3, x4
			for(i = 0; i < n; i++)
			{	g[i*3 + k]  = Eg[i];
				x3[i]      += h * d3[k] * Eg[i];
				x4[i]      += h * d4[k] * Eg[i];
			}
		}
		// Form Eg for last update to x4 only
		for(i = 0; i < n; i++)
			Eg[i] = ftmp[i] + ct[3] * f_t[i] * h;
		for(l = 0; l < 3; l++)
		{	for(i = 0; i < n; i++)
				Eg[i] += cg[2*3 + l] * g[i*3 + l];
		}

		// Solve the equation E * g = Eg
		LuInvert(ip, jp, E, Eg);

		// advance x4 and accumulate error bound
		for(i = 0; i < n; i++)
		{	x4[i] += h * d4[3] * Eg[i];

			// cant use abs because cppad.hpp may not be included
			Scalar diff = x4[i] - x3[i];
			if( diff < zero )
				e[i] -= diff;
			else	e[i] += diff;
		}

		// advance xf for this step using x4
		xf = x4;
	}
	return xf;
}
Ejemplo n.º 5
0
void
fsort(int binno, int depth, union f_handle infiles, int nfiles, FILE *outfp,
    struct field *ftbl)
{
	u_char *weights, **keypos, *bufend, *tmpbuf;
	static u_char *buffer, **keylist;
	static size_t bufsize;
	int ntfiles, mfct = 0, total, i, maxb, lastb, panic = 0;
	int c, nelem;
	long sizes[NBINS+1];
	union f_handle tfiles, mstart = {MAXFCT-16};
	int (*get)(int, union f_handle, int, RECHEADER *,
		u_char *, struct field *);
	RECHEADER *crec;
	struct field tfield[2];
	FILE *prevfp, *tailfp[FSORTMAX+1];

	memset(tailfp, 0, sizeof(tailfp));
	prevfp = outfp;
	memset(tfield, 0, sizeof(tfield));
	if (ftbl[0].flags & R)
		tfield[0].weights = Rascii;
	else
		tfield[0].weights = ascii;
	tfield[0].icol.num = 1;
	weights = ftbl[0].weights;
	if (buffer == NULL) {
		bufsize = BUFSIZE;
		if ((buffer = malloc(bufsize)) == NULL ||
		    (keylist = calloc(MAXNUM, sizeof(u_char *))) == NULL)
			err(2, NULL);
	}
	bufend = buffer + bufsize - 1;
	if (binno >= 0) {
		tfiles.top = infiles.top + nfiles;
		get = getnext;
	} else {
		tfiles.top = 0;
		if (SINGL_FLD)
			get = makeline;
		else
			get = makekey;
	}				
	for (;;) {
		memset(sizes, 0, sizeof(sizes));
		c = ntfiles = 0;
		if (binno == weights[REC_D] &&
		    !(SINGL_FLD && ftbl[0].flags & F)) {	/* pop */
			rd_append(weights[REC_D],
			    infiles, nfiles, prevfp, buffer, bufend);
			break;
		} else if (binno == weights[REC_D]) {
			depth = 0;		/* start over on flat weights */
			ftbl = tfield;
			weights = ftbl[0].weights;
		}
		while (c != EOF) {
			keypos = keylist;
			nelem = 0;
			crec = (RECHEADER *) buffer;
			while ((c = get(binno, infiles, nfiles, crec, bufend,
			    ftbl)) == 0) {
				*keypos++ = crec->data + depth;
				if (++nelem == MAXNUM) {
					c = BUFFEND;
					break;
				}
				crec = (RECHEADER *)((char *)crec +
				    SALIGN(crec->length) + sizeof(TRECHEADER));
			}
			/*
			 * buffer was too small for data, allocate
			 * a bigger buffer.
			 */
			if (c == BUFFEND && nelem == 0) {
				bufsize *= 2;
				tmpbuf = realloc(buffer, bufsize);
				if (!tmpbuf)
					err(2, "failed to realloc buffer");
				crec = (RECHEADER *)
				    (tmpbuf + ((u_char *)crec - buffer));
				buffer = tmpbuf;
				bufend = buffer + bufsize - 1;
				continue;
			}
			if (c == BUFFEND || ntfiles || mfct) {	/* push */
				if (panic >= PANIC) {
					fstack[MAXFCT-16+mfct].fp = ftmp();
					if (radixsort((const u_char **)keylist,
					    nelem, weights, REC_D))
						err(2, NULL);
					append(keylist, nelem, depth, fstack[
					 MAXFCT-16+mfct].fp, putrec, ftbl);
					mfct++;
					/* reduce number of open files */
					if (mfct == 16 ||(c == EOF && ntfiles)) {
						fstack[tfiles.top + ntfiles].fp
						    = ftmp();
						fmerge(0, mstart, mfct, geteasy,
						  fstack[tfiles.top+ntfiles].fp,
						  putrec, ftbl);
						ntfiles++;
						mfct = 0;
					}
				} else {
					fstack[tfiles.top + ntfiles].fp= ftmp();
					onepass(keylist, depth, nelem, sizes,
					weights, fstack[tfiles.top+ntfiles].fp);
					ntfiles++;
				}
			}
		}
		get = getnext;
		if (!ntfiles && !mfct) {	/* everything in memory--pop */
			if (nelem > 1) {
				if (STABLE) {
					i = sradixsort((const u_char **)keylist,
					    nelem, weights, REC_D);
				} else {
					i = radixsort((const u_char **)keylist,
					    nelem, weights, REC_D);
				}
				if (i)
					err(2, NULL);
			}
			append(keylist, nelem, depth, outfp, putline, ftbl);
			break;					/* pop */
		}
		if (panic >= PANIC) {
			if (!ntfiles)
				fmerge(0, mstart, mfct, geteasy,
				    outfp, putline, ftbl);
			else
				fmerge(0, tfiles, ntfiles, geteasy,
				    outfp, putline, ftbl);
			break;
		}
		total = maxb = lastb = 0;	/* find if one bin dominates */
		for (i = 0; i < NBINS; i++)
		  if (sizes[i]) {
			if (sizes[i] > sizes[maxb])
				maxb = i;
			lastb = i;
			total += sizes[i];
		}
		if (sizes[maxb] < max((total / 2) , BUFSIZE))
			maxb = lastb;	/* otherwise pop after last bin */
		fstack[tfiles.top].lastb = lastb;
		fstack[tfiles.top].maxb = maxb;

			/* start refining next level. */
		get(-1, tfiles, ntfiles, crec, bufend, 0);	/* rewind */
		for (i = 0; i < maxb; i++) {
			if (!sizes[i])	/* bin empty; step ahead file offset */
				get(i, tfiles, ntfiles, crec, bufend, 0);
			else
				fsort(i, depth+1, tfiles, ntfiles, outfp, ftbl);
		}
		if (lastb != maxb) {
			if (prevfp != outfp)
				tailfp[panic] = prevfp;
			prevfp = ftmp();
			for (i = maxb+1; i <= lastb; i++)
				if (!sizes[i])
					get(i, tfiles, ntfiles, crec, bufend,0);
				else
					fsort(i, depth+1, tfiles, ntfiles,
					    prevfp, ftbl);
		}

		/* sort biggest (or last) bin at this level */
		depth++;
		panic++;
		binno = maxb;
		infiles.top = tfiles.top;	/* getnext will free tfiles, */
		nfiles = ntfiles;		/* so overwrite them */
	}
	if (prevfp != outfp) {
		concat(outfp, prevfp);
		fclose(prevfp);
	}
	for (i = panic; i >= 0; --i)
		if (tailfp[i]) {
			concat(outfp, tailfp[i]);
			fclose(tailfp[i]);
		}
}
Ejemplo n.º 6
0
Vector Runge45(
	Fun           &F ,
	size_t         M ,
	const Scalar &ti ,
	const Scalar &tf ,
	const Vector &xi ,
	Vector       &e )
{
	CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;

	// check numeric type specifications
	CheckNumericType<Scalar>();

	// check simple vector class specifications
	CheckSimpleVector<Scalar, Vector>();

	// Cash-Karp parameters for embedded Runge-Kutta method
	// are static to avoid recalculation on each call and
	// do not use Vector to avoid possible memory leak
	static Scalar a[6] = {
		Scalar(0),
		Scalar(1) / Scalar(5),
		Scalar(3) / Scalar(10),
		Scalar(3) / Scalar(5),
		Scalar(1),
		Scalar(7) / Scalar(8)
	};
	static Scalar b[5 * 5] = {
		Scalar(1) / Scalar(5),
		Scalar(0),
		Scalar(0),
		Scalar(0),
		Scalar(0),

		Scalar(3) / Scalar(40),
		Scalar(9) / Scalar(40),
		Scalar(0),
		Scalar(0),
		Scalar(0),

		Scalar(3) / Scalar(10),
		-Scalar(9) / Scalar(10),
		Scalar(6) / Scalar(5),
		Scalar(0),
		Scalar(0),

		-Scalar(11) / Scalar(54),
		Scalar(5) / Scalar(2),
		-Scalar(70) / Scalar(27),
		Scalar(35) / Scalar(27),
		Scalar(0),

		Scalar(1631) / Scalar(55296),
		Scalar(175) / Scalar(512),
		Scalar(575) / Scalar(13824),
		Scalar(44275) / Scalar(110592),
		Scalar(253) / Scalar(4096)
	};
	static Scalar c4[6] = {
		Scalar(2825) / Scalar(27648),
		Scalar(0),
		Scalar(18575) / Scalar(48384),
		Scalar(13525) / Scalar(55296),
		Scalar(277) / Scalar(14336),
		Scalar(1) / Scalar(4),
	};
	static Scalar c5[6] = {
		Scalar(37) / Scalar(378),
		Scalar(0),
		Scalar(250) / Scalar(621),
		Scalar(125) / Scalar(594),
		Scalar(0),
		Scalar(512) / Scalar(1771)
	};

	CPPAD_ASSERT_KNOWN(
		M >= 1,
		"Error in Runge45: the number of steps is less than one"
	);
	CPPAD_ASSERT_KNOWN(
		e.size() == xi.size(),
		"Error in Runge45: size of e not equal to size of xi"
	);
	size_t i, j, k, m;              // indices

	size_t  n = xi.size();           // number of components in X(t)
	Scalar  ns = Scalar(int(M));     // number of steps as Scalar object
	Scalar  h = (tf - ti) / ns;      // step size
	Scalar  zero_or_nan = Scalar(0); // zero (nan if Ode returns has a nan)
	for(i = 0; i < n; i++)           // initialize e = 0
		e[i] = zero_or_nan;

	// vectors used to store values returned by F
	Vector fh(6 * n), xtmp(n), ftmp(n), x4(n), x5(n), xf(n);

	xf = xi;           // initialize solution
	for(m = 0; m < M; m++)
	{	// time at beginning of this interval
		// (convert to int to avoid MS compiler warning)
		Scalar t = ti * (Scalar(int(M - m)) / ns)
		         + tf * (Scalar(int(m)) / ns);

		// loop over integration steps
		x4 = x5 = xf;   // start x4 and x5 at same point for each step
		for(j = 0; j < 6; j++)
		{	// loop over function evaluations for this step
			xtmp = xf;  // location for next function evaluation
			for(k = 0; k < j; k++)
			{	// loop over previous function evaluations
				Scalar bjk = b[ (j-1) * 5 + k ];
				for(i = 0; i < n; i++)
				{	// loop over elements of x
					xtmp[i] += bjk * fh[i * 6 + k];
				}
			}
			// ftmp = F(t + a[j] * h, xtmp)
			F.Ode(t + a[j] * h, xtmp, ftmp);

			// if ftmp has a nan, set zero_or_nan to nan
			for(i = 0; i < n; i++)
				zero_or_nan *= ftmp[i];

			for(i = 0; i < n; i++)
			{	// loop over elements of x
				Scalar fhi    = ftmp[i] * h;
				fh[i * 6 + j] = fhi;
				x4[i]        += c4[j] * fhi;
				x5[i]        += c5[j] * fhi;
				x5[i]        += zero_or_nan;
			}
		}
		// accumulate error bound
		for(i = 0; i < n; i++)
		{	// cant use abs because cppad.hpp may not be included
			Scalar diff = x5[i] - x4[i];
			e[i] += fabs(diff);
			e[i] += zero_or_nan;
		}

		// advance xf for this step using x5
		xf = x5;
	}
	return xf;
}
Ejemplo n.º 7
0
void
fsort(struct filelist *filelist, int nfiles, FILE *outfp, struct field *ftbl)
{
	RECHEADER **keylist;
	RECHEADER **keypos, **keyp;
	RECHEADER *buffer;
	size_t bufsize = DEFBUFSIZE;
	u_char *bufend;
	int mfct = 0;
	int c, nelem;
	get_func_t get;
	RECHEADER *crec;
	RECHEADER *nbuffer;
	FILE *fp, *tmp_fp;
	int file_no;
	int max_recs = DEBUG('m') ? 16 : MAXNUM;

	buffer = allocrec(NULL, bufsize);
	bufend = (u_char *)buffer + bufsize;
	/* Allocate double length keymap for radix_sort */
	keylist = malloc(2 * max_recs * sizeof(*keylist));
	if (buffer == NULL || keylist == NULL)
		err(2, "failed to malloc initial buffer or keylist");

	if (SINGL_FLD)
		/* Key and data are one! */
		get = makeline;
	else
		/* Key (merged key fields) added before data */
		get = makekey;

	file_no = 0;
	fp = fopen(filelist->names[0], "r");
	if (fp == NULL)
		err(2, "%s", filelist->names[0]);

	/* Loop through reads of chunk of input files that get sorted
	 * and then merged together. */
	for (;;) {
		keypos = keylist;
		nelem = 0;
		crec = buffer;
		makeline_copydown(crec);

		/* Loop reading records */
		for (;;) {
			c = get(fp, crec, bufend, ftbl);
			/* 'c' is 0, EOF or BUFFEND */
			if (c == 0) {
				/* Save start of key in input buffer */
				*keypos++ = crec;
				if (++nelem == max_recs) {
					c = BUFFEND;
					break;
				}
				crec = (RECHEADER *)(crec->data + SALIGN(crec->length));
				continue;
			}
			if (c == EOF) {
				/* try next file */
				if (++file_no >= nfiles)
					/* no more files */
					break;
				fp = fopen(filelist->names[file_no], "r");
				if (fp == NULL)
					err(2, "%s", filelist->names[file_no]);
				continue;
			}
			if (nelem >= max_recs
			    || (bufsize >= MAXBUFSIZE && nelem > 8))
				/* Need to sort and save this lot of data */
				break;

			/* c == BUFFEND, and we can process more data */
			/* Allocate a larger buffer for this lot of data */
			bufsize *= 2;
			nbuffer = allocrec(buffer, bufsize);
			if (!nbuffer) {
				err(2, "failed to realloc buffer to %zu bytes",
					bufsize);
			}

			/* patch up keylist[] */
			for (keyp = &keypos[-1]; keyp >= keylist; keyp--)
				*keyp = nbuffer + (*keyp - buffer);

			crec = nbuffer + (crec - buffer);
			buffer = nbuffer;
			bufend = (u_char *)buffer + bufsize;
		}

		/* Sort this set of records */
		radix_sort(keylist, keylist + max_recs, nelem);

		if (c == EOF && mfct == 0) {
			/* all the data is (sorted) in the buffer */
			append(keylist, nelem, outfp,
			    DEBUG('k') ? putkeydump : putline);
			break;
		}

		/* Save current data to a temporary file for a later merge */
		if (nelem != 0) {
			tmp_fp = ftmp();
			append(keylist, nelem, tmp_fp, putrec);
			save_for_merge(tmp_fp, geteasy, ftbl);
		}
		mfct = 1;

		if (c == EOF) {
			/* merge to output file */
			merge_sort(outfp, 
			    DEBUG('k') ? putkeydump : putline, ftbl);
			break;
		}
	}

	free(keylist);
	keylist = NULL;
	free(buffer);
	buffer = NULL;
}
Ejemplo n.º 8
0
void nuint09_1pi1(int isample, int single_pion_sources=0, int stage=1)
{
  cout << " ***** running: 1PI.1" << endl;

  if(isample<0 || isample >= kNSamples) return;
  if(single_pion_sources<0 || single_pion_sources>2) return;

  const char * label = kLabel[isample];

  int A = kA[isample];

  // get cross section graphs

  TFile fsig("../sig/splines.root","read");
  TDirectory * sig_dir = (TDirectory *) fsig.Get(label);  

  TGraph * sig_graph_totcc = (TGraph*) sig_dir->Get("tot_cc");

  // range & spacing

  const int    nEnu   = 60;
  const double Enumin =  0.05;
  const double Enumax = 30.00;

  // create output stream

  ostringstream out_filename;
  out_filename << label;

  if      (single_pion_sources==0) out_filename << ".1pi_1a.";
  else if (single_pion_sources==1) out_filename << ".1pi_1b.";
  else if (single_pion_sources==2) out_filename << ".1pi_1c.";

  if(stage==0) out_filename << "no_FSI.";

  out_filename << "sig1pi_vs_Enu.data";
  ofstream out_stream(out_filename.str().c_str(), ios::out);

  // write out txt file

  out_stream << "# [" << label << "]" << endl;
  out_stream << "#  " << endl;
  out_stream << "# [1PI.1]:" << endl;
  out_stream << "#  Total cross section for 1 pion (pi+ only) production as a function of energy" << endl;
  if(stage==0) {
    out_stream << "#  ***** NO FSI: The {X pi+} state is a primary hadronic state" << endl;
  }
  if(single_pion_sources==0) {
     out_stream << "#  1pi sources: All" << endl;
  }
  else if(single_pion_sources==1) {
     out_stream << "#  1pi sources: P33(1232) resonance only" << endl;
  }
  else if(single_pion_sources==2) {
     out_stream << "#  1pi sources: All resonances only" << endl;
  }
  out_stream << "#  " << endl;
  out_stream << "#  Note:" << endl;
  out_stream << "#   - neutrino energy E in GeV, linear spacing between Emin = " << Enumin << " GeV, Emax = " << Enumax << " GeV "  << endl;
  out_stream << "#   - cross sections in 1E-38 cm^2 " << endl;
  out_stream << "#   - quoted cross section is nuclear cross section divided with number of nucleons A" << endl;
  out_stream << "#  Columns:" << endl;
  out_stream << "#  |  Energy     |   sig(nu_mu + A -> mu- 1pi+ X)   |  "  << endl;

  out_stream << setiosflags(ios::fixed) << setprecision(6);

  //
  // load event data
  // 
    
  TChain * chain = new TChain("gst");
  
  // loop over CC/NC cases
  for(int iwkcur=0; iwkcur<kNWCur; iwkcur++) {
       // loop over runs for current case
       for(int ir=0; ir<kNRunsPerCase; ir++) {
          // build filename
          ostringstream filename;
          int run_number = kRunNu1PI1[isample][iwkcur][ir];

          cout << "isample = " << isample << ", iwkcur = " << iwkcur << ", ir = " << ir << ", run = " << run_number << endl;

          filename << "../gst/gntp." << run_number << ".gst.root";
          // add to chain
          cout << "Adding " << filename.str() << " to event chain" << endl;
          chain->Add(filename.str().c_str());
       }
  } 

  //
  // book histograms
  //
  TH1D * hst_cc1pip = new TH1D("hst_cc1pip","CC1pi+ events, Enu spectrum", nEnu, Enumin, Enumax);
  TH1D * hst_allcc  = new TH1D("hst_allcc", "all CC events, Enu spectrum", nEnu, Enumin, Enumax);

  //
  // fill histograms
  //

  chain->Draw("Ev>>hst_allcc", "cc","GOFF");

  if(stage==1) {
    if(single_pion_sources==0) {
      //all sources
      chain->Draw("Ev>>hst_cc1pip","cc&&pdgf==211&&nfpip==1&&nfpim==0&&nfpi0==0","GOFF");
    }
    else if(single_pion_sources==1) {
      //P33(1232) only
      chain->Draw("Ev>>hst_cc1pip","cc&&resid==0&&res&&pdgf==211&&nfpip==1&&nfpim==0&&nfpi0==0","GOFF");
    }
    else if(single_pion_sources==2) {
      //all resonances only
      chain->Draw("Ev>>hst_cc1pip","cc&&res&&pdgf==211&&nfpip==1&&nfpim==0&&nfpi0==0","GOFF");
    }
  }
  else if(stage==0) {
    if(single_pion_sources==0) {
      //all sources
      chain->Draw("Ev>>hst_cc1pip","cc&&pdgi==211&&nipip==1&&nipim==0&&nipi0==0","GOFF");
    }
    else if(single_pion_sources==1) {
      //P33(1232) only
      chain->Draw("Ev>>hst_cc1pip","cc&&resid==0&&res&&pdgi==211&&nipip==1&&nipim==0&&nipi0==0","GOFF");
    }
    else if(single_pion_sources==2) {
      //all resonances only
      chain->Draw("Ev>>hst_cc1pip","cc&&res&&pdgi==211&&nipip==1&&nipim==0&&nipi0==0","GOFF");
    }
  }

  cout << "CC1pi+ nevents: " << hst_cc1pip->GetEntries() << endl;
  cout << "ALLCC  nevents: " << hst_allcc->GetEntries() << endl;

  //
  // compute sig(CC1pi+) and write out in txt file expected by NuINT organizers
  // Also write out root graph in temp file to be re-used at later benchmarking calc
  //

  double e[nEnu], sig[nEnu];

  for(int i=1; i <= hst_cc1pip->GetNbinsX(); i++) {

     double Enu = hst_cc1pip->GetBinCenter(i);

     double Ncc1pip = hst_cc1pip -> GetBinContent(i);
     double Nallcc  = hst_allcc  -> GetBinContent(i);

     double sig_cc1pip=0;
     if(Nallcc>0) { sig_cc1pip = (Ncc1pip/Nallcc) * sig_graph_totcc->Eval(Enu) / A; }

     out_stream << setw(15) << Enu << setw(15) << sig_cc1pip << endl;

     e  [i-1] = Enu;
     sig[i-1] = sig_cc1pip;
  }

  out_stream.close();

  TFile ftmp("./cc1pip_tmp.root","recreate");
  TGraph * grCC1pip = new TGraph(nEnu,e,sig);  
  grCC1pip->Write("CC1pip");
  hst_allcc->Write();
  hst_cc1pip->Write();

  // visual inspection
  TCanvas * c1 = new TCanvas("c1","",20,20,500,500);
  grCC1pip->Draw("alp");
  c1->Update();

  ftmp.Close();

  delete chain;
}
void calcEscaleSystematics(TString lumiTag="DY_j22_19712pb", 
int saveTexTable=0){

  int nUnfoldingBins = DYTools::getTotalNumberOfBins();
  TVectorD observedYields(nUnfoldingBins);
  TVectorD observedYieldsErr(nUnfoldingBins);
  TVectorD dummyArr(nUnfoldingBins);
  TVectorD unfoldedYields(nUnfoldingBins);

  // 
  // Indicators (and also counters) whether the data was present
  //
  int countEScaleSyst=0;
  int countResidualShape=0;
  int countEtaSyst=0;
  int countFittingShape=0;
  std::vector<TString> usedFiles;

  ElectronEnergyScale escale("Date20120802_default");

  //
  // Calculate error associated with statistical 
  // uncertainty on the energy scale factors
  //
  TVectorD unfoldedYieldsMean(nUnfoldingBins);
  TVectorD unfoldedYieldsRMS(nUnfoldingBins);
  TVectorD unfoldedYieldsSquaredMean(nUnfoldingBins);

  unfoldedYieldsMean = 0;
  unfoldedYieldsRMS = 0;
  unfoldedYieldsSquaredMean = 0;

  TString matrixFileName = TString("../root_files/constants/") + lumiTag + 
    TString("/detResponse_unfolding_constants") + DYTools::analysisTag + TString("_PU.root");
  const int nFiles1 = 20;  // expected number of files
  if (1)
  for(int ifile=0; ifile<nFiles1; ifile++){
    int seed = 1001+ifile;
    escale.randomizeEnergyScaleCorrections(seed);
    TString fname = TString("../root_files/yields/") + lumiTag + 
      TString("_escale_randomized/yields_bg-subtracted") + DYTools::analysisTag + 
      TString("__") + escale.calibrationSetShortName();
    fname += ".root";
    TFile file(fname);
    if (!file.IsOpen()) {
      std::cout << "failed to open a file <" << fname << ">\n";
    }
    else {
      file.Close();

      // register
      usedFiles.push_back(fname);
      // work with data
      int res=	(readData(fname, observedYields,observedYieldsErr,dummyArr) == 1)
	&& (applyUnfoldingLocal(observedYields,unfoldedYields,matrixFileName) == 1);
      if (res==1) {
	countEScaleSyst++;
	//std::cout << "unfoldedYields for seed=" << seed << ": "; unfoldedYields.Print();
	// Accumulate mean and RMS
	for(int idx = 0; idx < nUnfoldingBins; idx++){
	  unfoldedYieldsMean[idx] += unfoldedYields[idx];
	  unfoldedYieldsSquaredMean[idx] += unfoldedYields[idx]*unfoldedYields[idx];
	}
      }
    }
  }

  // Final calculation of the mean and RMS for Smearing
  TVectorD escaleRandomizedSystRelative(nUnfoldingBins);
  if (countEScaleSyst) {
    for(int idx = 0; idx < nUnfoldingBins; idx++){
      unfoldedYieldsMean[idx] = unfoldedYieldsMean[idx]/double(countEScaleSyst);
      unfoldedYieldsSquaredMean[idx] = unfoldedYieldsSquaredMean[idx]/double(countEScaleSyst);
      unfoldedYieldsRMS[idx] = sqrt(unfoldedYieldsSquaredMean[idx] - 
				  unfoldedYieldsMean[idx]*unfoldedYieldsMean[idx]);
      escaleRandomizedSystRelative[idx] = unfoldedYieldsRMS[idx]/unfoldedYieldsMean[idx];
    }
    //std::cout << "unfoldedYieldsMean=" << ": "; unfoldedYieldsMean.Print();
    //std::cout << "escaleRandomizedSystRelative: "; escaleRandomizedSystRelative.Print();
  }
  else {
    std::cout << "escaleRandomizomized files were not found\n";
  }

  //
  // Calculate error related to the difference between
  // data and MC mass distribution shape after all corrections
  // had been applied to data and MC. "Residual differences"
  //
  TVectorD unfoldedYieldsVariation(nUnfoldingBins);
  TVectorD escaleResidualDiffSystRelative(nUnfoldingBins);
  TString fname = TString("../root_files/yields/") + lumiTag + 
    TString("/yields_bg-subtracted") + DYTools::analysisTag + TString(".root");
  int res=1;
  {
  TFile file(fname);
  if (file.IsOpen()) {
    file.Close();
    if (readData(fname,observedYields,observedYieldsErr,dummyArr) != 1) {
      std::cout << "failed to get data from file <" << fname << ">\n";
      throw 2;
    }
  //
    matrixFileName = TString("../root_files/constants/") + lumiTag + 
      TString("/detResponse_unfolding_constants") + DYTools::analysisTag + TString("_PU.root");
    res=applyUnfoldingLocal(observedYields, unfoldedYields, matrixFileName);
    if (res==1) usedFiles.push_back(matrixFileName);

  //
    if (res==1) {
      matrixFileName = TString("../root_files/constants/") + lumiTag + 
	TString("_escale_residual/unfolding_constants") + DYTools::analysisTag +
	TString("_escaleResidual.root");
      res=applyUnfoldingLocal(observedYields, unfoldedYieldsVariation, matrixFileName);
      if (res==1) {
	countResidualShape++;
	usedFiles.push_back(matrixFileName);
      }
    }
  }
  if (res==1) {
    for(int idx=0; idx<nUnfoldingBins; idx++){
      escaleResidualDiffSystRelative[idx] = 
	fabs(unfoldedYields[idx] - unfoldedYieldsVariation[idx])
	/(unfoldedYields[idx] + unfoldedYieldsVariation[idx]);
    }
  }
  }

  //
  // Calculate error related to extra smearing function shape
  //
  std::vector<TString> shapeNames;
  shapeNames.push_back("_6binNegs_BreitWigner_20120802");
  shapeNames.push_back("_6binNegs_Voigtian_20120802");
  std::vector<TVectorD*> unfoldedYieldsShape;
  if (1)
  for (unsigned int i=0; i<shapeNames.size(); ++i) {
    TVectorD observedYieldsShape(nUnfoldingBins);
    TVectorD observedYieldsShapeErr(nUnfoldingBins);
    TString shapeFName=TString("../root_files/yields/") + lumiTag + 
      TString("_escale_shape/yields_bg-subtracted") + DYTools::analysisTag +
      TString("_") + shapeNames[i] + TString(".root");
    TFile fShape(shapeFName);
    if (fShape.IsOpen()) {
      fShape.Close();
      usedFiles.push_back(shapeFName);
      if ( readData(shapeFName,observedYieldsShape,observedYieldsShapeErr,dummyArr) !=1) {
	std::cout << "failed to load data from <" << shapeFName << ">\n";
	throw 2;
      }
      TString matrixFileNameShape = TString("../root_files/constants/") + lumiTag + 
	TString("_escale_shape/unfolding_constants") + DYTools::analysisTag +
	TString("_") + shapeNames[i] + TString(".root");
      TVectorD *shapeYields=new TVectorD(nUnfoldingBins);
      {
	TFile ftmp(TString("tmp_") + shapeNames[i] + TString(".root"),"recreate");
	observedYieldsShape.Write("YieldsSignal");
	TVectorD tmp(nUnfoldingBins);
	tmp=0;
	tmp.Write("YieldsSignalErr");
	tmp.Write("YieldsSignalSystErr");
	ftmp.Close();
      }
      res=applyUnfoldingLocal(observedYieldsShape, *shapeYields, matrixFileNameShape);
      if (res) {
	countFittingShape++;
	usedFiles.push_back(matrixFileNameShape);
	unfoldedYieldsShape.push_back(shapeYields);
      }
      else delete shapeYields;
    }
  }
  
  //
  TVectorD escaleFitShapeSystRelative(nUnfoldingBins);
  for(int idx=0; idx<nUnfoldingBins; idx++){
    double min = unfoldedYields[idx];
    double max = unfoldedYields[idx];
    for (unsigned int iShape=0; iShape<unfoldedYieldsShape.size(); ++iShape) {
      min = TMath::Min( min, (*unfoldedYieldsShape[iShape])[idx] );
      max = TMath::Max( max, (*unfoldedYieldsShape[iShape])[idx] );
    }
    escaleFitShapeSystRelative[idx] = fabs(max-min)/(max+min);
  }

  //
  // Calculate error related to eta binning
  //
  std::vector<TString> etaBinNames;
  etaBinNames.push_back("_2binNegs_Gauss_20120802");
  etaBinNames.push_back("_3EB3EENegs_Gauss_20120802");
  etaBinNames.push_back("_4binNegs_Gauss_20120802");
  etaBinNames.push_back("_4EB3EENegs_Gauss_20120802");
  etaBinNames.push_back("_5binNegs_Gauss_20120802");
  etaBinNames.push_back("_6binNegs_Gauss_20120802"); // default
  etaBinNames.push_back("_6bins_Gauss_20120802");
  std::vector<TVectorD*> unfoldedYieldsEta;
  unfoldedYieldsEta.reserve(etaBinNames.size());
  if (1)
  for (unsigned int i=0; i<etaBinNames.size(); ++i) {
    TString fEtaFileName=TString("../root_files/yields/") + lumiTag + 
      TString("_escale_eta/yields_bg-subtracted") + DYTools::analysisTag +
      TString("_") + etaBinNames[i] + TString(".root");
    TFile fEta(fEtaFileName);
    if (fEta.IsOpen()) {
      fEta.Close();
      usedFiles.push_back(fEtaFileName);
      TVectorD observedYieldsEta(nUnfoldingBins);
      TVectorD observedYieldsEtaErr(nUnfoldingBins);
      if (readData(fEtaFileName,observedYieldsEta,observedYieldsEtaErr,dummyArr)!=1) {
	std::cout << "failed to get info from <" << fEtaFileName << ">\n";
	throw 2;
      }
      matrixFileName = TString("../root_files/constants/") + lumiTag + 
	TString("_escale_eta/unfolding_constants") + DYTools::analysisTag +
	TString("_") + etaBinNames[i] + TString(".root");
      TVectorD *unfYields = new TVectorD(nUnfoldingBins);
      res=applyUnfoldingLocal(observedYieldsEta, *unfYields, matrixFileName);
      if (res==1) {
	countEtaSyst++;
	usedFiles.push_back(matrixFileName);
	unfoldedYieldsEta.push_back(unfYields);
      }
      else {
	delete unfYields;
      }
    }
  }

  //
  TVectorD escaleEtaBinSystRelative(nUnfoldingBins);
  for(int idx=0; idx<nUnfoldingBins; idx++){
    double min = unfoldedYields[idx];
    double max = unfoldedYields[idx];
    for (unsigned int iShape=0; iShape<unfoldedYieldsEta.size(); ++iShape) {
      min = TMath::Min( min, (*unfoldedYieldsEta[iShape])[idx] );
      max = TMath::Max( max, (*unfoldedYieldsEta[iShape])[idx] );
    }
    escaleEtaBinSystRelative[idx] = fabs(max-min)/(max+min);
  }

  // 
  // Put all errors together
  //
  TVectorD escaleSystPercent(nUnfoldingBins);
  for(int idx = 0; idx < nUnfoldingBins; idx++){
    escaleSystPercent[idx] = 100.0 *
      sqrt(
	   escaleRandomizedSystRelative[idx]*escaleRandomizedSystRelative[idx]
	   + escaleResidualDiffSystRelative[idx]*escaleResidualDiffSystRelative[idx]
	   + escaleFitShapeSystRelative[idx]*escaleFitShapeSystRelative[idx]
	   + escaleEtaBinSystRelative[idx]*escaleEtaBinSystRelative[idx]
	   );
  }

  // Don't write TObject part of the objects
  TDescriptiveInfo_t::Class()->IgnoreTObjectStreamer();
  TDescriptiveInfo_t *info= new TDescriptiveInfo_t();
  std::vector<std::string> *lines = (info) ? (& info->_info) : NULL;

  const int bufsize=300;
  char buf[bufsize];
  std::string sbuf;


  snprintf(buf,bufsize," Summary of successful loads:\n");
  printf(buf);
  if (lines) lines->push_back(buf);
  snprintf(buf,bufsize,"  escale systematics   file count=  %2d\n", countEScaleSyst);
  printf(buf);
  if (lines) lines->push_back(buf);
  snprintf(buf,bufsize,"  residual shape syst. file count=  %2d\n", countResidualShape);
  printf(buf);
  if (lines) lines->push_back(buf);
  snprintf(buf,bufsize,"  eta systematics      file count=  %2d\n", countEtaSyst);
  printf(buf);
  if (lines) lines->push_back(buf);
  snprintf(buf,bufsize,"  fitting shape        file count=  %2d\n", countFittingShape);
  printf(buf);
  if (lines) { lines->push_back(buf); lines->push_back("\n"); }
  std::cout << "\n";

  int listFilesOnScreen=1;
  snprintf(buf,bufsize," Loaded files:\n");
  if (listFilesOnScreen) printf(buf);
  if (lines) lines->push_back(buf);
  for (unsigned int i=0; i<usedFiles.size(); ++i) {
    snprintf(buf,bufsize," %s\n",usedFiles[i].Data());
    if (listFilesOnScreen) printf(buf);
    if (lines) lines->push_back(buf);
  }
  std::cout << std::endl;


  if (saveTexTable) {
    std::vector<TString> headers;
    std::vector<int> padding;
    std::vector<TVectorD*> data;
    std::vector<double> factors;
    headers.push_back("mass range");
    headers.push_back("rapidity range");
    headers.push_back("\\multicolumn{1}{c|}{statistical, \\%}"); data.push_back(&escaleRandomizedSystRelative); factors.push_back(100.); padding.push_back(6);
    headers.push_back("\\multicolumn{1}{c|}{shape, \\%}"); data.push_back(&escaleFitShapeSystRelative); factors.push_back(100.); padding.push_back(4);
    headers.push_back("\\multicolumn{1}{c|}{residual, \\%}"); data.push_back(&escaleResidualDiffSystRelative); factors.push_back(100.); padding.push_back(5);
    headers.push_back("\\multicolumn{1}{c|}{$\\eta$ binning, \\%}"); data.push_back(&escaleEtaBinSystRelative); factors.push_back(100.); padding.push_back(6);
    headers.push_back("\\multicolumn{1}{c|}{total, \\%}"); data.push_back(&escaleSystPercent); factors.push_back(1.); padding.push_back(3);
    
    TString texFName=TString("../root_files/systematics/") + lumiTag + 
      TString("/escale_systematics") + DYTools::analysisTag + TString("_tmp.tex");
    printTexTable(texFName,headers,padding,data,factors);
  }

  TString finalFName=TString("../root_files/systematics/") + lumiTag + 
    TString("/escale_systematics") + DYTools::analysisTag + TString("_tmp.root");
  TFile fout(finalFName,"recreate");
  unfolding::writeBinningArrays(fout);
  escaleRandomizedSystRelative.Write("escaleRandomizedSystRelativeFI");
  escaleFitShapeSystRelative.Write("escaleFitShapeSystRelativeFI");
  escaleResidualDiffSystRelative.Write("escaleResidualDiffSystRelativeFI");
  escaleEtaBinSystRelative.Write("escaleEtaBinSystRelativeFI");
  escaleSystPercent.Write("escaleSystPercentFI");

  if (info) {
    TTree *infoTree = new TTree("Description","description");
    infoTree->Branch("description","TDescriptiveInfo_t",&info);
    infoTree->Fill();
    infoTree->Write();
  }
  fout.Close();

  return;
}
Ejemplo n.º 10
0
void
fmerge(int binno, union f_handle files, int nfiles,
    int (*get)(int, union f_handle, int, RECHEADER *, u_char *, struct field *),
    FILE *outfp, void (*fput)(RECHEADER *, FILE *), struct field *ftbl)
{
	FILE *tout;
	int i, j, last;
	void (*put)(RECHEADER *, FILE *);
	struct tempfile *l_fstack;

	wts = ftbl->weights;
	if (!UNIQUE && SINGL_FLD && (ftbl->flags & F))
		wts1 = (ftbl->flags & R) ? Rascii : ascii;
	if (cfilebuf == NULL) {
		cfilebuf = malloc(MAXLLEN + sizeof(MFILE));
		if (cfilebuf == NULL)
			errx(2, "cannot allocate memory");
	}

	i = min(16, nfiles) * LALIGN(MAXLLEN + sizeof(MFILE));
	if (i > bufsize) {
		bufsize = i;
		if ((buffer = realloc(buffer, bufsize)) == NULL)
			err(2, NULL);
	}

	if (binno >= 0)
		l_fstack = fstack + files.top;
	else
		l_fstack = fstack;

	while (nfiles) {
		put = putrec;
		for (j = 0; j < nfiles; j += 16) {
			if (nfiles <= 16) {
				tout = outfp;
				put = fput;
			}
			else
				tout = ftmp();
			last = min(16, nfiles - j);
			if (binno < 0) {
				for (i = 0; i < last; i++)
					if (!(l_fstack[i+MAXFCT-1-16].fp =
					    fopen(files.names[j + i], "r")))
						err(2, "%s", files.names[j+i]);
				merge(MAXFCT-1-16, last, get, tout, put, ftbl);
			} else {
				for (i = 0; i< last; i++)
					rewind(l_fstack[i+j].fp);
				merge(files.top+j, last, get, tout, put, ftbl);
			}
			if (nfiles > 16)
				l_fstack[j/16].fp = tout;
		}
		nfiles = (nfiles + 15) / 16;
		if (nfiles == 1)
			nfiles = 0;
		if (binno < 0) {
			binno = 0;
			get = geteasy;
			files.top = 0;
		}
	}
}