def doParse(dataArray,lk,outputBaseFilename,setOfRequestedColumns,column_names,dataRanges,all_best_fit_data,nBins,alt_best_fit): #Perform all numerical operations required for chain parsing # Determine the minimum log-likelihood requested as an isocontour in 2D plots min_contour = None if doProfile.value and twoDplots.value and contours2D.value: min_contour = deltaLnLike(1.0,0.01*max(contours2D.value)) # Standardise likelihood, prior and multiplicity labels, and rescale likelihood and columns if necessary standardise(dataArray,lk) # Sort array if required doSort(dataArray,lk) # Find best-fit point [bestFit,worstFit,bestFitIndex] = getBestFit(dataArray,lk,outputBaseFilename,column_names,all_best_fit_data,alt_best_fit,min_contour) # Find posterior mean [totalMult, posteriorMean] = getPosteriorMean(dataArray,lk,outputBaseFilename) # Get evidence for mcmc [lnZMain,lnZMainError] = getEvidence(dataArray,lk,bestFit,totalMult,outputBaseFilename) # Save data minima and maxima saveExtrema(dataArray,lk,outputBaseFilename,setOfRequestedColumns,dataRanges) # Save variables to plot in log scale saveLogVars(lk,outputBaseFilename,logPlots) # Save lookup keys for parameters saveLookupKeys(lk,outputBaseFilename) # Do binning for 1D plots oneDsampler(dataArray,lk,bestFit,worstFit,outputBaseFilename,dataRanges,nBins) # Do binning for 2D plots twoDsampler(dataArray,lk,bestFit,worstFit,outputBaseFilename,dataRanges,nBins)
def doParse(dataArray,lk,outputBaseFilename,setOfRequestedColumns,column_names,dataRanges,all_best_fit_data,nBins,alt_best_fit): #Perform all numerical operations required for chain parsing # Determine the minimum log-likelihood requested as an isocontour in 2D plots min_contour = None if doProfile.value and twoDplots.value and contours2D.value: min_contour = deltaLnLike(1.0,0.01*max(contours2D.value)) # Standardise likelihood, prior and multiplicity labels, and rescale likelihood and columns if necessary standardise(dataArray,lk) # Sort array if required doSort(dataArray,lk) # Find best-fit point [bestFit,worstFit,bestFitIndex] = getBestFit(dataArray,lk,outputBaseFilename,column_names,all_best_fit_data,alt_best_fit,min_contour) # Find posterior mean [totalMult, posteriorMean] = getPosteriorMean(dataArray,lk,outputBaseFilename) # Get evidence for mcmc [lnZMain,lnZMainError] = getEvidence(dataArray,lk,bestFit,totalMult,outputBaseFilename) # Save data minima and maxima saveExtrema(dataArray,lk,outputBaseFilename,setOfRequestedColumns,dataRanges) # Save lookup keys for parameters saveLookupKeys(lk,outputBaseFilename) # Do binning for 1D plots oneDsampler(dataArray,lk,bestFit,worstFit,outputBaseFilename,dataRanges,nBins) # Do binning for 2D plots twoDsampler(dataArray,lk,bestFit,worstFit,outputBaseFilename,dataRanges,nBins)
def twoDsampler(dataArray, lk, bestFit, worstFit, outputBaseFilename, dataRanges, nAllBins): # Do sample sorting for 2D plots if twoDplots.value is None: return # Determine profile likelihood contour levels (same for all plots of a given dimensionality) if contours.value is not None: profContourLevels = [np.exp(-deltaLnLike(1.0, 0.01 * contour)) for contour in contours.value] outName = outputBaseFilename + "_like2D.contours" outfile = smart_open(outName, "w") outfile.write( "# This 2D profile likelihood ratio contours file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write(" ".join([str(x) for x in profContourLevels])) outfile.close for plot in twoDplots.value: print " Parsing data for 2D plots of quantities ", plot nBins = [nAllBins[plot[j]] for j in range(2)] likeGrid = np.empty((nBins[0], nBins[1]), dtype=np.float64) likeGrid[:, :] = worstFit + 100.0 postGrid = np.zeros((nBins[0], nBins[1]), dtype=np.float64) # Work out maximum and minimum values of parameters/derived quantities minVal = [dataRanges[plot[j]][0] for j in range(2)] maxVal = [dataRanges[plot[j]][1] for j in range(2)] rangeOfVals = [maxVal[j] - minVal[j] for j in range(2)] # Pad edges of grid binSep = [rangeOfVals[j] / (nBins[j] - 2) for j in range(2)] minVal = [minVal[j] - binSep[j] for j in range(2)] maxVal = [maxVal[j] + binSep[j] for j in range(2)] rangeOfVals = [rangeOfVals[j] + 2.0 * binSep[j] for j in range(2)] # Calculate bin centres binCentresOrig = [] binCentresInterp = [] for j in range(2): binCentresOrig.append( np.array([minVal[j] + (x + 0.5) * rangeOfVals[j] / nBins[j] for x in range(nBins[j])]) ) for j in range(2): binCentresInterp.append( np.array( [ binCentresOrig[j][0] + x * (binCentresOrig[j][-1] - binCentresOrig[j][0]) / (resolution.value - 1) for x in range(resolution.value) ] ) ) # Loop over points in chain for i in range(dataArray.shape[0] - 1, -1, -1): [in1, in2] = [ min(int((dataArray[i, lk[plot[j]]] - minVal[j]) / rangeOfVals[j] * nBins[j]), nBins[j] - 2) for j in range(2) ] # Profile over likelihoods if doProfile.value: likeGrid[in1, in2] = min(dataArray[i, lk[labels.value[refLike]]], likeGrid[in1, in2]) # Marginalise by addding to posterior sample count if doPosterior.value: postGrid[in1, in2] += dataArray[i, lk[labels.value[refMult]]] # Convert -log(profile likelihoods) to profile likelihood ratio likeGrid = np.exp(bestFit - likeGrid) # Precompute co-ordinate grids for splines to avoid repetition if intMethod.value == "spline": oldCoords = np.array( [[binCentresOrig[0][i], binCentresOrig[1][j]] for i in range(nBins[0]) for j in range(nBins[1])] ) newCoords = [ [binCentresInterp[0][i], binCentresInterp[1][j]] for i in range(resolution.value) for j in range(resolution.value) ] # Interpolate posterior pdf and profile likelihood to requested display resolution if doProfile.value: if intMethod.value == "spline": likeGrid = np.array(likeGrid).reshape(nBins[0] * nBins[1]) interpolator = twoDspline(oldCoords, likeGrid) likeGrid = np.array(interpolator(newCoords)).reshape(resolution.value, resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], likeGrid, ky=1, kx=1) likeGrid = np.array( [ interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value) ] ).reshape(resolution.value, resolution.value) # Fix any points sent NaN by scipy's crappy interpolators likeGrid[np.isnan(likeGrid)] = 0.0 # Kill off any points that have been sent negative due to ringing likeGrid[np.isneginf(likeGrid)] = 0.0 likeGrid[likeGrid < 0] = 0.0 # Fix any points that have been sent >1 due to ringing likeGrid[np.isposinf(likeGrid)] = 1.0 likeGrid[likeGrid > 1] = 1.0 # Make sure we haven't erased the best-fit point by interpolating over it likeGrid[np.unravel_index(likeGrid.argmax(), likeGrid.shape)] = 1.0 if doPosterior.value: if intMethod.value == "spline": postGrid = np.array(postGrid).reshape(nBins[0] * nBins[1]) interpolator = twoDspline(oldCoords, postGrid) postGrid = np.array(interpolator(newCoords)).reshape(resolution.value, resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], postGrid, ky=1, kx=1) postGrid = np.array( [ interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value) ] ).reshape(resolution.value, resolution.value) # Kill off any points that have been sent negative due to ringing postGrid[~np.isfinite(postGrid)] = 0.0 postGrid[postGrid < 0] = 0.0 # Rescale posterior pdf back into the range [0,1] postGrid = postGrid / postGrid.max() # Find posterior pdf contour levels if contours.value is not None and doPosterior.value: # Zero posterior contour levels postContourLevels = [None for contour in contours.value] # Zero posterior integral integratedPosterior = 0.0 # Sort bins in order of posterior mass sortedPostGrid = np.ma.sort(postGrid.flatten()) # Work out the new total multiplicity totalMult = np.sum(sortedPostGrid) # Work through bins backwards until total posterior mass adds up to the requested confidence levels for i in range(sortedPostGrid.shape[0] - 1, -1, -1): integratedPosterior += sortedPostGrid[i] / totalMult for j, contour in enumerate(contours.value): if 100 * integratedPosterior >= contour and postContourLevels[j] is None: postContourLevels[j] = sortedPostGrid[i] if all([x is not None for x in postContourLevels]): break # Write profile likelihood to file if doProfile.value: outName = outputBaseFilename + "_" + "_".join([str(x) for x in plot]) + "_like2D.ct2" outfile = smart_open(outName, "w") outfile.write( "# This 2D binned profile likelihood ratio file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write( "\n".join( [ str(binCentresInterp[0][i]) + "\t" + str(binCentresInterp[1][j]) + "\t" + str(likeGrid[i, j]) for i in range(likeGrid.shape[0]) for j in range(likeGrid.shape[1]) ] ) ) outfile.close # Write posterior pdf and contours to file if doPosterior.value: outName = outputBaseFilename + "_" + "_".join([str(x) for x in plot]) + "_post2D.ct2" outfile = smart_open(outName, "w") outfile.write( "# This 2D binned posterior pdf file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write( "\n".join( [ str(binCentresInterp[0][i]) + "\t" + str(binCentresInterp[1][j]) + "\t" + str(postGrid[i, j]) for i in range(postGrid.shape[0]) for j in range(postGrid.shape[1]) ] ) ) outfile.close if contours.value is not None: outName = outputBaseFilename + "_" + "_".join([str(x) for x in plot]) + "_post2D.contours" outfile = smart_open(outName, "w") outfile.write( "# This 2D posterior pdf contours file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write(" ".join([str(x) for x in postContourLevels])) outfile.close
def oneDsampler(dataArray, lk, bestFit, worstFit, outputBaseFilename, dataRanges, nAllBins): # Do sample sorting for 1D plots if oneDplots.value is None: return if contours.value is not None: # Determine profile likelihood contour levels (same for all plots of a given dimensionality) profContourLevels = [np.exp(-deltaLnLike(0.5, 0.01 * contour)) for contour in contours.value] outfile = smart_open(outputBaseFilename + "_like1D.contours", "w") outfile.write( "# This 1D profile likelihood ratio contours file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write(" ".join([str(x) for x in profContourLevels]) + "\n") outfile.close for plot in oneDplots.value: print " Parsing data for 1D plots of quantity ", plot nBins = nAllBins[plot] likeGrid = np.empty((nBins), dtype=np.float64) likeGrid[:] = worstFit + 100.0 postGrid = np.zeros((nBins), dtype=np.float64) # Work out maximum and minimum values of parameter/derived quantity minVal = dataRanges[plot][0] maxVal = dataRanges[plot][1] rangeOfVals = maxVal - minVal binSep = rangeOfVals / nBins # Throw a sensible error if the range of values is a delta function if rangeOfVals <= 0: sys.exit( "Error: datastream " + str(plot) + " contains exactly the same " + "number for every point, so pippi cannot bin it further within its range. Does it make " + "sense to plot this quantity at all, if it is constant?" ) # Calculate bin centres binCentresOrig = np.array([minVal + (x + 0.5) * rangeOfVals / nBins for x in range(nBins)]) binCentresInterp = np.array( [ binCentresOrig[0] + x * (binCentresOrig[-1] - binCentresOrig[0]) / (resolution.value - 1) for x in range(resolution.value) ] ) # Loop over points in chain for i in range(dataArray.shape[0] - 1, -1, -1): index = min(int((dataArray[i, lk[plot]] - minVal) / rangeOfVals * nBins), nBins - 1) # Profile over likelihoods if doProfile.value: likeGrid[index] = min(dataArray[i, lk[labels.value[refLike]]], likeGrid[index]) if doPosterior.value: # Marginalise by addding to posterior sample count postGrid[index] += dataArray[i, lk[labels.value[refMult]]] # Convert -log(profile likelihoods) to profile likelihood ratio if doProfile.value: likeGrid = np.exp(bestFit - likeGrid) # Rescale posterior pdf to maximum 1 if doPosterior.value: postGrid = postGrid / postGrid.max() # Save raw binned profile likelihood and posterior pdf for outputting in histogram files if doProfile.value: likeGridHistogram = likeGrid if doPosterior.value: postGridHistogram = postGrid # Interpolate profile likelihoods and posterior pdfs to requested resolution if doProfile.value: interpolator = oneDspline(binCentresOrig, likeGrid) likeGrid = interpolator(binCentresInterp) # Fix any points sent NaN by scipy's crappy interpolators likeGrid[np.isnan(likeGrid)] = 0.0 # Kill off any points that have been sent negative due to ringing likeGrid[np.isneginf(likeGrid)] = 0.0 likeGrid[likeGrid < 0] = 0.0 # Fix any points that have been sent >1 due to ringing likeGrid[np.isposinf(likeGrid)] = 1.0 likeGrid[likeGrid > 1] = 1.0 if doPosterior.value: interpolator = oneDspline(binCentresOrig, postGrid) postGrid = interpolator(binCentresInterp) # Kill off any points that have been sent negative due to ringing postGrid[~np.isfinite(postGrid)] = 0.0 postGrid[postGrid < 0] = 0.0 # Rescale posterior pdf so that it has maximum 1 postGrid = postGrid / postGrid.max() # Find posterior pdf contour levels if contours.value is not None and doPosterior.value: # Zero posterior contour levels postContourLevels = [None for contour in contours.value] # Zero posterior integral integratedPosterior = 0.0 # Sort bins in order of posterior mass sortedPostGrid = np.ma.sort(postGrid) # Work out the new total multiplicity totalMult = np.sum(sortedPostGrid) # Work through bins backwards until total posterior mass adds up to the requested confidence levels for i in range(sortedPostGrid.shape[0] - 1, -1, -1): integratedPosterior += sortedPostGrid[i] / totalMult for j, contour in enumerate(contours.value): if 100 * integratedPosterior >= contour and postContourLevels[j] is None: postContourLevels[j] = sortedPostGrid[i] if all([x is not None for x in postContourLevels]): break # Write profile likelihood to file if doProfile.value: outfile = smart_open(outputBaseFilename + "_" + str(plot) + "_like1D.ct2", "w") outfile.write( "# This 1D binned profile likelihood ratio file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write("\n".join([str(binCentresInterp[i]) + "\t" + str(x) for i, x in enumerate(likeGrid)])) outfile.close outfile = smart_open(outputBaseFilename + "_" + str(plot) + "_like1Dhist.ct2", "w") outfile.write( "# This 1D binned profile likelihood ratio file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write( "\n".join( [ str(binCentresOrig[i] - 0.5 * binSep) + "\t" + str(x) + "\n" + str(binCentresOrig[i] + 0.5 * binSep) + "\t" + str(x) for i, x in enumerate(likeGridHistogram) ] ) ) outfile.close # Write posterior pdf and contours to file if doPosterior.value: outfile = smart_open(outputBaseFilename + "_" + str(plot) + "_post1D.ct2", "w") outfile.write( "# This 1D binned posterior pdf file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write("\n".join([str(binCentresInterp[i]) + "\t" + str(x) for i, x in enumerate(postGrid)])) outfile.close outfile = smart_open(outputBaseFilename + "_" + str(plot) + "_post1Dhist.ct2", "w") outfile.write( "# This 1D binned posterior pdf file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write( "\n".join( [ str(binCentresOrig[i] - 0.5 * binSep) + "\t" + str(x) + "\n" + str(binCentresOrig[i] + 0.5 * binSep) + "\t" + str(x) for i, x in enumerate(postGridHistogram) ] ) ) outfile.close if contours.value is not None: outfile = smart_open(outputBaseFilename + "_" + str(plot) + "_post1D.contours", "w") outfile.write( "# This 1D posterior pdf contours file created by pippi " + pippiVersion + " on " + datetime.datetime.now().strftime("%c") + "\n" ) outfile.write(" ".join([str(x) for x in postContourLevels]) + "\n") outfile.close
def twoDsampler(dataArray,lk,bestFit,worstFit,outputBaseFilename,dataRanges,nAllBins): # Do sample sorting for 2D plots if twoDplots.value is None: return # Determine profile likelihood contour levels (same for all plots of a given dimensionality) if contours2D.value is not None: profContourLevels = [np.exp(-deltaLnLike(1.0,0.01*contour)) for contour in contours2D.value] outName = outputBaseFilename+'_like2D.contours' outfile = smart_open(outName,'w') outfile.write('# This 2D profile likelihood ratio contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in profContourLevels])) outfile.close for plot in twoDplots.value: print(' Parsing data for 2D plots of quantities ',plot) nBins = [nAllBins[plot[j]] for j in range(2)] likeGrid = np.empty((nBins[0],nBins[1]), dtype=np.float64) likeGrid[:,:] = worstFit + 100.0 postGrid = np.zeros((nBins[0],nBins[1]), dtype=np.float64) num_obs = 0 if obsPlots.value is not None: for column in obsPlots.value: if column in lk: num_obs = num_obs+1 obsGrid = np.zeros((num_obs,nBins[0],nBins[1]), dtype=np.float64) k = -1 minimum_obs = np.zeros(num_obs) obsMinVal = np.zeros(num_obs) obsMaxVal = np.zeros(num_obs) obsFloor = np.zeros(num_obs) if obsPlots.value is not None: for column in obsPlots.value: if column in lk: k = k+1 obsMinVal[k] = dataArray[:,lk[column]].min() obsMaxVal[k] = dataArray[:,lk[column]].max() # temporarily set the whole grid to a very low value obsGrid[k,:,:] = obsMinVal[k] - 100 # set a value just below the actual minimum if obsMinVal[k] < 0: obsFloor[k] = obsMinVal[k]*1.01 if obsMinVal[k] > 0: obsFloor[k] = obsMinVal[k]*0.99 if obsMinVal[k] == 0: obsFloor[k] = -0.01 # Work out maximum and minimum values of parameters/derived quantities minVal = [dataRanges[plot[j]][0] for j in range(2)] maxVal = [dataRanges[plot[j]][1] for j in range(2)] rangeOfVals = [maxVal[j] - minVal[j] for j in range(2)] # Pad edges of grid binSep = [rangeOfVals[j]/(nBins[j]-2) for j in range(2)] minVal = [minVal[j] - binSep[j] for j in range(2)] maxVal = [maxVal[j] + binSep[j] for j in range(2)] rangeOfVals = [rangeOfVals[j] + 2.0 * binSep[j] for j in range(2)] # Calculate bin centres binCentresOrig = [] binCentresInterp = [] for j in range(2): binCentresOrig.append(np.array([minVal[j] + (x+0.5)*rangeOfVals[j]/nBins[j] for x in range(nBins[j])])) for j in range(2): binCentresInterp.append(np.array([binCentresOrig[j][0] + x*(binCentresOrig[j][-1]-binCentresOrig[j][0])\ /(resolution.value-1) for x in range(resolution.value)])) # Loop over points in chain for i in range(dataArray.shape[0]-1,-1,-1): [in1,in2] = [min(int((dataArray[i,lk[plot[j]]]-minVal[j])/rangeOfVals[j]*nBins[j]),nBins[j]-2) for j in range(2)] # Take observable at maximum likelihood for this bin if dataArray[i,lk[labels.value[refLike]]] < likeGrid[in1,in2]: if obsPlots.value is not None: k = -1 for column in obsPlots.value: if column in lk: k = k + 1 obsGrid[k,in1,in2] = dataArray[i,lk[column]] # Profile over likelihoods if doProfile.value: likeGrid[in1,in2] = min(dataArray[i,lk[labels.value[refLike]]],likeGrid[in1,in2]) # Marginalise by addding to posterior sample count if doPosterior.value: postGrid[in1,in2] += dataArray[i,lk[labels.value[refMult]]] # Convert -log(profile likelihoods) to profile likelihood ratio likeGrid = np.exp(bestFit - likeGrid) #obsFloor = np.zeros(k+1) k = -1 if obsPlots.value is not None: for column in obsPlots.value: if column in lk: k = k + 1 obsContourLevels = [obsFloor[k],obsMinVal[k],obsMaxVal[k]] outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_obs2D_' + str(column) + '.contours' outfile = smart_open(outName,'w') outfile.write('# This 2D observable color-map levels file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in obsContourLevels])) outfile.close # Precompute co-ordinate grids for splines to avoid repetition if intMethod.value == 'spline': oldCoords = np.array([[binCentresOrig[0][i], binCentresOrig[1][j]] for i in range(nBins[0]) for j in range(nBins[1])]) newCoords = [[binCentresInterp[0][i], binCentresInterp[1][j]] for i in range(resolution.value) for j in range(resolution.value)] # Interpolate posterior pdf, profile likelihood and observable to requested display resolution if doProfile.value: if intMethod.value == 'spline': likeGrid = np.array(likeGrid).reshape(nBins[0]*nBins[1]) interpolator = twoDspline(oldCoords,likeGrid) likeGrid = np.array(interpolator(newCoords)).reshape(resolution.value,resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], likeGrid, ky = 1, kx = 1) likeGrid = np.array([interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value)]).reshape(resolution.value,resolution.value) # Fix any points sent NaN by scipy's crappy interpolators likeGrid[np.isnan(likeGrid)] = 0.0 # Kill off any points that have been sent negative due to ringing likeGrid[np.isneginf(likeGrid)] = 0.0 likeGrid[likeGrid<0] = 0.0 # Fix any points that have been sent >1 due to ringing likeGrid[np.isposinf(likeGrid)] = 1.0 likeGrid[likeGrid>1] = 1.0 # Make sure we haven't erased the best-fit point by interpolating over it likeGrid[np.unravel_index(likeGrid.argmax(),likeGrid.shape)] = 1.0 if doPosterior.value: if intMethod.value == 'spline': postGrid = np.array(postGrid).reshape(nBins[0]*nBins[1]) interpolator = twoDspline(oldCoords,postGrid) postGrid = np.array(interpolator(newCoords)).reshape(resolution.value,resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], postGrid, ky = 1, kx = 1) postGrid = np.array([interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value)]).reshape(resolution.value,resolution.value) # Kill off any points that have been sent negative due to ringing postGrid[~np.isfinite(postGrid)] = 0.0 postGrid[postGrid<0] = 0.0 # Rescale posterior pdf back into the range [0,1] postGrid = postGrid / postGrid.max() if obsPlots.value is not None: k = -1 for column in obsPlots.value: if column in lk: k = k + 1 obsGrid_temp = obsGrid[k,:,:] obsGrid_temp[obsGrid_temp == (obsMinVal[k]-100) ] = obsMinVal[k] if intMethod.value == 'spline': obsGrid_temp = np.array(obsGrid_temp).reshape(nBins[0]*nBins[1]) interpolator = twoDspline(oldCoords,obsGrid_temp) obsGrid_temp = np.array(interpolator(newCoords)).reshape(resolution.value,resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], obsGrid_temp, ky = 1, kx = 1) obsGrid_temp = np.array([interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value)]).reshape(resolution.value,resolution.value) obsGrid_temp[obsGrid_temp < obsMinVal[k] ] = obsMinVal[k] # set points outside the contours to the floor value (effectively "no data") obsGrid_temp[likeGrid<min(profContourLevels)] = obsFloor[k] # Write observable to file outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_obs2D_'+str(column)+'.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned observable file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(obsGrid_temp[i,j]) \ for i in range(obsGrid_temp.shape[0]) for j in range(obsGrid_temp.shape[1])])) outfile.close # make a dummy grid with maximum and minimum values (of the reduced grid) to use for colorbar obsGrid_temp_list = obsGrid_temp.reshape(obsGrid_temp.shape[1] * obsGrid_temp.shape[0] ) obsGrid_temp_list = obsGrid_temp_list[obsGrid_temp_list != obsFloor[k]] obsMinValReduced = obsGrid_temp_list.min() obsMaxValReduced = obsGrid_temp_list.max() dummyGrid = np.zeros([2, 3]) dummyGrid[0,0] = binCentresInterp[0][0] dummyGrid[0,1] = binCentresInterp[0][0] dummyGrid[0,2] = obsMinValReduced dummyGrid[1,0] = binCentresInterp[0][1] dummyGrid[1,1] = binCentresInterp[0][1] dummyGrid[1,2] = obsMaxValReduced outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_obs2D_'+str(column)+'_colorbar.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned observable file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(dummyGrid[i,0])+'\t'+str(dummyGrid[i,1])+'\t'+str(dummyGrid[i,2]) \ for i in range(2) ])) outfile.close # Find posterior pdf contour levels if contours2D.value is not None and doPosterior.value: # Zero posterior contour levels postContourLevels = [None for contour in contours2D.value] # Zero posterior integral integratedPosterior = 0.0 # Sort bins in order of posterior mass sortedPostGrid = np.ma.sort(postGrid.flatten()) # Work out the new total multiplicity totalMult = np.sum(sortedPostGrid) # Work through bins backwards until total posterior mass adds up to the requested confidence levels for i in range(sortedPostGrid.shape[0]-1,-1,-1): integratedPosterior += sortedPostGrid[i]/totalMult for j,contour in enumerate(contours2D.value): if 100*integratedPosterior >= contour and postContourLevels[j] is None: postContourLevels[j] = sortedPostGrid[i] if all([x is not None for x in postContourLevels]): break # Write profile likelihood to file if doProfile.value: outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_like2D.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned profile likelihood ratio file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(likeGrid[i,j]) \ for i in range(likeGrid.shape[0]) for j in range(likeGrid.shape[1])])) outfile.close # Write posterior pdf and contours to file if doPosterior.value: outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_post2D.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned posterior pdf file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(postGrid[i,j]) \ for i in range(postGrid.shape[0]) for j in range(postGrid.shape[1])])) outfile.close if contours2D.value is not None: outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_post2D.contours' outfile = smart_open(outName,'w') outfile.write('# This 2D posterior pdf contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in postContourLevels])) outfile.close
def oneDsampler(dataArray,lk,bestFit,worstFit,outputBaseFilename,dataRanges,nAllBins): # Do sample sorting for 1D plots if oneDplots.value is None: return if contours1D.value is not None: # Determine profile likelihood contour levels (same for all plots of a given dimensionality) profContourLevels = [np.exp(-deltaLnLike(0.5,0.01*contour)) for contour in contours1D.value] outfile = smart_open(outputBaseFilename+'_like1D.contours','w') outfile.write('# This 1D profile likelihood ratio contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in profContourLevels])+'\n') outfile.close for plot in oneDplots.value: print(' Parsing data for 1D plots of quantity ',plot) nBins = nAllBins[plot] likeGrid = np.empty((nBins), dtype=np.float64) likeGrid[:] = worstFit + 100.0 postGrid = np.zeros((nBins), dtype=np.float64) # Work out maximum and minimum values of parameter/derived quantity minVal = dataRanges[plot][0] maxVal = dataRanges[plot][1] rangeOfVals = maxVal - minVal # Fix things if the range of values is a delta function if (rangeOfVals <= 0): rangeOfVals = maxVal * 1e-3 binSep = rangeOfVals / nBins # Calculate bin centres binCentresOrig = np.array([minVal + (x+0.5)*rangeOfVals/nBins for x in range(nBins)]) binCentresInterp = np.array([binCentresOrig[0] + x*(binCentresOrig[-1]-binCentresOrig[0])\ /(resolution.value-1) for x in range(resolution.value)]) # Loop over points in chain for i in range(dataArray.shape[0]-1,-1,-1): index = min(int((dataArray[i,lk[plot]]-minVal)/rangeOfVals*nBins),nBins-1) # Profile over likelihoods if doProfile.value: likeGrid[index] = min(dataArray[i,lk[labels.value[refLike]]],likeGrid[index]) if doPosterior.value: # Marginalise by addding to posterior sample count postGrid[index] += dataArray[i,lk[labels.value[refMult]]] # Convert -log(profile likelihoods) to profile likelihood ratio if doProfile.value: likeGrid = np.exp(bestFit - likeGrid) # Rescale posterior pdf to maximum 1 if doPosterior.value: postGrid = postGrid / postGrid.max() # Save raw binned profile likelihood and posterior pdf for outputting in histogram files if doProfile.value: likeGridHistogram = likeGrid if doPosterior.value: postGridHistogram = postGrid # Interpolate profile likelihoods and posterior pdfs to requested resolution if doProfile.value: interpolator = oneDspline(binCentresOrig, likeGrid) likeGrid = interpolator(binCentresInterp) # Fix any points sent NaN by scipy's crappy interpolators likeGrid[np.isnan(likeGrid)] = 0.0 # Kill off any points that have been sent negative due to ringing likeGrid[np.isneginf(likeGrid)] = 0.0 likeGrid[likeGrid<0] = 0.0 # Fix any points that have been sent >1 due to ringing likeGrid[np.isposinf(likeGrid)] = 1.0 likeGrid[likeGrid>1] = 1.0 if doPosterior.value: interpolator = oneDspline(binCentresOrig, postGrid) postGrid = interpolator(binCentresInterp) # Kill off any points that have been sent negative due to ringing postGrid[~np.isfinite(postGrid)] = 0.0 postGrid[postGrid<0] = 0.0 # Rescale posterior pdf so that it has maximum 1 postGrid = postGrid / postGrid.max() # Find posterior pdf contour levels if contours1D.value is not None and doPosterior.value: # Zero posterior contour levels postContourLevels = [None for contour in contours1D.value] # Zero posterior integral integratedPosterior = 0.0 # Sort bins in order of posterior mass sortedPostGrid = np.ma.sort(postGrid) # Work out the new total multiplicity totalMult = np.sum(sortedPostGrid) # Work through bins backwards until total posterior mass adds up to the requested confidence levels for i in range(sortedPostGrid.shape[0]-1,-1,-1): integratedPosterior += sortedPostGrid[i]/totalMult for j,contour in enumerate(contours1D.value): if 100*integratedPosterior >= contour and postContourLevels[j] is None: postContourLevels[j] = sortedPostGrid[i] if all([x is not None for x in postContourLevels]): break # Write profile likelihood to file if doProfile.value: outfile = smart_open(outputBaseFilename+'_'+str(plot)+'_like1D.ct2','w') outfile.write('# This 1D binned profile likelihood ratio file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[i])+'\t'+str(x) for i,x in enumerate(likeGrid)])) outfile.close outfile = smart_open(outputBaseFilename+'_'+str(plot)+'_like1Dhist.ct2','w') outfile.write('# This 1D binned profile likelihood ratio file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresOrig[i]-0.5*binSep)+'\t'+str(x)+'\n'+ str(binCentresOrig[i]+0.5*binSep)+'\t'+str(x) for i,x in enumerate(likeGridHistogram)])) outfile.close # Write posterior pdf and contours to file if doPosterior.value: outfile = smart_open(outputBaseFilename+'_'+str(plot)+'_post1D.ct2','w') outfile.write('# This 1D binned posterior pdf file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[i])+'\t'+str(x) for i,x in enumerate(postGrid)])) outfile.close outfile = smart_open(outputBaseFilename+'_'+str(plot)+'_post1Dhist.ct2','w') outfile.write('# This 1D binned posterior pdf file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresOrig[i]-0.5*binSep)+'\t'+str(x)+'\n'+ str(binCentresOrig[i]+0.5*binSep)+'\t'+str(x) for i,x in enumerate(postGridHistogram)])) outfile.close if contours1D.value is not None: outfile = smart_open(outputBaseFilename+'_'+str(plot)+'_post1D.contours','w') outfile.write('# This 1D posterior pdf contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in postContourLevels])+'\n') outfile.close
def twoDsampler(dataArray,lk,bestFit,worstFit,outputBaseFilename,dataRanges,nAllBins): # Do sample sorting for 2D plots if twoDplots.value is None: return # Determine profile likelihood contour levels (same for all plots of a given dimensionality) if contours2D.value is not None: profContourLevels = [np.exp(-deltaLnLike(1.0,0.01*contour)) for contour in contours2D.value] outName = outputBaseFilename+'_like2D.contours' outfile = smart_open(outName,'w') outfile.write('# This 2D profile likelihood ratio contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in profContourLevels])) outfile.close for plot in twoDplots.value: print ' Parsing data for 2D plots of quantities ',plot nBins = [nAllBins[plot[j]] for j in range(2)] likeGrid = np.empty((nBins[0],nBins[1]), dtype=np.float64) likeGrid[:,:] = worstFit + 100.0 postGrid = np.zeros((nBins[0],nBins[1]), dtype=np.float64) num_obs = 0 if obsPlots.value is not None: for column in obsPlots.value: if column in lk: num_obs = num_obs+1 obsGrid = np.zeros((num_obs,nBins[0],nBins[1]), dtype=np.float64) k = -1 minimum_obs = np.zeros(num_obs) obsMinVal = np.zeros(num_obs) obsMaxVal = np.zeros(num_obs) obsFloor = np.zeros(num_obs) if obsPlots.value is not None: for column in obsPlots.value: if column in lk: k = k+1 obsMinVal[k] = dataArray[:,lk[column]].min() obsMaxVal[k] = dataArray[:,lk[column]].max() # temporarily set the whole grid to a very low value obsGrid[k,:,:] = obsMinVal[k] - 100 # set a value just below the actual minimum if obsMinVal[k] < 0: obsFloor[k] = obsMinVal[k]*1.01 if obsMinVal[k] > 0: obsFloor[k] = obsMinVal[k]*0.99 if obsMinVal[k] == 0: obsFloor[k] = -0.01 # Work out maximum and minimum values of parameters/derived quantities minVal = [dataRanges[plot[j]][0] for j in range(2)] maxVal = [dataRanges[plot[j]][1] for j in range(2)] rangeOfVals = [maxVal[j] - minVal[j] for j in range(2)] # Pad edges of grid binSep = [rangeOfVals[j]/(nBins[j]-2) for j in range(2)] minVal = [minVal[j] - binSep[j] for j in range(2)] maxVal = [maxVal[j] + binSep[j] for j in range(2)] rangeOfVals = [rangeOfVals[j] + 2.0 * binSep[j] for j in range(2)] # Calculate bin centres binCentresOrig = [] binCentresInterp = [] for j in range(2): binCentresOrig.append(np.array([minVal[j] + (x+0.5)*rangeOfVals[j]/nBins[j] for x in range(nBins[j])])) for j in range(2): binCentresInterp.append(np.array([binCentresOrig[j][0] + x*(binCentresOrig[j][-1]-binCentresOrig[j][0])\ /(resolution.value-1) for x in range(resolution.value)])) # Loop over points in chain for i in range(dataArray.shape[0]-1,-1,-1): [in1,in2] = [min(int((dataArray[i,lk[plot[j]]]-minVal[j])/rangeOfVals[j]*nBins[j]),nBins[j]-2) for j in range(2)] # Take observable at maximum likelihood for this bin if dataArray[i,lk[labels.value[refLike]]] < likeGrid[in1,in2]: if obsPlots.value is not None: k = -1 for column in obsPlots.value: if column in lk: k = k + 1 obsGrid[k,in1,in2] = dataArray[i,lk[column]] # Profile over likelihoods if doProfile.value: likeGrid[in1,in2] = min(dataArray[i,lk[labels.value[refLike]]],likeGrid[in1,in2]) # Marginalise by addding to posterior sample count if doPosterior.value: postGrid[in1,in2] += dataArray[i,lk[labels.value[refMult]]] # Convert -log(profile likelihoods) to profile likelihood ratio likeGrid = np.exp(bestFit - likeGrid) #obsFloor = np.zeros(k+1) k = -1 if obsPlots.value is not None: for column in obsPlots.value: if column in lk: k = k + 1 obsContourLevels = [obsFloor[k],obsMinVal[k],obsMaxVal[k]] outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_obs2D_' + str(column) + '.contours' outfile = smart_open(outName,'w') outfile.write('# This 2D observable color-map levels file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in obsContourLevels])) outfile.close # Precompute co-ordinate grids for splines to avoid repetition if intMethod.value == 'spline': oldCoords = np.array([[binCentresOrig[0][i], binCentresOrig[1][j]] for i in range(nBins[0]) for j in range(nBins[1])]) newCoords = [[binCentresInterp[0][i], binCentresInterp[1][j]] for i in range(resolution.value) for j in range(resolution.value)] # Interpolate posterior pdf, profile likelihood and observable to requested display resolution if doProfile.value: if intMethod.value == 'spline': likeGrid = np.array(likeGrid).reshape(nBins[0]*nBins[1]) interpolator = twoDspline(oldCoords,likeGrid) likeGrid = np.array(interpolator(newCoords)).reshape(resolution.value,resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], likeGrid, ky = 1, kx = 1) likeGrid = np.array([interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value)]).reshape(resolution.value,resolution.value) # Fix any points sent NaN by scipy's crappy interpolators likeGrid[np.isnan(likeGrid)] = 0.0 # Kill off any points that have been sent negative due to ringing likeGrid[np.isneginf(likeGrid)] = 0.0 likeGrid[likeGrid<0] = 0.0 # Fix any points that have been sent >1 due to ringing likeGrid[np.isposinf(likeGrid)] = 1.0 likeGrid[likeGrid>1] = 1.0 # Make sure we haven't erased the best-fit point by interpolating over it likeGrid[np.unravel_index(likeGrid.argmax(),likeGrid.shape)] = 1.0 if doPosterior.value: if intMethod.value == 'spline': postGrid = np.array(postGrid).reshape(nBins[0]*nBins[1]) interpolator = twoDspline(oldCoords,postGrid) postGrid = np.array(interpolator(newCoords)).reshape(resolution.value,resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], postGrid, ky = 1, kx = 1) postGrid = np.array([interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value)]).reshape(resolution.value,resolution.value) # Kill off any points that have been sent negative due to ringing postGrid[~np.isfinite(postGrid)] = 0.0 postGrid[postGrid<0] = 0.0 # Rescale posterior pdf back into the range [0,1] postGrid = postGrid / postGrid.max() if obsPlots.value is not None: k = -1 for column in obsPlots.value: if column in lk: k = k + 1 obsGrid_temp = obsGrid[k,:,:] obsGrid_temp[obsGrid_temp == (obsMinVal[k]-100) ] = obsMinVal[k] if intMethod.value == 'spline': obsGrid_temp = np.array(obsGrid_temp).reshape(nBins[0]*nBins[1]) interpolator = twoDspline(oldCoords,obsGrid_temp) obsGrid_temp = np.array(interpolator(newCoords)).reshape(resolution.value,resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], obsGrid_temp, ky = 1, kx = 1) obsGrid_temp = np.array([interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value)]).reshape(resolution.value,resolution.value) obsGrid_temp[obsGrid_temp < obsMinVal[k] ] = obsMinVal[k] # set points outside the contours to the floor value (effectively "no data") obsGrid_temp[likeGrid<min(profContourLevels)] = obsFloor[k] # Write observable to file outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_obs2D_'+str(column)+'.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned observable file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(obsGrid_temp[i,j]) \ for i in range(obsGrid_temp.shape[0]) for j in range(obsGrid_temp.shape[1])])) outfile.close # make a dummy grid with maximum and minimum values (of the reduced grid) to use for colorbar obsGrid_temp_list = obsGrid_temp.reshape(obsGrid_temp.shape[1] * obsGrid_temp.shape[0] ) obsGrid_temp_list = obsGrid_temp_list[obsGrid_temp_list != obsFloor[k]] obsMinValReduced = obsGrid_temp_list.min() obsMaxValReduced = obsGrid_temp_list.max() dummyGrid = np.zeros([2, 3]) dummyGrid[0,0] = binCentresInterp[0][0] dummyGrid[0,1] = binCentresInterp[0][0] dummyGrid[0,2] = obsMinValReduced dummyGrid[1,0] = binCentresInterp[0][1] dummyGrid[1,1] = binCentresInterp[0][1] dummyGrid[1,2] = obsMaxValReduced outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_obs2D_'+str(column)+'_colorbar.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned observable file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(dummyGrid[i,0])+'\t'+str(dummyGrid[i,1])+'\t'+str(dummyGrid[i,2]) \ for i in range(2) ])) outfile.close # Find posterior pdf contour levels if contours2D.value is not None and doPosterior.value: # Zero posterior contour levels postContourLevels = [None for contour in contours2D.value] # Zero posterior integral integratedPosterior = 0.0 # Sort bins in order of posterior mass sortedPostGrid = np.ma.sort(postGrid.flatten()) # Work out the new total multiplicity totalMult = np.sum(sortedPostGrid) # Work through bins backwards until total posterior mass adds up to the requested confidence levels for i in range(sortedPostGrid.shape[0]-1,-1,-1): integratedPosterior += sortedPostGrid[i]/totalMult for j,contour in enumerate(contours2D.value): if 100*integratedPosterior >= contour and postContourLevels[j] is None: postContourLevels[j] = sortedPostGrid[i] if all([x is not None for x in postContourLevels]): break # Write profile likelihood to file if doProfile.value: outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_like2D.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned profile likelihood ratio file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(likeGrid[i,j]) \ for i in range(likeGrid.shape[0]) for j in range(likeGrid.shape[1])])) outfile.close # Write posterior pdf and contours to file if doPosterior.value: outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_post2D.ct2' outfile = smart_open(outName,'w') outfile.write('# This 2D binned posterior pdf file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(postGrid[i,j]) \ for i in range(postGrid.shape[0]) for j in range(postGrid.shape[1])])) outfile.close if contours2D.value is not None: outName = outputBaseFilename+'_'+'_'.join([str(x) for x in plot])+'_post2D.contours' outfile = smart_open(outName,'w') outfile.write('# This 2D posterior pdf contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in postContourLevels])) outfile.close
def twoDsampler(dataArray, lk, bestFit, worstFit, outputBaseFilename, dataRanges, nAllBins): # Do sample sorting for 2D plots if twoDplots.value is None: return # Determine profile likelihood contour levels (same for all plots of a given dimensionality) if contours2D.value is not None: profContourLevels = [ np.exp(-deltaLnLike(1.0, 0.01 * contour)) for contour in contours2D.value ] outName = outputBaseFilename + '_like2D.contours' outfile = smart_open(outName, 'w') outfile.write('# This 2D profile likelihood ratio contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in profContourLevels])) outfile.close for plot in twoDplots.value: print ' Parsing data for 2D plots of quantities ', plot nBins = [nAllBins[plot[j]] for j in range(2)] likeGrid = np.empty((nBins[0], nBins[1]), dtype=np.float64) likeGrid[:, :] = worstFit + 100.0 postGrid = np.zeros((nBins[0], nBins[1]), dtype=np.float64) # Work out maximum and minimum values of parameters/derived quantities minVal = [dataRanges[plot[j]][0] for j in range(2)] maxVal = [dataRanges[plot[j]][1] for j in range(2)] rangeOfVals = [maxVal[j] - minVal[j] for j in range(2)] # Pad edges of grid binSep = [rangeOfVals[j] / (nBins[j] - 2) for j in range(2)] minVal = [minVal[j] - binSep[j] for j in range(2)] maxVal = [maxVal[j] + binSep[j] for j in range(2)] rangeOfVals = [rangeOfVals[j] + 2.0 * binSep[j] for j in range(2)] # Calculate bin centres binCentresOrig = [] binCentresInterp = [] for j in range(2): binCentresOrig.append( np.array([ minVal[j] + (x + 0.5) * rangeOfVals[j] / nBins[j] for x in range(nBins[j]) ])) for j in range(2): binCentresInterp.append(np.array([binCentresOrig[j][0] + x*(binCentresOrig[j][-1]-binCentresOrig[j][0])\ /(resolution.value-1) for x in range(resolution.value)])) # Loop over points in chain for i in range(dataArray.shape[0] - 1, -1, -1): [in1, in2] = [ min( int((dataArray[i, lk[plot[j]]] - minVal[j]) / rangeOfVals[j] * nBins[j]), nBins[j] - 2) for j in range(2) ] # Profile over likelihoods if doProfile.value: likeGrid[in1, in2] = min(dataArray[i, lk[labels.value[refLike]]], likeGrid[in1, in2]) # Marginalise by addding to posterior sample count if doPosterior.value: postGrid[in1, in2] += dataArray[i, lk[labels.value[refMult]]] # Convert -log(profile likelihoods) to profile likelihood ratio likeGrid = np.exp(bestFit - likeGrid) # Precompute co-ordinate grids for splines to avoid repetition if intMethod.value == 'spline': oldCoords = np.array([[binCentresOrig[0][i], binCentresOrig[1][j]] for i in range(nBins[0]) for j in range(nBins[1])]) newCoords = [[binCentresInterp[0][i], binCentresInterp[1][j]] for i in range(resolution.value) for j in range(resolution.value)] # Interpolate posterior pdf and profile likelihood to requested display resolution if doProfile.value: if intMethod.value == 'spline': likeGrid = np.array(likeGrid).reshape(nBins[0] * nBins[1]) interpolator = twoDspline(oldCoords, likeGrid) likeGrid = np.array(interpolator(newCoords)).reshape( resolution.value, resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], likeGrid, ky=1, kx=1) likeGrid = np.array([ interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value) ]).reshape(resolution.value, resolution.value) # Fix any points sent NaN by scipy's crappy interpolators likeGrid[np.isnan(likeGrid)] = 0.0 # Kill off any points that have been sent negative due to ringing likeGrid[np.isneginf(likeGrid)] = 0.0 likeGrid[likeGrid < 0] = 0.0 # Fix any points that have been sent >1 due to ringing likeGrid[np.isposinf(likeGrid)] = 1.0 likeGrid[likeGrid > 1] = 1.0 # Make sure we haven't erased the best-fit point by interpolating over it likeGrid[np.unravel_index(likeGrid.argmax(), likeGrid.shape)] = 1.0 if doPosterior.value: if intMethod.value == 'spline': postGrid = np.array(postGrid).reshape(nBins[0] * nBins[1]) interpolator = twoDspline(oldCoords, postGrid) postGrid = np.array(interpolator(newCoords)).reshape( resolution.value, resolution.value) else: interpolator = twoDbilinear(binCentresOrig[0], binCentresOrig[1], postGrid, ky=1, kx=1) postGrid = np.array([ interpolator(binCentresInterp[0][j], binCentresInterp[1][i]) for j in range(resolution.value) for i in range(resolution.value) ]).reshape(resolution.value, resolution.value) # Kill off any points that have been sent negative due to ringing postGrid[~np.isfinite(postGrid)] = 0.0 postGrid[postGrid < 0] = 0.0 # Rescale posterior pdf back into the range [0,1] postGrid = postGrid / postGrid.max() # Find posterior pdf contour levels if contours2D.value is not None and doPosterior.value: # Zero posterior contour levels postContourLevels = [None for contour in contours2D.value] # Zero posterior integral integratedPosterior = 0.0 # Sort bins in order of posterior mass sortedPostGrid = np.ma.sort(postGrid.flatten()) # Work out the new total multiplicity totalMult = np.sum(sortedPostGrid) # Work through bins backwards until total posterior mass adds up to the requested confidence levels for i in range(sortedPostGrid.shape[0] - 1, -1, -1): integratedPosterior += sortedPostGrid[i] / totalMult for j, contour in enumerate(contours2D.value): if 100 * integratedPosterior >= contour and postContourLevels[ j] is None: postContourLevels[j] = sortedPostGrid[i] if all([x is not None for x in postContourLevels]): break # Write profile likelihood to file if doProfile.value: outName = outputBaseFilename + '_' + '_'.join( [str(x) for x in plot]) + '_like2D.ct2' outfile = smart_open(outName, 'w') outfile.write('# This 2D binned profile likelihood ratio file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(likeGrid[i,j]) \ for i in range(likeGrid.shape[0]) for j in range(likeGrid.shape[1])])) outfile.close # Write posterior pdf and contours to file if doPosterior.value: outName = outputBaseFilename + '_' + '_'.join( [str(x) for x in plot]) + '_post2D.ct2' outfile = smart_open(outName, 'w') outfile.write('# This 2D binned posterior pdf file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write('\n'.join([str(binCentresInterp[0][i])+'\t'+str(binCentresInterp[1][j])+'\t'+str(postGrid[i,j]) \ for i in range(postGrid.shape[0]) for j in range(postGrid.shape[1])])) outfile.close if contours2D.value is not None: outName = outputBaseFilename + '_' + '_'.join( [str(x) for x in plot]) + '_post2D.contours' outfile = smart_open(outName, 'w') outfile.write('# This 2D posterior pdf contours file created by pippi '\ +pippiVersion+' on '+datetime.datetime.now().strftime('%c')+'\n') outfile.write(' '.join([str(x) for x in postContourLevels])) outfile.close