Example #1
0
 def jinc(self, x):
     # I'm jury-rigging / hard coding this to work
     # to test it
     y = numpy.zeros(len(x))
     if (x[0] == 0.0):
         y[0] = 0.5
         y[1:] = j1(x[1:]) / (x[1:])
     else:
         return j1(x) / x
Example #2
0
def obsc_airy(x, h, w, q):
    #Search for 0 in array - if not present, pass
    try:
        #loc = n.argwhere(x==0.)[0]
        #x[loc[0],loc[1]] = 1.E-30 #Fix for 0. in array - using 1.E-30 seems to give good result for Airy function
        loc = n.argwhere(x==0.)
        x[loc] = 1.E-30
    except IndexError:
        pass
    return h*((2*j1(n.sin(x)/w) - q*j1(q*(n.sin(x)/w)))/((n.sin(x)/w)*(1 - q**2)))**2
Example #3
0
def cutoffHE1(b):
    a = rho * b
    i = ivp(1, u1*a) / (u1*a * i1(u1*a))

    X = (1 / (u1*a)**2 + 1 / (u2*a)**2)

    P = j1(u2*a) * y1(u2*b) - y1(u2*a) * j1(u2*b)
    Ps = (jvp(1, u2*a) * y1(u2*b) - yvp(1, u2*a) * j1(u2*b)) / (u2 * a)

    return (i * P + Ps) * (n12 * i * P + n22 * Ps) - n32 * X * X * P * P
Example #4
0
 def wave(self, **kw):
     amplitude, r, a, w, f = (
             kw.get(key, Human.aawf[key]) for key in (
                 'amplitude', 'radius', 'aperture', 'wavelength', 'focal'))
     u = (pi*r*a)/(w*f)
     if isinstance(r,float):
         return amplitude*(1.0 if u == 0.0 else 2.0*j1(u)/u)
     else:
         u[u==0.0] = 1e-32
         return amplitude*2.0*j1(u)/u
Example #5
0
def wijCoefficients(n, x, y, rad1, rad2, theta, ellipticity):
    
    wid, xcen, ycen = n, (n+1)/2, (n+1)/2
    
    dx, dy = x - xcen, y - ycen
    
    if n%2:
        
        dx, dy = dx + 1, dy + 1
        
    ftWij = numpy.zeros([wid, wid], dtype=complex)

    scale = 1.0 - ellipticity
        
    for iy in range(wid):

        ky = float(iy - ycen)/wid

        for ix in range(wid):

            kx = float(ix - xcen)/wid
            
# rotate and rescale
            
            cosT, sinT = numpy.cos(theta), numpy.sin(theta)
            
            kxr, kyr = kx*cosT + ky*sinT, scale*(-kx*sinT + ky*cosT)
            
            k = numpy.sqrt(kxr**2 + kyr**2)

# compute the airy terms, and apply shift theorem

            if k != 0.0:

                airy1 = rad1*special.j1(2.0*numpy.pi*rad1*k)/k
                
                airy2 = rad2*special.j1(2.0*numpy.pi*rad2*k)/k
                
            else:

                airy1, airy2 = numpy.pi*rad1**2, numpy.pi*rad2**2
                
            airy = airy2 - airy1
            
            phase = numpy.exp(-1.0j*2.0*numpy.pi*(dx*kxr + dy*kyr))
            
    ftWij[iy,ix] = phase*scale*airy

    ftWijShift = numpy.fft.fftshift(ftWij)
    
    wijShift = numpy.fft.ifft2(ftWijShift)
    
    wij = numpy.fft.fftshift(wijShift)
    
    return wij.real
Example #6
0
 def rootAiryIntensity(self, myxaxis, epsilon=0.0, showplot=False):
     """
     This function computes 2*J1(x)/x, which can be squared to get an Airy disk.
     myxaxis: the x-axis values to use
     epsilon: radius of central hole in units of the dish diameter
     Migrated from AnalysisUtils.py (revision 1.2204, 2015/02/18)
     """
     if (epsilon > 0):
         a = (2*spspec.j1(myxaxis)/myxaxis - \
              epsilon**2*2*spspec.j1(myxaxis*epsilon)/(epsilon*myxaxis)) / (1-epsilon**2)
     else:
         a = 2*spspec.j1(myxaxis)/myxaxis  # simpler formula for epsilon=0
     return(a)
def funcCn(root, b):
    """
    First term in the theta function
    root = root from the zeta, Bi equation
    b = shape factor where 2 sphere, 1 cylinder, 0 slab
    """
    if b == 2:
        Cn = 4*(np.sin(root)-root*np.cos(root)) / (2*root-np.sin(2*root))
    elif b == 1:
        Cn = (2/root) * (sp.j1(root) / (sp.j0(root)**2 + sp.j1(root)**2))
    elif b == 0:
        Cn = (4*np.sin(root)) / (2*root + np.sin(2*root))
    return Cn
Example #8
0
 def jinc(self, x):
     # a 'jinc' function
     if (len(x) == 1):
         if (x == 0.0):
             return 0.5
         else:
             return j1(x)/x
     else:
         y = numpy.zeros(len(x))
         index_0 = numpy.where(x == 0.0)
         index_not_0
         y[index_0] = 0.5
         y[index_not_0] = j1(x[index_not_0])/x[index_not_0]
Example #9
0
def j1_x_over_x(x,EPS=1E-8):
    x = numpy.asarray(x)
    if x.shape==():
        if abs(x)<EPS:
            return 1./3.
        else:
            return j1(x)/x
    else:
        x = numpy.asarray(x)
        i = numpy.where(abs(x)<EPS)
        x[i] = 1.
        ret = j1(x)/x
        ret[i] = 1./3.
        return ret
Example #10
0
    def SNRcalc(self, pulsar, pop):
        """Calculate the S/N ratio of a given pulsar in the survey"""
        # if not in region, S/N = 0

        # if we have a list of pointings, use this bit of code
        # haven't tested yet, but presumably a lot slower
        # (loops over the list of pointings....)
 

        # otherwise check if pulsar is in entire region
        if self.inRegion(pulsar):
            # If pointing list is provided, check how close nearest 
            # pointing is
            if self.pointingslist is not None:
                # convert offset from degree to arcmin
                offset = self.inPointing(pulsar) * 60.0

            else:
                # calculate offset as a random offset within FWHM/2
                offset = self.fwhm * math.sqrt(random.random()) / 2.0
        else:
            return -2

        # Get degfac depending on self.gainpat
        if self.gainpat == 'airy':
            conv    = math.pi/(60*180.)         # Conversion arcmins -> radians
            eff_diam = 3.0e8/(self.freq*self.fwhm*conv*1.0e6)  # Also MHz -> Hz
            a       = eff_diam/2.               # Effective radius of telescope
            lamda   = 3.0e8/(self.freq*1.0e6)   # Obs. wavelength
            kasin   = (2*math.pi*a/lamda)*np.sin(offset*conv)
            degfac = 4*(j1(kasin)/kasin)**2
        else:
            #### NOTE! HERE I WANT TO CHECK UNITS OF FWHM (ARCMIN???)
            degfac = math.exp(-2.7726 * offset * offset / (self.fwhm *self.fwhm))

        # Dunc's code here uses a ^-2.6 to convert frequencies
        # don't think I need to do this - I'm using the frequency in call
        Ttot = self.tsys + self.tskypy(pulsar)

        # calc dispersion smearing across single channel
        tdm = self._dmsmear(pulsar)

        # calculate bhat et al scattering time (inherited from GalacticOps)
        # in units of ms
        tscat = go.scatter_bhat(pulsar.dm, pulsar.scindex, self.freq)

        # Calculate the effective width
        weff_ms = math.sqrt(pulsar.width_ms()**2 + self.tsamp**2 + tdm**2 + tscat**2)

        # calculate duty cycle (period is in ms)
        delt = weff_ms / pulsar.period
        #print weff_ms, pulsar.period

        # if pulse is smeared out, return -1.0
        if delt > 1.0:
            #print weff_ms, tscat, pulsar.dm, pulsar.gl, pulsar.gb, pulsar.dtrue
            return -1
        else:
            return self._SNfac(pulsar, pop.ref_freq, degfac, Ttot) \
                                  * math.sqrt((1.0 -delt)/delt)
Example #11
0
def vis_disk(u, v, wavels, p):
	''' Calculate the visibilities observed by an array on a binary star
	----------------------------------------------------------------
	p: 3-component vector (+2 optional), the binary "parameters":
	- p[0] = angular size of star (mas)
	- p[1] = linear limb-darkening coefficient - not done yet
	- p[2] = quadratic limb-darkening coefficient - not done yet

	- u,v: baseline coordinates (meters)
	- wavel: wavelength (meters)
	---------------------------------------------------------------- '''

	p = np.array(p)
	# relative locations
	th1 = mas2rad(p[0])
	if np.size(p)>1:
		mu = p[1]
	else:
		mu = 0.
	# baselines into number of wavelength
	pref = 1./((1.-mu)/2. + mu/3.)
	eps = 1.e-20
	x = np.sqrt(u*u+v*v)/wavels+eps

	v1 = pref*((1.-mu)*j1(np.pi*th1*x)/(np.pi*th1*x) + mu*np.sqrt(np.pi/2.)*jv(1.5,np.pi*th1*x)/((np.pi*th1*x)**1.5))

	return np.abs(v1)
Example #12
0
def makeAiryArr(maxRad,dd):
    
    from numpy import pi,sqrt,arctan2,zeros,zeros_like
    from scipy import where
    from scipy.special import j1
    
    pixCtr = maxRad / dd

    ##make position/radius Arrays
    npix = int(2.*maxRad/dd + 1)
    xArr = zeros((npix,npix))
    yArr = zeros_like(xArr)
    
    for x in range(npix):
        xArr[x,:] = -maxRad + x*dd
        yArr[:,x] = -maxRad + x*dd
        
    radArr = sqrt(xArr**2 + yArr**2)
    azArr = arctan2(yArr,xArr)
        
    ##remove zero
    radArr = where(radArr == 0.,1.e-12,radArr)
        
        ###radius is the angle in units of lambda/d

    ##Make Airy function
    bessArr = j1(pi*radArr)
    airyArr = ((2./pi) * (bessArr / radArr))**2
    
    return(xArr,yArr,airyArr)
