From 115541449f8fd5afd4b8fd2cd86e3185d5ea04a5 Mon Sep 17 00:00:00 2001
From: "Michael D. M. Dryden" <mdryden@chem.utoronto.ca>
Date: Mon, 7 Jul 2014 19:33:06 -0400
Subject: [PATCH] Implemented CSWV by adding to old SWV module. Changed storage
 of forward/reverse current to new data_extra class object to use existing CV
 plotting code. Renamed Converted Data tab to Extra data. Saving of extra data
 not yet implemented.

---
 dstatInterface/dstat_comm.py                  | 37 +++++++++--
 dstatInterface/interface/dstatInterface.glade |  2 +-
 dstatInterface/interface/swv.glade            | 66 ++++++++++++++++++-
 dstatInterface/interface/swv.py               |  4 +-
 dstatInterface/interface_test.py              | 26 ++++++--
 5 files changed, 121 insertions(+), 14 deletions(-)

diff --git a/dstatInterface/dstat_comm.py b/dstatInterface/dstat_comm.py
index 604bf4a..a11f9a5 100644
--- a/dstatInterface/dstat_comm.py
+++ b/dstatInterface/dstat_comm.py
@@ -49,6 +49,7 @@ class Experiment:
         pass
     
     def init(self):
+        self.data_extra = [] #must be defined even when not needed
         self.__gaintable = [1e2, 3e2, 3e3, 3e4, 3e5, 3e6, 3e7, 5e8]
         self.gain = self.__gaintable[int(self.parameters['gain'])]
         self.updatelimit = self.view_parameters['updatelimit']
@@ -290,13 +291,14 @@ class swv_exp(Experiment):
         self.datatype = "SWVData"
         self.xlabel = "Voltage (DAC units)"
         self.ylabel = "Current (A)"
-        self.data = [[],[],[],[]] #one extra for difference
-        self.datalength = 4
+        self.data = [[],[]] #only difference stored here
+        self.datalength = 2 * self.parameters['scans']
         
         self.xmin = self.parameters['start']
         self.xmax = self.parameters['stop']
         
         self.init()
+        self.data_extra = [[],[]] #forward/reverse stored here - needs to be after self.init to keep from being redefined
         
         self.commands += "S"
         self.commands[2] += str(self.parameters['start'])
@@ -309,20 +311,24 @@ class swv_exp(Experiment):
         self.commands[2] += " "
         self.commands[2] += str(self.parameters['freq'])
         self.commands[2] += " "
+        self.commands[2] += str(self.parameters['scans'])
+        self.commands[2] += " "
     
     def data_handler(self):
+        scan = 0
+    
         while True:
             for line in self.ser:
                 if line.startswith('B'):
                     inputdata = self.ser.read(size=10) #uint16 + 2*int32
                     voltage, forward, reverse = struct.unpack('<Hll', inputdata)
 
-                    self.data[0].append((voltage-32768)*3000./65536)
-                    self.data[1].append((forward-reverse)*(1.5/self.gain/8388607))
-                    self.data[2].append(forward*(1.5/self.gain/8388607))
-                    self.data[3].append(reverse*(1.5/self.gain/8388607))
+                    self.data[2*scan].append((voltage-32768)*3000./65536)
+                    self.data[2*scan+1].append((forward-reverse)*(1.5/self.gain/8388607))
+                    self.data_extra[2*scan].append(forward*(1.5/self.gain/8388607))
+                    self.data_extra[2*scan+1].append(reverse*(1.5/self.gain/8388607))
                     
-                    self.plot.updateline(self, 0) #displays only difference current, but forward and reverse stored
+                    self.plot.updateline(self, scan) #displays only difference current, but forward and reverse stored
                     
                     if self.update:
                         if self.updatecounter == self.updatelimit:
@@ -335,6 +341,23 @@ class swv_exp(Experiment):
                 elif line.lstrip().startswith("no"):
                     self.ser.flushInput()
                     break
+        
+                elif line.lstrip().startswith('S'):
+                    self.plot.redraw()
+                    self.plot.addline()
+                    self.data.append([])
+                    self.data.append([])
+                    self.data_extra.append([])
+                    self.data_extra.append([])
+                    scan += 1
+                
+                elif line.lstrip().startswith('D'):
+                    self.data.pop()
+                    self.data.pop() #instrument signals with S after each cycle, so last one will be blank, D singals end of experiment
+                    self.data_extra.pop()
+                    self.data_extra.pop()
+                    self.plot.clearline(scan)
+                    self.plot.redraw()
             
             break
 
diff --git a/dstatInterface/interface/dstatInterface.glade b/dstatInterface/interface/dstatInterface.glade
index 8c0a51b..c476d8f 100644
--- a/dstatInterface/interface/dstatInterface.glade
+++ b/dstatInterface/interface/dstatInterface.glade
@@ -569,7 +569,7 @@
                   <object class="GtkLabel" id="label5">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Converted Data</property>
+                    <property name="label" translatable="yes">Extra Data</property>
                   </object>
                   <packing>
                     <property name="position">2</property>
