Browse Source

rework GUI for better performance

tags/1.6.1
Trevor Irons 5 years ago
parent
commit
0a7123fb1a
7 changed files with 2508 additions and 2635 deletions
  1. 12
    13
      akvo/gui/akvoGUI.py
  2. 2187
    2574
      akvo/gui/main.ui
  3. 2
    2
      akvo/gui/mainui.py
  4. 11
    1
      akvo/tressel/adapt.py
  5. 16
    7
      akvo/tressel/decay.py
  6. 279
    37
      akvo/tressel/mrsurvey.py
  7. 1
    1
      setup.py

+ 12
- 13
akvo/gui/akvoGUI.py View File

@@ -179,7 +179,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
179 179
         self.ui.barProgress.hide();        
180 180
 
181 181
         self.ui.mplwidget_navigator.setCanvas(self.ui.mplwidget)
182
-        self.ui.mplwidget_navigator_2.setCanvas(self.ui.mplwidget_2)
182
+        #self.ui.mplwidget_navigator_2.setCanvas(self.ui.mplwidget)
183 183
 
184 184
         ##########################################################################
185 185
         # Loop Table 
@@ -845,7 +845,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
845 845
 #        QtCore.QObject.connect(self.RAWDataProc, QtCore.SIGNAL("enableDSP()"), self.enableDSP)
846 846
 #        QtCore.QObject.connect(self.RAWDataProc, QtCore.SIGNAL("doneStatus()"), self.doneStatus)
847 847
 
848
-        self.ui.ProcessedBox.setEnabled(True)
848
+        #self.ui.ProcessedBox.setEnabled(True)
849 849
         self.ui.lcdNumberFID1Length.setEnabled(1)
850 850
         self.ui.lcdNumberFID2Length.setEnabled(1)
851 851
         self.ui.lcdNumberResampFreq.setEnabled(1)
@@ -970,9 +970,9 @@ class ApplicationWindow(QtWidgets.QMainWindow):
970 970
 
971 971
     def calcQ(self):
972 972
         if "Calc Q" not in self.YamlNode.Processing.keys():
973
-            print("In CalcQ", yaml.dump(self.YamlNode.Processing)  )
973
+            #print("In CalcQ", yaml.dump(self.YamlNode.Processing)  )
974 974
             self.YamlNode.Processing["Calc Q"] = True
975
-            print( yaml.dump(self.YamlNode.Processing)  )
975
+            #print( yaml.dump(self.YamlNode.Processing)  )
976 976
             self.Log()
977 977
         else:
978 978
             err_msg = "Q values have already been calculated"
@@ -983,7 +983,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
983 983
         self.lock("pulse moment calculation")
984 984
         thread.start_new_thread(self.RAWDataProc.effectivePulseMoment, \
985 985
                 (self.ui.CentralVSpinBox.value(), \
986
-                self.ui.mplwidget_2))
986
+                self.ui.mplwidget))
987 987
 
988 988
     def FDSmartStack(self):
989 989
 
@@ -1002,7 +1002,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
1002 1002
         thread.start_new_thread(self.RAWDataProc.TDSmartStack, \
1003 1003
                 (str(self.ui.outlierTestCB.currentText()), \
1004 1004
                 self.ui.MADCutoff.value(),
1005
-                self.ui.mplwidget_2))
1005
+                self.ui.mplwidget))
1006 1006
 
1007 1007
     def adaptFilter(self):
1008 1008
 
@@ -1016,9 +1016,8 @@ class ApplicationWindow(QtWidgets.QMainWindow):
1016 1016
             self.Log()
1017 1017
         else:
1018 1018
             err_msg = "TD noise cancellation has already been applied!"
1019
-            reply =QtWidgets.QMessageBox.critical(self, 'Error', 
1020
-                err_msg) 
1021
-            return 
1019
+            reply =QtWidgets.QMessageBox.critical(self, 'Error', err_msg) 
1020
+            #return 
1022 1021
         
1023 1022
         self.lock("TD noise cancellation filter")
1024 1023
         thread.start_new_thread(self.RAWDataProc.adaptiveFilter, \
@@ -1104,7 +1103,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
1104 1103
 
1105 1104
         self.lock("quadrature detection")
1106 1105
         thread.start_new_thread(self.RAWDataProc.quadDet, \
1107
-                (self.ui.trimSpin.value(), int(self.ui.QDType.currentIndex()), self.ui.mplwidget_2))
1106
+                (self.ui.trimSpin.value(), int(self.ui.QDType.currentIndex()), self.ui.mplwidget))
1108 1107
 
1109 1108
         self.ui.plotQD.setEnabled(True)
1110 1109
     
@@ -1112,7 +1111,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
1112 1111
         self.lock("plot QD")
1113 1112
 
1114 1113
         thread.start_new_thread(self.RAWDataProc.plotQuadDet, \
1115
-                (self.ui.trimSpin.value(), int(self.ui.QDType.currentIndex()), self.ui.mplwidget_2))
1114
+                (self.ui.trimSpin.value(), int(self.ui.QDType.currentIndex()), self.ui.mplwidget))
1116 1115
 
1117 1116
 
1118 1117
     def gateIntegrate(self):
@@ -1124,7 +1123,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
1124 1123
  
1125 1124
         self.lock("gate integration")
1126 1125
         thread.start_new_thread(self.RAWDataProc.gateIntegrate, \
1127
-                (self.ui.GPDspinBox.value(), self.ui.trimSpin.value(), self.ui.mplwidget_2))
1126
+                (self.ui.GPDspinBox.value(), self.ui.trimSpin.value(), self.ui.mplwidget))
1128 1127
         
