Commit 48dddf1d authored by Lars Bittrich's avatar Lars Bittrich

bugfixes in particle analysis

parent 545f462e
...@@ -456,6 +456,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): ...@@ -456,6 +456,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
#draw Sample Spectrum #draw Sample Spectrum
specIndex = self.currentSpectrumIndex specIndex = self.currentSpectrumIndex
spectra = self.datastats.spectra spectra = self.datastats.spectra
particlestats = self.datastats.getParticleStats()
self.spec_ax.axis("on") self.spec_ax.axis("on")
self.spec_ax.clear() self.spec_ax.clear()
self.spec_ax.plot(spectra[:, 0], spectra[:, specIndex+1]) self.spec_ax.plot(spectra[:, 0], spectra[:, specIndex+1])
...@@ -463,7 +464,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): ...@@ -463,7 +464,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
self.spec_ax.set_xlabel('Wavenumber (cm-1)', fontsize = 15) self.spec_ax.set_xlabel('Wavenumber (cm-1)', fontsize = 15)
self.spec_ax.set_ylabel('Counts', fontsize = 15) self.spec_ax.set_ylabel('Counts', fontsize = 15)
self.spec_ax.set_title('ScanPoint Number {}, Size = {} µm'.format(specIndex+1, self.spec_ax.set_title('ScanPoint Number {}, Size = {} µm'.format(specIndex+1,
np.round(self.datastats.particlestats[self.currentParticleIndex][2], 1))) np.round(particlestats[self.currentParticleIndex][2], 1)))
self.spec_ax.set_xbound(100, (3400 if spectra[-1, 0] > 3400 else spectra[-1, 0])) self.spec_ax.set_xbound(100, (3400 if spectra[-1, 0] > 3400 else spectra[-1, 0]))
wavenumber_diff = list(spectra[:, 0]-100) wavenumber_diff = list(spectra[:, 0]-100)
y_start = wavenumber_diff.index(min(wavenumber_diff)) y_start = wavenumber_diff.index(min(wavenumber_diff))
...@@ -498,8 +499,8 @@ class ParticleAnalysis(QtWidgets.QMainWindow): ...@@ -498,8 +499,8 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
if uniquePolymers is not None: if uniquePolymers is not None:
#the index is the contour index, find particle index: #the index is the contour index, find particle index:
specIndex = self.datastats.particles2spectra[index][0] #select first spectrum of partoicle specIndex = self.datastats.particles2spectra[index][0] #select first spectrum of partoicle
self.datastats.currentParticleIndex = index self.currentParticleIndex = index
self.datastats.currentSpectrumIndex = specIndex self.currentSpectrumIndex = specIndex
selectedPolymer = self.datastats.currentPolymers[specIndex] selectedPolymer = self.datastats.currentPolymers[specIndex]
try: try:
...@@ -649,7 +650,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): ...@@ -649,7 +650,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow):
#general size histogram #general size histogram
self.bins = np.logspace(0.1, 3, 20) self.bins = np.logspace(0.1, 3, 20)
self.sizes = [i[0] if np.isnan(i[2]) else i[2] for i in self.datastats.particlestats] #extract long size (if ellipse fit is nan -> box fit) self.sizes = [i[0] if np.isnan(i[2]) else i[2] for i in self.datastats.getParticleStats()] #extract long size (if ellipse fit is nan -> box fit)
sizehist = np.histogram(self.sizes, self.bins) sizehist = np.histogram(self.sizes, self.bins)
self.totalhistx = [] self.totalhistx = []
for i in range(19): for i in range(19):
......
...@@ -36,7 +36,7 @@ class ExpExcelDialog(QtWidgets.QDialog): ...@@ -36,7 +36,7 @@ class ExpExcelDialog(QtWidgets.QDialog):
self.setGeometry(200,200, 300, 300) self.setGeometry(200,200, 300, 300)
self.datastats = datastats self.datastats = datastats
self.particles = self.datastats.particlestats self.particles = self.datastats.getParticleStats()
self.polymers = self.datastats.particleResults self.polymers = self.datastats.particleResults
self.additives = self.datastats.currentAdditives self.additives = self.datastats.currentAdditives
self.hqis = self.datastats.hqis self.hqis = self.datastats.hqis
......
...@@ -41,7 +41,6 @@ class DataStats(object): ...@@ -41,7 +41,6 @@ class DataStats(object):
self.spectraResults = None #entire List of all spectra assignments self.spectraResults = None #entire List of all spectra assignments
self.additiveResults = None #entire List of all additives self.additiveResults = None #entire List of all additives
self.particlestats = None
self.particleResults = None #final assignment for each particle self.particleResults = None #final assignment for each particle
self.currentPolymers = None #list of polymers after setting entries with low hqi to unknown self.currentPolymers = None #list of polymers after setting entries with low hqi to unknown
...@@ -113,15 +112,6 @@ class DataStats(object): ...@@ -113,15 +112,6 @@ class DataStats(object):
return specs return specs
def loadParticleData(self): def loadParticleData(self):
self.particlestats = np.array(self.dataset.particlestats)
pixelscale = self.dataset.getPixelScale()
#convert to mikrometer scale
for index in range(len(self.particlestats)):
for subindex in range(5):
self.particlestats[index][subindex] = self.particlestats[index][subindex] * pixelscale #multiply by pixelscale
if subindex == 4:
self.particlestats[index][subindex] = self.particlestats[index][subindex] * pixelscale #again for the area...
self.particles2spectra = self.dataset.particles2spectra self.particles2spectra = self.dataset.particles2spectra
sortindices = self.dataset.ramanscansortindex sortindices = self.dataset.ramanscansortindex
...@@ -161,12 +151,21 @@ class DataStats(object): ...@@ -161,12 +151,21 @@ class DataStats(object):
return None return None
return self.uniquePolymers return self.uniquePolymers
def getParticleStats(self):
particlestats = np.array(self.dataset.particlestats)
pixelscale = self.dataset.getPixelScale()
#convert to mikrometer scale
particlestats[:,:5] *= pixelscale
particlestats[:,4] *= pixelscale #again for the area...
return particlestats
def createHistogramData(self): def createHistogramData(self):
particlestats = self.getParticleStats()
self.uniquePolymers = np.unique(self.currentPolymers) self.uniquePolymers = np.unique(self.currentPolymers)
self.particleResults = [None]*len(self.particlestats) self.particleResults = [None]*len(particlestats)
self.typehistogram = {i: 0 for i in self.uniquePolymers} self.typehistogram = {i: 0 for i in self.uniquePolymers}
if len(self.particles2spectra) != len(self.particlestats): if len(self.particles2spectra) != len(particlestats):
return False return False
for particleID, specList in enumerate(self.particles2spectra): for particleID, specList in enumerate(self.particles2spectra):
......
...@@ -57,8 +57,6 @@ class ParticleEditor(object): ...@@ -57,8 +57,6 @@ class ParticleEditor(object):
return return
contourIndices = sorted(contourIndices) #we want to keep the contour with lowest index contourIndices = sorted(contourIndices) #we want to keep the contour with lowest index
print('merging contours:', contourIndices)
self.createSafetyBackup()
#get contours: #get contours:
contours = [self.datastats.dataset.particlecontours[i] for i in contourIndices] contours = [self.datastats.dataset.particlecontours[i] for i in contourIndices]
cnt = np.vstack(tuple(contours)) #combine contous cnt = np.vstack(tuple(contours)) #combine contous
...@@ -73,7 +71,7 @@ class ParticleEditor(object): ...@@ -73,7 +71,7 @@ class ParticleEditor(object):
img = np.zeros((rangey, rangex)) img = np.zeros((rangey, rangex))
for i in contourIndices: for i in contourIndices:
curCnt = self.datastats.dataset.particlecontours[i] curCnt = self.datastats.dataset.particlecontours[i].copy()
for i in range(len(curCnt)): for i in range(len(curCnt)):
curCnt[i][0][0] -= xmin-padding curCnt[i][0][0] -= xmin-padding
curCnt[i][0][1] -= ymin-padding curCnt[i][0][1] -= ymin-padding
...@@ -88,6 +86,11 @@ class ParticleEditor(object): ...@@ -88,6 +86,11 @@ class ParticleEditor(object):
else: else:
temp, contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE) temp, contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
if len(contours)>1:
QtWidgets.QMessageBox.critical(self.parent, 'ERROR!',
'Particle contours are not connected and cannot be combined!')
return
newContour = contours[0] newContour = contours[0]
stats = self.characterizeParticle(newContour) stats = self.characterizeParticle(newContour)
...@@ -95,6 +98,8 @@ class ParticleEditor(object): ...@@ -95,6 +98,8 @@ class ParticleEditor(object):
newContour[i][0][0] += xmin-padding newContour[i][0][0] += xmin-padding
newContour[i][0][1] += ymin-padding newContour[i][0][1] += ymin-padding
print('merging contours:', contourIndices)
self.createSafetyBackup()
#check, if dataset contains (already modified) particle2spectra, otherwise create new. #check, if dataset contains (already modified) particle2spectra, otherwise create new.
if self.datastats.dataset.particles2spectra is None: #create default assignment if self.datastats.dataset.particles2spectra is None: #create default assignment
...@@ -134,6 +139,9 @@ class ParticleEditor(object): ...@@ -134,6 +139,9 @@ class ParticleEditor(object):
print('removing index from particles2spectra:', index) print('removing index from particles2spectra:', index)
del self.datastats.dataset.particles2spectra[index] del self.datastats.dataset.particles2spectra[index]
#update contours in sampleview
self.parent.parent.contouritem.resetContours(self.datastats.dataset.particlecontours)
self.parent.loadParticleData()
#save data #save data
minHQI = self.parent.hqiSpinBox.value() minHQI = self.parent.hqiSpinBox.value()
compHQI = self.parent.compHqiSpinBox.value() compHQI = self.parent.compHqiSpinBox.value()
...@@ -142,9 +150,6 @@ class ParticleEditor(object): ...@@ -142,9 +150,6 @@ class ParticleEditor(object):
'Data inconsistency after saving!', QtWidgets.QMessageBox.Ok, 'Data inconsistency after saving!', QtWidgets.QMessageBox.Ok,
QtWidgets.QMessageBox.Ok) QtWidgets.QMessageBox.Ok)
#update contours in sampleview
self.parent.parent.contouritem.resetContours(self.datastats.dataset.particlecontours)
self.parent.loadParticleData()
def reassignParticles(self, contourindices, new_assignment): def reassignParticles(self, contourindices, new_assignment):
...@@ -161,6 +166,9 @@ class ParticleEditor(object): ...@@ -161,6 +166,9 @@ class ParticleEditor(object):
self.datastats.spectraResults[specIndex] = new_assignment self.datastats.spectraResults[specIndex] = new_assignment
self.datastats.hqis[specIndex] = 100 self.datastats.hqis[specIndex] = 100
#update contours in sampleview
self.parent.parent.contouritem.resetContours(self.datastats.dataset.particlecontours)
self.parent.loadParticleData()
#save data #save data
minHQI = self.parent.hqiSpinBox.value() minHQI = self.parent.hqiSpinBox.value()
compHQI = self.parent.compHqiSpinBox.value() compHQI = self.parent.compHqiSpinBox.value()
...@@ -168,8 +176,6 @@ class ParticleEditor(object): ...@@ -168,8 +176,6 @@ class ParticleEditor(object):
QtWidgets.QMessageBox.warning(self.parent, 'Error!', QtWidgets.QMessageBox.warning(self.parent, 'Error!',
'Data inconsistency after saving!', 'Data inconsistency after saving!',
QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok) QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
self.parent.loadParticleData()
def deleteParticles(self): def deleteParticles(self):
......
...@@ -21,16 +21,16 @@ class SQLExport(QtWidgets.QDialog): ...@@ -21,16 +21,16 @@ class SQLExport(QtWidgets.QDialog):
self.datastats = datastats self.datastats = datastats
self.polymerList = self.datastats.particleResults self.polymerList = self.datastats.particleResults
self.longSizes = np.round(np.array([i[0] if np.isnan(i[2]) else i[2] for i in self.datastats.particlestats]), 1) particlestats = self.datastats.getParticleStats()
self.shortSize = np.round(np.array([i[1] if np.isnan(i[3]) else i[3] for i in self.datastats.particlestats]), 1) self.longSizes = np.round(np.array([i[0] if np.isnan(i[2]) else i[2] for i in particlestats]), 1)
self.shortSize = np.round(np.array([i[1] if np.isnan(i[3]) else i[3] for i in particlestats]), 1)
#spectra can be quite some data size, they are not copied here but referenced later on... #spectra can be quite some data size, they are not copied here but referenced later on...
self.particleImages = None self.particleImages = None
self.log = [] self.log = []
configfilename = os.path.join(os.path.dirname(os.path.split(__file__)[0]), configfilename = os.path.join(os.path.split(__file__)[0], 'database_config.txt')
'database_config.txt')
if not os.path.exists(configfilename): if not os.path.exists(configfilename):
QtWidgets.QMessageBox.warning(self, 'Warning!', QtWidgets.QMessageBox.warning(self, 'Warning!',
...@@ -338,6 +338,9 @@ class SQLExport(QtWidgets.QDialog): ...@@ -338,6 +338,9 @@ class SQLExport(QtWidgets.QDialog):
self.cnx = mysql.connector.connect(**self.config) #port: 3306 self.cnx = mysql.connector.connect(**self.config) #port: 3306
except mysql.connector.Error as err: except mysql.connector.Error as err:
print(err) print(err)
QtWidgets.QMessageBox.warning(self, 'Error!',
str(err),
QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
self.cnx = None self.cnx = None
def getEntireTable(self, tablename): def getEntireTable(self, tablename):
......
...@@ -54,11 +54,13 @@ def saveData(dataset, fname): ...@@ -54,11 +54,13 @@ def saveData(dataset, fname):
dataset.zvalimg = zvalimg dataset.zvalimg = zvalimg
def arrayCompare(a1, a2): def arrayCompare(a1, a2):
if a1.shape!=a2.shape:
return False
if a1.dtype!=np.float32 and a1.dtype!=np.float64:
return np.all(a1==a2)
ind = np.isnan(a1) ind = np.isnan(a1)
if not np.any(ind): if not np.any(ind):
return np.all(a1==a2) return np.all(a1==a2)
if a1.shape!=a2.shape:
return False
return np.all(a1[~ind]==a2[~ind]) return np.all(a1[~ind]==a2[~ind])
def listCompare(l1, l2): def listCompare(l1, l2):
...@@ -78,10 +80,11 @@ def listCompare(l1, l2): ...@@ -78,10 +80,11 @@ def listCompare(l1, l2):
def recursiveDictCompare(d1, d2): def recursiveDictCompare(d1, d2):
for key in d1: for key in d1:
if not key in d2: if not key in d2:
print("key missing in d2:", key, flush=True)
return False return False
a = d1[key] a = d1[key]
b = d2[key] b = d2[key]
print(key, type(a), type(b)) print(key, type(a), type(b), flush=True)
if isinstance(a, np.ndarray): if isinstance(a, np.ndarray):
if not isinstance(b, np.ndarray) or not arrayCompare(a, b): if not isinstance(b, np.ndarray) or not arrayCompare(a, b):
print("data is different!", a, b) print("data is different!", a, b)
...@@ -97,8 +100,9 @@ def recursiveDictCompare(d1, d2): ...@@ -97,8 +100,9 @@ def recursiveDictCompare(d1, d2):
print("data is different!", a, b) print("data is different!", a, b)
return False return False
elif a != b: elif a != b:
print("data is different!", a, b) if (a is not None) and (b is not None):
return False print("data is different!", a, b)
return False
return True return True
class DataSet(object): class DataSet(object):
......
...@@ -145,25 +145,16 @@ class SegmentationContours(QtWidgets.QGraphicsItem): ...@@ -145,25 +145,16 @@ class SegmentationContours(QtWidgets.QGraphicsItem):
elif numParticles == 1: elif numParticles == 1:
combineMenu.setDisabled(True) combineMenu.setDisabled(True)
action = contextMenu.exec_(event.screenPos()) action = contextMenu.exec_(event.screenPos())
if action == deleteAct: if action == deleteAct:
print('deleting') print('deleting')
elif action in combineActs: elif action in combineActs:
newAssignment = action.text() newAssignment = action.text()
# if newAssignment == "other":
# QtWidgets.QMessageBox.about(self.parent, "Not yet implemented", "we are getting there...")
# return
self.parent.analysiswidget.editor.combineParticles(self.selectedContours, newAssignment) self.parent.analysiswidget.editor.combineParticles(self.selectedContours, newAssignment)
elif action in reassignActs: elif action in reassignActs:
newAssignment = action.text() newAssignment = action.text()
# if newAssignment == "other":
# QtWidgets.QMessageBox.about(self.parent, "Not yet implemented", "we are getting there...")
# return
self.parent.analysiswidget.editor.reassignParticles(self.selectedContours, newAssignment) self.parent.analysiswidget.editor.reassignParticles(self.selectedContours, newAssignment)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment