def __init__(self, parent=None): """ This function initializes the GUI and sets up all of the default parameters """ QtGui.QWidget.__init__(self, parent) self.ui = Ui_Dialog() self.ui.setupUi(self) #make sure functions know we're in the init method right now self.initializing = 1 #set up all of the variables (with some default values) #that we will eventually extract from the gui self.sv_thetaoff = 0.05 self.sv_percK2 = 0.5 self.sv_Alpha = [0.01,0.01,0.01,0.01] self.sv_K1 = [3e5, 3e6, 0.0, 0.0] self.sv_Ms = [650000, 600000, 0, 0] self.sv_lposz = [0.0, 7.0, 0.0, 0.0] self.sv_simtype = 0 self.sv_jmin = -1e11 self.sv_jmax = 1e11 self.sv_n = 30 self.sv_hzmin = -1e6 self.sv_hzmax = 1e6 self.sv_nfield = 30 self.sv_tf = 2.5e-8 self.sv_j_timdep_funs = 1 self.sv_hz_timdep_funs = 1 self.sv_dx = 50 self.sv_dy = 50 self.sv_temperature = 0 self.sv_initmag_x = [0.0,0.0,0.0,0.0] self.sv_initmag_y = [0.1, 0.0, 0.0, 0.0] self.sv_initmag_z = [0.9, 1, 0, 0] self.sv_dz = [3,3,0,0] self.sv_pol = [0.3,0.3,0.3,0.3] self.sv_layerEn = [1,1,0,0] self.sv_layerFixed = [0,1,0,0] self.sv_numthreads = 1 self.sv_numFrames = 50 self.sv_fieldInPlane = 0 #relaxation time to not apply field nor current self.sv_relax = 0.0 #af coupling terms: coupling b/w 1-2, 1-3, 1-4, 2-3, 2-4, 3-4 self.sv_af = [0.0,0.0,0.0,0.0,0.0,0.0] #constant variable; list of currently implemented simtype's self.VALID_SIMTYPES = [6, 9, 10, 26, 41, 6+(1<<31), 9+(1<<31), 10+(1<<31), 26+(1<<31), 41+(1<<31)] #handle switching to CGS units self.switch_units_to_cgs(self.cgs_units) #[/end if cgs_units] #set up all of the GUI fields to the "default" values #for non-layer dependent things self.variablesToDialogNonLayer() #set layer 1 as the first layer that's selected self.handleLayer1Button() #setup progress bar self.ui.progressBar_Progress.setVisible(False) self.ui.label_Progress.setVisible(False) #setup threading lock self.spinsim_thread_lock = thread.allocate_lock() self.progress_var_lock = thread.allocate_lock() self.progress_var = 0 #setup threading lock for plot limit poll-er self.spinsim_plot_lock = thread.allocate_lock() self.plot_lims = [0,0,0,0] self.plot_lims_updated = 0 #setup timer for updating progress bar when the spinsim c program is runnings self.progress_timer = QtCore.QTimer() QtCore.QObject.connect(self.progress_timer, QtCore.SIGNAL("timeout()"), self.handleUpdateProgress) #setup the comboBox (and its label) for plotting self.ui.comboBox_PlotType.setEditable(False) self.ui.comboBox_PlotType.setVisible(True) #self.ui.label_GeneratePlot.setVisible(False) #self.ui.pushButton_MakePlot.setVisible(False) #make sure number of frames is not visible (until we select the plot type such that it should be) self.ui.label_numFrames.setVisible(False) self.ui.lineEdit_numFrames.setVisible(False) #hide the layer 4 button for now self.ui.pushButton_layer4.setVisible(False) #make sure functions know we're no longer in the init method self.initializing = 0
class MyForm(QtGui.QMainWindow): cgs_units = 0 """This class initializes the GUI and also contains code for reading in the parameters and running the spinsim C code""" def __init__(self, parent=None): """ This function initializes the GUI and sets up all of the default parameters """ QtGui.QWidget.__init__(self, parent) self.ui = Ui_Dialog() self.ui.setupUi(self) #make sure functions know we're in the init method right now self.initializing = 1 #set up all of the variables (with some default values) #that we will eventually extract from the gui self.sv_thetaoff = 0.05 self.sv_percK2 = 0.5 self.sv_Alpha = [0.01,0.01,0.01,0.01] self.sv_K1 = [3e5, 3e6, 0.0, 0.0] self.sv_Ms = [650000, 600000, 0, 0] self.sv_lposz = [0.0, 7.0, 0.0, 0.0] self.sv_simtype = 0 self.sv_jmin = -1e11 self.sv_jmax = 1e11 self.sv_n = 30 self.sv_hzmin = -1e6 self.sv_hzmax = 1e6 self.sv_nfield = 30 self.sv_tf = 2.5e-8 self.sv_j_timdep_funs = 1 self.sv_hz_timdep_funs = 1 self.sv_dx = 50 self.sv_dy = 50 self.sv_temperature = 0 self.sv_initmag_x = [0.0,0.0,0.0,0.0] self.sv_initmag_y = [0.1, 0.0, 0.0, 0.0] self.sv_initmag_z = [0.9, 1, 0, 0] self.sv_dz = [3,3,0,0] self.sv_pol = [0.3,0.3,0.3,0.3] self.sv_layerEn = [1,1,0,0] self.sv_layerFixed = [0,1,0,0] self.sv_numthreads = 1 self.sv_numFrames = 50 self.sv_fieldInPlane = 0 #relaxation time to not apply field nor current self.sv_relax = 0.0 #af coupling terms: coupling b/w 1-2, 1-3, 1-4, 2-3, 2-4, 3-4 self.sv_af = [0.0,0.0,0.0,0.0,0.0,0.0] #constant variable; list of currently implemented simtype's self.VALID_SIMTYPES = [6, 9, 10, 26, 41, 6+(1<<31), 9+(1<<31), 10+(1<<31), 26+(1<<31), 41+(1<<31)] #handle switching to CGS units self.switch_units_to_cgs(self.cgs_units) #[/end if cgs_units] #set up all of the GUI fields to the "default" values #for non-layer dependent things self.variablesToDialogNonLayer() #set layer 1 as the first layer that's selected self.handleLayer1Button() #setup progress bar self.ui.progressBar_Progress.setVisible(False) self.ui.label_Progress.setVisible(False) #setup threading lock self.spinsim_thread_lock = thread.allocate_lock() self.progress_var_lock = thread.allocate_lock() self.progress_var = 0 #setup threading lock for plot limit poll-er self.spinsim_plot_lock = thread.allocate_lock() self.plot_lims = [0,0,0,0] self.plot_lims_updated = 0 #setup timer for updating progress bar when the spinsim c program is runnings self.progress_timer = QtCore.QTimer() QtCore.QObject.connect(self.progress_timer, QtCore.SIGNAL("timeout()"), self.handleUpdateProgress) #setup the comboBox (and its label) for plotting self.ui.comboBox_PlotType.setEditable(False) self.ui.comboBox_PlotType.setVisible(True) #self.ui.label_GeneratePlot.setVisible(False) #self.ui.pushButton_MakePlot.setVisible(False) #make sure number of frames is not visible (until we select the plot type such that it should be) self.ui.label_numFrames.setVisible(False) self.ui.lineEdit_numFrames.setVisible(False) #hide the layer 4 button for now self.ui.pushButton_layer4.setVisible(False) #make sure functions know we're no longer in the init method self.initializing = 0 #[/__init__()] def switch_units_to_cgs(self, cgs_units): """This function translates the SI units entered into the GUI into CGS, and also re-sets the GUI labels.""" if(cgs_units != 0): count = 0 #Switch all labels self.ui.label_5.setText("Saturation Magnetization, in emu/cc") self.ui.label_18.setText("Layer Anisotropy, erg/cc") self.ui.label_11.setText("Min/Max Field & # of Points (Oe)") #Switch entered values for element in self.sv_K1: self.sv_K1[count] = element * K_PER_ERGCC count = count + 1 count = 0 for element in self.sv_Ms: self.sv_Ms[count] = element * MS_PER_EMUCC count = count+1 self.sv_hzmin = self.sv_hzmin * AM_PER_OE self.sv_hzmax = self.sv_hzmax * AM_PER_OE #[/switch_units_to_cgs()] def switch_units_to_si(self, cgs_units): """This function translates the SI units entered into the GUI into CGS, and also re-sets the GUI labels.""" if(cgs_units != 0): count = 0 #Switch entered values for element in self.sv_K1: self.sv_K1[count] = element / K_PER_ERGCC count = count + 1 count = 0 for element in self.sv_Ms: self.sv_Ms[count] = element / MS_PER_EMUCC count = count+1 self.sv_hzmin = self.sv_hzmin / AM_PER_OE self.sv_hzmax = self.sv_hzmax / AM_PER_OE #[/switch_units_to_si()] def printDebugVars(self): """This function prints out all of the currently stored internal variables""" self.dialogToVariablesNonLayer() print("sv_thetaoff = %f" % self.sv_thetaoff) print("sv_Alpha = %f" % self.sv_Alpha) print("sv_K1 = [%f, %f, %f, %f]" % (self.sv_K1[0],self.sv_K1[1],self.sv_K1[2],self.sv_K1[3])) print("sv_Ms = [%f, %f, %f, %f]" % (self.sv_Ms[0],self.sv_Ms[1],self.sv_Ms[2],self.sv_Ms[3])) print("sv_lposz = [%f, %f, %f, %f" % (self.sv_lposz[0],self.sv_lposz[1],self.sv_lposz[2],self.sv_lposz[3])) print("sv_jmin/sv_jmax/sv_n = %f / %f / %f" % (self.sv_jmin, self.sv_jmax, self.sv_n)) def dialogToVariablesNonLayer(self): """This function grabs all of the text in the non-layer-dependent fields and puts it into the GUIs internal variable storage""" #self.sv_Alpha = float(self.ui.lineEdit_Alpha.text()) self.sv_jmin = float(self.ui.lineEdit_jmin.text()) self.sv_jmax = float(self.ui.lineEdit_jmax.text()) self.sv_n = int(self.ui.lineEdit_n.text()) self.sv_hzmin = float(self.ui.lineEdit_hzmin.text()) self.sv_hzmax = float(self.ui.lineEdit_hzmax.text()) self.sv_nfield = int(self.ui.lineEdit_nfield.text()) self.sv_tf = float(self.ui.lineEdit_IntegrationTime.text()) self.sv_temperature = float(self.ui.lineEdit_SampTemp.text()) self.sv_percK2 = float(self.ui.lineEdit_perK2.text()) self.sv_thetaoff = float(self.ui.lineEdit_thetaoff.text()) self.sv_numthreads = int(self.ui.lineEdit_threadcount.text()) self.sv_dx = float(self.ui.lineEdit_dx.text()) self.sv_dy = float(self.ui.lineEdit_dy.text()) if(self.ui.checkBox_fieldInPlane.checkState() == QtCore.Qt.Checked): self.sv_fieldInPlane = 1 else: self.sv_fieldInPlane = 0 #af coupling terms self.sv_af[0] = float(self.ui.lineEdit_af_12.text()); self.sv_af[1] = float(self.ui.lineEdit_af_13.text()); self.sv_af[2] = float(self.ui.lineEdit_af_14.text()); self.sv_af[3] = float(self.ui.lineEdit_af_23.text()); self.sv_af[4] = float(self.ui.lineEdit_af_24.text()); self.sv_af[5] = float(self.ui.lineEdit_af_34.text()); #relaxation time self.sv_relax = float(self.ui.lineEdit_relax.text()); #[/dialogToVariablesNonLayer] def variablesToDialogNonLayer(self): """This function takes all of the non-layer-dependent variables from memory and writes them into the dialog text boxes""" #self.ui.lineEdit_Alpha.setText(str(self.sv_Alpha)) self.ui.lineEdit_jmin.setText(str(self.sv_jmin)) self.ui.lineEdit_jmax.setText(str(self.sv_jmax)) self.ui.lineEdit_n.setText(str(self.sv_n)) self.ui.lineEdit_hzmin.setText(str(self.sv_hzmin)) self.ui.lineEdit_hzmax.setText(str(self.sv_hzmax)) self.ui.lineEdit_nfield.setText(str(self.sv_nfield)) self.ui.lineEdit_IntegrationTime.setText(str(self.sv_tf)) self.ui.lineEdit_SampTemp.setText(str(self.sv_temperature)) self.ui.lineEdit_perK2.setText(str(self.sv_percK2)) self.ui.lineEdit_thetaoff.setText(str(self.sv_thetaoff)) self.ui.lineEdit_threadcount.setText(str(self.sv_numthreads)) self.ui.lineEdit_dx.setText(str(self.sv_dx)) self.ui.lineEdit_dy.setText(str(self.sv_dy)) self.ui.lineEdit_numFrames.setText(str(self.sv_numFrames)) if(self.sv_fieldInPlane == 1): self.ui.checkBox_layerFixed.setCheckState(QtCore.Qt.Checked) else: self.ui.checkBox_layerFixed.setCheckState(QtCore.Qt.Unchecked) #af coupling terms self.ui.lineEdit_af_12.setText(str(self.sv_af[0])); self.ui.lineEdit_af_13.setText(str(self.sv_af[1])); self.ui.lineEdit_af_14.setText(str(self.sv_af[2])); self.ui.lineEdit_af_23.setText(str(self.sv_af[3])); self.ui.lineEdit_af_24.setText(str(self.sv_af[4])); self.ui.lineEdit_af_34.setText(str(self.sv_af[5])); #relaxation time self.ui.lineEdit_relax.setText(str(self.sv_relax)); #[/variablesToDialogNonLayer()] def handleLayer1Button(self): """Handler for layer 1 button - stores the old layer's fields to internal variables, sets up the push button colors and GUI labels, and writes from internal variables to the new layer's GUI fields""" #store the old variable's fields, if the program is NOT initializing if(self.initializing != 1): self.storeLayern(self.ui.curr_layer) #set up the push buttons, lables, etc self.ui.pushButton_layer1.setStyleSheet("* { color: red }"); self.ui.pushButton_layer2.setStyleSheet("* { color: black }"); self.ui.pushButton_layer3.setStyleSheet("* { color: black }"); self.ui.pushButton_layer4.setStyleSheet("* { color: black }"); self.ui.label_layerParams.setText("Layer 1 Parameters"); self.ui.curr_layer = 1 #write from the internal variables to the GUI fields for the new layer self.handleLayernButton(self.ui.curr_layer) def handleLayer2Button(self): """Handler for layer 1 button - stores the old layer's fields to internal variables, sets up the push button colors and GUI labels, and writes from internal variables to the new layer's GUI fields""" #store the old variable's fields, if the program is NOT initializing if(self.initializing != 1): self.storeLayern(self.ui.curr_layer) #set up the push buttons, lables, etc self.ui.pushButton_layer1.setStyleSheet("* { color: black }"); self.ui.pushButton_layer2.setStyleSheet("* { color: red }"); self.ui.pushButton_layer3.setStyleSheet("* { color: black }"); self.ui.pushButton_layer4.setStyleSheet("* { color: black }"); self.ui.label_layerParams.setText("Layer 2 Parameters"); self.ui.curr_layer = 2 #write from the internal variables to the GUI fields for the new layer self.handleLayernButton(self.ui.curr_layer) def handleLayer3Button(self): """Handler for layer 3 button - stores the old layer's fields to internal variables, sets up the push button colors and GUI labels, and writes from internal variables to the new layer's GUI fields""" #store the old variable's fields, if the program is NOT initializing if(self.initializing != 1): self.storeLayern(self.ui.curr_layer) #set up the push buttons, lables, etc self.ui.pushButton_layer1.setStyleSheet("* { color: black }"); self.ui.pushButton_layer2.setStyleSheet("* { color: black }"); self.ui.pushButton_layer3.setStyleSheet("* { color: red }"); self.ui.pushButton_layer4.setStyleSheet("* { color: black }"); self.ui.label_layerParams.setText("Layer 3 Parameters"); self.ui.curr_layer = 3 #write from the internal variables to the GUI fields for the new layer self.handleLayernButton(self.ui.curr_layer) def handleLayer4Button(self): """Handler for layer 4 button - stores the old layer's fields to internal variables, sets up the push button colors and GUI labels, and writes from internal variables to the new layer's GUI fields""" #store the old variable's fields, if the program is NOT initializing if(self.initializing != 1): self.storeLayern(self.ui.curr_layer) #set up the push buttons, lables, etc self.ui.pushButton_layer1.setStyleSheet("* { color: black }"); self.ui.pushButton_layer2.setStyleSheet("* { color: black }"); self.ui.pushButton_layer3.setStyleSheet("* { color: black }"); self.ui.pushButton_layer4.setStyleSheet("* { color: red }"); self.ui.label_layerParams.setText("Layer 4 Parameters"); self.ui.curr_layer = 4 #write from the internal variables to the GUI fields for the new layer self.handleLayernButton(self.ui.curr_layer) def storeLayern(self, n): """This method stores the current GUI settings into the variables for layer n""" self.sv_Ms[n-1] = float(self.ui.lineEdit_SatMag.text()) self.sv_K1[n-1] = float(self.ui.lineEdit_K1.text()) self.sv_lposz[n-1] = float(self.ui.lineEdit_layerpos_z.text()) self.sv_dz[n-1] = float(self.ui.lineEdit_dz.text()) self.sv_initmag_x[n-1] = float(self.ui.lineEdit_InitMagX.text()) self.sv_initmag_y[n-1] = float(self.ui.lineEdit_InitMagY.text()) self.sv_initmag_z[n-1] = float(self.ui.lineEdit_InitMagZ.text()) self.sv_Alpha[n-1] = float(self.ui.lineEdit_Alpha.text()) self.sv_pol[n-1] = float(self.ui.lineEdit_Pol.text()) if(self.ui.checkBox_layerEn.checkState() == QtCore.Qt.Checked): self.sv_layerEn[n-1] = 1 else: self.sv_layerEn[n-1] = 0 if(self.ui.checkBox_layerFixed.checkState() == QtCore.Qt.Checked): self.sv_layerFixed[n-1] = 1 else: self.sv_layerFixed[n-1] = 0 #[/storeLayern()] def handleLayernButton(self, n): """This method sets up the GUI fields based on the current variables stored for layer n. Typically gets called when the <layer n> button gets pressed""" self.ui.lineEdit_SatMag.setText(str(self.sv_Ms[n-1])) self.ui.lineEdit_K1.setText(str(self.sv_K1[n-1])) self.ui.lineEdit_layerpos_z.setText(str(self.sv_lposz[n-1])) self.ui.lineEdit_dz.setText(str(self.sv_dz[n-1])) self.ui.lineEdit_InitMagX.setText(str(self.sv_initmag_x[n-1])) self.ui.lineEdit_InitMagY.setText(str(self.sv_initmag_y[n-1])) self.ui.lineEdit_InitMagZ.setText(str(self.sv_initmag_z[n-1])) self.ui.lineEdit_Alpha.setText(str(self.sv_Alpha[n-1])) self.ui.lineEdit_Pol.setText(str(self.sv_pol[n-1])) #set up checkboxes if(self.sv_layerEn[n-1] == 1): self.ui.checkBox_layerEn.setCheckState(QtCore.Qt.Checked) else: self.ui.checkBox_layerEn.setCheckState(QtCore.Qt.Unchecked) if(self.sv_layerFixed[n-1] == 1): self.ui.checkBox_layerFixed.setCheckState(QtCore.Qt.Checked) else: self.ui.checkBox_layerFixed.setCheckState(QtCore.Qt.Unchecked) #[/handleLayernButton()] def handleUpdateProgress(self): """This function gets called by a timer to update the progress bar""" #print("Updating progress...") #acquire lock and set progress bar self.progress_var_lock.acquire() self.ui.progressBar_Progress.setValue(self.progress_var) #if we get to 100%, we're done, stop the timer if(self.progress_var == 100): self.progress_timer.stop() self.ui.comboBox_PlotType.setVisible(True) self.ui.label_GeneratePlot.setVisible(True) self.ui.pushButton_MakePlot.setVisible(True) self.progress_var_lock.release() def handleSetLimits(self): """This function gets called when the user hits the "Limits from Plot" button in the GUI. It updates the j and Hz limits based on the last zoom-box limit settings from the last figure call. The settings themselves get passed to spinsim_gui through the stdout pipe from the spinsim C engine. """ #check to see if our plot limits were updated. If so, post the updates to the GUI self.spinsim_plot_lock.acquire() if(self.plot_lims_updated == 1): self.ui.lineEdit_jmax.setText(str(self.plot_lims[3])); self.ui.lineEdit_hzmax.setText(str(self.plot_lims[1])); self.ui.lineEdit_jmin.setText(str(self.plot_lims[2])); self.ui.lineEdit_hzmin.setText(str(self.plot_lims[0])); self.plot_lims_updated = 0 self.spinsim_plot_lock.release() def handleTimeDepDialog(self): """This function gets called when the Setup Time Dependent Functions button is pressed. It initializes the time dependent function setup dialog and displays it. The dialog itself passes the new settings back to spinsim_gui via callbacks""" tdd = TimeDep_Handler(self, self.sv_hz_timdep_funs, self.sv_j_timdep_funs) def makePlotSlotT(self,plotToMake,numFrames): """This function calls spinsim_make_plots.py via the shell to create the figure window and draw our plots. It also creates *.png file with the plots in the file""" #if we're doing an animation, we must also give spinsim_make_plots the # of frames we want if(plotToMake == 6): cmdstr = "python spinsim_make_plots.py %d %d" % ((plotToMake+1), (numFrames+1)) #default to '2' layers for plotting an x-y time domain plot, since as of #2011-09-25 I handle this well even if one of the layers isn't generated elif(plotToMake == 5): cmdstr = "python spinsim_make_plots.py %d %d" % ((plotToMake+1), 2) else: cmdstr = "python spinsim_make_plots.py %d" % (plotToMake+1) #create plots by calling a new process plot_process = Popen(cmdstr, shell=True, stdout=PIPE, cwd=os.getcwd()) #loop to poll status of plot and update limits while(plot_process.poll() == None): time.sleep(1) #grab stdout plot_stdout = plot_process.stdout #Ivan: Why does this line only return when we exit the program? #because I wasn't flushing stdout in the other process...duh... line = plot_stdout.readline() #print("DEBUG: Got line \"%s\"" % line) line = line.rstrip('\n') #chomp #get the progress from stdout lims = re.match('\S+ = (\S+) (\S+) (\S+) (\S+)',line) if(lims != None): print("Spinsim_GUI: New limits are %f %f %f %f" % (float(lims.group(1)), float(lims.group(2)), float(lims.group(3)), float(lims.group(4)))) #set the progress var self.spinsim_plot_lock.acquire() self.plot_lims[0] = float(lims.group(1)) self.plot_lims[1] = float(lims.group(2)) self.plot_lims[2] = float(lims.group(3)) self.plot_lims[3] = float(lims.group(4)) self.plot_lims_updated = 1 self.spinsim_plot_lock.release() #[/if(lims != None) #[/while plot_process.poll() == None] def handlePlotTypeSelect(self, selected): """This handler is called when a new plot type is selected in the plot type drop-down menu. If the user selects the Animation plot type, make visible the text entry field for number of frames""" if(selected == 6): self.ui.label_numFrames.setVisible(True) self.ui.lineEdit_numFrames.setVisible(True) else: self.ui.label_numFrames.setVisible(False) self.ui.lineEdit_numFrames.setVisible(False) #print("Selected plot type %d\n" % selected) def makePlotSlot(self): """This function calls makePlotSlotT in a new thread. Used for calling the python program that actually creates the plots using matplotlib.""" plotToMake = self.ui.comboBox_PlotType.currentIndex() #get the # of frames from the UI, if the user has selected the animation plot type if(plotToMake == 6): self.sv_numFrames = int(self.ui.lineEdit_numFrames.text()) thread.start_new_thread(self.makePlotSlotT, (plotToMake,self.sv_numFrames)) def runHsweepSlot(self): """This function is called when "OK" is pressed. It reads all of the parameters and calls the runHSweepFun() function, in another thread""" #Extract all values from text boxes self.dialogToVariablesNonLayer() self.storeLayern(self.ui.curr_layer) #check that number of threads, current density point count, field point count #are all valid values if(self.sv_numthreads < 1): self.sv_numthreads = 1 print("Thread Count must be set to something greater than 1 - defaulting to 1") Qt.QMessageBox.warning(self, "Error", "Thread Count must be set to something greater than 1 - defaulting to 1") if(self.sv_n < 1): self.sv_n = 1 print("Current conditions count must be set to something greater than 1 - defaulting to 1") Qt.QMessageBox.warning(self, "Error", "Current conditions count must be set to something greater than 1 - defaulting to 1") if(self.sv_nfield < 1): self.sv_nfield = 1 print("External Magnetic Field count must be set to something greater than 1 - defaulting to 1") Qt.QMessageBox.warning(self, "Error", "External Magnetic Field count must be set to something greater than 1 - defaulting to 1") #check that we've implemented the simtype they want to do if self.generateSimType() in self.VALID_SIMTYPES: #do nothing print("DEBUG: Simtype OK") else: print("ERROR: Got unsupported simtype %d" % self.generateSimType()) Qt.QMessageBox.warning(self, "Error", "Invalid Sim Type") return if(print_command_only == 0): #launch new thread to run the spinsim code and update progress if(self.spinsim_thread_lock.acquire(0)): #make progress bar visible self.ui.progressBar_Progress.setVisible(True) self.ui.label_Progress.setVisible(True) #reset progress bar self.progress_var_lock.acquire() self.ui.progressBar_Progress.setValue(0) self.progress_var = 0 self.progress_var_lock.release() #start the progress timer self.progress_timer.start(1000) #spawn the thread thread.start_new_thread(self.runHsweepFun, (0,)) #can't run more than one instance of spinsim, sorry else: print("Sorry, process already running. Wait for current process to finish before restarting.\n") Qt.QMessageBox.information(self, "Info", "Sorry, process already running. Wait for current process to finish before restarting.") else: #spawn the thread thread.start_new_thread(self.runHsweepFun, (0,)) #print("Returned from runHsweepSlot") def runHsweepFun(self, garbage): """This function gets called by runHSweepSlot() which is the button press handler. It runs in another thread and periodically updates the progress via a locked variable""" #Ivan: This is the syntax to use cmd_str = "%s/spinsim" % (os.getcwd()) #put together simtype based on the current layerEn/layerFixed parameters self.sv_simtype = self.generateSimType() #If we're in 'CGS Mode' switch the units back to SI for just the duration of the cmd_str call self.switch_units_to_si(self.cgs_units) #Ivan : This is the syntax to use #Todo: Put in functionality for selecting something other than time-independent current and external field (last 2 params) cmd_args = " %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %d %e %e %d %e %e %d %e %d %d %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %d %d %e %e %e %e %e %e %e %e %e %e" % ( self.sv_thetaoff, self.sv_percK2, self.sv_Alpha[0], self.sv_Ms[0], self.sv_Ms[1], self.sv_Ms[2], self.sv_Ms[3], self.sv_K1[0], self.sv_K1[1], self.sv_K1[2], self.sv_K1[3], self.sv_lposz[0], self.sv_lposz[1], self.sv_lposz[2], self.sv_lposz[3], self.sv_simtype, self.sv_jmin, self.sv_jmax, self.sv_n, self.sv_hzmin, self.sv_hzmax, self.sv_nfield, self.sv_tf, self.sv_j_timdep_funs, self.sv_hz_timdep_funs, self.sv_dx, self.sv_dy, self.sv_temperature, self.sv_initmag_x[0], self.sv_initmag_y[0], self.sv_initmag_z[0], self.sv_initmag_x[1], self.sv_initmag_y[1], self.sv_initmag_z[1], self.sv_initmag_x[2], self.sv_initmag_y[2], self.sv_initmag_z[2], self.sv_initmag_x[3], self.sv_initmag_y[3], self.sv_initmag_z[3], self.sv_dz[0], self.sv_dz[1], self.sv_dz[2], self.sv_dz[3], self.sv_pol[0], self.sv_pol[1], self.sv_pol[2], self.sv_pol[3], 0, self.sv_numthreads, self.sv_af[0], self.sv_af[1], self.sv_af[2], self.sv_af[3], self.sv_af[4], self.sv_af[5], self.sv_Alpha[1], self.sv_Alpha[2], self.sv_Alpha[3], self.sv_relax) print ("Will run the spinsim C code with command:\n%s%s\n" % (cmd_str, cmd_args)) #switch units back to CGS, if necessary self.switch_units_to_cgs(self.cgs_units) if(print_command_only == 0): time_start = time.time() #spawn the spinsim process as a child process and DO NOT BLOCK #spinsim_pid = os.spawnv(os.P_NOWAIT, cmd_str, cmd_args) spinsim_process = Popen(cmd_str + cmd_args, shell=True, stdout=PIPE, cwd=os.getcwd()) spinsim_pid = spinsim_process.pid print("Running spinsim with PID %d" % spinsim_pid) #loop to poll status of spinsim and update progress bar spinsim_running = True while(spinsim_running): time.sleep(1) #print("DEBUG: Polling loop woke up") #grab stdout spinsim_stdout = spinsim_process.stdout line = spinsim_stdout.readline() line = line.rstrip('\n') #chomp #print("DEBUG: Read line %s" % line) #get the progress from stdout progress = re.search('\d+',line) if(progress != None): #print("Current progress is " + progress.group()) #set the progress var self.progress_var_lock.acquire() if(int(progress.group()) >= 100): self.progress_var = 100 else: self.progress_var = int(progress.group()) self.progress_var_lock.release() if(int(progress.group()) >= 100): spinsim_running = False #[/if(progress != None) #[/while spinsim_running] time_stop = time.time() print("Process took %.1f seconds to run" % (time_stop-time_start)) #done running, release lock self.spinsim_thread_lock.release() #[/runHsweepSlot()] def handleLoadParamsFromFile(self): """Handler for "load parameters from file" button""" #get filename from dialog #get filename from dialog filename = Qt.QFileDialog.getOpenFileName(self, "", "", "*.ini") #if it's a valid length, open the file! if(len(filename) > 1): self.loadParamsFromFile(str(filename)) def loadParamsFromFile(self, filename): """This function loads the parameters from file 'filename' and updates the GUI with the loaded params Intended for either hand-coding parameter file or saving your runs using saveParamsToFile""" #open the file for reading try: my_file = open(filename, 'r') except IOError: print "Couldn't open file! Sorry." Qt.QMessageBox.warning(self, "Info", "Couldn't open INI file! Sorry.") return 0 #Parse each line based on the first token (tokens split by '=' character) #If it's a valid token, read in the second token to the correct variable. If it's a comment, skip. #Otherwise, print "unrecognized line" error. for line in my_file: #split the line on the '=' character string_split = line.partition('=') if(line[0] == '#'): print("Skipping comment") #match line like "first_token=3.14159" elif(string_split[0] == "thetaoff"): self.sv_thetaoff = float(string_split[2]) elif(string_split[0] == "percK2"): self.sv_percK2 = float(string_split[2]) elif(string_split[0] == "Alpha"): self.sv_Alpha[0] = float(string_split[2]) self.sv_Alpha[1] = float(string_split[2]) self.sv_Alpha[2] = float(string_split[2]) self.sv_Alpha[3] = float(string_split[2]) elif(string_split[0] == "Alpha_0"): self.sv_Alpha[0] = float(string_split[2]) elif(string_split[0] == "Alpha_1"): self.sv_Alpha[1] = float(string_split[2]) elif(string_split[0] == "Alpha_2"): self.sv_Alpha[2] = float(string_split[2]) elif(string_split[0] == "Alpha_3"): self.sv_Alpha[3] = float(string_split[2]) elif(string_split[0] == "K1_1"): self.sv_K1[0] = float(string_split[2]) elif(string_split[0] == "K1_2"): self.sv_K1[1] = float(string_split[2]) elif(string_split[0] == "K1_3"): self.sv_K1[2] = float(string_split[2]) elif(string_split[0] == "K1_4"): self.sv_K1[3] = float(string_split[2]) elif(string_split[0] == "Ms_1"): self.sv_Ms[0] = float(string_split[2]) elif(string_split[0] == "Ms_2"): self.sv_Ms[1] = float(string_split[2]) elif(string_split[0] == "Ms_3"): self.sv_Ms[2] = float(string_split[2]) elif(string_split[0] == "Ms_4"): self.sv_Ms[3] = float(string_split[2]) elif(string_split[0] == "lposz_1"): self.sv_lposz[0] = float(string_split[2]) elif(string_split[0] == "lposz_2"): self.sv_lposz[1] = float(string_split[2]) elif(string_split[0] == "lposz_3"): self.sv_lposz[2] = float(string_split[2]) elif(string_split[0] == "lposz_4"): self.sv_lposz[3] = float(string_split[2]) elif(string_split[0] == "jmin"): self.sv_jmin = float(string_split[2]) elif(string_split[0] == "jmax"): self.sv_jmax = float(string_split[2]) elif(string_split[0] == "n"): self.sv_n = int(string_split[2]) elif(string_split[0] == "hzmin"): self.sv_hzmin = float(string_split[2]) elif(string_split[0] == "hzmax"): self.sv_hzmax = float(string_split[2]) elif(string_split[0] == "nfield"): self.sv_nfield = int(string_split[2]) elif(string_split[0] == "t_f"): self.sv_tf = float(string_split[2]) elif(string_split[0] == "j_timdep_funs"): self.sv_j_timdep_funs = int(string_split[2]) elif(string_split[0] == "hz_timdep_funs"): self.sv_hz_timdep_funs = int(string_split[2]) elif(string_split[0] == "dx"): self.sv_dx = float(string_split[2]) elif(string_split[0] == "dy"): self.sv_dy = float(string_split[2]) elif(string_split[0] == "temperature"): self.sv_temperature = float(string_split[2]) elif(string_split[0] == "initmag_x_1"): self.sv_initmag_x[0] = float(string_split[2]) elif(string_split[0] == "initmag_x_2"): self.sv_initmag_x[1] = float(string_split[2]) elif(string_split[0] == "initmag_x_3"): self.sv_initmag_x[2] = float(string_split[2]) elif(string_split[0] == "initmag_x_4"): self.sv_initmag_x[3] = float(string_split[2]) elif(string_split[0] == "initmag_y_1"): self.sv_initmag_y[0] = float(string_split[2]) elif(string_split[0] == "initmag_y_2"): self.sv_initmag_y[1] = float(string_split[2]) elif(string_split[0] == "initmag_y_3"): self.sv_initmag_y[2] = float(string_split[2]) elif(string_split[0] == "initmag_y_4"): self.sv_initmag_y[3] = float(string_split[2]) elif(string_split[0] == "initmag_z_1"): self.sv_initmag_z[0] = float(string_split[2]) elif(string_split[0] == "initmag_z_2"): self.sv_initmag_z[1] = float(string_split[2]) elif(string_split[0] == "initmag_z_3"): self.sv_initmag_z[2] = float(string_split[2]) elif(string_split[0] == "initmag_z_4"): self.sv_initmag_z[3] = float(string_split[2]) elif(string_split[0] == "dz_1"): self.sv_dz[0] = float(string_split[2]) elif(string_split[0] == "dz_2"): self.sv_dz[1] = float(string_split[2]) elif(string_split[0] == "dz_3"): self.sv_dz[2] = float(string_split[2]) elif(string_split[0] == "dz_4"): self.sv_dz[3] = float(string_split[2]) elif(string_split[0] == "polarisation_1"): self.sv_pol[0] = float(string_split[2]) elif(string_split[0] == "polarisation_2"): self.sv_pol[1] = float(string_split[2]) elif(string_split[0] == "polarisation_3"): self.sv_pol[2] = float(string_split[2]) elif(string_split[0] == "polarisation_4"): self.sv_pol[3] = float(string_split[2]) elif(string_split[0] == "t_relax"): self.sv_relax = float(string_split[2]) elif(string_split[0] == "layeren_1"): self.sv_layerEn[0] = int(string_split[2]) elif(string_split[0] == "layeren_2"): self.sv_layerEn[1] = int(string_split[2]) elif(string_split[0] == "layeren_3"): self.sv_layerEn[2] = int(string_split[2]) elif(string_split[0] == "layeren_4"): self.sv_layerEn[3] = int(string_split[2]) elif(string_split[0] == "layerfixed_1"): self.sv_layerFixed[0] = int(string_split[2]) elif(string_split[0] == "layerfixed_2"): self.sv_layerFixed[1] = int(string_split[2]) elif(string_split[0] == "layerfixed_3"): self.sv_layerFixed[2] = int(string_split[2]) elif(string_split[0] == "layerfixed_4"): self.sv_layerFixed[3] = int(string_split[2]) elif(string_split[0] == "numthreads"): self.sv_numthreads = int(string_split[2]) elif(string_split[0] == "numFrames"): self.sv_numFrames = int(string_split[2]) elif(string_split[0] == "af_bw_12"): self.sv_af[0] = float(string_split[2]) elif(string_split[0] == "af_bw_13"): self.sv_af[1] = float(string_split[2]) elif(string_split[0] == "af_bw_14"): self.sv_af[2] = float(string_split[2]) elif(string_split[0] == "af_bw_23"): self.sv_af[3] = float(string_split[2]) elif(string_split[0] == "af_bw_24"): self.sv_af[4] = float(string_split[2]) elif(string_split[0] == "af_bw_34"): self.sv_af[5] = float(string_split[2]) else: print("Couldn't parse line %s in file %s, are you sure the format is 'token=123.0' with no extra spaces?" % (line, filename)) #close the file my_file.close() #load new parameters into GUI fields self.variablesToDialogNonLayer() self.handleLayernButton(self.ui.curr_layer) return 0 #[/loadParamsFromFile] def handleSaveParamsToFile(self): """Handler for "save parameters to file" button""" #get filename from dialog filename = Qt.QFileDialog.getSaveFileName(self, "", "", "*.ini") #if it's a valid length, open the file! if(len(filename) > 1): self.saveParamsToFile(str(filename)) def saveParamsToFile(self, filename): """This function saves the parameters to file 'filename' Intended for saving your runs, to be used later with loadParamsFromFile""" #grab latest parameters from GUI fields self.dialogToVariablesNonLayer() self.storeLayern(self.ui.curr_layer) print("Debug: Saving params to file %s" % filename) #Open file for writing try: my_file = open(filename, 'w') except IOError: print ("Couldn't open file %s! Sorry." % my_file) Qt.QMessageBox.warning(self, "Info", "Couldn't open INI file! Sorry.") return 0 #write out all of the parameters, with the correct token string so that #loadParamsFromFile() can read and parse the file back in. my_file.write("thetaoff=%e\n" % self.sv_thetaoff) my_file.write("percK2=%e\n" % self.sv_percK2) my_file.write("Alpha_0=%e\n" % self.sv_Alpha[0]) my_file.write("Alpha_1=%e\n" % self.sv_Alpha[1]) my_file.write("Alpha_2=%e\n" % self.sv_Alpha[2]) my_file.write("Alpha_3=%e\n" % self.sv_Alpha[3]) my_file.write("K1_1=%e\n" % self.sv_K1[0]) my_file.write("K1_2=%e\n" % self.sv_K1[1]) my_file.write("K1_3=%e\n" % self.sv_K1[2]) my_file.write("K1_4=%e\n" % self.sv_K1[3]) my_file.write("Ms_1=%e\n" % self.sv_Ms[0]) my_file.write("Ms_2=%e\n" % self.sv_Ms[1]) my_file.write("Ms_3=%e\n" % self.sv_Ms[2]) my_file.write("Ms_4=%e\n" % self.sv_Ms[3]) my_file.write("lposz_1=%e\n" % self.sv_lposz[0]) my_file.write("lposz_2=%e\n" % self.sv_lposz[1]) my_file.write("lposz_3=%e\n" % self.sv_lposz[2]) my_file.write("lposz_4=%e\n" % self.sv_lposz[3]) my_file.write("jmin=%e\n" % self.sv_jmin) my_file.write("jmax=%e\n" % self.sv_jmax) my_file.write("n=%d\n" % self.sv_n) my_file.write("hzmin=%e\n" % self.sv_hzmin) my_file.write("hzmax=%e\n" % self.sv_hzmax) my_file.write("nfield=%d\n" % self.sv_nfield) my_file.write("t_f=%e\n" % self.sv_tf) my_file.write("j_timdep_funs=%d\n" % self.sv_j_timdep_funs) my_file.write("hz_timdep_funs=%d\n" % self.sv_hz_timdep_funs) my_file.write("dx=%e\n" % self.sv_dx) my_file.write("dy=%e\n" % self.sv_dy) my_file.write("temperature=%e\n" % self.sv_temperature) my_file.write("initmag_x_1=%e\n" % self.sv_initmag_x[0]) my_file.write("initmag_x_2=%e\n" % self.sv_initmag_x[1]) my_file.write("initmag_x_3=%e\n" % self.sv_initmag_x[2]) my_file.write("initmag_x_4=%e\n" % self.sv_initmag_x[3]) my_file.write("initmag_y_1=%e\n" % self.sv_initmag_y[0]) my_file.write("initmag_y_2=%e\n" % self.sv_initmag_y[1]) my_file.write("initmag_y_3=%e\n" % self.sv_initmag_y[2]) my_file.write("initmag_y_4=%e\n" % self.sv_initmag_y[3]) my_file.write("initmag_z_1=%e\n" % self.sv_initmag_z[0]) my_file.write("initmag_z_2=%e\n" % self.sv_initmag_z[1]) my_file.write("initmag_z_3=%e\n" % self.sv_initmag_z[2]) my_file.write("initmag_z_4=%e\n" % self.sv_initmag_z[3]) my_file.write("dz_1=%e\n" % self.sv_dz[0]) my_file.write("dz_2=%e\n" % self.sv_dz[1]) my_file.write("dz_3=%e\n" % self.sv_dz[2]) my_file.write("dz_4=%e\n" % self.sv_dz[3]) my_file.write("polarisation_1=%e\n" % self.sv_pol[0]) my_file.write("polarisation_2=%e\n" % self.sv_pol[1]) my_file.write("polarisation_3=%e\n" % self.sv_pol[2]) my_file.write("polarisation_4=%e\n" % self.sv_pol[3]) my_file.write("layeren_1=%d\n" % self.sv_layerEn[0]) my_file.write("layeren_2=%d\n" % self.sv_layerEn[1]) my_file.write("layeren_3=%d\n" % self.sv_layerEn[2]) my_file.write("layeren_4=%d\n" % self.sv_layerEn[3]) my_file.write("layerfixed_1=%d\n" % self.sv_layerFixed[0]) my_file.write("layerfixed_2=%d\n" % self.sv_layerFixed[1]) my_file.write("layerfixed_3=%d\n" % self.sv_layerFixed[2]) my_file.write("layerfixed_4=%d\n" % self.sv_layerFixed[3]) my_file.write("numthreads=%d\n" % self.sv_numthreads) my_file.write("numFrames=%d\n" % self.sv_numFrames) my_file.write("af_bw_12=%e\n" % self.sv_af[0]); my_file.write("af_bw_13=%e\n" % self.sv_af[1]); my_file.write("af_bw_14=%e\n" % self.sv_af[2]); my_file.write("af_bw_23=%e\n" % self.sv_af[3]); my_file.write("af_bw_24=%e\n" % self.sv_af[4]); my_file.write("af_bw_34=%e\n" % self.sv_af[5]); my_file.write("t_relax=%e\n" % self.sv_relax); my_file.close() return 0 #[/saveParamsToFile] def generateSimType(self): """This function reads sv_layerEn and sv_layerFixed variables and packs them into the standard 'simtype' form. See the documentation for more information about what the "generic" models that we pack down into are. Mostly, it's just moving the layers so that the enabled layers are all adjacent to each other.""" layerPos = [0,0,0,0] count = 0 lp_count = 0 #go through all enabled layers and count them while(count < 4): if(self.sv_layerEn[count] != 0): layerPos[lp_count] = count lp_count += 1 count += 1 #put together integer to return returned = 0 count = 0 while(count < lp_count): if(self.sv_layerFixed[layerPos[count]] == 1): returned += (1 << (2*count)) else: returned += (2 << (2*count)) count += 1 #[/while] #set field-in-plane simulation function returned += self.sv_fieldInPlane << 31 return(returned) def timedep_writeback(self, j_funs, hz_funs): """This function gets called by TimeDep_Handler to pass the j_timdep_funs and hz_timdep_funs variables back to (this) parent dialog""" self.sv_j_timdep_funs = j_funs self.sv_hz_timdep_funs = hz_funs print("DEBUG: spinsim GUI parent dialog got %f, %f for j_funs and hz_funs" % (self.sv_j_timdep_funs, self.sv_hz_timdep_funs))