Browse Source

Better legacy support, old FID data were not phase cycled.

tags/1.6.1
Trevor Irons 4 years ago
parent
commit
7fe281b34d
6 changed files with 443 additions and 328 deletions
  1. 19
    4
      akvo/gui/akvoGUI.py
  2. 230
    312
      akvo/gui/main.ui
  3. 2
    1
      akvo/tressel/adapt.py
  4. 1
    1
      akvo/tressel/decay.py
  5. 190
    9
      akvo/tressel/mrsurvey.py
  6. 1
    1
      setup.py

+ 19
- 4
akvo/gui/akvoGUI.py View File

@@ -596,7 +596,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
596 596
         self.ui.lcdNumberNQ.display(self.RAWDataProc.nPulseMoments)
597 597
         self.ui.DeadTimeSpinBox.setValue(1e3*self.RAWDataProc.deadTime)
598 598
         self.ui.CentralVSpinBox.setValue( self.RAWDataProc.transFreq )
599
-       
599
+            
600 600
         if self.RAWDataProc.pulseType != "FID":
601 601
             self.ui.lcdNumberTauPulse2.setEnabled(1)
602 602
             self.ui.lcdNumberTauPulse2.display(1e3*self.RAWDataProc.pulseLength[1])
@@ -604,7 +604,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
604 604
             self.ui.lcdNumberTauDelay.display(1e3*self.RAWDataProc.interpulseDelay)
605 605
 
606 606
         self.ui.FIDProcComboBox.clear() 
607
-        if self.RAWDataProc.pulseType == "4PhaseT1":
607
+        if self.RAWDataProc.pulseType == "4PhaseT1" or self.RAWDataProc.pulseType == "T1":
608 608
             self.ui.FIDProcComboBox.insertItem(0, "Pulse 1") 
609 609
             self.ui.FIDProcComboBox.insertItem(1, "Pulse 2") 
610 610
             self.ui.FIDProcComboBox.insertItem(2, "Both")    
@@ -716,6 +716,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
716 716
         # Add some extra info 
717 717
         INFO = {}
718 718
         INFO["pulseType"] = self.RAWDataProc.pulseType
719
+        INFO["interpulseDelay"] = self.RAWDataProc.interpulseDelay
719 720
         INFO["transFreq"] = self.RAWDataProc.transFreq
720 721
         INFO["pulseLength"] = self.RAWDataProc.pulseLength
721 722
         INFO["TuneCapacitance"] = self.RAWDataProc.TuneCapacitance
@@ -780,6 +781,8 @@ class ApplicationWindow(QtWidgets.QMainWindow):
780 781
         self.RAWDataProc.transFreq = self.RAWDataProc.DATADICT["INFO"]["transFreq"]
781 782
         self.RAWDataProc.dt = 1./self.RAWDataProc.samp 
782 783
 
784
+
785
+
783 786
         self.dataChan = self.RAWDataProc.DATADICT[ self.RAWDataProc.DATADICT["PULSES"][0] ]["chan"]
784 787
         # Keep backwards compatibility with prior saved pickles???
785 788
         #self.ui.logTextBrowser.clear() 
@@ -795,6 +798,10 @@ class ApplicationWindow(QtWidgets.QMainWindow):
795 798
         self.YamlNode = AkvoYamlNode( )  #self.logText )
796 799
        
797 800
         self.YamlNode.Akvo_VERSION = (yaml.load( self.logText, Loader=yaml.Loader )).Akvo_VERSION
801
+        AKVO_VERSION = np.array(self.YamlNode.Akvo_VERSION.split("."), dtype=int)
802
+        if  AKVO_VERSION[0] >= 1 and AKVO_VERSION[1] >= 2 and AKVO_VERSION[2] >= 3:
803
+            self.RAWDataProc.interpulseDelay = self.RAWDataProc.DATADICT["INFO"]["interpulseDelay"]
804
+
798 805
         self.YamlNode.Import = OrderedDict((yaml.load( self.logText, Loader=yaml.Loader )).Import)
799 806
         self.YamlNode.Processing = OrderedDict((yaml.load( self.logText, Loader=yaml.Loader )).Processing)
800 807
         self.Log() 
@@ -859,7 +866,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
859 866
             self.ui.lcdNumberTauDelay.display(1e3*self.RAWDataProc.interpulseDelay)
860 867
 
861 868
         self.ui.FIDProcComboBox.clear() 
862
-        if self.RAWDataProc.pulseType == "4PhaseT1":
869
+        if self.RAWDataProc.pulseType == "4PhaseT1" or self.RAWDataProc.pulseType == "T1":
863 870
             self.ui.FIDProcComboBox.insertItem(0, "Pulse 1") #, const QVariant & userData = QVariant() )
864 871
             self.ui.FIDProcComboBox.insertItem(1, "Pulse 2") #, const QVariant & userData = QVariant() )
865 872
             self.ui.FIDProcComboBox.insertItem(2, "Both")    #, const QVariant & userData = QVariant() )
@@ -950,12 +957,20 @@ class ApplicationWindow(QtWidgets.QMainWindow):
950 957
                 (str(self.headerstr), self.procStacks, self.dataChan, self.refChan, \
951 958
                  str(self.ui.FIDProcComboBox.currentText()), self.ui.mplwidget, \
952 959
                 1e-3 * self.ui.DeadTimeSpinBox.value( ), self.ui.plotImportCheckBox.isChecked() )) #, self)) 
953
-            
954 960
         elif self.RAWDataProc.pulseType == "4PhaseT1":
955 961
             self.procThread = thread.start_new_thread(self.RAWDataProc.load4PhaseT1Data, \
956 962
                 (str(self.headerstr), self.procStacks, self.dataChan, self.refChan, \
957 963
                  str(self.ui.FIDProcComboBox.currentText()), self.ui.mplwidget, \
958 964
                 1e-3 * self.ui.DeadTimeSpinBox.value( ), self.ui.plotImportCheckBox.isChecked() )) #, self)) 