Example #13
0
def airyconv(xArr,yArr,airyArr,wid,radList):

    from scipy.special import j1,j0
    from numpy import pi,sum,ones,arange
    from scipy import where
    from scipy.signal import convolve2d
    from beam import beam_azsm

    nRad=len(radList)
    dd=radList[2]-radList[1]
    #print 'wid:',wid
    #print 'dd:',dd
    radListTot=arange(0,300,0.01)
    radListTot=where(radListTot == 0.,1.e-12,radListTot)
    airyList= ((2./pi) * (j1(pi*radListTot)/radListTot))**2
    
    airyTot=sum(airyList*2.*pi*radListTot*dd)
    #print 'airyTot:',airyTot
    npKer=wid / dd
    kernel=ones((npKer,npKer))
    #kernel = kernel/size(kernel)
    kernel = kernel * (dd**2.) / airyTot

    convSame=convolve2d(airyArr,kernel,mode="same")    
    convAz=beam_azsm(xArr,yArr,convSame,radList,nsamp=360)

    return(convAz)
Example #14
0
 def calc_ff(self, Q_VALS):	
     for q in Q_VALS:      
         temp = np.sin(self.theta)*np.cos(self.phi)+ np.sin(self.theta)*np.sin(self.phi)
         if temp < -1:
                 a = np.floor(temp)
                 temp = temp - a
         if temp > 1:
                 a = np.ceil(temp)
                 temp = temp - a
         self.alpha = np.arccos(temp)
 
         h,r,v,c, a= self.h,self.r,self.V,self.rho, self.alpha
                 
         inside = q*r*np.sin(a)
         if a == 0:
                 J1 = 0
         else:
                 J1 = special.j1(inside)/(inside)
         
         inside = q*r*np.cos(a)
         if inside == 0:
                 j0 = 1
         else:
                 j0 = np.sin(inside)/inside
         temp = 2*(2*3.14*r*h)*c*j0*J1
         yield temp
Example #15
0
def discreteModel(theta, uvsamples, bins):

    # retrieve inputs
    incl, PA, offset, w = theta
    rin, b = bins
    u, v = uvsamples			# in **lambda** units

    # convert angles to radians
    inclr = np.radians(incl)
    PAr = 0.5*np.pi-np.radians(PA)
    offr = offset * np.pi / (180.*3600.)

    # coordinate change to deal with projection, rotation, and shifts
    #uprime = ((u-offr[0])*np.cos(PAr) + (v-offr[1])*np.sin(PAr)) * np.cos(inclr)
    #vprime = (-(u-offr[0])*np.sin(PAr) + (v-offr[1])*np.cos(PAr))
    uprime = (u*np.cos(PAr) + v*np.sin(PAr)) 
    vprime = (-u*np.sin(PAr) + v*np.cos(PAr)) * np.cos(inclr)
    rho = np.sqrt(uprime**2 + vprime**2) * np.pi / (180.*3600.)

    # re-orient arrays
    rbin = np.concatenate([np.array([rin]), b])
    wbin = np.append(np.concatenate([np.array([0.0]), w]), 0.)
    ww = wbin-np.roll(wbin, -1)
    intensity = np.delete(ww, b.size+1)

    # compute the visibilities
    jarg = np.outer(2.*np.pi*rbin, rho)
    jinc = sc.j1(jarg)/jarg
    vis = np.dot(2.*np.pi*rbin**2*intensity, jinc)

    # impart a phase center shift
    shift = np.exp(-2.*np.pi*1.0j*((u*-offr[0]) + (v*-offr[1])))
    model_vis = vis*shift

    return model_vis
Example #16
0
def d3sbModel(theta, uvsamples, bins):

    incl = 0.
    w = theta
    #incl = np.deg2rad(theta[0]) #Projected Inclination
    #w = theta[1:] #Ring bin amplitudes

    u, v = uvsamples
    udeproj = u * np.cos(incl) #Deproject
    #vdeproj = v * np.cos(incl) #Deproject
    rho  = 1e3*np.sqrt(udeproj**2+v**2)
    #rho = 1e3*np.sqrt(vdeproj**2+u**2)

    rin, b = bins

    rbin = np.concatenate([np.array([rin]), b])
    wbin = np.append(np.concatenate([np.array([0.0]), w]), 0.)
    ww = wbin-np.roll(wbin, -1)
    wgt = np.delete(ww, b.size+1)

    jarg = np.outer(2.*np.pi*rbin, rho/206264.806427)
    jinc = sc.j1(jarg)/jarg

    vis = np.dot(2.*np.pi*rbin**2*wgt, jinc)

    return vis
Example #17
0
 def jinc(x):
     """Jinc function (J_1(x) / x)."""
     j = np.ones(x.shape)
     # Handle 0/0 at origin
     nonzero_x = abs(x) > 1e-20
     j[nonzero_x] = 2 * sp.j1(np.pi * x[nonzero_x]) / (np.pi * x[nonzero_x])
     return j
Example #18
0
File: initials.py Project: natl/bg
def gravground( x          ,
                y          ,
                g          ,
                G          ,
                *args      ,
                **kwargs):
  '''
  def gravground( x       ,
                  y       ,
                  g       ,
                  G       ,
                  *args   ,
                  **kwargs):
  Create the Thomas-Fermi ground state for a gravitational system
  '''
  X,Y = np.meshgrid(x,y)
  R = np.sqrt( X ** 2. + Y ** 2. )
  bj0z1   = jn_zeros( 0, 1 ) #First zero of zeroth order besselj
  scaling = np.sqrt( 2 * np.pi * G / g  )
  gr0     = bj0z1 / scaling
  Rprime  = R * scaling
  
  gtfsol = j0( Rprime ) * np.array( [ map( int,ii ) for ii in map( 
                                      lambda rad: rad <= gr0, R ) ] )

      
  gtfsol *= scaling ** 2. / ( 2 * np.pi * j1( bj0z1 ) * bj0z1 ) 
  
  return gtfsol
Example #19
0
def discreteModel(theta, uvsamples, bins):

    # retrieve inputs
    incl, PA, offset, w = theta
    rin, b = bins
    u, v = uvsamples			# in **lambda** units

    # convert angles to radians
    inclr = np.radians(incl)
    PAr = np.radians(PA)
    offr = offset * np.pi / (180.*3600.)

    # coordinate change to deal with projection, rotation, and shifts
    uprime = (u * np.cos(PAr) + v * np.sin(PAr)) * np.cos(inclr)
    vprime = (-u * np.sin(PAr) + v * np.cos(PAr))
    rho = np.sqrt(uprime**2 + vprime**2) * np.pi / (180.*3600.)

    # re-orient arrays
    rbin = np.concatenate([np.array([rin]), b])
    wbin = np.append(np.concatenate([np.array([0.0]), w]), 0.)
    ww = wbin-np.roll(wbin, -1)
    intensity = np.delete(ww, b.size+1)

    jarg = np.outer(2.*np.pi*rbin, rho)
    jinc = sc.j1(jarg)/jarg

    vis = np.dot(2.*np.pi*rbin**2*intensity, jinc)

    Re_vis = vis * np.cos(-2*np.pi*(u*offr[0] + v*offr[1]))
    Im_vis = vis * np.sin(-2*np.pi*(u*offr[0] + v*offr[1]))

    vis_complex = Re_vis + 1j*Im_vis

    return vis_complex
Example #20
0
    def tetmConstants(self, ri, ro, neff, wl, EH, c, idx):
        a = numpy.empty((2, 2))
        n = self.maxIndex(wl)
        u = self.u(ro, neff, wl)
        urp = self.u(ri, neff, wl)

        if neff < n:
            B1 = j0(u)
            B2 = y0(u)
            F1 = j0(urp) / B1
            F2 = y0(urp) / B2
            F3 = -j1(urp) / B1
            F4 = -y1(urp) / B2
            c1 = wl.k0 * ro / u
        else:
            B1 = i0(u)
            B2 = k0(u)
            F1 = i0(urp) / B1
            F2 = k0(urp) / B2
            F3 = i1(urp) / B1
            F4 = -k1(urp) / B2
            c1 = -wl.k0 * ro / u
        c3 = c * c1

        a[0, 0] = F1
        a[0, 1] = F2
        a[1, 0] = F3 * c3
        a[1, 1] = F4 * c3

        return numpy.linalg.solve(a, EH.take(idx))
Example #21
0
 def _tmcoeq(self, v0, nu):
     u1r1, u2r1, u2r2, s1, s2, n1sq, n2sq, n3sq = self.__params(v0)
     if s1 == 0:  # e
         f11a, f11b = 2, 1
     elif s1 > 0:  # a, b, d
         f11a, f11b = j0(u1r1) * u1r1, j1(u1r1)
     else:  # c
         f11a, f11b = i0(u1r1) * u1r1, i1(u1r1)
     if s2 > 0:
         f22a, f22b = j0(u2r2), y0(u2r2)
         f2a = j1(u2r1) * f22b - y1(u2r1) * f22a
         f2b = j0(u2r1) * f22b - y0(u2r1) * f22a
     else:  # a
         f22a, f22b = i0(u2r2), k0(u2r2)
         f2a = i1(u2r1) * f22b + k1(u2r1) * f22a
         f2b = i0(u2r1) * f22b - k0(u2r1) * f22a
     return f11a * n2sq * f2a - f11b * n1sq * f2b * u2r1
