示例#1
0
class Universal(object):
	"""
	Other functions that can be used in the building and set-up of data
	"""
	
	def __init__(self,varib):
		self.__dict__.update(varib)
		self.C = Caustic()


	def build(self,r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags,r200):
		"""
		This function builds the ensemble and individual cluster phase spaces, depending on fed parameters
		method 0 : top Ngal brightest
		method 1 : random Ngal within top Ngal*~10 brightest
		Interloper treatment done with ShiftGapper
		r : radius
		v : velocity
		en_gal_id : unique id for each ensemble galaxy
		en_clus_id : id for each galaxy relating back to its original parent halo
		ln_gal_id : unique id for each individual cluster galaxy
		rmags : SDSS r magnitude
		imags : SDSS i magnitude
		gmags : SDSS g magnitude
		halodata : 2 dimensional array, with info on halo properties
		- r200
		"""
		# Sort galaxies by r Magnitude
		bright = np.argsort(rmags)
		r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags = r[bright],v[bright],en_gal_id[bright],en_clus_id[bright],ln_gal_id[bright],gmags[bright],rmags[bright],imags[bright]

		if self.method_num == 0:
			en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags,ln_r,ln_v,ln_gal_id,ln_gmags,ln_rmags,ln_imags = self.build_method_0(r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags,r200)

		elif self.method_num == 1:
			en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags,ln_r,ln_v,ln_gal_id,ln_gmags,ln_rmags,ln_imags,samp_size = self.build_method_1(r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags,r200)

		else:
			print 'No Build...?'

		return en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags,ln_r,ln_v,ln_gal_id,ln_gmags,ln_rmags,ln_imags


	def build_method_0(self,r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags,r200):
		'''Picking top brightest galaxies, such that there are gal_num galaxies within r200'''

		gal_num = self.gal_num

		## ------------------------------- ##
		## Build Ensemble (en => ensemble) ##
		## ------------------------------- ##
	
		# define indicies of galaxies within r200
		within = np.where(r<r200)[0]
		# pick out gal_num 'th index in list, (include extra to counter shiftgapper's possible dimishement of richness)
		if gal_num < 10:
			excess = gal_num * 3.0 / 5.0				# galaxy excess to counter shiftgapper
		else:
			excess = gal_num / 5.0
		end = within[:gal_num + excess + 1][-1]		# instead of indexing I am slicing b/c of chance of not enough gals existing...	
		# Choose Ngals within r200
		if self.init_shiftgap == True:
			excess *= 2.0				# make excess a bit larger than previously defined
			end = within[:gal_num + excess + 1][-1]
			r2,v2,en_gal_id,en_clus_id,gmags2,rmags2,imags2 = self.C.shiftgapper(np.vstack([r[:end],v[:end],en_gal_id[:end],en_clus_id[:end],gmags[:end],rmags[:end],imags[:end]]).T).T # Shiftgapper inputs and outputs data as transpose...
			within = np.where(r2<r200)[0]	# re-calculate within array with new sample
			excess = gal_num / 5.0
			end = within[:gal_num + excess + 1][-1]
			# Append to ensemble array
			en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags = r2[:end],v2[:end],en_gal_id[:end],en_clus_id[:end],gmags2[:end],rmags2[:end],imags2[:end]
		else:
			en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags = r[0:end],v[0:end],en_gal_id[:end],en_clus_id[:end],gmags[0:end],rmags[0:end],imags[0:end]


		## ----------------------------------------- ##
		## Build Line of Sight (ln => line of sight) ##
		## ----------------------------------------- ##

		# define indicies of galaxies within r200
		within = np.where(r<r200)[0]
		# pick out gal_num 'th index in list, (include extra to counter shiftgapper's possible dimishement of richness)
		if gal_num < 10:
			excess = gal_num * 3.0 / 5.0				# galaxy excess to counter shiftgapper
		else:
			excess = gal_num / 5.0
		end = within[:gal_num + excess + 1][-1]		# instead of indexing I am slicing b/c
		# shiftgapper on line of sight
		try:
			r2,v2,ln_gal_id,gmags2,rmags2,imags2 = self.C.shiftgapper(np.vstack([r[:end],v[:end],ln_gal_id[:end],gmags[:end],rmags[:end],imags[:end]]).T).T
		except UnboundLocalError:	#When only a couple or no galaxies exist within RVIR
			print '-'*40
			print 'UnboundLocalError raised for shiftgapper on individual cluster....'
			print '-'*40
			r2,v2,ln_gal_id,gmags2,rmags2,imags2 = r[:end],v[:end],ln_gal_id[:end],gmags[:end],rmags[:end],imags[:end]

		# Sort by rmags
		sort = np.argsort(rmags2)
		r2,v2,ln_gal_id,gmags2,rmags2,imags2 = r2[sort],v2[sort],ln_gal_id[sort],gmags2[sort],rmags2[sort],imags2[sort]

		ln_r,ln_v,ln_gal_id,ln_gmags,ln_rmags,ln_imags = r2,v2,ln_gal_id,gmags2,rmags2,imags2

		# Done! Now we have en_r and ln_r arrays, which will either be stacked (former) or put straight into Caustic technique (latter)
		return en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags,ln_r,ln_v,ln_gal_id,ln_gmags,ln_rmags,ln_imags


	def build_method_1(self,r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags,r_crit200):
		'''Randomly choosing bright galaxies until gal_num galaxies are within r200'''

		gal_num = self.gal_num
		
		# reduce size of sample to something reasonable within magnitude limits
		sample = gal_num * 25				# arbitrary coefficient, see sites page post Apr 24th, 2013 for more info
		r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags = r[:sample],v[:sample],en_gal_id[:sample],en_clus_id[:sample],ln_gal_id[:sample],gmags[:sample],rmags[:sample],imags[:sample]
		samp_size = len(r)				# actual size of sample (might be less than gal_num*25)
		self.samp_size = samp_size

		# create random numbered array for galaxy selection
		if gal_num < 10:				# when gal_num < 10, has trouble hitting gal_num richness inside r200
			excess = gal_num * 4.0 / 5.0
		else:
			excess = gal_num * 2.0 / 5.0

		samp_num = gal_num + excess			# sample size of randomly generated numbers, start too low on purpose, then raise in loop
		loop = True					# break condition
		while loop == True:				# see method 0 comments on variables such as 'excess' and 'within' and 'end'
			for it in range(3):			# before upping sample size, try to get a good sample a few times
				rando = npr.randint(0,samp_size,samp_num)
				within = np.where(r[rando]<=r_crit200)[0]
				if len(within) >= gal_num + excess:
					loop = False
			if len(within) < gal_num + excess:
				samp_num += 2

		### Build Ensemble ###
		if self.init_shiftgap == True:

			r2,v2,en_gal_id,en_clus_id,gmags2,rmags2,imags2 = self.C.shiftgapper(np.vstack([r[rando],v[rando],en_gal_id[rando],en_clus_id[rando],gmags[rando],rmags[rand],imags[rando]]).T).T
			within = np.where(r2<r_crit200)[0]
			excess = gal_num / 5.0
			end = within[:gal_num + excess + 1][-1]
			# Append to ensemble array
			en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags = r2[:end],v2[:end],en_gal_id[:end],en_clus_id[:end],gmags2[:end],rmags2[:end],imags2[:end]
		else:
			excess = gal_num / 5.0
			end = within[:gal_num + excess + 1][-1]
			en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags = r[rando][:end],v[rando][:end],en_gal_id[rando][:end],en_clus_id[rando][:end],gmags[rando][:end],rmags[rando][:end],imags[rando][:end]

		### Build LOS ###
		# Set Sample
		if gal_num < 10:
			excess = gal_num * 4.0 / 5.0
		else:
			excess = gal_num * 2.0 / 5.0
		try:
			end = within[:gal_num + excess + 1][-1]
			# shiftgapper
			r2,v2,ln_gal_id2,gmags2,rmags2,imags2 = self.C.shiftgapper(np.vstack([r[rando][:end],v[rando][:end],ln_gal_id[rando][:end],gmags[rando][:end],rmags[rando][:end],imags[rando][:end]]).T).T
			# sort by rmags
			sort = np.argsort(rmags2)
			r2,v2,ln_gal_id2,gmags2,rmags2,imags2 = r2[sort],v2[sort],ln_gal_id2[sort],gmags2[sort],rmags2[sort],imags2[sort]
			# feed back gal_num gals within r200
			within = np.where(r2<r_crit200)[0]
			end = within[:gal_num + 1][-1]
			richness = len(within)
		except IndexError:
			print '****RAISED INDEX ERROR on LOS Building****'
			richness = 0		

		# Make sure gal_num richness inside r200
		run_time = time.asctime()
		j = 0
		while richness < gal_num:
			## Ensure this loop doesn't get trapped forever
			duration = (float(time.asctime()[11:13])*3600+float(time.asctime()[14:16])*60+float(time.asctime()[17:19]))-(float(run_time[11:13])*3600+float(run_time[14:16])*60+float(run_time[17:19]))
			if duration > 30:
				print "****Duration exceeded 30 seconds in LOS Buiding, manually broke loop****"
				break
			##
			j += 1
			loop = True
			while loop == True:				
				for j in range(3):			
					rando = npr.randint(0,samp_size,samp_num)
					within = np.where(r[rando]<=r_crit200)[0]
					if len(within) >= gal_num + excess:
						loop = False
				if len(within) < gal_num + excess:
					samp_num += 2
			try:
				end = within[:gal_num + excess + 1][-1]
				r2,v2,ln_gal_id2,gmags2,rmags2,imags2 = self.C.shiftgapper(np.vstack([r[rando][:end],v[rando][:end],ln_gal_id[rando][:end],gmags[rando][:end],rmags[rando][:end],imags[rando][:end]]).T).T
				within = np.where(r2<r_crit200)[0]
				end = within[:gal_num + 1][-1]
				richness = len(within)
			except IndexError:
				print '**** Raised Index Error on LOS Building****'
				richness = 0

			if j >= 100:
				print 'j went over 100'
				break

		ln_r,ln_v,ln_gal_id,ln_gmags,ln_rmags,ln_imags = r2[:end],v2[:end],ln_gal_id2[:end],gmags2[:end],rmags2[:end],imags2[:end]
		# Done! Now we have en_r and ln_r arrays (ensemble and line of sight arrays)
		
		return en_r,en_v,en_gal_id,en_clus_id,en_gmags,en_rmags,en_imags,ln_r,ln_v,ln_gal_id,ln_gmags,ln_rmags,ln_imags,samp_size


	def rand_pos(self,distance):
	        '''Picks a random position for the observer a given distance away from the center'''
		theta = npr.normal(np.pi/2,np.pi/4)
		phi = npr.uniform(0,2*np.pi)
		x = np.sin(theta)*np.cos(phi)
		y = np.sin(theta)*np.sin(phi)
		z = np.cos(theta)
	
		unit = np.array([x,y,z])/(x**2+y**2+z**2)**(.5)
		# move the position a random 'distance' Mpc away
	        return distance*unit


	def limit_gals(self,r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags,r200):
		''' Sort data by magnitude, and elimite values outside phase space limits '''
		# Sort by ascending r magnitude (bright to dim)
		sorts = np.argsort(rmags)
		r = r[sorts]
		v = v[sorts]
		en_gal_id = en_gal_id[sorts]
		en_clus_id = en_clus_id[sorts]
		ln_gal_id = ln_gal_id[sorts]
		gmags = gmags[sorts]
		rmags = rmags[sorts]
		imags = imags[sorts]

		# Limit Phase Space
		sample = np.where( (r < r200*self.r_limit) & (v > -self.v_limit) & (v < self.v_limit) )[0] 
		r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags = r[sample],v[sample],en_gal_id[sample],en_clus_id[sample],ln_gal_id[sample],gmags[sample],rmags[sample],imags[sample]
		samp_size = len(sample)

		# Eliminate galaxies w/ mag = 99.
		cut = np.where((gmags!=99)&(rmags!=99)&(imags!=99))[0]
		r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags = r[cut],v[cut],en_gal_id[cut],en_clus_id[cut],ln_gal_id[cut],gmags[cut],rmags[cut],imags[cut]
		samp_size = len(cut)

		return r,v,en_gal_id,en_clus_id,ln_gal_id,gmags,rmags,imags,samp_size


	def Bin_Calc(self,M200,R200,HVD):
		'''
		This function does pre-technique binning analysis
		'''
		# Choose Averaging Method
		if self.avg_meth == 'median':
			avg_method = np.median
		elif self.avg_meth == 'mean':
			avg_method = np.mean
		else:
			print 'Average Method for Bin is Mean()'
			avg_method = np.mean

		# Calculate Bin R200 and Bin HVD, use median
		BIN_M200,BIN_R200,BIN_HVD = [],[],[]
		for i in range(len(M200)/self.line_num):
			BIN_M200.append( avg_method( M200[i*self.line_num:(i+1)*self.line_num] ) )
			BIN_R200.append( avg_method( R200[i*self.line_num:(i+1)*self.line_num] ) )
			BIN_HVD.append( avg_method( HVD[i*self.line_num:(i+1)*self.line_num] ) )

		BIN_M200,BIN_R200,BIN_HVD = np.array(BIN_M200),np.array(BIN_R200),np.array(BIN_HVD)

		return BIN_M200,BIN_R200,BIN_HVD


	def get_3d(self,Gal_P,Gal_V,ens_gal_id,los_gal_id,stack_range,ens_num,self_stack,j):
		'''
		This function recovers the 3D positions and velocities of the galaxies in the ensemble and los phase space.
		'''

		if self_stack == True:
			# Create fully concatenated arrays to draw ensemble data from
			GPX3D,GPY3D,GPZ3D = Gal_P[j][0],Gal_P[j][1],Gal_P[j][0]
			GVX3D,GVY3D,GVZ3D = Gal_V[j][0],Gal_V[j][1],Gal_V[j][0]
		
			# Recover ensemble 3D data
			ens_gpx3d,ens_gpy3d,ens_gpz3d = GPX3D[ens_gal_id],GPY3D[ens_gal_id],GPZ3D[ens_gal_id]
			ens_gvx3d,ens_gvy3d,ens_gvz3d = GVX3D[ens_gal_id],GVY3D[ens_gal_id],GVZ3D[ens_gal_id]

			# Recover line_of_sight 3D data	
			los_gpx3d,los_gpy3d,los_gpz3d = np.array(map(lambda x: GPX3D[x],los_gal_id)),np.array(map(lambda x: GPY3D[x],los_gal_id)),np.array(map(lambda x: GPZ3D[x],los_gal_id))
			los_gvx3d,los_gvy3d,los_gvz3d = np.array(map(lambda x: GVX3D[x],los_gal_id)),np.array(map(lambda x: GVY3D[x],los_gal_id)),np.array(map(lambda x: GVZ3D[x],los_gal_id))

		else:	
			# Create fully concatenated arrays to draw ensemble data from
			[BIN_GPX3D,BIN_GPY3D,BIN_GPZ3D] = map(np.concatenate,Gal_P[j*self.line_num:(j+1)*self.line_num].T)
			[BIN_GVX3D,BIN_GVY3D,BIN_GVZ3D] = map(np.concatenate,Gal_V[j*self.line_num:(j+1)*self.line_num].T)

			# Recover ensemble 3D data	
			ens_gpx3d,ens_gpy3d,ens_gpz3d = BIN_GPX3D[ens_gal_id],BIN_GPY3D[ens_gal_id],BIN_GPZ3D[ens_gal_id]
			ens_gvx3d,ens_gvy3d,ens_gvz3d = BIN_GVX3D[ens_gal_id],BIN_GVY3D[ens_gal_id],BIN_GVZ3D[ens_gal_id]

			# Recover line_of_sight 3D data
			los_gpx3d,los_gpy3d,los_gpz3d = [],[],[]
			los_gvx3d,los_gvy3d,los_gvz3d = [],[],[]
			for i,k in zip( np.arange(j*self.line_num,(j+1)*self.line_num), np.arange(self.line_num) ):
				los_gpx3d.append(Gal_P[i][0][los_gal_id[k]])
				los_gpy3d.append(Gal_P[i][1][los_gal_id[k]])
				los_gpz3d.append(Gal_P[i][2][los_gal_id[k]])
				los_gvx3d.append(Gal_V[i][0][los_gal_id[k]])
				los_gvy3d.append(Gal_V[i][1][los_gal_id[k]])
				los_gvz3d.append(Gal_P[i][2][los_gal_id[k]])

			los_gpx3d,los_gpy3d,los_gpz3d = np.array(los_gpx3d),np.array(los_gpy3d),np.array(los_gpz3d)
			los_gvx3d,los_gvy3d,los_gvz3d = np.array(los_gvx3d),np.array(los_gvy3d),np.array(los_gvz3d)

		return np.array([ens_gpx3d,ens_gpy3d,ens_gpz3d]),np.array([ens_gvx3d,ens_gvy3d,ens_gvz3d]),np.array([los_gpx3d,los_gpy3d,los_gpz3d]),np.array([los_gvx3d,los_gvy3d,los_gvz3d])


	def line_of_sight(self,gal_p,gal_v,halo_p,halo_v):
		'''Line of Sight Calculations to mock projected data, if given 3D data'''
		# Pick Position
		new_pos = self.rand_pos(30)
		new_pos += halo_p 

		# New Halo Information
		halo_dist = ((halo_p[0]-new_pos[0])**2 + (halo_p[1]-new_pos[1])**2 + (halo_p[2]-new_pos[2])**2)**0.5
		halo_pos_unit = np.array([halo_p[0]-new_pos[0],halo_p[1]-new_pos[1],halo_p[2]-new_pos[2]]) / halo_dist
		halo_vlos = np.dot(halo_pos_unit, halo_v)

		# New Galaxy Information
		gal_p = np.array(gal_p)
		gal_v = np.array(gal_v)
		gal_dist = ((gal_p[0]-new_pos[0])**2 + (gal_p[1]-new_pos[1])**2 + (gal_p[2]-new_pos[2])**2)**0.5
		gal_vlos = np.zeros(gal_dist.size)
		gal_pos_unit = np.zeros((3,gal_dist.size))	#vector from new_p to gal	
		n = gal_dist.size

		# Line of sight
		code = """
		int u,w;
		for (u=0;u<n;++u){
		for(w=0;w<3;++w){
		gal_pos_unit(w,u) = (gal_p(w,u)-new_pos(w))/gal_dist(u);
		}
		gal_vlos(u) = gal_pos_unit(0,u)*gal_v(0,u)+gal_pos_unit(1,u)*gal_v(1,u)+gal_pos_unit(2,u)*gal_v(2,u);
		}
		"""
		fast = weave.inline(code,['gal_pos_unit','n','gal_dist','gal_vlos','gal_v','new_pos','gal_p'],type_converters=converters.blitz,compiler='gcc')
		angles = np.arccos(np.dot(halo_pos_unit,gal_pos_unit))
		r = angles*halo_dist
		#v_pec = gal_vlos-halo_vlos*np.dot(halo_pos_unit,gal_pos_unit)
		z_clus_cos = self.H0*halo_dist/self.c
		z_clus_pec = halo_vlos/self.c
		z_clus_obs = (1+z_clus_pec)*(1+z_clus_cos)-1
		z_gal_cos = self.H0*gal_dist/self.c
		z_gal_pec = gal_vlos/self.c
		z_gal_obs = (1+z_gal_pec)*(1+z_gal_cos)-1
		v = self.c*(z_gal_obs-z_clus_obs)/(1+z_clus_obs)
		#gal_vdisp3d[i] = np.sqrt(astStats.biweightScale(gal_v[0][np.where(gal_radius<=HaloR200[i])]-Halo_V[0],9.0)**2+astStats.biweightScale(gal_v[1][np.where(gal_radius<=HaloR200[i])]-Halo_V[1],9.0)**2+astStats.biweightScale(gal_v[2][np.where(gal_radius<=HaloR200[i])]-Halo_V[2],9.0)**2)/np.sqrt(3)
		#print 'MY VELOCITY OF GALAXIES', gal_vdisp3d[i]