965
+        elif self.RAWDataProc.pulseType == "T1":
966
+            self.procThread = thread.start_new_thread(self.RAWDataProc.loadT1Data, \
967
+                (str(self.headerstr), self.procStacks, self.dataChan, self.refChan, \
968
+                 str(self.ui.FIDProcComboBox.currentText()), self.ui.mplwidget, \
969
+                1e-3 * self.ui.DeadTimeSpinBox.value( ), self.ui.plotImportCheckBox.isChecked() )) #, self)) 
970
+            #self.procThread = thread.start_new_thread(self.RAWDataProc.load4PhaseT1Data, \
971
+            #    (str(self.headerstr), self.procStacks, self.dataChan, self.refChan, \
972
+            #     str(self.ui.FIDProcComboBox.currentText()), self.ui.mplwidget, \
973
+            #    1e-3 * self.ui.DeadTimeSpinBox.value( ), self.ui.plotImportCheckBox.isChecked() )) #, self)) 
959 974
 
960 975
         self.YamlNode.Import["GMR Header"] = self.headerstr
961 976
         self.YamlNode.Import["opened"] = datetime.datetime.now().isoformat() 

+ 230
- 312
akvo/gui/main.ui View File

@@ -1651,71 +1651,67 @@ background: dark grey;
1651 1651
               <property name="checkable">
1652 1652
                <bool>true</bool>
1653 1653
               </property>
1654
-              <widget class="QLabel" name="label_8">
1655
-               <property name="geometry">
1656
-                <rect>
1657
-                 <x>8</x>
1658
-                 <y>84</y>
1659
-                 <width>399</width>
1660
-                 <height>10</height>
1661
-                </rect>
1662
-               </property>
1663
-               <property name="sizePolicy">
1664
-                <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
1665
-                 <horstretch>0</horstretch>
1666
-                 <verstretch>0</verstretch>
1667
-                </sizepolicy>
1668
-               </property>
1669
-               <property name="minimumSize">
1670
-                <size>
1671
-                 <width>0</width>
1672
-                 <height>10</height>
1673
-                </size>
1674
-               </property>
1675
-               <property name="maximumSize">
1676
-                <size>
1677
-                 <width>16777215</width>
1678
-                 <height>10</height>
1679
-                </size>
1680
-               </property>
1681
-               <property name="text">
1682
-                <string>Fourier-based calculation</string>
1683
-               </property>
1684
-              </widget>
1685
-              <widget class="QPushButton" name="calcQGO">
1686
-               <property name="geometry">
1687
-                <rect>
1688
-                 <x>400</x>
1689
-                 <y>100</y>
1690
-                 <width>84</width>
1691
-                 <height>30</height>
1692
-                </rect>
1693
-               </property>
1694
-               <property name="sizePolicy">
1695
-                <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
1696
-                 <horstretch>0</horstretch>
1697
-                 <verstretch>0</verstretch>
1698
-                </sizepolicy>
1699
-               </property>
1700
-               <property name="minimumSize">
1701
-                <size>
1702
-                 <width>80</width>
1703
-                 <height>30</height>
1704
-                </size>
1705
-               </property>
1706
-               <property name="styleSheet">
1707
-                <string notr="true">#calcQGO {
1654
+              <layout class="QGridLayout" name="gridLayout_13">
1655
+               <item row="1" column="1">
1656
+                <widget class="QPushButton" name="calcQGO">
1657
+                 <property name="sizePolicy">
1658
+                  <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
1659
+                   <horstretch>0</horstretch>
1660
+                   <verstretch>0</verstretch>
1661
+                  </sizepolicy>
1662
+                 </property>
1663
+                 <property name="minimumSize">
1664
+                  <size>
1665
+                   <width>80</width>
1666
+                   <height>20</height>
1667
+                  </size>
1668
+                 </property>
1669
+                 <property name="maximumSize">
1670
+                  <size>
1671
+                   <width>16777215</width>
1672
+                   <height>16777215</height>
1673
+                  </size>
1674
+                 </property>
1675
+                 <property name="styleSheet">
1676
+                  <string notr="true">#calcQGO {
1708 1677
     background: green;
1709 1678
 }
1710 1679
 
1711 1680
 #calcQGO:disabled{
1712 1681
     background: black;
1713 1682
 }</string>
1714
-               </property>
1715
-               <property name="text">
1716
-                <string>GO</string>
1717
-               </property>
1718
-              </widget>
1683
+                 </property>
1684
+                 <property name="text">
1685
+                  <string>GO</string>
1686
+                 </property>
1687
+                </widget>
1688
+               </item>
1689
+               <item row="1" column="0">
1690
+                <widget class="QLabel" name="label_8">
1691
+                 <property name="sizePolicy">
1692
+                  <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
1693
+                   <horstretch>0</horstretch>
1694
+                   <verstretch>0</verstretch>
1695
+                  </sizepolicy>
1696
+                 </property>
1697
+                 <property name="minimumSize">
1698
+                  <size>
1699
+                   <width>0</width>
1700
+                   <height>10</height>
1701
+                  </size>
1702
+                 </property>
1703
+                 <property name="maximumSize">
1704
+                  <size>
1705
+                   <width>16777215</width>
1706
+                   <height>10</height>
1707
+                  </size>
1708
+                 </property>
1709
+                 <property name="text">
1710
+                  <string>Fourier-based calculation</string>
1711
+                 </property>
1712
+                </widget>
1713
+               </item>
1714
+              </layout>
1719 1715
              </widget>
1720 1716
             </item>
1721 1717
             <item>
@@ -1747,83 +1743,61 @@ background: dark grey;
1747 1743
               <property name="checkable">
1748 1744
                <bool>true</bool>