Example #22
0
def phase_binary(u, v, wavel, p):
	''' Calculate the phases observed by an array on a binary star
	----------------------------------------------------------------
	p: 3-component vector (+2 optional), the binary "parameters":
	- p[0] = sep (mas)
	- p[1] = PA (deg) E of N.
	- p[2] = contrast ratio (primary/secondary)
	
	optional:
	- p[3] = angular size of primary (mas)
	- p[4] = angular size of secondary (mas)

	- u,v: baseline coordinates (meters)
	- wavel: wavelength (meters)
	---------------------------------------------------------------- '''

	p = np.array(p)
	# relative locations
	th = (p[1] + 90.0) * np.pi / 180.0
	ddec =  mas2rad(p[0] * np.sin(th))
	dra  = -mas2rad(p[0] * np.cos(th))

	# baselines into number of wavelength
	x = np.sqrt(u*u+v*v)/wavel

	# decompose into two "luminosity"
	l2 = 1. / (p[2] + 1)
	l1 = 1 - l2
	
	# phase-factor
	phi = np.zeros(u.size, dtype=complex)
	phi.real = np.cos(-2*np.pi*(u*dra + v*ddec)/wavel)
	phi.imag = np.sin(-2*np.pi*(u*dra + v*ddec)/wavel)

	# optional effect of resolved individual sources
	if p.size == 5:
		th1, th2 = mas2rad(p[3]), mas2rad(p[4])
		v1 = 2*j1(np.pi*th1*x)/(np.pi*th1*x)
		v2 = 2*j1(np.pi*th2*x)/(np.pi*th2*x)
	else:
		v1 = np.ones(u.size)
		v2 = np.ones(u.size)

	cvis = l1 * v1 + l2 * v2 * phi
	phase = np.angle(cvis, deg=True)
	return np.mod(phase + 10980., 360.) - 180.0
Example #23
0
def _jinc(x):
    """Internal implementation of the `jinc` function.
    The `jinc(x)` is defined as `J_1(x)/2x` and `jinc(0)=0.5`.
    """
    mask = x != 0.0
    result = 0.5*_np.ones(x.shape)
    result[mask] = _sps.j1(x[mask])/(x[mask])
    return result
Example #24
0
    def _tefield(self, wl, nu, neff, r):
        rho = self.fiber.outerRadius(0)
        k = wl.k0
        nco2 = self.fiber.maxIndex(0, wl)**2
        ncl2 = self.fiber.minIndex(1, wl)**2
        u = rho * k * sqrt(nco2 - neff**2)
        w = rho * k * sqrt(neff**2 - ncl2)

        if r < rho:
            hz = -Y0 * u / (k * rho) * j0(u * r / rho) / j1(u)
            ephi = -j1(u * r / rho) / j1(u)
        else:
            hz = Y0 * w / (k * rho) * k0(w * r / rho) / k1(w)
            ephi = -k1(w * r / rho) / k1(w)
        hr = -neff * Y0 * ephi

        return numpy.array((0, ephi, 0)), numpy.array((hr, 0, hz))
Example #25
0
def airyconv_MG(wid,radList):
    
    from scipy.special import j1,j0
    from numpy import pi,sum,ones,arange,zeros,sqrt
    from scipy import where

    nRad=len(radList)
    dd=radList[2]-radList[1]
    #print 'wid:',wid
    #print 'dd:',dd
    radListTot=arange(0,300,0.01)
    radListTot=where(radListTot == 0.,1.e-12,radListTot)
    airyList= ((2./pi) * (j1(pi*radListTot)/radListTot))**2
    
    airyTot=sum(airyList*2.*pi*radListTot*dd)

    conv1=zeros(nRad)
    conv2=zeros(nRad)
    npKer=wid/dd
    xList0=arange(-wid/2.,wid/2.+dd,dd)
    npKer=len(xList0)
    xArr0=zeros((npKer,npKer))
    yArr0=zeros((npKer,npKer))
    for x in range(npKer):
        xArr0[x,:]=xList0[x]
        yArr0[:,x]=xList0[x]
    
    for r in range(nRad):
        ##move along axis
        radArr=sqrt((xArr0+radList[r])**2 + yArr0**2)
        radArr=where(radArr == 0.,1.e-12,radArr) ##prevent div/0 errors
        bessArr = j1(pi*radArr)
        airyArr = ((2./pi) * (bessArr / radArr))**2
        conv1[r] = sum(airyArr)*dd**2./airyTot
    
        ##move at 45 degrees
        radArr=sqrt((xArr0+radList[r]/sqrt(2))**2 + (yArr0+radList[r]/sqrt(2))**2)
        radArr=where(radArr == 0.,1.e-12,radArr) ##prevent div/0 errors
        bessArr = j1(pi*radArr)
        airyArr = ((2./pi) * (bessArr / radArr))**2
        conv2[r] = sum(airyArr)*dd**2./airyTot
    
    convAz=(conv1 + conv2)/2.
    
    return(conv1,conv2,convAz)
Example #26
0
 def _j1(self, x):
     if self._nu == -1:
         return j0(x)
     elif self._nu == 0:
         return j1(x)
     elif np.floor(self._nu) == self._nu:
         return jn(self._nu + 1, x)
     else:
         return jv(self._nu + 1, x)
Example #27
0
def plotCF():
    ncl = 1.444
    nco = ncl + 0.05
    V = numpy.linspace(1, 7)

    pyplot.plot(V, j0(V))
    pyplot.plot(V, j1(V))
    pyplot.plot(V, jn(2, V))

    n02 = ncl*ncl / (nco * nco)
    a = (1 - n02) / (1 + n02)
    pyplot.plot(V, a * jn(2, V) - j0(V))
    pyplot.plot(V, a * jn(3, V) - j1(V))
    pyplot.plot(V, a * jn(4, V) - jn(2, V))

    pyplot.axhline(0, ls='--', color='k')

    pyplot.show()
Example #28
0
def funcZetaCyl(z, Bi):
    """
    zeta, Bi function for cylinder as f(z) = z*J1(z) - Bi*J0(z)
    note that J1 and J0 are bessel functions
    z = zeta values which are later solved for the positive roots for theta
    Bi = Biot number h*L/k, (-)
    """
    f = z*sp.j1(z) - Bi*sp.j0(z)
    return f
Example #29
0
    def _tmfield(self, wl, nu, neff, r):
        rho = self.fiber.outerRadius(0)
        k = wl.k0
        nco2 = self.fiber.maxIndex(0, wl)**2
        ncl2 = self.fiber.minIndex(1, wl)**2
        u = rho * k * sqrt(nco2 - neff**2)
        w = rho * k * sqrt(neff**2 - ncl2)

        if r < rho:
            ez = -u / (k * neff * rho) * j0(u * r / rho) / j1(u)
            er = j1(u * r / rho) / j1(u)
            hphi = Y0 * nco2 / neff * er
        else:
            ez = nco2 / ncl2 * w / (k * neff * rho) * k0(w * r / rho) / k1(w)
            er = nco2 / ncl2 * k1(w * r / rho) / k1(w)
            hphi = Y0 * nco2 / ncl2 * k1(w * r / rho) / k1(w)

        return numpy.array((er, 0, ez)), numpy.array((0, hphi, 0))
Example #30
0
 def _j1(self, x):
     if self._nu == -1:
         return j0(x)
     elif self._nu == 0:
         return j1(x)
     elif isinstance(self._nu, int):
         return jn(self._nu + 1, x)
     else:
         return jv(self._nu + 1, x)
Example #31
0
def plot_temp_ana(name):
    # parameters
    mu = 0.01
    E = 30000  # Young's modulus
    v = 0.2  # poisson's ratio
    mu_s = E / (2 + 2 * v)  # lame coefficient
    lambda_s = 2 * mu_s * v / (1 - 2 * v)  # lame coefficient
    HA = lambda_s + 2 * mu_s  # aggregate modulus
    r0 = 1.0  # radius 1m
    ubc = -0.05  # displacement boundary
    epsilon0 = ubc / r0  # strain
    kappa = 1e-10  # permeability
    vis = 1e-3  # viscosity
    K = kappa / vis  # hydraulic conductivity
    t = 10  # unit second
    eta = (1 - v) / (1 - 2 * v)

    tol = 1e-10  # tolerance to stop

    r = np.arange(0, 1.05, 0.05)  # the different locations along the axises
    u1 = np.zeros(21)
    for i in range(len(r)):
        u1[i] = r0 * epsilon0 * (1 - eta) / (2 * eta - 1) * r[i] / r0

    u2 = np.zeros(21)
    for i in range(len(r)):
        error = 1e10  # initial error
        n = 1  # iteration calculator
        u0 = 1e10  # initial guess for displacement
        while error > tol:
            a1 = sp.j1(roots[n] * r[i] / r0)
            a2 = roots[n] * sp.j0(
                roots[n]) * (2 * eta - 1 - eta * eta * roots[n] * roots[n])
            a3 = math.exp(-roots[n] * roots[n] * t * HA * K / (r0 * r0))
            #  u2[i] += (HA - lambda_s) / (
            #           roots[n] * ((HA + lambda_s) * sp.j0(roots[n]) - roots[n] * HA * sp.j1(roots[n]))) * sp.j1(
            #           roots[n] * r[i] / r0) * math.exp(-HA * K / (r0 ** 2) * (roots[n] ** 2) * t)
            u2[i] += a1 / a2 * a3
            error = np.fabs(u2[i] - u0)
            u0 = u2[i]
            n += 1

    u2 = u2 * r0 * epsilon0
    u = u1 + u2

    # np.savetxt('test',R)
    setupMatplotlib()
    plt.close('all')
    # fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col', sharey='row')
    # ax.plot(r, s_tt, label='analytical')
    fig = plt.figure(figsize=(6, 4))
    ax = fig.add_subplot(111)
    # lns1 = ax.plot(data.arc_length, data.displacement1, "o", mec="red", mfc="none", label='ogs6')
    lns2 = ax.plot(r, u, "b--", label='analytical')
    ax.set_xlabel('radius (m)')
    ax.set_ylabel('Displacment_x (m)', color='b')
    legend = ax.legend(loc='upper right', shadow=True)
    plt.title('Unconfined Consolidation')
    ax.grid()
    '''fig = plt.figure(figsize=(6, 4))
    # fig, axes = plt.subplots(nrows=2, ncols=2)
    ax = fig.add_subplot(111)
    ay = ax.twinx()
    ax1 = fig.add_subplot(221)
    # fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    ax1.set_title('2 months')
    #lns1 = ax1.plot(data1_2m.arc_length, data1_2m.TEMPERATURE1, "b", label='ogs5')
    ax1.plot(data2_2m.arc_length, T2months_num, "o", mec="red", mfc="none", label='ogs6')
    ax1.plot(x, T2months, "b--", label='analytical')
    ax2.plot(x, R1, "black", label='error')


    ax3 = fig.add_subplot(222)
    ax4 = ax3.twinx()
    ax3.set_title('1 year')
    #ax3.plot(data1_1y.arc_length, data1_1y.TEMPERATURE1, "b", label='ogs5')
    ax3.plot(data2_1y.arc_length, T1year_num, "o", mec="red", mfc="none", label='ogs6')
    ax3.plot(x, T1year, "g--", label='analytical')
    ax4.plot(x, R2, "black", label='error')
    ax5 = fig.add_subplot(223)
    ax6 = ax5.twinx()
    ax5.set_title('2 years')
    #ax5.plot(data1_2y.arc_length, data1_2y.TEMPERATURE1, "b", label='ogs5')
    ax5.plot(data2_2y.arc_length, T2years_num, "o", mec="red", mfc="none", label='ogs6')
    ax5.plot(x, T2years, "g--", label='analytical')
    ax6.plot(x, R3, "black", label='error')
    ax7 = fig.add_subplot(224)
    ax8 = ax7.twinx()
    ax7.set_title('4 years')
    #ax7.plot(data1_4y.arc_length, data1_4y.TEMPERATURE1, "b", label='ogs5')
    ax7.plot(data2_4y.arc_length, T4years_num, "o", mec="red", mfc="none", label='ogs6')
    ax7.plot(x, T4years, "g--", label='analytical')
    ax8.plot(x, R4, "black", label='error')

    # Turn off axis lines and ticks of the big subplot
    ax.spines['top'].set_color('none')
    ax.spines['bottom'].set_color('none')
    ax.spines['left'].set_color('none')
    ax.spines['right'].set_color('none')
    ay.spines['top'].set_color('none')
    ay.spines['bottom'].set_color('none')
    ay.spines['left'].set_color('none')
    ay.spines['right'].set_color('none')
    ax.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off')
    ay.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off')

    ax.set_xlabel('Distance (m)')
    ax.set_ylabel('Temperature (K)')
    ay.set_ylabel('Error')
    ax1.legend()
    ax3.legend()
    ax5.legend()
    ax7.legend()
    # ax1.set_title('2 months')
    # commonFormat(ax)
    # ax.set_xlabel('Distance', fontsize=16)
    # ax.xaxis.set_label_coords(0.5,-0.05)
    # ax.set_ylabel('Temperature', fontsize=18)
    # ax.set_xlim(right=10)
    # ax.set_ylim(bottom=3.e-2)
    # ax.set_ylim(top = 7.e-2)
    # ax.set_yscale('log')
    # ax.legend(loc='lower right')
    # ax.yaxis.set_label_coords(-0.05, 0.5) '''
    fig.tight_layout()
    fig.savefig(name)
    return None