#		particle_vdisp3d[i] = HVD*np.sqrt(3)
#		gal_rmag_new = gal_abs_rmag# + 5*np.log10(gal_dist*1e6/10.0)

		return r, v, np.array(new_pos)


	def app2abs(self,m_app,color,z,photo_band,color_band):
		'''
		takes apparent magnitude of a galaxy in some photometric band (SDSS g or r or i)
		and converts it to an absolute magnitude via distance modulus and k correction
		M_abs = m_app - Dist_Mod - K_corr
		takes:
			m_app		: float, apparent magnitude of galaxy
			color		: float, color of galaxy between two SDSS bands
			z		: float, total redshift of galaxy
			photo_band	: str, SDSS band for magnitude. Ex: 'g' or 'r' or 'i'
			color_band	: str, color between two SDSS bands. Ex: 'g - r' or 'g - i' or 'r - i', etc..
		'''
		dm = self.distance_mod(z)
		K_corr = calc_kcor(photo_band,z,color_band,color)
		return m_app - dm - K_corr


	def distance_mod(self,z):
		ang_d,lum_d = self.C.zdistance(z,self.H0)
		dm = 5.0 * np.log10(lum_d*1e6 / 10.0 )
		return dm


	def print_varibs(self,names,dictionary):
		print '## Variables Defined in the Run'
		print '-'*50
		for i in names:
			try:
				if i=='':
					print ''
				print i+'\r\t\t\t= '+str(dictionary[i])
			except:
				pass
		print '-'*50

	def print_separation(self,text,type=1):
		if type==1:
			print ''
			print '-'*60
			print str(text)
			print '-'*60
		elif type==2:
			print ''
			print str(text)
			print '-'*30
		return
示例#2
0
	Nspec = []
	N200 = []
	HVD = []

	good2 = []
	for i in good:
		try:
			gal_ra, gal_dec, gal_umag, gal_gmag, gal_rmag, gal_imag, gal_zmag, gal_z = np.loadtxt(data_root+'/proj_data/C4_dr12_'+str(i)+'_data.csv',dtype='float',delimiter=',',skiprows=1,usecols=(1,2,3,4,5,6,7,13),unpack=True)
		except: continue

		clus_ra = RA[i]
		clus_dec = DEC[i]
		clus_z = Z[i]
		rvir = RVIR[i]

		ang_d,lum_d = C.zdistance(clus_z,H0)
		angles = C.findangle(gal_ra,gal_dec,clus_ra,clus_dec)
		rdata = angles * ang_d
		vdata = c * (gal_z - clus_z) / (1 + clus_z)

		# Calculate HVD
		rlim = rvir * 1.25   # Mpc
		rad_cut = np.where(rdata < rlim)[0]
		if len(rad_cut) == 0:
			continue
		elif len(rad_cut) > 2:
			hvd = astats.biweight_midvariance(vdata[np.where((rdata < rlim)&(np.abs(vdata)<3000))])
		else:
			hvd = np.std(vdata[np.where(rdata < rlim)])

		Nspec.append( np.where((rdata < rvir) & (np.abs(vdata) < hvd * 1.5))[0].size )
