예제 #1
0
파일: RbFEL.py 프로젝트: lynch829/radtrack
 def setResultBox(self, textBox, value):
     if value is not None:
         self.valueFromTextBox[textBox] = value
         textBox.setText(util.displayWithUnitsNumber(util.roundSigFig(value, 5), textBox.unit))
         textBox.setCursorPosition(0)
     else:
         self.unsetValue(textBox)
예제 #2
0
    def saveToCSV(self, fileName = None):
        if not fileName:
            fileName = util.getSaveFileName(self, 'csv')
            if not fileName:
                return

        # make sure the top-level parameters are up-to-date
        self.designMomentumEV = util.convertUnitsStringToNumber(self.ui.designMomentum.text(), 'eV')
        self.totalCharge = util.convertUnitsStringToNumber(self.ui.totalCharge.text(), 'C')

        # create a header to identify this as a RadTrack file
        h1 = 'RadTrack,Copyright 2012-2014 by RadiaBeam Technologies LLC - All rights reserved (C)\n '
        # names of the top-level parameters
        h2 = 'p0 [eV],Q [C],mass [eV]\n '
        # values of the top-level parameters
        h3 = str(self.designMomentumEV)+','+str(self.totalCharge)+','+str(self.eMassEV)+'\n '
        # label the columns
        h4 = 'x,xp,y,yp,s,dp\n '
        # specify the units
        h5 = '[m],[rad],[m],[rad],[m],[rad]'
        # assemble the full header
        myHeader = h1 + h2 + h3 + h4 + h5

        # write particle data into the file
        
        # create local pointer to particle array
        userNumberOfParticles = int(self.ui.numPtcls.text())
        tmp6 = randomSampleOfBunch(self.myBunch.getDistribution6D().getPhaseSpace6D().getArray6D(), userNumberOfParticles)
        np.savetxt(fileName, tmp6.transpose(), fmt=str('%1.12e'), delimiter=',', comments='', header=myHeader)
예제 #3
0
파일: RbFEL.py 프로젝트: lynch829/radtrack
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
예제 #4
0
파일: RbFEL.py 프로젝트: lynch829/radtrack
 def getValue(self, textBox):
     try:
         self.valueFromTextBox[textBox] = util.convertUnitsStringToNumber(textBox.text(), textBox.unit)
         return self.valueFromTextBox[textBox]
     except ValueError:
         if textBox in self.valueFromTextBox:
             del self.valueFromTextBox[textBox]
예제 #5
0
    def saveToSDDS(self, sddsFileName = None):
        if not sddsFileName:
            sddsFileName = util.getSaveFileName(self, 'sdds')
            if not sddsFileName:
                return

        mySDDS = sdds.SDDS(0)
        mySDDS.description[0] = "RadTrack"
        mySDDS.description[1] = "Copyright 2013-2015 by RadiaBeam Technologies. All rights reserved."
        mySDDS.parameterName = ["designMomentumEV", "totalCharge", "eMassEV"]
        mySDDS.parameterData = [[self.designMomentumEV],
                                [self.totalCharge],
                                [self.eMassEV]]
        mySDDS.parameterDefinition = [["","","","",mySDDS.SDDS_DOUBLE,""],
                                      ["","","","",mySDDS.SDDS_DOUBLE,""],
                                      ["","","","",mySDDS.SDDS_DOUBLE,""]]
        mySDDS.columnName = ["x", "xp", "y", "yp", "t", "p"]

        tmp6 = self.myBunch.getDistribution6D().getPhaseSpace6D().getArray6D()
        if not self.userInputEnabled():
            tmp6 = randomSampleOfBunch(tmp6, int(self.ui.numPtcls.text()))

        mySDDS.columnData = [ [list(tmp6[i,:])] for i in range(6)]

        mySDDS.columnDefinition = [["","m",  "","",mySDDS.SDDS_DOUBLE,0],
                                   ["","","","",mySDDS.SDDS_DOUBLE,0],
                                   ["","m",  "","",mySDDS.SDDS_DOUBLE,0],
                                   ["","","","",mySDDS.SDDS_DOUBLE,0],
                                   ["","s",  "","",mySDDS.SDDS_DOUBLE,0],
                                   ["","m_ec","","",mySDDS.SDDS_DOUBLE,0]]
        mySDDS.save(sddsFileName)
예제 #6
0
def set_widget_value(decl, param, widget):
    """Sets parameter value accordingly on widget

    Args:
        decl (dict): decl for parameter
        param (dict): value
        widget (widget): what to set on

    Returns:
        str: value that was set
    """
    t = decl.py_type
    if isinstance(t, enum.EnumMeta):
        widget.setCurrentIndex(list(t).index(param))
        return rt_qt.i18n_text(param.display_name)
    if issubclass(t, bool):
        widget.setChecked(param)
        # Approximate size of checkbox
        return ' '
    if decl.units:
        l = RbUtility.displayWithUnitsNumber(param, decl.units)
    else:
        l = str(param)
    widget.setText(l)
    return l
예제 #7
0
    def importFile(self, fileName = None):
        """Allow importing from CSV or SDDS"""
        # use Qt file dialog
        if not fileName:
            fileName = QtGui.QFileDialog.getOpenFileName(self, "Import particle file",
                    self.parent.lastUsedDirectory, util.fileTypeList(self.acceptsFileTypes))

            # if user cancels out, do nothing
            if not fileName:
                return

        self.parent.lastUsedDirectory = os.path.dirname(fileName)

        if os.path.basename(fileName).startswith(self.parent.tabPrefix):
            if fileName.split('+')[-1].split('.')[0] == 'False':
                self.disableInput()
        else:
            self.disableInput()


        if re.search('\.csv$', fileName, re.IGNORECASE):
            self.readFromCSV(fileName)
        else:
            self.readFromSDDS(fileName)

        self.calculateTwiss()
        self.refreshPlots()
예제 #8
0
 def _num(d, w):
     # need type checking
     if w is None:
         return None
     v = w.text()
     if d.units:
         v = RbUtility.convertUnitsStringToNumber(v, d.units)
     return d.py_type(v)
예제 #9
0
파일: RbFEL.py 프로젝트: lynch829/radtrack
    def exportToFile(self, fileName = None):
        if not fileName:
            fileName = util.getSaveFileName(self)
            if not fileName:
                return

        fileLines = []
        for box in self.textBox.values():
            try:
                try:
                    _, unit = util.separateNumberUnit(box.text())
                    value = util.convertUnitsNumberToString(self.valueFromTextBox[box], box.unit, unit)
                except (ValueError, KeyError):
                    value = box.text()
                fileLines.append(box.objectName() + ':' + value) # text box
            except AttributeError:
                fileLines.append(box.objectName() + ':' + box.currentText()) # combo box

        with open(fileName, 'w') as f:
            f.write('\n'.join(sorted(fileLines)))
예제 #10
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()
예제 #11
0
파일: RbFEL.py 프로젝트: lynch829/radtrack
    def importFile(self, fileName = None):
        if not fileName:
            fileName = QtGui.QFileDialog.getOpenFileName(self, 'Open file', self.parent.lastUsedDirectory,
                util.fileTypeLists(self.acceptsFileTypes))
            if not fileName:
                return
            self.parent.lastUsedDirectory = os.path.dirname(fileName)

        with open(fileName, 'r') as f:
            for line in f:
                name, value = line.strip().split(':')
                box = self.textBox[name]
                try:
                    box.setText(value) # text box
                except AttributeError:
                    box.setCurrentIndex(box.findText(value)) # combo box

        self.calculateAll()
        self.plot()
예제 #12
0
    def exportToFile(self, fileName = None):
        if not fileName:
            fileName = util.getSaveFileName(self, ['sdds', 'csv'])
            if not fileName:
                return

        if os.path.basename(fileName).startswith(self.parent.tabPrefix):
            name, ext = os.path.splitext(fileName)
            fileName = name + '+' + str(self.userInputEnabled()) + ext
            with open(fileName, 'w'):
                pass # create file in case no data to be saved

        if self.userInputEnabled():
            self.generateBunch() # save all particles

        if fileName.lower().endswith('csv'):
            self.saveToCSV(fileName)
        else:
            self.saveToSDDS(fileName)
예제 #13
0
파일: RbFEL.py 프로젝트: lynch829/radtrack
    def goalSeek(self):
        # Newton's method
        variableTextBox = self.textBox[self.ui.vary.currentText()]
        resultTextBox = self.textBox[self.ui.target.currentText()]
        self.ui.solverResult.setText('Searching...')

        maximumIterations = 1000
        success = False
        dxFactor = 1e-9
        try:
            x0 = self.valueFromTextBox[variableTextBox]
        except KeyError:
            x0 = dxFactor
        bestX = x0

        try:
            goal = util.convertUnitsStringToNumber(self.ui.lineEdit.text(), resultTextBox.unit)
            y0 = self.calculateValue(variableTextBox, x0, resultTextBox)
            bestError = abs((y0-goal)/goal)
            for i in range(maximumIterations):
                try:
                    y0 = self.calculateValue(variableTextBox, x0, resultTextBox)
                    error = abs((y0-goal)/goal)
                    if error < 1e-6:
                        success = True
                        break
                    else:
                        if error < bestError:
                            bestX = x0
                            bestError = error

                    dx = abs(dxFactor*x0)
                    slope = self.calculateSlope(variableTextBox, x0, dx, resultTextBox)

                    x0 = x0 - (y0-goal)/slope
                    if x0 < 0:
                        x0 = dx
                except (ZeroDivisionError, KeyError, OverflowError):
                    dxFactor = 2*dxFactor
                    x0 = x0+dx

        except ValueError: # "goal" is blank -> find extrema by Newton's method on slope
            dx = abs(dxFactor*x0)
            bestSlope = abs(self.calculateSlope(variableTextBox, x0, dx, resultTextBox))
            for i in range(maximumIterations):
                try:
                    dx = abs(dxFactor*x0)
                    slope = self.calculateSlope(variableTextBox, x0, dx, resultTextBox)
                    if abs(slope) < 1e-6:
                        success = True
                        break
                    else:
                        if slope < bestSlope:
                            bestX = x0
                            bestSlope = slope

                    secondDerivitive = self.calculateSecondDerivitive(variableTextBox, x0, dx, resultTextBox)

                    x0 = x0 - (slope)/secondDerivitive
                    if x0 < 0:
                        x0 = dx
                except (ZeroDivisionError, KeyError, OverflowError):
                    dxFactor = 2*dxFactor
                    x0 = x0+dx

        if success:
            value = x0
            self.ui.solverResult.setText('Success.')
        else:
            value = bestX
            self.ui.solverResult.setText('Failed. Could not find a solution.')

        variableTextBox.setText(util.displayWithUnitsNumber(util.roundSigFig(value, 5), variableTextBox.unit))
        variableTextBox.setCursorPosition(0)
        self.calculateAll()
예제 #14
0
파일: RbFEL.py 프로젝트: lynch829/radtrack
    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()
