B
    â‹d”`  ã               @   sì   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dl	mZ d dl	mZ d dlmZ d dlmZ d dlmZmZmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ G dd„ deƒZdd„ ZddgZdS )é    N)Ú	threading)Úligolw)Ú	lsctables)Úutils)Úversion)Úpnutils)Úreturn_empty_snglÚcreate_process_tableÚmake_psd_xmldocÚsnr_series_to_xml)Úgenerate_asd_plot)Ú	ifo_color)Úsource_color)Úcalc_probabilitiesc               @   s*   e Zd ZdZdd„ Zdd„ Zdd	d
„ZdS )ÚCandidateForGraceDBzJThis class provides an interface for uploading candidates to GraceDB.
    c       '   
      s0  ˆ ˆ_ |d ˆ_dˆ_| d¡r*|d ˆ_dˆ ko8ˆ d ˆ_dˆ_d|d › d}|ˆ krdˆ | ˆ_‡ fdd	„|D ƒˆ_d
|kr|d
 ‰t‡fdd„ˆD ƒƒdks¬t	dƒ‚ˆ 
¡ }‡fdd„|D ƒˆ_tt|ƒtˆjƒ ƒ}xB|D ](‰ˆˆjksöt	‚ˆjˆ  jˆj7  _qäW ndˆ_ˆj}g }t ¡ }| t ¡ ¡ t|d|dj}	t tj¡}
t d¡}t ¡ }d|_d|_||_d|_|
 |¡ |jd  |
¡ t  d¡}t tj!¡}t "¡ }||_t|ƒ|_#d $|¡|_%t &d¡|_'|	|_||_(d|_)| |¡ |jd  |¡ t tj*¡}t tj+¡}d}d}xšt,|ƒD ]Œ\}‰t-dd}t .|¡|_/|	|_ˆ|_0‡fdd	„ˆ D ƒ}xl|D ]d}ˆ dˆ› d|›  }|dkr´|ˆj7 }t1 2|¡|_3n(yt4|||ƒ W n t5k
rÚ   Y nX qzW |j6r$|j7r$t8 9|j6|j7¡\|_:|_;t8 <|j6|j7¡\|_=}|}|j>rL|j?d |j> |_@||j>d 7 }d|krrˆ|d krr|d ˆ |_A| |¡ t B¡ }d|_C||_(|j/|_/| |¡ ˆjdk	r6tDˆjˆ ||j/ƒ q6W tE F‡ fd d	„ˆjD ƒ¡ˆj ˆ_Gd! H¡ }xJ|D ]B}|j0|krøx |D ]}t4||tI||ƒƒ qW t1 2ˆjG¡|_3qøW |jd  |¡ |jd  |¡ t tjJ¡}t K¡ }d|_Ld|_MtN|ƒ|_%||_(|j=|_=|j:|_O|jP|_P|jQ|_Q|d |_>d"t1jRˆ d#   }||_S| |¡ |jd  |¡ i } x€ˆj T¡ D ]r\‰}!tU|d$ |!jV ƒ}"t1 Wd%|!jX|d$ |!jVt1jYd& t1jZ t|!ƒ|" ¡}#|! E¡ |"d… t[j\d  |#j]_]|#| ˆ< qúW t^| |ƒ d'|krd(|kr–t_d)ƒ‚t|ƒd*k s´t	d+|› d,ƒ‚|j6|j7|j`|ja|d ||ˆjd-œ}$‡fd.d„ˆjD ƒ}%|d'  b|$|%¡\ˆ_cˆ_dn2d(|kr,d|d(  |d(  ˆ_cˆ_dnd/\ˆ_cˆ_dd0|krÌd1d	„ |D ƒ}&te|j=|j>tf|&ƒ|d0 ƒˆ_gth i|d0 ¡|d2< d|d2 d3< d4|d2 d5 d6< d7|d2 d5 d8< te|j=|j>tf|&ƒ|d2 ƒd9 ˆ_jndˆ_gdˆ_jˆjcdk	rˆjgdk	r‡fd:d„ˆjg T¡ D ƒˆ_kˆjdˆjkd;< ndˆ_k|ˆ_l|j3ˆ_mdS )<a_  Initialize a representation of a zerolag candidate for upload to
        GraceDB.

        Parameters
        ----------
        coinc_ifos: list of strs
            A list of the originally triggered ifos with SNR above threshold
            for this candidate, before possible significance followups.
        ifos: list of strs
            A list of ifos which may have triggers identified in coinc_results
            for this candidate: ifos potentially contributing to significance
        coinc_results: dict of values
            A dictionary of values. The format is defined in
            `pycbc/events/coinc.py` and matches the on-disk representation in
            the hdf file for this time.
        psds: dict of FrequencySeries
            Dictionary providing PSD estimates for all detectors observing.
        low_frequency_cutoff: float
            Minimum valid frequency for the PSD estimates.
        high_frequency_cutoff: float, optional
            Maximum frequency considered for the PSD estimates. Default None.
        skyloc_data: dict of dicts, optional
            Dictionary providing SNR time series for each detector, to be used
            in sky localization with BAYESTAR. The format should be
            `skyloc_data['H1']['snr_series']`. More detectors can be present
            than in `ifos`; if so, extra detectors will only be used for sky
            localization.
        channel_names: dict of strings, optional
            Strain channel names for each detector. Will be recorded in the
            `sngl_inspiral` table.
        padata: PAstroData instance
            Organizes info relevant to the astrophysical probability of the
            candidate.
        mc_area_args: dict of dicts, optional
            Dictionary providing arguments to be used in source probability
            estimation with `pycbc/mchirp_area.py`.
        ÚpsdsNÚgracedbZHWINJr   zforeground/z/time_offsetc                s    g | ]}d |› dˆ kr|‘qS )zforeground/z	/end_time© )Ú.0Úi)Úcoinc_resultsr   úZ/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/pycbc/io/live.pyú
