0

I have this code that have three function called ( Bx,Bhalo, Bdisk)these three the functions only accept arrays (e.g. shape (1000)):

import numpy as np
import logging
import warnings
import gmf
signum = lambda x: (x < 0.) * -1. + (x >= 0) * 1.
pi = np.pi
#Class with analytical functions that describe the GMF according to the model of JF12  
class GMF(object):     
    def __init__(self): # self:is automatically set to reference the newly created object that needs to be initialized      
    self.Rsun   = -8.5          # position of the sun along the x axis  in kpc  
############################################################################
    # Disk Parameters
############################################################################
    self.bring, self.bring_unc  = 0.1,0.1   # floats, field strength in ring at 3 kpc < r < 5 kpc
    self.hdisk, self.hdisk_unc  = 0.4, 0.03 # float, disk/halo transition height 
    self.wdisk, self.wdisk_unc  = 0.27,0.08 #  floats, transition width
    self.b      = np.array([0.1,3.,-0.9,-0.8,-2.0,-4.2,0.,2.7]) # (8,1)-dim np.arrays, field strength of spiral arms at 5 kpc
    self.b_unc  = np.array([1.8,0.6,0.8,0.3,0.1,0.5,1.8,1.8]) # uncertainty 
    self.rx     = np.array([5.1,6.3,7.1,8.3,9.8,11.4,12.7,15.5])#  (8,1)-dim np.array,dividing lines of spiral lines coordinates of neg. x-axes that intersect with arm
    self.idisk  = 11.5 * pi/180.  #  float, spiral arms pitch angle
#############################################################################
    # Halo Parameters
#############################################################################
    self.Bn, self.Bn_unc    = 1.4,0.1   #  floats, field strength northern halo
    self.Bs, self.Bs_unc    = -1.1,0.1  #  floats, field strength southern halo
    self.rn, self.rn_unc    = 9.22,0.08 # floats, transition radius south, lower limit 
    self.rs, self.rs_unc    = 16.7,0.   # transition radius south, lower limit
    self.whalo, self.whalo_unc  = 0.2,0.12  # floats, transition width
    self.z0, self.z0_unc        = 5.3, 1.6  # floats, vertical scale height
##############################################################################
    # Out of plaxe or "X" component Parameters
##############################################################################
    self.BX0, self.BX_unc   = 4.6,0.3   # floats,  field strength at origin
    self.ThetaX0, self.ThetaX0_unc  = 49. * pi/180., pi/180. # elev. angle at z = 0, r > rXc
    self.rXc, self.rXc_unc  = 4.8, 0.2  # floats, radius where thetaX = thetaX0
    self.rX, self.rX_unc    = 2.9, 0.1  # floats, exponential scale length
    # striated field
    self.gamma, self.gamma_unc  = 2.92,0.14 # striation and/or rel. elec. number dens. rescaling
    return  
##################################################################################
##################################################################################
    # Transition function given by logistic function eq.5
##################################################################################
    def L(self,z,h,w): 

    if np.isscalar(z):
        z = np.array([z]) # scalar or numpy array with positions (height above disk, z; distance from center, r)
    ones = np.ones(z.shape[0])
    return 1./(ones + np.exp(-2. *(np.abs(z)- h)/w))    
####################################################################################
    # return distance from center for angle phi of logarithmic spiral
    # r(phi) = rx * exp(b * phi) as np.array
####################################################################################
    def r_log_spiral(self,phi):

    if np.isscalar(phi): #Returns True if the type of num is a scalar type.
        phi = np.array([phi])
    ones = np.ones(phi.shape[0])
    # self.rx.shape = 8
    # phi.shape = p
    # then result is given as (8,p)-dim array, each row stands for one rx
    # vstack : Take a sequence of arrays and stack them vertically to make a single array
    # tensordot(a, b, axes=2):Compute tensor dot product along specified axes for arrays >=1D.
    result = np.tensordot(self.rx , np.exp((phi - 3.*pi*ones) / np.tan(pi/2. - self.idisk)),axes = 0)
    result = np.vstack((result, np.tensordot(self.rx , np.exp((phi - pi*ones) / np.tan(pi/2. - self.idisk)),axes = 0) ))
    result = np.vstack((result, np.tensordot(self.rx , np.exp((phi + pi*ones) / np.tan(pi/2. - self.idisk)),axes = 0) ))
    return np.vstack((result, np.tensordot(self.rx , np.exp((phi + 3.*pi*ones) / np.tan(pi/2. - self.idisk)),axes = 0) ))    
#############################################################################################
    # Disk component in galactocentric cylindrical coordinates (r,phi,z)
#############################################################################################
    def Bdisk(self,r,phi,z):
    # Bdisk is purely azimuthal (toroidal) with the field strength b_ring
    """ 
    r:  N-dim np.array, distance from origin in GC cylindrical coordinates, is in kpc
    z:  N-dim np.array, height in kpc in GC cylindrical coordinates
    phi:N-dim np.array, polar angle in GC cylindircal coordinates, in radian    
    Bdisk:  (3,N)-dim np.array with (r,phi,z) components of disk field for each coordinate tuple
    Bdisk|: N-dim np.array, absolute value of Bdisk for each coordinate tuple
    """
    if (not r.shape[0] == phi.shape[0]) and (not z.shape[0] == phi.shape[0]):
        warnings.warn("List do not have equal shape! returning -1", RuntimeWarning)
        return -1
    # Return a new array of given shape and type, filled with zeros.
    Bdisk = np.zeros((3,r.shape[0]))    # Bdisk vector in r, phi, z   
    ones        = np.ones(r.shape[0])
    r_center    = (r >= 3.) & (r < 5.1)
    r_disk      = (r >= 5.1) & (r <= 20.)
    Bdisk[1,r_center] = self.bring

    # Determine in which arm we are
    # this is done for each coordinate individually
    if np.sum(r_disk):
        rls = self.r_log_spiral(phi[r_disk])

        rls = np.abs(rls - r[r_disk])
        arms = np.argmin(rls, axis = 0) % 8
        # The magnetic spiral defined at r=5 kpc and fulls off as 1/r ,the field direction is given by:
        Bdisk[0,r_disk] = np.sin(self.idisk)* self.b[arms] * (5. / r[r_disk]) 
        Bdisk[1,r_disk] = np.cos(self.idisk)* self.b[arms] * (5. / r[r_disk])

    Bdisk  *= (ones - self.L(z,self.hdisk,self.wdisk)) # multiplied by (1-L) 
    return Bdisk, np.sqrt(np.sum(Bdisk**2.,axis = 0)) # the Bdisk, the normalization 
    # axis=0 : sum over index 0(row)
    # axis=1 : sum over index 1(columns)    
##############################################################################################
    # Halo component 
###############################################################################################
    def Bhalo(self,r,z):    
    # Bhalo is purely azimuthal (toroidal), i.e. has only a phi component
    if (not r.shape[0] == z.shape[0]):
        warnings.warn("List do not have equal shape! returning -1", RuntimeWarning)
        return -1

    Bhalo = np.zeros((3,r.shape[0]))    # Bhalo vector in r, phi, z  rows: r, phi and z component
    ones  = np.ones(r.shape[0])
    m = ( z != 0. )
    # SEE equation 6.
    Bhalo[1,m] = np.exp(-np.abs(z[m])/self.z0) * self.L(z[m], self.hdisk, self.wdisk) * \
            ( self.Bn * (ones[m] - self.L(r[m], self.rn, self.whalo)) * (z[m] > 0.) \
            + self.Bs * (ones[m] - self.L(r[m], self.rs, self.whalo)) * (z[m] < 0.) )
    return Bhalo , np.sqrt(np.sum(Bhalo**2.,axis = 0))    
##############################################################################################
    # BX component (OUT OF THE PLANE) 
###############################################################################################
    def BX(self,r,z):   
    #BX is purely  ASS  and poloidal, i.e. phi component = 0    
    if (not r.shape[0] == z.shape[0]):
        warnings.warn("List do not have equal shape! returning -1", RuntimeWarning)
        return -1

    BX= np.zeros((3,r.shape[0]))    # BX vector in r, phi, z  rows: r, phi and z component
    m = np.sqrt(r**2. + z**2.) >= 1.

    bx = lambda r_p: self.BX0 * np.exp(-r_p / self.rX) # eq.7
    thetaX = lambda r,z,r_p: np.arctan(np.abs(z)/(r - r_p)) # eq.10

    r_p = r[m] *self.rXc/(self.rXc + np.abs(z[m] ) / np.tan(self.ThetaX0)) # eq. 9

    m_r_b = r_p > self.rXc  # region with constant elevation angle
    m_r_l = r_p <= self.rXc # region with varying elevation angle

    theta = np.zeros(z[m].shape[0])
    b     = np.zeros(z[m].shape[0])

    r_p0 = (r[m])[m_r_b]  - np.abs( (z[m])[m_r_b] ) / np.tan(self.ThetaX0) # eq.8
    b[m_r_b] = bx(r_p0) * r_p0/ (r[m])[m_r_b] # the field strength in the constant elevation angle (b_x(r_p)r_p/r)
    theta[m_r_b] = self.ThetaX0 * np.ones(theta.shape[0])[m_r_b]

    b[m_r_l] = bx(r_p[m_r_l]) * (r_p[m_r_l]/(r[m])[m_r_l] )**2. # the field strength with varying elevation angle (b_x(r_p)(r_p/r)**2)
    theta[m_r_l] = thetaX((r[m])[m_r_l] ,(z[m])[m_r_l] ,r_p[m_r_l])

    mz = (z[m] == 0.)
    theta[mz]   = np.pi/2.

    BX[0,m] = b * (np.cos(theta) * (z[m] >= 0) + np.cos(pi*np.ones(theta.shape[0]) - theta) * (z[m] < 0))
    BX[2,m] = b * (np.sin(theta) * (z[m] >= 0) + np.sin(pi*np.ones(theta.shape[0]) - theta) * (z[m] < 0))
    return BX, np.sqrt(np.sum(BX**2.,axis=0))   

now I want to add these three function together; Btotal= Bx+ Bhalo+ Bdisk,these function is a vector field in cylindrical coordinate (r,theta,z), I convert from cylindrical to Cartesian(x,y,z) and I defined a function called vectors to calculate new two vector called n1,n2 (to get two perpendicular vector to Btotal).to calculate the diffusion of particle using stochastic differential equations for many particles(~10000) in the code below, I am trying to call the three functions (form above code) by defined r, theta, z to use it the diffusion equation and plot the result i.e:
in the for loop I have to get one position in shape (3,1)[I put the range from (0,1)] in (r,theta,z) then convert the value to Cartesian(x,y,z) to use it to find n1,n2,d eltaX,deltaY,deltaZ, respectively! :

import scipy as sp
import numpy as np
import numpy.random as npr
from numpy.lib.scimath import logn # to logartnim scale
import math as math
from random import seed,random, choice
from pylab import *
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import gmf 
###########################################################
gmfm = gmf.GMF()
#############################################################
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_xlabel(r'$\ X$',size=16)
ax.set_ylabel(r'$\ Y$',size=16)
ax.set_zlabel(r'$\ Z$',size=16)
ax.set_title(' Diffusion Particles in GMF in 3D ')
#############################################################
def vectors(b): 
    b = b/np.sqrt(np.sum(b**2.,axis=0))
    b = b/np.linalg.norm(b)     
    z = np.array([0.,0.,1.])
    n1 = np.cross(z,b,axis=0)
    n1 = n1/np.linalg.norm(n1) 
    n2 = np.cross(b,n1,axis=0)
    n2 = n2/np.linalg.norm(n2) 
    return n1,n2