Example #32
0
def getAiryProbe(
        wavelength=0.142e-9,  # 8.7 keV 
        pixel_pitch=30e-9,  # 55 micrometers 
        npix=32,
        n_photons=1e6,
        beam_diam_pixels=5):
    """Calculates the beam profile given the final beam diameter. 
    
    Parameters:
    
    wavelength : 
    self-explanatory
    
    pixel_pitch : 
    object/probe pixel pitch. Usually calculated using the Nyquist theorem using the object-detector
    distance and the detector pixel pitch.
    
    n_pix:
    number of pixels along each axis in the probe view
    
    n_photons:
    self-explanatory
    
    beam_diam_pixels:
    the diameter (in pixels) of the first central lobe of the probe beam at the object (sample) plane.

    Assumption:
    - propagation distance (from aperture to sample) and initial aperture width are calculated 
    assuming a Fresnel number of 0.1
    """
    beam_width_dist = beam_diam_pixels * pixel_pitch
    radius = beam_width_dist / 2
    # Initial Aperture width
    w = 0.1 * 2 * np.pi * radius / (special.jn_zeros(1, 1))

    # Propagation dist from aperture to sample
    z = 0.1 * (2 * np.pi * radius)**2 / (special.jn_zeros(1, 1)**2 *
                                         wavelength)

    beam_center = npix // 2
    xvals = np.linspace(-beam_center * pixel_pitch, beam_center * pixel_pitch,
                        npix)
    xx, yy = np.meshgrid(xvals, xvals)

    k = 2 * np.pi / wavelength
    lz = wavelength * z
    S = xx**2 + yy**2

    jinc_input = np.sqrt(S) * w / lz
    mask = (jinc_input != 0)
    jinc_term = np.pi * np.ones_like(jinc_input)
    jinc_term[mask] = special.j1(
        jinc_input[mask] * 2 * np.pi) / jinc_input[mask]

    # wavefield
    #term1 = np.exp(1j * k * z) / (1j * lz)
    term1 = 1 / (1j * lz)
    term2 = np.exp(1j * k * S / (2 * z))
    term3 = w**2 * jinc_term
    field_vals = (term1 * term2 * term3).astype('complex64')

    scaling_factor = np.sqrt(n_photons / (np.abs(field_vals)**2).sum())
    field_vals = scaling_factor * field_vals
    return field_vals
Example #33
0
def sombrero():
    a0 = 2.
    S = lambda r: a0 * scs.j1(a0 * r) / r
    H = lambda r: r < a0
    return S, H
Example #34
0
    def SNRcalc(self, pulsar, pop):
        """Calculate the S/N ratio of a given pulsar in the survey"""
        # if not in region, S/N = 0

        # if we have a list of pointings, use this bit of code
        # haven't tested yet, but presumably a lot slower
        # (loops over the list of pointings....)

        if pulsar.dead:
            return 0.
        # otherwise check if pulsar is in entire region
        if self.inRegion(pulsar):
            # If pointing list is provided, check how close nearest
            # pointing is
            if self.pointingslist is not None:
                # convert offset from degree to arcmin
                offset = self.inPointing(pulsar) * 60.0

            else:
                # calculate offset as a random offset within FWHM/2
                offset = self.fwhm * math.sqrt(random.random()) / 2.0
        else:
            return -2

        # Get degfac depending on self.gainpat
        if self.gainpat == 'airy':
            conv = math.pi / (60 * 180.)  # Conversion arcmins -> radians
            eff_diam = 3.0e8 / (self.freq * self.fwhm * conv * 1.0e6
                                )  # Also MHz -> Hz
            a = eff_diam / 2.  # Effective radius of telescope
            lamda = 3.0e8 / (self.freq * 1.0e6)  # Obs. wavelength
            kasin = (2 * math.pi * a / lamda) * np.sin(offset * conv)
            degfac = 4 * (j1(kasin) / kasin)**2
        else:
            degfac = math.exp(-2.7726 * offset * offset /
                              (self.fwhm * self.fwhm))

        # calc dispersion smearing across single channel
        tdm = self._dmsmear(pulsar)

        # calculate bhat et al scattering time (inherited from GalacticOps)
        # in units of ms
        tscat = go.scatter_bhat(pulsar.dm, pulsar.scindex, self.freq)

        # Calculate the effective width
        width_ms = pulsar.width_degree * pulsar.period / 360.0
        weff_ms = math.sqrt(width_ms**2 + self.tsamp**2 + tdm**2 + tscat**2)

        # calculate duty cycle (period is in ms)
        delta = weff_ms / pulsar.period

        # if pulse is smeared out, return -1.0
        if delta > 1.0:
            return -1

        #radiometer signal to noise
        sig_to_noise = rad.calcSNR(self.calcflux(pulsar,
                                                 pop.ref_freq), self.beta,
                                   self.tsys, self.tskypy(pulsar), self.gain,
                                   self.npol, self.tobs, self.bw, delta)

        # account for aperture array, if needed
        if self.AA:
            sig_to_noise *= self._AA_factor(pulsar)

        # return the S/N accounting for beam offset
        return sig_to_noise * degfac
# jn_zeros calculates the first n zeros of the zero-th order Bessel function
# of the first kind
max_zeros = 10
w = jn_zeros(0, max_zeros)
b = 2 * np.sqrt(L / g)


def func(u, n):
    """The integrand for the Fourier-Bessel coefficient A_n."""
    return u * f(u) * j0(w[n - 1] / b * u)


# Calculate the Fourier-Bessel coefficients using numerical integration
A = []
for n in range(1, max_zeros + 1):
    An = quad(func, 0, b, args=(n, ))[0] * 2 / (b * j1(w[n - 1]))**2
    A.append(An)

# Create a labelled plot comparing f(z) with the Fourier-Bessel series
# approximation truncated at 2, 3 and 5 terms.
plt.plot(f(u), z, 'k', lw=2, label='$f(z)$')
for nmax in (3, 5, 10):
    ffit = np.zeros(N)
    for n in range(nmax):
        ffit += A[n - 1] * j0(w[n - 1] / b * u)
    plt.plot(ffit, z, label=r'$n_\mathrm{max} = ' + '{}$'.format(nmax))
plt.xlim(-d / 5, d)
plt.xlabel(r'$x$')
plt.ylabel(r'$z$')
plt.legend()
Example #36
0
# the loop repeats

# what could be added is a clause that says for r <= 10**-10 r = 0.01? (small)

# can include the line with math.log( ... , 10) to log base 10 the function so it fits better on my
# graph do i need to multiply by the dx here or? not sure

for i in x:

    cj = 0

    for j in y:

        r = x[ci]**2 + y[cj]**2

        I_theta_arr[ci][cj] = ((2 * sp.j1(r) / r)**2) * dx

        cj = cj + 1

    ci = ci + 1

# these help make the lengths more identifiable, can be uncommented if needed

# print(r)
#
# print(I_theta_arr)
# print(I_theta_arr.size)
# print(x.size)
# print(y.size)
# print(r.size)
Example #37
0
res_sc_br = minimize_scalar(f, method='brent')

print(res_sc_br.x)
print(res_sc_br.fun)
print(f(res_sc_br.x))

#--------------------------------------------------
# Bounded method: Need to specify an interval.
#--------------------------------------------------

from scipy.special import j1
# Plot this function to show an optimum.
x_grid = np.arange(4, 7, 0.01)
f_grid = x_grid * 0
for i in range(0, len(x_grid)):
    f_grid[i] = j1(x_grid[i])

