From 0519e87599e5f4c20dc24a5d576b823bb83e4e56 Mon Sep 17 00:00:00 2001 From: "benjamin.jakimow@geo.hu-berlin.de" <q8DTkxUg-BB> Date: Mon, 12 Mar 2018 13:42:10 +0100 Subject: [PATCH] fixel pixeloader error --- test/test_pixelloader.py | 29 ++++-- test/test_spectrallibraries.py | 41 +++++++- timeseriesviewer/pixelloader.py | 117 ++++++++++++++--------- timeseriesviewer/profilevisualization.py | 6 +- timeseriesviewer/temporalprofiles.py | 31 +++--- 5 files changed, 149 insertions(+), 75 deletions(-) diff --git a/test/test_pixelloader.py b/test/test_pixelloader.py index d21febb8..c1ec4e6a 100644 --- a/test/test_pixelloader.py +++ b/test/test_pixelloader.py @@ -22,6 +22,10 @@ from timeseriesviewer import file_search QGIS_APP = initQgisApplication() +def onDummy(*args): + print(('dummy', args)) + + class PixelLoaderTest(unittest.TestCase): """Test translations work.""" @@ -141,12 +145,14 @@ class PixelLoaderTest(unittest.TestCase): ext = SpatialExtent.fromRasterSource(files[0]) x, y = ext.center() - geoms = [ + geoms1 = [ # SpatialPoint(ext.crs(), 681151.214,-752388.476), #nodata in Img_2014_04_29_LE72270652014119CUB00_BOA SpatialExtent(ext.crs(), x + 10000, y, x + 12000, y + 70), # out of image SpatialExtent(ext.crs(), x, y, x + 10000, y + 70), - SpatialPoint(ext.crs(), x, y), - SpatialPoint(ext.crs(), x + 250, y + 70)] + ] + + geoms2 = [SpatialPoint(ext.crs(), x, y), + SpatialPoint(ext.crs(), x + 250, y + 70)] from multiprocessing import Pool @@ -157,8 +163,6 @@ class PixelLoaderTest(unittest.TestCase): PL = PixelLoader() - def onDummy(*args): - print(('dummy', args)) def onTimer(*args): print(('TIMER', PL)) @@ -170,12 +174,21 @@ class PixelLoaderTest(unittest.TestCase): PL.sigLoadingStarted.connect(lambda: onDummy('started')) PL.sigPixelLoaded.connect(lambda: onDummy('px loaded')) - tasks = [] + tasks1 = [] + for i, f in enumerate(files): + kwargs = {'myid': 'myID{}'.format(i)} + tasks1.append(PixelLoaderTask(f, geoms1, bandIndices=None, **kwargs)) + + tasks2 = [] for i, f in enumerate(files): kwargs = {'myid': 'myID{}'.format(i)} - tasks.append(PixelLoaderTask(f, geoms, bandIndices=None, **kwargs)) + tasks2.append(PixelLoaderTask(f, geoms2, bandIndices=None, **kwargs)) + + PL.startLoading(tasks1) + PL.startLoading(tasks2) + + print('DONE') - PL.startLoading(tasks) diff --git a/test/test_spectrallibraries.py b/test/test_spectrallibraries.py index 5bfe2199..e4527651 100644 --- a/test/test_spectrallibraries.py +++ b/test/test_spectrallibraries.py @@ -17,7 +17,7 @@ *************************************************************************** """ # noinspection PyPep8Naming -import os, sys, unittest +import os, sys, unittest, tempfile from timeseriesviewer.utils import initQgisApplication qapp = initQgisApplication() @@ -45,11 +45,44 @@ class TestInit(unittest.TestCase): self.SP = spec1 def test_spectralLibrary(self): + + spec1 = SpectralProfile() + spec1.setValues([0, 4, 3, 2, 1], ['-'], [450, 500, 750, 1000, 1500], 'nm') + + spec2 = SpectralProfile() + spec2.setValues([3, 2, 1, 0, 1], ['-'], [450, 500, 750, 1000, 1500], 'nm') + sl = SpectralLibrary() - sl.addProfile(self.SP) + sl.addProfiles([spec1, spec2]) + self.assertEqual(len(sl),2) + self.assertEqual(sl[0], spec1) + + + tempDir = tempfile.gettempdir() + pathESL = tempfile.mktemp(prefix='speclib.', suffix='.esl') + pathCSV = tempfile.mktemp(prefix='speclib.', suffix='.csv') + try: + sl.exportProfiles(pathESL) + except Exception as ex: + self.fail('Unable to write ESL. {}'.format(ex)) + + try: + sl2 = SpectralLibrary.readFrom(pathESL) + except Exception as ex: + self.fail('Unable to read ESL. {}'.format(ex)) + + + try: + sl.exportProfiles(pathCSV) + except Exception as ex: + self.fail('Unable to write CSV. {}'.format(ex)) + + try: + sl2 = SpectralLibrary.readFrom(pathCSV) + except Exception as ex: + self.fail('Unable to read CSV. {}'.format(ex)) + - self.assertEqual(len(sl),1) - self.assertEqual(sl[0], self.SP) self.SPECLIB = sl diff --git a/timeseriesviewer/pixelloader.py b/timeseriesviewer/pixelloader.py index d4edb1d8..528fd666 100644 --- a/timeseriesviewer/pixelloader.py +++ b/timeseriesviewer/pixelloader.py @@ -95,6 +95,18 @@ class PixelLoaderTask(object): self.__dict__[k] = kwargs[k] + def validPixelValues(self, i): + if not self.success(): + return False + if i >= len(self.resProfiles): + return False + + profileData = self.resProfiles[i] + if profileData in [INFO_OUT_OF_IMAGE, INFO_NO_DATA]: + return False + else: + return True + def imageCrs(self): return QgsCoordinateReferenceSystem(self.resCrsWkt) @@ -365,23 +377,30 @@ def pixelLoadingLoop(inputQueue, resultQueue, cancelEvent, finishedEvent): assert isinstance(finishedEvent, Event) - while not cancelEvent.is_set(): - - if not inputQueue.empty(): - print('Taskloop {} '.format(time.time())) - task = inputQueue.get() - if not isinstance(task, str): - try: - task = doLoaderTask(task) - print('Taskloop put {} '.format(task)) - resultQueue.put(task) - except Exception as ex: - resultQueue.put(ex) - elif task.startswith('LAST'): - resultQueue.put('FINISHED') - finishedEvent.set() - else: - print('Unhandled {}'.format(task)) + while not inputQueue.empty(): + if cancelEvent.is_set(): + print('Taskloop put CANCELED') + break + #if not inputQueue.empty(): + print('Taskloop {} '.format(time.time())) + task = inputQueue.get() + if not isinstance(task, str): + try: + print('Taskloop do {} '.format(task)) + task = doLoaderTask(task) + print('Taskloop put {} '.format(task)) + resultQueue.put(task) + except Exception as ex: + resultQueue.put(ex) + elif task.startswith('LAST'): + print('Taskloop put FINISHED') + resultQueue.put('FINISHED') + finishedEvent.set() + print('Taskloop FINISHED set') + else: + print('Taskloop put UNHANDLED') + print('Unhandled {}'.format(task)) + break resultQueue.put('CANCELED') @@ -451,13 +470,18 @@ class PixelLoader(QObject): self.mWorkerProcess = None self.queueCheckTimer = QTimer() # - #self.queueCheckTimer.setInterval(1000) + #self.queueCheckTimer.setInterval(200) self.queueCheckTimer.timeout.connect(self.checkTaskResults) - self.queueCheckTimer.start(200) + self.queueCheckTimer.timeout.connect(self.dummySlot) + self.queueCheckTimer.start(1000) + + def dummySlot(self, *args): + print('dummy slot triggered') + def initWorkerProcess(self): - if not isinstance(self.mWorkerProcess, multiprocessing.Process) or not self.mWorkerProcess.is_alive(): + if not isinstance(self.mWorkerProcess, multiprocessing.Process) : self.mWorkerProcess = multiprocessing.Process(name='PixelLoaderWorkingProcess', target=pixelLoadingLoop, args=(self.mTaskQueue, self.mResultQueue, self.mCancelEvent, self.mKillEvent,)) @@ -465,6 +489,10 @@ class PixelLoader(QObject): self.mWorkerProcess.daemon = False self.mWorkerProcess.start() + else: + if not self.mWorkerProcess.is_alive(): + self.mWorkerProcess.run() + @@ -506,13 +534,13 @@ class PixelLoader(QObject): self.jobProgress[jobId] = LoadingProgress(jobId, len(tasks)) self.sigLoadingStarted.emit(paths[:]) - + self.mKillEvent.clear() self.initWorkerProcess() for t in tasks: assert isinstance(t, PixelLoaderTask) t.mJobId = self.jobId self.mTaskQueue.put(t) - self.mKillEvent.clear() + self.mTaskQueue.put('LAST_{}'.format(jobId)) def cancelLoading(self): @@ -526,34 +554,35 @@ class PixelLoader(QObject): def checkTaskResults(self, *args): dataList = [] - + print('CHECK TASK RESULTS') finished = False canceled = False - while not self.mResultQueue.empty(): - data = self.mResultQueue.get() - if isinstance(data, PixelLoaderTask): - dataList.append(data) - print('result pulled') - elif isinstance(data, str): - if data == 'FINISHED': - finished = True - elif data == 'CANCELED': - canceled = True + if isinstance(self.mWorkerProcess, multiprocessing.Process): + while not self.mResultQueue.empty(): + data = self.mResultQueue.get() + if isinstance(data, PixelLoaderTask): + dataList.append(data) + print('result pulled') + elif isinstance(data, str): + if data == 'FINISHED': + finished = True + elif data == 'CANCELED': + canceled = True + else: + s = "" else: - s = "" - else: - raise Exception('Unhandle type returned {}'.format(data)) - if len(dataList) > 0: - self.onPixelLoaded(dataList) + raise Exception('Unhandled type returned {}'.format(data)) + if len(dataList) > 0: + self.onPixelLoaded(dataList) - if finished: - dt = np.datetime64('now', 'ms') - self.mLoadingStartTime - self.sigLoadingFinished.emit(dt) + if finished: + dt = np.datetime64('now', 'ms') - self.mLoadingStartTime + self.sigLoadingFinished.emit(dt) - if self.mTaskQueue.empty() and self.mResultQueue.empty(): - self.mWorkerProcess.terminate() - self.mWorkerProcess.join() + if self.mTaskQueue.empty() and self.mResultQueue.empty(): + self.mWorkerProcess.terminate() + self.mWorkerProcess.join() diff --git a/timeseriesviewer/profilevisualization.py b/timeseriesviewer/profilevisualization.py index 4273c420..c91cd0cc 100644 --- a/timeseriesviewer/profilevisualization.py +++ b/timeseriesviewer/profilevisualization.py @@ -1560,8 +1560,8 @@ class SpectralTemporalVisualization(QObject): if not isinstance(self.plotSettingsModel2D, PlotSettingsModel2D): return False - if not self.pixelLoader.isReadyToLoad(): - return False + #if not self.pixelLoader.isReadyToLoad(): + # return False assert isinstance(self.TS, TimeSeries) @@ -1639,7 +1639,7 @@ class SpectralTemporalVisualization(QObject): if len(tasks) > 0: aGoodDefault = 2 if len(self.TS) > 25 else 1 - self.pixelLoader.setNumberOfProcesses(SETTINGS.value('profileloader_threads', aGoodDefault)) + #self.pixelLoader.setNumberOfProcesses(SETTINGS.value('profileloader_threads', aGoodDefault)) if DEBUG: print('Start loading for {} geometries from {} sources...'.format( len(theGeometries), len(tasks) diff --git a/timeseriesviewer/temporalprofiles.py b/timeseriesviewer/temporalprofiles.py index 5370479d..9c42fb0c 100644 --- a/timeseriesviewer/temporalprofiles.py +++ b/timeseriesviewer/temporalprofiles.py @@ -650,23 +650,22 @@ class TemporalProfile(QObject): i = d.temporalProfileIDs.index(self.mID) tsd = self.mTimeSeries.getTSD(d.sourcePath) assert isinstance(tsd, TimeSeriesDatum) - profileData = d.resProfiles[i] - if not isinstance(profileData, tuple): - s = "" - try: + + if d.validPixelValues(i): + + profileData = d.resProfiles[i] + vMean, vStd = profileData - except Exception as ex: - s = "" - values = {} - validValues = not isinstance(vMean, str) - # 1. add the pixel values per returned band - - for iBand, bandIndex in enumerate(d.bandIndices): - key = 'b{}'.format(bandIndex + 1) - values[key] = vMean[iBand] if validValues else None - key = 'std{}'.format(bandIndex + 1) - values[key] = vStd[iBand] if validValues else None - self.updateData(tsd, values) + values = {} + validValues = not isinstance(vMean, str) + # 1. add the pixel values per returned band + + for iBand, bandIndex in enumerate(d.bandIndices): + key = 'b{}'.format(bandIndex + 1) + values[key] = vMean[iBand] if validValues else None + key = 'std{}'.format(bandIndex + 1) + values[key] = vStd[iBand] if validValues else None + self.updateData(tsd, values) def loadMissingData(self, showGUI=False): -- GitLab