示例#3
0
文件: c4_clusters.py 项目: nkern/C4
			gal_subclass = dr12['subclass'][cut]
			gal_DistMod = dr12['DistMod'][cut]
			gal_absMagU = dr12['absMagU'][cut]
			gal_absMagG = dr12['absMagG'][cut]
			gal_absMagR = dr12['absMagR'][cut]
			gal_absMagI = dr12['absMagI'][cut]
			gal_absMagZ = dr12['absMagZ'][cut]
			gal_kcorrU = dr12['kcorrU'][cut]
			gal_kcorrG = dr12['kcorrG'][cut]
			gal_kcorrR = dr12['kcorrR'][cut]
			gal_kcorrI = dr12['kcorrI'][cut]
			gal_kcorrZ = dr12['kcorrZ'][cut]


			# Project	
			ang_d,lum_d = C.zdistance(clus_z,H0)
			angles = C.findangle(gal_ra,gal_dec,clus_ra,clus_dec)	
			rdata = angles * ang_d
			vdata = c * (gal_z - clus_z) / (1 + clus_z)
			# RV Cut
			cut = np.where((vdata < 7000) & (vdata > -7000) & (rdata < 12))[0]
			gal_specobjid,gal_objid = gal_specobjid[cut],gal_objid[cut]
			gal_class,gal_subclass = gal_class[cut],gal_subclass[cut]
			gal_ra,gal_dec,gal_z,gal_zerr = gal_ra[cut],gal_dec[cut],gal_z[cut],gal_zerr[cut]
			gal_DistMod,gal_absMagU,gal_absMagG,gal_absMagR,gal_absMagI,gal_absMagZ = gal_DistMod[cut],gal_absMagU[cut],gal_absMagG[cut],gal_absMagR[cut],gal_absMagI[cut],gal_absMagZ[cut]
			gal_kcorrU,gal_kcorrG,gal_kcorrR,gal_kcorrI,gal_kcorrZ = gal_kcorrU[cut],gal_kcorrG[cut],gal_kcorrR[cut],gal_kcorrI[cut],gal_kcorrZ[cut]

			# Make FITS table
			col1 = fits.Column(name='specobjid',format='J',array=gal_specobjid)
			col2 = fits.Column(name='objid',format='J',array=gal_objid)
			col3 = fits.Column(name='ra',format='D',array=gal_ra)