Example #1
0
def ln_prior_base(pars):

    lnp = 0.0

    #Wd flux
    prior = Prior('uniform',0.001,2)
    lnp += prior.ln_prob(pars[0])

    #Disc flux
    prior = Prior('uniform',0.001,2)
    lnp += prior.ln_prob(pars[1])

    #BS flux
    prior = Prior('uniform',0.001,2)
    lnp += prior.ln_prob(pars[2])

    #Donor flux
    prior = Prior('uniform',0.0,2)
    lnp += prior.ln_prob(pars[3])

    #Mass ratio
    prior = Prior('uniform',0.001,3.5)
    lnp += prior.ln_prob(pars[4])

    #Wd eclipse width, dphi
    tol = 1.0e-6
    try:
        maxphi = roche.findphi(pars[4],90.0) #dphi when i is slightly less than 90
        prior = Prior('uniform',0.001,maxphi-tol)
        lnp += prior.ln_prob(pars[5])
    except:
        # we get here when roche.findphi raises error - usually invalid q
        lnp += -np.inf

    #Disc radius (XL1) 
    try:
        xl1 = roche.xl1(pars[4]) # xl1/a
        prior = Prior('uniform',0.25,0.46/xl1) # maximum size disc can be without precessing
        lnp += prior.ln_prob(pars[6])
    except:
        # we get here when roche.findphi raises error - usually invalid q
        lnp += -np.inf
    
    #Limb darkening
    prior = Prior('gauss',0.39,0.005)
    lnp += prior.ln_prob(pars[7])

    #Wd radius (XL1)
    prior = Prior('uniform',0.0001,0.1)
    lnp += prior.ln_prob(pars[8])

    #BS scale (XL1)
    rwd = pars[8]
    prior = Prior('log_uniform',rwd/3.,rwd*3.)
    lnp += prior.ln_prob(pars[9])

    #BS az
    slop=40.0

    try:
        # find position of bright spot where it hits disc
        # will fail if q invalid
        xl1 = roche.xl1(pars[4]) # xl1/a
        rd_a = pars[6]*xl1

        # Does stream miss disc? (disc/a < 0.2 or > 0.65 )
        # if so, Tom's code will fail
        x,y,vx,vy = roche.bspot(pars[4],rd_a)
            
        # find tangent to disc at this point
        alpha = np.degrees(np.arctan2(y,x))
            
        # alpha is between -90 and 90. if negative spot lags disc ie alpha > 90
        if alpha < 0: alpha = 90-alpha
        tangent = alpha + 90 # disc tangent
    
        prior = Prior('uniform',max(0,tangent-slop),min(178,tangent+slop))
        lnp += prior.ln_prob(pars[10])
    except:
        lnp += -np.inf
        
    #BS isotropic fraction
    prior = Prior('uniform',0.001,0.9)
    lnp += prior.ln_prob(pars[11])
    
    #Disc exponent
    prior = Prior('uniform',0.0001,2.5)
    lnp += prior.ln_prob(pars[12])

    #Phase offset
    prior = Prior('uniform',-0.1,0.1)
    lnp += prior.ln_prob(pars[13])

    if len(pars) > 14:
        #BS exp1
        prior = Prior('uniform',0.01,4.0)
        lnp += prior.ln_prob(pars[14])

        #BS exp2
        prior = Prior('uniform',0.9,3.0)
        lnp += prior.ln_prob(pars[15])

        #BS tilt angle
        prior = Prior('uniform',0.0,165.0)
        lnp += prior.ln_prob(pars[16])

        #BS yaw angle
        prior = Prior('uniform',-90,90.0)
        lnp += prior.ln_prob(pars[17])
    return lnp
    def ln_prior(self,verbose=False):
        """Returns the natural log of the prior probability of this model.
        
        Certain parameters (dphi, rdisc, scale, az) need to be treated as special cases,
        as the model contains more prior information than included in the parameter priors"""
        
        # Use of the super function allows abstract class in model.py to be referenced
        # Here the ln_prior function is referenced
        retVal = super(LCModel,self).ln_prior()
        
        # Remaining part of this function deals with special cases
        # dphi
        tol = 1.0e-6
        try:
            # Uses getParam function from model.py to get the objects of variable parameters
            q = self.getParam('q')
            dphi = self.getParam('dphi')
            # maxphi is dphi when i = 90
            maxphi = roche.findphi(q.currVal,90.0)
            # dphi cannot be greater than (or within a certain tolerance of) maxphi
            if dphi.currVal > maxphi-tol:
                if verbose:
                    print('Combination of q and dphi is invalid')
                retVal += -np.inf
            
        except:
            # We get here when roche.findphi raises error - usually invalid q
            retVal += -np.inf
            if verbose:
                print('Combination of q and dphi is invalid')
        
        # rdisc 
        try:
            xl1 = roche.xl1(q.currVal) # xl1/a
            maxrdisc = 0.46/xl1 # Maximum size disc can reach before precessing
            # rdisc is unique to each eclipse, so have to use slightly different method to 
            # obtain its object, compared to q and dphi which are shared parameters
            rdiscTemplate = 'rdisc_{0}'
            for iecl in range(self.necl):
                rdisc = self.getParam(rdiscTemplate.format(iecl))
                # rdisc cannot be greater than maxrdisc
                if rdisc.currVal > maxrdisc:
                    retVal += -np.inf
                
        except:
            # We get here when roche.findphi raises error - usually invalid q
            if verbose:
                print('Rdisc and q imply disc does not hit stream')
            retVal += -np.inf
        
        #BS scale
        rwd = self.getParam('rwd')
        minscale = rwd.currVal/3 # Minimum BS scale equal to 1/3 of rwd
        maxscale = rwd.currVal*3 # Maximum BS scale equal to 3x rwd
        scaleTemplate = 'scale_{0}'
        for iecl in range(self.necl):
            scale = self.getParam(scaleTemplate.format(iecl))
            # BS scale must be within allowed range 
            if scale.currVal < minscale or scale.currVal > maxscale:
                retVal += -np.inf
                if verbose:
                    print('BS Scale is not between 1/3 and 3 times WD size')
            
        #BS az
        slope = 80.0
        try:
            # Find position of bright spot where it hits disc
            azTemplate = 'az_{0}'
            for iecl in range(self.necl):
                rdisc = self.getParam(rdiscTemplate.format(iecl))
                rd_a = rdisc.currVal*xl1 # rdisc/a
                az = self.getParam(azTemplate.format(iecl))
                # Does stream miss disc? (rdisc/a < 0.2 or rdisc/a > 0.65 )
                # If yes, Tom's code will fail
                # Calculate position of BS
                x,y,vx,vy = roche.bspot(q.currVal,rd_a)
                # Find tangent to disc at this point
                alpha = np.degrees(np.arctan2(y,x))
                # Alpha is between -90 and 90. If negative, spot lags disc (i.e. alpha > 90)
                if alpha < 0: alpha = 90 - alpha
                tangent = alpha + 90 # Disc tangent
                # Calculate minimum and maximum az values using tangent and slope
                minaz = max(0,tangent-slope)
                maxaz = min(178,tangent+slope)
                # BS az must be within allowed range
                if az.currVal < minaz or az.currVal > maxaz:
                    retVal += -np.inf

        except:
            if verbose:
                print('Stream does not hit disc, or az is outside 80 degree tolerance')
            # We get here when roche.findphi raises error - usually invalid q
            retVal += -np.inf
           
        if complex:
            # BS exponential parameters
            # Total extent of bright spot is scale*(e1/e2)**(1/e2)
            # Limit this to half an inner lagrangian distance
            scaleTemplate = 'scale_{0}'
            exp1Template = 'exp1_{0}'
            exp2Template = 'exp2_{0}'
            for iecl in range(self.necl):
                sc = self.getParam(scaleTemplate.format(iecl))
                e1 = self.getParam(exp1Template.format(iecl))
                e2 = self.getParam(exp2Template.format(iecl))
                if sc.currVal*(e1.currVal/e2.currVal)**(1.0/e2.currVal) > 0.5:
                    retVal += -np.inf
    
        return retVal
