B
    dd                 @   sT  d dl mZ d dlmZ d dlZd dlmZ d dlmZm	Z	 dd Z
dd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZeeeeedZd>ddZdd Zd d! Zd?d#d$Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Z d5d6 Z!d7d8 Z"d9d: Z#d;d< Z$eee e e!e!e ee e e e e e e#e"e!e!e$e$e$d=Z%dS )@    )division)sqrtN)uniform)PIMTSUN_SIc             C   s   ddt |  d   S )z}
    A0 is a conversion factor between tau0 and mchirp, defined in eqn
    B3 of the appendix of arxiv.org/abs/0706.4437
    g      @   gUUUUUU@)r   )flow r	   g/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/lalinspiral/sbank/tau0tau3.pyA0   s    r   c             C   s   t dt |  d   S )z}
    A3 is a conversion factor between tau3 and tau0*M, defined in eqn
    B3 of the appendix of arxiv.org/abs/0706.4437
       g?)r   )r   r	   r	   r
   A3&   s    r   c             C   sX   ddt  t  |  ||   }t||  |d  }|t }|dd| d   }||| fS )z=
    Convert tau0-tau3 coordinates to m1-m2 coordinates.
    g      @    gg      ?g      ?)r   r   r   )tau0tau3r   mtotaletam1r	   r	   r
   tau0tau3_to_m1m2-   s
    r   c       	      C   sX   | t  }|t  }|| }|| ||  }t|| |d  }t|| |d  }||fS )z=
    Convert m1-m2 coordinates to tau0-tau3 coordinates.
    ggUUUUUU)r   r   r   )	r   m2r   Zm1_sZm2_sr   r   r   r   r	   r	   r
   m1m2_to_tau0tau3;   s    r   c       
         sT  ddddddddg  fd	d
|   D }t|rDtdd| | dd\}}|dksd|dkrltd| dd\dkr|dkr|f| d< | dd\}}|dks|| k r| }|dks| |k r| }| dd\}}|dks|| k rt| d}|dk r0td|dksRt||  |k rdt||  }||f| d< | dd\}}	|dkrtfdd||fD }|	dkrtfdd||fD }	||	f| d< ||d| d | d  k r|d| d | d  }||	d| d | d  krD|	d| d | d  }||f| d< | S )a  
    Check that the constraints dict does not containt unknown
    constraints. Check that required constraints are given. To define
    a 2D parameter space, one needs at least three and possibly four
    points of intersection. This function preps the constraint dict so
    that it defines a bounded region (if possible) or crashes (if
    not). By convention, we require mass1 limits to be set.
    mass1mass2mratior   mchirpspin1spin2durationc                s   g | ]}| kr|qS r	   r	   ).0k)known_constraintsr	   r
   
<listcomp>^   s    z+set_default_constraints.<locals>.<listcomp>zunknown constraints %sz, )NNNz,Must specify both minimum and maximum mass1.   z)We use the convention that q = m1/m2 > 1.c             3   s&   | ]} fD ]}t ||V  qqd S )N)m1m2_to_mchirp)r   r   r   )	mass2_max	mass2_minr	   r
   	<genexpr>   s    z*set_default_constraints.<locals>.<genexpr>c             3   s&   | ]} fD ]}t ||V  qqd S )N)r#   )r   r   r   )r$   r%   r	   r
   r&      s       g333333?)keyslen
ValueErrorjoin
setdefaultmaxmin)
constraintsZunknown_constraints	mass1_min	mass1_max
mtotal_min
mtotal_maxqminqmaxmcminmcmaxr	   )r    r$   r%   r
   set_default_constraintsR   sN    



"

r8   c             C   s   | | S )Nr	   )r   r   r	   r	   r
   m1m2_to_mratio   s    r9   c             C   s   | S )Nr	   )r   r   r	   r	   r
   
m1m2_to_m1   s    r:   c             C   s   |S )Nr	   )r   r   r	   r	   r
   
m1m2_to_m2   s    r;   c             C   s   | | S )Nr	   )r   r   r	   r	   r
   m1m2_to_mtotal   s    r<   c             C   s$   | |  |  | | | | |  d S )Ng?r	   )r   r   r	   r	   r
   r#      s    r#   )r   r   r   r   r   绽|=c       	      C   s   x|  D ]}|| \}}|dkr,|dkr,q
