Esempio n. 1
0
def writeRValuesTex(rvalues, usePrettyNames=True):
    """ write out the leading rvalues of the critic, in latex
    :param usePrettyNames: use the pretty names, not analysis ids
    """
    namer = SParticleNames(False)
    g = open("rvalues.tex", "wt")
    g.write("\\begin{tabular}{l|c|c|c|c|c}\n")
    g.write(
        "\\bf{Analysis Name} & \\bf{Production} & $\sigma_{XX}$ (fb) & $\sigma^\mathrm{UL}_\mathrm{obs}$ (fb) & $\sigma^\mathrm{UL}_\mathrm{exp}$ (fb) & $r$ \\\\\n"
    )
    #g.write ( "\\begin{tabular}{l|c|r|r}\n" )
    #g.write ( "\\bf{Analysis Name} & \\bf{Topo} & $r_{\mathrm{obs}}$ & $r_{\mathrm{exp}}$ \\\\\n" )
    g.write("\\hline\n")
    bibtex = BibtexWriter()
    from smodels_utils.helper.prettyDescriptions import prettyTexAnalysisName
    for rv in rvalues[:5]:
        srv = "N/A"
        if type(rv[1]) in [float, numpy.float64, numpy.float32]:
            srv = "%.2f" % rv[1]
        else:
            srv = str(rv[1])
        anaId = rv[2].analysisId()
        prettyName = getPrettyName(rv[2])
        prettyName = prettyTexAnalysisName(prettyName, anaid=anaId)
        ref = bibtex.query(anaId)
        txnames = ",".join(map(str, rv[2].txnames))
        allpids = rv[2].PIDs
        pids = []
        for p in allpids:
            tmp = []
            for b in p:
                if type(b[0]) == int:
                    tmp.append(b[0])
                else:
                    tmp.append(b[0][0])
            pids.append(tuple(tmp))
        prod = []
        for p in pids:
            tmp = namer.texName(p,
                                addDollars=True,
                                addSign=False,
                                addBrackets=True)
            prod.append(tmp)
        prod = "; ".join(prod)
        sigmapred = "20.13"
        sigmapred = rv[2].xsection.value.asNumber(fb)
        sigmaexp = "--"
        if type(rv[2].expectedUL) != type(None):
            sigmaexp = "%.2f" % rv[2].expectedUL.asNumber(fb)
        sigmaobs = rv[2].upperLimit.asNumber(fb)
        g.write ( "%s~\\cite{%s} & %s & %.2f & %.2f & %s & %.2f\\\\\n" % \
                ( prettyName, ref, prod, sigmapred, sigmaobs, sigmaexp, rv[0] ) )
    g.write("\\end{tabular}\n")
    g.close()
Esempio n. 2
0
 def retrieveMasses ( self ):
     """ retrieve the masses from slha file """
     logger=logging.getLogger(__name__)
     logger.info ( "now extracting masses from slha file %s" % ( self.slhafile) )
     namer = SParticleNames( susy = False )
     f = pyslha.read ( self.slhafile )
     m = f.blocks["MASS"]
     keys = m.keys()
     D={}
     for key in keys:
         mass = m[key]
         if mass > 4000.:
             continue
         name = namer.texName ( key )
         if namer.isSM ( key ): ## skip SM particles
             continue
         if self.mergesquark: ## sum up all squarks
             if namer.particleType ( key ) == "q":
                 name=name.rootName ( 1000001 )
         D[key]={ "name": name, "m": mass }
     self.masspids = D
     return D
Esempio n. 3
0
                     size=30,
                     clip_on=False)
            lastingHS -= 1  ## count down to zero
        # arrow = plt.arrow ( currentstep, -50, -currentstep-2, 0, width=20, clip_on=False, transform=ax2.transData, color="black" )
        # arrow = patches.FancyArrowPatch((.1, .5), (.1, .5), clip_on=False,
        #arrow = patches.FancyArrowPatch((firststep+currentstep-5-nstart, firststep-nstart), ( 50, 50),
        #    clip_on=False, connectionstyle="arc3,rad=.1", **kw, transform=ax2.transData )
        # plt.gca().add_patch ( arrow )

        for pid in pids:
            if max(masses[pid][firststep:laststep:nsteps]) <= 0.0: continue
            ctentries += 1
            data = df[firststep:laststep:nsteps]
            datamax = df[stepatmax:stepatmax + 1]
            datacur = df[firststep + currentstep:firststep + currentstep + 1]
            tName = r'$%s$' % namer.texName(pid)
            c = colorDict[pid]
            #if ctentries>9:
            #        tName=""
            m = np.where(masses[pid] > 0, masses[pid],
                         np.nan)  #Fix for avoid plotting to negative values
            ## the lines
            plt.plot(df['step'][firststep:laststep + 2:nsteps],
                     m[firststep:laststep + 2:nsteps],
                     '-',
                     linewidth=2,
                     color=c,
                     alpha=.5)
            sizes = []

            def getSize(k):
Esempio n. 4
0
    axarr[0].annotate(r'$%1.2f$' % row['K'],
                      (row['run'] - 0.2, row['K'] + 0.8),
                      fontsize=13)

axarr[0].vlines(x=0, ymin=2, ymax=15, linestyle='--', color='gray')

for pid in masses.keys():
    if not pid in masses:  #Skip particles present in real run, but not the fakes
        continue
    data = df
    sns.scatterplot(x=data['run'],
                    y=data[pid],
                    size=1000,
                    sizes=(1500, 1500),
                    marker='_',
                    label=r'$%s$' % (namer.texName(pid, addOnes=True)),
                    legend=False,
                    color=[colorDict[pid]],
                    ax=axarr[1])
    for i, m in enumerate(masses[pid]):
        if m < 0: continue
        if 'b' in namer.texName(pid):
            axarr[1].annotate(r'$%s$' % (namer.texName(pid, addOnes=True)),
                              (runs[i] - 0.3, m + 25.),
                              fontsize=15)
        else:
            axarr[1].annotate(r'$%s$' % (namer.texName(pid, addOnes=True)),
                              (runs[i], m + 25.),
                              fontsize=15)