Example #3
0
xl2, yl2 = roche.lobe2(q)

## Stream
xs, ys = roche.stream(q, 1./200)

## Disc radius
xd, yd = mg.circle(drad,n=1000)

## Circularisation radius
xc, yc = mg.circle(roche.rcirc(q))

## White dwarf radius
xw, yw = mg.circle(wdrad)

## Bright spot central position
xb, yb, vxb, vyb = roche.bspot(q, brad)

## Shadow
if phase is not None:
	xsh, ysh, sh = roche.shadow(q, iangle, phase, 10000)
	xsh[np.arange(len(xsh)/2)] = xsh[np.arange(len(xsh)/2)][::-1]
	xsh[np.arange(len(xsh)/2,len(xsh))] = xsh[np.arange(len(xsh)/2,len(xsh))][::-1]
	ysh[np.arange(len(ysh)/2)] = ysh[np.arange(len(ysh)/2)][::-1]
	ysh[np.arange(len(ysh)/2,len(ysh))] = ysh[np.arange(len(ysh)/2,len(ysh))][::-1]
	shmask = xsh**2 + ysh**2 < drad**2  	# only plot points within the disc

##  Spot profile
nmax = (bexn / bexm) ** (1 / bexm)	# the number of length scales from flux=0 to flux=max
l = np.linspace(-nmax,20,500) * blen	# offset by lmax so that l=0 corresponds to flux=max
profile = spotProfile(l,blen,bexn,bexm)
halfpoints = l[profile>profile.max()/2][[0,-1]] / blen