def processAlgorithm(self, progress):
        """Here is where the processing itself takes place."""

        progress.setInfo(u'Start querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(70)

        compound_name = self.getParameterValue(self.COMPOUND)

        db = JupiterDb()
        compound_no = db.compoundname_to_no(compound_name)

        progress.setInfo(u'End querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(100)

        progress.setText(u'<br><b>RESULTAT:</b>')

        if not compound_name:
            progress.setText(
                u'<br><b>Stofnavn {} findes ikke!!</b><br>'.format(
                    compound_name))
        else:
            progress.setText(
                u'<b>Stofnavn: "{}" har stofnummer: {}.</b><br>'.format(
                    compound_name, compound_no))
    def processAlgorithm(self, progress):
        """Here is where the processing itself takes place."""

        progress.setInfo(u'Start querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(40)

        sampleid = self.getParameterValue(self.SAMPLE)
        compound_name = self.getParameterValue(self.COMPOUND)

        db = JupiterDb()
        unit = db.get_unit(sampleid, compound_name)

        progress.setInfo(u'End querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(100)

        progress.setText('<br><b>RESULTAT:</b><br>')

        if unit:
            progress.setText(
                u'<b>Enhed for {} i prøve {} er [{}].<br></b><br>'.format(
                    compound_name, sampleid, unit))
        else:
            progress.setText(
                u'<b>Enheden for {} i prøve {} findes ikke. Tjek dit sampleno og komponentnavn igen.<br></b><br>'
                .format(compound_name, sampleid, unit))
    def test_graph2(self):
        """
        http://data.geus.dk/JupiterWWW/borerapport.jsp?atlasblad=0&loebenr=0&bogstav=&dgunr=230.++205&submit=Vis+boringsdata
        https://www.linuxquestions.org/questions/programming-9/python-matplotlib-postgresql-xaxis-as-dates-4175445040/
        """
        from jupiter_db import JupiterDb
        import psycopg2
        from matplotlib import pyplot as plot, dates

        db = JupiterDb()
        params = db.get_dbparams()
        conn = psycopg2.connect(**params)  #psycopg2.connect('dbname=foo user=bar')
        cur = conn.cursor()
        cur.execute("""
            SELECT
              amount,
              sampledate
            FROM 
              jupiter.mstmvw_chemanalysis
            WHERE
              long_text ilike 'nitrat' AND 
              boreholeno = '230.  205'
        """)

        data = cur.fetchall()
        cur.close()
        conn.close()

        ms, dt = zip(*data)
        dt = dates.date2num(dt)
        plot.plot_date(dt, ms)
        plot.xticks(rotation='vertical')
        plot.show()

        return True
    def test1_timeseries(self, boreholeno, compound, datefrom, dateto):
        """ Based of matplotlib.plot_date
            TEST: No use of ax - one borehole multiple compounds
        """
        # Here we just use one figure
        plt.figure(1)

        db = JupiterDb()

        # Test compound - overwrites gui input
        compound = 'Nitrat; Sulfat'

        compounds = compound.split(';')
        for c in compounds:
            amount, dt = db.get_timeserie(boreholeno, c.strip(), datefrom,
                                          dateto)
            if amount is None:
                return False

            dt = dates.date2num(dt)
            plt.plot_date(dt, amount, linestyle='-', label=c)

        plt.xticks(rotation='vertical')
        plt.title('{}-tidsserie for boring: {}'.format(compound, boreholeno))

        plt.legend(loc='upper center', shadow=True)
        plt.grid(True)

        plt.show()

        return True
    def addStyle(self, pglayername, vlayer, uri):
        """Add style to layer. Assumes tablename if stylename
        :param pglayername: layer to query for in public.layer_styles
        :param vlayer: layer to apply style for
        :return: True if no error
        """

        qmlfile = os.path.join(JupiterAux.pluginpath(), 'style',
                               'borehole.qml')
        msg, styleloaded = vlayer.loadNamedStyle(qmlfile, True)
        iface.mapCanvas().refresh()
        iface.legendInterface().refreshLayerSymbology(vlayer)
        vlayer.triggerRepaint()

        return True

        JupiterAux.log_info(u'Loading default style from db...')
        db = JupiterDb()
        styleqml = db.get_style(pglayername)

        if styleqml:
            #vlayer.applyNamedStyle(pglayername)
            styleok = vlayer.loadNamedStyle(styleqml, True)
            iface.mapCanvas().refresh()
            iface.legendInterface().refreshLayerSymbology(vlayer)
            vlayer.triggerRepaint()
            JupiterAux.log_info(u'Style applied to: {}'.format(pglayername))
        else:
            JupiterAux.log_info(
                u'Table {} has no default style in db'.format(pglayername))

        return True
    def processAlgorithm(self, progress):
        """Here is where the processing itself takes place."""

        progress.setInfo(u'Start querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(70)

        compound_id = self.getParameterValue(self.COMPOUND)

        db = JupiterDb()
        compound_name = db.compoundno_to_name(compound_id)

        progress.setInfo(u'End querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(100)

        progress.setText(u'<br><b>RESULTAT:</b>')

        if not compound_name:
            progress.setText(
                u'<br><b>Indtastede stofnummer: "{}" findes ikke i PCJupiterXL</b><br>'
                .format(compound_id))
        else:
            progress.setText(
                u'<b>Indtastet stofnummer: "{}" har navnet: {}</b><br>'.format(
                    compound_id, compound_name))
    def make_dguno_spatial(self, progress, pglayername, layer, fieldname,
                           output):
        """
        :param progress: Processing progressbar and info
        :param pglayername: PostgreSQL layer to load subset from
        :param layer: layer with dgunummer
        :param fieldname: field with dgunummer
        :param output: result output file
        :return: True if non error - else False
        """

        layerobj = dataobjects.getObjectFromUri(layer)

        dguno_list = [ft[fieldname] for ft in layerobj.getFeatures()]
        dguno_str = "'" + "', '".join(dguno_list) + "'"

        where_sql = 'boreholeno in ({})'.format(dguno_str)
        # JupiterAux.log_info('wheresql: {}'.format(where_sql))

        db = JupiterDb()

        # Find input boreholeno that have match in db
        str_no_match = ''
        list_no_boreholeno_match = db.boring_not_in_csv(dguno_str, dguno_list)
        if list_no_boreholeno_match:
            str_no_match = ''.join(list_no_boreholeno_match)
            # JupiterAux.msg_box(''.join(list_no_boreholeno_match))

        # Find input boreholeno that have duplicates
        import collections
        counter = collections.Counter(dguno_list)
        str_duplicates = ''
        if counter:
            d = dict((k, v) for k, v in counter.items() if v >= 2)
            import json
            str_duplicates = json.dumps(d)

        uri = db.getUri()
        uri.setDataSource("jupiter", pglayername, "geom", where_sql)

        ok, pglayer = self.getQgsVectorLayerFromUri(uri, pglayername)
        if not ok:
            return False

        if not self.writeOutputVector(progress, pglayer, output):
            return False

        #if not self.addStyle(pglayername, vlayer):
        #return False

        return True, str_no_match, str_duplicates
    def processAlgorithm(self, progress):
        """Here is where the processing itself takes place."""

        #import sys
        #reload(sys)
        #sys.setdefaultencoding('utf-8')

        progress.setInfo(u'Start querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(40)

        compound_name = self.getParameterValue(self.COMPOUND)

        db = JupiterDb()
        result_list = db.count_compound_units(compound_name)

        progress.setInfo(u'End querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(100)

        progress.setText(u'<br><b>RESULTAT:</b>')

        if not result_list:
            progress.setText(
                u'<br><b>Der er ikke fundet nogle enheder for komponent med navn: {}</b><br>'
                .format(compound_name))
            return

        if len(result_list) == 1:
            progress.setText(u'<br><b>Der er 1 resultat:</b><br>')
        else:
            progress.setText(
                u'<br><b>Der er {} resultater. Måske er der datafejl i Jupiter?!!</b><br>'
                .format(len(result_list)))

        # OutputHTML er for ringe
        #output = self.getOutputValue(self.OUTPUT)  #https://docs.qgis.org/2.2/en/docs/training_manual/processing/log.html
        #f = open(output, 'w')

        for item in result_list:
            count, unit = item

            progress.setText(
                u'<b>Enhed for {} er [{}]. Enheden optræder i Jupiter {} gange for {}.</b><br>'
                .format(compound_name, unit, count, compound_name))
    def add_vertexmarker_borehole(self, boreholeno, keepExistingMarkers=False):
        """ Warning - this method fails silently on error """
        if not keepExistingMarkers:
            self.remove_canvas_items()

        db = JupiterDb()
        x, y = db.get_xy(boreholeno)

        #JupiterAux.msg_box('x,y = {}, {}'.format(x, y))

        # Add new vertexmarker
        vm = QgsVertexMarker(iface.mapCanvas())
        vm.setCenter(QgsPoint(x, y))
        vm.setColor(QColor(0, 255, 0, 255))
        vm.setIconSize(30)
        vm.setIconType(
            QgsVertexMarker.ICON_CROSS)  # ICON_BOX, ICON_CROSS, ICON_X
        vm.setPenWidth(2)
    def __init__(self):
        AlgorithmProvider.__init__(self)

        ## Try to clear the message log
        # from PyQt4.QtGui import QDockWidget
        # from qgis.utils import iface
        # consoleWidget = iface.mainWindow().findChild(QDockWidget, 'PythonConsole')
        # consoleWidget.console.shellOut.clearConsole()
        # MessageLog = iface.mainWindow().findChild(QDockWidget, 'MessageLog')

        # for child in iface.mainWindow().children():
        #    JupiterAux.log_info(child.objectName())

        ## Explained: Debugger between QGIS and pyCharm
        ## For the debugger to run the four lines below must be enabled - disable for qgis startup
        ## Enable the lines - run the debugger from pyCharm - and refresh plugin in QGIS

        if 1 == 2:
            import sys
            sys.path.append(r'C:\Program Files\JetBrains\PyCharm 2017.3.2\debug-eggs\pycharm-debug.egg')
            import pydevd
            pydevd.settrace('localhost', port=53100, stdoutToServer=True, stderrToServer=True)

        # Deactivate provider by default
        #self.activate = False

        JupiterAux.log_info('\n------------ Qupiter ------------')

        # Write out status information
        db = JupiterDb()
        #JupiterAux.log_info(u'Test DB connection: {}'.format(db.test_connection()))
        JupiterAux.log_info(u'{} version:\t\t{}'.format(JupiterAux.JUPITER, JupiterAux.get_meta_version()))
        JupiterAux.log_info(u'Sidste komplette restore:\t\t{} dage'.format(db.database_geus_export_time_in_days()))
        JupiterAux.log_info(u'Sidste DbSync synkronisation:\t{} dage'.format(db.database_dbsync_success_in_days()))
        JupiterAux.log_info(u'Yngste sample insert i databasen:\t{} dage'.format(db.database_youngest_insert_in_days()))

        #JupiterAux.log_info('Host: {} -- Database: {} -- User: {}'.format(

        #JupiterAux.enable_qgis_log()
        #JupiterAux.log_info('Global QGIS log enabled!')

        self.createAlgsList()
    def test_graph1(self):
        """
        http://data.geus.dk/JupiterWWW/borerapport.jsp?atlasblad=0&loebenr=0&bogstav=&dgunr=230.++205&submit=Vis+boringsdata
        https://www.linuxquestions.org/questions/programming-9/python-matplotlib-postgresql-xaxis-as-dates-4175445040/
        TODO: Why is test_graph1 faster than test_graph2 ?
        """
        from jupiter_db import JupiterDb
        import psycopg2
        from matplotlib import pyplot as plot, dates

        db = JupiterDb()
        params = db.get_dbparams()
        conn = psycopg2.connect(
            **params)  #psycopg2.connect('dbname=foo user=bar')
        cur = conn.cursor()
        cur.execute("""
            SELECT
              ca.amount,
              cs.sampledate
            FROM jupiter.borehole b
            --INNER JOIN jupiter.intake i USING (boreholeno)
            INNER JOIN jupiter.grwchemsample cs USING (boreholeno)
            INNER JOIN jupiter.grwchemanalysis ca ON ca.sampleid = cs.sampleid
            INNER JOIN jupiter.compoundlist cl ON ca.compoundno = cl.compoundno
            --INNER JOIN kort.lolland l ON st_dwithin(b.geom, l.geom, 0)
            WHERE cl.long_text ilike 'nitrat' AND b.boreholeno = '230.  205'
            ORDER BY cs.sampledate
        """)

        data = cur.fetchall()
        cur.close()
        conn.close()

        ms, dt = zip(*data)
        dt = dates.date2num(dt)
        plot.plot_date(dt, ms)
        plot.xticks(rotation='vertical')
        plot.show()

        return True
    def add_alphaview(self, progress, pglayername, output):
        """Load a non spatial table or view from postgresql - currently pesticide list
        :param progress: Information text and progress
        :param pglayername: Name of alpha view to load
        :param output: processing.core.outputs.OutputVector object
        :return: True if no error
        """
        db = JupiterDb()
        uri = db.getUri()
        uri.setDataSource("jupiter", pglayername, None)

        JupiterAux.log_info(
            'Loading alphalayer: {} from URI'.format(pglayername),
            progress=progress)

        ok, pglayer = self.getQgsVectorLayerFromUri(uri, pglayername)
        if not ok:
            return False

        if not self.writeOutputVector(
                progress, pglayer, output, isSpatial=False):
            return False

        return True
    def timeseries_oneborehole_multiplecompounds(self,
                                                 boreholeno,
                                                 compoundlist,
                                                 datefrom,
                                                 dateto,
                                                 skip_unit=False,
                                                 progress=None):
        """ Based of matplotlib.plot_date
             Multiple compounds and one borehole
         """
        # General Figure
        plt.figure(1)
        fig = plt.figure(1)
        plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.15)

        # General Axis
        ax = fig.add_subplot(1, 1, 1)

        # X-Axis
        ax.set_xlabel(u'År')

        # Y-Axis
        ax.set_ylabel('Koncentration')
        ax.yaxis.grid()

        db = JupiterDb()
        compounds = compoundlist.split(';')

        not_found = []
        compound_index = 0
        for c in compounds:
            compound_index += 1
            if progress is not None:
                progress.setPercentage(compound_index * 100 / len(compounds))
            c = c.strip()
            # Get amount and dates for compound
            amount, dt = db.get_timeserie(boreholeno, c, datefrom, dateto)
            if amount is None:
                not_found.append(c)
                if len(compounds) == 1:
                    return False, None
                else:
                    continue

            if skip_unit:
                label_legend = c
            else:
                # Get unit for legend label - time consuming part
                unit_tuple_list = db.count_compound_units(c)
                if unit_tuple_list is None:
                    # No unit for compound - not likely
                    label_legend = '{} [???]'.format(c)
                else:
                    if len(unit_tuple_list) == 1:
                        # Perfect - just one unit for compound
                        unit_count, unit = unit_tuple_list[0]
                        label_legend = '{} [{}]'.format(c, unit)
                    elif len(unit_tuple_list) > 1:
                        # More than one unit pr compound
                        units = []
                        for unit_count, unit in unit_tuple_list:
                            units.append('{}?'.format(unit))
                        label_legend = '{} [{}]'.format(c, ' '.join(units))

            # Convert datetime to matplot numbers
            dt = dates.date2num(dt)
            plt.plot_date(dt,
                          amount,
                          linestyle='-',
                          markersize=3,
                          label=label_legend)

        plt.xticks(rotation='vertical')
        plt.title('Tidsserie for boring: {}'.format(boreholeno))
        plt.legend(loc='upper center', shadow=True)

        plt.show()

        return True, not_found
    def scatterplot(self,
                    extent_or_wkt,
                    compoundname_x,
                    compoundname_y,
                    datefrom,
                    dateto,
                    extent_layer=None,
                    x_marker=None,
                    y_marker=None,
                    showannotations=False):
        """
        Create a scatter plot Either from boreholes in bbox or wkt selected geometries
        :param extent_or_wkt: Either a extent string or a wkt geometry
        :param compoundname_x: Compound name for x axe
        :param compoundname_y: Compound name for y axe
        :param datefrom: Query from date
        :param dateto: Query to date
        :param extent_layer: layername with selection. Only relevant if WKT bound.
        :param x_marker: marker line for given value
        :param y_marker: marker line for given value
        :return: True if no error
        :param showannotations: Show boreholeno label for each scatter point
        """
        def onpick(event):
            # Warning matplotlib fails in silence - https://matplotlib.org/examples/event_handling/pick_event_demo.html
            index = event.ind
            borehole_arr_pick = np.take(boreholenos, index)
            #JupiterAux.msg_box('onpick scatter: {}'.format(borehole_arr_pick))

            qgis = JupiterQGIS()
            for j, b in enumerate(borehole_arr_pick):
                if j == 0:
                    qgis.add_vertexmarker_borehole(b)
                else:
                    qgis.add_vertexmarker_borehole(b, keepExistingMarkers=True)

        db = JupiterDb()
        compoundno_x = db.compoundname_to_no(compoundname_x)
        compoundno_y = db.compoundname_to_no(compoundname_y)

        unit_x = db.get_unit_quess(compoundno_x)
        unit_y = db.get_unit_quess(compoundno_y)

        if compoundno_x is None or compoundno_y is None:
            JupiterAux.msg_box(
                'Et af de to indtastede stoffer: "{}, {}" findes ikke i PCJupiterXL'
                .format(compoundname1, compoundname2))
            return

        qgis = JupiterQGIS()
        qgis.remove_canvas_items()  # Remove marker from a previous plot

        boreholenos = []
        if extent_or_wkt != '0,0,0,0':
            bbox = qgis.extentToBoundingbox(extent_or_wkt)
            x, y, boreholenos = db.get_scatter_array_bbox(
                compoundno_x, compoundno_y, bbox, datefrom, dateto,
                compoundname_x, compoundname_y)
        else:
            wkt = qgis.selectedFeatureToWKT(extent_layer)
            x, y, boreholenos = db.get_scatter_array_wkt(
                compoundno_x, compoundno_y, wkt, datefrom, dateto,
                compoundname_x, compoundname_y)

        # General Figure
        plt.figure(1)
        fig = plt.figure(1)

        # Connect pick event on plot
        cid = fig.canvas.mpl_connect('pick_event', onpick)

        plt.scatter(
            x, y, alpha=0.8,
            picker=True)  # plt.scatter(x, y, s=area, c=colors, alpha=0.5)

        ax = fig.add_subplot(1, 1, 1)
        ax.set_xlabel('{} [{}]'.format(compoundname_x, unit_x))
        ax.set_ylabel('{} [{}]'.format(compoundname_y, unit_y))

        ax.xaxis.grid()
        ax.yaxis.grid()

        # label points in scatter plot
        if showannotations:
            for i, txt in enumerate(boreholenos):
                ax.annotate(str(txt), (x[i], y[i]))

        plt.axhline(y=y_marker)
        plt.axvline(x=x_marker)
        plt.title('Scatterplot')

        plt.show()

        return True
    def add_maplayer(self,
                     progress,
                     pglayername,
                     output,
                     extent,
                     selectionLayername=None,
                     rowid=None,
                     where_sql2=None):
        """Adds a postgis layer to map
        :type progress: Processing progressbar and info
        :type pglayername: string name of pglayer to select from Jupiter
        :param output: processing.core.outputs.OutputVector object
        :type extent: Bounding box of query, if none use selected geom(s) as bound
        :type selectionLayername: string name of layer with selected geom to use as border in query
        :type rowid: needed for qgis to open views
        :where_sql: additional sql, not only bound search ... update doc

        WARNING: Do not use semicolon after where sql at uri.setDataSource
        """

        # import sys
        # sys.path.append(r'C:\Program Files\JetBrains\PyCharm 2017.2.3\debug-eggs\pycharm-debug.egg')
        # import pydevd
        # pydevd.settrace('localhost', port=53100, stdoutToServer=True, stderrToServer=True)

        JupiterAux.log_info('add_maplayer: {}'.format(pglayername), progress)

        db = JupiterDb()
        uri = db.getUri()

        where_sql = ''
        # https://gis.stackexchange.com/questions/239601/sqlqueries-in-postgis-database-layer-using-python-and-qgis/239682#239682
        if extent == "0,0,0,0":
            ''' Query by geometry of selection in a layer '''

            wkt = self.selectedFeatureToWKT(selectionLayername)

            if not where_sql2:
                where_sql = "ST_WITHIN(geom , ST_GeomFromText('{}', 25832))".format(
                    wkt)
            else:
                where_sql = "ST_WITHIN(geom , ST_GeomFromText('{}', 25832) ) AND {}".format(
                    wkt, where_sql2)
        else:
            ''' Query by entered extent '''
            bbox = self.extentToBoundingbox(extent)

            if not where_sql2:
                where_sql = "geom && ST_MakeEnvelope({}, {}, {}, {}, 25832)". \
                    format(bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum())
            else:
                where_sql = "geom && ST_MakeEnvelope({}, {}, {}, {}, 25832) AND {}" \
                    .format(bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum(), where_sql2)

        uri.setDataSource("jupiter", pglayername, "geom", where_sql)

        JupiterAux.log_info(
            'Loading layer: "{}" from URI with where clause: "{}"'.format(
                pglayername, where_sql2),
            progress=progress)

        # Views must have defined a rowid
        if rowid:
            uri.setKeyColumn(rowid)

        ok, pglayer = self.getQgsVectorLayerFromUri(uri, pglayername)
        if not ok:
            return False

        if not self.writeOutputVector(progress, pglayer, output):
            return False

        #if not self.addStyle(pglayername, vlayer, uri):
        #return False

        # TODO  layer is not add to map until end of table_geoalgorithm.processAlgorithm
        # TODO  therefor is the showFeatureCount below not working
        # self.showFeatureCount(vlayer.name())

        return True
    def timeseries_onecompound_multipleborehole(self,
                                                boreholenolist,
                                                compound,
                                                datefrom,
                                                dateto,
                                                progress=None):
        """ Based of matplotlib.plot_date. Multiple borehole and one compound """

        from datetime import datetime

        def onclick(event):
            JupiterAux.msg_box(
                '%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
                ('double' if event.dblclick else 'single', event.button,
                 event.x, event.y, event.xdata, event.ydata))

        def onpick(event):
            thisline = event.artist
            borehole_graph_pick = thisline.get_label()

            #JupiterAux.msg_box('Picked borehole graph: {}'.format(borehole_graph_pick))

            #xdata = thisline.get_xdata()  #convert to  dates.num2date(dt)
            #ydata = thisline.get_ydata()
            #ind = event.ind
            #points = tuple(zip(xdata[ind], ydata[ind]))
            #JupiterAux.msg_box('{} - onpick points: {}'.format(borehole_graph_selection, points))

            qgis = JupiterQGIS()
            qgis.add_vertexmarker_borehole(borehole_graph_pick)

        # General Figure
        plt.figure(1)
        fig = plt.figure(1)
        plt.subplots_adjust(left=0.1, right=0.75, top=0.9, bottom=0.15)

        #cid = fig.canvas.mpl_connect('button_press_event', onclick)
        cid = fig.canvas.mpl_connect('pick_event', onpick)

        # General Axis
        ax = fig.add_subplot(1, 1, 1)

        # Draw compound limit as a horizontal line
        #plt.axhline(y=2.7)  only relevant for drwplant, no boreholes

        # X-Axis
        ax.set_xlabel(u'År')

        # Y-Axis - get unit of compound
        db = JupiterDb()
        unit_tuple_list = db.count_compound_units(compound)
        ax_ylabel = compound.title()
        if unit_tuple_list is None:
            # No unit for compound - not likely
            ax_ylabel += u' [???]'
            JupiterAux.msg_box(
                u'Bemærk der findes ingen enhed for stoffet: {} i PCJupiterXL'.
                format(compound))
        else:
            if len(unit_tuple_list) == 1:
                # Perfect - just one unit for compound
                unit_count, unit = unit_tuple_list[0]
                ax_ylabel += u' [{}]'.format(unit)
            elif len(unit_tuple_list) > 1:
                # More than one unit pr compound
                units = []
                for unit_count, unit in unit_tuple_list:
                    units.append(u'{}?'.format(unit))

                ax_ylabel = u' [{}]'.format(' '.join(units))
                JupiterAux.msg_box(
                    u'Bemærk stoffet: {} har flere enheder: ({}) i PCJupiterXL'
                    .format(compound, ', '.join(units)))

        ax.set_ylabel(ax_ylabel)

        ax.yaxis.grid()

        boreholes = boreholenolist.split(',')
        not_found = []
        borehole_index = 0

        for b in boreholes:
            borehole_index += 1

            if progress is not None:
                progress.setPercentage(borehole_index * 100 / len(boreholes))

            b = b.strip()

            # Get amount and dates for compound and boreholes
            amount, dt = db.get_timeserie(b, compound, datefrom, dateto)
            if amount is None:
                not_found.append(b)
                if len(boreholes) == 1:
                    return False, None
                else:
                    continue

            # Convert datetime to matplot numbers
            dt = dates.date2num(dt)
            plt.plot_date(dt,
                          amount,
                          linestyle='-',
                          markersize=3,
                          label=b,
                          picker=5)

        plt.xticks(rotation='vertical')
        plt.title('Tidsserie')
        plt.legend(bbox_to_anchor=(1.02, 1),
                   loc=2,
                   borderaxespad=0.,
                   shadow=True)

        plt.show()

        return True, not_found
    def processAlgorithm(self, progress):
        """Here is where the processing itself takes place."""
        progress.setInfo(u'Start querying "{}" in PCJupiterXL...'.format(
            self.name))
        progress.setPercentage(50)

        extent = self.getParameterValue(self.EXTENT)
        extent_layer = self.getParameterValue(self.VECTOR_SELECTION)
        compoundname = unicode(self.getParameterValue(self.COMPOUNDNAME))
        compoundlimit = self.getParameterValue(self.COMPOUNDLIMIT)
        date_from = self.getParameterValue(self.DATE_FROM)
        date_to = self.getParameterValue(self.DATE_TO)
        onlyload_latest = self.getParameterValue(self.LOAD_ONLY_LATEST)
        output = self.getOutputFromName(self.OUTPUT)

        where_sql = None

        db = JupiterDb()
        compoundno = db.compoundname_to_no(compoundname)
        if compoundno is None:
            JupiterAux.msg_box(
                u'Stoffet: "{}" findes ikke i PCJupiterXL'.format(
                    compoundname))
            progress.setPercentage(100)
            return

        JupiterAux.log_info(u'\nprocessAlgorithm: {}'.format(self.tablename))

        output.description = compoundname

        if self.tablename == u'Søg et stof fra grundvand (boring)':
            if onlyload_latest:
                pgtablename = u'mstvw_bulk_grwchem_latestdates'
                where_sql = u"compoundno = {} AND amount > {} AND geom IS NOT NULL".format(
                    compoundno, compoundlimit)
            else:
                pgtablename = u'mstvw_bulk_grwchem'  #is alldates
                where_sql = u"sampledate > to_date('{}', 'YYYY-MM-DD') AND sampledate < to_date('{}', 'YYYY-MM-DD') AND compoundno = {} AND amount > {} AND geom IS NOT NULL".\
                    format(date_from, date_to, compoundno, compoundlimit)
        elif self.tablename == u'Søg et stof fra vandværk (anlæg)':
            if onlyload_latest:
                pgtablename = u'mstmvw_bulk_pltchem_latestdates'
                where_sql = u"compoundno = {} AND amount > {} AND geom IS NOT NULL".format(
                    compoundno, compoundlimit)
            else:
                pgtablename = u'mstmvw_bulk_pltchem_alldates'
                where_sql = u"sampledate > to_date('{}', 'YYYY-MM-DD') AND sampledate < to_date('{}', 'YYYY-MM-DD') AND compoundno = {} AND amount > {} AND geom IS NOT NULL".\
                    format(date_from, date_to, compoundno, compoundlimit)
        else:
            raise Exception(u'Fejl: Tabel eller view: "{}" findes ikke'.format(
                self.tablename))

        jq = JupiterQGIS()
        ok_add_map = jq.add_maplayer(progress,
                                     pgtablename,
                                     output,
                                     extent,
                                     selectionLayername=extent_layer,
                                     rowid='row_id',
                                     where_sql2=where_sql)

        if ok_add_map:
            progress.setInfo(u'End querying "{}" in PCJupiterXL...'.format(
                self.name))

            progress.setText(u'<br><b>RESULTAT:</b>')
            progress.setText(
                u'<br><b>Tabel {} er åbnet med navnet {}</b>'.format(
                    self.tablename, compoundname))
        else:
            progress.setInfo(u'Der er sket en fejl i "{}"'.format(self.name))