def isWritable(layer): if isInvalid(layer) or len(layer.vectorJoins()) > 0: return False if layer.storageType() == 'ESRI Shapefile': sourceList = layer.source().split('|') shpFile = QFileInfo(sourceList[0]) baseFilePath = shpFile.canonicalPath() + '/' + shpFile.completeBaseName() shxFile = QFileInfo(baseFilePath + '.shx') dbfFile = QFileInfo(baseFilePath + '.dbf') return (shpFile.exists() and shpFile.isWritable() and shxFile.exists() and shxFile.isWritable() and dbfFile.exists() and dbfFile.isWritable()) return True
def isWritable(layer): if isInvalid(layer) or len(layer.vectorJoins()) > 0: return False if layer.storageType() == 'ESRI Shapefile': sourceList = layer.source().split('|') shpFile = QFileInfo(sourceList[0]) baseFilePath = shpFile.canonicalPath( ) + '/' + shpFile.completeBaseName() shxFile = QFileInfo(baseFilePath + '.shx') dbfFile = QFileInfo(baseFilePath + '.dbf') return (shpFile.exists() and shpFile.isWritable() and shxFile.exists() and shxFile.isWritable() and dbfFile.exists() and dbfFile.isWritable()) return True
def fill_media_location(self): caption = _('Select media location') selected = unicode(QFileDialog.getExistingDirectory(self, caption)) if not selected: return info = QFileInfo(selected) if not info.isReadable(): self.main_widget().layout().addWidget( self.not_accessible_media_path_label, 13, 1, 1, 4) return if not info.isWritable(): self.main_widget().layout().addWidget( self.not_writable_media_path_label, 13, 1, 1, 4) return self.media_location_editor.setText(selected)
def processFile(self,fullPath): fileName, fileExtension = os.path.splitext(fullPath) fileName = os.path.basename(fullPath) self.fileNames.append(fileName) if fileExtension == '.csv': delimiter = ',' else: delimiter = None self.ui.statusbar.showMessage("processing: "+ fileName,2500) #wait here for the file to be completely written to disk and closed before trying to read it fi = QFileInfo(fullPath) while (not fi.isWritable()): time.sleep(0.001) fi.refresh() fp = open(fullPath, mode='r') fileBuffer = fp.read() fp.close() first10 = fileBuffer[0:10] nMcHeaderLines = 25 #number of header lines in mcgehee IV file format isMcFile = False #true if this is a McGehee iv file format if (not first10.__contains__('#')) and (first10.__contains__('/')) and (first10.__contains__('\t')):#the first line is not a comment #the first 8 chars do not contain comment symbol and do contain / and a tab, it's safe to assume mcgehee iv file format isMcFile = True #comment out the first 25 rows here fileBuffer = '#'+fileBuffer fileBuffer = fileBuffer.replace('\n', '\n#',nMcHeaderLines-1) splitBuffer = fileBuffer.splitlines(True) area = 1 noArea = True vsTime = False #this is not an i,v vs t data file #extract header lines and search for area header = [] for line in splitBuffer: if line.startswith('#'): header.append(line) if line.__contains__('Area'): area = float(line.split(' ')[3]) noArea = False if line.__contains__('I&V vs t'): if float(line.split(' ')[5]) == 1: vsTime = True else: break outputScaleFactor = np.array(1000/area) #for converstion to [mA/cm^2] tempFile = QTemporaryFile() tempFile.open() tempFile.writeData(fileBuffer) tempFile.flush() #read in data try: data = np.loadtxt(str(tempFile.fileName()),delimiter=delimiter) VV = data[:,0] II = data[:,1] if vsTime: time = data[:,2] except: self.ui.statusbar.showMessage('Could not read' + fileName +'. Prepend # to all non-data lines and try again',2500) return tempFile.close() tempFile.remove() if isMcFile: #convert to amps II = II/1000*area if not vsTime: #sort data by ascending voltage newOrder = VV.argsort() VV=VV[newOrder] II=II[newOrder] #remove duplicate voltage entries VV, indices = np.unique(VV, return_index =True) II = II[indices] else: #sort data by ascending time newOrder = time.argsort() VV=VV[newOrder] II=II[newOrder] time=time[newOrder] time=time-time[0]#start time at t=0 #catch and fix flipped current sign: if II[0] < II[-1]: II = II * -1 indexInQuad1 = np.logical_and(VV>0,II>0) if any(indexInQuad1): #enters statement if there is at least one datapoint in quadrant 1 isDarkCurve = False else: self.ui.statusbar.showMessage("Dark curve detected",500) isDarkCurve = True #put items in table self.ui.tableWidget.insertRow(self.rows) for ii in range(len(self.cols)): self.ui.tableWidget.setItem(self.rows,ii,QTableWidgetItem()) if not vsTime: fitParams, fitCovariance, infodict, errmsg, ier = self.bestEffortFit(VV,II) #print errmsg I0_fit = fitParams[0] Iph_fit = fitParams[1] Rs_fit = fitParams[2] Rsh_fit = fitParams[3] n_fit = fitParams[4] #0 -> LS-straight line #1 -> cubic spline interpolant smoothingParameter = 1-2e-6 iFitSpline = SmoothSpline(VV, II, p=smoothingParameter) def cellModel(voltageIn): #voltageIn = np.array(voltageIn) return vectorizedCurrent(voltageIn, I0_fit, Iph_fit, Rs_fit, Rsh_fit, n_fit) def invCellPowerSpline(voltageIn): if voltageIn < 0: return 0 else: return -1*voltageIn*iFitSpline(voltageIn) def invCellPowerModel(voltageIn): if voltageIn < 0: return 0 else: return -1*voltageIn*cellModel(voltageIn) if not isDarkCurve: VVq1 = VV[indexInQuad1] IIq1 = II[indexInQuad1] vMaxGuess = VVq1[np.array(VVq1*IIq1).argmax()] powerSearchResults = optimize.minimize(invCellPowerSpline,vMaxGuess) #catch a failed max power search: if not powerSearchResults.status == 0: print "power search exit code = " + str(powerSearchResults.status) print powerSearchResults.message vMax = nan iMax = nan pMax = nan else: vMax = powerSearchResults.x[0] iMax = iFitSpline([vMax])[0] pMax = vMax*iMax #only do this stuff if the char eqn fit was good if ier < 5: powerSearchResults_charEqn = optimize.minimize(invCellPowerModel,vMaxGuess) #catch a failed max power search: if not powerSearchResults_charEqn.status == 0: print "power search exit code = " + str(powerSearchResults_charEqn.status) print powerSearchResults_charEqn.message vMax_charEqn = nan else: vMax_charEqn = powerSearchResults_charEqn.x[0] #dude try: Voc_nn_charEqn=optimize.brentq(cellModel, VV[0], VV[-1]) except: Voc_nn_charEqn = nan else: Voc_nn_charEqn = nan vMax_charEqn = nan try: Voc_nn = optimize.brentq(iFitSpline, VV[0], VV[-1]) except: Voc_nn = nan else: Voc_nn = nan vMax = nan iMax = nan pMax = nan Voc_nn_charEqn = nan vMax_charEqn = nan iMax_charEqn = nan pMax_charEqn = nan if ier < 5: dontFindBounds = False iMax_charEqn = cellModel([vMax_charEqn])[0] pMax_charEqn = vMax_charEqn*iMax_charEqn Isc_nn_charEqn = cellModel(0) FF_charEqn = pMax_charEqn/(Voc_nn_charEqn*Isc_nn_charEqn) else: dontFindBounds = True iMax_charEqn = nan pMax_charEqn = nan Isc_nn_charEqn = nan FF_charEqn = nan #there is a maddening bug in SmoothingSpline: it can't evaluate 0 alone, so I have to do this: try: Isc_nn = iFitSpline([0,1e-55])[0] except: Isc_nn = nan FF = pMax/(Voc_nn*Isc_nn) if (ier != 7) and (ier != 6) and (not dontFindBounds) and (type(fitCovariance) is not float): #error estimation: alpha = 0.05 # 95% confidence interval = 100*(1-alpha) nn = len(VV) # number of data points p = len(fitParams) # number of parameters dof = max(0, nn - p) # number of degrees of freedom # student-t value for the dof and confidence level tval = t.ppf(1.0-alpha/2., dof) lowers = [] uppers = [] #calculate 95% confidence interval for a, p,var in zip(range(nn), fitParams, np.diag(fitCovariance)): sigma = var**0.5 lower = p - sigma*tval upper = p + sigma*tval lowers.append(lower) uppers.append(upper) else: uppers = [nan,nan,nan,nan,nan] lowers = [nan,nan,nan,nan,nan] plotPoints = 1000 fitX = np.linspace(VV[0],VV[-1],plotPoints) if ier < 5: modelY = cellModel(fitX)*outputScaleFactor else: modelY = np.empty(plotPoints)*nan splineY = iFitSpline(fitX)*outputScaleFactor graphData = {'vsTime':vsTime,'origRow':self.rows,'fitX':fitX,'modelY':modelY,'splineY':splineY,'i':II*outputScaleFactor,'v':VV,'Voc':Voc_nn,'Isc':Isc_nn*outputScaleFactor,'Vmax':vMax,'Imax':iMax*outputScaleFactor} #export button exportBtn = QPushButton(self.ui.tableWidget) exportBtn.setText('Export') exportBtn.clicked.connect(self.handleButton) self.ui.tableWidget.setCellWidget(self.rows,self.cols.keys().index('exportBtn'), exportBtn) self.ui.tableWidget.item(self.rows,self.cols.keys().index('pce')).setData(Qt.DisplayRole,round(pMax/area*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('pce')).setToolTip(str(round(pMax_charEqn/area*1e3,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax')).setData(Qt.DisplayRole,round(pMax/area*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax')).setToolTip(str(round(pMax_charEqn/area*1e3,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('jsc')).setData(Qt.DisplayRole,round(Isc_nn/area*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('jsc')).setToolTip(str(round(Isc_nn_charEqn/area*1e3,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('voc')).setData(Qt.DisplayRole,round(Voc_nn*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('voc')).setToolTip(str(round(Voc_nn_charEqn*1e3,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('ff')).setData(Qt.DisplayRole,round(FF,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('ff')).setToolTip(str(round(FF_charEqn,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs')).setData(Qt.DisplayRole,round(Rs_fit*area,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs')).setToolTip('[{0} {1}]'.format(lowers[2]*area, uppers[2]*area)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh')).setData(Qt.DisplayRole,round(Rsh_fit*area,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh')).setToolTip('[{0} {1}]'.format(lowers[3]*area, uppers[3]*area)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('jph')).setData(Qt.DisplayRole,round(Iph_fit/area*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('jph')).setToolTip('[{0} {1}]'.format(lowers[1]/area*1e3, uppers[1]/area*1e3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('j0')).setData(Qt.DisplayRole,round(I0_fit/area*1e9,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('j0')).setToolTip('[{0} {1}]'.format(lowers[0]/area*1e9, uppers[0]/area*1e9)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('n')).setData(Qt.DisplayRole,round(n_fit,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('n')).setToolTip('[{0} {1}]'.format(lowers[4], uppers[4])) self.ui.tableWidget.item(self.rows,self.cols.keys().index('Vmax')).setData(Qt.DisplayRole,round(vMax*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('Vmax')).setToolTip(str(round(vMax_charEqn*1e3,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('area')).setData(Qt.DisplayRole,round(area,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax2')).setData(Qt.DisplayRole,round(pMax*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('pmax2')).setToolTip(str(round(pMax_charEqn*1e3,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('isc')).setData(Qt.DisplayRole,round(Isc_nn*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('isc')).setToolTip(str(round(Isc_nn_charEqn*1e3,3))) self.ui.tableWidget.item(self.rows,self.cols.keys().index('iph')).setData(Qt.DisplayRole,round(Iph_fit*1e3,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('iph')).setToolTip('[{0} {1}]'.format(lowers[1]*1e3, uppers[1]*1e3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('i0')).setData(Qt.DisplayRole,round(I0_fit*1e9,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('i0')).setToolTip('[{0} {1}]'.format(lowers[0]*1e9, uppers[0]*1e9)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs2')).setData(Qt.DisplayRole,round(Rs_fit,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rs2')).setToolTip('[{0} {1}]'.format(lowers[2], uppers[2])) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh2')).setData(Qt.DisplayRole,round(Rsh_fit,3)) self.ui.tableWidget.item(self.rows,self.cols.keys().index('rsh2')).setToolTip('[{0} {1}]'.format(lowers[3], uppers[3])) else:#vs time graphData = {'vsTime':vsTime,'origRow':self.rows,'time':time,'i':II*outputScaleFactor,'v':VV} #file name self.ui.tableWidget.item(self.rows,self.cols.keys().index('file')).setText(fileName) self.ui.tableWidget.item(self.rows,self.cols.keys().index('file')).setToolTip(''.join(header)) #plot button plotBtn = QPushButton(self.ui.tableWidget) plotBtn.setText('Plot') plotBtn.clicked.connect(self.handleButton) self.ui.tableWidget.setCellWidget(self.rows,self.cols.keys().index('plotBtn'), plotBtn) self.ui.tableWidget.item(self.rows,self.cols.keys().index('plotBtn')).setData(Qt.UserRole,graphData) self.ui.tableWidget.resizeColumnsToContents() self.rows = self.rows + 1