<listcomp>U   s    z0CandidateForGraceDB.__init__.<locals>.<listcomp>Zskyloc_datac                s   h | ]}ˆ | d  j ’qS )Ú
snr_series)Zdelta_t)r   Úifo)Úsldr   r   ú	<setcomp>Z   s    z/CandidateForGraceDB.__init__.<locals>.<setcomp>é   z!delta_t for all ifos do not matchc                s   i | ]}ˆ | d  |“qS )r   r   )r   r   )r   r   r   ú
<dictcomp>]   s    z0CandidateForGraceDB.__init__.<locals>.<dictcomp>Úpycbc)Zprogram_nameZ	detectorsZinspiralz%sngl_inspiral<-->sngl_inspiral coincsú,g        T)Znonesc                s(   g | ] }d ˆ › |kr|  d¡d ‘qS )zforeground/ú/éÿÿÿÿ)Úsplit)r   Ún)r   r   r   r   ˜   s    r!   Úend_timeg      à?g       @Zchannel_namesZsngl_inspiralc                s   g | ]}ˆ d |› d ‘qS )zforeground/z	/end_timer   )r   r   )r   r   r   r   ¾   s    zGmass1 mass2 mtotal mchirp eta spin1x spin1y spin1z spin2x spin2y spin2zg      ð?zforeground/ifarZlow_frequency_cutoffÚpsdé   ZpadataÚp_terrznBoth p_astro calculation data and a previously calculated p_terr value were provided, this doesn't make sense!é   zp_astro can't handle z coinc ifos!)Úmass1Úmass2Úspin1zÚspin2zZnetwork_snrÚfarZ	triggeredZ	sensitivec                s   i | ]}ˆ j | j|“qS r   )r   Údist)r   r   )Úselfr   r   r   ÿ   s    )NNZmc_area_argsc             S   s   g | ]
}|j ‘qS r   )Úeff_distance)r   Úsnglr   r   r   r   	  s    Zhasmassgap_argsZmass_gapg      @Z
mass_bdaryZns_maxg      @Zgap_maxzMass Gapc                s   i | ]\}}|ˆ j  |“qS r   )Úp_astro)r   ÚclÚpr)r0   r   r   r     s   ZTerrestrial)nr   r   ÚbasenameÚgetr   Úis_hardware_injectionÚtime_offsetÚet_ifosÚlenÚAssertionErrorÚkeysr   ÚlistÚsetÚ
start_timer   ZDocumentZappendChildZLIGO_LWr	   Z
process_idr   ZNewZCoincDefTableZ
CoincDefIDZCoincDefÚsearchÚdescriptionÚcoinc_def_idZsearch_coinc_typeÚappendZ
childNodesZCoincIDZ
CoincTableZCoincZneventsÚjoinZinstrumentsZTimeSlideIDZtime_slide_idZcoinc_event_idZ
likelihoodZSnglInspiralTableZCoincMapTableÚ	enumerater   ZSnglInspiralIDÚevent_idr   ÚlalZLIGOTimeGPSÚendÚsetattrÚAttributeErrorr*   r+   r   Zmass1_mass2_to_mtotal_etaZmtotalÚetaZmass1_mass2_to_mchirp_etaZmchirpÚsnrZsigmasqr1   ZchannelZCoincMapZ
table_namer   ÚnumpyZmeanÚmerger_timer#   ÚgetattrZCoincInspiralTableZCoincInspiralZfalse_alarm_rateZminimum_durationÚtupleZmassr%   Zend_time_nsZYRJUL_SIZcombined_farÚitemsÚintZdelta_fZCreateREAL8FrequencySeriesÚepochZ
StrainUnitZ	HertzUnitr   ÚDYN_RANGE_FACÚdatar
   ÚRuntimeErrorr,   r-   Zdo_pastro_calcr3   r(   r   ÚminÚprobabilitiesÚcopyÚdeepcopyÚ
hasmassgapÚastro_probsÚoutdocÚtime)'r0   Z
coinc_ifosZifosr   ÚkwargsZrtoffZsnr_ifosZ
extra_ifosr^   Zproc_idZcoinc_def_tablerC   Zcoinc_def_rowZcoinc_idZcoinc_event_tableZcoinc_event_rowZsngl_inspiral_tableZcoinc_event_map_tableZsngl_populatedZnetwork_snrsqZsngl_idr2   ÚnamesÚnameÚvalÚ_Zcoinc_map_rowZbayestar_check_fieldsZbcfZcoinc_inspiral_tableZcoinc_inspiral_rowr.   Zpsds_lalr&   ZkminZfseriesZtrigger_dataZhorizonsZeff_distancesr   )r   r   r0   r   r   Ú__init__   sJ   &
































