Ejemplo n.º 1
0
def rangeUnits(textBox, array):
    # For some reason, max() doesn't work on numpy arrays containing non-finite numbers
    maxValue = float('-inf')
    for value in array:
        if isfinite(value) and value > maxValue:
            maxValue = value
    if textBox.unit != '':
        unit = util.displayWithUnitsNumber(maxValue, textBox.unit).split()[1]
        rangeInUnits = [util.convertUnitsNumber(value, textBox.unit, unit) for value in array]
    else:
        power = int(round(floor(log10(abs(maxValue)))/3)*3) # round power to nearest multiple of 3
        unit = '10^' + str(power) if power != 0 else ''
        rangeInUnits = [x/(10**power) for x in array]

    axisLabel = textBox.objectName() + (' (' + unit + ')' if unit else '')
    return unit, axisLabel, rangeInUnits
Ejemplo n.º 2
0
    def refreshPlots(self):
        self.parent.ui.statusbar.showMessage('Redrawing plots ...')
        self.erasePlots()

        # nothing to plot, if beam hasn't been initialized
        if not self.myBunch:
            return

        # get the specified units for plotting
        self.unitsPos = self.ui.unitsPos.text()
        self.unitsAngle = self.ui.unitsAngle.text()

        # get the number of tick marks
        self.numTicks = int(self.ui.numTicks.text())

        # create local pointer to particle array
        tmp6 = randomSampleOfBunch(
                self.myBunch.getDistribution6D().getPhaseSpace6D().getArray6D(),
                min(self.maxParticles, int(self.ui.numPtcls.text())))

        numParticles = tmp6.shape[1]

        self.calculateLimits(tmp6)

        nLevels = 5 + int(math.pow(numParticles, 0.33333333))
        nDivs = 10 + int(math.pow(numParticles, 0.2))

        # generate the four plots
        self.plotXY( util.convertUnitsNumber(tmp6[0,:], 'm', self.unitsPos),
                     util.convertUnitsNumber(tmp6[2,:], 'm', self.unitsPos),
                     nDivs, nLevels)

        self.plotXPX(util.convertUnitsNumber(tmp6[0,:], 'm', self.unitsPos),
                     util.convertUnitsNumber(tmp6[1,:], 'rad', self.unitsAngle),
                     nDivs, nLevels)

        self.plotYPY(util.convertUnitsNumber(tmp6[2,:], 'm', self.unitsPos),
                     util.convertUnitsNumber(tmp6[3,:], 'rad', self.unitsAngle),
                     nDivs, nLevels)

        self.plotSDP(util.convertUnitsNumber(tmp6[4,:], 'm', self.unitsPos),
                     util.convertUnitsNumber(tmp6[5,:], 'rad', self.unitsAngle),
                     nDivs, nLevels)

        self.parent.ui.statusbar.clearMessage()
Ejemplo n.º 3
0
    def plot(self):
        try:
            xTextBox = self.textBox[self.ui.x.currentText()]
            xOrginalValue = xTextBox.text()
            yTextBox = self.textBox[self.ui.y.currentText()]
            yOrginalValue = yTextBox.text()
            zTextBox = self.textBox[self.ui.z.currentText()]
        except KeyError:
            return # Combo box choice was left blank

        try:
            xmin = util.convertUnitsStringToNumber(self.ui.xmin.text(), xTextBox.unit)
            xmax = util.convertUnitsStringToNumber(self.ui.xmax.text(), xTextBox.unit)
            if xmin > xmax:
                xmin, xmax = xmax, xmin

            ymin = util.convertUnitsStringToNumber(self.ui.ymin.text(), yTextBox.unit)
            ymax = util.convertUnitsStringToNumber(self.ui.ymax.text(), yTextBox.unit)
            if ymin > ymax:
                ymin, ymax = ymax, ymin

        except ValueError: # text box left blank
            return

        numPoints = 32 # per variable, 32*32 = 1,024 points total

        xRange = numpy.linspace(xmin, xmax, numPoints)
        _, xAxisLabel, xRangeUnits = rangeUnits(xTextBox, xRange)

        yRange = numpy.linspace(ymin, ymax, numPoints)
        _, yAxisLabel, yRangeUnits = rangeUnits(yTextBox, yRange)

        Z = numpy.zeros((numPoints, numPoints))
        plotProgress = QtGui.QProgressDialog("Plotting ...", None, 0, (numPoints**2)-1)
        plotProgress.setMinimumDuration(0)

        try:
            for j, x in enumerate(xRange):
                for i, y in enumerate(yRange):
                    plotProgress.setValue(plotProgress.value()+1)
                    xTextBox.setText(str(x))
                    yTextBox.setText(str(y))
                    results = calculate(self.userInputDict())
                    try:
                        Z[i,j] = results[zTextBox.dictName]
                    except KeyError:
                        Z[i,j] = float('nan')

            zUnit, zAxisLabel, _ = rangeUnits(zTextBox, Z.flat)
            for z in numpy.nditer(Z, op_flags=['readwrite']):
                z[...] = util.convertUnitsNumber(z, zTextBox.unit, zUnit)

            # Plotting
            self.ui.plotWidget.canvas.fig.clear()
            self.ui.plotWidget.canvas.ax = self.ui.plotWidget.canvas.fig.add_subplot(111)
            c = self.ui.plotWidget.canvas.ax.imshow(numpy.flipud(Z), cmap = 'hot',
                    extent = [min(xRangeUnits), max(xRangeUnits),
                    min(yRangeUnits), max(yRangeUnits)],
                    aspect = 'auto')
            self.ui.plotWidget.canvas.ax.set_xlabel(xAxisLabel)
            self.ui.plotWidget.canvas.ax.set_ylabel(yAxisLabel)
            cb = self.ui.plotWidget.canvas.fig.colorbar(c)
            cb.set_label(zAxisLabel)
            self.ui.plotWidget.canvas.ax.set_xlim(min(xRangeUnits), max(xRangeUnits))
            self.ui.plotWidget.canvas.ax.set_ylim(min(yRangeUnits), max(yRangeUnits))
            self.ui.plotWidget.canvas.fig.tight_layout()
            self.ui.plotWidget.canvas.draw()

        finally:
            # Restore text boxes to original state
            xTextBox.setText(xOrginalValue)
            xTextBox.setCursorPosition(0)
            yTextBox.setText(yOrginalValue)
            yTextBox.setCursorPosition(0)
            self.calculateAll()