t| | |}|dkrP||| k}n.|dkrf|| |k}n|| |k||| k }| | } || }q
W | |fS )zt
    Return those values of m1,m2 from the input arrays
    that are consistent with the specified constraints.
    N)r(   m1m2_mappings)	r   r   Zm1m2_constraintstolparamZmnZmxparamsincluder	   r	   r
   allowed_m1m2   s    rC   c             C   s@   d|  ddd|  d   }d|  ddd|  d   }||fS )Ng      ?g      ?g      @r	   )Zm_totalr   r   r   r	   r	   r
   mtotal_eta_to_mass1_mass2   s    rD   c             C   s   | |d  }t ||S )Ng333333?)rD   )Zm_chirpr   Mr	   r	   r
   mchirp_eta_to_mass1_mass2   s    rF   ư>c                s~   | d  |d  }|| }t dd||g} fdd|D }t|dkrTtd}n&t|dkrj|d }ntd| |f |S )	N      r"   r   c                s*   g | ]"}t |j k r|jd kr|jqS )r   )absimagreal)r   r)r?   r	   r
   r!      s    z"mchirpm1_to_m2.<locals>.<listcomp>nanz<No unique real solution for m2 found for mchirp=%f and m1=%f)numpyrootsr)   floatr*   )Zmcr   r?   pqrtsr   r	   )r?   r
   mchirpm1_to_m2   s    

rU   c                sB  t |}d}|d \ |d \fddt |D }|fddt |D 7 }|fddt|D 7 }| fddt|D 7 }xP|d	 D ]D|fd
dt |D 7 }|fddt|D 7 }qW xP|d D ]D|fddt |D 7 }|fddt|D 7 }qW |dd\|d \}}||d d  }||d d  }dk	rt|\}}	t|\}
}| kr }|
k r}
|	k rЈ}	|krވ}|fddt|
||D 7 }|fddt|	||D 7 }dk	rt|\}}t|\}}| krR }|k r`}|k rn}|kr|}|fddt|||D 7 }|fddt|||D 7 }tdd |D }tdd |D }t|||\}}t|dkr
tdt	||| \}}t
|t|g}t
|t|g}||fS )a  
    For a given set of constraints on the m1-m2 parameter space,
    this function returns the corners of a box which bounds the
    same region (tightly) above and below in tau0-tau3 space.

    Supported constraints: mass1, mass2, mtotal, mratio, mchirp
    g     @r   r   c                s   g | ]}| fqS r	   r	   )r   r   )m2minr	   r
   r!      s    z"tau0tau3_bound.<locals>.<listcomp>c                s   g | ]}| fqS r	   r	   )r   r   )m2maxr	   r
   r!      s    c                s   g | ]} |fqS r	   r	   )r   r   )m1minr	   r
   r!      s    c                s   g | ]} |fqS r	   r	   )r   r   )m1maxr	   r
   r!      s    r   c                s   g | ]}| | fqS r	   r	   )r   r   )valr	   r
   r!     s    c                s   g | ]} | |fqS r	   r	   )r   r   )rZ   r	   r
   r!     s    r   c                s   g | ]}||  fqS r	   r	   )r   r   )rZ   r	   r
   r!     s    c                s   g | ]} | |fqS r	   r	   )r   r   )rZ   r	   r
   r!   	  s    r   )NNg      ?r'   Nc                s   g | ]}|t  |fqS r	   )rU   )r   r   )r7   r	   r
   r!   "  s    c                s   g | ]}t  ||fqS r	   )rU   )r   r   )r7   r	   r
   r!   #  s    c                s   g | ]}|t  |fqS r	   )rU   )r   r   )r6   r	   r
   r!   0  s    c                s   g | ]}t  ||fqS r	   )rU   )r   r   )r7   r	   r
   r!   1  s    c             S   s   g | ]}|d  qS )r   r	   )r   ir	   r	   r
   r!   4  s    c             S   s   g | ]}|d  qS )r"   r	   )r   r[   r	   r	   r
   r!   5  s    r   z'The requested parameter space is empty.)r8   rO   Zlinspacer,   rF   arrayrC   r)   r*   r   r.   r-   )r   r/   ZnptsZm1m2_pointsZmrminZmrmaxZetaminZetamaxZmcmax_maxm1Zmcmax_minm2Zmcmax_minm1Zmcmax_maxm2Zmcmin_maxm1Zmcmin_minm2Zmcmin_minm1Zmcmin_maxm2r   r   	lims_tau0	lims_tau3r	   )rY   rX   rW   rV   r7   r6   rZ   r
   tau0tau3_bound   sj        $ $




  




  r_   c             c   sZ   | d| | d  d  }| | d d| | d   }d}x|t dd| |  V  q:W dS )z
    This is a generator for random total mass values corresponding to a
    uniform distribution of mass pairs in (tau0, tau3) space.  See also
    urand_eta_generator(), and see LIGO-T1300127 for details.
    r"   g@g۶m۶mۿr   N)r   )r2   r3   alphabetanr	   r	   r
   urand_mtotal_generatorC  s
    rc   c             c   sV   | t d| | d   }| | d d| | d   }x|t tdd|  V  q6W dS )z
    This is a generator for random eta (symmetric mass ratio) values
    corresponding to a uniform distribution of mass pairs in (tau0, tau3)
    space.  See also urand_mtotal_generator(), and see LIGO-T1300127 for
    details.
    r"   r'   r   N)r   r   )Zeta_minZeta_maxr`   ra   r	   r	   r
   urand_eta_generatorP  s    rd   c             k   sX  t |}t| f|\}}|\}}|\}}|d \}}	|d \}
}|d \}}|d \}}t| }t| }|| }ddlm} d}x|||}|||| | }|| ||  }|dkrq|t }|d	td|   }|| }||  k r|k rn q||  kr
|	krn q|
|  kr$|krn q|||   k rB|k rn q||fV  qW d
S )a_  
    This is a generator for random (m1, m2) pairs that are uniformly
    distributed in (tau0, tau3) space, subject to the constraints given in
    the inputs.

    @param flow UNDOCUMENTED
    @param constraints: must specify a mass1 range; mtotal, q, and tau0
    ranges are optional. The arguments for each of these keywords should be a
    tuple of (min, max). E.g., mtotal = (50, 100) constrains
    50 <= mtotal < 100.

    Example:
    >>> urand_tau0tau3 = urand_tau0tau3_generator(40, mass1 = (1, 99), mtotal = (55, 100), mratio = (1, 10))
    >>> urand_tau0tau3.next()
    (49.836271184652254, 6.6152675269639829)
    >>> urand_tau0tau3.next()
    (46.701700599815645, 14.07462196069671)

    Equivalently, use a dictionary with **:
    >>> urand_tau0tau3 = urand_tau0tau3_generator(40, **{"mass1": (1, 99), "mtotal": (55, 100), "mratio": (1, 10)})
    r   r   r   r   r   )r   gg      ?g      ?N)r8   r_   r   r   numpy.random.mtrandr   r   r   )r   r/   r]   r^   Ztau0_minZtau0_maxZtau3_minZtau3_maxr0   r1   r%   r$   r2   r3   r4   r5   Z_A0Z_A3ZA0_A3r   Zminus_five_thirdsr   mtotr   r   r   r	   r	   r
   urand_tau0tau3_generator]  s6    
 rg   c             k   sV   | dr|d | dr(|d x(t| f|D ]\}}||||dV  q6W dS )zb
    Wrapper for urand_tau0tau3_generator() to remove spin options
    for EOBNRv2 waveforms.
    r   r   )bankN)has_keypoprg   )r   tmplt_classrh   r/   r   r   r	   r	   r
   nonspin_param_generator  s    