zCandidateForGraceDB.__init__c          	   C   s’  i }t  ¡ t  ¡ k	rd|d< tj| j|fddi|—Ž tj |¡}| j	dk	r”tj 
|d¡| _t| jdƒ}t d| j	i|¡ W dQ R X t d| j¡ | jdk	râtj 
|d	¡| _t| jdƒ}t | j|¡ W dQ R X t d
| j¡ | jdk	r6tj 
|d¡| _t| jdƒ}t | j|¡ W dQ R X t d| j¡ dS | jdk	rŽtj 
|d¡| _t| jdƒ}t | j| jdœ|¡ W dQ R X t d| j¡ dS )zÎWrite a file representing this candidate in a LIGOLW XML format
        compatible with GraceDB.

        Parameters
        ----------
        fname: str
            Name of file to write to disk.
        NZtrap_signalsÚcompressÚautozpycbc.em_bright.jsonÚwZ
HasMassGapzEM Bright file saved as %szpycbc.p_astro.jsonzMulti p_astro file saved as %szsrc_probs.jsonz%Source probabilities file saved as %szpa_pterr.json)r3   r(   zP_astro file saved as %s)r   Úcurrent_threadÚmain_threadÚligolw_utilsZwrite_filenamer^   ÚosÚpathÚdirnamer\   rE   Úembright_fileÚopenÚjsonÚdumpÚloggingÚinfor]   Úmultipa_filerY   Ú	prob_filer3   Úpastro_filer(   )r0   Úfnamer`   Úsave_dirZ	embrightfZmultipafZprobfZpastrofr   r   r   Úsave&  s8    	

zCandidateForGraceDB.saveNTÚAllSkyc          
   C   sB  ddl }| d¡ ddl}| d¡r4| dd¡| _n&| d¡rN| dd¡| _ntd| ƒ‚|  |¡ d}y–t| dƒs¦dd	l	m
}	 d
ddœ}
|rš|	|f|
Žn|	f |
Ž| _|r®dnd}| j |d||¡ ¡ }|d }t d|¡ | jrü| j |d¡ t d|¡ W n> tk
r< } zt d|¡ t t|ƒ¡ W dd}~X Y nX | jdk	r²y(| jj|d| jdgd t d|¡ W n> tk
r° } zt d|¡ t t|ƒ¡ W dd}~X Y nX | jdk	r(y*| jj|d| jdgdd t d|¡ W n> tk
r& } zt d|¡ t t|ƒ¡ W dd}~X Y nX t| d ƒrœy(| jj|d!| jd"gd t d#|¡ W n> tk
rš } zt d$|¡ t t|ƒ¡ W dd}~X Y nX | jdk	r| jd% }| jd& }| jd' }| ¡  t| jƒ}x¦t| jƒD ]˜}| j| }|j|d(| d) |j |j!| t"|ƒt#|ƒ|d* || j$kräd+ %|¡}| j&|d,  }| j&|d-  | j' }|j || g|gt#|ƒd.d/ qäW | (¡  | )d0 %|¡¡ | *d1¡ | +|¡ | ,¡  t-| j.|ƒ xFt| j.ƒD ]8}| j.|  /t0j1¡}|t2j3d2  }|j|d3| d) qÌW | jdk	ržyJ| jj|d4|d5 | jj|d6|d7gd8gd9 | jj|d:|d;gd<gd9 W n> tk
rœ } zt d=|¡ t t|ƒ¡ W dd}~X Y nX t| d>ƒrº| j4 d?d@¡| _5dAdB„ | j6 7¡ D ƒ}t8| 7¡ Ž \}}dCdD„ |D ƒ}| 9¡ \}}|j:|||dEdFdGidH | ;dI¡ | +| j5¡ | ,¡  yL| jj|dJ| j4dKgd t dL|¡ | jj|dM| j5dKgd t dN|¡ W n> tk
r¸ } zt dO|¡ t t|ƒ¡ W dd}~X Y nX |dk	r>y:t<| j|ƒ x(|pÜg D ]}| jj||dPgdQ qÞW W n> tk
r< } zt dR|¡ t t|ƒ¡ W dd}~X Y nX |S )Sa‹  Upload this candidate to GraceDB, and annotate it with a few useful
        plots and comments.

        Parameters
        ----------
        fname: str
            The name to give the xml file associated with this trigger
        gracedb_server: string, optional
            URL to the GraceDB web API service for uploading the event.
            If omitted, the default will be used.
        testing: bool
            Switch to determine if the upload should be sent to gracedb as a
            test trigger (True) or a production trigger (False).
        search: str
            String going into the "search" field of the GraceDB event.
        r   NZAggz.xml.gzÚ z.xmlz3Upload filename must end in .xml or .xml.gz, got %sr   )ÚGraceDbTi,  )Zreload_certificateZreload_bufferZTestZCBCr   ZgraceidzUploaded event %sZINJz Tagging event %s as an injectionz`Something failed during the upload of event %s on GraceDB. The event may not have been uploaded!z%EM Bright properties JSON file uploadZ	em_bright)ÚfilenameÚtag_namez$Uploaded em_bright properties for %sz1Failed to upload em_bright properties file for %sz(Multi-component p_astro JSON file uploadr3   ZPASTRO_READY)r~   r   ÚlabelzUploaded multi p_astro for %sz*Failed to upload multi p_astro file for %srw   z$2-component p_astro JSON file uploadZsig_infozUploaded p_astro for %sz$Failed to upload p_astro file for %sz.hdfz_snr.pngz_asd.pngz%s/snr)Úgroup)Úcr€   zforeground/{}/rM   r%   Úx)r‚   ÚmarkerzGPS time from {:d} (s)ZSNRg       @z%s/psdzSNR timeseries HDF file upload)r~   zSNR timeseries plot uploadÚ
