def printPotTypeArg(pot_name, pot_module, pot_instance, print_front_offset=0, print_long_list=False): """ print the petar --type-arg options for a given potential Format of --type-arg is type1,type2,...:arg1,arg2,... or type1:arg1-1,arg1-2,...|type2:arg2-1,arg2-2,... Parameters ---------- pot_name: string Name of potential pot_module: class object The corresponding Potential class of a given potential, if the potential is a list of potential instances, input None pot_instance: potential instance The potential instance or a list of potential instances Return ---------- type_arg: petar --type-arg option argument for the given potential npot: number of potential models pot_type: a list of potential types used in the given potential pot_arg: a list of potential argments used in the given potential """ name_format='{:30}' if (pot_module == None) & (type(pot_instance) == list): print(" "*print_front_offset, name_format.format(pot_name), "a combination of %d potentials:" % len(pot_instance)) type_arg="" npot=0 pot_type=np.array([]).astype(int) pot_arg=np.array([]) for pot_sub in pot_instance: type_arg_sub, n_sub, type_sub, arg_sub = printPotTypeArg(type(pot_sub).__name__, None, pot_sub, print_front_offset+4, print_long_list) if (type_arg != ""): type_arg += "|" type_arg += type_arg_sub npot += n_sub pot_type = np.append(pot_type,type_sub) pot_arg = np.append(pot_arg,arg_sub) print(" "*(print_front_offset+4), name_format.format("Combination: "),type_arg) return type_arg, npot, pot_type, pot_arg elif (pot_instance != None): npot, pot_type, pot_args= _parse_pot(pot_instance) if (pot_type.size>0): pot_args_str='' for i in range(pot_args.size-1): pot_args_str+=str(pot_args[i])+',' if (pot_args.size>0): pot_args_str+=str(pot_args[-1]) type_arg = '' if (pot_type.size==1): type_arg = str(pot_type[0])+':'+pot_args_str else: for i in range(pot_type.size-1): type_arg += str(pot_type[i])+',' type_arg += str(pot_type[-1])+':'+pot_args_str if (pot_args.size>12) & (not print_long_list): print(" "*print_front_offset, name_format.format(pot_name), "long argument list, require a configure file") else: print(" "*print_front_offset, name_format.format(pot_name), type_arg) return type_arg, npot, pot_type, pot_args return "", 0, np.array([]).astype(int), np.array([])
def eval_potential_c(pot,R,z): """ NAME: eval_potential_c PURPOSE: Use C to evaluate the interpolated potential INPUT: pot - Potential or list of such instances R - array z - array OUTPUT: potential evaluated R and z HISTORY: 2013-01-24 - Written - Bovy (IAS) """ from galpy.orbit.integrateFullOrbit import _parse_pot #here bc otherwise there is an infinite loop #Parse the potential npot, pot_type, pot_args= _parse_pot(pot,potforactions=True) #Set up result arrays out= numpy.empty((len(R))) err= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') interppotential_calc_potentialFunc= _lib.eval_potential interppotential_calc_potentialFunc.argtypes= [ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [R.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS']] R= numpy.require(R,dtype=numpy.float64,requirements=['C','W']) z= numpy.require(z,dtype=numpy.float64,requirements=['C','W']) out= numpy.require(out,dtype=numpy.float64,requirements=['C','W']) #Run the C code interppotential_calc_potentialFunc(len(R), R, z, ctypes.c_int(npot), pot_type, pot_args, out, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R= numpy.asfortranarray(R) if f_cont[1]: z= numpy.asfortranarray(z) return (out,err.value)
def calc_potential_c(pot,R,z,rforce=False,zforce=False): """ NAME: calc_potential_c PURPOSE: Use C to calculate the potential on a grid INPUT: pot - Potential or list of such instances R - grid in R z - grid in z rforce=, zforce= if either of these is True, calculate the radial or vertical force instead OUTPUT: potential on the grid (2D array) HISTORY: 2013-01-24 - Written - Bovy (IAS) 2013-01-29 - Added forces - Bovy (IAS) """ from galpy.orbit.integrateFullOrbit import _parse_pot #here bc otherwise there is an infinite loop #Parse the potential npot, pot_type, pot_args= _parse_pot(pot) #Set up result arrays out= numpy.empty((len(R),len(z))) err= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') if rforce: interppotential_calc_potentialFunc= _lib.calc_rforce elif zforce: interppotential_calc_potentialFunc= _lib.calc_zforce else: interppotential_calc_potentialFunc= _lib.calc_potential interppotential_calc_potentialFunc.argtypes= [ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [R.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS']] R= numpy.require(R,dtype=numpy.float64,requirements=['C','W']) z= numpy.require(z,dtype=numpy.float64,requirements=['C','W']) out= numpy.require(out,dtype=numpy.float64,requirements=['C','W']) #Run the C code interppotential_calc_potentialFunc(len(R), R, len(z), z, ctypes.c_int(npot), pot_type, pot_args, out, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R= numpy.asfortranarray(R) if f_cont[1]: z= numpy.asfortranarray(z) return (out,err.value)
def actionAngleTorus_xvFreqs_c(pot,jr,jphi,jz, angler,anglephi,anglez, tol=0.003): """ NAME: actionAngleTorus_xvFreqs_c PURPOSE: compute configuration (x,v) and frequencies of a set of angles on a single torus INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) angler - radial angle (array [N]) anglephi - azimuthal angle (array [N]) anglez - vertical angle (array [N]) tol= (0.003) goal for |dJ|/|J| along the torus OUTPUT: (R,vR,vT,z,vz,phi,Omegar,Omegaphi,Omegaz,flag) HISTORY: 2015-08-05/07 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potfortorus=True) #Set up result arrays R= numpy.empty(len(angler)) vR= numpy.empty(len(angler)) vT= numpy.empty(len(angler)) z= numpy.empty(len(angler)) vz= numpy.empty(len(angler)) phi= numpy.empty(len(angler)) Omegar= numpy.empty(1) Omegaphi= numpy.empty(1) Omegaz= numpy.empty(1) flag= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleTorus_xvFreqsFunc= _lib.actionAngleTorus_xvFreqs actionAngleTorus_xvFreqsFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [angler.flags['F_CONTIGUOUS'], anglephi.flags['F_CONTIGUOUS'], anglez.flags['F_CONTIGUOUS']] angler= numpy.require(angler,dtype=numpy.float64,requirements=['C','W']) anglephi= numpy.require(anglephi,dtype=numpy.float64,requirements=['C','W']) anglez= numpy.require(anglez,dtype=numpy.float64,requirements=['C','W']) R= numpy.require(R,dtype=numpy.float64,requirements=['C','W']) vR= numpy.require(vR,dtype=numpy.float64,requirements=['C','W']) vT= numpy.require(vT,dtype=numpy.float64,requirements=['C','W']) z= numpy.require(z,dtype=numpy.float64,requirements=['C','W']) vz= numpy.require(vz,dtype=numpy.float64,requirements=['C','W']) phi= numpy.require(phi,dtype=numpy.float64,requirements=['C','W']) Omegar= numpy.require(Omegar,dtype=numpy.float64,requirements=['C','W']) Omegaphi= numpy.require(Omegaphi,dtype=numpy.float64,requirements=['C','W']) Omegaz= numpy.require(Omegaz,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleTorus_xvFreqsFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(len(angler)), angler, anglephi, anglez, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), R,vR,vT,z,vz,phi, Omegar,Omegaphi,Omegaz, ctypes.byref(flag)) #Reset input arrays if f_cont[0]: angler= numpy.asfortranarray(angler) if f_cont[1]: anglephi= numpy.asfortranarray(anglephi) if f_cont[2]: anglez= numpy.asfortranarray(anglez) return (R,vR,vT,z,vz,phi,Omegar[0],Omegaphi[0],Omegaz[0],flag.value)
def actionAngleTorus_jacobian_c(pot,jr,jphi,jz,angler,anglephi,anglez, tol=0.003,dJ=0.001): """ NAME: actionAngleTorus_jacobian_c PURPOSE: compute d(x,v)/d(J,theta) on a single torus, also compute dO/dJ and the frequencies INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) angler - radial angle (array [N]) anglephi - azimuthal angle (array [N]) anglez - vertical angle (array [N]) tol= (0.003) goal for |dJ|/|J| along the torus dJ= (0.001) action difference when computing derivatives (Hessian or Jacobian) OUTPUT: (d[R,vR,vT,z,vz,phi]/d[J,theta], Omegar,Omegaphi,Omegaz, Autofit error message) Note: dO/dJ is *not* symmetrized here HISTORY: 2016-07-19 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potfortorus=True) #Set up result R= numpy.empty(len(angler)) vR= numpy.empty(len(angler)) vT= numpy.empty(len(angler)) z= numpy.empty(len(angler)) vz= numpy.empty(len(angler)) phi= numpy.empty(len(angler)) dxvOdJaT= numpy.empty(36*len(angler)) dOdJT= numpy.empty(9) Omegar= numpy.empty(1) Omegaphi= numpy.empty(1) Omegaz= numpy.empty(1) flag= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleTorus_JacFunc= _lib.actionAngleTorus_jacobianFreqs actionAngleTorus_JacFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [angler.flags['F_CONTIGUOUS'], anglephi.flags['F_CONTIGUOUS'], anglez.flags['F_CONTIGUOUS']] angler= numpy.require(angler,dtype=numpy.float64,requirements=['C','W']) anglephi= numpy.require(anglephi,dtype=numpy.float64,requirements=['C','W']) anglez= numpy.require(anglez,dtype=numpy.float64,requirements=['C','W']) R= numpy.require(R,dtype=numpy.float64,requirements=['C','W']) vR= numpy.require(vR,dtype=numpy.float64,requirements=['C','W']) vT= numpy.require(vT,dtype=numpy.float64,requirements=['C','W']) z= numpy.require(z,dtype=numpy.float64,requirements=['C','W']) vz= numpy.require(vz,dtype=numpy.float64,requirements=['C','W']) phi= numpy.require(phi,dtype=numpy.float64,requirements=['C','W']) dxvOdJaT= numpy.require(dxvOdJaT, dtype=numpy.float64,requirements=['C','W']) dOdJT= numpy.require(dOdJT,dtype=numpy.float64,requirements=['C','W']) Omegar= numpy.require(Omegar,dtype=numpy.float64,requirements=['C','W']) Omegaphi= numpy.require(Omegaphi,dtype=numpy.float64,requirements=['C','W']) Omegaz= numpy.require(Omegaz,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleTorus_JacFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(len(angler)), angler, anglephi, anglez, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), ctypes.c_double(dJ), R,vR,vT,z,vz,phi, dxvOdJaT, dOdJT, Omegar,Omegaphi,Omegaz, ctypes.byref(flag)) #Reset input arrays if f_cont[0]: angler= numpy.asfortranarray(angler) if f_cont[1]: anglephi= numpy.asfortranarray(anglephi) if f_cont[2]: anglez= numpy.asfortranarray(anglez) dxvOdJaT= numpy.reshape(dxvOdJaT,(len(angler),6,6),order='C') dxvOdJa= numpy.swapaxes(dxvOdJaT,1,2) return (R,vR,vT,z,vz,phi, dxvOdJa, dOdJT.reshape((3,3)).T, Omegar[0],Omegaphi[0],Omegaz[0], flag.value)
def actionAngleTorus_hessian_c(pot,jr,jphi,jz, tol=0.003,dJ=0.001): """ NAME: actionAngleTorus_hessian_c PURPOSE: compute dO/dJ on a single torus INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) tol= (0.003) goal for |dJ|/|J| along the torus dJ= (0.001) action difference when computing derivatives (Hessian or Jacobian) OUTPUT: (dO/dJ,Omegar,Omegaphi,Omegaz,Autofit error flag) Note: dO/dJ is *not* symmetrized here HISTORY: 2016-07-15 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potfortorus=True) #Set up result dOdJT= numpy.empty(9) Omegar= numpy.empty(1) Omegaphi= numpy.empty(1) Omegaz= numpy.empty(1) flag= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleTorus_HessFunc= _lib.actionAngleTorus_hessianFreqs actionAngleTorus_HessFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements dOdJT= numpy.require(dOdJT,dtype=numpy.float64,requirements=['C','W']) Omegar= numpy.require(Omegar,dtype=numpy.float64,requirements=['C','W']) Omegaphi= numpy.require(Omegaphi,dtype=numpy.float64,requirements=['C','W']) Omegaz= numpy.require(Omegaz,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleTorus_HessFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), ctypes.c_double(dJ), dOdJT, Omegar,Omegaphi,Omegaz, ctypes.byref(flag)) return (dOdJT.reshape((3,3)).T,Omegar[0],Omegaphi[0],Omegaz[0],flag.value)
def actionAngleTorus_Freqs_c(pot,jr,jphi,jz, tol=0.003): """ NAME: actionAngleTorus_Freqs_c PURPOSE: compute frequencies on a single torus INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) tol= (0.003) goal for |dJ|/|J| along the torus OUTPUT: (Omegar,Omegaphi,Omegaz,flag) HISTORY: 2015-08-05/07 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potfortorus=True) #Set up result Omegar= numpy.empty(1) Omegaphi= numpy.empty(1) Omegaz= numpy.empty(1) flag= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleTorus_FreqsFunc= _lib.actionAngleTorus_Freqs actionAngleTorus_FreqsFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements Omegar= numpy.require(Omegar,dtype=numpy.float64,requirements=['C','W']) Omegaphi= numpy.require(Omegaphi,dtype=numpy.float64,requirements=['C','W']) Omegaz= numpy.require(Omegaz,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleTorus_FreqsFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), Omegar,Omegaphi,Omegaz, ctypes.byref(flag)) return (Omegar[0],Omegaphi[0],Omegaz[0],flag.value)
def actionAngleTorus_Freqs_c(pot, jr, jphi, jz, tol=0.003): """ NAME: actionAngleTorus_Freqs_c PURPOSE: compute frequencies on a single torus INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) tol= (0.003) goal for |dJ|/|J| along the torus OUTPUT: (Omegar,Omegaphi,Omegaz,flag) HISTORY: 2015-08-05/07 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potfortorus=True) #Set up result Omegar = numpy.empty(1) Omegaphi = numpy.empty(1) Omegaz = numpy.empty(1) flag = ctypes.c_int(0) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleTorus_FreqsFunc = _lib.actionAngleTorus_Freqs actionAngleTorus_FreqsFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements Omegar = numpy.require(Omegar, dtype=numpy.float64, requirements=['C', 'W']) Omegaphi = numpy.require(Omegaphi, dtype=numpy.float64, requirements=['C', 'W']) Omegaz = numpy.require(Omegaz, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleTorus_FreqsFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), Omegar, Omegaphi, Omegaz, ctypes.byref(flag)) return (Omegar[0], Omegaphi[0], Omegaz[0], flag.value)
def actionAngleFreqAngleStaeckel_c(pot,delta,R,vR,vT,z,vz,phi, u0=None,order=10): """ NAME: actionAngleFreqAngleStaeckel_c PURPOSE: Use C to calculate actions, frequencies, and angles using the Staeckel approximation INPUT: pot - Potential or list of such instances delta - focal length of prolate spheroidal coordinates R, vR, vT, z, vz, phi - coordinates (arrays) u0= (None) if set, u0 to use order= (10) order of Gauss-Legendre integration of the relevant integrals OUTPUT: (jr,jz,Omegar,Omegaphi,Omegaz,Angler,Anglephi,Anglez,err) jr,jz,Omegar,Omegaphi,Omegaz,Angler,Anglephi,Anglez : array, shape (len(R)) err - non-zero if error occured HISTORY: 2013-08-27 - Written - Bovy (IAS) """ if u0 is None: u0, dummy= bovy_coords.Rz_to_uv(R,z,delta=numpy.atleast_1d(delta)) #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potforactions=True) #Parse delta delta= numpy.atleast_1d(delta) ndelta= len(delta) #Set up result arrays jr= numpy.empty(len(R)) jz= numpy.empty(len(R)) Omegar= numpy.empty(len(R)) Omegaphi= numpy.empty(len(R)) Omegaz= numpy.empty(len(R)) Angler= numpy.empty(len(R)) Anglephi= numpy.empty(len(R)) Anglez= numpy.empty(len(R)) err= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleStaeckel_actionsFunc= _lib.actionAngleStaeckel_actionsFreqsAngles actionAngleStaeckel_actionsFunc.argtypes= [ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'], vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'], vz.flags['F_CONTIGUOUS'], u0.flags['F_CONTIGUOUS'], delta.flags['F_CONTIGUOUS']] R= numpy.require(R,dtype=numpy.float64,requirements=['C','W']) vR= numpy.require(vR,dtype=numpy.float64,requirements=['C','W']) vT= numpy.require(vT,dtype=numpy.float64,requirements=['C','W']) z= numpy.require(z,dtype=numpy.float64,requirements=['C','W']) vz= numpy.require(vz,dtype=numpy.float64,requirements=['C','W']) u0= numpy.require(u0,dtype=numpy.float64,requirements=['C','W']) delta= numpy.require(delta,dtype=numpy.float64,requirements=['C','W']) jr= numpy.require(jr,dtype=numpy.float64,requirements=['C','W']) jz= numpy.require(jz,dtype=numpy.float64,requirements=['C','W']) Omegar= numpy.require(Omegar,dtype=numpy.float64,requirements=['C','W']) Omegaphi= numpy.require(Omegaphi,dtype=numpy.float64, requirements=['C','W']) Omegaz= numpy.require(Omegaz,dtype=numpy.float64,requirements=['C','W']) Angler= numpy.require(Angler,dtype=numpy.float64,requirements=['C','W']) Anglephi= numpy.require(Anglephi,dtype=numpy.float64, requirements=['C','W']) Anglez= numpy.require(Anglez,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleStaeckel_actionsFunc(len(R), R, vR, vT, z, vz, u0, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_int(ndelta), delta, ctypes.c_int(order), jr, jz, Omegar, Omegaphi, Omegaz, Angler, Anglephi, Anglez, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R= numpy.asfortranarray(R) if f_cont[1]: vR= numpy.asfortranarray(vR) if f_cont[2]: vT= numpy.asfortranarray(vT) if f_cont[3]: z= numpy.asfortranarray(z) if f_cont[4]: vz= numpy.asfortranarray(vz) if f_cont[5]: u0= numpy.asfortranarray(u0) if f_cont[6]: delta= numpy.asfortranarray(delta) badAngle = Anglephi != 9999.99 Anglephi[badAngle]= (Anglephi[badAngle] + phi[badAngle] % (2.*numpy.pi)) % (2.*numpy.pi) Anglephi[Anglephi < 0.]+= 2.*numpy.pi return (jr,jz,Omegar,Omegaphi,Omegaz,Angler, Anglephi,Anglez,err.value)
def actionAngleStaeckel_calcu0(E, Lz, pot, delta): """ NAME: actionAngleStaeckel_calcu0 PURPOSE: Use C to calculate u0 in the Staeckel approximation INPUT: E, Lz - energy and angular momentum pot - Potential or list of such instances delta - focal length of prolate spheroidal coordinates OUTPUT: (u0,err) u0 : array, shape (len(E)) err - non-zero if error occured HISTORY: 2012-12-03 - Written - Bovy (IAS) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potforactions=True) #Set up result arrays u0 = numpy.empty(len(E)) err = ctypes.c_int(0) #Parse delta delta = numpy.atleast_1d(delta) ndelta = len(delta) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleStaeckel_actionsFunc = _lib.calcu0 actionAngleStaeckel_actionsFunc.argtypes = [ ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int) ] #Array requirements, first store old order f_cont = [ E.flags['F_CONTIGUOUS'], Lz.flags['F_CONTIGUOUS'], delta.flags['F_CONTIGUOUS'] ] E = numpy.require(E, dtype=numpy.float64, requirements=['C', 'W']) Lz = numpy.require(Lz, dtype=numpy.float64, requirements=['C', 'W']) delta = numpy.require(delta, dtype=numpy.float64, requirements=['C', 'W']) u0 = numpy.require(u0, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleStaeckel_actionsFunc(len(E), E, Lz, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_int(ndelta), delta, u0, ctypes.byref(err)) #Reset input arrays if f_cont[0]: E = numpy.asfortranarray(E) if f_cont[1]: Lz = numpy.asfortranarray(Lz) if f_cont[2]: delta = numpy.asfortranarray(delta) return (u0, err.value)
def actionAngleAdiabatic_c(pot, gamma, R, vR, vT, z, vz): """ NAME: actionAngleAdiabatic_c PURPOSE: Use C to calculate actions using the adiabatic approximation INPUT: pot - Potential or list of such instances gamma - as in Lz -> Lz+\gamma * J_z R, vR, vT, z, vz - coordinates (arrays) OUTPUT: (jr,jz,err) jr,jz : array, shape (len(R)) err - non-zero if error occured HISTORY: 2012-12-10 - Written - Bovy (IAS) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potforactions=True) #Set up result arrays jr = numpy.empty(len(R)) jz = numpy.empty(len(R)) err = ctypes.c_int(0) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleAdiabatic_actionsFunc = _lib.actionAngleAdiabatic_actions actionAngleAdiabatic_actionsFunc.argtypes = [ ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_double, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int) ] #Array requirements, first store old order f_cont = [ R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'], vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'], vz.flags['F_CONTIGUOUS'] ] R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W']) vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W']) vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W']) z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W']) vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W']) jr = numpy.require(jr, dtype=numpy.float64, requirements=['C', 'W']) jz = numpy.require(jz, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleAdiabatic_actionsFunc(len(R), R, vR, vT, z, vz, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(gamma), jr, jz, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R = numpy.asfortranarray(R) if f_cont[1]: vR = numpy.asfortranarray(vR) if f_cont[2]: vT = numpy.asfortranarray(vT) if f_cont[3]: z = numpy.asfortranarray(z) if f_cont[4]: vz = numpy.asfortranarray(vz) return (jr, jz, err.value)
def actionAngleTorus_xvFreqs_c(pot, jr, jphi, jz, angler, anglephi, anglez, tol=0.003): """ NAME: actionAngleTorus_xvFreqs_c PURPOSE: compute configuration (x,v) and frequencies of a set of angles on a single torus INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) angler - radial angle (array [N]) anglephi - azimuthal angle (array [N]) anglez - vertical angle (array [N]) tol= (0.003) goal for |dJ|/|J| along the torus OUTPUT: (R,vR,vT,z,vz,phi,Omegar,Omegaphi,Omegaz,flag) HISTORY: 2015-08-05/07 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potfortorus=True) #Set up result arrays R = numpy.empty(len(angler)) vR = numpy.empty(len(angler)) vT = numpy.empty(len(angler)) z = numpy.empty(len(angler)) vz = numpy.empty(len(angler)) phi = numpy.empty(len(angler)) Omegar = numpy.empty(1) Omegaphi = numpy.empty(1) Omegaz = numpy.empty(1) flag = ctypes.c_int(0) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleTorus_xvFreqsFunc = _lib.actionAngleTorus_xvFreqs actionAngleTorus_xvFreqsFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont = [ angler.flags['F_CONTIGUOUS'], anglephi.flags['F_CONTIGUOUS'], anglez.flags['F_CONTIGUOUS'] ] angler = numpy.require(angler, dtype=numpy.float64, requirements=['C', 'W']) anglephi = numpy.require(anglephi, dtype=numpy.float64, requirements=['C', 'W']) anglez = numpy.require(anglez, dtype=numpy.float64, requirements=['C', 'W']) R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W']) vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W']) vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W']) z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W']) vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W']) phi = numpy.require(phi, dtype=numpy.float64, requirements=['C', 'W']) Omegar = numpy.require(Omegar, dtype=numpy.float64, requirements=['C', 'W']) Omegaphi = numpy.require(Omegaphi, dtype=numpy.float64, requirements=['C', 'W']) Omegaz = numpy.require(Omegaz, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleTorus_xvFreqsFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(len(angler)), angler, anglephi, anglez, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), R, vR, vT, z, vz, phi, Omegar, Omegaphi, Omegaz, ctypes.byref(flag)) #Reset input arrays if f_cont[0]: angler = numpy.asfortranarray(angler) if f_cont[1]: anglephi = numpy.asfortranarray(anglephi) if f_cont[2]: anglez = numpy.asfortranarray(anglez) return (R, vR, vT, z, vz, phi, Omegar[0], Omegaphi[0], Omegaz[0], flag.value)
def actionAngleTorus_jacobian_c(pot, jr, jphi, jz, angler, anglephi, anglez, tol=0.003, dJ=0.001): """ NAME: actionAngleTorus_jacobian_c PURPOSE: compute d(x,v)/d(J,theta) on a single torus, also compute dO/dJ and the frequencies INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) angler - radial angle (array [N]) anglephi - azimuthal angle (array [N]) anglez - vertical angle (array [N]) tol= (0.003) goal for |dJ|/|J| along the torus dJ= (0.001) action difference when computing derivatives (Hessian or Jacobian) OUTPUT: (d[R,vR,vT,z,vz,phi]/d[J,theta], Omegar,Omegaphi,Omegaz, Autofit error message) Note: dO/dJ is *not* symmetrized here HISTORY: 2016-07-19 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potfortorus=True) #Set up result R = numpy.empty(len(angler)) vR = numpy.empty(len(angler)) vT = numpy.empty(len(angler)) z = numpy.empty(len(angler)) vz = numpy.empty(len(angler)) phi = numpy.empty(len(angler)) dxvOdJaT = numpy.empty(36 * len(angler)) dOdJT = numpy.empty(9) Omegar = numpy.empty(1) Omegaphi = numpy.empty(1) Omegaz = numpy.empty(1) flag = ctypes.c_int(0) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleTorus_JacFunc = _lib.actionAngleTorus_jacobianFreqs actionAngleTorus_JacFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont = [ angler.flags['F_CONTIGUOUS'], anglephi.flags['F_CONTIGUOUS'], anglez.flags['F_CONTIGUOUS'] ] angler = numpy.require(angler, dtype=numpy.float64, requirements=['C', 'W']) anglephi = numpy.require(anglephi, dtype=numpy.float64, requirements=['C', 'W']) anglez = numpy.require(anglez, dtype=numpy.float64, requirements=['C', 'W']) R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W']) vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W']) vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W']) z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W']) vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W']) phi = numpy.require(phi, dtype=numpy.float64, requirements=['C', 'W']) dxvOdJaT = numpy.require(dxvOdJaT, dtype=numpy.float64, requirements=['C', 'W']) dOdJT = numpy.require(dOdJT, dtype=numpy.float64, requirements=['C', 'W']) Omegar = numpy.require(Omegar, dtype=numpy.float64, requirements=['C', 'W']) Omegaphi = numpy.require(Omegaphi, dtype=numpy.float64, requirements=['C', 'W']) Omegaz = numpy.require(Omegaz, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleTorus_JacFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(len(angler)), angler, anglephi, anglez, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), ctypes.c_double(dJ), R, vR, vT, z, vz, phi, dxvOdJaT, dOdJT, Omegar, Omegaphi, Omegaz, ctypes.byref(flag)) #Reset input arrays if f_cont[0]: angler = numpy.asfortranarray(angler) if f_cont[1]: anglephi = numpy.asfortranarray(anglephi) if f_cont[2]: anglez = numpy.asfortranarray(anglez) dxvOdJaT = numpy.reshape(dxvOdJaT, (len(angler), 6, 6), order='C') dxvOdJa = numpy.swapaxes(dxvOdJaT, 1, 2) return (R, vR, vT, z, vz, phi, dxvOdJa, dOdJT.reshape( (3, 3)).T, Omegar[0], Omegaphi[0], Omegaz[0], flag.value)
def actionAngleTorus_hessian_c(pot, jr, jphi, jz, tol=0.003, dJ=0.001): """ NAME: actionAngleTorus_hessian_c PURPOSE: compute dO/dJ on a single torus INPUT: pot - Potential object or list thereof jr - radial action (scalar) jphi - azimuthal action (scalar) jz - vertical action (scalar) tol= (0.003) goal for |dJ|/|J| along the torus dJ= (0.001) action difference when computing derivatives (Hessian or Jacobian) OUTPUT: (dO/dJ,Omegar,Omegaphi,Omegaz,Autofit error flag) Note: dO/dJ is *not* symmetrized here HISTORY: 2016-07-15 - Written - Bovy (UofT) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potfortorus=True) #Set up result dOdJT = numpy.empty(9) Omegar = numpy.empty(1) Omegaphi = numpy.empty(1) Omegaz = numpy.empty(1) flag = ctypes.c_int(0) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleTorus_HessFunc = _lib.actionAngleTorus_hessianFreqs actionAngleTorus_HessFunc.argtypes=\ [ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements dOdJT = numpy.require(dOdJT, dtype=numpy.float64, requirements=['C', 'W']) Omegar = numpy.require(Omegar, dtype=numpy.float64, requirements=['C', 'W']) Omegaphi = numpy.require(Omegaphi, dtype=numpy.float64, requirements=['C', 'W']) Omegaz = numpy.require(Omegaz, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleTorus_HessFunc(ctypes.c_double(jr), ctypes.c_double(jphi), ctypes.c_double(jz), ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(tol), ctypes.c_double(dJ), dOdJT, Omegar, Omegaphi, Omegaz, ctypes.byref(flag)) return (dOdJT.reshape( (3, 3)).T, Omegar[0], Omegaphi[0], Omegaz[0], flag.value)
def actionAngleFreqAngleStaeckel_c(pot, delta, R, vR, vT, z, vz, phi, u0=None, order=10): """ NAME: actionAngleFreqAngleStaeckel_c PURPOSE: Use C to calculate actions, frequencies, and angles using the Staeckel approximation INPUT: pot - Potential or list of such instances delta - focal length of prolate spheroidal coordinates R, vR, vT, z, vz, phi - coordinates (arrays) u0= (None) if set, u0 to use order= (10) order of Gauss-Legendre integration of the relevant integrals OUTPUT: (jr,jz,Omegar,Omegaphi,Omegaz,Angler,Anglephi,Anglez,err) jr,jz,Omegar,Omegaphi,Omegaz,Angler,Anglephi,Anglez : array, shape (len(R)) err - non-zero if error occured HISTORY: 2013-08-27 - Written - Bovy (IAS) """ if u0 is None: u0, dummy = bovy_coords.Rz_to_uv(R, z, delta=numpy.atleast_1d(delta)) #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potforactions=True) #Parse delta delta = numpy.atleast_1d(delta) ndelta = len(delta) #Set up result arrays jr = numpy.empty(len(R)) jz = numpy.empty(len(R)) Omegar = numpy.empty(len(R)) Omegaphi = numpy.empty(len(R)) Omegaz = numpy.empty(len(R)) Angler = numpy.empty(len(R)) Anglephi = numpy.empty(len(R)) Anglez = numpy.empty(len(R)) err = ctypes.c_int(0) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleStaeckel_actionsFunc = _lib.actionAngleStaeckel_actionsFreqsAngles actionAngleStaeckel_actionsFunc.argtypes = [ ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int) ] #Array requirements, first store old order f_cont = [ R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'], vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'], vz.flags['F_CONTIGUOUS'], u0.flags['F_CONTIGUOUS'], delta.flags['F_CONTIGUOUS'] ] R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W']) vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W']) vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W']) z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W']) vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W']) u0 = numpy.require(u0, dtype=numpy.float64, requirements=['C', 'W']) delta = numpy.require(delta, dtype=numpy.float64, requirements=['C', 'W']) jr = numpy.require(jr, dtype=numpy.float64, requirements=['C', 'W']) jz = numpy.require(jz, dtype=numpy.float64, requirements=['C', 'W']) Omegar = numpy.require(Omegar, dtype=numpy.float64, requirements=['C', 'W']) Omegaphi = numpy.require(Omegaphi, dtype=numpy.float64, requirements=['C', 'W']) Omegaz = numpy.require(Omegaz, dtype=numpy.float64, requirements=['C', 'W']) Angler = numpy.require(Angler, dtype=numpy.float64, requirements=['C', 'W']) Anglephi = numpy.require(Anglephi, dtype=numpy.float64, requirements=['C', 'W']) Anglez = numpy.require(Anglez, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleStaeckel_actionsFunc(len(R), R, vR, vT, z, vz, u0, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_int(ndelta), delta, ctypes.c_int(order), jr, jz, Omegar, Omegaphi, Omegaz, Angler, Anglephi, Anglez, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R = numpy.asfortranarray(R) if f_cont[1]: vR = numpy.asfortranarray(vR) if f_cont[2]: vT = numpy.asfortranarray(vT) if f_cont[3]: z = numpy.asfortranarray(z) if f_cont[4]: vz = numpy.asfortranarray(vz) if f_cont[5]: u0 = numpy.asfortranarray(u0) if f_cont[6]: delta = numpy.asfortranarray(delta) badAngle = Anglephi != 9999.99 Anglephi[badAngle] = (Anglephi[badAngle] + phi[badAngle] % (2. * numpy.pi)) % (2. * numpy.pi) Anglephi[Anglephi < 0.] += 2. * numpy.pi return (jr, jz, Omegar, Omegaphi, Omegaz, Angler, Anglephi, Anglez, err.value)
def actionAngleStaeckel_calcu0(E,Lz,pot,delta): """ NAME: actionAngleStaeckel_calcu0 PURPOSE: Use C to calculate u0 in the Staeckel approximation INPUT: E, Lz - energy and angular momentum pot - Potential or list of such instances delta - focal length of prolate spheroidal coordinates OUTPUT: (u0,err) u0 : array, shape (len(E)) err - non-zero if error occured HISTORY: 2012-12-03 - Written - Bovy (IAS) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potforactions=True) #Set up result arrays u0= numpy.empty(len(E)) err= ctypes.c_int(0) #Parse delta delta= numpy.atleast_1d(delta) ndelta= len(delta) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleStaeckel_actionsFunc= _lib.calcu0 actionAngleStaeckel_actionsFunc.argtypes= [ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [E.flags['F_CONTIGUOUS'], Lz.flags['F_CONTIGUOUS'], delta.flags['F_CONTIGUOUS']] E= numpy.require(E,dtype=numpy.float64,requirements=['C','W']) Lz= numpy.require(Lz,dtype=numpy.float64,requirements=['C','W']) delta= numpy.require(delta,dtype=numpy.float64,requirements=['C','W']) u0= numpy.require(u0,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleStaeckel_actionsFunc(len(E), E, Lz, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_int(ndelta), delta, u0, ctypes.byref(err)) #Reset input arrays if f_cont[0]: E= numpy.asfortranarray(E) if f_cont[1]: Lz= numpy.asfortranarray(Lz) if f_cont[2]: delta= numpy.asfortranarray(delta) return (u0,err.value)
def actionAngleUminUmaxVminStaeckel_c(pot, delta, R, vR, vT, z, vz, u0=None): """ NAME: actionAngleUminUmaxVminStaeckel_c PURPOSE: Use C to calculate umin, umax, and vmin using the Staeckel approximation INPUT: pot - Potential or list of such instances delta - focal length of prolate spheroidal coordinates R, vR, vT, z, vz - coordinates (arrays) OUTPUT: (umin,umax,vmin,err) umin,umax,vmin : array, shape (len(R)) err - non-zero if error occured HISTORY: 2017-12-12 - Written - Bovy (UofT) """ if u0 is None: u0, dummy = bovy_coords.Rz_to_uv(R, z, delta=numpy.atleast_1d(delta)) #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args = _parse_pot(pot, potforactions=True) #Parse delta delta = numpy.atleast_1d(delta) ndelta = len(delta) #Set up result arrays umin = numpy.empty(len(R)) umax = numpy.empty(len(R)) vmin = numpy.empty(len(R)) err = ctypes.c_int(0) #Set up the C code ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE') actionAngleStaeckel_actionsFunc = _lib.actionAngleStaeckel_uminUmaxVmin actionAngleStaeckel_actionsFunc.argtypes = [ ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int) ] #Array requirements, first store old order f_cont = [ R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'], vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'], vz.flags['F_CONTIGUOUS'], u0.flags['F_CONTIGUOUS'], delta.flags['F_CONTIGUOUS'] ] R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W']) vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W']) vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W']) z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W']) vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W']) u0 = numpy.require(u0, dtype=numpy.float64, requirements=['C', 'W']) delta = numpy.require(delta, dtype=numpy.float64, requirements=['C', 'W']) umin = numpy.require(umin, dtype=numpy.float64, requirements=['C', 'W']) umax = numpy.require(umax, dtype=numpy.float64, requirements=['C', 'W']) vmin = numpy.require(vmin, dtype=numpy.float64, requirements=['C', 'W']) #Run the C code actionAngleStaeckel_actionsFunc(len(R), R, vR, vT, z, vz, u0, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_int(ndelta), delta, umin, umax, vmin, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R = numpy.asfortranarray(R) if f_cont[1]: vR = numpy.asfortranarray(vR) if f_cont[2]: vT = numpy.asfortranarray(vT) if f_cont[3]: z = numpy.asfortranarray(z) if f_cont[4]: vz = numpy.asfortranarray(vz) if f_cont[5]: u0 = numpy.asfortranarray(u0) if f_cont[6]: delta = numpy.asfortranarray(delta) return (umin, umax, vmin, err.value)
def actionAngleUminUmaxVminStaeckel_c(pot,delta,R,vR,vT,z,vz,u0=None): """ NAME: actionAngleUminUmaxVminStaeckel_c PURPOSE: Use C to calculate umin, umax, and vmin using the Staeckel approximation INPUT: pot - Potential or list of such instances delta - focal length of prolate spheroidal coordinates R, vR, vT, z, vz - coordinates (arrays) OUTPUT: (umin,umax,vmin,err) umin,umax,vmin : array, shape (len(R)) err - non-zero if error occured HISTORY: 2017-12-12 - Written - Bovy (UofT) """ if u0 is None: u0, dummy= bovy_coords.Rz_to_uv(R,z,delta=numpy.atleast_1d(delta)) #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potforactions=True) #Parse delta delta= numpy.atleast_1d(delta) ndelta= len(delta) #Set up result arrays umin= numpy.empty(len(R)) umax= numpy.empty(len(R)) vmin= numpy.empty(len(R)) err= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleStaeckel_actionsFunc= _lib.actionAngleStaeckel_uminUmaxVmin actionAngleStaeckel_actionsFunc.argtypes= [ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'], vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'], vz.flags['F_CONTIGUOUS'], u0.flags['F_CONTIGUOUS'], delta.flags['F_CONTIGUOUS']] R= numpy.require(R,dtype=numpy.float64,requirements=['C','W']) vR= numpy.require(vR,dtype=numpy.float64,requirements=['C','W']) vT= numpy.require(vT,dtype=numpy.float64,requirements=['C','W']) z= numpy.require(z,dtype=numpy.float64,requirements=['C','W']) vz= numpy.require(vz,dtype=numpy.float64,requirements=['C','W']) u0= numpy.require(u0,dtype=numpy.float64,requirements=['C','W']) delta= numpy.require(delta,dtype=numpy.float64,requirements=['C','W']) umin= numpy.require(umin,dtype=numpy.float64,requirements=['C','W']) umax= numpy.require(umax,dtype=numpy.float64,requirements=['C','W']) vmin= numpy.require(vmin,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleStaeckel_actionsFunc(len(R), R, vR, vT, z, vz, u0, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_int(ndelta), delta, umin, umax, vmin, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R= numpy.asfortranarray(R) if f_cont[1]: vR= numpy.asfortranarray(vR) if f_cont[2]: vT= numpy.asfortranarray(vT) if f_cont[3]: z= numpy.asfortranarray(z) if f_cont[4]: vz= numpy.asfortranarray(vz) if f_cont[5]: u0= numpy.asfortranarray(u0) if f_cont[6]: delta= numpy.asfortranarray(delta) return (umin,umax,vmin,err.value)
def actionAngleAdiabatic_c(pot,gamma,R,vR,vT,z,vz): """ NAME: actionAngleAdiabatic_c PURPOSE: Use C to calculate actions using the adiabatic approximation INPUT: pot - Potential or list of such instances gamma - as in Lz -> Lz+\gamma * J_z R, vR, vT, z, vz - coordinates (arrays) OUTPUT: (jr,jz,err) jr,jz : array, shape (len(R)) err - non-zero if error occured HISTORY: 2012-12-10 - Written - Bovy (IAS) """ #Parse the potential from galpy.orbit.integrateFullOrbit import _parse_pot npot, pot_type, pot_args= _parse_pot(pot,potforactions=True) #Set up result arrays jr= numpy.empty(len(R)) jz= numpy.empty(len(R)) err= ctypes.c_int(0) #Set up the C code ndarrayFlags= ('C_CONTIGUOUS','WRITEABLE') actionAngleAdiabatic_actionsFunc= _lib.actionAngleAdiabatic_actions actionAngleAdiabatic_actionsFunc.argtypes= [ctypes.c_int, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_int, ndpointer(dtype=numpy.int32,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.c_double, ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ndpointer(dtype=numpy.float64,flags=ndarrayFlags), ctypes.POINTER(ctypes.c_int)] #Array requirements, first store old order f_cont= [R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'], vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'], vz.flags['F_CONTIGUOUS']] R= numpy.require(R,dtype=numpy.float64,requirements=['C','W']) vR= numpy.require(vR,dtype=numpy.float64,requirements=['C','W']) vT= numpy.require(vT,dtype=numpy.float64,requirements=['C','W']) z= numpy.require(z,dtype=numpy.float64,requirements=['C','W']) vz= numpy.require(vz,dtype=numpy.float64,requirements=['C','W']) jr= numpy.require(jr,dtype=numpy.float64,requirements=['C','W']) jz= numpy.require(jz,dtype=numpy.float64,requirements=['C','W']) #Run the C code actionAngleAdiabatic_actionsFunc(len(R), R, vR, vT, z, vz, ctypes.c_int(npot), pot_type, pot_args, ctypes.c_double(gamma), jr, jz, ctypes.byref(err)) #Reset input arrays if f_cont[0]: R= numpy.asfortranarray(R) if f_cont[1]: vR= numpy.asfortranarray(vR) if f_cont[2]: vT= numpy.asfortranarray(vT) if f_cont[3]: z= numpy.asfortranarray(z) if f_cont[4]: vz= numpy.asfortranarray(vz) return (jr,jz,err.value)