def MassEnclosed(self, ptype, radii): # Finds the mass enclosed in each radius from the list of radii, # for a given particle type # Find the center of mass for given particle type COM = CenterOfMass(self.filename, ptype) Gal_COM = COM.COM_P(1) # Create an array to store indexes of particles of desired Ptype index = np.where(self.data['type'] == ptype) # Define the new coordinates and masses m_new = self.m[index] x_new = self.X[index] - Gal_COM[0] y_new = self.Y[index] - Gal_COM[1] z_new = self.Z[index] - Gal_COM[2] # The magnitude of the distance of the particle from COM R = np.sqrt(x_new**2 + y_new**2 + z_new**2) # Initialize the array that will contain the masses mass = np.array([]) # Loop throught list of radii and find mass inside that radius for r in radii: # Select all particles within radius r list_index = np.where(R < r * u.kpc) # Find the total mass within the radius m = sum(m_new[list_index]) * 1e10 * u.Msun # Add the total mass to list mass = np.append(mass, m) return mass
def MassEnclosed(self, type, radius): COM = CenterOfMass(self.filename, type) #calculate center of Mass galCOMP = COM.COM_P(0.1) index = np.where(self.data['type'] == type) #Select desired indexes and adjust values xIndex = self.x[index] - galCOMP[0] yIndex = self.y[index] - galCOMP[1] zIndex = self.z[index] - galCOMP[2] RIndex = np.sqrt(xIndex**2 + yIndex**2 + zIndex**2) #Calculate the distance magnitudes mIndex = np.zeros( radius.size) #initialize an array for storing all mass profiles for i in range( np.size(radius) ): #loop through each radius and sum up each total mass profile value index2 = np.where(radius[i] > RIndex) mIndex[i] = np.sum(self.m[index2]) mIndex *= u.Msun #print(mIndex) return mIndex
def PosAndVels(self, filename, radius_cut): # calculates the relative positions and velocities of all halo particles, necessary for # vel anistropy and spin calculations # takes snap number and outer radius, returns position magnitude and components, and vel components # set COM params here delta = 5.0 VolDec = 2 COM = CenterOfMass(filename, 1) xcom, ycom, zcom = COM.COM_P(delta, VolDec) vxcom, vycom, vzcom = COM.COM_V(xcom, ycom, zcom) # relative positions x = COM.x - xcom y = COM.y - ycom z = COM.z - zcom R = (x**2 + y**2 + z**2)**0.5 # relative velocities vx = COM.vx - vxcom vy = COM.vy - vycom vz = COM.vz - vzcom # only return particles within radius cut index = np.where(R < radius_cut * u.kpc) #print(radius_cut) return R[index], x[index], y[index], z[index], vx[index], vy[ index], vz[index], COM.m[index] * u.Msun * 1e10
def MassEnclosed(self, ptype, Renc): # Input: # ptype - the particle type (Halo: 1, Disk: 2, Bulge: 3) # Renc - the galaxy radius within which the mass is enclosed # Output: # Menc - the mass enclosed within the given radius for the specified galaxy index = np.where(self.data['type'] == ptype) # Create an array to store indexes of particles of desired Ptype COM = CenterOfMass(self.filename, ptype) # Create a center of mass object COMP = COM.COM_P(0.1) # Calculate the center of mass position # Change the frame of reference to the newly computed COM position xNew = self.x[index] - COMP[0] yNew = self.y[index] - COMP[1] zNew = self.z[index] - COMP[2] rCOM = np.sqrt(xNew**2 + yNew**2 + zNew**2) # Calculate the distance from the COM position Menc = np.zeros(len(Renc)) # Initialize an array of 0's to store the total mass within a given radius for i in range(len(Renc)): rad = Renc[i] pindex = np.where(rCOM.value <= rad) Mpart = self.m[pindex] Menc[i] = np.sum(Mpart) if self.gname == 'M33' and ptype == 1: # To account for M33 having no bulge Menc = np.zeros(len(Renc)) return Menc*1e10*u.Msun
def MassEnclosed(self, ptype, radii): # find ptype particles. If not finded, print caveat and return ptype_index, = np.where(self.data['type'] == ptype) if len(ptype_index) == 0: print("CAVEAT: NO %s component in %s!" % (INDEX2STR(ptype), self.gname)) return 0, 0 # to ensure radii is sorted radii = np.sort(radii) # get COM position and calculate R with regard to COM center = CenterOfMass(self.filename, ptype) COMP = center.COM_P(TOLERANCE()) R = np.sqrt( np.sum((self.position[ptype_index] - COMP) * (self.position[ptype_index] - COMP), 1)) # loop through radii to deliver mass into bins self.massary = np.zeros(len(radii)) mass = self.m[ptype_index] for i in np.arange(0, len(radii), 1): ind = np.where(R < radii[i]) self.massary[i] = np.sum(mass[ind]) # set units self.massary *= 1e10 self.massary *= u.Msun return self.massary, 1
def OrbitCOM(galaxy, start, end, n): #setup paramters for CenterOfMass, array, and output file fileout = "Orbit_" + "%s" % (galaxy) + ".txt" Orbit = np.zeros((int(end / n) + 1, 7)) delta = 0.5 VolDec = 4 #calculate center of mass for every snap number and save into Orbit array for i in np.arange(start, end + n, n): ilbl = '000' + str(i) # add string of filenumber to 000 ilbl = ilbl[-3:] # keep last 3 digits filename = '/home/agibbs/VLowRes/' + "%s_" % (galaxy) + ilbl + '.txt' COM = CenterOfMass(filename, 2) #disk particles only xcom, ycom, zcom = COM.COM_P(delta, VolDec) vxcom, vycom, vzcom = COM.COM_V(xcom, ycom, zcom) Orbit[int(i / n), 0] = float(COM.time / u.Myr) Orbit[int(i / n), 1] = float(xcom / u.kpc) Orbit[int(i / n), 2] = float(ycom / u.kpc) Orbit[int(i / n), 3] = float(zcom / u.kpc) Orbit[int(i / n), 4] = float(vxcom / u.km * u.s) Orbit[int(i / n), 5] = float(vycom / u.km * u.s) Orbit[int(i / n), 6] = float(vzcom / u.km * u.s) print(i) #save text file with complete array np.savetxt(fileout, Orbit, header='t, x, y, z, vx, vy, vz', comments='#', fmt='%.2f') return
def OrbitCOM(galaxy, start, end, n): # define output filename, initialize fileout = "Orbit_%s.txt" % galaxy rows = int((end - start) / n) + 1 Orbit = np.zeros((rows, 7)) ## DEFINE TOLERANCE AND VOLUMN DECREASE FACTOR delta = 0.5 VolDec = 4. # loop through snapnumbers for i in np.arange(start, end + 1, n): print("Looping at snap number = %d\n" % i) # index in array ct = int((i - start) / n) # construct filename filename = "%s/%s_%03d.txt" % ("../MW_VLowRes", galaxy, i) # construct COM object using disk particles, get COM info center = CenterOfMass(filename, 2) rc = center.COM_P(delta, VolDec) vc = center.COM_V(30, rc) # write data into list Orbit[ct][0] = float(center.time / u.Gyr) Orbit[ct][1] = float(rc[0] / u.kpc) Orbit[ct][2] = float(rc[1] / u.kpc) Orbit[ct][3] = float(rc[2] / u.kpc) Orbit[ct][4] = float(vc[0] / (u.km / u.s)) Orbit[ct][5] = float(vc[1] / (u.km / u.s)) Orbit[ct][6] = float(vc[2] / (u.km / u.s)) # print list np.savetxt(fileout, Orbit, header='#t x y z vx vy vz', \ comments='# time in Gyr, position in kpc, velocity in km/s\n',\ fmt=['%.2f','%.2f','%.2f','%.2f','%.2f','%.2f','%.2f'])
def MassEnclosed(self, ptype, r): marray = np.zeros(shape=len(r)) #find the center of mass position using function from CenterOfMass that takes in filename and particle type and returns x,y,z components of center of mass to a certain toleance COM = CenterOfMass(self.filename, ptype) COMP = COM.COM_P(1.0, 4.0) #array if indixes of partices of desired type index = np.where(self.data['type'] == ptype) #find postiion of all particles relative to center of mass m2 = self.m[index] x2 = self.x[index] - COMP[0] y2 = self.y[index] - COMP[1] z2 = self.z[index] - COMP[2] r2 = np.sqrt(x2**2 + y2**2 + z2**2) #loop over radius array to define particles that are enclosed within the radius given at each element for radius in range(len(r)): #find and store particle masses that are within given radius index2 = np.where(r2 < r[radius]) marray[radius] = np.sum(m2[index2]) ''' #sum to find mass enclosed msum = np.sum(mnew) #append to mass array marray[count] = msum count = count +1 ''' return marray * 10e10
def MassEnclosed(self, PType, r): # Function that will compute the mass within any given radius with respect # to the COM for a specified galaxy and specified component of that galaxy. # input: the array of all the radii of the total mass enclosed # return: the array of the mass of each particle within each specified # radius. # read in COM position from last HW COM = CenterOfMass(COM_P) Position = COM.COM_P(0.1) # 1) find the x,y,z positions of each indicidual particle within # specified radius. x = self.x - Position y = self.y - Position z = self.z - Position # 2) find the mass of each particle m = self.m # computes magnitude of position vector r = np.sqrt(x**2 + y**2 + z**2) # for loop to iterate over the radius given at each array element for i in range(0, r): particlepos = np.where(r1 <= r[i]) # individual particle position particlemass = m[particlepos] # individual particle mass mass[i] = sum(particlemass) # total mass of particles return mass * 1e10 * u.Msun
def OrbitCOM(galaxy, start, end, n): """ A function that generates a text file containing orbital information in 7 columns. The file will have a header 't x y z vx vy vz', which serves as the name of each column. Going from left to right, the columns are time, x-position, y-position, z-position, x-velocity, y-velocity, z-velocity. PARAMETERS ---------- galaxy: Name of the galaxy, e.g. 'MW'. Type = str start : Number of the first snapshot to be read in. Type = int end : Number of the last snapshot to be read in. Type = int n : Interval over which snapshots are iterated. Type = int RETURNS ------- fileout: Name of the generated file. Type = str Generates a text file named with the variable fileout in current working directory. """ fileout = "Orbit_%s.txt" % galaxy #Name of the file to be generated size = int(end / n) + 1 #Number of rows for the orbit array Orbit = np.zeros( [size, 7]) #Initializing the array that will hold orbital parameters delta, VolDec = 0.5, 4 #Defining parameters required by the COM_P method #Looping over snapshots and generating orbital parameters at each snapshot for i in np.arange(start, end + 1, n): #Creating filename for desired snapshot ilbl = '000' + str(i) ilbl = ilbl[-3:] #making 3 digit numbers folder = 'VLowRes/' filename = folder + '%s_' % galaxy + ilbl + '.txt' #Creating the center of mass object COM = CenterOfMass(filename, 2) #Generating orbital parameters for the i-th snapshot t = COM.time / 1000 #converting Myr to Gyr x, y, z = COM.COM_P(delta, VolDec) vx, vy, vz = COM.COM_V(x, y, z, 15) #Assigning values to the proper row of orbit array row_ind = int(i / n) Orbit[row_ind] = [ t.value, x.value, y.value, z.value, vx.value, vy.value, vz.value ] print('%s i = %i' % (galaxy, i)) #Saves the orbit array to a file in current directory np.savetxt(fileout, Orbit, header='t x y z vx vy vz', comments='#', fmt=['%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f']) return fileout
def __init__(self, filename): # initialize class, filename is the output file to contain the future locations and velocities of M33. # initial conditions are for M31 and M33 are loaded without input. #determine relative position and velocity of M33 com to M31 com, and save M31COM = CenterOfMass('/home/agibbs/M31_000.txt', 2) M33COM = CenterOfMass('/home/agibbs/M33_000.txt', 2) x31, y31, z31 = M31COM.COM_P(0.1) x33, y33, z33 = M33COM.COM_P(0.1) vx31, vy31, vz31 = M31COM.COM_V(x31, y31, z31) vx33, vy33, vz33 = M33COM.COM_V(x33, y33, z33) self.x, self.y, self.z = x33 - x31, y33 - y31, z33 - z31 self.vx, self.vy, self.vz = vx33 - vx31, vy33 - vy31, vz33 - vz31 # mass and characteristic radii for disk, bulge, and halo # to be used in Hernquist and Miyamoto-Nagai profiles self.rdisk = 5 * u.kpc self.Mdisk = 1.2e11 * u.Msun self.rbulge = 1 * u.kpc self.Mbulge = 1.9e10 * u.Msun self.rhalo = 60 * u.kpc self.Mhalo = 1.92e12 * u.Msun self.filename = filename return
def MassEnclosed(self, ptype, radii): # Return array of masses within specific radii of COM. Takes particle type and an array of radii to use. p_index = np.where(self.data['type'] == ptype) GALCOM = CenterOfMass(self.filename, ptype) GAL_xcom, GAL_ycom, GAL_zcom = GALCOM.COM_P(self.comdel) radius = ( (self.x[p_index] - GAL_xcom)**2 + (self.y[p_index] - GAL_ycom)**2 + \ (self.z[p_index] - GAL_zcom)**2 ) ** 0.5 mass = np.zeros(radii.size) p_mass = self.m[p_index] #print(np.argwhere(np.isnan(radius))) #debugging nan values for index, radii_val in enumerate(radii): r_index = np.where(radius < radii_val) mass[index] = np.sum(p_mass[r_index]) return mass * u.Msun * 1e10
def MassEnclosed(self, ptype, r): """ Calculates the enclosed mass for a specific particle type. Inputs: ptype = particle type r = array of radii to calculate enclosed mass (u.kpc) Outputs: array of enclosed masses (u.Msun) """ # M33 does not have any bulge stars # check for this case before any calculations if self.gname == 'M33' and ptype == 3: return np.zeros(len(r)) # create CenterOfMass object # always use disk stars for CoM COM = CenterOfMass(self.filename, 2) # ptype=2 for disk stars # get COM position delta = 0.1 COMX, COMY, COMZ = COM.COM_P(delta) # get particle positions in COM frame of reference xNew = self.x - COMX yNew = self.y - COMY zNew = self.z - COMZ # select only particles of ptype ind = np.where(self.type == ptype) xNew2 = xNew[ind] yNew2 = yNew[ind] zNew2 = zNew[ind] mNew = self.m[ind] # Calculate magnitudes R = (xNew2**2 + yNew2**2 + zNew2**2)**(0.5) # create array to store answers encmass = np.zeros(len(r)) # loop through r to do the calculations for i in range(len(r)): # find indices of particles within this radius index = np.where(R < r[i]) # add their masses and store in our array encmass[i] = np.sum(mNew[index]) # return masses with proper units return encmass * 1e10 * u.Msun
def __init__(self, filename): """inputs: filename for file in which we will store the integrated orbit""" ### get the gravitational constant (the value is 4.498502151575286e-06) self.G = const.G.to(u.kpc**3/u.Msun/u.Gyr**2).value ### **** store the output file name self.fileout = filename ### get the current pos/vel of M33 # **** create an instance of the CenterOfMass class for M33 M33COM = CenterOfMass("M33_000.txt", 2) #print("got M33COM") # **** store the position VECTOR of the M33 COM (.value to get rid of units) M33_COMP = M33COM.COM_P(0.1) # **** store the velocity VECTOR of the M33 COM (.value to get rid of units) M33_COMV = M33COM.COM_V(M33_COMP[0], M33_COMP[1], M33_COMP[2]) ### get the current pos/vel of M31 # **** create an instance of the CenterOfMass class for M31 M31COM = CenterOfMass("M31_000.txt", 2) #print("got M31COM") # **** store the position VECTOR of the M31 COM (.value to get rid of units) M31_COMP = M31COM.COM_P(0.1) # **** store the velocity VECTOR of the M31 COM (.value to get rid of units) M31_COMV = M31COM.COM_V(M31_COMP[0], M31_COMP[1], M31_COMP[2]) ### store the DIFFERENCE between the vectors posM33 - posM31 # **** create two VECTORs self.r0 and self.v0 and have them be the # relative position and velocity VECTORS of M33 #M31_COMP is a vector self.r0 = (M33_COMP - M31_COMP).value self.v0 = (M33_COMV - M31_COMV).value ### get the mass of each component in M31 ### disk # **** self.rdisk = scale length (no units) self.rdisk = 5 #in kpc # **** self.Mdisk set with ComponentMass function. Remember to *1e12 to get the right units. Use the right ptype self.Mdisk = ComponentMass("M31_000.txt", 2)*1e12 #in M_sun ### bulge # **** self.rbulge = set scale length (no units) self.rbulge = 1 # **** self.Mbulge set with ComponentMass function. Remember to *1e12 to get the right units Use the right ptype self.Mbulge = ComponentMass("M31_000.txt", 3)*1e12 # Halo # **** self.rhalo = set scale length from HW5 (no units) self.rhalo = 62 #kpc # **** self.Mhalo set with ComponentMass function. Remember to *1e12 to get the right units. Use the right ptype self.Mhalo = ComponentMass("M31_000.txt", 1)*1e12
def r200(galaxy, start, end, n): #setup parameters for CenterOfMass, array, and output file fileout = "R200_" + "%s"%(galaxy) + ".txt" R200 = np.zeros(( int(end/n) + 1, 3)) delta = 5.0 # com params VolDec = 2 crit_density = 147.712 * u.Msun / u.kpc**3 #critical density for closure #calculate r200 for every snap number and save into R200 array for i in np.arange(start, end+n, n): ilbl = '000' + str(i) # add string of filenumber to 000 ilbl = ilbl[-3:] # keep last 3 digits #filename = '/home/agibbs/VLowRes/' + "%s_"%(galaxy) + ilbl +'.txt' # change comments for MW+M31 filename = '/home/agibbs/400B/ASTR400B_Gibbs/Project/Remnant/MW+M31_'+ilbl+'.txt' #COM position COM = CenterOfMass(filename, 1) #halo particles only xcom, ycom, zcom = COM.COM_P(delta, VolDec) #Find R200 radius xref = COM.x - xcom yref = COM.y - ycom zref = COM.z - zcom R = (xref**2 + yref**2 + zref**2)**0.5 density = 1e9 * u.Msun / u.kpc**3 # initial density to start loop R_step = 0.1 * u.kpc # radius steps R_iter = 50.0 * u.kpc # first radius while density > crit_density * 200: R_iter = R_iter + R_step rindex = np.where(R < R_iter) mass = np.sum(COM.m[rindex]) * 1e10 * u.Msun volume = 4*np.pi/3 * R_iter**3 density = mass / volume #Save R200[int(i/n), 0] = float(COM.time / u.Myr) R200[int(i/n), 1] = float(R_iter / u.kpc) R200[int(i/n), 2] = float(R_iter * 0.25 / u.kpc) print(i) #save text file with complete array np.savetxt(fileout, R200, header='t, r200, qr200', comments='#', fmt='%.2f') return
def MassEnclosed(self, ptype, radii): # Inputs: # ptype = type of particle (1=halo, 2=disk, 3=bulge) # radii = array of radii within given radius of COM position # Returns: # masses = array of masses to calculate mass profile with later # Create array to store indexes of particles of desired Ptype self.index = np.where(self.data['type'] == ptype) # Store the positions, velocities, and mass of only the particles of the given type x = self.x[self.index] y = self.y[self.index] z = self.z[self.index] m = self.m[self.index] # Define empty list of enclosed masses that's same size as radii list M_Enc = [] # Determine COM position of galaxy COM = CenterOfMass(self.filename, 2) COM_P = COM.COM_P(0.1) # Define components of COM XCOM = COM_P[0] YCOM = COM_P[1] ZCOM = COM_P[2] # Determine COM radius RCOM = np.sqrt((x - XCOM)**2 + (y - YCOM)**2 + (z - ZCOM)**2) # Measure mass enclosed within each radius for i in range(0, len(radii)): # Find indices of particles enclosed within RCOM new_index = np.where(RCOM < radii[i]) # Fill out M_Enc array accordingly M_Enc.append(np.sum(m[new_index]) * 1e10) # Uncomment to test code #print(M_Enc*u.Msun) return M_Enc * u.Msun
def OrbitCOM(galaxy, start, end, n): fileout = "Orbit_{}.txt".format(galaxy) Orbit = np.zeros((int(end/n + 1),7)) # Define the values for COM delta = 0.1 VolDec = 2 for i in np.arange(start, end+n, n): # add a string of the filenumber to the value “000” ilbl = '000' + str(i) # remove all but the last 3 digits ilbl = ilbl[-3:] # create the filename filename = "{:s}_{:s}.txt".format(galaxy, ilbl) # Create a Center of Mass object for the Galaxy COM = CenterOfMass(filename, ptype = 2) Gal_COM = COM.COM_P(delta, VolDec) Gal_COMV = COM.COM_V(Gal_COM) # Get the time, position, and velocities of the particles time = float(COM.time/u.Myr)/1000.0 X = float(Gal_COM[0]/u.kpc) Y = float(Gal_COM[1]/u.kpc) Z = float(Gal_COM[2]/u.kpc) Vx = float(Gal_COMV[0]/(u.km/u.s)) Vy = float(Gal_COMV[1]/(u.km/u.s)) Vz = float(Gal_COMV[2]/(u.km/u.s)) # Store the values in the Orbit array Orbit[int(i/n),] = np.array([time, X, Y, Z, Vx, Vy, Vz]) print("{} {}".format(galaxy, i)) np.savetxt(fileout, Orbit, header='t x y z vx vy vz', comments='# ',\ fmt=['%.2f ', '%.2f ','%.2f ','%.2f ','%.2f ','%.2f ','%.2f ']) return None
def OrbitCOM(galaxy, start, end, n): fileout = 'Orbits_M31.txt' shape = ( int(end / n) + 1, 7 ) #i think just putting row,column for the shape makes np.zeros think column is the dtype Orbit = np.zeros(shape) delta = 1 VolDec = 5 for i in np.arange(start, end + n, n): ilbl = '000' + str(i) # remove all but the last 3 digits ilbl = ilbl[-3:] # create filenames filename = '%s_' % (galaxy) + ilbl + '.txt' time, total, data = Read(filename) COM = CenterOfMass(filename, 2) time = float(COM.time / u.Myr) #x = float(COM.x/u.kpc) #print(int(i/n)) R = COM.COM_P(delta, VolDec) V = COM.COM_V(R[0], R[1], R[2]) Orbit[int(i / n), 0] = time / 1000 Orbit[int(i / n), 1] = float(R[0] / u.kpc) Orbit[int(i / n), 2] = float(R[1] / u.kpc) Orbit[int(i / n), 3] = float(R[2] / u.kpc) Orbit[int(i / n), 4] = float(V[0] / u.km * u.s) Orbit[int(i / n), 5] = float(V[1] / u.km * u.s) Orbit[int(i / n), 6] = float(V[2] / u.km * u.s) print(i) print(Orbit) np.savetxt(fileout, Orbit, header='t x y z vx vy vz', comments='#', fmt=['%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f ', '%.2f '])
def OrbitCom(galaxy, start, end, n): fileout = "Orbit_M31.txt" #initialize file to contain all values delta = 0.1 #initialize delta and VolDec VolDec = 2 snapID = np.arange(start, end, n) #Array for deciding files to be read in orbit = np.zeros([snapID.size, 7]) #Array for containing all COM's for i, snapID in enumerate(snapID): ilbl = '000' + str( snapID) #Initialize new file to be read in from desired galaxy ilbl = ilbl[-3:] filename = "%s_" % (galaxy) + ilbl + ".txt" print(snapID) print(i) print(filename) COM = CenterOfMass(filename, 2) #Take in COM values orbitCOMP = COM.COM_P(VolDec, delta) #COM Position orbitCOMV = COM.COM_V(orbitCOMP[0], orbitCOMP[1], orbitCOMP[2]) #COM Velocity orbit[i, 0] = COM.time.value #assign time and COM values in order. orbit[i, 1] = orbitCOMP[0].value orbit[i, 2] = orbitCOMP[1].value orbit[i, 3] = orbitCOMP[2].value orbit[i, 4] = orbitCOMV[0].value orbit[i, 5] = orbitCOMV[1].value orbit[i, 6] = orbitCOMV[2].value #Output orbit array to file np.savetxt(fileout, orbit, header="time x y z vx vy vz", comments='#', fmt=['%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f']) return orbit
def MassEnclosed(self, ptype, R): # Function that determines the MassEnclosed of particles of a given type # input: ptype Particle type, 1=Halo, 2=Disk, 3=Bulge # R An Array of Radii within which to compute the mass enclosed. # return: an array with the Mass enclosed (units of Msun) # Determine the COM position using Disk Particles # Disk Particles afford the best centroiding. # Create a COM object COM = CenterOfMass(self.filename,2) # Store the COM position of the galaxy # Set Delta = whatever you determined to be a good value in Homework 4. GalCOMP = COM.COM_P(0.1) # create an array to store indexes of particles of desired Ptype index = np.where(self.data['type'] == ptype) # Store positions of particles of given ptype from the COMP. xG = self.x[index] - GalCOMP[0] yG = self.y[index] - GalCOMP[1] zG = self.z[index] - GalCOMP[2] # Compute the mag. of the 3D radius rG = np.sqrt(xG**2 + yG**2 + zG**2) # store mass of particles of a given ptype mG = self.m[index] # Array to store enclosed mass as a function of the input radius array Menc = np.zeros(np.size(R)) # set up a while loop that continues until the end of the input radius array for i in range(np.size(R)): # Only want particles within the given radius indexR = np.where(rG < R[i]*u.kpc) Menc[i] = np.sum(mG[indexR])*1e10 # return the array of enclosed mass with appropriate units return Menc*u.Msun
def __init__(self, filename): # INPUTS: # # filename -- string, name of the file to store integrated orbit ### get the gravitational constant (the value is 4.498502151575286e-06) self.G = const.G.to(u.kpc**3 / u.Msun / u.Gyr**2).value ### **** store the output file name self.filename = filename ### get the current pos/vel of M33 # **** create an instance of the CenterOfMass class for M33 M33_com = CenterOfMass("M33_000.txt", 2) # Store postion and velocity vectors M33_comP = M33_com.COM_P(0.1) M33_comV = M33_com.COM_V(M33_comP[0], M33_comP[1], M33_comP[2]) ### get the current pos/vel of M31 M31_com = CenterOfMass("M31_000.txt", 2) M31_comP = M31_com.COM_P(0.1) M31_comV = M31_com.COM_V(M31_comP[0], M31_comP[1], M31_comP[2]) ### store the DIFFERENCE between the vectors posM33 - posM31 # **** create two VECTORs self.r0 and self.v0 and have them be the self.r0 = (M33_comP - M31_comP).value self.v0 = (M33_comV - M31_comV).value ### get the mass of each component in M31 ### disk # **** self.rdisk = scale length (no units) self.rdisk = 5 # **** self.Mdisk set with ComponentMass function. Remember to *1e12 to get the right units. Use the right ptype self.Mdisk = ComponentMass("M31_000.txt", 2) * 1e12 #in M_sun ### bulge # **** self.rbulge = set scale length (no units) self.rbulge = 1 # **** self.Mbulge set with ComponentMass function. Remember to *1e12 to get the right units Use the right ptype self.Mbulge = ComponentMass("M31_000.txt", 3) * 1e12 # Halo # **** self.rhalo = set scale length from HW5 (no units) self.rhalo = 62 # **** self.Mhalo set with ComponentMass function. Remember to *1e12 to get the right units. Use the right ptype self.Mhalo = ComponentMass("M31_000.txt", 1) * 1e12
def MassEnclosed(self, ptype, radii): """ A method that calculates the mass enclosed within a given radius of the galaxy for a given component PARAMETERS ---------- ptype : Particle type. Possible values are 'Halo', 'Disk' or 'Bulge'. Type = str radii : Radii within which total mass is to be computed. Type = Array RETURNS ------- masses : masses at each radii. Type = Array """ #creating exception for M33's non-existent bulge if (self.gname == 'M33') & (ptype == 3): return np.zeros(len(radii)) * u.Msun COM = CenterOfMass(self.filename, ptype) #center of mass position of the galaxy xcom, ycom, zcom = COM.COM_P(1) #tolerance level of 1kpc # calculating coordinates of each particle in COM's frame of reference xnew = COM.x - xcom ynew = COM.y - ycom znew = COM.z - zcom rnew = np.sqrt( (xnew**2) + (ynew**2) + (znew**2)) #position vecotr magnitudes masses = np.zeros(len(radii)) #initializing mass array to be returned #calculating mass at each radius for i, r in enumerate(radii): ind = np.where( rnew.value < r)[0] #masking for particles within the radius mass = np.sum(COM.m[ind]) masses[i] = mass.value return masses * u.Msun
def MassEnclosed(self, ptype, r): # Inputs: # ptype : particle type # r : magnitude radius # Returns: # An array of masses (in Msun) so we can use it to calculate the mass profile conveniently # Creating the COM object to then call COM position COM = CenterOfMass(self.filename, ptype) # Calling COM position delta = 0.1 XCOM, YCOM, ZCOM = COM.COM_P(delta) # change reference frame to COM frame xNew = self.x - XCOM yNew = self.y - YCOM zNew = self.z - ZCOM index = np.where(self.type == ptype) xNew2 = xNew[index] yNew2 = yNew[index] zNew2 = zNew[index] # Calculate magnitude R = (xNew2**2 + yNew2**2 + zNew2**2)**0.5 # Create array enmass = np.zeros(len(r)) # Loop over the radius array for i in range(len(r)): index2 = np.where(R < r[i]) # Adding the masses enmass[i] = np.sum(self.m[index][index2]) return enmass*1e10*u.Msun
def __init__(self, filename): self.filename = filename M31 = CenterOfMass(m31snap0,2) # realization of M31 M33 = CenterOfMass(m33snap0,2) # realization of M33 R_M31 = M31.COM_P(delta, VolDec) # Absolute position, kpc V_M31 = M31.COM_V(15.,R_M31) # Absolute velocity, km/s R_M33 = M33.COM_P(delta, VolDec) V_M33 = M33.COM_V(15.,R_M33) self.x = (R_M33 - R_M31)[0] # relative position of M33 to M31 self.y = (R_M33 - R_M31)[1] # kpc self.z = (R_M33 - R_M31)[2] self.vx = (V_M33 - V_M31)[0] # relative velocity ''' self.vy = (V_M33 - V_M31)[1] # km/s self.vz = (V_M33 - V_M31)[2] self.rd = 5.*u.kpc # disk scale length, kpc self.Mdisk = ComponentMass(m31snap0,2) # disk mass, M_sun self.rbulge = 1.*u.kpc # bulge scale length, kpc self.Mbulge = ComponentMass(m31snap0,3) # bulge mass, M_sun self.rhalo = 60.*u.kpc # determined from Assignment 3, kpc self.Mhalo = ComponentMass(m31snap0,1) # halo mass, M_sun
def __init__(self, filename): # Set the name of the file for the output self.filename = filename # Define the Gravitational constant self.G = 4.498768e-6*u.kpc**3/u.Msun/u.Gyr**2 # Create a Center of Mass object for M31 M31_COM = CenterOfMass("M31_000.txt", ptype=2) M31_COMP = M31_COM.COM_P(0.1, 2) M31_COMV = M31_COM.COM_V(M31_COMP) # Create a Center of Mass object for M33 M33_COM = CenterOfMass("M33_000.txt", ptype=2) M33_COMP = M33_COM.COM_P(0.1, 2) M33_COMV = M33_COM.COM_V(M33_COMP) # Recenter to COM position of M33 centered on M31 self.x = M31_COMP[0] - M33_COMP[0] self.y = M31_COMP[1] - M33_COMP[1] self.z = M31_COMP[2] - M33_COMP[2] # Recenter to COM velocity with respect to M31 self.vx = M31_COMV[0] - M33_COMV[0] self.vy = M31_COMV[1] - M33_COMV[1] self.vz = M31_COMV[2] - M33_COMV[2] # Set the scale lengths of the disk, bulge, and halo of M31 self.rd = 5.0*u.kpc self.rbulge = 1.0*u.kpc self.rhalo = 63.0*u.kpc # Set Masses for the disk, bulge, and halo self.Md = ComponentMass('M31_000.txt', 2) self.Mbulge = ComponentMass('M31_000.txt', 3) self.Mhalo = ComponentMass('M31_000.txt', 1) return None
origin="lower", **contour_kwargs) for l, s in zip(contour.levels, strs): fmt[l] = s ax.clabel(contour, contour.levels, inline=True, fmt=fmt, fontsize=12) return contour # Use the CenterOfMass code to compute the positions and velocities of all particles in M31's disk relative to its center of mass position and motion. # In[ ]: # Create a COM of object for M31 Disk Using Code from Assignment 4 #always give particle type two = dust particles COMD = CenterOfMass("M31_000.txt", 2) # In[ ]: # Compute COM of M31 using disk particles COMP = COMD.COM_P(0.1) COMV = COMD.COM_V(COMP[0], COMP[1], COMP[2]) # In[ ]: # Determine positions of disk particles relative to COM xD = COMD.x - COMP[0].value yD = COMD.y - COMP[1].value zD = COMD.z - COMP[2].value # total magnitude
for i, snap_id in enumerate(snap_ids): # Compose the data filename (be careful about the folder) # Add string of filenumber to value 000 ilbl = '000' + str(snap_id) # Remove all but last 3 digits of string ilbl = ilbl[-3:] # Assign filename based on snapshot and galaxy inputs MW_file = 'C:/Users/Jimmy/Downloads/MW/MW_' + ilbl + '.txt' M31_file = 'C:/Users/Jimmy/Downloads/M31/M31_' + ilbl + '.txt' M33_file = 'C:/Users/Jimmy/Downloads/M33/M33_' + ilbl + '.txt' # Define CoM object for each galaxy COMD_MW = CenterOfMass(MW_file, 2) COMD_M31 = CenterOfMass(M31_file, 2) COMD_M33 = CenterOfMass(M33_file, 2) # Find CoM components for position and velocity of the MW COMP_MW = COMD_MW.COM_P(0.1) COMV_MW = COMD_MW.COM_V(COMP_MW[0], COMP_MW[1], COMP_MW[2]) # Center the MW in the images xD_MW = COMD_MW.x - COMP_MW[0].value yD_MW = COMD_MW.y - COMP_MW[1].value zD_MW = COMD_MW.z - COMP_MW[2].value # Define positions of M31 Disk Particles xD_M31 = COMD_M31.x - COMP_MW[0].value yD_M31 = COMD_M31.y - COMP_MW[1].value
# my modules from ReadFile import Read from CenterOfMass import CenterOfMass from MassProfile import MassProfile # yt import yt from yt.units import kiloparsec, Msun, Gyr # In[ ]: # Create a COM of object for MW Disk Using Code from Assignment 4 # using highest res files - HR COMD = CenterOfMass("MW_HR_000.txt", 2) # In[ ]: # Compute COM of MW using disk particles COMP = COMD.COM_P(0.1, 4.0) # In assignment 6 you are asked to modify the CenterOfMass.py file so that # in addition to a 'delta' (tolerance) there is also a volume decrement value. # dividing the volume by 4.0 actually works better than dividing by half (RMAX/4 instead) # store COM Velocity COMV = COMD.COM_V(COMP[0], COMP[1], COMP[2]) # ## (PART 1) Edit Below: # ### Define the remaining data properties: yD, zD, vxD, vyD, vzD
def OrbitCOM(galaxy, start, end, n): # This function will compute the time and COM position and velocity # vectors of a given galaxy in each snapshot and save that output into a file # # INPUTS: # galaxy - the name of the galaxy as a string, e.g. “MW” # start - The number of the first snapshot to be read in # end - the number of the last snapshot to be read in. # n - n integer indicating the intervals over which COM will be returned. # # RETURNS: # No returns? # compose the filename for output fileout = "Orbit_" + galaxy + ".txt" # set tolerance and VolDec for calculating COM_P in CenterOfMass # for M33 that is stripped more, use different values for VolDec if galaxy == "M33": delta = 0.1 VolDec = 4.0 else: delta = 0.1 VolDec = 2.0 # generate the snapshot id sequence snap_ids = np.arange(start, end, n) # it is always a good idea to also check if the input is eligible (not required) if len(snap_ids) == 0: print("snap_ids array initialization failed. Check inputs") return # initialize the array for orbital info: t, x, y, z, vx, vy, vz of COM # NOTE: maybe could replace "len(snap_ids)" with "n", but not certain orbit = np.zeros((len(snap_ids), 7)) #orbit = np.zeros((n,7)) # print for awareness of what is going on print("\n\ncalculating data for " + galaxy + "\n") # a for loop for i, snap_id in enumerate(snap_ids): # loop over files # compose the data filename (be careful about the folder) loc = "/Users/colinhauch/Documents/College/Undergraduate/Semester8/400B/400B_hauch/Homeworks/Homework6" galaxyFolder = "/" + galaxy + "_VLowRes/" # create snap number string ilbl = '000' + str(snap_id) #remove all but last 3 digits to finalize snap number string ilbl = ilbl[-3:] # finalize the file name filename = loc + galaxyFolder + galaxy + "_" + ilbl + ".txt" # Initialize an instance of CenterOfMass class, using disk particles COM = CenterOfMass(filename, 2) # Store the COM pos and vel. Remember that now COM_P required VolDec GalCOMP = COM.COM_P(delta, VolDec) #GalCOMV = COM.COM_V(GalCOMP[0].value, GalCOMP[1].value, GalCOMP[2].value) GalCOMV = COM.COM_V(GalCOMP[0], GalCOMP[1], GalCOMP[2]) # store the time, pos, vel in ith element of the orbit array, without units (.value) # note that you can store # a[i] = var1, *tuple(array1) orbit[i] = COM.time.value / 1000, GalCOMP[0].value, GalCOMP[ 1].value, GalCOMP[2].value, GalCOMV[0].value, GalCOMV[ 1].value, GalCOMV[2].value # print snap_id to see the progress print(snap_id) # write the data to a file # we do this because we don't want to have to repeat this process # this code should only have to be called once per galaxy. np.savetxt(fileout, orbit, fmt = "%11.3f"*7, comments='#', header="{:>10s}{:>11s}{:>11s}{:>11s}{:>11s}{:>11s}{:>11s}"\ .format('t', 'x', 'y', 'z', 'vx', 'vy', 'vz'))
# import plotting modules import matplotlib import matplotlib.pyplot as plt from matplotlib.colors import LogNorm get_ipython().magic('matplotlib inline') # my modules from ReadFile import Read from CenterOfMass import CenterOfMass # In[5]: # Create a COM of object for MW Disk Using Code from Assignment 4 # using highest res files # modified CenterOfMass so that it doesn't return rounded values COMD = CenterOfMass("MW_HR_000.txt", 2) # In[6]: # Compute COM of MW using disk particles COMP = COMD.COM_P(0.1, 4.0) # In[7]: # Determine positions and velocities of disk particles relative to COM motion xD = COMD.x - float(COMP[0] / u.kpc) yD = COMD.y - float(COMP[1] / u.kpc) zD = COMD.z - float(COMP[2] / u.kpc) # In[8]: