def fit_allgasdata( E, conservative=True ) :
	A = [] # design matrix
	Y = [] # target values for the fit
	for e in E :
		for d in e['data'] :
			A.append( [ e['D47eq']/d['sD47'], d['d47']/d['sD47'], 1./d['sD47'] ] )
			Y.append( d['D47'] / d['sD47'] )
	A,Y = numpy.array(A), numpy.array(Y)
	f = linalg.lstsq(A,Y.T)[0] # best-fit parameters
	CM = linalg.inv(linalg.dot(A.T,A)) # covariance matrix of fit parameters
	if conservative :
		# Scale up uncertainties in the fit parameters if the goodnes-of-fit is worse than average.
		# To some extent, this helps account for external errors in the gas line data.
		chi2 = sum( ( Y - linalg.dot( A, f ) )**2 )
		nf = sum([len(e['data']) for e in E]) -3
		if chi2 > nf :
			CM = CM * chi2 / nf
	return f,CM
def fit_gaslines( E, conservative=True ) :
	A = [] # design matrix
	Y = [] # target values for the fit
	nE = len(E)
	N = sum([len(e['data']) for e in E])
	r = 0
	for e in E :
		v = [0.]*nE
		v[r] = 1.
		r = r + 1
		for d in e['data'] :
			A.append( scipy.array( [ d['d47'] ] + v ) / d['sD47'] )
			Y.append( d['D47'] / d['sD47'] )
	A,Y = scipy.array(A), scipy.array(Y)
	f = linalg.lstsq(A,Y.T)[0] # best-fit parameters
	C = linalg.inv(linalg.dot(A.T,A)) # covariance matrix of fit parameters
	if conservative :
		# Scale up uncertainties in the fit parameters if the goodnes-of-fit is worse than average.
		# To some extent, this helps account for external errors in the gas line data.
		chi2 = sum( ( Y - linalg.dot( A, f ) )**2 )
		nf = N-3
		if chi2 > nf :
			C = C * chi2 / nf
	return f,C