def print_element_info(self, pre_class, post_class, element, field_name=None): if field_name is not None: fn = field_name.split('_all')[0] if field_name.endswith( 'all') else field_name.split('_first_pulse')[0] units = [ field[1].get('units', '') for field in self.fields if field[0] == field_name ][0] print("Connection type: %s -> %s" % (pre_class, post_class)) print("\t Grand Average %s = %s" % (field_name, pg.siFormat(element[field_name].mean(), suffix=units))) print("Connected Pairs:") no_qc_data = [] for pair, value in element[field_name].iteritems(): if pair.synapse is not True: continue if np.isnan(value): no_qc_data.append(pair) else: print("\t %s" % (pair)) print("\t\t Average %s: %s" % (field_name, pg.siFormat(value, suffix=units))) print("\t No QC Data:") for pair in no_qc_data: print("\t\t %s" % (pair))
def CAP(self, row): actual = float(self.tbl.item(row, 0).text()) cap1 = self.get_capacitance(1) self.I.__charge_cap__(0, 50000) cap2 = self.get_capacitance(2) if cap1 and cap2: item = self.tbl.item(row, 1) item.setText( '%s,%s' % (pg.siFormat(cap1, precision=4, suffix='F', space=True), pg.siFormat(cap2, precision=3, suffix='F', space=True))) self.CR1 = cap1 / actual self.CR2 = cap2 / actual else: QtGui.QMessageBox.about( self, 'Cap error', "Capacitance invalid. \nIf a %sF capacitor is plugged correctly into CAP socket, this may be an issue." % actual) if abs(cap1 - actual) < self.CAPACITANCE_ERROR: self.setSuccess(item, 1) #capacitance within error margins else: self.setSuccess(item, 0) QtGui.QMessageBox.about( self, 'Cap error', "Capacitance invalid. \nIf a %sF capacitor is plugged correctly into CAP socket, this may be an issue." % actual)
def mouseMoved(evt): """ Handle the event from the mouse. Mainly updates the crosshair and top right values. """ if len(dataFrame.index): pos = evt[ 0] # using signal proxy turns original arguments into a tuple mousePoint = vb.mapSceneToView(pos) # Needed to round the values to multiple of 5, # otherwise the index may not be defined for accessing values in the dataframe. # Change according to the sampling rate. index = int(mousePoint.x()) if index < lastIndex: try: val = pg.siFormat(mousePoint.y() / 1000, 3, 'A') time = pg.siFormat(mousePoint.x(), 3, 's') label.setText( "<span style='font-size: 12pt'>time=%s, <span style='color: red'>y1=%s</span>" % (time, val)) except KeyError: pass vLine.setPos(mousePoint.x()) hLine.setPos(mousePoint.y())
def generate_warnings(self): self.warnings = [] latency_mode = [] for mode in modes: latency_holding = [] for holding in holdings: initial_latency = self.fit_params['initial'][mode][str( holding)].get('xoffset') fit_latency = self.fit_params['fit'][mode][str(holding)].get( 'xoffset') if fit_latency is None or initial_latency is None: continue if abs(np.diff([fit_latency, initial_latency])) > 0.1e-3: warning = 'Initial latency and fit latency differ by %s' % pg.siFormat( abs(np.diff([fit_latency, initial_latency])), suffix='s') latency_holding.append(fit_latency) if len(latency_holding) == 2 and abs( np.diff(latency_holding)) > 0.01e-3: warning = 'Fit latencies for %s mode do not match' % mode self.warnings.append(warning) latency_mode.append(np.mean(latency_holding)) latency_diff = np.diff(latency_mode)[0] if abs(latency_diff) > 0.2e-3: warning = 'Latency across modes differs by %s' % pg.siFormat( latency_diff, suffix='s') self.warnings.append(warning) if np.min(latency_mode) < 0.4e-3 and self.ctrl_panel.user_params[ 'Gap junction call'] is False: self.warnings.append("Short latency; is this a gap junction?") guess_sign = [] guess = None for mode, fits1 in self.output_fit_parameters.items(): for holding, fit in fits1.items(): if 'amp' not in fit: continue if mode == 'ic': guess = 1 if fit['amp'] > 0 else -1 elif mode == 'vc': guess = -1 if fit['amp'] > 0 else 1 guess_sign.append(guess) if np.all(np.array(guess) == 1): guess = "ex" elif np.all(np.array(guess) == -1): guess = "in" if guess is None: self.warnings.append( "Mixed amplitude signs; pick ex/in carefully.") elif guess != self.ctrl_panel.user_params['Synapse call']: self.warnings.append("Looks like an %s synapse??" % guess) print_warning = '\n'.join(self.warnings) self.ctrl_panel.output_params.child('Warnings').setValue(print_warning)
def plotClicked(self, plot, points): if self.top_plot is not None: self.plot.removeItem(self.top_plot) # for pt, style in self.selected_points: # brush, pen, size = style # try: # pt.setBrush(brush) # pt.setPen(pen) # pt.setSize(size) # except AttributeError: # pass selected_points = [[], []] for pt in points: # style = (pt.brush(), pt.pen(), pt.size()) x, y = pt.pos() selected_points[0].append(x) selected_points[1].append(y) data = pt.data() pair = data.index print('Clicked:' '%s' % pair) fields = self.fieldList.selectedItems() for field in fields: field_name = field.text() value = data[field_name] print('%s: %s' % (field_name, pg.siFormat(value))) # pt.setBrush(pg.mkBrush('y')) # pt.setSize(15) self.top_plot = self.plot.plot(selected_points[0], selected_points[1], pen=None, symbol='o', symbolBrush='y', symbolSize=15) self.sigScatterPlotClicked.emit(self, points)
def plotClicked(self, plot, points): if len(self.selected_points) > 0: for pt, style in self.selected_points: brush, pen, size = style try: pt.setBrush(brush) pt.setPen(pen) pt.setSize(size) except AttributeError: pass self.selected_points = [] for pt in points: style = (pt.brush(), pt.pen(), pt.size()) self.selected_points.append([pt, style]) data = pt.data() element = ('%s -> %s ' % (data.pre_class.name, data.post_class.name)) print('Clicked:' '%s' % element) fields = self.fieldList.selectedItems() for field in fields: field_name = field.text() value = data[field_name] print('%s: %s' % (field_name, pg.siFormat(value))) pt.setBrush(pg.mkBrush('y')) pt.setSize(15) self.sigScatterPlotClicked.emit(self, points)
def print_info(self): # update instrument panel self.instNameLabel.setText(self.parent.liaInfo.instName) self.instInterfaceLabel.setText(self.parent.liaInfo.instInterface) self.instInterfaceNumLabel.setText( str(self.parent.liaInfo.instInterfaceNum)) # update ref group self.refSrcLabel.setText(self.parent.liaInfo.refSrcText) self.refFreqLabel.setText( siFormat(self.parent.liaInfo.refFreq, suffix='Hz')) self.refHarmLabel.setText('{:d}'.format(self.parent.liaInfo.refHarm)) self.refPhaseLabel.setText('{:.2f} deg'.format( self.parent.liaInfo.refPhase)) # update input group self.inputConfigLabel.setText(self.parent.liaInfo.configText) self.inputGroundingLabel.setText(self.parent.liaInfo.groundingText) self.inputCoupleLabel.setText(self.parent.liaInfo.coupleText) self.inputFilterLabel.setText(self.parent.liaInfo.inputFilterText) # update gain group self.gainSensLabel.setText(self.parent.liaInfo.sensText) self.gainTCLabel.setText(self.parent.liaInfo.tcText) self.gainReserveLabel.setText(self.parent.liaInfo.reserveText) self.lpSlopeLabel.setText(self.parent.liaInfo.lpSlopeText) # update output group self.outputDisp1Label.setText(self.parent.liaInfo.disp1Text) self.outputDisp2Label.setText(self.parent.liaInfo.disp2Text) self.outputFront1Label.setText(self.parent.liaInfo.front1Text) self.outputFront2Label.setText(self.parent.liaInfo.front2Text) self.outputSRateLabel.setText(self.parent.liaInfo.sampleRateText)
def plotClicked(self, plot, points): if len(self.selected_points) > 0: for pt, style in self.selected_points: brush, pen, size = style try: pt.setBrush(brush) pt.setPen(pen) pt.setSize(size) except AttributeError: pass self.selected_points = [] for pt in points: style = (pt.brush(), pt.pen(), pt.size()) self.selected_points.append([pt, style]) data = pt.data() print('Clicked:' '%s' % data.index) # fields = self.fieldList.selectedItems() for field, options in self.fields.items(): value = data[field] if value is not None: if options.get('mode') == 'range': print('%s: %s' % (field, pg.siFormat(value))) elif options.get('mode') == 'enum': print('%s: %s' % (field, value)) pt.setBrush(pg.mkBrush('y')) pt.setSize(15) self.sigScatterPlotClicked.emit(self, plot, points)
def CCS(self, row): self.I.set_state(CCS=1) time.sleep(0.1) V = self.I.get_voltage('CCS') if V < 2.5: item = self.tbl.item(row, 1) res = V / 1.1e-3 #assume 1.1mA print(V, res) item.setText( pg.siFormat(res, precision=3, suffix=u"\u03A9", space=True, error=None, minVal=1e-25, allowUnicode=True)) actual = float(self.tbl.item(row, 0).text()) if abs(res - actual) < self.CCS_ERROR: self.setSuccess(item, 1) #resistance within error margins self.CCS_SCALING = actual / res else: self.setSuccess(item, 0) else: item.setText('Open') self.setSuccess(item, 0)
def generateText(self): if len(self.values) == 0: return '' avg = self.averageValue() val = self.values[-1][1] if self.siPrefix: return pg.siFormat(avg, suffix=self.suffix) else: return self.formatStr.format(value=val, avgValue=avg, suffix=self.suffix)
def print_element_info(self, pre_class, post_class, element, field_name=None): if field_name is not None: fn = field_name.split('_all')[0] if field_name.endswith('all') else field_name.split('_first_pulse')[0] units = [field[1].get('units', '') for field in self.fields if field[0] == field_name][0] print ("Connection type: %s -> %s" % (pre_class, post_class)) print ("\t Grand Average %s = %s" % (field_name, pg.siFormat(element[field_name].mean(), suffix=units))) print ("Connected Pairs:") no_qc_data = [] for pair, value in element[field_name].iteritems(): if pair.synapse is not True: continue if np.isnan(value): no_qc_data.append(pair) else: print ("\t %s" % (pair)) print ("\t\t Average %s: %s" % (field_name, pg.siFormat(value, suffix=units))) print("\t No QC Data:") for pair in no_qc_data: print ("\t\t %s" % (pair))
def __WA__(self, ADC, row): self.I.set_wave(1e3) #1KHz test x, y = self.I.capture1(ADC, 1000, 5) #get about five cycles self.WCurve.setData(x, y) self.tbl.item(row, 0).setText('1 KHz') try: amp, frq, ph, off = self.sineFit(x, y) self.tbl.item(row, 1).setText( pg.siFormat(frq, precision=3, suffix='Hz', space=True) + ',' + pg.siFormat(amp, precision=3, suffix='V', space=True)) if abs(frq - 1e3) > 2: self.setSuccess(self.tbl.item(row, 1), 0) print(frq) else: self.setSuccess(self.tbl.item(row, 1), 1) except: self.tbl.item(row, 1).setText('Check Connections') self.setSuccess(self.tbl.item(row, 1), 0)
def format_fit_output(self, values, name, suffix): format_list = [] for p in zip(name, suffix): if values.get(p[0]) is None: format_list.append('nan') else: value = values[p[0]] if p[0] == 'nrmse': p_format = ('%0.2f' % value) else: p_format = pg.siFormat(value, suffix=p[1]) format_list.append(p_format) output = ", ".join(format_list) return output
def __init__(self, nsamples, initRange=[0, 30000], maxNSamples=90000): QtGui.QLabel.__init__(self) self.nsamples = nsamples self.time_total = nsamples / SAMPLE_RATE # in seconds # some drawing parameters self.margin = 40 self.tickLength = 30 self.pen_timeline = QtGui.QPen(QtGui.QColor('gray')) self.brush_scrubber = QtGui.QBrush(QtGui.QColor(200, 200, 200, 64)) self.pen_scrubber = QtGui.QPen() self.pen_scrubber.setStyle(QtCore.Qt.NoPen) # widget properties self.setFrameStyle(QtGui.QFrame.StyledPanel) self.setStyleSheet('background-color: #0F0F0F') self.setMouseTracking(True) # mouse state variables self.edgeDetect = 0 self.edgeDetectMargin = 3 self.centerHold = 0 self.leftHold = 0 self.rightHold = 0 # scrubber state variables: to preserve state across resizings, it makes # sense to track state as sample indices rather than pixels. however, # we can set them from pixel values using setStateLeft(), setStateRight(), # and setStateCenter(). these functions also implement limit-checking. self.totalsamp = maxNSamples if (initRange[1] - initRange[0]) > maxNSamples: raise ValueError( "Exceeding maximum number of samples to represent! initRange must be less than maxSamples!!" ) self.minsamp = initRange[0] self.maxsamp = initRange[1] [timespan, suffix] = pg.siFormat(self.time_total, suffix='s').split(' ') self.leftLabel = QtGui.QLabel('sample 0 \n (0 %s)' % suffix) self.rightLabel = QtGui.QLabel('sample %d' % self.nsamples + \ '\n (%s %s)' % (timespan, suffix)) for label in [self.leftLabel, self.rightLabel]: label.setStyleSheet('color:gray; background:transparent') label.setAlignment(QtCore.Qt.AlignCenter) label.setParent(self) label.show()
def compute(): """ Function used to compute the info shown in the right side panel from tjhe selected region. """ if len(dataFrame.index): u = ualimSpin.value() bounds = region.getRegion() slicedDf = dataFrame.loc[bounds[0]:bounds[1]] computeResult.setText( pg.siFormat( np.trapz(slicedDf.current.values / 1000 * u, slicedDf.time.values), 3, 'J')) # Info computations delta = (region.getRegion()[1] - region.getRegion()[0]) integ = np.trapz(slicedDf.current.values / 1000, slicedDf.time.values) / delta avgCurr = pg.siFormat(integ, 3, 'A') labAvgCurrent.setText(f"Average current: {avgCurr}") avgPow = pg.siFormat(integ * u, 3, 'W') labAvgPower.setText(f"Average power: {avgPow}") delta = pg.siFormat(delta, 3, 's') labBoxDelta.setText(f"\u0394t: {delta}")
def CAP1uF(self, row): actual = float(self.tbl.item(row, 0).text()) cap = self.I.capacitance_via_RC_discharge() if cap: item = self.tbl.item(row, 1) item.setText( '%s' % (pg.siFormat(cap, precision=4, suffix='F', space=True))) self.CRRC = actual / cap else: QtGui.QMessageBox.about( self, 'Cap error', "Capacitance invalid. \nIf a 1uF capacitor is plugged correctly into CAP socket, this may be an issue." ) if abs(cap - actual) < 0.1e-6: self.setSuccess(item, 1) #capacitance within error margins else: self.setSuccess(item, 0)
def paint(self, p, *args): pg.ROI.paint(self, p, *args) h1 = self.handles[0]['item'].pos() h2 = self.handles[1]['item'].pos() h4 = self.handles[3]['item'] h5 = self.handles[4]['item'] h4.setVisible(False) h5.setVisible(False) p1 = p.transform().map(h1) p2 = p.transform().map(h2) vec = pg.Point(h2) - pg.Point(h1) length = vec.length() pvec = p2 - p1 pvecT = pg.Point(pvec.y(), -pvec.x()) pos = 0.5 * (p1 + p2) + pvecT * 40 / pvecT.length() angle = pg.Point(1, 0).angle(pg.Point(pvec)) self.ab_angle = angle # Overlay a line to signal which side of the ROI is the back. if self.ac_angle > 0: self.newRoi.setVisible(True) self.newRoi.setPos(h5.pos()) elif self.ac_angle < 0: self.newRoi.setVisible(True) self.newRoi.setPos(h4.pos()) else: self.newRoi.setVisible(False) self.newRoi.setSize(pg.Point(self.size()[0], 0)) p.resetTransform() txt = pg.siFormat( length, suffix='m') + '\n%0.1f deg' % angle + '\n%0.1f deg' % self.ac_angle p.drawText(QtCore.QRectF(pos.x() - 50, pos.y() - 50, 100, 100), QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter, txt)
def SEN(self, row): res = self.I.get_resistance() item = self.tbl.item(row, 1) if res != np.inf: item.setText( pg.siFormat(res, precision=3, suffix=u"\u03A9", space=True, error=None, minVal=1e-25, allowUnicode=True)) actual = float(self.tbl.item(row, 0).text()) if abs(res - actual) < self.RESISTANCE_ERROR: self.setSuccess(item, 1) #resistance within error margins self.RESISTANCE_SCALING = actual / res else: self.setSuccess(item, 0) else: item.setText('Open') self.setSuccess(item, 0)
def CAP_SOCK(self, row): #cap = self.I.get_capacitance() V = self.I.__get_capacitance_voltage__(1, 0, 180) Charge_Current = self.I.currents[1] cap = (Charge_Current * 180 * 1e-6 / V) / self.I.currentScalers[1] self.I.SOCKET_CAPACITANCE = cap print(V, cap) item = self.tbl.item(row, 1) item.setText( pg.siFormat(cap, precision=3, suffix='F', space=True, minVal=1e-25, allowUnicode=True)) if abs(cap - float(self.tbl.item(row, 0).text())) < self.CAPACITANCE_ERROR: self.setSuccess(item, 1) #capacitance within error margins self.socket_cap = cap else: self.setSuccess(item, 0)
def paint(self, p, *args): pg.ROI.paint(self, p, *args) h1 = self.handles[0]['item'].pos() h2 = self.handles[1]['item'].pos() h4 = self.handles[3]['item'] h5 = self.handles[4]['item'] h4.setVisible(False) h5.setVisible(False) p1 = p.transform().map(h1) p2 = p.transform().map(h2) vec = pg.Point(h2) - pg.Point(h1) length = vec.length() pvec = p2 - p1 pvecT = pg.Point(pvec.y(), -pvec.x()) pos = 0.5 * (p1 + p2) + pvecT * 40 / pvecT.length() angle = pg.Point(1, 0).angle(pg.Point(pvec)) self.ab_angle = angle # Overlay a line to signal which side of the ROI is the back. if self.ac_angle > 0: self.newRoi.setVisible(True) self.newRoi.setPos(h5.pos()) elif self.ac_angle < 0: self.newRoi.setVisible(True) self.newRoi.setPos(h4.pos()) else: self.newRoi.setVisible(False) self.newRoi.setSize(pg.Point(self.size()[0], 0)) p.resetTransform() txt = pg.siFormat(length, suffix='m') + '\n%0.1f deg' % angle + '\n%0.1f deg' % self.ac_angle p.drawText(QtCore.QRectF(pos.x() - 50, pos.y() - 50, 100, 100), QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter, txt)
def __init__(self, parent, entry_setting=()): QtGui.QWidget.__init__(self, parent=None) self.parent = parent # add labels self.scanNumLabel = QtGui.QCheckBox() self.commentLabel = QtGui.QLabel() self.dateLabel = QtGui.QLabel() self.timeLabel = QtGui.QLabel() self.itLabel = QtGui.QLabel() self.sensLabel = QtGui.QLabel() self.tcLabel = QtGui.QLabel() self.modModeLabel = QtGui.QLabel() self.modFreqLabel = QtGui.QLabel() self.modAmpLabel = QtGui.QLabel() self.startFreqLabel = QtGui.QLabel() self.stopFreqLabel = QtGui.QLabel() self.stepLabel = QtGui.QLabel() self.ptsLabel = QtGui.QLabel() self.avgLabel = QtGui.QLabel() self.harmLabel = QtGui.QLabel() self.phaseLabel = QtGui.QLabel() # set label text self.scanNumLabel.setText(str(entry_setting[0])) self.commentLabel.setText(entry_setting[1]) self.dateLabel.setText(entry_setting[2]) self.timeLabel.setText(entry_setting[3]) self.itLabel.setText(siFormat(entry_setting[4]*1e-3, suffix='s')) self.sensLabel.setText(siFormat(entry_setting[5], suffix='V')) self.tcLabel.setText(siFormat(entry_setting[6], suffix='s')) self.modModeLabel.setText(entry_setting[7]) self.modFreqLabel.setText(siFormat(entry_setting[8]*1e3, suffix='Hz')) self.modAmpLabel.setText(siFormat(entry_setting[9]*1e3, suffix='Hz')) self.startFreqLabel.setText('{:.3f}'.format(entry_setting[10])) self.stopFreqLabel.setText('{:.3f}'.format(entry_setting[11])) self.stepLabel.setText(siFormat(entry_setting[12]*1e6, suffix='Hz')) self.ptsLabel.setText(str(entry_setting[13])) self.avgLabel.setText(str(entry_setting[14])) self.harmLabel.setText(str(entry_setting[15])) self.phaseLabel.setText('{:.2f} deg'.format(entry_setting[16]))
def print_info(self): # update instrument panel self.instNameLabel.setText(self.parent.synInfo.instName) self.instInterfaceLabel.setText(self.parent.synInfo.instInterface) self.instInterfaceNumLabel.setText( str(self.parent.synInfo.instInterfaceNum)) self.instRemoteDispLabel.setText( 'ON' if self.parent.synInfo.instRemoteDisp else 'OFF') # update RF setting panel self.rfOutputLabel.setText( 'ON' if self.parent.synInfo.rfToggle else 'OFF') self.modOutputLabel.setText( 'ON' if self.parent.synInfo.modToggle else 'OFF') self.synFreqLabel.setText('{:.9f} MHz'.format( self.parent.synInfo.synFreq * 1e-6)) # update modulation setting panel self.am1StateLabel.setText( 'ON' if self.parent.synInfo.AM1Toggle else 'OFF') self.am1SrcLabel.setText(self.parent.synInfo.AM1Src) self.am1DepthLabel.setText('{:.1f}% ({:.0f} dB)'.format( self.parent.synInfo.AM1DepthPercent, self.parent.synInfo.AM1DepthDbm)) self.am1FreqLabel.setText( siFormat(self.parent.synInfo.AM1Freq, suffix='Hz')) self.am1WaveLabel.setText(self.parent.synInfo.AM1Wave) self.am2StateLabel.setText( 'ON' if self.parent.synInfo.AM2Toggle else 'OFF') self.am2SrcLabel.setText(self.parent.synInfo.AM2Src) self.am2DepthLabel.setText('{:.1f}% ({:.0f} dB)'.format( self.parent.synInfo.AM2DepthPercent, self.parent.synInfo.AM2DepthDbm)) self.am2FreqLabel.setText( siFormat(self.parent.synInfo.AM2Freq, suffix='Hz')) self.am2WaveLabel.setText(self.parent.synInfo.AM2Wave) self.fm1StateLabel.setText( 'ON' if self.parent.synInfo.FM1Toggle else 'OFF') self.fm1SrcLabel.setText(self.parent.synInfo.FM1Src) self.fm1DevLabel.setText( siFormat(self.parent.synInfo.FM1Dev, suffix='Hz')) self.fm1FreqLabel.setText( siFormat(self.parent.synInfo.FM1Freq, suffix='Hz')) self.fm1WaveLabel.setText(self.parent.synInfo.FM1Wave) self.fm2StateLabel.setText( 'ON' if self.parent.synInfo.FM2Toggle else 'OFF') self.fm2SrcLabel.setText(self.parent.synInfo.FM2Src) self.fm2DevLabel.setText( siFormat(self.parent.synInfo.FM2Dev, suffix='Hz')) self.fm2FreqLabel.setText( siFormat(self.parent.synInfo.FM2Freq, suffix='Hz')) self.fm2WaveLabel.setText(self.parent.synInfo.FM2Wave) self.pm1StateLabel.setText( 'ON' if self.parent.synInfo.PM1Toggle else 'OFF') self.pm1SrcLabel.setText(self.parent.synInfo.PM1Src) self.pm1DevLabel.setText( siFormat(self.parent.synInfo.PM1Dev, suffix='rad')) self.pm1FreqLabel.setText( siFormat(self.parent.synInfo.PM1Freq, suffix='Hz')) self.pm1WaveLabel.setText(self.parent.synInfo.PM1Wave) self.pm2StateLabel.setText( 'ON' if self.parent.synInfo.PM2Toggle else 'OFF') self.pm2SrcLabel.setText(self.parent.synInfo.PM2Src) self.pm2DevLabel.setText( siFormat(self.parent.synInfo.PM2Dev, suffix='rad')) self.pm2FreqLabel.setText( siFormat(self.parent.synInfo.PM2Freq, suffix='Hz')) self.pm2WaveLabel.setText(self.parent.synInfo.PM2Wave) self.lfStateLabel.setText( 'ON' if self.parent.synInfo.LFToggle else 'OFF') self.lfSrcLabel.setText(self.parent.synInfo.LFSrc) self.lfVolLabel.setText( siFormat(self.parent.synInfo.LFVoltage, suffix='V'))
def si_format(self): return pg.siFormat(self)
def describe(self): return "%s < %s < %s" % (pg.siFormat(self['Min'], suffix=self.units), self.fieldName, pg.siFormat(self['Max'], suffix=self.units))
def calc_rho(field, data_xx, data_xy, curr=1e-9, width=50e-6, length=100e-6, field_center=1, name="Analyzed_Field_Sweep"): """ Calculate rho_xx, rho_xy from given data sweeps: Parameters: - field: field setpoints - data_xx: V_xx DataArray - data_xy: V_xy DataArray - curr: Either the current as a number or as a DataArray. If a DataArray is given, the trace will be averaged to extract a mean current. - width/length: Width of the hall bar/distance between V_xx probes to extract a sheet resistance - field_center: - name: Name to save output data """ path = "data" / Path(name) np_field = field.ndarray.copy() np_xx = data_xx.ndarray.copy() np_xy = data_xy.ndarray.copy() if isinstance(curr, qc.DataArray): curr = np.average(-1 * (curr.ndarray.copy()) / 1e6) print(curr) # Calculate resistances rho_xy = np_xy / curr # rho_xx is scaled by the width+length of the hall bar to get a sheet resistivity rho_xx = (np_xx / curr) * (width / length) # Calculate density # We want to do a fit between (field_center, -field_center) tesla as there is some extra structure # above these values min_ind = np.where(np.abs(np_field + field_center) < 0.01)[0][0] max_ind = np.where(np.abs(np_field - field_center) < 0.01)[0][0] min_ind, max_ind = np.min((min_ind, max_ind)), np.max((min_ind, max_ind)) res = np.polyfit(np_field[min_ind:max_ind], rho_xy[min_ind:max_ind], 1) poly = np.poly1d(res) # Then the density is given by 1/(|e| dp/dB), in cm^2 density = 1 / (const.e * res[0]) density *= 1e-4 print("Density is: {:.2e} cm^-2".format(density)) # And the calculated mobility is given by mu=1/(rho_xx |e| ns) mu = 1 / (rho_xx * const.e * density) # And let's quote the density slightly offset from 0, at 0.1T mob_ind = np.where(np.abs(np_field - 0.1) < 0.005)[0][0] mobility = mu[mob_ind] print("Mobility is: {:.2e} cm^2/V s".format(mobility)) # And finally, let's create a new dataset. Leave location unset for now... dataset = qc.DataSet(location=str(path)) da_field = qc.DataArray(array_id="Field", label="Field", unit="T", is_setpoint=True, preset_data=np_field) da_reduced_field = qc.DataArray(array_id="Reduced_Field", label="Field", unit="T", is_setpoint=True, preset_data=np_field[min_ind:max_ind]) da_poly = qc.DataArray(array_id="Poly_Deg", label="Polynomial Degree", is_setpoint=True, preset_data=list(range(2))[::-1]) da_rho_xy = qc.DataArray(array_id="Rho_XY", label="Rho XY", unit="Ohms", set_arrays=(da_field, ), preset_data=rho_xy) da_rho_xy_fit = qc.DataArray(array_id="fit_Rho_XY", label="Rho XY", unit="Ohms", set_arrays=(da_reduced_field, ), preset_data=poly(np_field[min_ind:max_ind])) da_rho_xy_coef = qc.DataArray(array_id="coef_Rho_XY", label="Poly Coefficients", set_arrays=(da_poly, ), preset_data=res) da_rho_xx = qc.DataArray(array_id="Rho_XX", label="Rho XX", unit="Ohms", set_arrays=(da_field, ), preset_data=rho_xx) da_mu = qc.DataArray(array_id="mu", label="Mobility", unit="cm<sup>2</sup> (V s)<sup>-1</sup>", set_arrays=(da_field, ), preset_data=mu) dataset.add_array(da_field) dataset.add_array(da_reduced_field) dataset.add_array(da_poly) dataset.add_array(da_rho_xy) dataset.add_array(da_rho_xy_fit) dataset.add_array(da_rho_xy_coef) dataset.add_array(da_rho_xx) dataset.add_array(da_mu) # Save the data dataset.finalize() # Make some nice plots # Showing Density (Rho_XY) analysis fig, ax = plt.subplots() ax.plot(dataset.Field, dataset.Rho_XY, 'r') ax.plot(dataset.Field, dataset.fit_Rho_XY, 'k') ax.set_xlabel(format_ax(dataset.Field)) ax.set_ylabel(format_ax(dataset.Rho_XY)) ax.text( 0.05, 0.95, "Using {} current<br>".format(qtplot.siFormat(curr, suffix="A")) + "From a linear fit:<br>" + "dρ/dB = {}<br>".format(qtplot.siFormat(res[0], suffix="Ω")) + "n<sub>s</sub> = 1/(|e| dρ/dB) = {:e} cm<sup>-2</sup>".format(density), transform=ax.transAxes) fig.savefig(path / "rho_xy.png") # Showing Mobility analysis fig, ax = plt.subplots() ax.plot(dataset.Field, dataset.mu, c=color_cycle[5]) ax.set_xlabel(format_ax(dataset.Field)) ax.set_ylabel(format_ax(dataset.mu)) ax.text( 0.05, 0.95, "Mobility extracted from:<br>" + "μ = 1/ρ<sub>xx</sub> |e| n<sub>s</sub>, with n<sub>s</sub>= {:.2e} cm<sup>-2</sup><br>" .format(density) + "And using W = {}, L = {}".format(qtplot.siFormat(width, suffix="m"), qtplot.siFormat(length, suffix="m")), transform=ax.transAxes) fig.savefig(path / "mobility.png") return dataset
def describe(self): return "%s < %s < %s" % (pg.siFormat( self['Min'], suffix=self.units), self.fieldName, pg.siFormat(self['Max'], suffix=self.units))
fr, Pxx_den = scipy.signal.periodogram(inp['i1'], inp['samplerate']) #f, Pxx_den = scipy.signal.welch(input, samplerate, nperseg=10*256, scaling='spectrum') ax.set_ylabel('PSD [pA^2/Hz]') ax.set_xlabel('Frequency') ax.set_yscale('log') ax.set_xscale('log') ax.xaxis.set_major_formatter(EngFormatter(unit='Hz')) ax.plot(fr, Pxx_den*1e24, 'b') ax.grid(1) ax.autoscale() if inp['graphene']: fr, Pxx_den = scipy.signal.periodogram(inp['i2'], inp['samplerate']) ax.plot(fr, Pxx_den * 1e24, 'r') ax.legend(['Ion', 'Transverse']) textstr = 'STD ionic: {}\nSTD trans: {}'.format(pg.siFormat(np.std(inp['i1'])), pg.siFormat(np.std(inp['i2']))) else: textstr = 'STD ionic: {}'.format(pg.siFormat(np.std(inp['i1']))) ax.text(0.75, 0.1, textstr, transform=ax.transAxes, fontsize=8, verticalalignment='top', bbox=props) if SaveAsPDF: pp.savefig(fig1) else: fig1.savefig(directory + os.sep + str(os.path.split(filename)[1][:-4]) + '_PSD.png') fig1.clear() ax.clear() plt.close(fig1)