1129 1128
         self.ui.actionExport_Preprocessed_Dataset.setEnabled(True)
1130 1129
         self.ui.plotGI.setEnabled(True)
@@ -1133,7 +1132,7 @@ class ApplicationWindow(QtWidgets.QMainWindow):
1133 1132
         self.lock("plot gate integrate")
1134 1133
         thread.start_new_thread(self.RAWDataProc.plotGateIntegrate, \
1135 1134
                 (self.ui.GPDspinBox.value(), self.ui.trimSpin.value(), \
1136
-                self.ui.QDType_2.currentIndex(),  self.ui.mplwidget_2))
1135
+                self.ui.QDType_2.currentIndex(),  self.ui.mplwidget))
1137 1136
  
1138 1137
     def designFilter(self):
1139 1138
         [bord, fe] = self.RAWDataProc.designFilter( \

+ 2187
- 2574
akvo/gui/main.ui
File diff suppressed because it is too large
View File


+ 2
- 2
akvo/gui/mainui.py View File

@@ -1025,8 +1025,8 @@ class Ui_MainWindow(object):
1025 1025
 
1026 1026
         self.retranslateUi(MainWindow)
1027 1027
         self.tabWidget.setCurrentIndex(0)
1028
-        self.actionClose.activated.connect(MainWindow.close)
1029
-        self.actionAboutBrewCentral.activated.connect(MainWindow.show)
1028
+        #self.actionClose.activated.connect(MainWindow.close)
1029
+        #self.actionAboutBrewCentral.activated.connect(MainWindow.show)
1030 1030
         QtCore.QMetaObject.connectSlotsByName(MainWindow)
1031 1031
 
1032 1032
     def retranslateUi(self, MainWindow):

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

@@ -33,14 +33,24 @@ class AdaptiveFilter:
33 33
             exit(1)
34 34
         
35 35
         if PCA == "Yes":
36
+            print("Performing PCA calculation in noise cancellation")
36 37
             # PCA decomposition on ref channels so signals are less related
37 38
             R, K, means = pca.pca( R )
38
-        
39
+           
40
+            # test for in loop reference  
41
+            #print("Cull nearly zero terms?", np.shape(x), np.shape(R))     
42
+            #R = R[0:3,:] 
43
+            #R = R[2:4,:] 
44
+            #print("    removed zero terms?", np.shape(x), np.shape(R))     
45
+            #H0 = H0[0:3*np.shape(x)[0]]
46
+            #H0 = H0[0:2*np.shape(x)[0]]
47
+
39 48
         if all(H0) == 0:
40 49
             H = np.zeros( (len(R)*M))
41 50
             #print ("resetting filter")
42 51
         else:
43 52
             H = H0
53
+
44 54
         Rn = np.ones(len(R)*M) / mu 
45 55
         
46 56
         r_ = np.zeros( (len(R), M) ) 

+ 16
- 7
akvo/tressel/decay.py View File

@@ -291,15 +291,24 @@ def quadratureDetect2(X, Y, tt, x0="None"):
291 291
         Y = imaginary component of NMR signal 
292 292
         tt = time 
293 293
     """
294
-    print("Pure Python Quad Det")
295
-    # df 
294
+    print("Pure Python Quad Det", "TODO look at loss functions and method")
295
+    # Loss functions, linear, soft_l1, huber, cauchy, arctan 
296
+    # df
297
+    loss = 'cauchy'  #  'soft_l1'
298
+    method = 'trf'   # trf, dogbox, lm 
296 299
     if x0=="None":
297
-        x0 = np.array( [1., 0., 0., .2] )
298
-        res_lsq = least_squares(fun, x0, args=(tt, np.concatenate((X, Y))), loss='cauchy', f_scale=1.0,\
299
-            bounds=( [1., -np.pi, -5, .005] , [1000., np.pi, 5, .800] ))
300
+        x0 = np.array( [1., 0., 0., .2] ) # A0, zeta, df, T2 
301
+        res_lsq = least_squares(fun, x0, args=(tt, np.concatenate((X, Y))), loss=loss, f_scale=1.0,\
302
+            bounds=( [1., -np.pi, -5, .005] , [1000., np.pi, 5, .800] ),
303
+            method=method 
304
+            )
305
+        x = res_lsq.x 
306
+        print ("df", x[0], x[1], x[2], x[3])
300 307
     else:
301
-        res_lsq = least_squares(fun, x0, args=(tt, np.concatenate((X, Y))), loss='cauchy', f_scale=1.0,\
302
-            bounds=( [1., -np.pi, -5, .005] , [1000., np.pi, 5, .800] ))
308
+        res_lsq = least_squares(fun, x0, args=(tt, np.concatenate((X, Y))), loss=loss, f_scale=1.0,\
309
+            bounds=( [1., -np.pi, -5, .005] , [1000., np.pi, 5, .800] ),
310
+            method=method 
311
+            )
303 312
 
304 313
         #bounds=( [0., 0, -20, .0] , [1., np.pi, 20, .6] ))
305 314
 

+ 279
- 37
akvo/tressel/mrsurvey.py View File

@@ -337,7 +337,7 @@ class GMRDataProcessor(SNMRDataProcessor):
337 337
                 y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
338 338
                 ax1.yaxis.set_major_formatter(y_formatter)
339 339
 
340
-                ax1.plot( 1e3*self.DATADICT[pulse]["TIMES"], np.average(  SimpleStack[pulse][chan], 0 ), color='darkblue' )
340
+                ax1.plot( 1e3*self.DATADICT[pulse]["TIMES"], np.average(  SimpleStack[pulse][chan], 0 )) #, color='darkblue' )
341 341
                 ax1.set_title("Ch." + str(chan) + ": avg FID", fontsize=8)
342 342
                 ax1.set_xlabel(r"time (ms)", fontsize=8)
343 343
 
@@ -408,7 +408,7 @@ class GMRDataProcessor(SNMRDataProcessor):
408 408
                                            (float)(self.DATADICT["nPulseMoments"] * len(self.DATADICT[pulse]["chan"])))
409 409
                         self.progressTrigger.emit(percent)
410 410
 
411
-                    ax1.plot( 1e3*self.DATADICT[pulse]["TIMES"], np.average(  madstack[ichan], 0  ) , color='darkred')
411
+                    ax1.plot( 1e3*self.DATADICT[pulse]["TIMES"], np.average(  madstack[ichan], 0  ))# , color='darkred')
412 412
                         
413 413
                     MADStack[pulse][chan] = madstack[ichan]
414 414
                     VarStack[pulse][chan] = varstack[ichan]
@@ -427,6 +427,7 @@ class GMRDataProcessor(SNMRDataProcessor):
427 427
 #         cbar_ax = canvas.fig.add_axes([0.85, 0.1, 0.015, 0.355])
428 428
 #         cbar_ax.ticklabel_format(style='sci', scilimits=(0,0), axis='y')                 
429 429
         im2 = []
430
+        im1 = []
430 431
         for pulse in self.DATADICT["PULSES"]:
431 432
             ichan = 0
432 433
             axes = canvas.fig.axes
@@ -447,8 +448,8 @@ class GMRDataProcessor(SNMRDataProcessor):
447 448
                 df = nu[1] - nu[0]
448 449
                 of = 0
449 450
 
450
-                istart = int((self.transFreq-150.)/df)
451
-                iend = int((self.transFreq+150.)/df)
451
+                istart = int((self.transFreq-50.)/df)
452
+                iend = int((self.transFreq+50.)/df)
452 453
                 of = nu[istart]
453 454
                 
454 455
                 def freqlabel(xxx, pos):
@@ -466,10 +467,15 @@ class GMRDataProcessor(SNMRDataProcessor):
466 467
                 # convert to dB and add colorbars
467 468
                 #db = 20.*np.log10(np.abs(SFFT[:,istart:iend]))
468 469
                 db = (np.abs(SFFT[:,istart:iend]))
470
+                #db = (np.real(SFFT[:,istart:iend]))
471
+                #dbr = (np.real(SFFT[:,istart:iend]))
472
+                #db = (np.imag(SFFT[:,istart:iend]))
469 473
                 
470 474
                 vvmin =  min(vvmin, np.min (db))
471 475
                 vvmax =  max(vvmax, np.max (db))
472 476
                 im2.append(ax2.matshow( db, aspect='auto', cmap=cmocean.cm.ice, vmin=vvmin, vmax=vvmax))
477
+                #im1.append(ax1.matshow( dbr, aspect='auto')) #, vmin=vvmin, vmax=vvmax))
478
+                #im2.append(ax2.matshow( db, aspect='auto', vmin=vvmin, vmax=vvmax))
473 479
                 #im2 = ax2.matshow( db, aspect='auto', cmap=cmocean.cm.ice, vmin=vvmin, vmax=vvmax)
474 480
                 if ichan == 0:
475 481
                     ax2.set_ylabel(r"$q$ (A $\cdot$ s)", fontsize=8)
@@ -510,6 +516,227 @@ class GMRDataProcessor(SNMRDataProcessor):
510 516
         canvas.draw()
511 517
         self.doneTrigger.emit() 
512 518
 
519
+    def FDSmartStack(self, outlierTest, MADcutoff, canvas):
520
+        
521
+        print("FFT stuff")
522
+        self.dataCubeFFT()       
523
+
524
+        Stack = {}
525
+        # align phase cycling for stacking and modulate
526
+        for pulse in self.DATADICT["PULSES"]:
527
+            stack = np.zeros(( len(self.DATADICT[pulse]["chan"]), \
528
+                               self.DATADICT["nPulseMoments"],\
529
+                               len(self.DATADICT["stacks"]),\
530
+                               len(self.DATADICT[pulse][self.DATADICT[pulse]["chan"][0] ]["FFT"]["nu"])//2 + 1),\
531
+                               dtype=np.complex )
532
+            for ipm in range(self.DATADICT["nPulseMoments"]):
533
+                istack = 0
534
+                for sstack in self.DATADICT["stacks"]:
535
+                    if self.pulseType == "FID" or pulse == "Pulse 2":
536
+                        mod = (-1)**(ipm%2) * (-1)**(sstack%2)
537
+                    elif self.pulseType == "4PhaseT1":
538
+                        mod = (-1)**(ipm%2) * (-1)**(((sstack-1)/2)%2)
539
+                    ichan = 0
540
+                    for chan in self.DATADICT[pulse]["chan"]:
541
+                        #stack[ichan,ipm,istack,:] += mod*self.DATADICT[pulse][chan][ipm][sstack]
542
+                        stack[ichan,ipm,istack,:] += mod*self.DATADICT[pulse][chan]["FFT"][sstack][ipm,:] 
543
+                        ichan += 1
544
+                    istack += 1
545
+            Stack[pulse] = stack
546
+
547
+        ######################################### 
548
+        # simple stack and plot of simple stack #
549
+        ########################################https://faculty.apps.utah.edu/#
550
+        canvas.reAxH2(np.shape(stack)[0], False, False)
551
+        axes = canvas.fig.axes
552
+        SimpleStack = {}
553
+        VarStack = {}
554
+        for pulse in self.DATADICT["PULSES"]:
555
+            SimpleStack[pulse] = {}
556
+            VarStack[pulse] = {}
557
+            ichan = 0
558
+            for chan in self.DATADICT[pulse]["chan"]: 
559
+                SimpleStack[pulse][chan] = 1e9*np.average( Stack[pulse][ichan], 1 ) 
560
+                VarStack[pulse][chan] = 1e9*np.std( Stack[pulse][ichan], 1 ) 
561
+                ax1 = axes[ 2*ichan ]
562
+                #ax1.get_yaxis().get_major_formatter().set_useOffset(False)
563
+
564
+                y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
565
+                ax1.yaxis.set_major_formatter(y_formatter)
566
+
567
+                #ax1.plot( 1e3*self.DATADICT[pulse][chan]["FFT"]["nu"][0:len(SimpleStack[pulse][chan])], np.average(SimpleStack[pulse][chan], 0 )) #, color='darkblue' )
568
+                #ax1.pcolor( np.real(SimpleStack[pulse][chan]) ) #, color='darkblue' )
569
+                ax1.matshow( np.real(SimpleStack[pulse][chan]), aspect='auto') #, color='darkblue' )
570
+                ax1.set_title("Ch." + str(chan) + ": avg FID", fontsize=8)
571
+                ax1.set_xlabel(r"time (ms)", fontsize=8)
572
+
573
+                if ichan == 0:
574
+                    ax1.set_ylabel(r"signal [nV]", fontsize=8)
575
+                else:
576
+                    plt.setp(ax1.get_yticklabels(), visible=False)
577
+                    plt.setp(ax1.get_yaxis().get_offset_text(), visible=False) 
578
+                ichan += 1
579
+
580
+        #########################
581
+        # Oulier rejectig stack #
582
+        #########################
583
+        if outlierTest == "MAD":
584
+            MADStack = {}
585
+            VarStack = {}
586
+            #1.4826 is assumption of gaussian noise 
587
+            madstack = np.zeros(( len(self.DATADICT[pulse]["chan"]),\
588
+                                  self.DATADICT["nPulseMoments"],\
589
+                                  len(self.DATADICT[pulse][self.DATADICT[pulse]["chan"][0] ]["FFT"]["nu"])//2 + 1))
590
+            varstack = np.zeros(( len(self.DATADICT[pulse]["chan"]),\
591
+                                  self.DATADICT["nPulseMoments"],\
592
+                                  len(self.DATADICT[pulse][self.DATADICT[pulse]["chan"][0] ]["FFT"]["nu"])//2 + 1))
593
+            for pulse in self.DATADICT["PULSES"]:
594
+                MADStack[pulse] = {}
595
+                VarStack[pulse] = {}
596
+                ichan = 0
597
+                for chan in self.DATADICT[pulse]["chan"]:
598
+                    ax1 = axes[ 2*ichan  ]
599
+                    for ipm in range(self.DATADICT["nPulseMoments"]):
600
+#                         # brutal loop over time, can this be vectorized? 
601
+#                         for it in range(len(self.DATADICT[pulse]["TIMES"])): 
602
+#                             x = 1e9 *Stack[pulse][ichan,ipm,:,it]
603
+#                             MAD = 1.4826 * np.median( np.abs(x-np.median(x)) )
604
+#                             good = 0
605
+#                             for istack in self.DATADICT["stacks"]:
606
+#                                 if (np.abs(x[istack-1]-np.median(x))) / MAD < 2:
607
+#                                     good += 1
608
+#                                     madstack[ ichan, ipm, it ] += x[istack-1]
609
+#                                 else:
610
+#                                     pass
611
+#                             madstack[ichan, ipm, it] /= good
612
+#                         percent = int(1e2* (float)(ipm) / (float)(self.DATADICT["nPulseMoments"]) )
613
+#                         self.progressTrigger.emit(percent)
614
+
615
+                        # Vectorized version of above...much, much faster 
616
+                        x = 1e9*copy.deepcopy(Stack[pulse][ichan][ipm,:,:])      # stack and time indices
617
+                        tile_med =  np.tile( np.median(x, axis=0), (np.shape(x)[0],1)) 
618
+                        MAD = MADcutoff * np.median(np.abs(x - tile_med), axis=0)
619
+                        tile_MAD =  np.tile( MAD, (np.shape(x)[0],1)) 
620
+                        good = np.abs(x-tile_med)/tile_MAD < 2. # 1.4826 # 2
621
+
622
+                        madstack[ichan][ipm] = copy.deepcopy( np.ma.masked_array(x, good != True).mean(axis=0) )
623
+                        varstack[ichan][ipm] = copy.deepcopy( np.ma.masked_array(x, good != True).std(axis=0) )
624
+                        
625
+                        # reporting
626
+                        percent = int(1e2* (float)((ipm)+ichan*self.DATADICT["nPulseMoments"]) / 
627
+                                           (float)(self.DATADICT["nPulseMoments"] * len(self.DATADICT[pulse]["chan"])))
628
+                        self.progressTrigger.emit(percent)
629
+
630
+                    ax2 = axes[2*ichan+1] # TODO fix hard coded number
631
+                    #ax1.plot( 1e3*self.DATADICT[pulse]["TIMES"], np.average(  madstack[ichan], 0  ))# , color='darkred')
632
+                    MADStack[pulse][chan] = madstack[ichan]
633
+                    VarStack[pulse][chan] = varstack[ichan]
634
+                    ax2.matshow( np.real(MADStack[pulse][chan]), aspect='auto') #, color='darkblue' )
635
+                    ichan += 1
636
+ 
637
+            self.DATADICT["stack"] = MADStack 
638
+
639
+        else:
640
+            self.DATADICT["stack"] = SimpleStack 
641
+ 
642
+#         #########################################
643
+#         # Plot Fourier Transform representation #
644
+#         #########################################
645
+# 
646
+# #         canvas.fig.subplots_adjust(right=0.8)
647
+# #         cbar_ax = canvas.fig.add_axes([0.85, 0.1, 0.015, 0.355])
648
+# #         cbar_ax.ticklabel_format(style='sci', scilimits=(0,0), axis='y')                 
649
+#         im2 = []
650
+#         im1 = []
651
+#         for pulse in self.DATADICT["PULSES"]:
652
+#             ichan = 0
653
+#             axes = canvas.fig.axes
654
+#             vvmin = 1e10 
655
+#             vvmax = 0
656
+#             for chan in self.DATADICT[pulse]["chan"]: 
657
+#                 ax1 = axes[2*ichan  ]
658
+#                 ax2 = axes[2*ichan+1] # TODO fix hard coded number
659
+#                 if outlierTest == "MAD":
660
+#                     X = np.fft.rfft( MADStack[pulse][chan][0,:] )
661
+#                     nu = np.fft.fftfreq(len( MADStack[pulse][chan][0,:]), d=self.dt)
662
+#                 else:
663
+#                     X = np.fft.rfft( SimpleStack[pulse][chan][0,:] )
664
+#                     nu = np.fft.fftfreq(len( SimpleStack[pulse][chan][0,:]), d=self.dt)
665
+#                 
666
+#                 nu = nu[0:len(X)]
667
+#                 nu[-1] = np.abs(nu[-1])
668
+#                 df = nu[1] - nu[0]
669
+#                 of = 0
670
+# 
671
+#                 istart = int((self.transFreq-50.)/df)
672
+#                 iend = int((self.transFreq+50.)/df)
673
+#                 of = nu[istart]
674
+#                 
675
+#                 def freqlabel(xxx, pos):
676
+#                     return  '%1.0f' %(of + xxx*df)
677
+#                 formatter = FuncFormatter(freqlabel)
678
+#         
679
+#                 SFFT = np.zeros( (self.DATADICT["nPulseMoments"], len(X)), dtype=np.complex64 )
680
+#                 SFFT[0,:] = X
681
+#                 for ipm in range(1, self.DATADICT["nPulseMoments"]):
682
+#                     if outlierTest == "MAD":
683
+#                         SFFT[ipm,:] = np.fft.rfft( MADStack[pulse][chan][ipm,:] )
684
+#                     else:
685
+#                         SFFT[ipm,:] = np.fft.rfft( SimpleStack[pulse][chan][ipm,:] )
686
+#                 
687
+#                 # convert to dB and add colorbars
688
+#                 #db = 20.*np.log10(np.abs(SFFT[:,istart:iend]))
689
+#                 db = (np.abs(SFFT[:,istart:iend]))
690
+#                 #db = (np.real(SFFT[:,istart:iend]))
691
+#                 #dbr = (np.real(SFFT[:,istart:iend]))
692
+#                 #db = (np.imag(SFFT[:,istart:iend]))
693
+#                 
694
+#                 vvmin =  min(vvmin, np.min (db))
695
+#                 vvmax =  max(vvmax, np.max (db))
696
+#                 im2.append(ax2.matshow( db, aspect='auto', cmap=cmocean.cm.ice, vmin=vvmin, vmax=vvmax))
697
+#                 #im1.append(ax1.matshow( dbr, aspect='auto')) #, vmin=vvmin, vmax=vvmax))
698
+#                 #im2.append(ax2.matshow( db, aspect='auto', vmin=vvmin, vmax=vvmax))
699
+#                 #im2 = ax2.matshow( db, aspect='auto', cmap=cmocean.cm.ice, vmin=vvmin, vmax=vvmax)
700
+#                 if ichan == 0:
701
+#                     ax2.set_ylabel(r"$q$ (A $\cdot$ s)", fontsize=8)
702
+#                 else:
703
+#                     #ax2.yaxis.set_ticklabels([])
704
+#                     plt.setp(ax2.get_yticklabels(), visible=False)
705
+# 
706
+#                 ax2.xaxis.set_major_formatter(formatter)
707
+#                 ax2.xaxis.set_ticks_position('bottom')
708
+#                 ax2.xaxis.set_major_locator(MaxNLocator(3))
709
+#                 
710
+#                 y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
711
+#                 ax2.yaxis.set_major_formatter(y_formatter)
712
+# 
713
+# 
714
+#                 #if chan == self.DATADICT[pulse]["chan"][-1]:
715
+#                     #cb2 = canvas.fig.colorbar(im2, cax=cbar_ax, format='%1.0e')
716
+# 
717
+#                 #cb2 = canvas.fig.colorbar(im2[0], ax=ax2, format='%1.0e', orientation='horizontal')
718
+#                 #cb2 = canvas.fig.colorbar(im2, ax=ax2, format='%1.0e', orientation='horizontal')
719
+#                 #cb2.ax.tick_params(axis='both', which='major', labelsize=8)
720
+#                 #cb2.set_label("signal (dB)", fontsize=8)
721
+#  
722
+#                 ichan += 1   
723
+# 
724
+# 
725
+#         canvas.fig.subplots_adjust(hspace=.1, wspace=.05, left=.075, right=.95 )#left=None, bottom=None, right=None, top=None, wspace=None, hspace=None) 
726
+#         
727
+#         #cb1 = canvas.fig.colorbar(im, ax=axes[0::2], format='%1.0e', orientation='horizontal', shrink=.35, aspect=30)
728
+#         #cb1.ax.tick_params(axis='both', which='major', labelsize=8)
729
+#         #cb1.set_label("$\mathcal{V}_N$ (nV)", fontsize=8)
730
+# 
731
+#         cb2 = canvas.fig.colorbar(im2[-1], ax=axes[1::2], format='%1.0e', orientation='horizontal', shrink=.35, aspect=30)
732
+#         cb2.ax.tick_params(axis='both', which='major', labelsize=8)
733
+#         cb2.set_label("$\mathcal{V}_N$ (nV)", fontsize=8)
734
+
735
+        #canvas.fig.tight_layout() 
736
+        canvas.draw()
737
+        self.doneTrigger.emit() 
738
+
739
+
513 740
     def sumData(self, canvas, fred):
514 741
         chans = copy.deepcopy(self.DATADICT[self.DATADICT["PULSES"][0]]["chan"]) #= np.array( ( self.DATADICT[pulse]["chan"][0], ) )
515 742
         nchan = len(chans)
@@ -522,24 +749,29 @@ class GMRDataProcessor(SNMRDataProcessor):
522 749
                     for ipm in range(self.DATADICT["nPulseMoments"]):
523 750
                         self.DATADICT[pulse][chsum][ipm] = {} 
524 751
                         for istack in self.DATADICT["stacks"]:
525
-                            self.DATADICT[pulse][chsum][ipm][istack] = self.DATADICT[pulse][chans[ich]][ipm][istack] + self.DATADICT[pulse][ch][ipm][istack] 
526
-                    self.DATADICT[pulse]["chan"].append(chsum)
752
+                            self.DATADICT[pulse][chsum][ipm][istack] = self.DATADICT[pulse][chans[ich]][ipm][istack] - self.DATADICT[pulse][ch][ipm][istack] 
753
+                    if chsum == "1+2":
754
+                        #self.DATADICT[pulse]["rchan"].pop()
755
+                        #self.DATADICT[pulse]["rchan"].pop()
756
+                        self.DATADICT[pulse]["chan"].append(chsum)
527 757
 
528 758
         # Sum all channels 
529
-        chsum = ""
530
-        for ch in chans:
531
-            chsum += ch + "+" 
532
-        chsum = chsum[0:-1] # remove last "+"
759
+        sumall = False
760
+        if sumall:
761
+            chsum = ""
762
+            for ch in chans:
763
+                chsum += ch + "+" 
764
+            chsum = chsum[0:-1] # remove last "+"
533 765
          
534
-        for pulse in self.DATADICT["PULSES"]:
535
-            self.DATADICT[pulse][chsum] = {} 
536
-            for ipm in range(self.DATADICT["nPulseMoments"]):
537
-                self.DATADICT[pulse][chsum][ipm] = {} 
538
-                for istack in self.DATADICT["stacks"]:
539
-                    self.DATADICT[pulse][chsum][ipm][istack] = copy.deepcopy(self.DATADICT[pulse][chans[0]][ipm][istack])
540
-                    for ch in chans[1:]:
541
-                        self.DATADICT[pulse][chsum][ipm][istack] += self.DATADICT[pulse][ch][ipm][istack] 
542
-        self.DATADICT[pulse]["chan"].append(chsum)
766
+            for pulse in self.DATADICT["PULSES"]:
767
+                self.DATADICT[pulse][chsum] = {} 
768
+                for ipm in range(self.DATADICT["nPulseMoments"]):
769
+                    self.DATADICT[pulse][chsum][ipm] = {} 
770
+                    for istack in self.DATADICT["stacks"]:
771
+                        self.DATADICT[pulse][chsum][ipm][istack] = copy.deepcopy(self.DATADICT[pulse][chans[0]][ipm][istack])
772
+                        for ch in chans[1:]:
773
+                            self.DATADICT[pulse][chsum][ipm][istack] += self.DATADICT[pulse][ch][ipm][istack] 
774
+            self.DATADICT[pulse]["chan"].append(chsum)
543 775
 
544 776
 #         if nchan > 2:
545 777
 #             for ch in chans:
@@ -611,9 +843,10 @@ class GMRDataProcessor(SNMRDataProcessor):
611 843
                     # Rotated amplitude
612 844
                     #if ipm != 0:
613 845
                     #[success, E0, df, phi, T2] = decay.quadratureDetect2( ht.real, ht.imag, self.DATADICT[pulse]["TIMES"], (E0,phi,df,T2))
614
-                    [success, E0, df, phi, T2] = decay.quadratureDetect( ht.real, ht.imag, self.DATADICT[pulse]["TIMES"] )
846
+                    #[success, E0, df, phi, T2] = decay.quadratureDetect( ht.real, ht.imag, self.DATADICT[pulse]["TIMES"] )
615 847
                     #else:
616
-                    #    [success, E0, df, phi, T2] = decay.quadratureDetect2( ht.real, ht.imag, self.DATADICT[pulse]["TIMES"])
848
+                    [success, E0, df, phi, T2] = decay.quadratureDetect2( ht.real, ht.imag, self.DATADICT[pulse]["TIMES"])
849
+                    #[success, E0, df, phi, T2] = decay.quadratureDetect2( ht.real, ht.imag, self.DATADICT[pulse]["TIMES"], (E0,phi,df,T2))
617 850
                     #[success, E0, df, phi, T2] = decay.quadratureDetect( ht.real, ht.imag, self.DATADICT[pulse]["TIMES"] )
618 851
                     #print("success", success, "E0", E0, "phi", phi, "df", df, "T2", T2)
619 852
                     
@@ -649,7 +882,7 @@ class GMRDataProcessor(SNMRDataProcessor):
649 882
         ###############
650 883
         # Plot on GUI #      
651 884
         ############### 
652
-        dcmap = cmocean.cm.balance_r #"RdBu" #YlGn" # "coolwarm_r"  # diverging 
885
+        dcmap = cmocean.cm.curl_r  #"seismic_r" #cmocean.cm.balance_r #"RdBu" #YlGn" # "coolwarm_r"  # diverging 
653 886
         canvas.reAxH2(  len(self.DATADICT[ self.DATADICT["PULSES"][0] ]["chan"] ), False, False)
654 887
         for pulse in self.DATADICT["PULSES"]:
655 888
             ichan = 0
@@ -679,7 +912,7 @@ class GMRDataProcessor(SNMRDataProcessor):
679 912
                 if phase == 2: # CA NR
680 913
                     im1 = ax1.pcolormesh( time_sp, QQ, self.DATADICT["CA"][pulse][chan], cmap=dcmap, rasterized=True,\
681 914
                          vmin=-self.DATADICT["CAmax"][pulse] , vmax=self.DATADICT["CAmax"][pulse] )
682
-                    im2 = ax2.pcolormesh( time_sp, QQ, self.DATADICT["NR"][pulse][chan], cmap=dcmap, rasterized=True,
915
+                    im2 = ax2.pcolormesh( time_sp, QQ, self.DATADICT["NR"][pulse][chan], cmap=dcmap, rasterized=True,\
683 916
                          vmin=-self.DATADICT["NRmax"][pulse] , vmax=self.DATADICT["NRmax"][pulse] )
684 917
 #                     cb2 = canvas.fig.colorbar(im2, ax=ax2, format='%1.0e')
685 918
 #                     cb2.set_label("Noise residual (nV)", fontsize=8)
@@ -729,7 +962,7 @@ class GMRDataProcessor(SNMRDataProcessor):
729 962
             ax2.set_xlabel(r"Time (ms)", fontsize=8)
730 963
         
731 964
         canvas.fig.subplots_adjust(hspace=.15, wspace=.05, left=.075, right=.95, bottom=.1, top=.95 )#left=None, bottom=None, right=None, top=None, wspace=None, hspace=None) 
732
-        tick_locator = MaxNLocator(nbins=5)
965
+        tick_locator = MaxNLocator(nbins=3)
733 966
 
734 967
         cb1 = canvas.fig.colorbar(im1, ax=axes[0::2], format='%1.0e', orientation='horizontal', shrink=.35, aspect=30)
735 968
         cb1.ax.tick_params(axis='both', which='major', labelsize=8)
@@ -737,12 +970,13 @@ class GMRDataProcessor(SNMRDataProcessor):
737 970
         cb1.locator = tick_locator
738 971
         cb1.update_ticks()
739 972
 
973
+        tick_locator2 = MaxNLocator(nbins=3)
740 974
         cb2 = canvas.fig.colorbar(im2, ax=axes[1::2], format='%1.0e', orientation='horizontal', shrink=.35, aspect=30, pad=.2)
741 975
         cb2.ax.tick_params(axis='both', which='major', labelsize=8)
742 976
         cb2.set_label("$\mathcal{V}_N$ (nV)", fontsize=8)
743 977
 
744 978
 
745
-        cb2.locator = tick_locator
979
+        cb2.locator = tick_locator2
746 980
         cb2.update_ticks()
747 981
 
748 982
         canvas.draw()
@@ -1131,7 +1365,7 @@ class GMRDataProcessor(SNMRDataProcessor):
1131 1365
         
1132 1366
         canvas.reAxH(2)
1133 1367
         nstack = len(self.DATADICT["stacks"]) 
1134
-        #canvas.ax1.set_yscale('log')
1368
+        canvas.ax1.set_yscale('log')
1135 1369
 
1136 1370
         for pulse in self.DATADICT["PULSES"]:
1137 1371
             self.DATADICT[pulse]["qeff"] = {}
@@ -1140,7 +1374,15 @@ class GMRDataProcessor(SNMRDataProcessor):
1140 1374
                 self.DATADICT[pulse]["qeff"][ipm] = {}
1141 1375
                 self.DATADICT[pulse]["q_nu"][ipm] = {}
1142 1376
                 #canvas.ax1.clear()
1143
-                scolours = np.array([0.,0.,1.])
1377
+                #scolours = np.array( (   np.linspace(0.8,0.4,len(self.DATADICT["stacks"])), \
1378
+                #                         np.linspace(0.0,0.6,len(self.DATADICT["stacks"])), \
1379
+                #                         np.linspace(0.6,0.0,len(self.DATADICT["stacks"])) )   
1380
+                #                   ).T
1381
+
1382
+                #scolours = plt.cm.Spectral(np.linspace(0,1,len(self.DATADICT["stacks"])))
1383
+                #scolours = plt.cm.Blues(np.linspace(0,1,1.5*len(self.DATADICT["stacks"])))
1384
+                scolours = cmocean.cm.ice(np.linspace(0,1,1.5*len(self.DATADICT["stacks"])))
1385
+                iistack = 0
1144 1386
                 for istack in self.DATADICT["stacks"]:
1145 1387
                     #self.DATADICT[pulse]["PULSE_TIMES"]
1146 1388
                     x = self.DATADICT[pulse]["CURRENT"][ipm][istack]
@@ -1154,12 +1396,10 @@ class GMRDataProcessor(SNMRDataProcessor):
1154 1396
                     canvas.ax1.set_title(r"pulse moment index " +str(ipm), fontsize=10)
1155 1397
                     canvas.ax1.set_xlabel(r"$\nu$ [Hz]", fontsize=8)
1156 1398
                     canvas.ax1.set_ylabel(r"$q_{eff}$ [A$\cdot$sec]", fontsize=8)
1157
-                    if nstack > 1:
1158
-                        canvas.ax1.plot(v, qeff, color=scolours+istack*np.array((0.,1./(nstack+1.),-1./(nstack+1.)) )) # eff current
1159
-                    else:
1160
-                        canvas.ax1.plot(v, qeff, color=scolours) # eff current
1399
+                    canvas.ax1.plot(v, qeff, color=scolours[iistack] ) # eff current
1161 1400
                     self.DATADICT[pulse]["qeff"][ipm][istack] = qeff
1162 1401
                     self.DATADICT[pulse]["q_nu"][ipm][istack] = v
1402
+                    iistack += 1
1163 1403
                 canvas.draw()
1164 1404
                         
1165 1405
                 percent = int(1e2* (float)((istack)+ipm*self.DATADICT["nPulseMoments"]) / 
@@ -1177,25 +1417,27 @@ class GMRDataProcessor(SNMRDataProcessor):
1177 1417
 
1178 1418
         ####################################
1179 1419
         # TODO label fid1 and fid2, and make a legend, and colour by pulse 
1180
-        scolours = ['blue','green']
1181 1420
         nstack = len(self.DATADICT["stacks"])
1182 1421
         iFID = 0 
1183 1422
         for pulse in self.DATADICT["PULSES"]:
1184 1423
             self.DATADICT[pulse]["Q"] = np.zeros( (self.DATADICT["nPulseMoments"], len(self.DATADICT["stacks"])) )
1185 1424
             ilabel = True
1186 1425
             for ipm in range(self.DATADICT["nPulseMoments"]):
1187
-                scolours = np.array([0.,0.,1.])
1426
+                #scolours = np.array([0.,0.,1.])
1427
+                scolours = cmocean.cm.ice(np.linspace(0,1,1.5*len(self.DATADICT["stacks"])))
1428
+                #scolours = plt.cm.Spectral(np.linspace(0,1,len(self.DATADICT["stacks"])))
1429
+                #scolours = plt.cm.Spectral(np.linspace(0,1,len(self.DATADICT["stacks"])))
1188 1430
                 istack = 0
1189 1431
                 for stack in self.DATADICT["stacks"]:
1190 1432
                     # find index 
1191 1433
                     icv = int (round(cv / self.DATADICT[pulse]["q_nu"][ipm][stack][1]))
1192 1434
                     self.DATADICT[pulse]["Q"][ipm,istack] = self.DATADICT[pulse]["qeff"][ipm][stack][icv]
1193 1435
                     if ilabel:
1194
-                        ax.scatter(ipm, self.DATADICT[pulse]["qeff"][ipm][stack][icv], facecolors='none', edgecolors=scolours, label=(str(pulse)))
1436
+                        ax.scatter(ipm, self.DATADICT[pulse]["qeff"][ipm][stack][icv], facecolors='none', edgecolors=scolours[istack], label=(str(pulse)))
1195 1437
                         ilabel = False
1196 1438
                     else:    
1197
-                        ax.scatter(ipm, self.DATADICT[pulse]["qeff"][ipm][stack][icv], facecolors='none', edgecolors=scolours)
1198
-                    scolours += np.array((0,1./(nstack+1),-1/(nstack+1.)))
1439
+                        ax.scatter(ipm, self.DATADICT[pulse]["qeff"][ipm][stack][icv], facecolors='none', edgecolors=scolours[istack])
1440
+                    #scolours += np.array((0,1./(nstack+1),-1/(nstack+1.)))
1199 1441
 
1200 1442
                     percent = int(1e2* (float)((istack)+ipm*self.DATADICT["nPulseMoments"]) / 
1201 1443
                                        (float)(len(self.DATADICT["PULSES"])*self.DATADICT["nPulseMoments"]*nstack))
@@ -1419,7 +1661,7 @@ class GMRDataProcessor(SNMRDataProcessor):
1419 1661
                     self.DATADICT[pulse][ichan]["FFT"][istack] = np.zeros((self.DATADICT["nPulseMoments"] , len(self.DATADICT[pulse][ichan][0][istack])//2+1), dtype=complex)
1420 1662
                     for ipm in range(self.DATADICT["nPulseMoments"]):
1421 1663
                         # Mod works for FID pulse sequences, TODO generalize this for 4 phase T1, etc..
1422
-                        #mod = (-1)**(ipm%2) * (-1)**(istack%2)
1664
+                        mod = (-1)**(ipm%2) * (-1)**(istack%2)
1423 1665
                         self.DATADICT[pulse][ichan]["FFT"][istack][ipm,:] = np.fft.rfft( self.DATADICT[pulse][ichan][ipm][istack] )
1424 1666
                         #if ipm%2:
1425 1667
                             # odd, phase cycled from previous

+ 1
- 1
setup.py View File

@@ -17,7 +17,7 @@ class custom_build_py(build_py):
17 17
         build_py.run(self)
18 18
 
19 19
 setup(name='Akvo',
20
-      version='1.0.5',
20
+      version='1.0.6',
21 21
       description='Surface nuclear magnetic resonance workbench',
22 22
       author='Trevor P. Irons',
23 23
       author_email='Trevor.Irons@lemmasoftware.org',

Loading…
Cancel
Save