rl   c             k   s   | dd\}}| d td td|td|f}td|td|f}xt| f|D ]\}}	t||	 |	| }
d	|
  k rd
krn nt| }t| }n2d|
  krd	krn nt| }t| }ntd|||	|||dV  qXW dS )a~  
    Specify the min and max mass of the bigger component, then
    the min and max mass of the total mass. This function includes
    restrictions on q and chi based on IMRPhenomB's range of believability.
    Ref: http://arxiv.org/pdf/0908.2090

    @param flow: Lower frequency at which to generate waveform
    @param tmplt_class: Template generation class for this waveform
    @param bank: sbank bank object
    @param kwargs: must specify a component_mass range; mtotal, q, chi, and tau0
    ranges are optional. If no chi is specified, the IMRPhenomB limits will be used.
    See urand_tau0tau3_generator for more usage help.
    r   )g      g      ?r   zNPhenomB: spin2 limits not implemented. Using spin1 limits for both components.g333333g333333?g      g      ?   
   r"   zmass ratio out of range)rh   N)rj   Warningr-   r.   rg   r   r*   )r   rk   rh   kwargsZsminZsmaxZchi_low_boundsZchi_high_boundsr   r   rS   r   r   r	   r	   r
   IMRPhenomB_param_generator  s    


rq   c             k   s   | dd\}}| d||f\}}td|td| }}td|td| }}xdt| f|D ]T\}}	t||	 |	| }
|
dkrt||}t||}ntd|||	|||dV  q^W d	S )
au  
    Generate random parameters for the IMRPhenomC waveform model.
    Specify the min and max mass of the bigger component, then the min
    and max mass of the total mass. This function includes
    restrictions on q and chi based on IMRPhenomC's range of
    believability, namely q <=20 and |chi| <= 0.9.

    @param flow: low frequency cutoff
    @param tmplt_class: Template generation class for this waveform
    @param bank: sbank bank object
    @param kwargs: constraints on waveform parameters. See urand_tau0tau3_generator for more usage help. If no spin limits are specified, the IMRPhenomC limits will be used.
    r   )gg?r   gg?   zmass ratio out of range)rh   N)rj   r-   r.   rg   r   r*   )r   rk   rh   rp   Zs1minZs1maxs2mins2maxr   r   rS   r   r   r	   r	   r
   IMRPhenomC_param_generator  s    