plt.figure()
plt.plot(x_grid, f_grid, label='J_1(x)')
plt.xlabel('x')
plt.ylabel('J_(x)')
plt.show()

# Search for good bounds first:
j1(4)
j1(5)
j1(7)

res_sc_bdd = minimize_scalar(j1, bounds=(4, 7), method='bounded')

print(res_sc_bdd.x)
Example #38
0
    arg3_DOP = [
        Lav, betst, Inc, Ombn, alph, n0, Rde, pp, thetTst, J3, aeff, nu0, nne
    ]
    arg4_DOP = [
        Lav, betst, Inc, Ombn, alph, n0, Rde, pp, thetTst, J4, aeff, nu0, nne
    ]
    arg5_DOP = [
        Lav, betst, Inc, Ombn, alph, n0, Rde, pp, thetTst, J5, aeff, nu0, nne
    ]

    Dop1_anal = 1. / (2. * ma.pi * frc_a)**2 * np.sin(Inc - np.pi / 2) * (
        2. * ma.pi * frc_a * np.cos(2. * ma.pi * frc_a * np.cos(thetTst)) -
        np.sin(2. * ma.pi * frc_a * np.cos(thetTst)) / np.cos(thetTst))

    from scipy import special as spc
    DopRing_anal = spc.j1(2. * ma.pi * frc_a)

    DOP1_AIR_over_AUV = np.zeros(len(frc_t))
    DOP2_AIR_over_AUV = np.zeros(len(frc_t))
    DOP3_AIR_over_AUV = np.zeros(len(frc_t))
    DOP4_AIR_over_AUV = np.zeros(len(frc_t))
    DOP5_AIR_over_AUV = np.zeros(len(frc_t))

    for i in range(len(frc_t)):
        DOP1_AIR_over_AUV[i] = DOP_AIR_o_AUV(frc_t[i], numn, numx, Dst,
                                             arg1_DOP, RHS_table, T_table)
        DOP2_AIR_over_AUV[i] = DOP_AIR_o_AUV(frc_t[i], numn, numx, Dst,
                                             arg2_DOP, RHS_table, T_table)
        DOP3_AIR_over_AUV[i] = DOP_AIR_o_AUV(frc_t[i], numn, numx, Dst,
                                             arg3_DOP, RHS_table, T_table)
        DOP4_AIR_over_AUV[i] = DOP_AIR_o_AUV(frc_t[i], numn, numx, Dst,
Example #39
0
def calc_P_clad(omega, a, beta, u, w, A):
    return ((np.pi / 2) * omega * mu_0 * beta * np.abs(A)**2 * (a**4 / u**2) *
            j1(u)**2 * (((k0(w) * kv(2, w)) / k1(w)**2) - 1))
Example #40
0
def Hr_core(r, phase, beta, a, u, A):
    return 1j * beta * (a / u) * A * j1(u * r / a) * np.exp(1j * phase)
Example #41
0
def Ep_core(r, phase, omega, a, u, A):
    return -1j * omega * mu_0 * (a / u) * A * j1(u * r / a) * np.exp(
        1j * phase)
Example #42
0
def eve_lhs(u, w):
    return j1(u) / (u * j0(u))
def jinc(x):
    return spl.j1(x) / x
Example #44
0
G_tot = 72.41
A = np.exp(-tau * G_tot)

m = (DWF * U * dk * tau * 1e-9)**2 * sqrt(N) / (4 * sqrt(2) *
                                                sqrt(A**(-2) - 1))
plt.plot(amps_th,
         fit(amps_th, m, 2),
         '--',
         label=r'{:.3f}*z^({:.3f})'.format(m, 2))

amps_th = np.linspace(1, 3, 500)
pwr = np.linspace(0, 1, 500)

theta_max_2 = np.linspace(2, 2, 300)
amps_th_2 = np.linspace(10, 0.25, 300)
theta_max = np.append(theta_max_2, theta_max)
amps_th = np.append(amps_th_2, amps_th)
Pup = 1 / 2 - 1 / 2 * A * j0(theta_max)
sig_proj = 1 / sqrt(55) * sqrt(Pup * (1 - Pup))
sig_up = (A**2) / 8 * (1 + j0(2 * theta_max) - 2 * j0(theta_max)**2)
delta_J_m = 2 * A**(-1) * sqrt(sig_proj**2 + sig_up)
delta_th_m = delta_J_m / (j1(theta_max))
S_N_m = theta_max / delta_th_m / 2

#plt.plot(amps_th,S_N_m,'--')

plt.legend(loc=(1, 0))
plt.ylim(0, 2)
#plt.xlim(0,.5)
plt.xlabel('Displacement Amplitude (nm)')
plt.ylabel('Signal to noise')
Example #45
0
etaV = etaV[0, :]
zetaH = zetaH[0, :]
zetaV = zetaV[0, :]
rtol = htarg['rtol']
atol = htarg['atol']
nquad = htarg['nquad']
maxint = htarg['maxint']
pts_per_dec = htarg['pts_per_dec']
diff_quad = htarg['diff_quad']
a = htarg['a']
b = htarg['b']
limit = htarg['limit']
g_x, g_w = special.roots_legendre(nquad)
b_zero = np.pi * np.arange(1.25, maxint + 1)
for i in range(10):
    b_x0 = special.j1(b_zero)
    b_x1 = special.jv(2, b_zero)
    b_h = -b_x0 / (b_x0 / b_zero - b_x1)
    b_zero += b_h
    if all(np.abs(b_h) < 8 * np.finfo(float).eps * b_zero):
        break
xint = np.concatenate((np.array([1e-20]), b_zero))
dx = np.repeat(np.diff(xint) / 2, nquad)
Bx = dx * (np.tile(g_x, maxint) + 1) + np.repeat(xint[:-1], nquad)
BJ0 = special.j0(Bx) * np.tile(g_w, maxint)
BJ1 = special.j1(Bx) * np.tile(g_w, maxint)
intervals = xint / off[:, None]
lambd = Bx / off[:, None]
ang_fact = kernel.angle_factor(angle, ab, msrc, mrec)
# 1 Spline version
start = np.log(lambd.min())
def airy_fun(x, centre, amp):  # , exp):  # , amp, bg):
    with np.errstate(divide='ignore', invalid='ignore'):
        return np.where((x - centre) == 0, amp * .5**2,
                        amp * (special.j1(x - centre) / (x - centre))**2)
Example #47
0
    def update_Theta(self, p):
        '''
        Update the model to the current Theta parameters.

        :param p: parameters to update model to
        :type p: model.ThetaParam
        '''

        # durty HACK to get fixed logg
        # Simply fixes the middle value to be 4.29
        # Check to see if it exists, as well
        fix_logg = Starfish.config.get("fix_logg", None)
        if fix_logg is not None:
            p.grid[1] = fix_logg
        print("grid pars are", p.grid)

        self.logger.debug("Updating Theta parameters to {}".format(p))

        # Store the current accepted values before overwriting with new proposed values.
        self.flux_mean_last = self.flux_mean.copy()
        self.flux_std_last = self.flux_std.copy()
        self.eigenspectra_last = self.eigenspectra.copy()
        self.mus_last = self.mus
        self.C_GP_last = self.C_GP

        # Local, shifted copy of wavelengths
        wl_FFT = self.wl_FFT * np.sqrt((C.c_kms + p.vz) / (C.c_kms - p.vz))

        # If vsini is less than 0.2 km/s, we might run into issues with
        # the grid spacing. Therefore skip the convolution step if we have
        # values smaller than this.
        # FFT and convolve operations
        if p.vsini < 0.0:
            raise C.ModelError("vsini must be positive")
        elif p.vsini < 0.2:
            # Skip the vsini taper due to instrumental effects
            eigenspectra_full = self.EIGENSPECTRA.copy()
        else:
            FF = np.fft.rfft(self.EIGENSPECTRA, axis=1)

            # Determine the stellar broadening kernel
            ub = 2. * np.pi * p.vsini * self.ss
            sb = j1(ub) / ub - 3 * np.cos(ub) / (
                2 * ub**2) + 3. * np.sin(ub) / (2 * ub**3)
            # set zeroth frequency to 1 separately (DC term)
            sb[0] = 1.

            # institute vsini taper
            FF_tap = FF * sb

            # do ifft
            eigenspectra_full = np.fft.irfft(FF_tap, self.pca.npix, axis=1)

        # Spectrum resample operations
        if min(self.wl) < min(wl_FFT) or max(self.wl) > max(wl_FFT):
            raise RuntimeError(
                "Data wl grid ({:.2f},{:.2f}) must fit within the range of wl_FFT ({:.2f},{:.2f})"
                .format(min(self.wl), max(self.wl), min(wl_FFT), max(wl_FFT)))

        # Take the output from the FFT operation (eigenspectra_full), and stuff them
        # into respective data products
        for lres, hres in zip(
                chain([self.flux_mean, self.flux_std], self.eigenspectra),
                eigenspectra_full):
            interp = InterpolatedUnivariateSpline(wl_FFT, hres, k=5)
            lres[:] = interp(self.wl)
            del interp

        # Helps keep memory usage low, seems like the numpy routine is slow
        # to clear allocated memory for each iteration.
        gc.collect()

        # Adjust flux_mean and flux_std by Omega
        Omega = 10**p.logOmega
        self.flux_mean *= Omega
        self.flux_std *= Omega

        # Now update the parameters from the emulator
        # If pars are outside the grid, Emulator will raise C.ModelError
        self.emulator.params = p.grid
        self.mus, self.C_GP = self.emulator.matrix
Example #48
0
def lnprob(p):

    grid = p[:3]
    vz, vsini, logOmega = p[3:]

    # Local, shifted copy of wavelengths
    wl_FFT = wl_FFT_orig * np.sqrt((C.c_kms + vz) / (C.c_kms - vz))

    # Holders to store the convolved and resampled eigenspectra
    eigenspectra = np.empty((pca.m, ndata))
    flux_mean = np.empty((ndata, ))
    flux_std = np.empty((ndata, ))

    # If vsini is less than 0.2 km/s, we might run into issues with
    # the grid spacing. Therefore skip the convolution step if we have
    # values smaller than this.
    # FFT and convolve operations
    if vsini < 0.0:
        return -np.inf
    elif vsini < 0.2:
        # Skip the vsini taper due to instrumental effects
        eigenspectra_full = EIGENSPECTRA.copy()
    else:
        FF = np.fft.rfft(EIGENSPECTRA, axis=1)

        # Determine the stellar broadening kernel
        ub = 2. * np.pi * vsini * ss
        sb = j1(ub) / ub - 3 * np.cos(ub) / (2 * ub**2) + 3. * np.sin(ub) / (
            2 * ub**3)
        # set zeroth frequency to 1 separately (DC term)
        sb[0] = 1.

        # institute vsini taper
        FF_tap = FF * sb

        # do ifft
        eigenspectra_full = np.fft.irfft(FF_tap, pca.npix, axis=1)

    # Spectrum resample operations
    if min(wl) < min(wl_FFT) or max(wl) > max(wl_FFT):
        raise RuntimeError(
            "Data wl grid ({:.2f},{:.2f}) must fit within the range of wl_FFT ({:.2f},{:.2f})"
            .format(min(wl), max(wl), min(wl_FFT), max(wl_FFT)))

    # Take the output from the FFT operation (eigenspectra_full), and stuff them
    # into respective data products
    for lres, hres in zip(chain([flux_mean, flux_std], eigenspectra),
                          eigenspectra_full):
        interp = InterpolatedUnivariateSpline(wl_FFT, hres, k=5)
        lres[:] = interp(wl)
        del interp

    gc.collect()

    # Adjust flux_mean and flux_std by Omega
    Omega = 10**logOmega
    flux_mean *= Omega
    flux_std *= Omega

    # Now update the parameters from the emulator
    # If pars are outside the grid, Emulator will raise C.ModelError
    try:
        emulator.params = grid
        mus, C_GP = emulator.matrix
    except C.ModelError:
        return -np.inf

    # Get the mean spectrum
    X = (flux_std * np.eye(ndata)).dot(eigenspectra.T)
    mean_spec = flux_mean + X.dot(mus)
    R = fl - mean_spec

    # Evaluate chi2
    lnp = -0.5 * np.sum((R[mask] / sigma[mask])**2)
    return lnp
#All parameters are in Ang
#This is for circular annular ap in 1d
import matplotlib.pyplot as plt
import numpy as np
import scipy.special as spl
q1 = np.linspace(-2 * 10**7, 2 * 10**7, 512)
a = 1 * 10**7
k = 2 * 3.14 / 6000
f = 10**10
e = 0.6
m = q1 * k * a / f
n = k * a * e * q1 / f
z = 1 / (1 - e**2) * ((2 * spl.j1(m) / m) - (e) * (2 * spl.j1(n) / m))
plt.xlabel('q1*a*k/f')
plt.ylabel('intensity')
plt.plot(q1 * a * k / f, z**2)
plt.show()
Example #50
0
    def __init__(self, L, R, n_modes_z, n_modes_r):

        self.n_modes_r = n_modes_r
        self.n_modes_z = n_modes_z

        self.domain_L = L
        self.domain_R = R

        self.kr = jn_zeros(0, self.n_modes_r) / R
        self.kz = np.pi * np.arange(1, self.n_modes_z + 1) / L

        self.oneOkr = 1. / self.kr
        self.oneOkz = 1. / self.kz

        # Needed for the normalization
        zero_zeros = jn_zeros(0, self.n_modes_r)

        self.omega_coords = np.zeros((self.n_modes_z, self.n_modes_r, 2))
        self.dc_coords = np.zeros((self.n_modes_z, self.n_modes_r, 2))
        self.mode_mass = np.ones((self.n_modes_z, self.n_modes_r))

        self.omega = np.zeros((self.n_modes_z, self.n_modes_r))
        for idx_r in range(0, self.n_modes_r):
            for idx_z in range(0, self.n_modes_z):
                self.omega[idx_z,idx_r]= \
                    np.sqrt(self.kr[idx_r]**2 +self.kz[idx_z]**2)
                # Integral of cos^2(k_z z)*J_z(k_r r)^2 over the domain volume
                self.mode_mass[idx_z, idx_r] = R * R * L * (j1(
                    zero_zeros[idx_r]))**2 / (4. * consts.c)

        self.omegaOtwokz = 0.5 * np.einsum('z, zr -> zr', 1. / self.kz,
                                           self.omega)
        self.omegaOtwokr = 0.5 * np.einsum('r, zr -> zr', 1. / self.kr,
                                           self.omega)

        self.oneOomega = 1. / self.omega

        self.kzOomega = einsum('z, zr -> zr', self.kz, self.oneOomega)
        self.krOomega = einsum('r, zr -> zr', self.kr, self.oneOomega)

        self.delta_P_dc = np.zeros((self.n_modes_z, self.n_modes_r))
        self.delta_P_omega = np.zeros((self.n_modes_z, self.n_modes_r))

        # Particles are tent functions with widths the narrowest of the
        # k-vectors for each direction. Default for now is to have the
        # particle widths be half the shortest wavelength, which should
        # resolve the wave physics reasonably well.
        self.ptcl_width_z = .25 * 2. * np.pi / max(self.kz)
        self.ptcl_width_r = .25 * 2. * np.pi / max(self.kr)

        self.shape_function_z = np.exp(-0.5 * (self.kz * self.ptcl_width_z)**2)

        # With the conducting boundaries, unphysically large fields can
        # get trapped on the conducting surfaces. To squelch this, we put
        # a tanh-function envelope on the fields to make the fields go to
        # zero quickly but smoothly on the boundaries.

        self.tanh_width = np.max(self.kz)
        self.z_mean = 0.5 * self.domain_L

        # Create the mpi communicator
        self.comm = mpi.COMM_WORLD
Example #51
0
def jinc(x):
    j = np.ones(x.shape)
    # Handle 0/0 at origin
    nonzero_x = abs(x) > 1e-20
    j[nonzero_x] = 2 * sp.j1(np.pi * x[nonzero_x]) / (np.pi * x[nonzero_x])
    return j
TCM = 72.013
h = 6.582 * 10**(-22)
r0 = 1.44 * 10**-15
k1 = 2. * mr * TCM
k2 = c**2 * h**2
k = np.sqrt(k1 / k2)
R = r0 * (16**(1 / 3) + 12**(1 / 3))
kR = k * R
k2R4 = k**2 * R**4
k2R4mb = k2R4 * 10**31

y = np.array([
    400, 180, 70, 28, 20, 10, 18, 27, 45, 70, 80, 90, 80, 70, 50, 25, 11, 6,
    1.1, 4.2, 7, 12, 16, 20, 15, 11, 9, 7, 5, 3, 2, 1.8, 2.2, 3.1, 3.8, 4.1,
    3.7, 3.1, 2.7, 2.5, 1.1, 1.5, 1.3, 1.0, 0.9, 0.8, 0.9, 1.0, 1.05, 1.2, 1.2,
    0.8, 0.6, 0.4, 0.3, 0.2
])
x = np.linspace(np.pi * 15.0 / 180, np.pi * 42.5 / 180, len(y))

theta = np.arange(np.pi * 15.0 / 180, np.pi * 42.5 / 180, 0.005)
y1 = k2R4mb * ((spe.j1(kR * theta) / (kR * theta))**2)

plt.plot(x, y, '.')
plt.plot(theta, y1, '-')
plt.title('Difracción Teoría de Fraunhöfer vs. Pts. Experimentales', size='10')
plt.xlabel(r'$\theta$ (rad)')
plt.ylabel('Sección eficaz diferencial (mbarn/sr)')
plt.legend(('Pts. predichos por Fraunhöfer', 'Valores experimentales'),
           prop={'size': 10},
           loc='upper right')
Example #53
0
import numpy as np
import pickle
import scipy.special as sp
from scipy.optimize import fmin

expect_full = []
expect_with_full = []

#for i in range(1):
#    with open("data/expectation_{0}_False.txt".format(i),"rb") as fp:
#        expect_full.append(pickle.load(fp))
#    with open("data/expectation_{0}_True.txt".format(i),"rb") as fp:
#        expect_with_full.append(pickle.load(fp))
expect_theo = 1j * sp.j1(1) / sp.j0(1)
#R = len(expect_full)
#Nr = len(expect_full[0])
#N = Nr*R

with open("data/config_mu_0.1_T_4.0.txt", "rb") as fp:
    expect_full = pickle.load(fp)

#with open("data/expectation_Nt20_beta1_step10_True.txt","rb") as fp:
#    expect_full = pickle.load(fp)

N = len(expect_full)
print('N=', N)
R = 0
Nr = N


def Moyenne(list_obs):
Example #54
0
#
# Origen:        Propio.
# Autor:         José María Herrera-Fernandez, Luis Miguel Sánchez-Brea
#
# Creación:        18 de Septiembre de 2013
# Historia:
#
# Dependencias:    scipy, matplotlib
# Licencia:        GPL
#----------------------------------------------------------------------
"""
Descripción: Cálculo de los coeficientes de orden cero y uno de la función de Bessel
contenida en el paquete special.
"""
from scipy import special  # Importamos scipy.special
import scipy as sp  # Importamos scipy como el alias sp
import matplotlib.pyplot as plt  # Importamos matplotlib.pyplot como el alias plt.

# Creamos el array dimensional
x = sp.arange(0, 50, .1)
print(x)
x1 = sp.arange(0, 1, .1)
print(x1)
# Calculamos los coeficientes de orden cero.
# j0 = special.j0(x)
j0 = special.j0(x1)
print(j0)
# # Calculamos los coeficientes de orden uno.
j1 = special.j1(x)
print(j1)
Example #55
0
def get2DSpheromakFlux(r, z, R=1, L=1, b0=1):
    j1_zero1 = jn_zeros(1, 1)[0]
    kr = j1_zero1 / R
    kz = np.pi / L
    return b0 * r * j1(kr * r) * np.sin(kz * z)
Example #56
0
def expect_th(beta=default_beta):
    # Return the imaginary part of the theoretical expect. value
    result = []
    for i in beta:
        result.append(sp.j1(i) / sp.j0(i))
    return result
Example #57
0
    def __init__(self,
                 target_res=0.005,
                 lenslet_CA=0.165,
                 zsampling='uniform_random',
                 cross_corr_norm='log_sum_exp',
                 aberrations=False,
                 GrinAber='',
                 GrinDictName='',
                 zernikes=[],
                 psf_norm='l1',
                 logsumparam=1e-2,
                 psf_scale=1e2):  #'log_sum_exp'
        # psf_scale: scale all PSFS by this constant after normalizing
        super(Model, self).__init__()
        target_option = 'airy'
        #self.samples = (512,512)  #Grid for PSF simulation
        self.samples = (768, 768)  #Grid for PSF simulation

        self.lam = 510e-6
        if GrinAber:
            #'/media/hongdata/Kristina/MiniscopeData/GrinAberrations.mat'
            # 'GrinAberrations'
            file = scipy.io.loadmat(GrinAber)
            GrinAber = file[GrinDictName]
            self.Grin = []
            for i in range(len(GrinAber)):
                Grinpad = pad_frac_tf(GrinAber[i, :, :] * self.lam,
                                      padfrac=0.5)
                Grinresize = cv2.resize(Grinpad.numpy(),
                                        (self.samples[1], self.samples[1]))
                self.Grin.append(Grinresize)

        # min and max lenslet focal lengths in mm
        self.fmin = 6.15
        self.fmax = 25.
        self.ior = 1.515
        self.lam = 510e-6
        self.psf_norm = psf_norm
        # Min and max lenslet radii
        self.Rmin = self.fmin * (self.ior - 1.)
        self.Rmax = self.fmax * (self.ior - 1.)
        self.psf_scale = tf.constant(psf_scale)
        # Convert to curvatures
        self.cmin = 1 / self.Rmax
        self.cmax = 1 / self.Rmin
        self.xgrng = np.array((-1.8, 1.8)).astype(
            'float32'
        )  #Range, in mm, of grid of the whole plane (not just grin)
        self.ygrng = np.array((-1.8, 1.8)).astype('float32')

        self.t = 10.  #Distance to sensor from mask in mm

        #Compute depth range of virtual image that mask sees (this is assuming an objective is doing some magnification)

        self.zmin_virtual = 1. / (1. / self.t - 1. / self.fmin)
        self.zmax_virtual = 1. / (1. / self.t - 1. / self.fmax)
        self.CA = .9
        #semi clear aperature of GRIN
        self.mean_lenslet_CA = lenslet_CA  #average lenslest semi clear aperture in mm.

        #Getting number of lenslets and z planes needed as well as defocus list
        self.ps = (self.xgrng[1] - self.xgrng[0]) / self.samples[0]
        self.Nlenslets = np.int(
            np.floor((self.CA**2) / (self.mean_lenslet_CA**2)))
        self.Nz = 20
        self.zsampling = zsampling
        self.grid_z_planes = 20

        #self.defocus_grid=  1./(np.linspace(1/self.zmin_virtual, 1./self.zmax_virtual, self.grid_z_planes)) #mm or dioptres

        #if self.zsampling is 'fixed':
        #    self.defocus_list = 1./(np.linspace(1/self.zmin_virtual, 1./self.zmax_virtual, self.Nz)) #mm or dioptres

        self.min_offset = 0  #-10e-3
        self.max_offset = 50e-3
        #self.lenslet_offset=tfe.Variable(tf.zeros(self.Nlenslets),name='offset', dtype = tf.float32)
        #self.lenslet_offset=tfe.Variable(tf.zeros(self.Nlenslets),name='offset', dtype = tf.float32,constraint=lambda t: tf.clip_by_value(t,self.min_offset, self.max_offset))
        self.lenslet_offset = tf.zeros(self.Nlenslets)
        #initializing the x and y positions
        [xpos, ypos, rlist] = poissonsampling_circular(self)

        self.min_r = self.Rmin
        self.max_r = self.Rmax
        self.rlist = tf.Variable(
            rlist,
            name='rlist',
            dtype=tf.float32,
            constraint=lambda t: tf.clip_by_value(t, self.min_r, self.max_r))
        #self.xpos = tfe.Variable(xpos, name='xpos', dtype = tf.float32, constraint=lambda t: tf.clip_by_value(t,-self.CA, self.CA))
        #self.ypos = tfe.Variable(ypos, name='ypos', dtype = tf.float32, constraint=lambda t: tf.clip_by_value(t,-self.CA, self.CA))
        self.xpos = tf.Variable(xpos, name='xpos', dtype=tf.float32)
        self.ypos = tf.Variable(ypos, name='ypos', dtype=tf.float32)
        #parameters for making the lenslet surface
        self.yg = tf.constant(np.linspace(self.ygrng[0], self.ygrng[1],
                                          self.samples[0]),
                              dtype=tf.float32)
        self.xg = tf.constant(np.linspace(self.xgrng[0], self.xgrng[1],
                                          self.samples[1]),
                              dtype=tf.float32)
        self.px = tf.constant(self.xg[1] - self.xg[0], tf.float32)
        self.py = tf.constant(self.yg[1] - self.yg[0], tf.float32)
        self.xgm, self.ygm = tf.meshgrid(self.xg, self.yg)

        # Normalized coordinates
        self.xnorm = self.xgm / np.max(self.xgm)
        self.ynorm = self.ygm / np.max(self.ygm)

        #PSF generation parameters
        self.lam = tf.constant(510. * 10.**(-6.), dtype=tf.float32)
        self.k = np.pi * 2. / self.lam

        fx = tf.constant(np.linspace(-1. / (2. * self.ps), 1. / (2. * self.ps),
                                     self.samples[1]),
                         dtype=tf.float32)
        fy = tf.constant(np.linspace(-1. / (2. * self.ps), 1. / (2. * self.ps),
                                     self.samples[0]),
                         dtype=tf.float32)
        self.Fx, self.Fy = tf.meshgrid(fx, fy)
        self.field_list = tf.constant(np.array((0., 0.)).astype('float32'))
        M = 6
        self.corr_pad_frac = 0
        self.target_res = target_res * M  # micron
        #         sig = 2*self.target_res/(2.355) * 1e-3
        #         real_target = tf.exp(-(tf.square(self.xgm) + tf.square(self.ygm))/(2*tf.square(sig)))
        #         real_target = pad_frac_tf(real_target / tf.reduce_max(real_target), self.corr_pad_frac)
        #         self.target_F = tf.abs(tf.fft2d(tf.complex(tf_fftshift(real_target), 0.)))

        D = 1.22 * self.lam / (tf.sin(2 * tf.atan(self.target_res /
                                                  (2 * self.t)))
                               )  #0.514 for half_max, 1.22 for first zero.
        x_airy = self.k * D * tf.sin(tf.atan(self.xgm / self.t)) / 2
        y_airy = self.k * D * tf.sin(tf.atan(self.ygm / self.t)) / 2
        #Xa, Ya = tf.meshgrid(x_airy, y_airy)
        Ra = tf.sqrt(tf.square(x_airy) + tf.square(y_airy))

        #         self.target_airy=((2*scsp.j1(x_airy)/x_airy)**2) *((2*scsp.j1(y_airy)/y_airy)**2)
        target_airy = (2 * scsp.j1(Ra) / Ra)**2
        self.target_airy = target_airy / tf.sqrt(
            tf.reduce_sum(tf.square(target_airy)))
        self.target_airy_pad = pad_frac_tf(self.target_airy,
                                           self.corr_pad_frac)

        sig_aprox = 0.42 * self.lam * self.t / D
        self.airy_aprox_target = tf.exp(
            -(tf.square(self.xgm) + tf.square(self.ygm)) /
            (2 * tf.square(sig_aprox)))

        self.airy_aprox_pad = pad_frac_tf(
            self.airy_aprox_target / tf.reduce_max(self.airy_aprox_target),
            self.corr_pad_frac)

        if target_option == 'airy':
            self.target_F = tf.square(
                tf.abs(
                    tf.signal.fft2d(
                        tf.complex(tf_fftshift(self.target_airy_pad), 0.))))
        elif target_option == 'gaussian':
            self.target_F = tf.abs(
                tf.signal.fft2d(
                    tf.complex(tf_fftshift(self.airy_aprox_pad), 0.)))

        # Set regularization. Problem will be treated as l1 of spectral error at each depth + tau * l_inf(cross_corr)
        self.cross_corr_norm = cross_corr_norm
        self.logsumexp_param = tf.constant(
            logsumparam, tf.float32
        )  #lower is better l-infinity approximation, higher is worse but smoother
        self.tau = tf.constant(
            30, tf.float32)  #Extra weight for cross correlation terms

        self.ignore_dc = True  #Ignore DC in autocorrelations when computing frequency domain loss
        dc_mask = np.ones_like(
            self.target_F.numpy()
        )  #Mask for DC. Set to zero anywhere we want to ignore loss computation of power spectrum
        dc_mask[:3, :3] = 0
        dc_mask[-2:, :1] = 0
        dc_mask[:1, -2:] = 0
        dc_mask[-2:, -2:] = 0
        dc_mask = dc_mask * self.target_F.numpy() > (
            .001 * np.max(self.target_F.numpy()))
        self.dc_mask = tf.constant(dc_mask, tf.float32)

        # Use Zernike aberrations with random initialization
        # Zernike
        self.zernikes = zernikes
        self.numzern = len(zernikes)

        if aberrations == True:
            zern_init = []
            for i in range(self.Nlenslets):
                aberrations = np.zeros(self.numzern)
                zern_init.append(aberrations)

            self.zernlist = tf.Variable(zern_init,
                                        dtype='float32',
                                        name='zernlist')
        else:
            self.zernlist = 0
 def airy(r, sigma):
     from scipy.special import j1
     r = r / sigma * np.sqrt(2)
     a = (2 * j1(r) / r)**2
     a[r == 0] = 1
     return a
Example #59
0
def hqwe(zsrc, zrec, lsrc, lrec, off, angle, depth, ab, etaH, etaV, zetaH,
         zetaV, xdirect, qweargs, use_spline, use_ne_eval, msrc, mrec):
    """Hankel Transform using Quadrature-With-Extrapolation.

    *Quadrature-With-Extrapolation* was introduced to geophysics by
    [Key_2012]_. It is one of many so-called *ISE* methods to solve Hankel
    Transforms, where *ISE* stands for Integration, Summation, and
    Extrapolation.

    Following [Key_2012]_, but without going into the mathematical details
    here, the QWE method rewrites the Hankel transform of the form

    .. math:: F(r)   = \int^\infty_0 f(\lambda)J_v(\lambda r)\
            \mathrm{d}\lambda

    as a quadrature sum which form is similar to the FHT (equation 15),

    .. math::   F_i   \\approx \sum^m_{j=1} f(x_j/r)w_j g(x_j) =
                \sum^m_{j=1} f(x_j/r)\hat{g}(x_j) \ ,

    but with various bells and whistles applied (using the so-called Shanks
    transformation in the form of a routine called :math:`\epsilon`-algorithm
    ([Shanks_1955]_, [Wynn_1956]_; implemented with algorithms from
    [Trefethen_2000]_ and [Weniger_1989]_).

    This function is based on `get_CSEM1D_FD_QWE.m`, `qwe.m`, and
    `getBesselWeights.m` from the source code distributed with [Key_2012]_.

    In the spline-version, `hqwe` checks how steep the decay of the
    wavenumber-domain result is, and calls QUAD for the very steep interval,
    for which QWE is not suited.

    The function is called from one of the modelling routines in :mod:`model`.
    Consult these modelling routines for a description of the input and output
    parameters.

    Returns
    -------
    fEM : array
        Returns frequency-domain EM response.

    kcount : int
        Kernel count.

    conv : bool
        If true, QWE/QUAD converged. If not, <htarg> might have to be adjusted.

    """
    # Input params have an additional dimension for frequency, reduce here
    etaH = etaH[0, :]
    etaV = etaV[0, :]
    zetaH = zetaH[0, :]
    zetaV = zetaV[0, :]

    # Get rtol, atol, nquad, maxint, and pts_per_dec
    rtol, atol, nquad, maxint, pts_per_dec = qweargs[:5]

    # 1. PRE-COMPUTE THE BESSEL FUNCTIONS
    # at fixed quadrature points for each interval and multiply by the
    # corresponding Gauss quadrature weights

    # Get Gauss quadrature weights
    g_x, g_w = special.p_roots(nquad)

    # Compute n zeros of the Bessel function of the first kind of order 1 using
    # the Newton-Raphson method, which is fast enough for our purposes.  Could
    # be done with a loop for (but it is slower):
    # b_zero[i] = optimize.newton(special.j1, b_zero[i])

    # Initial guess using asymptotic zeros
    b_zero = np.pi*np.arange(1.25, maxint+1)

    # Newton-Raphson iterations
    for i in range(10):   # 10 is more than enough, usually stops in 5

        # Evaluate
        b_x0 = special.j1(b_zero)     # j0 and j1 have faster versions
        b_x1 = special.jv(2, b_zero)  # j2 does not have a faster version

        # The step length
        b_h = -b_x0/(b_x0/b_zero - b_x1)

        # Take the step
        b_zero += b_h

        # Check for convergence
        if all(np.abs(b_h) < 8*np.finfo(float).eps*b_zero):
            break

    # 2. COMPUTE THE QUADRATURE INTERVALS AND BESSEL FUNCTION WEIGHTS

    # Lower limit of integrand, a small but non-zero value
    xint = np.concatenate((np.array([1e-20]), b_zero))

    # Assemble the output arrays
    dx = np.repeat(np.diff(xint)/2, nquad)
    Bx = dx*(np.tile(g_x, maxint) + 1) + np.repeat(xint[:-1], nquad)
    BJ0 = special.j0(Bx)*np.tile(g_w, maxint)
    BJ1 = special.j1(Bx)*np.tile(g_w, maxint)

    # 3. START QWE

    # Intervals and lambdas for all offset
    intervals = xint/off[:, None]
    lambd = Bx/off[:, None]

    # Angle dependent factors
    factAng = kernel.angle_factor(angle, ab, msrc, mrec)

    # Call and return QWE, depending if spline or not
    if use_spline:  # If spline, we calculate all kernels here
        # New lambda, from min to max required lambda with pts_per_dec
        start = np.log10(lambd.min())
        stop = np.log10(lambd.max())
        ilambd = np.logspace(start, stop, (stop-start)*pts_per_dec + 1)

        # Call the kernel
        PJ0, PJ1, PJ0b = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth,
                                           etaH[None, :], etaV[None, :],
                                           zetaH[None, :], zetaV[None, :],
                                           np.atleast_2d(ilambd), ab, xdirect,
                                           msrc, mrec, use_ne_eval)

        # Interpolation : Has to be done separately on each PJ,
        # in order to work with multiple offsets which have different angles.
        sPJ0r = iuSpline(np.log10(ilambd), PJ0.real)
        sPJ0i = iuSpline(np.log10(ilambd), PJ0.imag)
        sPJ1r = iuSpline(np.log10(ilambd), PJ1.real)
        sPJ1i = iuSpline(np.log10(ilambd), PJ1.imag)
        sPJ0br = iuSpline(np.log10(ilambd), PJ0b.real)
        sPJ0bi = iuSpline(np.log10(ilambd), PJ0b.imag)

        # Get quadargs: diff_quad, a, b, limit
        diff_quad, a, b, limit = qweargs[5:]

        # Set quadargs if not given:
        if not limit:
            limit = maxint
        if not a:
            a = intervals[:, 0]
        else:
            a = a*np.ones(off.shape)
        if not b:
            b = intervals[:, -1]
        else:
            b = b*np.ones(off.shape)

        # Check if we use QWE or SciPy's QUAD
        # If there are any steep decays within an interval we have to use QUAD,
        # as QWE is not designed for these intervals.
        check0 = np.log10(intervals[:, :-1])
        check1 = np.log10(intervals[:, 1:])
        doqwe = np.all((np.abs(sPJ0r(check0) + 1j*sPJ0i(check0) +
                        sPJ1r(check0) + 1j*sPJ1i(check0) +
                        sPJ0br(check0) + 1j*sPJ0bi(check0)) /
                        np.abs(sPJ0r(check1) + 1j*sPJ0i(check1) +
                        sPJ1r(check1) + 1j*sPJ1i(check1) +
                        sPJ0br(check1) + 1j*sPJ0bi(check1)) < diff_quad), 1)

        # Pre-allocate output array
        fEM = np.zeros(off.size, dtype=complex)
        conv = True

        # Carry out SciPy's Quad if required
        if np.any(~doqwe):

            # Loop over offsets that require Quad
            for i in np.where(~doqwe)[0]:

                # Input-dictionary for quad
                iinp = {'a': a[i], 'b': b[i], 'epsabs': atol, 'epsrel': rtol,
                        'limit': limit}

                fEM[i], tc = quad(sPJ0r, sPJ0i, sPJ1r, sPJ1i, sPJ0br, sPJ0bi,
                                  ab, off[i], factAng[i], iinp)

                # Update conv
                conv *= tc

            # Return kcount=1 in case no QWE is calculated
            kcount = 1

        if np.any(doqwe):
            # Get EM-field at required offsets
            sPJ0 = sPJ0r(np.log10(lambd)) + 1j*sPJ0i(np.log10(lambd))
            sPJ1 = sPJ1r(np.log10(lambd)) + 1j*sPJ1i(np.log10(lambd))
            sPJ0b = sPJ0br(np.log10(lambd)) + 1j*sPJ0bi(np.log10(lambd))

            # Carry out and return the Hankel transform for this interval
            sEM = np.sum(np.reshape(sPJ1*BJ1, (off.size, nquad, -1),
                         order='F'), 1)
            if ab in [11, 12, 21, 22, 14, 24, 15, 25]:  # Because of J2
                # J2(kr) = 2/(kr)*J1(kr) - J0(kr)
                sEM /= np.atleast_1d(off[:, np.newaxis])
            sEM += np.sum(np.reshape(sPJ0b*BJ0, (off.size, nquad, -1),
                                     order='F'), 1)
            sEM *= factAng[:, np.newaxis]
            sEM += np.sum(np.reshape(sPJ0*BJ0, (off.size, nquad, -1),
                                     order='F'), 1)

            getkernel = sEM[doqwe, :]

            # Get QWE
            fEM[doqwe], kcount, tc = qwe(rtol, atol, maxint, getkernel,
                                         intervals[doqwe, :], None, None, None)
            conv *= tc

    else:  # If not spline, we define the wavenumber-kernel here
        def getkernel(i, inplambd, inpoff, inpfang):
            """Return wavenumber-domain-kernel as a fct of interval i."""

            # Indices and factor for this interval
            iB = i*nquad + np.arange(nquad)

            # PJ0 and PJ1 for this interval
            PJ0, PJ1, PJ0b = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth,
                                               etaH[None, :], etaV[None, :],
                                               zetaH[None, :], zetaV[None, :],
                                               np.atleast_2d(inplambd)[:, iB],
                                               ab, xdirect, msrc, mrec,
                                               use_ne_eval)

            # Carry out and return the Hankel transform for this interval
            gEM = inpfang*np.dot(PJ1[0, :], BJ1[iB])
            if ab in [11, 12, 21, 22, 14, 24, 15, 25]:  # Because of J2
                # J2(kr) = 2/(kr)*J1(kr) - J0(kr)
                gEM /= np.atleast_1d(inpoff)
            gEM += inpfang*np.dot(PJ0b[0, :], BJ0[iB])
            gEM += np.dot(PJ0[0, :], BJ0[iB])

            return gEM

        # Get QWE
        fEM, kcount, conv = qwe(rtol, atol, maxint, getkernel, intervals,
                                lambd, off, factAng)

    return fEM, kcount, conv
from scipy import special, r_, optimize
import pylab as plt

x = r_[2:7.1:.1]
j1x = special.j1(x)
plt.plot(x, j1x, '-')
plt.hold('on')
x_min = optimize.fminbound(special.j1, 4, 7)
plt.plot([x_min], [special.j1(x_min)], 'ro')
plt.hold('off')
plt.show()