Esempio n. 1
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)
Esempio n. 2
0
 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]
Esempio n. 3
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)
Esempio n. 4
0
    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()
Esempio n. 5
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()
Esempio n. 6
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()