ru   c             +   s  | dd\}}d|krXd|krXd|krX| d | d| d fdd}n&| dd	| d
d	fdd}xt| f|D ]\}}|||\}	}
|| }||	d  ||
d   | }||	d  ||
d   | }t||}t|
d || ||	d   | }t|
d || ||	d   | }t||}|| ||  | }||||||d}|dk	rx|j|k s|dk	r|j|krq|V  qW dS )z
    Specify the min and max mass of the bigger component, the min and
    max mass of the total mass and the min and max values for the
    z-axis spin angular momentum.
    r   )NNZns_bh_boundary_massZbh_spinZns_spinc                s    | kr n|kr nfS )Nr	   )r   r   )bh_spin_boundsns_bh_boundaryns_spin_boundsr	   r
   spin_bounds  s    z1aligned_spin_param_generator.<locals>.spin_boundsr   )g      g      ?r   c                s    fS )Nr	   )r   r   )spin1bspin2br	   r
   ry     s    r   r"   )rh   N)rj   rg   r   r-   r.   Zdur)r   rk   rh   rp   Zdur_minZdur_maxry   r   r   spin1_boundsspin2_boundsrf   Zchis_minZchis_maxZchisrs   rt   r   r   tr	   )rv   rw   rx   rz   r{   r
   aligned_spin_param_generator  s2    



""
r   c             k   sl  | dd}| dd}xLt| f|D ]:\}}t| }t| }	tdtj}
tddtj }tdtj}tddtj }|t|
 }|t|
 t| }|t|
 t| }|	t| }|	t| t| }|	t| t| }tdtj}tddtj }tddtj }tdtj}tddtj }|||||||||||||||dV  q(W dS )zB
    Currently a stub to test precessing template generation.
    r   )g        g?r   r   r'   )rh   N)rj   rg   r   rO   picossin)r   rk   rh   rp   r|   r}   r   r   spin1magZspin2mag	spin1ang1	spin1ang2Z	spin2ang1Z	spin2ang2spin1zspin1xspin1yZspin2zZspin2xZspin2ythetaphipsiiota	orb_phaser	   r	   r
   &double_spin_precessing_param_generator$  s,    r   c             k   s   | dd}| dd}xt| f|D ]\}}t| }tdtj}	tddtj }
|t|	 }|t|	 t|
 }|t|	 t|
 }tdtj}tddtj }tddtj }tdtj}|||||||||||d
V  q&W dS )zB
    Currently a stub to test precessing template generation.
    r   )g        g?r   r   r'   )rh   N)rj   rg   r   rO   r   r   r   )r   rk   rh   rp   r|   r}   r   r   r   r   r   r   r   r   r   r   r   r   r	   r	   r
   &single_spin_precessing_param_generatorB  s    r   c             K   s   t d S )N)NotImplementedError)r   rk   rh   rp   r	   r	   r
   SpinTaylorT4_param_generator[  s    r   c             k   s   | dr|d | dr(|d xt| f|D ]t\}}tdtj}tddtj }tddtj }tdtj}	tddtj }
|||dddddd|||	||
|V  q6W dS )zb
    Wrapper for urand_tau0tau3_generator() to remove spin options
    for EOBNRv2 waveforms.
    r   r   r   r'   N)ri   rj   rg   r   rO   r   )r   rk   rh   r/   r   r   r   r   r   r   r   r	   r	   r
   nonspin_hom_param_generator`  s    



r   )Z
IMRPhenomBZ
IMRPhenomCZ
IMRPhenomDZTaylorF2Z
IMRPhenomPZIMRPhenomPv2ZTaylorF2RedSpinZEOBNRv2ZSEOBNRv1ZSEOBNRv2ZSEOBNRv2_ROM_DoubleSpinZSEOBNRv2_ROM_DoubleSpin_HIZSEOBNRv4ZSEOBNRv4_ROMZSpinTaylorT4ZSpinTaylorF2ZSpinTaylorT5FourierZSEOBNRv3ZEOBNRv2HM_ROMZEOBNRv2HM_ROM_AmpMaxZEOBNRv2HM_ROM_PhaseMax)r=   )rG   )&
__future__r   mathr   rO   re   r   Zlalr   r   r   r   r   r   r8   r9   r:   r;   r<   r#   r>   rC   rD   rF   rU   r_   rc   rd   rg   rl   rq   ru   r   r   r   r   r   Z	proposalsr	   r	   r	   r
   <module>   sp   B

aA)!/