axarr[1].set_ylim(0., 1500.0)
axarr[1].set_xlabel('run (BSM)', fontsize=23)
Esempio n. 5
0
    def plot ( self, ulSeparately=True, pid1=None ):
        """ a summary plot, overlaying all contributing analyses 
        :param ulSeparately: if true, then plot UL results on their own
        """
        if pid1 == None and type(self.pid1) in [ list, tuple ]:
            for p in self.pid1:
                self.plot ( ulSeparately, p )
            return
        if type(pid1) in [ tuple, list ]:
            for p in pid1:
                self.plot ( ulSeparately, p )
            return
        if pid1 == None:
            pid1 = self.pid1
        self.pprint ( "plotting summary for %s, %s" % ( pid1, self.topo ) )
        resultsForPIDs = {}
        from plotting.plotHiscore import getPIDsOfTPred, obtain
        protomodel = obtain ( 0, self.hiscorefile )
        for tpred in protomodel.bestCombo:
            resultsForPIDs = getPIDsOfTPred ( tpred, resultsForPIDs, integrateSRs=False )
        stats = self.getAnaStats( integrateSRs=False )
        if stats == None:
            self.pprint ( "found no ana stats?" )
            return
        anas = list(stats.keys())
        if pid1 in resultsForPIDs:
            self.debug ( "results for PIDs %s" % ", ".join ( resultsForPIDs[pid1] ) )
            anas = list ( resultsForPIDs[pid1] )
        anas.sort()
        self.pprint ( "summary plot: %s" % ", ".join ( anas ) )
        # print ( stats.keys() )
        colors = [ "red", "green", "blue", "orange", "cyan", "magenta", "grey", "brown",
                   "pink", "indigo", "olive", "orchid", "darkseagreen", "teal" ]
        xmin,xmax,ymin,ymax=9000,0,9000,0
        for m in self.masspoints:
            if m[0] < xmin:
                xmin = m[0]
            if m[0] > xmax:
                xmax = m[0]
            if m[1] < ymin:
                ymin = m[1]
            if m[1] > ymax:
                ymax = m[1]
        if abs(xmin-310.)<1e-5:
            xmin=330. ## cut off the left margin
        print ( "[plotLlhds] range x [%d,%d] y [%d,%d]" % ( xmin, xmax, ymin, ymax ) )
        handles = []
        existingPoints = []
        combL = {}
        namer = SParticleNames ( susy = False )
        for ctr,ana in enumerate ( anas ): ## loop over the analyses
            if ctr >= self.max_anas:
                self.pprint ( "too many (%d > %d) analyses." % (len(anas),self.max_anas) )
                for ana in anas[ctr:]:
                    self.pprint ( "  - skipping %s" % ana )
                break
            color = colors[ctr]
            x,y=set(),set()
            L, R = {}, {}
            minXY=( 0.,0., float("inf") )
            s=""
            r,sr = self.getResultFor ( ana, self.masspoints[0][2] )
            if r:
                s="(%.2f)" % (-np.log(r))
            print ( "[plotLlhds] result for", ana,"is", s )
            cresults = 0
            for cm,masspoint in enumerate(self.masspoints[1:]):
                #if cm % 10 != 0:
                #    continue
                if cm % 1000 == 0:
                    print ( ".", end="", flush=True )
                m1,m2,llhds,robs=masspoint[0],masspoint[1],masspoint[2],masspoint[3]
                rmax=float("nan")
                if len(robs)>0:
                    rmax=robs[0]
                if m2 > m1:
                    print ( "m2,m1 mass inversion?",m1,m2 )
                x.add ( m1 )
                y.add ( m2 )
                zt = float("nan")
                result,sr = self.getResultFor ( ana, llhds )
                if result:
                    zt = - np.log( result )
                    cresults += 1
                    if zt < minXY[2] and rmax<=self.rthreshold:
                        minXY=(m1,m2,zt)
                h = self.getHash(m1,m2)
                L[h]=zt
                if not h in combL:
                    combL[h]=0.
                if np.isnan(zt):
                    combL[h] = combL[h] + 100.
                else:
                    combL[h] = combL[h] + zt
                R[h]=rmax
            print ()
            # print ( "\n[plotLlhds] min(xy) for %s is at m=(%d/%d): %.2f(%.2g)" % ( ana, minXY[0], minXY[1], minXY[2], np.exp(-minXY[2] ) ) )
            if cresults == 0:
                print ( "[plotLlhds] warning: found no results for %s. skip" % \
                        str(masspoint) )
                continue
                # return
            x.add ( xmax*1.03 )
            x.add ( xmin*.93 )
            y.add ( ymax+50. )
            y.add ( 0. )
            x,y=list(x),list(y)
            x.sort(); y.sort()
            X, Y = np.meshgrid ( x, y )
            Z = float("nan")*X
            RMAX = float("nan")*X
            for irow,row in enumerate(Z):
                for icol,col in enumerate(row):
                    h = 0
                    if len(x)>= icol and len(y) >= irow:
                        h = self.getHash(list(x)[icol],list(y)[irow])
                    if h in L:
                        Z[irow,icol]=L[h]
                    if h in R:
                        RMAX[irow,icol]=R[h]
            if self.interactive:
                self.RMAX = RMAX
                # self.ZCOMB = ZCOMB
                self.Z = Z
                self.L = L
                self.R = R
                self.X = X
                self.Y = Y
            hldZ100 = computeHPD ( Z, None, 1., False, rthreshold=self.rthreshold )
            cont100 = plt.contour ( X, Y, hldZ100, levels=[0.25], colors = [ color ], linestyles = [ "dotted" ], zorder=10 )
            #hldZ95 = computeHPD ( Z, .95, False )
            #cont95 = plt.contour ( X, Y, hldZ95, levels=[0.5], colors = [ color ], linestyles = [ "dashed" ] )
            #plt.clabel ( cont95, fmt="95%.0s" )
            hldZ50 = computeHPD ( Z, RMAX, .68, False, rthreshold=self.rthreshold )
            cont50c = plt.contour ( X, Y, hldZ50, levels=[1.0], colors = [ color ], zorder=10 )
            cont50 = plt.contourf ( X, Y, hldZ50, levels=[1.,10.], colors = [ color, color ], alpha=getAlpha( color ), zorder=10 )
            plt.clabel ( cont50c, fmt="68%.0s" )
            if hasattr ( cont50, "axes" ):
                ax = cont50.axes
            else:
                ax = cont50.ax
            while isCloseToExisting ( minXY, existingPoints ):
                minXY = ( minXY[0]+8., minXY[1]+8., minXY[2] )
            a = ax.scatter( [ minXY[0] ], [ minXY[1] ], marker="*", s=180, color="black", zorder=20 )
            anan = ana.replace(":None",":UL") # + " (%.2f)" % (minXY[2])
            label = self.getPrettyName ( ana )
            a = ax.scatter( [ minXY[0] ], [ minXY[1] ], marker="*", s=110, color=color, 
                            label=label, alpha=1., zorder=20 )
            existingPoints.append ( minXY )
            handles.append ( a )
        ZCOMB = float("nan")*X
        for irow,row in enumerate(Z):
            for icol,col in enumerate(row):
                h = 0
                if len(x)> icol and len(y) > irow:
                    h = self.getHash(list(x)[icol],list(y)[irow])
                if h in combL and not np.isnan(combL[h]):
                    ZCOMB[irow,icol]=combL[h]
                    if combL[h]==0.:
                        ZCOMB[irow,icol]=float("nan")
        self.ZCOMB = ZCOMB
        contRMAX = plt.contour ( X, Y, RMAX, levels=[self.rthreshold], colors = [ "gray" ], zorder=10 )
        contRMAXf = plt.contourf ( X, Y, RMAX, levels=[self.rthreshold,float("inf")], colors = [ "gray" ], hatches = ['////'], alpha=getAlpha( "gray" ), zorder=10 )
        hldZcomb68 = computeHPD ( ZCOMB, RMAX, .68, False, rthreshold=self.rthreshold )
        contZCOMB = plt.contour ( X, Y, hldZcomb68, levels=[.25], colors = [ "black" ], zorder=10 )

        # ax.scatter( [ minXY[0] ], [ minXY[1] ], marker="s", s=110, color="gray", label="excluded", alpha=.3, zorder=20 )
        print()
        self.pprint ( "timestamp:", self.timestamp, self.topo, max(x) )
        dx,dy = max(x)-min(x),max(y)-min(y)
        if self.drawtimestamp:
            plt.text( max(x)-.37*dx,min(y)-.11*dy,self.timestamp, c="gray" )
        ### the altitude of the alpha quantile is l(nuhat) - .5 chi^2_(1-alpha);ndf
        ### so for alpha=0.05%, ndf=1 the dl is .5 * 3.841 = 1.9207
        ### for ndf=2 the dl is ln(alpha) = .5 * 5.99146 = 2.995732
        ### folien slide 317
        if hasattr ( cont50, "axes" ):
            ax = cont50.axes
        else:
            ax = cont50.ax
        # Xs,Ys=X,Y
        Xs,Ys = filterSmaller ( X, Y )
        h = self.getHash()
        # print ( "hash is", h )
        #s=" (??)"
        #if h in L:
        #    s=" (%.2f)" % L[h]
        #s=" (%.2f)" % self.getLClosestTo ( L )
        s=""
        ax.scatter( [ self.mx ], [ self.my ], marker="*", s=200, color="white", zorder=20 )
        c = ax.scatter( [ self.mx ], [ self.my ], marker="*", s=160, color="black", 
                      label="proto-model%s" % s, zorder=20 )
        handles.append ( c )
        if sr == None:
            sr = "UL"
        # plt.title ( "HPD regions, %s [%s]" % ( namer.texName(pid1, addSign=False, addDollars=True), self.topo ), fontsize=14 )
        plt.xlabel ( "m(%s) [GeV]" % namer.texName(pid1,addSign=False, addDollars=True), fontsize=14 )
        plt.ylabel ( "m(%s) [GeV]" % namer.texName(self.pid2, addSign=False, addDollars=True), fontsize=14 )
        circ1 = mpatches.Patch( facecolor="gray",alpha=getAlpha("gray"),hatch=r'////',label='excluded by critic', edgecolor="black" )
        handles.append ( circ1 )
        plt.legend( handles=handles, loc="upper left", fontsize=12 )
        figname = "%s/llhd%d.png" % ( self.rundir, pid1 )
        self.pprint ( "saving to %s" % figname )
        plt.savefig ( figname )
        if self.interactive:
            self.axes = ax
            self.plt = plt
        plt.close()
        if self.copy:
            self.copyFile ( figname )
        return