예제 #15
0
    def generateBunch(self, particleLimit = None):
        if self.userInputEnabled():
            errorMessage = []
            self.parent.ui.statusbar.showMessage('Generating bunch ...')

            # Get input from text boxes.
            try:
                numParticles = int(self.ui.numPtcls.text())
            except ValueError:
                numParticles = 0
            if numParticles <= 0:
                errorMessage.append(self.ui.numPtclsLabel.text().strip() + ' must be a postive number.')
            if particleLimit:
                numParticles = min(numParticles, particleLimit)

            try:
                self.designMomentumEV = util.convertUnitsStringToNumber(self.ui.designMomentum.text(), 'eV')
            except ValueError:
                self.designMomentumEV = 0
            if self.designMomentumEV <= 0:
                errorMessage.append(self.ui.designMomentumLabel.text().strip() + ' must be a positive value.')

            try:
                self.totalCharge = util.convertUnitsStringToNumber(self.ui.totalCharge.text().strip(), 'C')
            except ValueError:
                self.totalCharge = 0
            if self.totalCharge <= 0:
                errorMessage.append(self.ui.charge.text() + ' must be a positive value.')

            if errorMessage:
                QtGui.QMessageBox(QtGui.QMessageBox.Warning,
                        'Input Error' + ('s' if len(errorMessage) > 1 else ''),
                        '\n'.join(errorMessage),
                        QtGui.QMessageBox.Ok,
                        self).exec_()
                self.parent.ui.statusbar.clearMessage()
                self.myBunch = None
                return

            beta0gamma0 = self.designMomentumEV / self.eMassEV
            gamma0 = math.sqrt(beta0gamma0**2 + 1.)
            beta0 = beta0gamma0 / gamma0

            # get input from the table of Twiss parameters
            self.twissAlphaX = util.convertUnitsStringToNumber(self.ui.twissTable.item(0,0).text(), '')
            self.twissAlphaY = util.convertUnitsStringToNumber(self.ui.twissTable.item(1,0).text(), '')
            self.twissBetaX  = util.convertUnitsStringToNumber(self.ui.twissTable.item(0,1).text(), 'm/rad')
            self.twissBetaY  = util.convertUnitsStringToNumber(self.ui.twissTable.item(1,1).text(), 'm/rad')
            self.twissEmitNX = util.convertUnitsStringToNumber(self.ui.twissTable.item(0,2).text(), 'm*rad')
            self.twissEmitNY = util.convertUnitsStringToNumber(self.ui.twissTable.item(1,2).text(), 'm*rad')

            if self.longTwissFlag == "alpha-bct-dp":
                self.twissAlphaZ = util.convertUnitsStringToNumber(self.ui.twissTableZ.item(0,0).text(), '')
                self.bctRms = util.convertUnitsStringToNumber(self.ui.twissTableZ.item(0,1).text(), 'm')
                self.dPopRms  = float(self.ui.twissTableZ.item(0,2).text())

                self.twissEmitNZ = (self.bctRms/beta0) * self.dPopRms / math.sqrt(1.+self.twissAlphaZ**2)
                self.twissBetaZ  = (self.bctRms/beta0) / self.dPopRms * math.sqrt(1.+self.twissAlphaZ**2)

            # elif self.longTwissFlag == "coupling-bct-dp":
            #     msgBox = QtGui.QMessageBox()
            #     message  = 'Error --\n\n'
            #     message += '  longTwissFlag has been specified as "'+self.longTwissFlag+'".\n'
            #     message += '  This value is not yet supported, but is coming soon!\n\n'
            #     message += 'Please go to the "Specification Type" button and choose "alpha-bct-dp".\n\n'
            #     msgBox.setText(message)
            #     msgBox.exec_()
            # elif self.longTwissFlag == "alpha-beta-emit":
            #     msgBox = QtGui.QMessageBox()
            #     message  = 'Error --\n\n'
            #     message += '  longTwissFlag has been specified as "'+self.longTwissFlag+'".\n'
            #     message += '  This value is not yet supported, but is coming soon!\n\n'
            #     message += 'Please go to the "Specification Type" button and choose "alpha-bct-dp".\n\n'
            #     msgBox.setText(message)
            #     msgBox.exec_()
            # else:
            #     msgBox = QtGui.QMessageBox()
            #     message  = 'Error --\n\n'
            #     message += '  longTwissFlag has been specified as "'+self.longTwissFlag+'".\n'
            #     message += '  This choice is invalid!\n\n'
            #     message += 'Please use the "Specification Type" button to choose a valid option.\n\n'
            #     msgBox.setText(message)
            #     msgBox.exec_()

            # Get input from the table of phase space offsets
            self.offsetX  = util.convertUnitsStringToNumber(self.ui.offsetTable.item(0,0).text(), 'm')
            self.offsetY  = util.convertUnitsStringToNumber(self.ui.offsetTable.item(1,0).text(), 'm')
            self.offsetT  = util.convertUnitsStringToNumber(self.ui.offsetTable.item(2,0).text(), 'm')
            self.offsetXP = util.convertUnitsStringToNumber(self.ui.offsetTable.item(0,1).text(), 'rad')
            self.offsetYP = util.convertUnitsStringToNumber(self.ui.offsetTable.item(1,1).text(), 'rad')
            self.offsetPT = util.convertUnitsStringToNumber(self.ui.offsetTable.item(2,1).text(), 'rad')

            # instantiate the particle bunch
            self.myBunch = beam.RbParticleBeam6D(numParticles)
            self.myBunch.setDesignMomentumEV(self.designMomentumEV)
            self.myBunch.setTotalCharge(self.totalCharge)
            self.myBunch.setMassEV(self.eMassEV)     # assume electrons

            # specify the distribution flag and extent
            self.myDist = self.myBunch.getDistribution6D()
            self.myDist.setDistributionType(self.distributionFlag)
            self.myDist.setMaxRmsFactor(3.)

            # specify the Twiss parameters
            self.myBunch.setTwissParamsByName2D(self.twissAlphaX,self.twissBetaX,
                                                self.twissEmitNX/beta0gamma0,'twissX')
            self.myBunch.setTwissParamsByName2D(self.twissAlphaY,self.twissBetaY,
                                                self.twissEmitNY/beta0gamma0,'twissY')
            self.myBunch.setTwissParamsByName2D(self.twissAlphaZ,self.twissBetaZ,
                                                self.twissEmitNZ,'twissZ')

            # create the distribution
            self.myBunch.makeParticlePhaseSpace6D()

            # offset the distribution
            if (self.offsetX  != 0.):
                self.myDist.offsetDistribComp(self.offsetX,  0)
            if (self.offsetXP != 0.):
                self.myDist.offsetDistribComp(self.offsetXP, 1)
            if (self.offsetY  != 0.):
                self.myDist.offsetDistribComp(self.offsetY,  2)
            if (self.offsetYP != 0.):
                self.myDist.offsetDistribComp(self.offsetYP, 3)
            if (self.offsetT  != 0.):
                self.myDist.offsetDistribComp(self.offsetT,  4)
            if (self.offsetPT != 0.):
                self.myDist.offsetDistribComp(self.offsetPT, 5)

        # generate the plots
        self.refreshPlots()

        self.parent.ui.statusbar.clearMessage()
예제 #16
0
 def plotGenericBefore(self, hData, vData, _canvas, nDivs, nLevels):
     _canvas.ax.clear()
     util.scatConPlot(self.plotFlag, hData, vData, _canvas.ax, nDivs, nLevels)
     _canvas.ax.xaxis.set_major_locator(plt.MaxNLocator(self.numTicks))
     _canvas.ax.yaxis.set_major_locator(plt.MaxNLocator(self.numTicks))
예제 #17
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)