def OrbitCOM(galaxy,start,end,n): """function that loops over all the desired snapshots to compute the COM pos and vel as a function of time inputs: galaxy the name of the galaxy e.g. "MW" start initial SnapNumber e.g. 0 end final SnapNumber e.g. 100 n integer indicating the frequency with which the snapshots are read in; n should not be 0 returns: file with COM pos/vel of a galaxy at snapshots over the range (start, end+n, n) columns t, x, y, z, vx, vy, vz for n snapshots """ # compose the filename for output #fileout = "Orbit_" + galaxy + ".txt" fileout = 'Orbit_%s.txt'%(galaxy) # filename to store output # set tolerance and VolDec for calculating COM_P in CenterOfMass delta, VolDec = 0.1, 2.0 # for M33 that is stripped more, use different values for VolDec if galaxy is "M33": delta, VolDec = 0.1, 4.0 # generate the snapshot id sequence and check if the input is eligible snap_ids = np.arange(start, end+n, n) if snap_ids.size == 0: raise ValueError("Cannot build a sequence using the input, start = ", start, "end = ", end, "n = ", n) # initialize the array for orbital info: t, x, y, z, vx, vy, vz of COM orbit = np.zeros([snap_ids.size, 7]) # a for loop for i, snap_id in enumerate(snap_ids): # loop over files # compose the data filename (be careful about the folder) filename = "VLowRes/" + galaxy + "_VLowRes/" + galaxy + "_{:03d}".format(snap_id) + ".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 COM_pos = COM.COM_P(delta, VolDec) COM_vel = COM.COM_V(COM_pos[0],COM_pos[1], COM_pos[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, *tuple(COM_pos.value), *tuple(COM_vel.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'))
def __init__(self, filename): # Define gravitational constant as global variable self.G = const.G.to(u.kpc**3 / u.Msun / u.Gyr**2).value # Define centers of mass for M31 and M33 by calling CoM function M31COM = CenterOfMass('C:/Users/Jimmy/400B_Lilly/M31_000.txt', 2) M33COM = CenterOfMass('C:/Users/Jimmy/400B_Lilly/M33_000.txt', 2) M31_COMP = M31COM.COM_P(0.1, 2) # delta = 0.1, VolDec = 2 M31_COMV = M31COM.COM_V(M31_COMP[0], M31_COMP[1], M31_COMP[2]) M33_COMP = M33COM.COM_P(0.1, 4) # delta = 0.1, VolDec = 4 M33_COMV = M33COM.COM_V(M33_COMP[0], M33_COMP[1], M33_COMP[2]) # Calculate relative position and velocity of M31 and M33 self.r0 = (M33_COMP - M31_COMP).value self.v0 = (M33_COMV - M31_COMV).value # Assign filename to variable self.filename = filename # Scale lengths and masses for each component of M31 self.rdisk = 5.0 # in kpc self.Mdisk = 1e12 * ComponentMass( 'C:/Users/Jimmy/400B_Lilly/M31_000.txt', 2).value # in Msun self.rbulge = 1.0 # in kpc self.Mbulge = 1e12 * ComponentMass( 'C:/Users/Jimmy/400B_Lilly/M31_000.txt', 3).value # in Msun self.rhalo = 61.5 # in kpc self.Mhalo = 1e12 * ComponentMass( 'C:/Users/Jimmy/400B_Lilly/M31_000.txt', 1).value # in Msun
def __init__(self,outfile): """ inputs: outfile = string containing the filename to write orbit data to """ # save output file name for later self.outfile = outfile ### get the gravitational constant (the value is 4.498502151575286e-06) self.G = const.G.to(u.kpc**3/u.Msun/u.Gyr**2).value ### get the current pos/vel of M33 M33COM = CenterOfMass('M33_000.txt',2) # store the position VECTOR of the M33 COM delta = 0.1 VolDec = 4 M33COMP = M33COM.COM_P(delta,VolDec) # store the velocity VECTOR of the M33 COM M33COMV = M33COM.COM_V(*M33COMP) # these are astropy quantities, we would like to get rid of the units M33COMP = M33COMP.value M33COMV = M33COMV.value ### get the current pos/vel of M31 M31COM = CenterOfMass('M31_000.txt',2) # store the position VECTOR of the M31 COM delta = 0.1 VolDec = 2 M31COMP = M31COM.COM_P(delta,VolDec) # store the velocity VECTOR of the M31 COM M31COMV = M31COM.COM_V(*M31COMP) # these are astropy quantities, we would like to get rid of the units M31COMP = M31COMP.value M31COMV = M31COMV.value # store the relative position and velocity of M33 w.r.t. M31 self.r0 = M33COMP - M31COMP self.v0 = M33COMV - M31COMV ### get the mass of each component in M31 # disk self.rdisk = 5 # kpc self.Mdisk = ComponentMass('M31_000.txt',2)*1e12 # Msun # bulge self.rbulge = 1 # kpc self.Mbulge = ComponentMass('M31_000.txt',3)*1e12 # Msun # halo self.rhalo = 60 # kpc self.Mhalo = ComponentMass('M31_000.txt',1)*1e12 # Msun
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 Voldec=self.VolDec Delta=self.delta 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(Delta,Voldec) # 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 CumDispersion(self, rArray): # Takes as input an array of radii # Returns the cumulative velocity dispersion within the stars enclosed COM_Object = CenterOfMass(self.filename, 2) VX_COM, VY_COM, VZ_COM = COM_Object.COM_V(1.0) X_COM, Y_COM, Z_COM = COM_Object.COM_P( 1.0) # Finds the center of mass coordinates of the galaxy typeIndex = np.where(self.data['type'] == 3) # Selects bulge particles radii = self.distance(self.x, X_COM, self.y, Y_COM, self.z, Z_COM) # Creates an array to hold distances of particles from the COM dispersions = np.zeros(len(rArray)) # Creates our result array for index in range(len(rArray)): # Loops over rArray to find enclosed dispersion indices = np.where(radii < rArray[index]) dispersions[index] = self.dispersion(self.data[indices], VX_COM, VY_COM, VZ_COM) print(rArray[index]) return dispersions
def __init__(self, filename): """ Initialize the class with the current properties of M33 input: filename, string denoting the name of the file in which the output orbit will be stored """ # 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 relative to M31 M33_COM = CenterOfMass("M33_000.txt", 2) self.r0 = M33_COM.COM_P( 0.1, 4 ) # equivalently could have set self.x self.y self.z to each component. self.v0 = M33_COM.COM_V(self.r0[0], self.r0[1], self.r0[2]).value self.r0 = self.r0.value M31_COM = CenterOfMass("M31_000.txt", 2) M31_r0 = M31_COM.COM_P(0.1, 2) self.r0 -= M31_r0.value # subtract out the M31 COM Position from the previously defined values self.v0 -= M31_COM.COM_V(M31_r0[0], M31_r0[1], M31_r0[2]).value # subtract out the M31 COM velocity from the previously defined values # get the mass of each component in M31 # disk self.rdisk = 5.0 # set the scale length self.Mdisk = ComponentMass("M31_000.txt", 2) * 1e12 # bulge self.rbulge = 1.0 # set the bulge scale length self.Mbulge = ComponentMass("M31_000.txt", 3) * 1e12 # Halo self.rhalo = 61.58 # use the Hernquist scale length (a) computed in HW5 self.Mhalo = ComponentMass("M31_000.txt", 1) * 1e12 ### ADD M33 HALO MASS HERE #### self.M33halo = ComponentMass("M33_000.txt", 1) * 1e12 ### ADD M31 CIRCULAR SPEED HERE ### self.Vc = 230 #km/s ### Fudge factor ## self.fudge = 0.5
def OrbitCom(galaxy, start, end, n=5): """function that loops over all the desired snapshots to compute the COM pos and vel as a function of time. inputs: galaxy name ie: "MW", start: first snapshot to be read, end: last snapshot to be read, n: intervals to return the COM We will compute up to snapshot 800 and we will outpu values in intervals of n=5 returns: computes the timen and COM position and velocity vectors of a given a galaxy in each snapshot saves that output into a file. """ # 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 else: delta = 0.1 VolDec = 2 # generate the snapshot id sequence # it is always a good idea to also check if the input is eligible (not required) snap_ids = np.arange(start, end + 1, step=n) # initialize the array for orbital info: t, x, y, z, vx, vy, vz of COM orbit = np.zeros((snap_ids.size, 7)) # a for loop for i, snap_id in enumerate(snap_ids): # compose the data filename (be careful about the folder) # inputs to recontruct the filenumber to the value "000" ilbl = '000' + str(snap_id) # remove all but the last 3 digits ilbl = ilbl[-3:] filename = "%s_" % (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 COM_P = COM.COM_P(delta, VolDec) COM_V = COM.COM_V(COM_P[0], COM_P[1], COM_P[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, *tuple(COM_P.value), *tuple( COM_V.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'))
# and then call them when you want to e.g. make plots or do some analysis. from contour import density_contour # # Part A. Load in Data and make some simple plots # # To do this lab you will need to sftp into nimoy to get the highres data files for this lab: # MW_000.txt and MW_400.txt # If you don't have enough space on your computer you can use the low res files. # # In[ ]: # Load in disk particles centered on the MW # this is from the HighRes data files on nimoy so it might take a bit of time to load # you can use the low res files if this is taking too long or if you don't have enough space on your computer COM = CenterOfMass("MW_000.txt", 2) # In[ ]: # Compute COM of the MW at the new position using disk particles COMP = COM.COM_P(0.1, 2) COMV = COM.COM_V(COMP[0], COMP[1], COMP[2]) # Determine positions of disk particles relative to COM MW_Disk_x = COM.x - COMP[0].value MW_Disk_y = COM.y - COMP[1].value # Also store the disk velocity in the y direction MW_Disk_vy = COM.vy - COMV[1].value # In[ ]:
def OrbitCOM(galaxy, start, end, n): # Inputs: # galaxy = name of galaxy (MW, M31, or M33) # start = number of first snapshot # end = number of last snapshot # n = intervals at which to return COM # Returns: # COM_P = position of center of mass of galaxy # COM_V = velocity of center of mass of galaxy # compose the filename for output fileout = "C:/Users/Jimmy/400B_Lilly/Homeworks/Homework6/Orbit_{0}.txt".format( galaxy) # 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 else: delta = 0.1 VolDec = 5 # generate the snapshot id sequence # it is always a good idea to also check if the input is eligible (not required) snap_ids = np.arange(start, end, n) # initialize the array for orbital info: t, x, y, z, vx, vy, vz of COM orbit = np.zeros([len(snap_ids), 7]) # Loop to calculate COM pos. and vel. at each snapshot 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 filename = 'C:/Users/Jimmy/Downloads/' + '%s/' % (galaxy) + '%s_' % ( 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 COM_P = COM.COM_P(delta, VolDec) COM_V = COM.COM_V(COM_P[0], COM_P[1], COM_P[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, *tuple(COM_P.value), *tuple( COM_V.value) # print snap_id to see the progress print('Calculating COM info for ' + str(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. """
def OrbitCOM(galaxy, start, end, n): """function that loops over all the desired snapshots to compute the COM pos and vel as a function of time. inputs: galaxy = string containing galaxy name start = first snapshot # end = last snapshot # n = length of the intervals (in snapshots) returns: an array with columns: time, x, y, z, vx, vy, vz each row contains calculations for 1 snapshot """ # 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 else: delta = 0.1 VolDec = 2 # generate the snapshot id sequence # check if the input is eligible snap_ids = np.arange(start, end, n) if (len(snap_ids) == 0): sys.exit("no snapshots included in given range") # initialize the array for orbital info: t, x, y, z, vx, vy, vz of COM orbit = np.zeros([len(snap_ids), 7]) # loop over snapshots for i, snap_id in enumerate(snap_ids): # compose the data filename # add a string of the filenumber to the value “000” ilbl = '000' + str(snap_id) # remove all but the last 3 digits ilbl = ilbl[-3:] filename = "VLowRes/" + "%s_" % (galaxy) + ilbl + '.txt' # Initialize an instance of CenterOfMass class, using disk particles COM = CenterOfMass(filename, 2) # 2 for disk particles # Store the COM pos and vel. Remember that now COM_P required VolDec COMP = COM.COM_P(delta, VolDec) COMV = COM.COM_V(*COMP) # 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) t = COM.time.value / 1000 # units Gyr COMP = COMP.value COMV = COMV.value orbit[i] = t, *tuple(COMP), *tuple(COMV) # 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'))