Esempio n. 6
0
def draw( pid= 1000022, interactive=False, pid2=0, copy=False,
          drawtimestamp = True, rundir = None, plotrmax=False,
          rthreshold = 1.3, upload = "latest" ):
    """ draw plots
    :param copy: copy final plots to ../../smodels.github.io/protomodels/latest
    :param drawtimestamp: if True, put a timestamp on it
    :param plotrmax: if True, plot also rmax curve
    :param upload: upload directory, default is "latest"
    """
    if pid2 == 0: ## means all
        pidpairs = findPidPairs( rundir )
        if len(pidpairs) == 0:
            print ( "[scanner] could not find ssm*pcl files. Maybe run ./fetchFromClip.py --ssms" )
            return
        for pids in pidpairs:
            try:
                draw ( pids[0], interactive, pids[1], copy, drawtimestamp, \
                       rundir, plotrmax, upload = upload )
            except Exception as e:
                print ( "[scanner] %s" % e )
        return

    def isSSMPlot():
        ## is this an ssm or a mass plot
        return pid2!=-1

    import matplotlib
    matplotlib.use("Agg")
    from matplotlib import pyplot as plt
    import pickle
    namer = SParticleNames ( susy = False )
    #if False:
    #    rundir = ""
    picklefile = "%sscanM%s.pcl" % (rundir, pid )
    if isSSMPlot():
        picklefile = "%sssm%s%d.pcl" % ( rundir, pid, pid2 )
    with open ( picklefile, "rb" ) as f:
        Zs = pickle.load( f )
        cmass = pickle.load ( f ) ## cmass is pids
        nevents = pickle.load ( f )
        timestamp = pickle.load ( f )
    x = list(Zs.keys())
    x.sort()
    y, yr, ydashed = [], [], []
    rs = []
    rsarea = []
    for i in x:
        y_ = Zs[i]
        y0=y_
        if type(y_)==tuple:
            idx = 2
            if len(y_)==2:
                idx = 0
            y0 = y_[idx]
            if y_[1] > rthreshold+.05 and plotrmax:
                rsarea.append ( y_[1] )
                y0 = -1.
            else:
                rsarea.append ( 0. )
            rs.append ( y_[1] )
            ydashed.append ( Zs[i][idx] )
        y2_ = y0
        if y2_ < 0.:
            y2_ = float("nan")
        y.append ( y0 )
        yr.append ( y2_ )
    pname = namer.texName ( pid, addDollars=False )
    if isSSMPlot():
        #pname = namer.texName ( pid, addDollars=False, addSign=True )+","+\
        #        namer.texName ( pid2, addDollars=False, addSign=True )
        pname = namer.texName ( pid2, addDollars=False, addSign=True )+\
                namer.texName ( pid, addDollars=False, addSign=True )
    fig,ax1 = plt.subplots()
    plt.plot ( x, ydashed, linewidth=.3, c="tab:blue", zorder=0 )
    plt.plot ( x, yr, linewidth=2., label="$K(%s)$" % ( pname ), 
               c="tab:blue", zorder=0 )
    #plt.plot ( x, yr, linewidth=2., label="$K(%s)$, %dk events" % ( pname, nevents/1000 ), 
    #           c="tab:blue", zorder=0 )
    ax1.tick_params ( axis="y", labelcolor="tab:blue", labelsize=12, labelleft=True )
    ax1.tick_params ( axis="x", labelsize=12 )
    ax1.set_ylabel ( "K", c="tab:blue", fontsize=15 )
    # ax1.set_xlabel ( "m [GeV]", fontsize=13 )
    ax1.set_xlabel ( "$m(%s)$ [GeV]" % pname, fontsize=16 )
    maxyr = numpy.nanmax(ydashed)
    # print ( "ydashed", ydashed )
    ax1.set_ylim ( bottom = 2., top=8.4 )
    #ax1.set_ylim ( bottom = 2., top=maxyr*1.03 )
    rsarea[0]=0.
    rsarea[-1]=0.
    if len(rs) == len(x) and plotrmax:
        ax2 = ax1.twinx()
        ax1.plot ([], [], label="$r_\mathrm{max}$", c="tab:red", zorder=1 )
        ax2.plot ( x, rs, label="$r_\mathrm{max}$", c="tab:red", zorder=2 )
        ax2.tick_params ( axis="y", labelcolor="tab:red", labelsize=12 )
        #ax2.set_ylim ( bottom=min(rs)*.7, top = 1.9 )
        ax2.set_ylim ( bottom=0.6, top = 1.9 )
        ax2.set_ylabel ( "$r_\mathrm{max}$", c="tab:red", fontsize=16 )
    if len(rsarea) == len(x) and plotrmax:
        # ax3 = ax1.twinx()
        ax2.fill ( x, rsarea, lw=0, edgecolor="white", alpha=.2, 
                   facecolor="tab:red", zorder=-1 )
    ymax = max(y)
    imax = y.index ( ymax )
    xmax = x[imax]
    param="%d GeV" % xmax
    if isSSMPlot():
        param="%.3f" % xmax
    # label = "maximum K\n K(%s)=%.2f" % (param, ymax )
    label = "maximum K"
    ax1.scatter ( [ xmax ], [ ymax ], label=label, s=130, c="k", marker="v", zorder=5 )
    if type(cmass)==tuple:
        cmass = x[int(len(x)/2)]
    param = "%d GeV" % cmass
    if isSSMPlot():
        param="%.3f" % cmass
    Zmax = getClosest( cmass, Zs )
    if type(Zmax)==tuple:
        Zmax=Zmax[idx]
    # label = "proto-model\n K(%s)=%.2f" % (param, Zmax )
    label = "proto-model"
    ax1.scatter ( [ cmass ], [ Zmax ], label=label, marker="^", s=130, c="g", zorder=10 )
    # plt.title ( "Test statistic $K=K(%s)$" % pname, fontsize=14 )
    if drawtimestamp:
        plt.text ( .7, -.12, timestamp, c="gray", transform = ax1.transAxes )
    if isSSMPlot():
        plt.xlabel ( "$\\hat\\mu\\kappa(%s)$" % pname, fontsize=17 )
        ax1.set_xlabel ( "$\\hat\\mu\\kappa(%s)$" % pname, fontsize=17 )
        ax1.legend( fontsize = 12, loc= "lower left" )
    else:
        ax1.legend( fontsize = 12 )
        plt.xlabel ( "$m(%s)$ [GeV]" % pname, fontsize=16 )

    # plt.text ( .9*min(x)+.1*(max(x)-min(x)), 1.*max(y), "%d events" % nevents )
    figname = "M%d.png" % pid
    if isSSMPlot():
        figname = "ssm_%d_%d.png" % ( pid, pid2 )
    stdvar =  numpy.std ( y )

    if interactive:
        import IPython
        IPython.embed( using=False )

    if stdvar < 1e-10:
        print ( "[scanner] standard deviation is a %.2f. Not plotting." % stdvar )
        return

    print ( "[scanner] creating %s" % figname )
    plt.tight_layout()
    plt.savefig ( figname )
    plt.close()
    if copy:
        dest = os.path.expanduser ( "~/git/smodels.github.io" )
        cmd = "cp %s/%s %s/protomodels/%s/" % ( rundir,figname, dest, upload )
        o = subprocess.getoutput ( cmd )
        print ( "[scanner] %s: %s" % ( cmd, o ) )
