Beispiel #1
0
def compute_chi2(flux, ferr=None):
    """Compute the chi2 distance matrix.

    Parameters
    ----------
    flux : numpy.ndarray
        Array [Nspec, Npix] of spectra or templates where Nspec is the number of
        spectra and Npix is the number of pixels.
    ferr : numpy.ndarray
        Uncertainty spectra ccorresponding to flux (default None).

    Returns
    -------
    Tuple of (chi2, amp) where:
        chi2 : numpy.ndarray
            Chi^2 matrix [Nspec, Nspec] between all combinations of spectra.
        amp : numpy.ndarray
            Amplitude matrix [Nspec, Nspec] between all combinations of spectra.

    """
    from SetCoverPy import mathutils

    nspec, npix = flux.shape
    if ferr is None:
        ferr = np.ones_like(flux)

    chi2 = np.zeros((nspec, nspec)).astype('f4')
    amp = np.zeros((nspec, nspec)).astype('f4')

    for ii in range(nspec):
        if ii % 500 == 0 or ii == 0:
            log.info(
                'Computing chi2 matrix for spectra {}-{} out of {}.'.format(
                    (ii % 500) * 500, np.min(
                        ((ii + 1) * (ii % 500), nspec - 1)), nspec))
        xx = flux[ii, :].reshape(1, npix)
        xxerr = ferr[ii, :].reshape(1, npix)
        amp1, chi21 = mathutils.quick_amplitude(xx, flux, xxerr, ferr, niter=1)
        chi2[ii, :] = chi21
        amp[ii, :] = amp1

    return chi2, amp
Beispiel #2
0
newwave = tmpwave
newflux = tmpflux
newivar = tmpivar
tmpchi2 = n.zeros((iuse.size, iuse.size))
A = n.zeros((iuse.size, iuse.size))

print("creates the matrix", time.time() - t0, 's', newflux.shape)
tmp_yerr = 1. / n.sqrt(newivar[:, iuse].T.reshape(iuse.size, newwave.size))
tmp_y = newflux[:, iuse].T
for i in n.arange(iuse.size):
    #print(i)
    tmp_x = newflux[:, iuse[i]].T.reshape(1, newwave.size)
    tmp_xerr = 1. / n.sqrt(newivar[:, iuse[i]].T.reshape(1, newwave.size))
    #print(tmp_x, tmp_y, tmp_xerr, tmp_yerr)
    A_tmp, chi2_tmp = mathutils.quick_amplitude(tmp_x, tmp_y, tmp_xerr,
                                                tmp_yerr)
    A[i, :] = A_tmp
    tmpchi2[i, :] = chi2_tmp

chi2 = tmpchi2 / (iuse.size - 1)  # reduced chi2

#pcs = n.array([1,10,25,50,75,90,99])
#pcs = n.array([16,17,18,19,20,21,22, 23, 24])
#scrs = scoreatpercentile(n.ravel(chi2), [16,17,18,19,20,21,22, 23, 24])

#scr = scoreatpercentile(n.ravel(chi2), 20 )
scr = scoreatpercentile(n.ravel(chi2), 10)

chi2_min = scr  # 0.05 # the minimum distance, the only free paramter
a_matrix = chi2 < chi2_min  # relationship matrix
cost = n.ones(iuse.size)
Beispiel #3
0
def make_archetype(stack, file_input, percentile=20, sn_min = 1.5):
	print('starts archetype for',file_input, time.time()-t0)
	try:
		out_name = 'archetype_'+os.path.basename(stack[file_input].out_file)+'_snMin_'+str(sn_min)+'_percentile_'+str(percentile)
		allflux  = n.loadtxt(stack[file_input].out_file+'.specMatrix.dat'      , unpack=True )      #, specMatrix)
		allsig   = n.loadtxt(stack[file_input].out_file+'.specMatrixErr.dat'   , unpack=True )#, specMatrixErr)
		allisig  = allsig**(-1)
		masterwave = stack[file_input].wave 
		tmploglam = n.log10(masterwave)
		N_wave = len(tmploglam)
		N_spectra = allflux.shape[1]
		# filter data
		median_sn = n.array([ n.median( (flux_el/sig_el)[((sig_el==9999)==False)] ) for flux_el, sig_el in zip(allflux.T, allsig.T) ])
		#median_sn = n.median( SNR[i][nodata[i]==False], axis=0)
		print(median_sn)
		iuse = n.where( median_sn>sn_min)[0]
		print('iuse',iuse)
		#
		tmpchi2 = n.zeros((iuse.size, iuse.size))
		A = n.zeros((iuse.size, iuse.size))
		print("creates the matrix", time.time()-t0, 's', allflux.shape)
		tmp_yerr = 1./allisig[:, iuse].T.reshape(iuse.size, masterwave.size)
		tmp_y = allflux[:,iuse].T
		for i in n.arange(iuse.size):
			#print(i)
			tmp_x = allflux[:, iuse[i]].T.reshape(1,masterwave.size)
			tmp_xerr = 1./allisig[:, iuse[i]].T.reshape(1,masterwave.size)
			#print(tmp_x, tmp_y, tmp_xerr, tmp_yerr)
			A_tmp, chi2_tmp = mathutils.quick_amplitude(tmp_x, tmp_y, tmp_xerr, tmp_yerr)
			A[i,:] = A_tmp
			tmpchi2[i,:] = chi2_tmp
			
		chi2 = tmpchi2/(iuse.size-1) # reduced chi2
		print('chi2', chi2)
		#pcs = n.array([1,10,25,50,75,90,99])
		#pcs = n.array([16,17,18,19,20,21,22, 23, 24])
		scrs = scoreatpercentile(n.ravel(chi2), [5, 15, 25, 35, 45, 55, 65, 75, 85, 95])#0,16,17,18,19,20,21,22, 23, 24])
		print('chi2 distribution 5,15,25,..95%', scrs)
		chi2_min = scoreatpercentile(n.ravel(chi2), percentile )
		#print('minimum distance chi2_min', chi2_min) # 0.05 # the minimum distance, the only free paramter
		a_matrix = chi2<chi2_min # relationship matrix
		cost = n.ones(iuse.size)
		g = setcover.SetCover(a_matrix, cost)
		# I'm using greedy just for demonstration
		# g.greedy()
		# SolveSCP() should be used to generate near-optimal solution
		g.SolveSCP()
		# These are the archetypes
		iarchetype = n.nonzero(g.s)[0]
		print( chi2_min, len(iarchetype), time.time()-t0, 's')

		# sort archeypes against the number of spectra they represent
		n_rep = n.sum(a_matrix[:, iarchetype], axis=0) # how many covered by the archetype?
		isort = n.argsort(n_rep)[::-1]
		print(n_rep)
		archetype_median = n.zeros((iarchetype.size, masterwave.size))

		# These are the archetypal composites we want to use as the initial guess
		for i in n.arange(iarchetype.size):
			itmp = a_matrix[:, iarchetype[i]] # These are the instances represented by the archetype
			for j in n.arange(masterwave.size):
				thisflux = allflux[j,iuse[itmp]]
				archetype_median[i, j] = n.median(thisflux[thisflux!=0]) # Only use the objects that have this wavelength covered

		#from _pickle import cPickle
		#cPickle.dum

		imax = n.max(isort)
		print('imax', imax)
		p.clf()
		fig = p.figure(figsize=(10,imax*5))
		fig.subplots_adjust(hspace=0)
		p.title(out_name)
		for i in n.arange(0,imax,1):
			ax = fig.add_subplot(imax,1,i+1)
			ax.plot(masterwave[::3], archetype_median[isort[i],:][::3] , label = 'nRep=' + str(n_rep[isort[i]]) )
			ax.set_xlim(masterwave[10], masterwave[-10])
			#ax.set_ylim(-0.1, 3)
			#ax.set_xticks([])
			ax.axvline(1215, color='b', ls='dashed', label='1215 Lya')
			ax.axvline(1546, color='c', ls='dashed', label='1546 CIV')
			ax.axvline(2800, color='m', ls='dashed', label='2800 MgII')
			ax.axvline(3727, color='g', ls='dashed', label='3727 [OII]')
			ax.axvline(5007, color='r', ls='dashed', label='5007 [OIII]')
			ax.axvline(6565, color='k', ls='dashed', label='6565 Ha')
			print(i, n.count_nonzero(a_matrix[:,iarchetype[isort[i]]]))
			ax.grid()
			ax.legend(frameon=False, loc=0)

		p.xlabel('Angstrom')
		p.tight_layout()
		p.savefig( os.path.join(archetype_dir, "figure_archetypes_"+out_name +".png") )
		p.clf()

		n.savetxt(os.path.join(archetype_dir, "archetypes_"+out_name+".txt")   , n.vstack((masterwave, archetype_median)))
		
		f = open(os.path.join(archetype_dir, "index_archetypes_"+out_name+".pkl"), 'wb')
		obj = ObjIds(imax, iuse, n_rep)
		pickle.dump(obj, f)
		f.close()
	except(ValueError):
		print('ValueError')
Beispiel #4
0
def compute_chi2(flux, ferr=None):
    """Compute the chi2 distance matrix.

    Parameters
    ----------
    flux : numpy.ndarray
        Array [Nspec, Npix] of spectra or templates where Nspec is the number of
        spectra and Npix is the number of pixels.
    ferr : numpy.ndarray
        Uncertainty spectra ccorresponding to flux (default None).

    Returns
    -------
    Tuple of (chi2, amp) where:
        chi2 : numpy.ndarray
            Chi^2 matrix [Nspec, Nspec] between all combinations of normalized spectra.
        amp : numpy.ndarray
            Amplitude matrix [Nspec, Nspec] between all combinations of spectra.

    """

    nspec, npix = flux.shape
    chi2 = np.zeros((nspec, nspec), dtype='f4')
    amp = np.zeros((nspec, nspec), dtype='f4')

    flux = flux.copy()
    rescale = np.sqrt(npix / np.sum(flux**2, axis=1))
    flux *= rescale[:, None]

    if ferr is None:
        for ii in range(nspec):
            if ii % 500 == 0:
                log.info('Computing chi2 matrix for spectra {}-{} out of {}.'.
                         format(
                             int(ii / 500) * 500,
                             np.min(((ii + 1) * int(ii / 500), nspec - 1)),
                             nspec))
            amp1 = np.sum(flux[ii] * flux, axis=1) / npix
            chi2[ii, :] = npix * (1. - amp1**2)
            amp[ii, :] = amp1
    else:
        from SetCoverPy import mathutils
        ferr = ferr.copy()
        ferr *= rescale[:, None]
        for ii in range(nspec):
            if ii % 500 == 0 or ii == 0:
                log.info('Computing chi2 matrix for spectra {}-{} out of {}.'.
                         format(
                             int(ii / 500) * 500,
                             np.min(((ii + 1) * int(ii / 500), nspec - 1)),
                             nspec))
            xx = flux[ii, :].reshape(1, npix)
            xxerr = ferr[ii, :].reshape(1, npix)
            amp[ii, :], chi2[ii, :] = mathutils.quick_amplitude(xx,
                                                                flux,
                                                                xxerr,
                                                                ferr,
                                                                niter=1)

    amp *= rescale[:, None] / rescale[None, :]
    np.fill_diagonal(chi2, 0.)
    np.fill_diagonal(amp, 1.)

    return chi2, amp