#############################################################
def CylindricalToCartesian(r,theta,z):
    x= r*np.cos(theta)
    y= r*np.sin(theta)
    z= z
    return np.array([x, y, z])  

############################################################
T=1 # 100 
N=10000
dt=float(T)/N 
D= 1 # 2
DII=10
n= 1000
seed(3)
finalpositions=[]
###############################################################
for number in range(0,1):

  finalpositions.append([])  
  r=[]
  theta=[]
  z=[]
  r.append(0)
  theta.append(0)
  z.append(0)

  x=[]
  y=[]

  x.append(8.5)
  y.append(0)


  for i in range(n): 

    Bdisk, Babs_d = gmfm.Bdisk(r,theta,z)
    Bhalo, Babs_h = gmfm.Bhalo(r,z)
    BX, Babs_x = gmfm.BX(r,z)
    Btotal = Bdisk + Bhalo + BX 


    FieldInXYZ = CylindricalToCartesian(r[-1],theta[-1],z[-1])

    FieldInXYZ =Btotal(x[-1],y[-1],z[-1])
    localB = Btotal(x[-1],y[-1],z[-1])
    print 'FieldInXYZ:', FieldInXYZ       
    #print 'localB:',localB

    n1, n2 = vectors(localB)        
    s = np.random.normal(0, 1, 3)


  finalpositions[-1].append(x)
  finalpositions[-1].append(y)
  finalpositions[-1].append(z)


allxes = [] 
allyes = []
allzes = []


for p in finalpositions:
  allxes.append(p[0][-1])
  allyes.append(p[1][-1]) 
  allzes.append(p[1][-1])

plt.plot(allxes, allyes,allzes, 'o') 
plt.show()

but I am getting an error:

AttributeError                            Traceback (most recent call last)
/usr/lib/python2.7/dist-packages/IPython/utils/py3compat.pyc in execfile(fname, *where)
    202             else:
    203                 filename = fname
--> 204             __builtin__.execfile(filename, *where)

/home/January.py in <module>()
     71   for i in range(n):
     72
---> 73     Bdisk, Babs_d = gmfm.Bdisk(r,theta,z)
     74     Bhalo, Babs_h = gmfm.Bhalo(r,z)
     75     BX, Babs_x = gmfm.BX(r,z)

/home/gmf.py in Bdisk(self, r, phi, z)
     80         Bdisk|: N-dim np.array, absolute value of Bdisk for each coordinate tuple
     81         """
---> 82         if (not r.shape[0] == phi.shape[0]) and (not z.shape[0] == phi.shape[0]):
     83             warnings.warn("List do not have equal shape! returning -1", RuntimeWarning)
     84             return -1

AttributeError: 'list' object has no attribute 'shape'

I don't know what I did wrong?! Any help would be appreciate

12
  • 2
    Please provide the full traceback. It looks like you're using a list where a numpy.ndarray is expected instead. Commented Jan 4, 2017 at 13:36
  • 2
    Wow, is all that code needed to reproduce the issue? Please try to provide an minimal reproducible example. Commented Jan 4, 2017 at 13:41
  • @a_guest you mean in the function Cylinricalto cartesian? Commented Jan 4, 2017 at 13:42
  • @das-g the first code is correct I posted it Just to call the functions, the second code I am stuck in the loop ( when call the variable r,theta,z ) and converted it to Cartesian? Commented Jan 4, 2017 at 13:47
  • 2
    can you provide the line no. at which this is happening. Full traceback provide line number too i guess Commented Jan 4, 2017 at 13:49

1 Answer 1

1

The traceback tells you exactly where the problem lives: you are using r.shape where type(r) is list while it should be numpy.ndarray instead. Tracing the problem back reveals that you declare r = [] and then you pass r to gmfm.Bdisk.

Instead you could do:

Bdisk, Babs_d = gmfm.Bdisk(numpy.ndarray(r),theta,z)

(line number 73); (If you have other lists that you treat as numpy.ndarrays then you need to convert them accordingly of course.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.