Esempio n. 7
0
class RulerPlot:
    """ a class that encapsulates a horizontal ruler plot """
    def __init__ ( self, inputfile="masses.txt", outputfile="out", Range=(None,None),
           formats={ "png": True }, printmass=False, mergesquark=True,
           drawdecays=True, hasResultsFor = None, 
           verbosity="info", susy=False, trim= True ):
        """
        :param mergesquark: if True, merge squarks FIXME
        :param susy: use SUSY particle names
        """
        self.inputfile = inputfile
        self.slhafile = inputfile
        for e in [ "png", "pdf", "eps" ]:
            if outputfile.endswith(f".{e}"):
                formats[e]=True
                outputfile = outputfile.replace(f".{e}","")
        self.outputfile = outputfile
        self.range = Range
        if sum ( formats.values() ) == 0:
            formats["png"]=True ## if nothing, then pngs
        self.formats = formats
        self.printmass = printmass
        self.mergesquark = mergesquark
        self.hasResultsFor = hasResultsFor 
        self.verbosity = verbosity
        self.logger=logging.getLogger("RulerPlot")
        self.susy = susy
        self.namer = SParticleNames ( susy = susy )
        self.decays = {}
        self.getMasses()
        self.getRange()
        self.drawdecays = drawdecays
        self.trim = trim
        if drawdecays:
            self.getDecays()

    def getMasses ( self ):
        """ obtain the masses from input file, remove > 3000 GeV """
        if self.inputfile.endswith ( ".slha" ):
            pmasses = self.retrieveMasses ()
        masses={}
        # masses=pmasses
        for (pid,D) in pmasses.items():
            masses[D["name"]] = D["m"]
        ## cut off at 3 TeV
        ret = [ m for m in masses.values() if m<3000. ]
        self.masses = ret
        self.logger.info ( "masses %s" % self.masses )
        return ret


    def getDecays ( self ):
        """ obtain the decays from input file, remove > 3000 GeV """
        f = pyslha.read ( self.slhafile )
        massblock = f.blocks["MASS"]
        mpids = []
        for mpid in massblock.keys():
            if massblock[mpid]<3000.:
                mpids.append ( mpid )
        decblock = f.decays
        decays = {}
        for mpid in mpids:
            dec = decblock[mpid].decays
            if len(dec)==0:
                continue
            for d in dec:
                if d.br < 1e-1: ## ignore too small branchings
                    continue
                if not mpid in decays:
                    decays[mpid]=[]
                decays[mpid].append( {"br": d.br, "ids": d.ids } )
        self.decays = decays

    def getRange ( self ):
        """ given self.masses, compute the range that we wish to plot. """
        maxvalue=max (self.masses)
        minvalue=min(self.masses)
        maxvalue = min ( [ maxvalue, 3100. ] )
        minvalue = max ( [ 0, minvalue ] )
        dm = maxvalue - minvalue
        if self.range[0] != None and self.range[0] >=0.:
            minvalue=self.range[0]
        if self.range[1] != None and self.range[1] >=0.:
            maxvalue=self.range[1]
        self.logger.info ( "range is [%d,%d]" % ( minvalue, maxvalue ) )
        self.minmass = minvalue
        self.maxmass = maxvalue

    def retrieveMasses ( self ):
        """ retrieve the masses from slha file """
        logger=logging.getLogger(__name__)
        logger.info ( "now extracting masses from slha file %s" % ( self.slhafile) )
        namer = SParticleNames( susy = False )
        f = pyslha.read ( self.slhafile )
        m = f.blocks["MASS"]
        keys = m.keys()
        D={}
        for key in keys:
            mass = m[key]
            if mass > 4000.:
                continue
            name = namer.texName ( key )
            if namer.isSM ( key ): ## skip SM particles
                continue
            if self.mergesquark: ## sum up all squarks
                if namer.particleType ( key ) == "q":
                    name=name.rootName ( 1000001 )
            D[key]={ "name": name, "m": mass }
        self.masspids = D
        return D

    def getSortedPids ( self ):
        """ get a container of pids, sorted by the masses """
        sortedpids = []
        for (pid,D) in self.masspids.items():
            m = D["m"]
            sortedpids.append((m,pid))
        sortedpids.sort()
        pids = [ x[1] for x in sortedpids ]
        return pids

    def drawHorizontal ( self ):
        # https://pythonprogramming.net/spines-hline-matplotlib-tutorial/
        """ the matplotlib plotting function """
        plt.rc("text",usetex=True)
        dm = self.maxmass - self.minmass
        ticks = numpy.arange ( self.minmass, self.maxmass, .05*dm )
        y = [ 0. ] * len(ticks)
        y[0]=1.
        fig = plt.figure(figsize=(10,3))
        ax1 = plt.subplot()
        # ax1 = plt.subplot2grid((1,1), (0,0))
        labels = []
        for i,label in enumerate(ax1.xaxis.get_ticklabels()):
                    label.set_rotation(45)
                    labels.append ( label.get_label() ) #  " GeV" )
        ax1.spines['right'].set_color('none')
        ax1.spines['left'].set_color('none')
        ax1.spines['top'].set_color('none')
        ax1.plot ( ticks, y, c="w" )
        ax1.set_yticks([])
        # plt.xlabel ( "m [GeV]" )
        plt.text(self.maxmass+30.,-.12,"m [GeV]" )

        sortedpids = self.getSortedPids()

        for ctr,pid in enumerate(sortedpids):
            name = self.masspids[pid]["name"]
            m = self.masspids[pid]["m"]
            y=(abs(m)-self.minmass)/(self.maxmass-self.minmass)
            col=self.namer.rgbColor ( name )
            coldark=self.namer.rgbColor ( name, bold=True )
            label = f"${name}$" 
            yoff = 0. ## yoffset, put every second one halfway down
            if ctr % 2 == 1:
                yoff=.5
            plt.text ( m, 1.-yoff, label, c = coldark, size=15, fontweight="bold" )
            lctr=0
            keys = []

            if self.hasResultsFor != None:
                for mana,analyses in self.hasResultsFor.items():
                    # print ( "m,mana",m,mana )
                    if abs(m-mana)<.1: ## max mass gap
                        if abs(m-mana)>1e-2:
                            print ( "WARNING: clustering particle masses %.2f and %.2f. hope its ok. check it." % ( m, mana )  )
                        keys.append ( mana )
                        for cana,ana in enumerate(analyses):
                            plt.text ( m-50., .91-yoff-.07*cana, ana.replace("201","1" ), c=col )
                            lctr+=1
        plt.savefig ( "horizontal.png" )
        self.ax1 = ax1
        self.plt = plt

    def drawVertical ( self ):
        # https://pythonprogramming.net/spines-hline-matplotlib-tutorial/
        """ the matplotlib plotting function """
        from matplotlib import pyplot as plt
        plt.rc("text",usetex=True)
        import numpy
        dm = self.maxmass - self.minmass
        ticks = numpy.arange ( self.minmass, self.maxmass, .05*dm )
        x = [ 0. ] * len(ticks)
        x[0]=1.
        figratio = ( 3, 10 )
        if self.drawdecays:
            figratio = ( 5, 6 )
        fig = plt.figure(figsize=figratio )
        ax1 = plt.subplot()
        labels = []
        for i,label in enumerate(ax1.yaxis.get_ticklabels()):
                    # label.set_rotation(45)
                    labels.append ( label.get_label() ) #  " GeV" )
        ax1.spines['right'].set_color('none')
        ax1.spines['left'].set_color('none')
        ax1.spines['top'].set_color('none')
        ax1.spines['bottom'].set_color('none')
        ax1.plot ( x, ticks, c="w" )
        ax1.set_xticks([])
        plt.text(-.22, self.minmass-30., "m [GeV]" )

        sortedpids = self.getSortedPids()

        for ctr,pid in enumerate(sortedpids):
            name = self.masspids[pid]["name"]
            m = self.masspids[pid]["m"]
            # print ( "m", ctr, m, name )
            y=(abs(m)-self.minmass)/(self.maxmass-self.minmass)
            col=self.namer.rgbColor ( name )
            coldark=self.namer.rgbColor ( name, bold=True )
            label = f"${name}$" 
            ## compute the xoffset, we start at the center the move left and right
            xoff = 0.5 + (-1)**(ctr) * .15 * math.ceil(ctr/2)
            side = -1 ## -1 is left 1 is right
            if ctr % 2 == 0:
                side = 4.
            # print  ( "mass", label, m, xoff )
            plt.text ( xoff, m, label, c = coldark, size=15, fontweight="bold", ha="left" )
            x1 = xoff + side * .05
            x2 = x1 + numpy.sign(side)*.1
            if ctr == 0:
                x2 = 1.
            ## small horizontal lines next to the particle names
            plt.plot ( [ x1, x2 ], [m+10. , m+10. ], c= coldark )

            ## the LBP gets horizontal lines in both directions 
            if ctr == 0:
                x1 = xoff - .05
                x2 = .1
                plt.plot ( [ x1, x2 ], [m+10. , m+10. ], c= coldark )
            ## 
            ## at the center of the decay line
            xavg = .5*x1 + .5*x2
            lctr=0
            dm = 20.
            if self.drawdecays:
                dm = 35.
            keys = []

            if self.hasResultsFor != None:
                for mana,analyses in self.hasResultsFor.items():
                    # print ( "m,mana",m,mana )
                    if abs(m-mana)<.1: ## max mass gap
                        if abs(m-mana)>1e-2:
                            print ( "WARNING: clustering particle masses %.2f and %.2f. hope its ok. check it." % ( m, mana )  )
                        keys.append ( mana )
                        dm1 = 30. ## gap to first ana id
                        if self.drawdecays:
                            dm1 = 50.
                        for cana,ana in enumerate(analyses):
                            plt.text ( xavg, m-dm1-dm*cana, ana.replace("201","1" ),
                                       c=col, ha="center" )
                            lctr+=1

            if pid in self.decays:
                ## now check for decays
                decays = self.decays[pid]
                # print ( "[rulerPlotter] check for decays", decays )
                for d in decays[:1]:
                    ids = d["ids"]
                    br = d["br"]
                    idBSM = 1000022
                    idNotBSM = []
                    for iD in ids:
                        if abs(iD)>1000000:
                            idBSM = iD
                        else:
                            idNotBSM.append( abs(iD) )

                    mlow = self.masspids[idBSM]["m"] + 20.
                    # delta m that is due to ana ids
                    dmResults = lctr * dm + bool(lctr)*30.
                    mtop = m - dmResults - 10.
                    dm = mlow - m + 20. + dmResults
                    plt.arrow ( xavg, mtop, 0., dm , color="grey",
                               linestyle="dashed", linewidth=.5, 
                               head_length=15, head_width=.05 )
                    label = self.namer.texName(idNotBSM,addDollars=True) 
                    if br < 0.95:
                        label += ": %s" % br
                    plt.text ( xavg + .05, mlow + 30., label, color="grey" )
        for frmat,runthis in self.formats.items():
            if not runthis:
                continue
            of = self.outputfile + "." + frmat
            self.logger.info ( "saving to %s" % of )
            plt.savefig ( of )
            if frmat == "png" and self.trim:
                cmd = "convert %s -trim %s" % ( of, of )
                subprocess.getoutput ( cmd )

        self.ax1 = ax1
        self.plt = plt

    def interactiveShell( self ):
        import IPython
        IPython.embed()