diff --git a/dstatInterface/interface/swv.glade b/dstatInterface/interface/swv.glade
index 875db5e..2f89f66 100644
--- a/dstatInterface/interface/swv.glade
+++ b/dstatInterface/interface/swv.glade
@@ -224,7 +224,7 @@
                           <object class="GtkTable" id="table2">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="n_rows">5</property>
+                            <property name="n_rows">7</property>
                             <property name="n_columns">2</property>
                             <property name="column_spacing">10</property>
                             <property name="homogeneous">True</property>
@@ -404,6 +404,70 @@
                                 <property name="y_padding">3</property>
                               </packing>
                             </child>
+                            <child>
+                              <object class="GtkLabel" id="label14">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="tooltip_text" translatable="yes">Scan both forwards and backwards.</property>
+                                <property name="label" translatable="yes">Cyclic Mode</property>
+                              </object>
+                              <packing>
+                                <property name="top_attach">5</property>
+                                <property name="bottom_attach">6</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label15">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Scans</property>
+                              </object>
+                              <packing>
+                                <property name="top_attach">6</property>
+                                <property name="bottom_attach">7</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="cyclic_checkbutton">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_stock">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">5</property>
+                                <property name="bottom_attach">6</property>
+                                <property name="x_options"/>
+                                <property name="y_options"/>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkEntry" id="scans_entry">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">●</property>
+                                <property name="width_chars">8</property>
+                                <property name="text" translatable="yes">0</property>
+                                <property name="xalign">1</property>
+                                <property name="invisible_char_set">True</property>
+                                <property name="primary_icon_activatable">False</property>
+                                <property name="secondary_icon_activatable">False</property>
+                                <property name="primary_icon_sensitive">True</property>
+                                <property name="secondary_icon_sensitive">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">6</property>
+                                <property name="bottom_attach">7</property>
+                                <property name="x_options"/>
+                                <property name="y_options">GTK_FILL</property>
+                                <property name="y_padding">3</property>
+                              </packing>
+                            </child>
                           </object>
                         </child>
                       </object>
diff --git a/dstatInterface/interface/swv.py b/dstatInterface/interface/swv.py
index e4201bd..ff7a497 100644
--- a/dstatInterface/interface/swv.py
+++ b/dstatInterface/interface/swv.py
@@ -12,4 +12,6 @@ class swv:
         self.stop_entry = self.builder.get_object('stop_entry')
         self.step_entry = self.builder.get_object('step_entry')
         self.pulse_entry = self.builder.get_object('pulse_entry')
-        self.freq_entry = self.builder.get_object('freq_entry')
\ No newline at end of file
+        self.freq_entry = self.builder.get_object('freq_entry')
+        self.cyclic_checkbutton = self.builder.get_object('cyclic_checkbutton')
+        self.scans_entry = self.builder.get_object('scans_entry')
\ No newline at end of file
diff --git a/dstatInterface/interface_test.py b/dstatInterface/interface_test.py
index da5f6ee..e521d96 100644
--- a/dstatInterface/interface_test.py
+++ b/dstatInterface/interface_test.py
@@ -261,6 +261,13 @@ class main:
                 parameters['pulse'] = int(self.swv.pulse_entry.get_text())
                 parameters['freq'] = int(self.swv.freq_entry.get_text())
                 
+                if self.swv.cyclic_checkbutton.get_active():
+                    parameters['scans'] = int(self.swv.scans_entry.get_text())
+                    if parameters['scans'] < 1:
+                        raise InputError(parameters['scans'],"Must have at least one scan.")
+                else:
+                    parameters['scans'] = 0
+                
                 #check parameters are within hardware limits (doesn't check if pulse will go out of bounds, but instrument checks this (I think))
                 if (parameters['start'] > 1499 or parameters['start'] < -1500):
                     raise InputError(parameters['start'],"Start parameter exceeds hardware limits.")
@@ -299,11 +306,22 @@ class main:
         
         self.databuffer.set_text("")
         self.databuffer.place_cursor(self.databuffer.get_start_iter())
+        self.rawbuffer.set_text("")
+        self.rawbuffer.place_cursor(self.rawbuffer.get_start_iter())
+
+        for col in zip(*self.current_exp.data):
+            for row in col:
+                self.rawbuffer.insert_at_cursor(str(row)+ "\t")
+            self.rawbuffer.insert_at_cursor("\n")
 
-        for i in zip(*self.current_exp.data):
-            for j in i:
-                self.databuffer.insert_at_cursor(str(j)+ "\t")
-            self.databuffer.insert_at_cursor("\n")
+        
+        if self.current_exp.data_extra:
+            for col in zip(*self.current_exp.data_extra):
+                for row in col:
+                    self.databuffer.insert_at_cursor(str(row)+ "\t")
+                self.databuffer.insert_at_cursor("\n")
+        
+        
         self.spinner.stop()
 
     def on_file_save_exp_activate(self, menuitem, data=None):
-- 
GitLab