1749 1745
               </property>
1750
-              <widget class="QComboBox" name="outlierTestCB">
1751
-               <property name="geometry">
1752
-                <rect>
1753
-                 <x>90</x>
1754
-                 <y>65</y>
1755
-                 <width>78</width>
1756
-                 <height>25</height>
1757
-                </rect>
1758
-               </property>
1759
-               <item>
1760
-                <property name="text">
1761
-                 <string>MAD</string>
1762
-                </property>
1746
+              <layout class="QGridLayout" name="gridLayout_14">
1747
+               <item row="0" column="0">
1748
+                <widget class="QLabel" name="label_37">
1749
+                 <property name="text">
1750
+                  <string>Outlier test</string>
1751
+                 </property>
1752
+                </widget>
1763 1753
                </item>
1764
-               <item>
1765
-                <property name="text">
1766
-                 <string>none</string>
1767
-                </property>
1754
+               <item row="1" column="0">
1755
+                <widget class="QComboBox" name="outlierTestCB">
1756
+                 <item>
1757
+                  <property name="text">
1758
+                   <string>MAD</string>
1759
+                  </property>
1760
+                 </item>
1761
+                 <item>
1762
+                  <property name="text">
1763
+                   <string>none</string>
1764
+                  </property>
1765
+                 </item>
1766
+                </widget>
1768 1767
                </item>
1769
-              </widget>
1770
-              <widget class="QLabel" name="label_37">
1771
-               <property name="geometry">
1772
-                <rect>
1773
-                 <x>10</x>
1774
-                 <y>70</y>
1775
-                 <width>71</width>
1776
-                 <height>16</height>
1777
-                </rect>
1778
-               </property>
1779
-               <property name="text">
1780
-                <string>Outlier test</string>
1781
-               </property>
1782
-              </widget>
1783
-              <widget class="QPushButton" name="FDSmartStackGO">
1784
-               <property name="geometry">
1785
-                <rect>
1786
-                 <x>350</x>
1787
-                 <y>70</y>
1788
-                 <width>99</width>
1789
-                 <height>23</height>
1790
-                </rect>
1791
-               </property>
1792
-               <property name="styleSheet">
1793
-                <string notr="true">#FDSmartStackGO {
1768
+               <item row="2" column="1">
1769
+                <widget class="QPushButton" name="FDSmartStackGO">
1770
+                 <property name="styleSheet">
1771
+                  <string notr="true">#FDSmartStackGO {
1794 1772
     background: green;
1795 1773
 }
1796 1774
 
1797 1775
 #FDSmartStackGO:disabled{
1798 1776
     background: black;
1799 1777
 }</string>
1800
-               </property>
1801
-               <property name="text">
1802
-                <string>GO</string>
1803
-               </property>
1804
-              </widget>
1805
-              <widget class="QDoubleSpinBox" name="MADCutoff">
1806
-               <property name="geometry">
1807
-                <rect>
1808
-                 <x>90</x>
1809
-                 <y>90</y>
1810
-                 <width>121</width>
1811
-                 <height>22</height>
1812
-                </rect>
1813
-               </property>
1814
-               <property name="toolTip">
1815
-                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The threshold value used in the median absolute deviation outlier test. The default value of 1.4826 follows from an assumption of Gaussian noise, lower cutoff values are stricter and will throw out more samples.  &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
1816
-               </property>
1817
-               <property name="decimals">
1818
-                <number>4</number>
1819
-               </property>
1820
-               <property name="maximum">
1821
-                <double>10.000000000000000</double>
1822
-               </property>
1823
-               <property name="value">
1824
-                <double>1.480000000000000</double>
1825
-               </property>
1826
-              </widget>
1778
+                 </property>
1779
+                 <property name="text">
1780
+                  <string>GO</string>
1781
+                 </property>
1782
+                </widget>
1783
+               </item>
1784
+               <item row="1" column="1">
1785
+                <widget class="QDoubleSpinBox" name="MADCutoff">
1786
+                 <property name="toolTip">
1787
+                  <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The threshold value used in the median absolute deviation outlier test. The default value of 1.4826 follows from an assumption of Gaussian noise, lower cutoff values are stricter and will throw out more samples.  &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
1788
+                 </property>
1789
+                 <property name="decimals">
1790
+                  <number>4</number>
1791
+                 </property>
1792
+                 <property name="maximum">
1793
+                  <double>10.000000000000000</double>
1794
+                 </property>
1795
+                 <property name="value">
1796
+                  <double>1.480000000000000</double>
1797
+                 </property>
1798
+                </widget>
1799
+               </item>
1800
+              </layout>
1827 1801
              </widget>
1828 1802
             </item>
1829 1803
             <item>
@@ -1855,110 +1829,82 @@ background: dark grey;
1855 1829
               <property name="checkable">
1856 1830
                <bool>true</bool>
1857 1831
               </property>
1858
-              <widget class="QPushButton" name="qdGO">
1859
-               <property name="geometry">
1860
-                <rect>
1861
-                 <x>350</x>
1862
-                 <y>60</y>
1863
-                 <width>99</width>
1864
-                 <height>23</height>
1865
-                </rect>
1866
-               </property>
1867
-               <property name="styleSheet">
1868
-                <string notr="true">#qdGO {
1832
+              <layout class="QGridLayout" name="gridLayout_15">
1833
+               <item row="1" column="3">
1834
+                <widget class="QPushButton" name="qdGO">
1835
+                 <property name="styleSheet">
1836
+                  <string notr="true">#qdGO {
1869 1837
     background: green;
1870 1838
 }
1871 1839
 
1872 1840
 #qdGO:disabled{
1873 1841
     background: black;
1874 1842
 }</string>
1875
-               </property>
1876
-               <property name="text">
1877
-                <string>GO</string>
1878
-               </property>
1879
-              </widget>
1880
-              <widget class="QSpinBox" name="trimSpin">
1881
-               <property name="geometry">
1882
-                <rect>
1883
-                 <x>90</x>
1884
-                 <y>30</y>
1885
-                 <width>91</width>
1886
-                 <height>28</height>
1887
-                </rect>
1888
-               </property>
1889
-               <property name="minimum">
1890
-                <number>0</number>
1891
-               </property>
1892
-               <property name="value">
1893
-                <number>0</number>
1894
-               </property>
1895
-              </widget>
1896
-              <widget class="QLabel" name="label_38">
1897
-               <property name="geometry">
1898
-                <rect>
1899
-                 <x>20</x>
1900
-                 <y>34</y>
1901
-                 <width>61</width>
1902
-                 <height>18</height>
1903
-                </rect>
1904
-               </property>
1905
-               <property name="text">
1906
-                <string>Trim</string>
1907
-               </property>
1908
-              </widget>
1909
-              <widget class="QComboBox" name="QDType">
1910
-               <property name="geometry">
1911
-                <rect>
1912
-                 <x>230</x>
1913
-                 <y>90</y>
1914
-                 <width>101</width>
1915
-                 <height>22</height>
1916
-                </rect>
1917
-               </property>
1918
-               <item>
1919
-                <property name="text">
1920
-                 <string>Real/Imag</string>
1921
-                </property>
1922
-               </item>
1923
-               <item>
1924
-                <property name="text">
1925
-                 <string>Amp/Phase</string>
1926
-                </property>
1843
+                 </property>
1844
+                 <property name="text">
1845
+                  <string>GO</string>
1846
+                 </property>
1847
+                </widget>
1927 1848
                </item>
1928
-               <item>
1929
-                <property name="text">
1930
-                 <string>Phased</string>
1931
-                </property>
1849
+               <item row="2" column="2">
1850
+                <widget class="QComboBox" name="QDType">
1851
+                 <item>
1852
+                  <property name="text">
1853
+                   <string>Real/Imag</string>
1854
+                  </property>
1855
+                 </item>
1856
+                 <item>
1857
+                  <property name="text">
1858
+                   <string>Amp/Phase</string>
1859
+                  </property>
1860
+                 </item>
1861
+                 <item>
1862
+                  <property name="text">
1863
+                   <string>Phased</string>
1864
+                  </property>
1865
+                 </item>
1866
+                </widget>
1932 1867
                </item>
1933
-              </widget>
1934
-              <widget class="QPushButton" name="plotQD">
1935
-               <property name="enabled">
1936
-                <bool>false</bool>
1937
-               </property>
1938
-               <property name="geometry">
1939
-                <rect>
1940
-                 <x>350</x>
1941
-                 <y>90</y>
1942
-                 <width>99</width>
1943
-                 <height>23</height>
1944
-                </rect>
1945
-               </property>
1946
-               <property name="styleSheet">
1947
-                <string notr="true">#plotQD {
1868
+               <item row="2" column="3">
1869
+                <widget class="QPushButton" name="plotQD">
1870
+                 <property name="enabled">
1871
+                  <bool>false</bool>
1872
+                 </property>
1873
+                 <property name="styleSheet">
1874
+                  <string notr="true">#plotQD {
1948 1875
     background: green;
1949 1876
 }
1950 1877
 
1951 1878
 #plotQD:disabled{
1952 1879
     background: black;
1953 1880
 }</string>
1954
-               </property>
1955
-               <property name="text">
1956
-                <string>PLOT</string>
1957
-               </property>
1958
-               <property name="checkable">
1959
-                <bool>false</bool>
1960
-               </property>
1961
-              </widget>
1881
+                 </property>
1882
+                 <property name="text">
1883
+                  <string>PLOT</string>
1884
+                 </property>
1885
+                 <property name="checkable">
1886
+                  <bool>false</bool>
1887
+                 </property>
1888
+                </widget>
1889
+               </item>
1890
+               <item row="1" column="2">
1891
+                <widget class="QSpinBox" name="trimSpin">
1892
+                 <property name="minimum">
1893
+                  <number>0</number>
1894
+                 </property>
1895
+                 <property name="value">
1896
+                  <number>0</number>
1897
+                 </property>
1898
+                </widget>
1899
+               </item>
1900
+               <item row="1" column="0">
1901
+                <widget class="QLabel" name="label_38">
1902
+                 <property name="text">
1903
+                  <string>Trim</string>
1904
+                 </property>
1905
+                </widget>
1906
+               </item>
1907
+              </layout>
1962 1908
              </widget>
1963 1909
             </item>
1964 1910
             <item>
@@ -1981,7 +1927,7 @@ background: dark grey;
1981 1927
               <property name="maximumSize">
1982 1928
                <size>
1983 1929
                 <width>505</width>
1984
-                <height>16777215</height>
1930
+                <height>200</height>
1985 1931
                </size>
1986 1932
               </property>
1987 1933
               <property name="title">
@@ -1990,113 +1936,85 @@ background: dark grey;
1990 1936
               <property name="checkable">
1991 1937
                <bool>true</bool>
1992 1938
               </property>
1993
-              <widget class="QPushButton" name="gateIntegrateGO">
1994
-               <property name="geometry">
1995
-                <rect>
1996
-                 <x>350</x>
1997
-                 <y>30</y>
1998
-                 <width>99</width>
1999
-                 <height>23</height>
2000
-                </rect>
2001
-               </property>
2002
-               <property name="styleSheet">
2003
-                <string notr="true">#gateIntegrateGO {
1939
+              <layout class="QGridLayout" name="gridLayout_16">
1940
+               <item row="0" column="1">
1941
+                <widget class="QSpinBox" name="GPDspinBox">
1942
+                 <property name="minimum">
1943
+                  <number>6</number>
1944
+                 </property>
1945
+                 <property name="maximum">
1946
+                  <number>30</number>
1947
+                 </property>
1948
+                 <property name="value">
1949
+                  <number>20</number>
1950
+                 </property>
1951
+                </widget>
1952
+               </item>
1953
+               <item row="0" column="3">
1954
+                <widget class="QPushButton" name="gateIntegrateGO">
1955
+                 <property name="styleSheet">
1956
+                  <string notr="true">#gateIntegrateGO {
2004 1957
     background: green;