Esempio n. 8
0
def writeIndexTex(protomodel, texdoc):
    """ write the index.tex file
    :param texdoc: the source that goes into texdoc.png
    """
    ssm = []
    namer = SParticleNames(False)
    for k, v in protomodel.ssmultipliers.items():
        if abs(v - 1.) < 1e-3:
            continue
        ssm.append("%s: %.2f" % (namer.texName(k, addSign=True), v))
    f = open("index.tex", "w")
    f.write ( "Our current winner has a score of \\K=%.2f, " % \
              ( protomodel.K ) )
    strategy = "aggressive"
    dbver = getDatabaseVersion(protomodel)
    dotlessv = dbver.replace(".", "")
    f.write ( " it was produced with database {\\tt v%s}, combination strategy {\\tt %s} walker %d in step %d." % \
            ( dotlessv, strategy, protomodel.walkerid, protomodel.step ) )
    f.write("\n")
    if hasattr(protomodel, "tpList"):
        rvalues = protomodel.tpList
        rvalues.sort(key=lambda x: x[0], reverse=True)
        writeRValuesTex(rvalues)
        #writeRValuesTexOld ( rvalues )
    else:
        print("[plotHiscore] protomodel has no r values!")

    if hasattr(protomodel, "analysisContributions"):
        print("[plotHiscore] contributions-per-analysis are defined")
        # f.write ( "Contributions per analysis:\n\\begin{itemize}[noitemsep,nolistsep]\n" )
        f.write(
            "The contributions per analysis are given in Tab.~\\ref{tab:analysiscontributions}.\n"
        )
        f.write("\\begin{table}\n")
        f.write("\\begin{center}\n")
        f.write("\\begin{tabular}{l|c|c}\n")
        f.write(
            "\\bf{Analysis Name} & \\bf{\\K(without)} & \\bf{Contribution} \\\\\n"
        )
        f.write("\\hline\n")
        conts = []
        dKtot = 0.
        Ktot = protomodel.K
        contributions = protomodel.analysisContributions
        for k, v in contributions.items():
            conts.append((v, k))
            dKtot += Ktot - v
        # dKtot = dKtot # * protomodel.K
        Ks, Kwo = {}, {}
        """
        for k,v in contributions:
            Ks[k] = ( protomodel.K - dKtot * v)
            Kwo[k] = protomodel.K
        """
        conts.sort(reverse=True)
        for v, k in conts:
            Kwithout = contributions[k]
            cont = (Ktot - Kwithout) / dKtot
            f.write("%s & %.2f & %s%s \\\\ \n" %
                    (k, Kwithout, int(round(100. * cont)), "\\%"))
            # f.write ( "\item %s: %s%s\n" % ( k, int(round(100.*v)), "\\%" ) )
        # f.write ( "\end{itemize}\n" )
        f.write("\\end{tabular}\n")
        f.write("\\end{center}\n")
        f.write(
            "\\caption{Contributions to the test statistic \\K. \\K(without) denotes the \\K value obtained in absence of the particular analysis.}\n"
        )
        f.write("\\label{tab:analysiscontributions}\n")
        f.write("\\end{table}\n")
    else:
        print("[plotHiscore] contributions are not defined")

    height = 32 * int((len(ssm) + 3) / 4)
    if ssm == []:
        height = 32
    if hasattr(protomodel, "particleContributions"):
        height += 32
    # f.write ( "<td><img width=600px src=./texdoc.png>\n" ) #  % height )
    # f.write ( "\small{Last updated: %s}\n" % time.asctime() )
    # f.write ( "% include decays.png\n" )
    contrs = texdoc.replace(":", " are ").replace("S",
                                                  "The s").replace(";", ", ")
    contrs = contrs.replace("\\\\\\\\Contr", "; the contr")
    f.write(contrs + "\n")
    f.close()
    print("[plotHiscore] Wrote index.tex")