Ejemplo n.º 4
0
    def calculateLimits(self, _arr):
        # nothing to do, if beam hasn't been initialized
        if not self.myBunch:
            return

        # get average, RMS, min, max values and diffs
        avgArray = self.myStat.calcAverages6D(_arr)
        rmsArray = self.myStat.calcRmsValues6D(_arr)
        minArray = self.myStat.calcMinValues6D(_arr)
        maxArray = self.myStat.calcMaxValues6D(_arr)

        # calculate the differences, imposing symmetry
        diffZero = np.zeros(6)
        for iLoop in range(6):
            diffZero[iLoop] = max( (avgArray[iLoop]-minArray[iLoop]),
                    (maxArray[iLoop]-avgArray[iLoop]) )

        # now switch based on the specified axis flag
        # specify plot limits, symmetric around the zero axis
        if self.axisFlag == 'symmetric':
            self.xMax  = (abs(avgArray[0])+diffZero[0])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.xpMax = (abs(avgArray[1])+diffZero[1])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.yMax  = (abs(avgArray[2])+diffZero[2])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.ypMax = (abs(avgArray[3])+diffZero[3])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.ptMax = (abs(avgArray[5])+diffZero[5])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)

            self.xMin  = -self.xMax
            self.xpMin = -self.xpMax
            self.yMin  = -self.yMax
            self.ypMin = -self.ypMax
            self.ptMin = -self.ptMax

        # specify plot limits, symmetric around the bunch (confined to 3 rms)
        elif self.axisFlag == 'compact':
            self.xMin  = (avgArray[0]-3.*rmsArray[0])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.xpMin = (avgArray[1]-3.*rmsArray[1])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.yMin  = (avgArray[2]-3.*rmsArray[2])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.ypMin = (avgArray[3]-3.*rmsArray[3])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.ptMin = (avgArray[5]-3.*rmsArray[5])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)

            self.xMax  = (avgArray[0]+3.*rmsArray[0])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.xpMax = (avgArray[1]+3.*rmsArray[1])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.yMax  = (avgArray[2]+3.*rmsArray[2])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.ypMax = (avgArray[3]+3.*rmsArray[3])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.ptMax = (avgArray[5]+3.*rmsArray[5])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)

        # symmetric around the bunch
        elif self.axisFlag == 'bunch-centered':
            self.xMin  = (avgArray[0]-diffZero[0])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.xpMin = (avgArray[1]-diffZero[1])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.yMin  = (avgArray[2]-diffZero[2])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.ypMin = (avgArray[3]-diffZero[3])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.ptMin = (avgArray[5]-diffZero[5])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)

            self.xMax  = (avgArray[0]+diffZero[0])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.xpMax = (avgArray[1]+diffZero[1])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.yMax  = (avgArray[2]+diffZero[2])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.ypMax = (avgArray[3]+diffZero[3])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)
            self.ptMax = (avgArray[5]+diffZero[5])*util.convertUnitsNumber(1, 'rad', self.unitsAngle)

        if self.axisFlag=='compact' or self.axisFlag=='symmetric-compact':
            # sMin / sMax always have to be 'bunch centered'
            self.sMin  = (avgArray[4]-3.*rmsArray[4])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.sMax  = (avgArray[4]+3.*rmsArray[4])*util.convertUnitsNumber(1, 'm', self.unitsPos)

        if self.axisFlag=='symmetric' or self.axisFlag=='bunch-centered':
            # sMin / sMax always have to be 'bunch centered'
            self.sMin  = (avgArray[4]-diffZero[4])*util.convertUnitsNumber(1, 'm', self.unitsPos)
            self.sMax  = (avgArray[4]+diffZero[4])*util.convertUnitsNumber(1, 'm', self.unitsPos)