def run_custom_evalscript(self):
        """
        Run operations given user inputted custom evalscript code and return a raster layer based on specifications
        """

        progressMessageBar = self.iface.messageBar().createMessage(
            'Getting mosaic preview')
        progress = QProgressBar()
        progress.setMaximum(3)
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)

        # get bounding box
        bbox = self.get_bounding_box(default=False)

        # validate and set time interval
        start_date, end_date = self.dockwidget.start_date.text(
        ), self.dockwidget.end_date.text()
        accepted_date_format = "%Y-%m-%d"
        try:
            dt.datetime.strptime(start_date, accepted_date_format)
            dt.datetime.strptime(end_date, accepted_date_format)
        except ValueError:
            raise ValueError(
                "Please enter start and end dates with the format of YYYY-MM-DD (ex. 2000-01-01)."
            )

        time_interval = [start_date, end_date]

        # set and validate max_cc
        max_cc = float(self.dockwidget.custom_max_cc.text())

        assert max_cc >= 0 and max_cc <= 1, 'Please enter a max cloud cover proportion between 0 and 1.'

        # grab user inputted custom evalscript and substitute generic
        custom_evalscript_code = self.dockwidget.custom_evalscript_code.toPlainText(
        )
        preview_eval = custom_evalscript_code

        QgsMessageLog.logMessage('requesting preview image', level=Qgis.Info)

        preview_request = SentinelHubRequest(
            evalscript=preview_eval,
            data_folder='/tmp/mosaic_tests',
            input_data=[
                SentinelHubRequest.input_data(
                    data_collection=DataCollection.SENTINEL2_L2A,
                    time_interval=time_interval,
                    maxcc=max_cc)
            ],
            responses=[
                SentinelHubRequest.output_response('default', MimeType.TIFF)
            ],
            bbox=bbox,
            size=(512, get_image_dimension(bbox=bbox, width=512)),
            config=config)

        preview_request.get_data(save_data=True)
        progress.setValue(3)
        output_file = '/tmp/mosaic_tests' + '/' + preview_request.get_filename_list(
        )[0]

        # add file to QGIS
        custom_layer_name_input = self.dockwidget.custom_layer_name_input.text(
        )
        if len(custom_layer_name_input) != 0:
            layer_name = custom_layer_name_input
        else:
            layer_name = 'custom_evalscript_layer'
        self.iface.addRasterLayer(output_file, layer_name)
        self.iface.messageBar().clearWidgets()

        return None
    def run_default_evalscript(self):
        """
        Run operations given default evalscript code and return a raster layer based on specifications
        """

        progressMessageBar = self.iface.messageBar().createMessage(
            'Getting mosaic preview')
        progress = QProgressBar()
        progress.setMaximum(3)
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)

        # get bounding box
        bbox = self.get_bounding_box()

        # make list of relative orbits
        orbit_string = self.dockwidget.relative_orbit.text()
        orbits = [int(orbit) for orbit in orbit_string.split(',')]
        orbit_list_string = ' & '.join([str(x) for x in orbits])
        QgsMessageLog.logMessage(f'orbits: {orbit_list_string}',
                                 level=Qgis.Info)

        # filter down to desired months/years
        months = []
        if self.dockwidget.month_january.isChecked():
            months.append(1)
        if self.dockwidget.month_february.isChecked():
            months.append(2)
        if self.dockwidget.month_march.isChecked():
            months.append(3)
        if self.dockwidget.month_april.isChecked():
            months.append(4)
        if self.dockwidget.month_may.isChecked():
            months.append(5)
        if self.dockwidget.month_june.isChecked():
            months.append(6)
        if self.dockwidget.month_july.isChecked():
            months.append(7)
        if self.dockwidget.month_august.isChecked():
            months.append(8)
        if self.dockwidget.month_september.isChecked():
            months.append(9)
        if self.dockwidget.month_october.isChecked():
            months.append(10)
        if self.dockwidget.month_november.isChecked():
            months.append(11)
        if self.dockwidget.month_december.isChecked():
            months.append(12)

        month_string = ' & '.join([str(x) for x in months])
        QgsMessageLog.logMessage(f'months: {month_string}', level=Qgis.Info)

        years = []
        if self.dockwidget.year_2018.isChecked():
            years.append(2018)
        if self.dockwidget.year_2019.isChecked():
            years.append(2019)
        if self.dockwidget.year_2020.isChecked():
            years.append(2020)
        if self.dockwidget.year_2021.isChecked():
            years.append(2021)

        year_string = ' & '.join([str(x) for x in years])
        QgsMessageLog.logMessage(f'years: {year_string}', level=Qgis.Info)
        progress.setValue(1)

        # date range for mosaicing
        max_cc = float(self.dockwidget.default_max_cc.text())
        # validate max_cc input
        assert max_cc >= 0 and max_cc <= 1, 'Please enter a max cloud cover proportion between 0 and 1.'

        first_year, last_year = str(min(years)), str(max(years))
        start_date, end_date = f'{first_year}-01-01', f'{last_year}-12-30'

        # query dates
        QgsMessageLog.logMessage('querying dates for bbox', level=Qgis.Info)

        dates = get_dates_by_orbit(bbox,
                                   start_date=start_date,
                                   end_date=end_date,
                                   max_cc=max_cc,
                                   target_orbit=orbits,
                                   config=config)

        progress.setValue(2)

        # filter dates down to desired months/years
        dates_filt = filter_dates(dates, months=months, years=years)

        # add dates to evalscript
        date_string = ', '.join([f'"{date}"' for date in dates_filt])
        preview_eval = PREVIEW_EVALSCRIPT % date_string

        # set time interval
        time_interval = [
            dt.datetime.strptime(date, '%Y-%m-%d').date()
            for date in [start_date, end_date]
        ]

        QgsMessageLog.logMessage('requesting preview image', level=Qgis.Info)

        preview_request = SentinelHubRequest(
            evalscript=preview_eval,
            data_folder='/tmp/mosaic_tests',
            input_data=[
                SentinelHubRequest.input_data(
                    data_collection=DataCollection.SENTINEL2_L2A,
                    time_interval=time_interval,
                    maxcc=max_cc)
            ],
            responses=[
                SentinelHubRequest.output_response('default', MimeType.TIFF)
            ],
            bbox=bbox,
            size=(512, get_image_dimension(bbox=bbox, width=512)),
            config=config)

        preview_request.get_data(save_data=True)
        progress.setValue(3)
        output_file = '/tmp/mosaic_tests' + '/' + preview_request.get_filename_list(
        )[0]

        # add file to QGIS
        default_layer_name_input = self.dockwidget.default_layer_name_input.text(
        )
        if len(default_layer_name_input) != 0:
            layer_name = default_layer_name_input
        else:
            layer_name = ' '.join([
                'orbits:', orbit_list_string, 'months:', month_string,
                'years:', year_string
            ])
        self.iface.addRasterLayer(output_file, layer_name)
        self.iface.messageBar().clearWidgets()

        return None