Esempio n. 9
0
def writeTex(protomodel, keep_tex):
    """ write the comment about ss multipliers and particle contributions, in tex.
    Creates texdoc.png.
    :param keep_tex: keep tex source of texdoc.png
    """
    cpids = {}
    frozen = protomodel.frozenParticles()
    xsecs = protomodel.getXsecs()[0]
    ssms = getUnfrozenSSMs(protomodel, frozen, includeOnes=True)
    namer = SParticleNames(susy=False)
    for pids, v in ssms.items():
        xsec = findXSecOfPids(xsecs, pids)
        if xsec < 0.001 * fb:  ## only for xsecs we care about
            continue
        sv = "%.2g" % v
        if v < .1:
            sv = "%.1g" % v
        if not sv in cpids:
            cpids[sv] = []
        cpids[sv].append(pids)

    ssm = {}
    for v, pids in cpids.items():
        sp = []
        for pairs in pids:
            pname = namer.texName(pairs, addSign=True, addBrackets=True)
            sp.append(pname)
        ssm[v] = ", ".join(sp)

    particleContributionList = ""
    if hasattr(protomodel, "particleContributions"):
        print("[plotHiscore] contributions-by-particle are defined")
        #particleContributionList+="\\\\Contributions by particles: $"
        particleContributionList += "\\\\"
        particleContributionList += "Contributions by particles: $"
        totalcont = 0.  ## to normalize contributions
        for k, v in protomodel.particleContributions.items():
            totalcont += (protomodel.K - v)
        tok = {}
        for k, v in protomodel.particleContributions.items():
            if v in tok.keys():
                v += 1e-6
            perc = 100.
            if totalcont != 0.:
                perc = round(100. * (protomodel.K - v) / totalcont)
            tok[v] = "%s: K_\mathrm{without}=%.2f (%d%s)" % (namer.texName(k),
                                                             v, perc, "\%")
            # tok[v] = "%s = (%.2f) %d%s" % ( namer.texName(k), v, perc, "\%" )
        keys = list(tok.keys())
        keys.sort()
        for v in keys:
            particleContributionList += tok[v] + ", "
        if len(keys) > 0:
            particleContributionList = particleContributionList[:-2]
        #particleContributionList+= ", ".join ( tok )
        particleContributionList += "$"
    else:
        print(
            "[plotHiscore] protomodel has no ``particleContributions'' defined."
        )

    from plotting import tex2png
    src = getExtremeSSMs(ssm, largest=True, nm=7)
    src += "\\\\"
    nsmallest = min(7, len(ssm) - 7)
    if nsmallest > 0:
        src += getExtremeSSMs(ssm, largest=False, nm=nsmallest)
    src += particleContributionList
    if keep_tex:
        with open("texdoc.tex", "wt") as f:
            f.write(src + "\n")
            f.close()
        print("[plotHiscore] wrote %s/texdoc.tex" % os.getcwd())
    try:
        p = tex2png.Latex(src, 600).write()
        f = open("texdoc.png", "wb")
        f.write(p[0])
        f.close()
    except Exception as e:
        print("[plotHiscore] Exception when latexing: %s" % e)
    return src
