def dimArrays(self): # Initialize numpy arrays and python lists as zeros. shape2D = (self.chCount, self.pktCount) # 0-indexed by packet number. self.pkt = sp.zeros(self.pktCount, dtype=int) self.cpuDTStr = [cs.emptyClass()] * self.pktCount self.cpuDT = [0] * self.pktCount self.gpsDTStr = [cs.emptyClass()] * self.pktCount self.gpsDT = [0] * self.pktCount self.lat = sp.zeros(self.pktCount, dtype=float) self.longi = sp.zeros(self.pktCount, dtype=float) # 0-indexed by channel number. # 0-indexed by packet number. self.clipHi = sp.zeros(shape2D, dtype=int) self.clipLo = sp.zeros(shape2D, dtype=int) self.meanPct = sp.zeros(shape2D, dtype=float) self.meanUpPct = sp.zeros(shape2D, dtype=float) self.meanDnPct = sp.zeros(shape2D, dtype=float) self.meanPhys = sp.zeros(shape2D, dtype=float) self.meanUpPhys = sp.zeros(shape2D, dtype=float) self.meanDnPhys = sp.zeros(shape2D, dtype=float) self.countUp = sp.zeros(shape2D, dtype=int) self.countDn = sp.zeros(shape2D, dtype=int) # 0-indexed by channel number. # 0-indexed by packet number. # 0-indexed by sample number. self.raw = sp.zeros((self.chCount, self.pktCount, self.n), dtype=float)
def ipArgandCompare(): pklFolder = r'C:\Users\timl\Documents\IP_data_plots\190503_oil' fileNums = sp.array([6, 7, 8, 9, 10]) # File numbers with the low frequency for normalization for each file # number. # lowFiles = sp.zeros_like(fileNums) # shortColors = ['C0', 'C1', 'blueviolet'] # shortIdx = 0 # shortLinestyles = ['--', '-', '-'] # # colors = [] # linestyles = [] # legFilter = sp.zeros_like(fileNums, dtype=bool) # for idx in range(0, len(fileNums), 3): # lowFiles[idx:idx+3] = fileNums[idx] # colors += 3*[shortColors[shortIdx]] # linestyles += 3*[shortLinestyles[shortIdx]] # shortIdx += 1 # legFilter[idx] = True linestyles = len(fileNums) * ['-'] colors = len(fileNums) * [None] legFilter = sp.ones(len(fileNums), dtype=bool) lowFiles = fileNums.copy() instruct = cs.emptyClass() instruct.pklFolder = pklFolder instruct.fileNums = fileNums instruct.lowFiles = lowFiles instruct.colors = colors instruct.linestyles = linestyles instruct.legFilter = legFilter arg.ipArgand(instruct)
def coordExtrema(a): """ Return corner coordinate positions of the smallest rectangle aligned with lines of longitude and latitude that would contain all the survey data points on or within its borders. Parameters ---------- a : fileStruct, list Contains longitude and latitude information for each packet in each file. Returns ------- ext : float (deg), fields of a class longiMin, longiMax, latMin, latMax """ # Extreme values of longitude and latitude in the survey. longiMin = sp.inf latMin = sp.inf longiMax = -sp.inf latMax = -sp.inf for t in range(len(a)): if a[t].pktCount > 0: arraMin = sp.amin(a[t].longi) if arraMin < longiMin: longiMin = sp.amin(a[t].longi) arraMin = sp.amin(a[t].lat) if arraMin < latMin: latMin = arraMin arraMax = sp.amax(a[t].longi) if arraMax > longiMax: longiMax = arraMax arraMax = sp.amax(a[t].lat) if arraMax > latMax: latMax = arraMax ext = cs.emptyClass() ext.longiMin = longiMin ext.longiMax = longiMax ext.latMin = latMin ext.latMax = latMax return ext
def ipScatterEverything(): folderPath = r'C:\temp\180827_smallSQUR' fileStart = cs.lastName(folderPath) # Processed file choice. loadThis = 'zOddH' # Plotting choice. plotThis = 'zPhase' # Channel plotted. ch = 2 # Index of the frequency plotted. freqIdx = 0 # Colors for plotting main results. if plotThis == 'zPhase': color = 'Red' elif plotThis == 'zMag': color = 'Green' elif plotThis == '2MagPhys': color = 'DarkGoldenRod' # Loading the data: fileName = fileStart + '_' + loadThis + '.pkl' filePath = os.path.join(folderPath, fileName) with open(filePath, 'rb') as f: # Python 3: open(..., 'rb') a = pickle.load(f) # Pick out the desired result data to be plotted as x and y values. res = cs.emptyClass() res.yVal = sp.array([]) for t in range(len(a)): if plotThis == 'zPhase': res.yVal = sp.hstack((res.yVal, a[t].phaseDiff[ch, :, freqIdx])) elif plotThis == 'zMag': res.yVal = sp.hstack((res.yVal, a[t].zMag[ch, :, freqIdx])) elif plotThis == '2MagPhys': res.yVal = sp.hstack((res.yVal, 2 * a[t].magPhys[ch, :, freqIdx])) res.xVal = sp.array(range(len(res.yVal))) # Initialize plot settings. ps = cs.emptyClass() ps.color = color ps.markerSize = 3 ps.marker = 'o' ps.titleWrap = 75 ps.xLabel = 'Packets' if plotThis == 'zPhase': ps.yLabel = 'Impedance Phase (mrad)' elif plotThis == 'zMag': ps.yLabel = 'Impedance Amplitude (m$\Omega$)' elif plotThis == '2MagPhys': if ch == 0: ps.yLabel = 'Twice Complex Mag. (A)' else: ps.yLabel = 'Twice Complex Mag. (V)' # Plot. # Function plots one thing at a time and can update formatting and labels. params = { 'legend.fontsize': 'x-large', 'figure.figsize': (9, 6.5), 'axes.labelsize': 'x-large', 'axes.titlesize': 'x-large', 'xtick.labelsize': 'x-large', 'ytick.labelsize': 'x-large' } plt.rcParams.update(params) # Plot the main result. # Use the string '_nolegend_' to hide the label from the legend display. plt.scatter(res.xVal, res.yVal, color=ps.color, marker=ps.marker) titleStr = '%s All Packets' % (fileStart) if ps.titleWrap < sp.inf: # Wrap text at a set character length. titleStr = '\n'.join(wrap(titleStr, ps.titleWrap)) plt.title(titleStr) plt.xlabel(ps.xLabel) plt.ylabel(ps.yLabel) plt.legend() plt.grid(b=True) plt.tight_layout() plt.show()
def circuitTheory(): ci = cs.emptyClass() # Resistors. (Ohm) ci.r1 = 0.1 ci.r2 = 0.1 ci.r3 = ci.r2 ci.r4 = 1 ci.r5 = ci.r4 ci.r6 = 0.8 ci.r7 = 8 # Capacitor. (F) ci.c = 3e-6 # Transmit current. Phase = 0. (complex A) ci.i1 = 3 # Transmit frequency list. (Hz) xmitFund = 4 freqList = sp.array(range(xmitFund, xmitFund * (33 + 1), 2 * xmitFund)) phaseShift = sp.zeros_like(freqList) for idx in range(len(freqList)): # Frequency. (Hz) ci.f = freqList[idx] # Phase shift between the voltage across R1 and the transmit current. # Convert to milliradian. phaseShift[idx] = 10**3 * phaseI4(ci) params = { 'legend.fontsize': 'x-large', 'figure.figsize': (9, 6.5), 'axes.labelsize': 'x-large', 'axes.titlesize': 'x-large', 'xtick.labelsize': 'x-large', 'ytick.labelsize': 'x-large' } plt.rcParams.update(params) ps = cs.emptyClass() ps.color = 'C0' ps.markerSize = 6 ps.marker = 'o' ps.legStr = 'Circuit Theory' ps.linestyle = 'solid' ps.titleStr = 'Capacitor, C = %.2f uF.' % (ci.c * 10**6) ps.titleWrap = 75 ps.titleBool = True ps.xLabel = 'Frequency (Hz)' ps.yLabel = 'Phase Shift (mrad)' ps.legOutside = False # Plot the main result. lines2D = plt.plot(freqList, phaseShift, color=ps.color, markersize=ps.markerSize, marker=ps.marker, label=ps.legStr, linestyle=ps.linestyle) titleStr = ps.titleStr if ps.titleWrap < sp.inf: # Wrap text at a set character length. titleStr = '\n'.join(wrap(titleStr, ps.titleWrap)) if ps.titleBool: plt.title(titleStr) plt.xlabel(ps.xLabel) plt.ylabel(ps.yLabel) if ps.legOutside: plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left") plt.subplots_adjust(right=0.75) else: plt.legend(loc="lower left") plt.tight_layout() plt.grid(b=True) plt.show()
def ipSurvey(): params = { 'legend.fontsize': 'x-large', 'figure.figsize': (9, 6.5), 'axes.labelsize': 'x-large', 'axes.titlesize': 'x-large', 'xtick.labelsize': 'x-large', 'ytick.labelsize': 'x-large' } plt.rcParams.update(params) # Class object holding plot settings. ps = cs.emptyClass() # Whether to save the plotted datasets to txt files. ps.saveTxt = False crop = True ps.folderPath = r'C:\Users\timl\Documents\IP_data_plots\190506_eagle' folderName = cs.lastName(ps.folderPath) # Processed result choice. loadThis = 'zAnyF' # Read the depth information for each file. infoPath = os.path.join(ps.folderPath, 'depthInfo.txt') depthList = [] with open(infoPath, 'r') as f: for lidx, line in enumerate(f, 1): # Strip off trailing newline characters. line = line.rstrip('\n') # Split up comma-delimited information. (fileDateStr, fileNum, senseFt) = line.split(',') # Type casting. fileNum = int(fileNum) # Estimated water depth on the line. senseFt = float(senseFt) # (ft) depth = senseFt / 3.28084 # (m) # Dump results in a list. depthList.append([fileDateStr, fileNum, depth]) # Loading the data. pklName = folderName + '_' + loadThis + '.pkl' filePath = os.path.join(ps.folderPath, pklName) with open(filePath, 'rb') as f: # Python 3: open(..., 'rb') a = pickle.load(f) # Which files will be plotted. filesPlotted = cs.readFilesPlotted(a, ps.folderPath) # Crop information. if crop: cs.readCropInfo(a, ps.folderPath, 'pklCropInfo.txt') # Plotting choice. ps.plotThis = 'zMag' # Channel plotted. ps.ch = 1 # Harmonic number of the xmitFund plotted. ps.h = 1 # Index of the frequency in the list of odd harmonics. ps.freqIdx = 4 * ps.h # Whether the color axis bounds are set manually. manualColor = True clipColorData = False colMin = 1 # /(2*sp.pi*4) colMax = 5.5 # /(2*sp.pi*4) # Whether to plot line segments and points along the survey track. ps.showLines = False # Whehter to save polygon and line shape files. ps.saveShape = False # Rectangle defined by coordinate extrema along longi and lat axes. ps.ext = mm.coordExtrema(a) # Offset distance to either side of the survey line color strip extends. ps.sideRange = 3 # (m) # Whether to plot in (longi, lat) or a projected reference. ps.plotWGS84 = False # The WGS84 latitude-longitude Coordinate Reference System (CRS). ps.crsWGS84 = {'init': 'epsg:4326'} # Define an azimuthal equidistant Coordinate Reference System (CRS). longiCent = (ps.ext.longiMax + ps.ext.longiMin) / 2 latCent = (ps.ext.latMax + ps.ext.latMin) / 2 longiCent = -122.50032907675 latCent = 47.617131187 ccrsAzEq = ccrs.AzimuthalEquidistant(central_longitude=longiCent, central_latitude=latCent) # This Cartopy CRS (CCRS) can be converted into a `proj4` string/dict # compatible with GeoPandas. ps.crsAzEq = ccrsAzEq.proj4_init # Initializations. ps.colMin = sp.inf ps.colMax = -sp.inf tList = sp.array(range(len(a))) tList = tList[filesPlotted] originalFreqIdx = ps.freqIdx for t in tList: ps.freqIdx = originalFreqIdx if a[t].pktCount > 0: # Join the longitude and latitude arrays into one matrix with two # columns. Col 0: longi, Col 1: lat. # (deg) a[t].fix = sp.transpose(sp.vstack((a[t].longi, a[t].lat))) # Associate a water depth with each fix at the ship location. for idx in range(len(depthList)): if a[t].fileNum == depthList[idx][1]: if a[t].fileDateStr == depthList[idx][0]: depth = depthList[idx][2] a[t].depth = depth * sp.ones_like(a[t].pkt) # (m) # Cable lead-length deployed. a[t].leadin = 65.25 # (m) # Take an average of the 3rd and 5th harmonics to get a reading # at 4 Hz when the xmitFund was 1 Hz. if a[t].xmitFund == 1 and ps.h == 1: ps.freqIdx = 4 * 4 freqIdx3Hz = 4 * 3 freqIdx5Hz = 4 * 5 a[t].phaseDiff[ps.ch, :, ps.freqIdx] = ( (a[t].phaseDiff[ps.ch, :, freqIdx3Hz] + a[t].phaseDiff[ps.ch, :, freqIdx5Hz]) / 2) # Pick which data to map to colors in the plot. if ps.plotThis == 'zPhase': a[t].color = a[t].phaseDiff[ps.ch, :, ps.freqIdx] # Despike phase differences with a threshold spike in mrad. # a[t].color = despike(a[t].color, 10) cbarLabel = 'Impedance Phase (mrad)' elif ps.plotThis == 'zMag': a[t].color = a[t].zMag[ps.ch, :, ps.freqIdx] # Despike magnitudes with a threshold spike in mOhm. # a[t].color = despike(a[t].color, 0.5) cbarLabel = 'Impedance Magnitude (m$\Omega$)' elif ps.plotThis == '2MagPhys': a[t].color = 2 * a[t].magPhys[ps.ch, :, ps.freqIdx] # a[t].color = despike(a[t].color, 0.01) if ps.ch == 0: cbarLabel = 'Twice Complex Mag. (A)' else: cbarLabel = 'Twice Complex Mag. (V)' elif ps.plotThis == 'zTime': freq = a[t].freq[ps.freqIdx] # (Hz) a[t].color = (a[t].phaseDiff[ps.ch, :, ps.freqIdx] / (2 * sp.pi * freq)) # (millisecond) # Despike phase differences with a threshold spike in us. # a[t].color = despike(a[t].color, 100) cbarLabel = 'v-i Time (ms)' elif ps.plotThis == 'crop': a[t].color = a[t].cropLogic.astype(float) # Edit the color data to clip at the manual bounds, if desired. if clipColorData: a[t].color[a[t].color < colMin] = colMin a[t].color[a[t].color > colMax] = colMax # Keep track of the maximum and minimum color values. if a[t].xmitFund != 8: if not crop: arraMin = sp.amin(a[t].color) arraMax = sp.amax(a[t].color) else: if sp.any(a[t].cropLogic): arraMin = sp.amin(a[t].color[a[t].cropLogic]) arraMax = sp.amax(a[t].color[a[t].cropLogic]) else: arraMin = sp.inf arraMax = -sp.inf if arraMin < ps.colMin: ps.colMin = arraMin if arraMax > ps.colMax: ps.colMax = arraMax # Manually set the min and max color values. if manualColor: ps.colMin = colMin ps.colMax = colMax # Big picture class containing master polygon, color, and line lists for # all survey lines. bp = cs.emptyClass() bp.polyList = [] bp.colorList = [] bp.lineList = [] for t in tList: if a[t].pktCount > 0: if not crop or (crop and sum(a[t].cropLogic) > 0): print('file %s_%d' % (a[t].fileDateStr, a[t].fileNum)) print(a[t].descript) # Print time the file started. print(a[t].cpuDTStr[0].t) plotStrip(bp, a[t], ps, crop) ps.fig = plt.gcf() ps.ax = ps.fig.add_subplot(111) ps.ax.set_aspect('equal') ps.cmap = 'jet' ps.lineCol = 'k' # Color of the basic track line shape. # Geopandas data frame object containing each polygon in the list, along # with colors. dfPoly = gpd.GeoDataFrame({'geometry': bp.polyList, 'color': bp.colorList}) dfPoly.crs = ps.crsAzEq dfLine = gpd.GeoDataFrame({'geometry': bp.lineList}) dfLine.crs = ps.crsAzEq # Transform back to (longi,lat), if requested. if ps.plotWGS84: dfLine = dfLine.to_crs(ps.crsWGS84) dfPoly = dfPoly.to_crs(ps.crsWGS84) dfPoly.plot(ax=ps.ax, column='color', cmap=ps.cmap, vmin=ps.colMin, vmax=ps.colMax) if ps.showLines: dfLine.plot(ax=ps.ax, color=ps.lineCol) # Transform back to (longi,lat). if ~ps.plotWGS84: dfLine = dfLine.to_crs(ps.crsWGS84) dfPoly = dfPoly.to_crs(ps.crsWGS84) # Keep axis bounds from before the shorelines are plotted. xlimLeft, xlimRight = plt.xlim() ylimLeft, ylimRight = plt.ylim() xlimLeft = -100 xlimRight = 500 ylimLeft = -600 ylimRight = 600 # xlimLeft = -100 # xlimRight = 500 # ylimLeft = -300 # ylimRight = 400 # xlimLeft = 5000 # xlimRight = 9000 # ylimLeft = -3500 # ylimRight = -1500 # xlimLeft = 7800 # xlimRight = 9000 # ylimLeft = -3000 # ylimRight = -2100 if ps.saveShape: # Save the geodataframes to files for colors and lines. polyFileName = '%s_%s_Ch%dH%d' % (a[0].fileDateStr, ps.plotThis, ps.ch, ps.h) if clipColorData: polyFileName += '_clip%dand%d' % (colMin, colMax) lineFileName = '%s_lines' % (a[0].fileDateStr) shapeFolder = r'C:\temp\181213_dataFrameFileEagle' polyFilePath = os.path.join(shapeFolder, polyFileName) lineFilePath = os.path.join(shapeFolder, lineFileName) dfPoly.to_file(polyFilePath) dfLine.to_file(lineFilePath) # Shoreline plotting. shoreline(ps) # Reset the axis bounds after shorelines are plotted. plt.xlim(xlimLeft, xlimRight) plt.ylim(ylimLeft, ylimRight) # Display the colormap in use as a sidebar colorbar. sm = plt.cm.ScalarMappable(cmap=ps.cmap, norm=plt.Normalize(vmin=ps.colMin, vmax=ps.colMax)) sm._A = [] # colorbar() requires a scalar mappable, "sm". if ps.plotThis != 'crop': # cbaxes = ps.fig.add_axes([0.8, 0.1, 0.03, 0.8]) divider = make_axes_locatable(ps.ax) cax1 = divider.append_axes("right", size="10%", pad=0.05) cb = plt.colorbar(sm, cax=cax1) cb.set_label(cbarLabel) plt.sca(ps.ax) # Axes labels. if not ps.plotWGS84: plt.xlabel('W-E (m)') plt.ylabel('S-N (m)') else: plt.xlabel('Longitude (deg)') plt.ylabel('Latitude (deg)') plt.grid(b=True) # Plot title. Use notes recorded in one of the files plotted. tTitle = cs.find(filesPlotted, True) # titleStr = ('%s Ch %d (%s). Harmonic %d = %.0f Hz. xmitFund = %.0f Hz.' # % (a[tTitle].fileDateStr, ps.ch, a[tTitle].measStr[ps.ch], ps.h, # ps.h*a[tTitle].xmitFund, a[tTitle].xmitFund)) titleStr = ('Ch %d (%s). Harmonic %d = %.0f Hz. xmitFund = %.0f Hz.' % (ps.ch, a[tTitle].measStr[ps.ch], ps.h, ps.h * a[tTitle].xmitFund, a[tTitle].xmitFund)) # titleStr = ('%s Ch %d (%s). Frequency = %.0f Hz.' # % (a[tTitle].fileDateStr, ps.ch, a[tTitle].measStr[ps.ch], # ps.h*a[tTitle].xmitFund)) # titleStr = ('%s_%d Line %s. Ch %d (%s). Frequency = %.0f Hz. ' # 'xmitFund = %.0f Hz.' # % (a[tTitle].fileDateStr, a[tTitle].fileNum, # a[tTitle].descript, ps.ch, a[tTitle].measStr[ps.ch], # a[tTitle].freq[ps.freqIdx], a[tTitle].xmitFund)) if manualColor or clipColorData: if ps.plotThis == 'zPhase': titleStr += (' \nColors clipped at %d mrad and %d mrad.' % (ps.colMin, ps.colMax)) elif ps.plotThis == 'zMag': titleStr += ((' \nColors clipped at %.1f m$\Omega$ ' + 'and %.1f m$\Omega$.') % (ps.colMin, ps.colMax)) elif ps.plotThis == '2MagPhys': titleStr += ((' \nColors clipped at %.2f A ' + 'and %.2f A.') % (ps.colMin, ps.colMax)) elif ps.plotThis == 'zTime': titleStr += ((' \nColors clipped at %.2f ms ' + 'and %.2f ms.') % (ps.colMin, ps.colMax)) elif ps.plotThis == 'crop': titleStr = '%s Orange = Array on Floor (Guess)' % ( a[0].fileDateStr) # t = 4 # titleStr = ('%s_%d Line %s. Average Speed 1.7 kt.' % # (a[t].fileDateStr, a[t].fileNum, a[t].descript)) plt.title(titleStr)
def artificialRaw(): int215 = 2**15 # Whether to add voltage spikes at the upward square wave transition. addSpikes = True doFilter = False ntaps = 1001 cutoff = 10 # (Hz) if addSpikes: descript = 'spikes' else: descript = 'no spikes' if doFilter: descript += ' filtered' else: descript += ' unfiltered' at = cs.emptyClass() at.descript = descript folderPath = os.path.join( r'C:\Users\timl\Documents\IP_data_plots\190415_artificialSpikes') # Change . rawFolderPath = os.path.join(folderPath, 'rawData') at.fileDateStr = '190415' # folderName[:6] at.fileNum = 2 fileName = '%s_%d.txt' % (at.fileDateStr, at.fileNum) filePath = os.path.join(rawFolderPath, fileName) if doFilter: at.minor = '%.0f Hz cutoff, %d taps' % (cutoff, ntaps) else: at.minor = 'None.' at.major = '' at.scanChCount = 8 at.writeChCount = 8 at.n = 8192 at.fs = 8192 # (Hz) at.xmitFund = 4 # (Hz) at.rCurrentMeas = 1.25 # (Ohm) at.rExtraSeries = 0 # (Ohm) at.measStr = at.writeChCount * ['N/A'] at.measStr[0] = 'currentMeas' at.measStr[1] = 'voltage' at.In5BHi = sp.array([10, 0.1, 0.1, 0.1, 0.1, 1, 10, 10]) at.In5BHi = at.In5BHi[:at.writeChCount] at.Out5BHi = sp.array([5, 10, 10, 10, 10, 5, 5, 5]) at.Out5BHi = at.Out5BHi[:at.writeChCount] at.ALoadQHi = at.Out5BHi # Artificially generate raw current and voltage waveforms. if False: at.pktCount = 1 at.raw = sp.zeros((at.writeChCount, at.pktCount, at.n)) oilFolderPath = r'C:\Users\Public\Documents\oil_data' oilFilePath = os.path.join(oilFolderPath, at.descript + 'i.txt') at.raw[0, 0, :] = readOilFile(oilFilePath, at.n) oilFilePath = os.path.join(oilFolderPath, at.descript + 'd.txt') at.raw[1, 0, :] = readOilFile(oilFilePath, at.n) elif True: # Number of packets saved to the file. at.pktCount = 1 # Time series. timeVec = sp.linspace(0, at.n / at.fs, at.n, endpoint=False) # Add a time offset from zero. timeVec += 0.1 # Basic wave parameters to work from. amp = 6 # (%) freq = 4 # (Hz) # Wave phases by channel. phaseVec = sp.array(7 * [17]) / 1000 # (rad) phaseVec = sp.hstack((sp.zeros(1), phaseVec)) # Measurment string. for ch in range(at.writeChCount): if addSpikes: if ch == 0: at.measStr[ch] = 'Ch %d. No Spikes.' % ch else: at.measStr[ch] = 'Ch %d. With Spikes.' % ch else: at.measStr[ch] = 'Ch %d. No Spikes.' % ch listTime = at.scanChCount * [timeVec] for ch in range(at.writeChCount): # Add channel skew error. deltaT = ch / (at.fs * at.scanChCount) # (s) listTime[ch] = timeVec + deltaT at.raw = sp.zeros((at.writeChCount, at.pktCount, at.n)) for p in range(at.pktCount): for ch in range(at.writeChCount): at.raw[ch, p, :] = amp * sp.signal.square( 2 * sp.pi * freq * listTime[ch] + phaseVec[ch]) # Add voltage spikes to 100% at the transition from negative to # positive. if addSpikes and ch != 0: lastSign = at.raw[ch, p, 0] > 0 for tIdx in range(1, len(at.raw[ch, p, :])): newSign = at.raw[ch, p, tIdx] > 0 if newSign and (newSign != lastSign): at.raw[ch, p, tIdx] = 100 lastSign = newSign # Convert from percentages of a range to a 16-bit integer scale. at.raw = scaleAndShift(at.raw) if doFilter: # Create an FIR filter. filtWin = firwin(ntaps, cutoff, fs=at.fs, pass_zero=True) # Apply the FIR filter to each channel. for p in range(at.pktCount): for ch in range(at.writeChCount): # filteredSig = sig_convolve(at.raw[ch, p, :], # filtWin) x = at.raw[ch, p, :] x = x[sp.newaxis, :] filteredSig = np.array( [np_convolve(xi, filtWin, mode='same') for xi in x]) at.raw[ch, p, :] = filteredSig.copy() with open(filePath, 'w') as f: # Write the file header. line = '%s,%d\n' % (at.fileDateStr, at.fileNum) f.write(line) line = '%s\n%s\n%s\n' % (at.descript, at.minor, at.major) f.write(line) line = '%d,%d,%d,%d,%.2f\n' % (at.scanChCount, at.writeChCount, at.n, at.fs, at.xmitFund) f.write(line) line = '%.1f,%.1f\n' % (at.rCurrentMeas, at.rExtraSeries) f.write(line) line = '' for ch in range(at.writeChCount): line = line + at.measStr[ch] + ',' # Remove the last comma, and include a carriage return line feed. line = line[:-1] + '\n' f.write(line) line = float2lineStr(at.In5BHi, 3) f.write(line) line = float2lineStr(at.Out5BHi, 3) f.write(line) line = float2lineStr(at.ALoadQHi, 3) f.write(line) # Write packets of data to the file. cpuTimeStr = '133130.621' gpsDateStr = '000000' gpsTimeStr = '000000.000' lat = 'NaN' longi = 'NaN' maskUp = at.raw >= int215 maskDn = at.raw < int215 for p in range(at.pktCount): line = '$%d\n' % (p + 1) f.write(line) line = '\'%s,%s\n' % (at.fileDateStr, cpuTimeStr) f.write(line) line = '@%s,%s,%s,%s\n' % (gpsDateStr, gpsTimeStr, lat, longi) f.write(line) clipHi = sp.sum(at.raw[:, p, :] == (2**16 - 1), axis=1) line = float2lineStr(clipHi, 0) f.write(line) clipLo = sp.sum(at.raw[:, p, :] == 0, axis=1) line = float2lineStr(clipLo, 0) f.write(line) mean = sp.mean(at.raw[:, p, :], axis=1) mean = shiftAndScale(mean, int215) line = float2lineStr(mean, 1) f.write(line) meanUp = sp.zeros(at.writeChCount) meanDn = sp.zeros(at.writeChCount) for ch in range(at.writeChCount): meanUp[ch] = sp.mean(at.raw[ch, p, maskUp[ch, p, :]]) meanDn[ch] = sp.mean(at.raw[ch, p, maskDn[ch, p, :]]) meanUp = shiftAndScale(meanUp, int215) meanDn = shiftAndScale(meanDn, int215) line = float2lineStr(meanUp, 1) f.write(line) line = float2lineStr(meanDn, 1) f.write(line) countUp = sp.sum(maskUp[:, p, :], 1) line = float2lineStr(countUp, 0) f.write(line) countDn = sp.sum(maskDn[:, p, :], 1) line = float2lineStr(countDn, 0) f.write(line) for s in range(at.n): line = float2lineStr(at.raw[:, p, s], 0) f.write(line) # Asterisk character to end the packet. line = '*\n' f.write(line)
def ipArgand(instruct): # Whether to save the plot images. doSave = False plotThis = 'zPhase' pklFolder = instruct.pklFolder fileStart = cs.lastName(pklFolder) # Processed file choice. loadThis = 'zAnyF' # Channels plotted. ch = 2 # Whether to identify and plot target files. targetBool = True # Whether to manually select which file numbers to plot. manualTargetBool = True manualTargetArra = instruct.fileNums # Whether to plot all the files together without erasing at all. fileTogether = True # Whether to omit 60 Hz data from the plots. omit60Hz = True # Frequencies plotted. maskChoice = 'oddHUp2' isYAxStartedFromZero = False # Whether to subtract baseline phase results from separate files. subtract1 = False if subtract1: # Pick a standard packet range to use. pktRang = range(17) # Whether to include the minor note in the legend entries rather than the # title. minorLegBool = False # Whether to include the minor note anywhere at all. minorBool = True # Whether to swap the description and minor note text for display purposes. swapDescriptMinor = False legOutside = False loc = 'center right' stdBool = False # Whether to plot only one packet's results instead of an average over all # the packets in the file. onePkt = False # File number from which the plot title is taken. inf if it doesn't matter. titleFileNum = sp.inf # Let colors be selected automatically if files are plotted together. if fileTogether: color = None stdColor = None # Loading the data: fileName = fileStart + '_' + loadThis + '.pkl' filePath = os.path.join(pklFolder, fileName) with open(filePath, 'rb') as f: # Python 3: open(..., 'rb') a = pickle.load(f) # List of file numbers. fileNumArra = sp.zeros(len(a)) for t in range(len(a)): fileNumArra[t] = a[t].fileNum if swapDescriptMinor: descript = a[t].descript a[t].descript = a[t].minor a[t].minor = descript if targetBool: tarList = [] lowFilesA = sp.zeros(len(a), dtype=int) colorsA = len(a) * [''] linestylesA = len(a) * [''] legFilterA = sp.zeros(len(a), dtype=bool) for t in range(len(a)): if manualTargetBool: if any(a[t].fileNum == manualTargetArra): tarList.append(t) # Set up the low frequency normalization files for each file. manualIdx = cs.find(manualTargetArra, a[t].fileNum) lowFileNum = instruct.lowFiles[manualIdx] lowFilesA[t] = cs.find(fileNumArra, lowFileNum) colorsA[t] = instruct.colors[manualIdx] linestylesA[t] = instruct.linestyles[manualIdx] legFilterA[t] = instruct.legFilter[manualIdx] else: # Identify target files (They aren't baselines or tests). if a[t].descript != 'baseline' and a[t].descript != 'test': if t < (len(a) - 1): tarList.append(t) # Discover the maximum file number. maxFile = -sp.inf for t in range(len(a)): if a[t].fileNum > maxFile: maxFile = a[t].fileNum # Pick out the desired result data to be plotted as x and y values. res = [] for t in range(len(a)): # Result class for each possible file to be read. res.append(cs.emptyClass()) for t in tarList: if not subtract1 or not any(t == sp.array(tarList)): # (radian) phaseDiff = a[t].phaseDiff[ch, ...] / 1000 zMag = a[t].zMag[ch, ...] else: # Subtract the baseline phase differences. (radian) fileOff = 3 phaseDiff = (a[t].phaseDiff[ch, pktRang, :] - a[t - fileOff].phaseDiff[ch, pktRang, :]) / 1000 # Magnitudes. zMag = a[t].zMag[ch, pktRang, :] res[t].xVal = zMag * sp.cos(phaseDiff) res[t].yVal = zMag * sp.sin(phaseDiff) # Average over packets. if not onePkt: res[t].xVal = sp.mean(res[t].xVal, axis=0) res[t].yVal = sp.mean(res[t].yVal, axis=0) else: meanRang = instruct.pkt + sp.array([-1, 0, 1]) res[t].xVal = res[t].xVal[meanRang, :] res[t].yVal = res[t].yVal[meanRang, :] # Average over the chosen packet and those on either side. res[t].xVal = sp.mean(res[t].xVal, axis=0) res[t].yVal = sp.mean(res[t].yVal, axis=0) # Mask out unwanted frequencies. mask = sp.zeros_like(a[t].freq, dtype=bool) if maskChoice == 'oddHUp2': mask[4:len(mask):8] = True # Number of frequencies included in the plot. freqCount = 17 mask[(1 + 4 + 8 * (freqCount - 1)):] = False # Mask out 60 Hz, if requested. if omit60Hz: mask[a[t].freq == 60] = False res[t].xVal = res[t].xVal[mask] res[t].yVal = res[t].yVal[mask] # Result X and Y data normalized by the low freq. fundamental real # component of impedance. if t == lowFilesA[t]: maxReal1 = res[lowFilesA[t]].xVal[0] res[t].xVal /= maxReal1 res[t].yVal /= maxReal1 # If the phase difference baselines were subtracted, divide the # magnitudes. if subtract1 and any(t == sp.array(tarList)): baseMags = sp.sqrt(res[t - fileOff].xVal**2 + res[t - fileOff].yVal**2) res[t].xVal /= baseMags res[t].yVal /= baseMags # Renormalize. if t == lowFilesA[t]: maxReal2 = res[lowFilesA[t]].xVal[0] res[t].xVal /= maxReal2 res[t].yVal /= maxReal2 # Initialize plot settings. ps = cs.emptyClass() # Figure with axes. ps.color = color ps.stdColor = stdColor ps.markerSize = 5 ps.marker = 'o' ps.linestyle = '-' ps.markerSize = 4 ps.titleWrap = 83 ps.legOutside = legOutside ps.omit60Hz = omit60Hz ps.isYAxStartedFromZero = isYAxStartedFromZero ps.xLabel = 'REAL' ps.yLabel = 'IMAG' ps.stdBool = stdBool ps.normMag = False ps.loc = loc # List of file indices plotted. if targetBool: tList = tarList else: tList = range(0, len(a)) # List adjacent files with each target file, if there are three per plot. tarList = tList # Plot, and save if needed. for idx in range(len(tList)): t = tList[idx] tar = tarList[idx] ps.ch = ch ps.color = colorsA[t] ps.linestyle = linestylesA[t] # ps.titleStr = ('%s Ch %d (%s). xmitFund = %.0f Hz. %s' # % (a[t].fileDateStr, ch, a[t].measStr[ch], # a[t].xmitFund, a[t].major)) ps.titleStr = ('%s Ch %d (%s). xmitFund = %.0f Hz.' % (a[t].fileDateStr, ch, a[t].measStr[ch], a[t].xmitFund)) # ps.titleStr = ('Phase differences for artificial signals.') if onePkt: ps.titleStr += (' Results averaged over three packets centered ' 'on each packet listed in the legend.') if subtract1: ps.titleStr += ( ' Baseline sand phase angles have been subtracted, ' + 'and normalized magnitudes have been divided by ' + 'baseline normalized magnitudes before normalizing ' + 'to a low frequency real value of 1 again.') # Legend text. if legFilterA[t]: # With legend. ps.legStr = 'File %d. Ch %d. %s.' % (a[t].fileNum, ch, a[t].descript) if onePkt: ps.legStr = '(pkt %d) ' % (a[t].pkt[instruct.pkt]) + ps.legStr else: # Without legend. ps.legStr = '_nolegend_' if minorBool and (ps.legStr != '_nolegend_'): if not minorLegBool: if a[t].minor != 'None.': ps.titleStr += ' %s.' % (a[t].minor) else: ps.legStr += ' %s.' % (a[t].minor) # The plot title is taken from the target file. ps.titleBool = False if t == tar: if (titleFileNum == sp.inf) or (titleFileNum == a[t].fileNum): ps.titleBool = True if plotThis == 'argand': ps.titleStr += ' Normalized Apparent Impedance Argand.' ps.xVal = res[t].xVal ps.yVal = res[t].yVal elif plotThis == 'zMag': ps.xVal = a[t].freq[mask] ps.yVal = sp.sqrt(res[t].xVal**2 + res[t].yVal**2) if subtract1: ps.titleStr += ( ' Normalized magnitudes have been divided by ' + 'baseline normalized magnitudes before normalizing ' + 'to a low frequency real value of 1 again.') ps.xLabel = 'Frequency (Hz)' ps.yLabel = 'Impedance Magnitude (Normalized)' elif plotThis == 'zPhase': ps.xVal = a[t].freq[mask] # Milliradian ps.yVal = 1000 * sp.arctan2(res[t].yVal, res[t].xVal) ps.xLabel = 'Frequency (Hz)' ps.yLabel = 'Impedance Phase (mrad)' pw.basePlot(ps) if (t == tar): if ((not fileTogether) or (fileTogether and idx == len(tList) - 1)): if doSave: pass if not (t == tList[-1]): plt.clf() ax = plt.gca() if plotThis == 'argand': ax.set_aspect('equal', 'box') xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() if ps.isYAxStartedFromZero: if ymax > 0: ax.axis([xmin, xmax, 0, ymax]) else: ax.axis([0, xmax, ymin, 0])
def ipSurvey(): params = { 'legend.fontsize': 'x-large', 'figure.figsize': (9, 6.5), 'axes.labelsize': 'x-large', 'axes.titlesize': 'x-large', 'xtick.labelsize': 'x-large', 'ytick.labelsize': 'x-large' } plt.rcParams.update(params) # Class object holding plot settings. ps = cs.emptyClass() # Whether to save the plotted datasets to txt files. ps.saveTxt = False crop = True ps.folderPath = r'C:\temp\181112_eagle' folderName = cs.lastName(ps.folderPath) # Processed result choice. loadThis = 'zAnyF' # Read the depth information for each file. infoPath = os.path.join(ps.folderPath, 'depthInfo.txt') depthList = [] with open(infoPath, 'r') as f: for lidx, line in enumerate(f, 1): # Strip off trailing newline characters. line = line.rstrip('\n') # Split up comma-delimited information. (fileDateStr, fileNum, senseFt) = line.split(',') # Type casting. fileNum = int(fileNum) senseFt = float(senseFt) # (ft) # Add the depth of the sensor and convert to meter. depth = (2.5 + senseFt) / 3.28084 # (m) # Dump results in a list. depthList.append([fileDateStr, fileNum, depth]) # Loading the data. pklName = folderName + '_' + loadThis + '.pkl' filePath = os.path.join(ps.folderPath, pklName) with open(filePath, 'rb') as f: # Python 3: open(..., 'rb') a = pickle.load(f) # Crop information. if crop: cs.readCropInfo(a, ps.folderPath) # Plotting choice. ps.plotThis = 'zPhase' # Channel plotted. ps.ch = 1 # Harmonic number of the xmitFund plotted. ps.h = 13 # Index of the frequency in the list of odd harmonics. ps.freqIdx = 4 * ps.h # Whether the color axis bounds are set manually. manualColor = False clipColorData = True colMin = 185 colMax = 420 # Whether to plot line segments and points along the survey track. ps.showLines = False ps.showPts = False # Rectangle defined by coordinate extrema along longi and lat axes. ps.ext = mm.coordExtrema(a) # Offset distance to either side of the survey line color strip extends. ps.sideRange = 3.5 # (m) # Whether to plot in (longi, lat) or a projected reference. ps.plotWGS84 = False # The WGS84 latitude-longitude Coordinate Reference System (CRS). ps.crsWGS84 = {'init': 'epsg:4326'} # Define an azimuthal equidistant Coordinate Reference System (CRS). longiCent = (ps.ext.longiMax + ps.ext.longiMin) / 2 latCent = (ps.ext.latMax + ps.ext.latMin) / 2 longiCent = -122.50032907675 latCent = 47.617131187 ccrsAzEq = ccrs.AzimuthalEquidistant(central_longitude=longiCent, central_latitude=latCent) # This Cartopy CRS (CCRS) can be converted into a `proj4` string/dict # compatible with GeoPandas. ps.crsAzEq = ccrsAzEq.proj4_init # Initializations. ps.colMin = sp.inf ps.colMax = -sp.inf tList = range(len(a)) for t in tList: if a[t].pktCount > 0: # Join the longitude and latitude arrays into one matrix with two # columns. Col 0: longi, Col 1: lat. # (deg) a[t].fix = sp.transpose(sp.vstack((a[t].longi, a[t].lat))) # Associate a water depth with each fix at the ship location. for idx in range(len(depthList)): if a[t].fileNum == depthList[idx][1]: if a[t].fileDateStr == depthList[idx][0]: depth = depthList[idx][2] a[t].depth = depth * sp.ones_like(a[t].pkt) # (m) # Cable lead-length deployed. a[t].leadin = 57 # (m) # Pick which data to map to colors in the plot. if ps.plotThis == 'zPhase': a[t].color = a[t].phaseDiff[ps.ch, :, ps.freqIdx] # Despike phase differences with a threshold spike in mrad. # a[t].color = despike(a[t].color, 10) cbarLabel = 'Impedance Phase (mrad)' elif ps.plotThis == 'zMag': a[t].color = a[t].zMag[ps.ch, :, ps.freqIdx] # Despike magnitudes with a threshold spike in mOhm. # a[t].color = despike(a[t].color, 0.5) cbarLabel = 'Impedance Magnitude (m$\Omega$)' elif ps.plotThis == '2MagPhys': a[t].color = 2 * a[t].magPhys[ps.ch, :, ps.freqIdx] # a[t].color = despike(a[t].color, 0.01) if ps.ch == 0: cbarLabel = 'Twice Complex Mag. (A)' else: cbarLabel = 'Twice Complex Mag. (V)' elif ps.plotThis == 'zTime': freq = a[t].freq[ps.freqIdx] # (Hz) a[t].color = (a[t].phaseDiff[ps.ch, :, ps.freqIdx] / (2 * sp.pi * freq)) # (millisecond) # Despike phase differences with a threshold spike in us. # a[t].color = despike(a[t].color, 100) cbarLabel = 'v-i Time (ms)' # Edit the color data to clip at the manual bounds, if desired. if clipColorData: a[t].color[a[t].color < colMin] = colMin a[t].color[a[t].color > colMax] = colMax # Keep track of the maximum and minimum color values. arraMin = sp.amin(a[t].color) if arraMin < ps.colMin: ps.colMin = arraMin arraMax = sp.amax(a[t].color) if arraMax > ps.colMax: ps.colMax = arraMax # Manually set the min and max color values. if manualColor: ps.colMin = colMin ps.colMax = colMax ps.fig, ps.ax = plt.subplots() ps.ax.set_aspect('equal') ps.cmap = 'jet' ps.lineCol = 'k' # Color of the basic track line shape. for t in tList: if a[t].pktCount > 0: if not crop or (crop and sum(a[t].cropLogic) > 0): print('file %s_%d' % (a[t].fileDateStr, a[t].fileNum)) print(a[t].descript) plotStrip(a[t], ps, crop) # Keep axis bounds from before the shorelines are plotted. xlimLeft, xlimRight = plt.xlim() ylimLeft, ylimRight = plt.ylim() xlimLeft = -408.14159194218564 xlimRight = 383.2435609713969 ylimLeft = -375.3266408701022 ylimRight = 325.37655253272123 if ps.saveShape: # Save the geodataframes to files for colors and lines. polyFileName = 'ch%d_H%d_%s_%s_%d.txt' % ( ps.ch, ps.h, ps.plotThis, at.fileDateStr, at.fileNum, ) # Shoreline plotting. shoreline(ps) # Reset the axis bounds after shorelines are plotted. plt.xlim(xlimLeft, xlimRight) plt.ylim(ylimLeft, ylimRight) # Display the colormap in use as a sidebar colorbar. sm = plt.cm.ScalarMappable(cmap=ps.cmap, norm=plt.Normalize(vmin=ps.colMin, vmax=ps.colMax)) sm._A = [] # colorbar() requires a scalar mappable, "sm". cb = plt.colorbar(sm) cb.set_label(cbarLabel) # Axes labels. if not ps.plotWGS84: plt.xlabel('W-E (m)') plt.ylabel('S-N (m)') else: plt.xlabel('Longitude (deg)') plt.ylabel('Latitude (deg)') plt.grid(b=True) # Plot title. titleStr = ('%s Ch %d (%s). Harmonic %d = %.2f Hz. xmitFund = %.2f Hz.' % (a[0].fileDateStr, ps.ch, a[0].measStr[ps.ch], ps.h, ps.h * a[0].xmitFund, a[0].xmitFund)) if manualColor or clipColorData: if ps.plotThis == 'zPhase': titleStr += (' \nColors clipped at %d mrad and %d mrad.' % (ps.colMin, ps.colMax)) elif ps.plotThis == 'zMag': titleStr += ((' \nColors clipped at %.1f m$\Omega$ ' + 'and %.1f m$\Omega$.') % (ps.colMin, ps.colMax)) elif ps.plotThis == '2MagPhys': titleStr += ((' \nColors clipped at %.2f A ' + 'and %.2f A.') % (ps.colMin, ps.colMax)) elif ps.plotThis == 'zTime': titleStr += ((' \nColors clipped at %.2f ms ' + 'and %.2f ms.') % (ps.colMin, ps.colMax)) plt.title(titleStr)
def ipPlot(inFolder, inFileNums, inPlotThis): # Whether to save the plot images. doSave = False pklFolder = inFolder fileStart = cs.lastName(pklFolder) # Processed file choice. loadThis = 'zAnyF' # Plotting choice (y-axis). plotThis = inPlotThis # Plotting choice (x-axis). # 'freq': frequency (Hz). # 'phase': absolute phase (rad). xChoice = 'freq' # Frequency index to plot, if not plotting vs frequency. hChoice = 1 freqIdx1 = 4*hChoice # Channels plotted. chList = [6] # Whether to include the listed channels together in the same plots. chTogether = False # Whether to identify and plot target files. targetBool = True # Whether to manually select which file numbers to plot. manualTargetBool = True manualTargetArra = inFileNums # Number of files included in each plot. # 1: just one file. # 3: 3 files are included, one primary, and each of the two adjacent files. fileCount = 1 # Whether to subtract an average of results from the adjacent two files. subtractAdj = False # Whether to subtract one file's results from the target. subtract1 = False # Whether to plot all the files together without erasing at all. fileTogether = True # Whether to average over packets. meanBool = True if meanBool: # Whether to plot standard deviation envelopes. stdBool = True else: stdBool = False # Whether to plot all packets individually on the same plots. allPktBool = True if not allPktBool: # Which packet index to plot alone. pIso = 0 # Whether to omit 60 Hz data from the plots. omit60Hz = True # Frequencies plotted. maskChoice = 'oddHUp2' isYAxStartedFromZero = False # Whether to include the minor note anywhere at all. minorBool = False # Whether to include the minor note in the legend entries rather than the # title. minorLegBool = False # Whether to swap the description and minor note text for display purposes. swapDescriptMinor = False legOutside = False loc = 'best' if plotThis == 'zMag': # Whether to normalize the impedance magnitudes by the fundamental. normMag = False else: normMag = False # File number from which the plot title is taken. inf if it doesn't matter. titleFileNum = sp.inf # Colors for plotting main results. if plotThis == 'zPhase': color = 'Red' stdColor = 'Fuchsia' elif plotThis == 'zMag': color = 'Green' stdColor = 'LimeGreen' elif plotThis == '2MagPhys': color = 'DarkGoldenRod' stdColor = 'Gold' elif plotThis == 'inductance': color = None stdColor = None # Let colors be selected automatically if files are plotted together. if fileTogether: color = None stdColor = None if fileCount == 3: # Colors for plotting main results. color3 = ['Black', 'Blue', color] stdColor3 = ['Gray', 'DodgerBlue', stdColor] # Colors for plotting results on different channels. chColor = ['Black', 'SteelBlue', 'LimeGreen', 'Crimson', 'Green', 'DeepPink', 'BlueViolet', 'Orange'] chStdColor = ['Gray', 'SkyBlue', 'YellowGreen', 'Brown', 'ForestGreen', 'HotPink', 'DarkMagenta', 'Coral'] # Loading the data: fileName = fileStart + '_' + loadThis + '.pkl' filePath = os.path.join(pklFolder, fileName) with open(filePath, 'rb') as f: # Python 3: open(..., 'rb') a = pickle.load(f) # Pick out the desired result data to be plotted as x and y values. res = [] for t in range(len(a)): res.append(cs.emptyClass()) if xChoice == 'freq': # Frequencies along the x-axis. res[t].xVal = a[t].freq elif xChoice == 'phase': res[t].xVal = abs(abs(a[t].phase) - sp.pi/2) if plotThis == 'zPhase': res[t].yVal = a[t].phaseDiff elif plotThis == 'zMag': res[t].yVal = a[t].zMag elif plotThis == '2MagPhys': res[t].yVal = 2*a[t].magPhys elif plotThis == 'zTime': res[t].yVal = sp.zeros_like(a[t].phaseDiff) # Convert phase differences to time differences. for idx in range(len(a[t].freq)): freq = a[t].freq[idx] if freq != 0: # (microsecond) res[t].yVal[:, :, idx] = (10**3 * a[t].phaseDiff[:, :, idx] / (2 * sp.pi * freq)) elif plotThis == 'inductance': # Convert to estimates of the inductance in the circuit. r2 = 8.1 # Ohm r3 = sp.inf # initialization if sp.any(a[t].fileNum == sp.array([2, 5, 9, 10])): r3 = 1.0 # Ohm elif sp.any(a[t].fileNum == sp.array([3, 6, 11, 12])): r3 = 2.0 # Ohm # Matrix of inductance values. lMat = sp.zeros_like(a[t].phaseDiff) for p in range(a[t].pktCount): for freqIdx in range(len(a[t].freq)): omega = 2*sp.pi*a[t].freq[freqIdx] # (rad/s) # Solving the quadratic for L. # (rad) phaseDiff = a[t].phaseDiff[chList[0], p, freqIdx]/1000 tangent = sp.tan(phaseDiff) aQ = omega**2*tangent b = -omega*r2 c = r3*(r3 + r2)*tangent # (H) lMat[chList[0], p, freqIdx] = (-b - sp.sqrt(b**2 - 4*aQ*c) )/(2*aQ) # Convert to microHenry. lMat *= 1e6 # (uH) res[t].yVal = lMat if xChoice == 'freq': # Mask out unwanted frequencies. mask = sp.zeros_like(a[t].freq, dtype=bool) if maskChoice == 'oddH': # Save odd harmonics of the transmit fundamental. mask[4:len(mask):8] = True elif maskChoice == 'fund': mask[4] = True elif maskChoice == 'blockSine': mask[4:len(mask):8] = True mask[12:len(mask):24] = False elif maskChoice == 'oddHUp2': mask[4:len(mask):8] = True # Number of frequencies included in the plot. freqCount = 17 mask[(1+4+8*(freqCount-1)):] = False elif maskChoice == 'oddUp2': mask[1:len(mask):2] = True mask[10:] = False elif maskChoice == 'nonzero': mask[1:150] = True elif maskChoice == 'custom': mask[sp.array([4, 12, 20, 27, 35, 43, 51, 59, 66, 74, 82, 90, 98, 106, 113, 121, 129, 137, 145])] = True # Mask out 60 Hz, if requested. if omit60Hz: mask[a[t].freq == 60] = False res[t].xVal = res[t].xVal[mask] res[t].yVal = res[t].yVal[..., mask] if targetBool: tarList = [] for t in range(len(a)): if manualTargetBool: if any(a[t].fileNum == manualTargetArra): tarList.append(t) else: # Identify target files (They aren't baselines or tests). if a[t].descript != 'baseline' and a[t].descript != 'test': if t < (len(a) - 1): tarList.append(t) # List of file numbers. fileNumList = [] for t in range(len(a)): fileNumList.append(a[t].fileNum) if swapDescriptMinor: descript = a[t].descript a[t].descript = a[t].minor a[t].minor = descript # Initialize plot settings. ps = cs.emptyClass() # Figure with axes. ps.color = color ps.stdColor = stdColor ps.stdBool = stdBool ps.markerSize = 3 ps.marker = 'o' if xChoice == 'freq': ps.linestyle = 'solid' else: ps.linestyle = 'none' ps.markerSize = 4 ps.titleWrap = 75 ps.legOutside = legOutside ps.omit60Hz = omit60Hz ps.isYAxStartedFromZero = isYAxStartedFromZero ps.normMag = normMag ps.loc = loc if xChoice == 'freq': ps.xLabel = 'Frequency (Hz)' elif xChoice == 'phase': ps.xLabel = 'abs(abs(Phase) - pi/2) (rad)' if plotThis == 'zPhase': ps.yLabel = 'Impedance Phase (mrad)' if subtractAdj or subtract1: ps.yLabel = 'Phase Displacement from Baseline (mrad)' elif plotThis == 'zMag': if not normMag: ps.yLabel = 'Impedance Magnitude (m$\Omega$)' else: ps.yLabel = 'Impedance Magnitude (Normalized)' elif plotThis == '2MagPhys': if chList[0] == 0: ps.yLabel = 'Twice Complex Mag. (A)' else: ps.yLabel = 'Twice Complex Mag. (V)' elif plotThis == 'zTime': ps.yLabel = 'Voltage Lead Time ($\mu$s)' elif plotThis == 'inductance': ps.yLabel = 'Inductance L ($\mu$H)' # List of file indices plotted. if targetBool: tList = tarList else: tList = range(0, len(a)) # List adjacent files with each target file, if there are three per plot. if fileCount == 3: newTList = [] tarList = [] for t in tList: newTList.extend(t + sp.array([-1, 1, 0])) tarList.extend(3*[t]) tList = newTList del newTList else: tarList = tList # Plot, and save if needed. for idx in range(len(tList)): imgFolder = plotThis + str(fileCount) t = tList[idx] tar = tarList[idx] if False: if a[t].fileNum <= 10 + 2: ps.color = 'C0' elif a[t].fileNum <= 22 + 2: ps.color = 'C1' elif a[t].fileNum <= 34 + 2: ps.color = 'C2' for ch in chList: ps.ch = ch if chTogether: ps.color = chColor[ch] ps.stdColor = chStdColor[ch] ps.xVal = res[t].xVal if fileCount == 3: colorIdx = cs.find((t - tar) == [-1, 1, 0], True) ps.color = color3[colorIdx] ps.stdColor = stdColor3[colorIdx] # ps.titleStr = ('%s Ch %d (%s). xmitFund = %.2f Hz. %s' # % (a[t].fileDateStr, ch, a[t].measStr[ch], # a[t].xmitFund, a[t].major)) ps.titleStr = ('%s Ch %d (%s). %s' % (a[t].fileDateStr, ch, a[t].measStr[ch], a[t].major)) if xChoice == 'phase': ps.titleStr = ('Plotted freq. = %d Hz. ' % (a[t].freq[freqIdx1]) + ps.titleStr) # Linestyle choice. if a[t].minor == 'Sand.': ps.linestyle = '--' else: ps.linestyle = 'solid' # Legend text. if a[t].xmitFund == 1 and sp.mod(a[t].fileNum, 12) != 0: # With legend. ps.legStr = '%s' % (a[t].descript[:-6]) else: # Without legend. ps.legStr = '_nolegend_' # ps.legStr = ('%d. %s' % (a[t].fileNum, a[t].descript)) if chTogether: ps.titleStr = ('%s_%d %s. xmitFund = %.1f Hz. %s' % (a[t].fileDateStr, a[t].fileNum, a[t].descript, a[t].xmitFund, a[t].major)) ps.legStr = 'Ch %d (%s)' % (ch, a[t].measStr[ch]) if minorBool and (ps.legStr != '_nolegend_'): if not minorLegBool: ps.titleStr = '%s ' % (a[t].minor) + ps.titleStr else: ps.legStr = '%s ' % (a[t].minor) + ps.legStr # if not sp.any(a[t].fileNum == # (32 + sp.array([1, 3, 5, 7, 9, 11, 13, 15]))): # ps.legStr = '_nolegend_' # The plot title is taken from the target file. ps.titleBool = False if t == tar: if (titleFileNum == sp.inf) or (titleFileNum == a[t].fileNum): ps.titleBool = True imgFile = ('%s_ch%d_%d_%s' % (a[t].fileDateStr, ch, a[t].fileNum, plotThis)) if meanBool: # Result Y data. ps.yVal = res[t].yVal[ch, ...] # ps.legStr += ' (Avg. of %d packets)' % (a[t].pktCount) if stdBool: ps.titleStr += ' Shaded patches are means +/- 1 STD.' if not subtractAdj and not subtract1: pw.plot1Mean(ps) elif subtract1: ps.yValA = res[t-3].yVal[ch, ...] pw.plot1MeanSubtract1(ps) elif subtractAdj: ps.yValA = res[t-1].yVal[ch, ...] ps.yValB = res[t+1].yVal[ch, ...] pw.plot1MeanSubtractAdj(ps) else: if allPktBool: pList = sp.array(range(a[t].pktCount)) else: pList = sp.array([pIso]) if xChoice != 'freq': pList = sp.array([0]) for idx in range(len(pList)): p = pList[idx] if idx != 0: # Only the first packet in the list appears in the # legend. ps.legStr = '_nolegend_' else: if allPktBool: ps.legStr += '\n (%d packets)' % (a[t].pktCount) else: ps.legStr += ' (pkt %d)' % (a[t].pkt[p]) if xChoice != 'freq': # When x is not frequency. ps.xVal = res[t].xVal[ch, :, freqIdx1] ps.yVal = res[t].yVal[ch, :, freqIdx1] else: ps.yVal = res[t].yVal[ch, p, :] pw.basePlot(ps) if (t == tar): if (not chTogether) or (chTogether and ch == chList[-1]): if ((not fileTogether) or (fileTogether and idx == len(tList) - 1)): if doSave: cs.saveImg(pklFolder, imgFolder, imgFile) if not ((t == tList[-1]) and (ch == chList[-1])): plt.clf() ax = plt.gca() xmin, xmax = plt.xlim() ymin, ymax = plt.ylim() # plt.xscale('log') if ps.isYAxStartedFromZero: if ymax > 0: ax.axis([xmin, xmax, 0, ymax]) else: ax.axis([xmin, xmax, ymin, 0])
def circuitTheory(meas='R1', plotThis='zPhase'): ci = cs.emptyClass() # Resistors. (Ohm) ci.r1 = 0.1 ci.r2 = 0.1 ci.r3 = ci.r2 ci.r4 = 8 # Capacitor. (F) ci.c = 3e-3 ci.meas = meas ci.plotThis = plotThis # Transmit current. Phase = 0. (complex A) ci.i1 = 1 # Transmit frequency list. (Hz) xmitFund = 4 freqList = sp.array(range(xmitFund, xmitFund*(100 + 1), 2*xmitFund)) result = sp.zeros_like(freqList) for idx in range(len(freqList)): # Frequency. (Hz) ci.f = freqList[idx] # Convert to milliUnits. result[idx] = 10**3*circuitSolve(ci) params = {'legend.fontsize': 'x-large', 'figure.figsize': (9, 6.5), 'axes.labelsize': 'x-large', 'axes.titlesize': 'x-large', 'xtick.labelsize': 'x-large', 'ytick.labelsize': 'x-large'} plt.rcParams.update(params) ps = cs.emptyClass() ps.color = None ps.markerSize = 3 ps.marker = 'o' ps.legStr = meas if meas == 'z_t': ps.legStr = 'Z_Target' ps.linestyle = 'solid' ps.titleStr = ('Resistors (Ohm): R1 = %.1f, R2 = %.1f, R3 = %.1f, ' 'R4 = %.0f. Capacitor: C = %.0f mF. ' 'Z_Target is the parallel impedance of R4 and C.' % (ci.r1, ci.r2, ci.r3, ci.r4, ci.c*10**3)) ps.titleWrap = 75 ps.titleBool = True ps.xLabel = 'Frequency (Hz)' if plotThis == 'zPhase': ps.yLabel = 'Voltage Phase Shift from Transmit Current (mrad)' elif plotThis == 'zMag': ps.yLabel = 'Voltage Magnitude (mV)' ps.legOutside = False # Plot the main result. lines2D = plt.plot(freqList, result, color=ps.color, markersize=ps.markerSize, marker=ps.marker, label=ps.legStr, linestyle=ps.linestyle) titleStr = ps.titleStr if ps.titleWrap < sp.inf: # Wrap text at a set character length. titleStr = '\n'.join(wrap(titleStr, ps.titleWrap)) if ps.titleBool: plt.title(titleStr) plt.xlabel(ps.xLabel) plt.ylabel(ps.yLabel) if ps.legOutside: plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left") plt.subplots_adjust(right=0.75) else: plt.legend(loc="best") plt.tight_layout() plt.grid(b=True) plt.show()