backgroundzSNR timeseries)r~   r   ZdisplayNamezASD plot uploadr&   ZASDsz.Failed to upload SNR timeseries and ASD for %srv   z.jsonz.pngc             S   s   i | ]\}}|d kr||“qS )g        r   )r   ÚkÚvr   r   r   r   ø  s    z.CandidateForGraceDB.upload.<locals>.<dictcomp>c             S   s   g | ]}t |ƒ‘qS r   )r   )r   r€   r   r   r   r   û  s    z.CandidateForGraceDB.upload.<locals>.<listcomp>z%1.1f%%Zfontsizeé   )ÚlabelsÚcolorsZautopctZ	textpropsÚequalz%Source probabilities JSON file uploadÚpez$Uploaded source probabilities for %sz Source probabilities plot uploadz.Uploaded source probabilities pie chart for %sz2Failed to upload source probability results for %sZanalyst_comments)r   zOSomething failed during annotation of analyst comments for event %s on GraceDB.)=Ú
matplotlibZuseZpylabÚendswithÚreplacer6   Ú
ValueErrorrz   ÚhasattrZligo.gracedb.restr}   r   Zcreate_eventrq   rs   rt   r8   Zwrite_labelÚ	ExceptionÚerrorÚstrr\   Ú	write_logro   r]   ru   rw   r   ZfigurerS   rO   ÚsortedZplotZsample_timesÚabsr   r:   Úformatr   r9   ZlegendZxlabelZylabelZsavefigÚcloser   r   ZastyperN   Zfloat64r   rU   rv   Z
prob_plotfrY   rR   ÚzipZsubplotsÚpieZaxisÚgracedb_tag_with_version)r0   rx   Zgracedb_serverÚtestingZextra_stringsrA   r   ÚplÚgidr}   Zgdbargsr   ÚrÚexcZsnr_series_fnameZsnr_series_plot_fnameZasd_series_plot_fnameZref_timer   Z	curr_snrsÚbaserM   ÚmtZcurr_psdZ	prob_plotr‰   ÚsizesrŠ   ZfigZaxÚtextr   r   r   ÚuploadV  s   





 
  
 








 



 
 zCandidateForGraceDB.upload)NTNr{   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__re   rz   r¦   r   r   r   r   r      s     
0 r   c             C   s8   d}|  tjtjrdndtj tj¡¡}|  	||¡ dS )zLAdd a GraceDB log entry reporting PyCBC's version and install location.
    zUsing PyCBC version {}{} at {}z
 (release)r|   N)
r˜   Úpycbc_versionr   Úreleaserl   rm   rn   r   Ú__file__r•   )r   rG   Úversion_strr   r   r   rœ   %  s    rœ   ) rs   rl   r   rN   rH   rq   rZ   Zmultiprocessing.dummyr   Zligo.lwr   r   r   rk   r   r«   r   Zpycbc.io.ligolwr   r	   r
   r   Zpycbc.resultsr   r   r   Zpycbc.mchirp_arear   Úobjectr   rœ   Ú__all__r   r   r   r   Ú<module>   s0       