Esempio n. 10
0
def writeRawNumbersLatex(protomodel, usePrettyNames=True):
    """ write out the raw numbers of the excess, in latex
    :param usePrettyNames: use the pretty names, not analysis ids
    """
    print("raw numbers of excess")
    print("=====================")
    f = open("rawnumbers.tex", "wt")
    f.write("\\begin{tabular}{l|c|r|r|c|r|r}\n")
    f.write(
        "\\bf{Analysis Name} & \\bf{Dataset} & \\bf{Obs} & \\bf{Expected} & \\bf{Z} & \\bf{Particle} & \\bf{Signal} \\\\\n"
    )
    f.write("\\hline\n")
    namer = SParticleNames(susy=False)
    bibtex = BibtexWriter()
    from smodels_utils.helper.prettyDescriptions import prettyTexAnalysisName
    for tp in protomodel.bestCombo:
        anaId = tp.analysisId()
        ananame = anaId
        if usePrettyNames:
            ananame = prettyTexAnalysisName(None, anaid=anaId)
        dtype = tp.dataType()
        print("[plotHiscore] item %s (%s)" % (anaId, dtype))
        dt = {"upperLimit": "ul", "efficiencyMap": "em"}
        # f.write ( "%s & %s & " % ( anaId, dt[dtype] ) )
        ref = bibtex.query(anaId)
        f.write("%s~\\cite{%s} & " % (ananame, ref))
        if dtype == "efficiencyMap":
            dI = tp.dataset.dataInfo
            obsN = dI.observedN
            if (obsN - int(obsN)) < 1e-6:
                obsN = int(obsN)
            print ( "  `- %s: observedN %s, bg %s +/- %s" % \
                    ( dI.dataId, obsN, dI.expectedBG, dI.bgError ) )
            did = dI.dataId.replace("_", "\_")
            if len(did) > 9:
                did = did[:6] + " ..."
            eBG = dI.expectedBG
            if eBG == int(eBG):
                eBG = int(eBG)
            bgErr = dI.bgError
            if bgErr == int(bgErr):
                bgErr = int(bgErr)
            toterr = math.sqrt(bgErr**2 + eBG)
            if toterr > 0.:
                S = "%.1f $\sigma$" % ((dI.observedN - eBG) / toterr)
            # pids = tp.PIDs
            pids = set()
            for prod in tp.PIDs:
                for branch in prod:
                    for pid in branch:
                        if type(pid) == int and abs(pid) != 1000022:
                            pids.add(abs(pid))
                        if type(pid) in [list, tuple]:
                            p = abs(pid[0])
                            if p != 1000022:
                                pids.add(p)
            particles = namer.texName(pids,
                                      addDollars=True,
                                      addSign=False,
                                      addBrackets=False)
            obs = dI.observedN
            if obs == 0.:
                obs = 0
            else:
                if abs(obs - int(obs)) / obs < 1e-6:
                    obs = int(obs)
            sigN = tp.xsection.value.asNumber(
                fb) * tp.dataset.globalInfo.lumi.asNumber(1 / fb)
            #sigmapred="%.2f fb" % ( tp.xsection.value.asNumber(fb) )
            sigmapred = "%.2f" % sigN
            f.write ( "%s & %s & %s $\\pm$ %s & %s & %s & %s \\\\ \n" % \
                      ( did, obs, eBG, bgErr, S, particles, sigmapred ) )
        if dtype == "upperLimit":
            S = "?"
            llhd, chi2 = tp.likelihoodFromLimits(expected=False, chi2also=True)
            eUL = tp.expectedUL.asNumber(fb)
            oUL = tp.upperLimit.asNumber(fb)
            sigma_exp = eUL / 1.96  # the expected scale, sigma
            Z = (oUL - eUL) / sigma_exp
            # Z = math.sqrt ( chi2 )
            S = "%.1f $\sigma$" % Z
            pids = set()
            for prod in tp.PIDs:
                for branch in prod:
                    for pid in branch:
                        if type(pid) == int and abs(pid) != 1000022:
                            pids.add(abs(pid))
                        if type(pid) in [tuple, list]:
                            for p in pid:
                                if type(p) == int and abs(p) != 1000022:
                                    pids.add(abs(p))
            particles = namer.texName(pids,
                                      addDollars=True,
                                      addSign=False,
                                      addBrackets=False)
            sigmapred = "%.2f fb" % (tp.xsection.value.asNumber(fb))
            print("  `- observed %s, expected %s" %
                  (tp.upperLimit, tp.expectedUL))
            f.write(" & %.1f fb & %.1f fb & %s & %s & %s \\\\ \n" %
                    (tp.upperLimit.asNumber(fb), tp.expectedUL.asNumber(fb), S,
                     particles, sigmapred))
    f.write("\end{tabular}\n")
    f.close()