2005 1958
 }
2006 1959
 
2007 1960
 #gateIntegrateGO:disabled{
2008 1961
     background: black;
2009 1962
 }</string>
2010
-               </property>
2011
-               <property name="text">
2012
-                <string>GO</string>
2013
-               </property>
2014
-              </widget>
2015
-              <widget class="QSpinBox" name="GPDspinBox">
2016
-               <property name="geometry">
2017
-                <rect>
2018
-                 <x>130</x>
2019
-                 <y>28</y>
2020
-                 <width>71</width>
2021
-                 <height>23</height>
2022
-                </rect>
2023
-               </property>
2024
-               <property name="minimum">
2025
-                <number>6</number>
2026
-               </property>
2027
-               <property name="maximum">
2028
-                <number>30</number>
2029
-               </property>
2030
-               <property name="value">
2031
-                <number>20</number>
2032
-               </property>
2033
-              </widget>
2034
-              <widget class="QLabel" name="label_53">
2035
-               <property name="geometry">
2036
-                <rect>
2037
-                 <x>20</x>
2038
-                 <y>30</y>
2039
-                 <width>111</width>
2040
-                 <height>16</height>
2041
-                </rect>
2042
-               </property>
2043
-               <property name="text">
2044
-                <string>Gates per decade </string>
2045
-               </property>
2046
-              </widget>
2047
-              <widget class="QComboBox" name="QDType_2">
2048
-               <property name="geometry">
2049
-                <rect>
2050
-                 <x>230</x>
2051
-                 <y>60</y>
2052
-                 <width>101</width>
2053
-                 <height>22</height>
2054
-                </rect>
2055
-               </property>
2056
-               <item>
2057
-                <property name="text">
2058
-                 <string>Real/Imag</string>
2059
-                </property>
2060
-               </item>
2061
-               <item>
2062
-                <property name="text">
2063
-                 <string>Amp/Phase</string>
2064
-                </property>
1963
+                 </property>
1964
+                 <property name="text">
1965
+                  <string>GO</string>
1966
+                 </property>
1967
+                </widget>
2065 1968
                </item>
2066
-               <item>
2067
-                <property name="text">
2068
-                 <string>Phased</string>
2069
-                </property>
1969
+               <item row="0" column="0">
1970
+                <widget class="QLabel" name="label_53">
1971
+                 <property name="text">
1972
+                  <string>Gates per decade </string>
1973
+                 </property>
1974
+                </widget>
2070 1975
                </item>
2071
-              </widget>
2072
-              <widget class="QPushButton" name="plotGI">
2073
-               <property name="enabled">
2074
-                <bool>false</bool>
2075
-               </property>
2076
-               <property name="geometry">
2077
-                <rect>
2078
-                 <x>350</x>
2079
-                 <y>60</y>
2080
-                 <width>99</width>
2081
-                 <height>23</height>
2082
-                </rect>
2083
-               </property>
2084
-               <property name="styleSheet">
2085
-                <string notr="true">#plotGI {
1976
+               <item row="1" column="3">
1977
+                <widget class="QPushButton" name="plotGI">
1978
+                 <property name="enabled">
1979
+                  <bool>false</bool>
1980
+                 </property>
1981
+                 <property name="styleSheet">
1982
+                  <string notr="true">#plotGI {
2086 1983
     background: green;
2087 1984
 }
2088 1985
 
2089 1986
 #plotGI:disabled{
2090 1987
     background: black;
2091 1988
 }</string>
2092
-               </property>
2093
-               <property name="text">
2094
-                <string>PLOT</string>
2095
-               </property>
2096
-               <property name="checkable">
2097
-                <bool>false</bool>
2098
-               </property>
2099
-              </widget>
1989
+                 </property>
1990
+                 <property name="text">
1991
+                  <string>PLOT</string>
1992
+                 </property>
1993
+                 <property name="checkable">
1994
+                  <bool>false</bool>
1995
+                 </property>
1996
+                </widget>
1997
+               </item>
1998
+               <item row="1" column="2">
1999
+                <widget class="QComboBox" name="QDType_2">
2000
+                 <item>
2001
+                  <property name="text">
2002
+                   <string>Real/Imag</string>
2003
+                  </property>
2004
+                 </item>
2005
+                 <item>
2006
+                  <property name="text">
2007
+                   <string>Amp/Phase</string>
2008
+                  </property>
2009
+                 </item>
2010
+                 <item>
2011
+                  <property name="text">
2012
+                   <string>Phased</string>
2013
+                  </property>
2014
+                 </item>
2015
+                </widget>
2016
+               </item>
2017
+              </layout>
2100 2018
              </widget>
2101 2019
             </item>
2102 2020
            </layout>

+ 2
- 1
akvo/tressel/adapt.py View File

@@ -33,7 +33,7 @@ class AdaptiveFilter:
33 33
             exit(1)
34 34
         
35 35
         if PCA == "Yes":
36
-            print("Performing PCA calculation in noise cancellation")
36
+            #print("Performing PCA calculation in noise cancellation")
37 37
             # PCA decomposition on ref channels so signals are less related
38 38
             R, K, means = pca.pca( R )
39 39
            
@@ -50,6 +50,7 @@ class AdaptiveFilter:
50 50
             #print ("resetting filter")
51 51
         else:
52 52
             H = H0
53
+            #H = np.zeros( (len(R)*M))
53 54
 
54 55
         Rn = np.ones(len(R)*M) / mu 
55 56
         

+ 1
- 1
akvo/tressel/decay.py View File

@@ -94,7 +94,7 @@ def quadratureDetect2(X, Y, tt, x0="None"):
94 94
             method=method 
95 95
             )
96 96
         x = res_lsq.x 
97
-        print ("df", x[0], x[1], x[2], x[3])
97
+        print ("A0={} zeta={} df={} T2={}".format(x[0],x[1],x[2],x[3]))
98 98
     else:
99 99
         res_lsq = least_squares(fun, x0, args=(tt, np.concatenate((X, Y))), loss=loss, f_scale=1.0,\
100 100
             bounds=( [1., -np.pi, -5, .005] , [1000., np.pi, 5, .800] ),

+ 190
- 9
akvo/tressel/mrsurvey.py View File

@@ -298,7 +298,7 @@ class GMRDataProcessor(SNMRDataProcessor):
298 298
         pass   
299 299
  
300 300
     def TDSmartStack(self, outlierTest, MADcutoff, canvas):
301
-
301
+        #print("Line 300 in mrsurvey")
302 302
         Stack = {}
303 303
         # align for stacking and modulate
304 304
         for pulse in self.DATADICT["PULSES"]:
@@ -308,9 +308,29 @@ class GMRDataProcessor(SNMRDataProcessor):
308 308
                 istack = 0
309 309
                 for sstack in self.DATADICT["stacks"]:
310 310
                     if self.pulseType == "FID" or pulse == "Pulse 2":
311
-                        mod = (-1)**(ipm%2) * (-1)**(sstack%2)
311
+                        if floor(self.nDAQVersion) < 2:
312
+                            mod = 1
313
+                        else:
314
+                            mod = (-1.)**(ipm%2) * (-1.)**(sstack%2)
315
+                    elif self.pulseType == "T1":
316
+                        #mod = (-1.)**(sstack%2)
317
+                        #mod = (-1)**(ipm%2) * (-1)**(sstack%2)
318
+                        #mod = (-1)**(ipm%2) * (-1.**(((sstack-1)/2)%2))
319
+                        #print("mod", mod, ipm, sstack,  (-1.)**(ipm%2),  -1.0**(((sstack-1)/2)%2 ))
320
+                        #mod = (-1.)**((ipm+1)%2) * (-1.**(((sstack)/2)%2))
321
+                        #mod = (-1.)**((ipm-1)%2) * (-1.)**((sstack-1)%2)
322
+                        #mod = 1 # (-1.**(((sstack-1)/2)%2))
323
+
324
+                        # These two give great noise estimate
325
+                        #qcycler = np.array([1,-1,-1,1])
326
+                        #scycler = np.array([1,-1,1,-1])
327
+
328
+                        qcycler = np.array([ 1, 1])
329
+                        scycler = np.array([ 1, 1])
330
+                        mod = qcycler.take([ipm], mode='wrap')*scycler.take([sstack], mode='wrap')
331
+                        #mod = (-1.)**(ipm%2) * (-1.)**(sstack%2)
312 332
                     elif self.pulseType == "4PhaseT1":
313
-                        mod = (-1)**(ipm%2) * (-1)**(((sstack-1)/2)%2)
333
+                        mod = (-1.)**(ipm%2) * (-1.**(((sstack-1)/2)%2))
314 334
                     ichan = 0
315 335
                     for chan in self.DATADICT[pulse]["chan"]:
316 336
                         stack[ichan,ipm,istack,:] += mod*self.DATADICT[pulse][chan][ipm][sstack]
@@ -472,8 +492,8 @@ class GMRDataProcessor(SNMRDataProcessor):
472 492
                 #dbr = (np.real(SFFT[:,istart:iend]))
473 493
                 #db = (np.imag(SFFT[:,istart:iend]))
474 494
                 
475
-                vvmin =  min(vvmin, np.min (db))
476
-                vvmax =  max(vvmax, np.max (db))
495
+                vvmin =  min(vvmin, np.min(db) + 1e-16 )
496
+                vvmax =  max(vvmax, np.max(db) + 1e-16 )
477 497
                 im2.append(ax2.matshow( db, aspect='auto', cmap=cmocean.cm.ice, vmin=vvmin, vmax=vvmax))
478 498
                 #im1.append(ax1.matshow( dbr, aspect='auto')) #, vmin=vvmin, vmax=vvmax))
479 499
                 #im2.append(ax2.matshow( db, aspect='auto', vmin=vvmin, vmax=vvmax))
@@ -2246,6 +2266,59 @@ class GMRDataProcessor(SNMRDataProcessor):
2246 2266
             nds += ndr
2247 2267
             nps += ndr 
2248 2268
 
2269
+    def loadGMRASCIIT1( self, rawfname, istack ):
2270
+        """Based on the geoMRI instrument manufactured by VistaClara. Imports 
2271
+        a suite of raw .lvm files with the following format (on one line)
2272
+
2273
+        time(s) DC_Bus/100(V) Current+/75(A)  Curr-/75(A)  Voltage+/200(V) \  
2274
+        Ch1(V) Ch2(V) Ch3(V) Ch4(V)
2275
+
2276
+        Sampling rate is assumed at 50 kHz 
2277
+        """
2278
+        import pandas as pd 
2279
+        #################################################################################
2280
+        # figure out key data indices
2281
+        # Pulse       
2282
+        nps  = (int)((self.prePulseDelay)*self.samp)
2283
+        npul = (int)(self.pulseLength[0]*self.samp) #+ 100 
2284
+
2285
+        # phase cycling 
2286
+        # Older T1 GMR data had a curious phase cycling
2287
+        npc = 2 #(int)( self.samp / self.transFreq / 6 )
2288
+        #print("npc", npc)
2289
+
2290
+        # Data 
2291
+        nds  = nps+npul+(int)((self.deadTime)*self.samp);           # indice pulse 1 data starts 
2292
+        nd1 = (int)( (self.interpulseDelay) * self.samp) - nds      # samples in first pulse
2293
+        ndr = (int)( (self.interpulseDelay) * self.samp)            # samples in record 
2294
+
2295
+        invGain = 1./self.RxGain        
2296
+        invCGain = self.CurrentGain        
2297
+
2298
+        pulse = "Pulse 1"
2299
+        chan = self.DATADICT[pulse]["chan"] 
2300
+        rchan = self.DATADICT[pulse]["rchan"] 
2301
+            
2302
+        T = 1.5 #N_samp * self.dt 
2303
+        TIMES = np.arange(0, T, self.dt) - .0002 # small offset in GMR DAQ?
2304
+        
2305
+        self.DATADICT["Pulse 1"]["TIMES"]       = TIMES[nds:nds+nd1]
2306
+        self.DATADICT["Pulse 1"]["PULSE_TIMES"] = TIMES[nps:nps+npul]
2307
+
2308
+        # pandas is much faster than numpy for io
2309
+        #DATA = np.loadtxt(rawfname)
2310
+        DATA = pd.read_csv(rawfname, header=None, sep="\t").values
2311
+        for ipm in range(self.nPulseMoments):
2312
+            for ichan in np.append(chan,rchan):
2313
+                if ipm%2:
2314
+                    self.DATADICT["Pulse 1"][ichan][ipm][istack]     =  DATA[:, eval(ichan)+4][(nds+npc):(nds+nd1+npc)] * invGain
2315
+                    #self.DATADICT["Pulse 1"][ichan][ipm][istack]     =  DATA[:, eval(ichan)+4][nds:(nds+nd1)] * invGain
2316
+                    self.DATADICT["Pulse 1"]["CURRENT"][ipm][istack] =  DATA[:,2][nps+npc:nps+npul+npc] * invCGain
2317
+                else:
2318
+                    self.DATADICT["Pulse 1"][ichan][ipm][istack]     =  DATA[:, eval(ichan)+4][nds:(nds+nd1)] * invGain
2319
+                    self.DATADICT["Pulse 1"]["CURRENT"][ipm][istack] =  DATA[:,2][nps:nps+npul] * invCGain
2320
+            nds += ndr
2321
+            nps += ndr 
2249 2322
 
2250 2323
     def loadFIDData(self, base, procStacks, chanin, rchanin, FIDProc, canvas, deadTime, plot):
2251 2324
         '''
@@ -2297,7 +2370,9 @@ class GMRDataProcessor(SNMRDataProcessor):
2297 2370
         iistack = 0
2298 2371
         fnames = []
2299 2372
         for istack in procStacks:
2300
-            if self.nDAQVersion < 2.3:
2373
+            if self.nDAQVersion <= 1.0:
2374
+                self.loadGMRASCIIFID( base + "_" + str(istack) + ".lvm", istack )
2375
+            elif self.nDAQVersion < 2.3:
2301 2376
                 #rawfname = base + "_" + str(istack) 
2302 2377
                 self.loadGMRASCIIFID( base + "_" + str(istack), istack )
2303 2378
             else:
@@ -2313,7 +2388,6 @@ class GMRDataProcessor(SNMRDataProcessor):
2313 2388
         #info["prePulseDelay"] = self.prePulseDelay
2314 2389
         #with multiprocessing.Pool() as pool: 
2315 2390
         #    results = pool.starmap( loadGMRBinaryFID, zip(itertools.repeat(self), fnames, info ) ) # zip(np.tile(vc, (ns, 1)), np.tile(vgc, (ns,1)), itertools.repeat(sys.argv[1]), itertools.repeat(sys.argv[2]), EPS_CMR))
2316
-
2317 2391
         # Plotting
2318 2392
 
2319 2393
         if plot: 
@@ -2354,7 +2428,115 @@ class GMRDataProcessor(SNMRDataProcessor):
2354 2428
 
2355 2429
         self.enableDSP()    
2356 2430
         self.doneTrigger.emit()
2357
-    
2431
+
2432
+    def loadT1Data(self, base, procStacks, chanin, rchanin, FIDProc, canvas, deadTime, plot):
2433
+        '''
2434
+            Loads a GMR T1 dataset, reads binary and ASCII format files 
2435
+        '''
2436
+
2437
+        canvas.reAx3(True,False)
2438
+
2439
+        chan = []
2440
+        for ch in chanin:
2441
+            chan.append(str(ch)) 
2442
+        
2443
+        rchan = []
2444
+        for ch in rchanin:
2445
+            rchan.append(str(ch)) 
2446
+
2447
+        # not in any headers but this has changed, NOT the place to do this. MOVE  
2448
+        #self.prePulseDelay  = 0.01          # delay before pulse
2449
+        self.deadTime       = deadTime       # instrument dead time before measurement
2450
+        self.samp = 50000.                   # in case this is a reproc, these might have 
2451
+        self.dt   = 1./self.samp             # changed
2452
+
2453
+
2454
+        #################################################################################
2455
+        # Data structures     
2456
+        PULSES = [FIDProc]
2457
+
2458
+        self.DATADICT = {}
2459
+        self.DATADICT["nPulseMoments"] = self.nPulseMoments
2460
+        self.DATADICT["stacks"] = procStacks
2461
+        self.DATADICT["PULSES"] = PULSES
2462
+        for pulse in PULSES: 
2463
+            self.DATADICT[pulse] = {}
2464
+            self.DATADICT[pulse]["chan"] = chan        # TODO these should not be a subet of pulse! for GMR all 
2465
+            self.DATADICT[pulse]["rchan"] = rchan      #      data are consistent 
2466
+            self.DATADICT[pulse]["CURRENT"] = {} 
2467
+            for ichan in np.append(chan,rchan):
2468
+                self.DATADICT[pulse][ichan] = {}
2469
+                for ipm in range(self.nPulseMoments):
2470
+                    self.DATADICT[pulse][ichan][ipm] = {} 
2471
+                    self.DATADICT[pulse]["CURRENT"][ipm] = {} 
2472
+                    for istack in procStacks:
2473
+                        self.DATADICT[pulse][ichan][ipm][istack] = np.zeros(3)
2474
+                        self.DATADICT[pulse]["CURRENT"][ipm][istack] = np.zeros(3) 
2475
+
2476
+        ##############################################
2477
+        # Read in binary (.lvm) data
2478
+        iistack = 0
2479
+        fnames = []
2480
+        for istack in procStacks:
2481
+            if self.nDAQVersion < 2.3:
2482
+                #rawfname = base + "_" + str(istack) 
2483
+                #self.loadGMRASCIIFID( base + "_" + str(istack), istack )
2484
+                self.loadGMRASCIIT1( base + "_" + str(istack), istack )
2485
+            else:
2486
+                self.loadGMRBinaryFID( base + "_" + str(istack) + ".lvm", istack )
2487
+                #fnames.append( base + "_" + str(istack) + ".lvm" )
2488
+                
2489
+            percent = (int) (1e2*((float)((iistack*self.nPulseMoments+ipm+1))  / (len(procStacks)*self.nPulseMoments)))
2490
+            self.progressTrigger.emit(percent) 
2491
+            iistack += 1
2492
+
2493
+        # multiprocessing load data
2494
+        #info = {}
2495
+        #info["prePulseDelay"] = self.prePulseDelay
2496
+        #with multiprocessing.Pool() as pool: 
2497
+        #    results = pool.starmap( loadGMRBinaryFID, zip(itertools.repeat(self), fnames, info ) ) # zip(np.tile(vc, (ns, 1)), np.tile(vgc, (ns,1)), itertools.repeat(sys.argv[1]), itertools.repeat(sys.argv[2]), EPS_CMR))
2498
+        # Plotting
2499
+
2500
+        if plot: 
2501
+            iistack = 0
2502
+            for istack in procStacks:
2503
+                #for ipm in range(0,7,1):
2504
+                for ipm in range(self.nPulseMoments):
2505
+                    canvas.ax1.clear()
2506
+                    canvas.ax2.clear()
2507
+                    canvas.ax3.clear()
2508
+                    #canvas.fig.patch.set_facecolor('blue')
2509
+                    for ichan in chan:
2510
+                        canvas.ax1.plot(self.DATADICT["Pulse 1"]["PULSE_TIMES"], self.DATADICT["Pulse 1"]["CURRENT"][ipm][istack] , color='black')
2511
+                        canvas.ax3.plot(self.DATADICT["Pulse 1"]["TIMES"],       self.DATADICT["Pulse 1"][ichan][ipm][istack], label="Pulse 1 FID data ch. "+str(ichan)) #, color='blue')
2512
+
2513
+                    for ichan in rchan:
2514
+                        canvas.ax2.plot(self.DATADICT["Pulse 1"]["TIMES"], self.DATADICT["Pulse 1"][ichan][ipm][istack], label="Pulse 1 FID ref ch. "+str(ichan)) #, color='blue')
2515
+
2516
+                    canvas.ax3.legend(prop={'size':6})
2517
+                    canvas.ax2.legend(prop={'size':6})
2518
+                    
2519
+                    canvas.ax1.set_title("stack "+str(istack)+" pulse index " + str(ipm), fontsize=8)
2520
+                    canvas.ax1.set_xlabel("time [s]", fontsize=8)
2521
+                    canvas.ax1.set_ylabel("Current [A]", fontsize=8) 
2522
+                    canvas.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y') 
2523
+                    
2524
+                    canvas.ax2.set_ylabel("RAW signal [V]", fontsize=8)
2525
+                    canvas.ax2.tick_params(axis='both', which='major', labelsize=8)
2526
+                    canvas.ax2.tick_params(axis='both', which='minor', labelsize=6)
2527
+                    canvas.ax2.set_xlabel("time [s]", fontsize=8)
2528
+                    canvas.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y') 
2529
+                    canvas.ax3.ticklabel_format(style='sci', scilimits=(0,0), axis='y') 
2530
+                    canvas.draw()
2531
+                #canvas.draw()
2532
+
2533
+                percent = (int) (1e2*((float)((iistack*self.nPulseMoments+ipm+1))  / (len(procStacks)*self.nPulseMoments)))
2534
+                self.progressTrigger.emit(percent) 
2535
+                iistack += 1
2536
+
2537
+        self.enableDSP()    
2538
+        self.doneTrigger.emit()   
2539
+ 
2358 2540
     def load4PhaseT1Data(self, base, procStacks, chan, rchan, FIDProc, canvas, deadTime, plot): 
2359 2541
 
2360 2542
         """
@@ -2527,7 +2709,6 @@ class GMRDataProcessor(SNMRDataProcessor):
2527 2709
                 # update GUI of where we are
2528 2710
                 percent = (int) (1e2*((float)((iistack*self.nPulseMoments+ipm+1))  / (len(procStacks)*self.nPulseMoments)))
2529 2711
                 self.progressTrigger.emit(percent)  
2530
-
2531 2712
             iistack += 1
2532 2713
         
2533 2714
         self.enableDSP()    

+ 1
- 1
setup.py View File

@@ -21,7 +21,7 @@ with open("README.md", "r") as fh:
21 21
     long_description = fh.read()
22 22
 
23 23
 setup(name='Akvo',
24
-      version='1.2.2',
24
+      version='1.2.3',
25 25
       description='Surface nuclear magnetic resonance workbench',
26 26
       long_description=long_description,
27 27
       long_description_content_type='text/markdown',

Loading…
Cancel
Save