class KharifModelDialogTest(unittest.TestCase):
    """Test dialog works."""
    def setUp(self):
        """Runs before each test."""
        self.dialog = KharifModelDialog(None)

    def tearDown(self):
        """Runs after each test."""
        self.dialog = None

    def test_dialog_ok(self):
        """Test we can click OK."""

        button = self.dialog.button_box.button(QDialogButtonBox.Ok)
        button.click()
        result = self.dialog.result()
        self.assertEqual(result, QDialog.Accepted)

    def test_dialog_cancel(self):
        """Test we can click cancel."""
        button = self.dialog.button_box.button(QDialogButtonBox.Cancel)
        button.click()
        result = self.dialog.result()
        self.assertEqual(result, QDialog.Rejected)
    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

		:param icon_path: Path to the icon for this action. Can be a resource
			path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
		:type icon_path: str

		:param text: Text that should be shown in menu items for this action.
		:type text: str

		:param callback: Function to be called when the action is triggered.
		:type callback: function

		:param enabled_flag: A flag indicating if the action should be enabled
			by default. Defaults to True.
		:type enabled_flag: bool

		:param add_to_menu: Flag indicating whether the action should also
			be added to the menu. Defaults to True.
		:type add_to_menu: bool

		:param add_to_toolbar: Flag indicating whether the action should also
			be added to the toolbar. Defaults to True.
		:type add_to_toolbar: bool

		:param status_tip: Optional text to show in a popup when mouse pointer
			hovers over the action.
		:type status_tip: str

		:param parent: Parent widget for the new action. Defaults None.
		:type parent: QWidget

		:param whats_this: Optional text to show in the status bar when the
			mouse pointer hovers over the action.

		:returns: The action that was created. Note that the action is also
			added to self.actions list.
		:rtype: QAction
		"""

        # Create the dialog (after translation) and keep reference
        self.dlg = KharifModelDialog()

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action
class KharifModel:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

		:param iface: An interface instance that will be passed to this class
			which provides the hook by which you can manipulate the QGIS
			application at run time.
		:type iface: QgsInterface
		"""
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'KharifModel_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Water Balance Dashboard')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'WaterBalanceDashboard')
        self.toolbar.setObjectName(u'WaterBalanceDashboard')

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

		We implement this ourselves since we do not inherit QObject.

		:param message: String for translation.
		:type message: str, QString

		:returns: Translated version of message.
		:rtype: QString
		"""
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('WaterBalanceDashboard', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

		:param icon_path: Path to the icon for this action. Can be a resource
			path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
		:type icon_path: str

		:param text: Text that should be shown in menu items for this action.
		:type text: str

		:param callback: Function to be called when the action is triggered.
		:type callback: function

		:param enabled_flag: A flag indicating if the action should be enabled
			by default. Defaults to True.
		:type enabled_flag: bool

		:param add_to_menu: Flag indicating whether the action should also
			be added to the menu. Defaults to True.
		:type add_to_menu: bool

		:param add_to_toolbar: Flag indicating whether the action should also
			be added to the toolbar. Defaults to True.
		:type add_to_toolbar: bool

		:param status_tip: Optional text to show in a popup when mouse pointer
			hovers over the action.
		:type status_tip: str

		:param parent: Parent widget for the new action. Defaults None.
		:type parent: QWidget

		:param whats_this: Optional text to show in the status bar when the
			mouse pointer hovers over the action.

		:returns: The action that was created. Note that the action is also
			added to self.actions list.
		:rtype: QAction
		"""

        # Create the dialog (after translation) and keep reference
        self.dlg = KharifModelDialog()

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/water_balance_dashboard/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'Water Balance Dashboard'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&Water Balance Dashboard'),
                                        action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog and get user response by executing its event-loop
        self.dlg.show()
        if self.dlg.exec_() == QFileDialog.Rejected: return False

        start_time = time.time()

        self.progress_dlg = KharifModelProgressDialog()
        self.progress_dlg.show()
        self.progress_dlg.progress_text.setText(
            'Reading roster of grid-points...')
        self.progress_dlg.progress_bar.setValue(0)
        points_data = None
        if READ_FROM_POINTS_DATA_FILE:
            reader = csv.DictReader(open(REGION_POINTS_DATA_FILE_PATH, 'r'))
            points_data = list(reader)

        self.fetch_inputs()
        self.modelCalculator = KharifModelCalculator(self.et0,
                                                     self.crop_name,
                                                     points_data=points_data,
                                                     **self.input_layers)
        self.modelCalculator.calculate(self.rain, self.sowing_threshold,
                                       self.rain_year, self.end_date_indices,
                                       self.progress_dlg)

        if self.progress_dlg.aborted:
            self.progress_dlg.close()
            return
        self.progress_dlg.close()

        op = KharifModelOutputProcessor()

        for end_date_index in self.end_date_indices:
            layer_name = 'Deficit_on_day_' + str(end_date_index)
            save_file_path = os.path.join(REGION_DATA_FILES_PATH,
                                          layer_name + '.tif')
            op.save_pointwise_deficit_as_raster(
                self.iface, self.modelCalculator.points_grid, end_date_index,
                save_file_path, layer_name)

        print self.modelCalculator.rain_not_found_for
        print 'Rain not found for : ', len(
            self.modelCalculator.rain_not_found_for), ' circles'
        print("--- %s seconds ---" % (time.time() - start_time))

    def fetch_inputs(self):
        if INPUT_FROM_GRID_POINTS_ROSTER:
            district = self.dlg.district.currentText()
            self.input_layers = {
                'grid_points_roster_layer':
                self.iface.addVectorLayer(
                    ROSTER_SHAPEFILES_PATH + '/' + district +
                    '/Grid_points.shp', 'Grid-points', 'ogr')
            }
            self.iface.addVectorLayer(
                ROSTER_SHAPEFILES_PATH + '/' + district + '/District.shp',
                district + ' District', 'ogr')

        if self.progress_dlg.aborted: return

        self.progress_dlg.progress_text.setText('Fetching rainfall data...')
        self.progress_dlg.progress_bar.setValue(0)
        print 'Fetching rainfall data'
        with open(
                os.path.join(ET0_AND_RAINFALL_MASTER_FILES_PATH,
                             'Rainfall.csv'), 'r') as f:
            reader = csv.reader(f)
            reader.next()
            self.rain = {(row[0].lower(), row[1].lower(), row[2].lower(),
                          row[3]): numpy.array([float(v) for v in row[4:]])
                         for row in reader}

        self.progress_dlg.progress_text.setText('Fetching ET0 data...')
        self.progress_dlg.progress_bar.setValue(0)
        print 'Fetching ET0 data'
        with open(os.path.join(ET0_AND_RAINFALL_MASTER_FILES_PATH, 'ET0.csv'),
                  'r') as f:
            reader = csv.DictReader(f)
            self.et0 = {
                row['District'].lower(): list(
                    itertools.chain(
                        *[[float(row['Jun'])] * 30, [float(row['Jul'])] *
                          31, [float(row['Aug'])] * 31, [float(row['Sep'])] *
                          30, [float(row['Oct'])] * 31, [float(row['Nov'])] *
                          30, [float(row['Dec'])] * 31, [float(row['Jan'])] *
                          31, [float(row['Feb'])] * 28, [float(row['Mar'])] *
                          31, [float(row['Apr'])] * 30, [float(row['May'])] *
                          31]))
                for row in reader
            }

        self.sowing_threshold = self.dlg.sowing_threshold.value()
        self.monsoon_end_date_index = self.dlg.monsoon_end.value() + 122
        self.crop_name = self.dlg.selected_crop.currentText()
        self.rain_year = self.dlg.rainfall_year.currentText()
        self.end_date_indices = self.dlg.end_date_indices
        return
class KharifModel:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

		:param iface: An interface instance that will be passed to this class
			which provides the hook by which you can manipulate the QGIS
			application at run time.
		:type iface: QgsInterface
		"""
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'KharifModel_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Kharif Model - all crop - all year - zone only')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'KharifModelMulticrop')
        self.toolbar.setObjectName(u'KharifModelMulticrop')

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

		We implement this ourselves since we do not inherit QObject.

		:param message: String for translation.
		:type message: str, QString

		:returns: Translated version of message.
		:rtype: QString
		"""
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('KharifModelMulticrop', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

		:param icon_path: Path to the icon for this action. Can be a resource
			path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
		:type icon_path: str

		:param text: Text that should be shown in menu items for this action.
		:type text: str

		:param callback: Function to be called when the action is triggered.
		:type callback: function

		:param enabled_flag: A flag indicating if the action should be enabled
			by default. Defaults to True.
		:type enabled_flag: bool

		:param add_to_menu: Flag indicating whether the action should also
			be added to the menu. Defaults to True.
		:type add_to_menu: bool

		:param add_to_toolbar: Flag indicating whether the action should also
			be added to the toolbar. Defaults to True.
		:type add_to_toolbar: bool

		:param status_tip: Optional text to show in a popup when mouse pointer
			hovers over the action.
		:type status_tip: str

		:param parent: Parent widget for the new action. Defaults None.
		:type parent: QWidget

		:param whats_this: Optional text to show in the status bar when the
			mouse pointer hovers over the action.

		:returns: The action that was created. Note that the action is also
			added to self.actions list.
		:rtype: QAction
		"""

        # Create the dialog (after translation) and keep reference
        self.dlg = KharifModelDialog(crops=dict_crop.keys())

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/KharifModelMulticrop/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Kharif Model - all crop - all year - zone only'),
            callback=self.run,
            parent=self.iface.mainWindow())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&Kharif Model - all crop - all year - zone only'),
                action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def run(self):
        """Run method that performs all the real work"""

        start_time = time.time()

        if PLUGIN_MODE == 'DEBUG':
            if not os.path.exists(DEBUG_BASE_FOLDER_PATH):
                raise Exception(
                    'Set DEBUG_BASE_FOLDER_PATH for the debug dataset')
            paths = [DEBUG_BASE_FOLDER_PATH]
        elif PLUGIN_MODE == 'REAL':
            paths = ['']
        else:
            if not os.path.exists(TEST_SUITE_BASE_FOLDER_PATH):
                raise Exception(
                    'Set TEST_SUITE_BASE_FOLDER_PATH for the debug dataset')
            paths = [
                os.path.join(TEST_SUITE_BASE_FOLDER_PATH, base_path)
                for base_path in os.listdir(TEST_SUITE_BASE_FOLDER_PATH)
            ]
            filter(lambda p: os.path.isdir(p), paths)
        path_num = 0
        for path in paths:
            path_num += 1
            # if os.path.basename(path) == '503_ptp-1_03': continue
            if not os.path.exists(os.path.join(path, 'Zones.shp')): continue
            if self.fetch_inputs(path) is False: return
            # return
            print 'cluster', os.path.basename(path)
            # print self.rain['2013'].keys();	return
            year_num = 0
            print 'years', self.rain.keys()
            for year in self.rain:
                # if year_num > 0: break
                year_num += 1
                print 'checking whether already processed for year', year
                if os.path.exists(
                        os.path.join(path, year + '_' +
                                     ZONEWISE_BUDGET_CSV_FILENAME)):
                    continue
                print 'initializing calculations'
                self.modelCalculator = KharifModelCalculator(
                    self.path, self.et0, **self.input_layers)
                rain_input_dict = {
                    circle: {
                        'daily_rain': self.rain[year][circle]
                    }
                    for circle in self.rain[year]
                }
                rain_sum_input_dict = {
                    circle: {
                        'year': year,
                        'sum': self.rain_sum_monsoon[year][circle]
                    }
                    for circle in self.rain_sum_monsoon[year]
                }
                self.modelCalculator.calculate(
                    rain_input_dict,
                    self.crop_names,
                    self.sowing_threshold,
                    monsoon_end_date_index=self.monsoon_end_date_index,
                    cluster=str(path_num) + '/' + str(len(paths) - 1),
                    year=str(year_num) + '/' + str(len(self.rain.keys())))

                pointwise_output_csv_filepath = os.path.join(
                    self.base_path, year + '_' + POINTWISE_OUTPUT_CSV_FILENAME)

                op = KharifModelOutputProcessor()
                # Removed for urgent case of zone-level outputs only
                # op.output_point_results_to_csv	(
                #   self.modelCalculator.output_grid_points,
                # 	pointwise_output_csv_filepath,
                # 	crops=[crop.name for crop in self.modelCalculator.crops]
                # )
                zonewise_budgets = op.compute_zonewise_budget(
                    self.modelCalculator.zone_points_dict,
                    self.modelCalculator.
                    zone_points_dict_ag_missing,  #removed for urgent village charts (17-11-2018)
                    self.modelCalculator.zone_points_dict_current_fallow,
                    self.modelCalculator.zone_points_dict_non_ag_missing_LU,
                    self.modelCalculator.zones_layer)
                print self.circle_avg_year_dict
                village_avg_year_dict = {
                    feature['VIL_NAME']:
                    self.circle_avg_year_dict[feature['Circle'].lower()]
                    for feature in
                    self.modelCalculator.zones_layer.feature_dict.values()
                }
                print village_avg_year_dict
                op.output_zonewise_budget_to_csv(
                    zonewise_budgets, self.modelCalculator.crops,
                    self.rabi_crop_names, self.modelCalculator.currnet_fallow,
                    self.modelCalculator.LULC_pseudo_crops.values(),
                    os.path.join(self.base_path,
                                 year + '_' + ZONEWISE_BUDGET_CSV_FILENAME),
                    rain_sum_input_dict, year, village_avg_year_dict)

                # Removed for urgent case of zone-level outputs only
                # op.compute_and_output_cadastral_vulnerability_to_csv(
                # 	self.crop_names,
                # 	self.modelCalculator.output_cadastral_points,
                # 	os.path.join(self.base_path, year + '_' + CADESTRAL_VULNERABILITY_CSV_FILENAME)
                # )

                # kharif_model_crop_end_output_layer = \
                # 	op.render_and_save_pointwise_output_layer(
                # 		pointwise_output_csv_filepath,
                # 		'Kharif Model Crop End Output',
                # 		'Crop duration PET-AET',
                # 		self.output_configuration['graduated_rendering_interval_points'],
                # 		shapefile_path=os.path.join(self.base_path, 'kharif_crop_duration_et_deficit.shp')
                # 	)
                # if(crop in long_kharif_crops):
                # 	kharif_model_monsoon_end_output_layer = \
                # 		op.render_and_save_pointwise_output_layer(
                # 			pointwise_output_csv_filepath,
                # 			'Kharif Model Monsoon End Output',
                # 			'Monsoon PET-AET',
                # 			self.output_configuration['graduated_rendering_interval_points'],
                # 			shapefile_path=os.path.join(self.base_path, 'kharif_monsoon_et_deficit.shp')
                # 		)

                # Removed for urgent case of zone-level outputs only
                # for i in range(len(self.crop_names)):
                # 	op.compute_and_display_cadastral_vulnerability(
                # 		self.modelCalculator.cadastral_layer,
                # 		self.modelCalculator.output_grid_points,
                # 		self.modelCalculator.output_cadastral_points,
                # 		i,
                # 		self.crop_names[i],
                # 		self.path
                # 	)

            QgsMapLayerRegistry.instance().removeMapLayers([
                self.input_layers['zones_layer'].id(),
                self.input_layers['soil_layer'].id(),
                self.input_layers['lulc_layer'].id(),
                self.input_layers['slope_layer'].id(),
                # self.input_layers['cadastral_layer'].id()
            ])
        print("KM--- %s seconds ---" % (time.time() - start_time))
        print self.plugin_dir

    # self.iface.actionHideAllLayers().trigger()
    # 	self.iface.legendInterface().setLayerVisible(self.input_layers['zones_layer'], True)
    # 	if 'drainage_layer' in locals():	self.iface.legendInterface().setLayerVisible(self.input_layers['drainage_layer'], True)
    # 	if (crop in long_kharif_crops):		self.iface.legendInterface().setLayerVisible(kharif_model_monsoon_end_output_layer, True)
    # 	self.iface.legendInterface().setLayerVisible(kharif_model_crop_end_output_layer, True)
    # 	self.iface.mapCanvas().setExtent(self.input_layers['zones_layer'].extent())
    # 	self.iface.mapCanvas().mapRenderer().setDestinationCrs(self.input_layers['zones_layer'].crs())

    #~ if self.dlg.save_image_group_box.isChecked():
    #~ QTimer.singleShot(1000, lambda :	self.iface.mapCanvas().saveAsImage(self.dlg.save_image_filename.text()))

    def fetch_inputs(self, path):
        def set_et0_from_et0_file_data(et0_file_data):
            et0 = []
            for i in range(0, len(et0_file_data)):
                if (i in [0, 3, 5, 10]): et0.extend([et0_file_data[i]] * 30)
                elif i == 8: et0.extend([et0_file_data[i]] * 28)
                else: et0.extend([et0_file_data[i]] * 31)
            return et0

        self.rain = OrderedDict()
        if path != '':
            self.base_path = self.path = path
            self.input_layers = {}
            self.input_layers['zones_layer'] = self.iface.addVectorLayer(
                os.path.join(path, 'Zones.shp'), 'Zones', 'ogr')
            self.input_layers['soil_layer'] = self.iface.addVectorLayer(
                os.path.join(path, 'Soil.shp'), 'Soil Cover', 'ogr')
            self.input_layers['lulc_layer'] = self.iface.addVectorLayer(
                os.path.join(path, 'LULC.shp'), 'Land-Use-Land-Cover', 'ogr')
            # self.input_layers['cadastral_layer'] = self.iface.addVectorLayer(os.path.join(path, 'Cadastral.shp'), 'Cadastral Map', 'ogr')
            self.input_layers['slope_layer'] = self.iface.addRasterLayer(
                os.path.join(path, 'Slope.tif'), 'Slope')
            #~ self.input_layers['drainage_layer'] = self.iface.addRasterLayer(os.path.join(path, 'Drainage.shp'), 'Drainage', 'ogr')
            data_dir = os.path.join(self.plugin_dir, 'Data')
            # self.input_layers['soil_layer'] = self.iface.addVectorLayer(os.path.join(data_dir, 'soil utm.shp'), 'Soil Cover', 'ogr')
            # self.input_layers['lulc_layer'] = self.iface.addVectorLayer(os.path.join(data_dir, 'lulc utm.shp'), 'Land-Use-Land-Cover', 'ogr')

            # csvreader=csv.reader(open(os.path.join(path, RAINFALL_CSV_FILENAME)))
            with open(os.path.join(path, 'Rainfall.csv')) as f:
                csvreader_for_avg_year = csv.DictReader(f)
                self.circle_avg_year_dict = {
                    row['Circle'].lower(): row['Year']
                    for row in csvreader_for_avg_year
                }
                print self.circle_avg_year_dict
            csvreader = csv.reader(
                open(
                    os.path.join(TEST_SUITE_BASE_FOLDER_PATH,
                                 'Rainfall_all.csv'))
            )  # FOR urgent village charts (17-11-2018)
            next(csvreader)
            # self.rain = OrderedDict((row[0].lower(),{'year': row[1],'daily_rain':[float(val) for val in row[2:]]}) for row in csvreader)
            # self.rain['0'] = self.rain[next(iter(self.rain.keys()))]
            ###For multiple rainfall years use the following###
            self.rain = {}
            years = []
            dist_taluka_year_tuples = set([])
            for row in csvreader:
                # print row
                if row[3] not in self.rain:
                    years += [row[3]]
                    self.rain[row[3]] = {}
                # self.rain[row[1]][row[0].lower()] = [float(val) for val in row[2:]]
                self.rain[row[3]][(row[0].lower(), row[1].lower(),
                                   row[2].lower())] = [
                                       float(val) for val in row[4:]
                                   ]
                dist_taluka_year_tuples.add(
                    (row[0].lower(), row[1].lower(), row[3]))

            for dty in dist_taluka_year_tuples:
                for k in self.rain[dty[2]]:
                    if (k[0], k[1]) == (dty[0], dty[1]):
                        # print zc[3], zc[0], zc[1]
                        self.rain[dty[2]][(dty[0], dty[1],
                                           '0')] = self.rain[dty[2]][(k[0],
                                                                      k[1],
                                                                      k[2])]
                        break

            # return

            et0_file_data = [
                float(row["ET0"]) for row in csv.DictReader(
                    open(os.path.join(path, ET0_CSV_FILENAME)))
            ]
            self.et0 = set_et0_from_et0_file_data(et0_file_data)
            self.sowing_threshold = DEFAULT_SOWING_THRESHOLD
            self.monsoon_end_date_index = MONSOON_END_DATE_INDEX
            self.rain_sum_monsoon = {
                year: {
                    circle:
                    sum(self.rain[year][circle]
                        [START_DATE_INDEX:self.monsoon_end_date_index + 1])
                    for circle in self.rain[year].keys()
                }
                for year in self.rain.keys()
            }
            # self.rain_sum_monsoon={key:{'year':self.rain[key]['year'],'sum':sum(self.rain[key]['daily_rain'][START_DATE_INDEX : self.monsoon_end_date_index+1])} for key in self.rain.keys()}

            # if not OVERRIDE_FILECROPS_BY_DEBUG_OR_TEST_CROPS and os.path.exists(os.path.join(path, CROPS_FILENAME)):
            # 	self.crop_names = open(os.path.join(path, CROPS_FILENAME), 'r').read().split(',')
            # 	print (self.crop_names)
            # 	if len(self.crop_names) == 0 :	raise Exception('No crop selected')
            # else:
            # 	self.crop_names = DEBUG_OR_TEST_CROPS
            # self.rabi_crop_names = DEBUG_OR_TEST_RABI_CROPS
            self.crop_names = dict_crop
            self.rabi_crop_names = dict_rabi_crop
            self.output_configuration = {}
            # self.output_configuration['graduated_rendering_interval_points'] = DEBUG_OR_TEST_GRADUATED_RENDERING_INTERVAL_POINTS

        else:
            self.dlg.show()
            if self.dlg.exec_() == QFileDialog.Rejected: return False

            path = self.path = self.base_path = self.dlg.folder_path.text()
            self.input_layers = {}
            self.input_layers['zones_layer'] = self.iface.addVectorLayer(
                self.dlg.zones_layer_filename.text(), 'Zones', 'ogr')
            self.input_layers['soil_layer'] = self.iface.addVectorLayer(
                self.dlg.soil_layer_filename.text(), 'Soil Cover', 'ogr')
            self.input_layers['lulc_layer'] = self.iface.addVectorLayer(
                self.dlg.lulc_layer_filename.text(), 'Land-Use-Land-Cover',
                'ogr')
            self.input_layers['cadastral_layer'] = self.iface.addVectorLayer(
                self.dlg.cadastral_layer_filename.text(), 'Cadastral Map',
                'ogr')
            self.input_layers['slope_layer'] = self.iface.addRasterLayer(
                self.dlg.slope_layer_filename.text(), 'Slope')
            if self.dlg.drainage_layer_filename.text() != '':
                self.drainage_layer = self.iface.addVectorLayer(
                    self.dlg.drainage_layer_filename.text(), 'Drainage', 'ogr')

            csvreader = csv.reader(
                open(str(self.dlg.rainfall_csv_filename.text())))
            next(csvreader)
            # self.rain = OrderedDict((row[0].lower(),{'year': row[1],'daily_rain':[float(val) for val in row[2:]]}) for row in csvreader)
            # self.rain['0'] = self.rain[next(iter(self.rain.keys()))]
            ###For multiple rainfall years use the following###
            self.rain = {}
            years = []
            for row in csvreader:
                if row[1] not in self.rain:
                    years += row[1]
                    self.rain[row[1]] = {}
                self.rain[row[1]][row[0].lower()] = [
                    float(val) for val in row[2:]
                ]
            for y in years:
                self.rain[y]['0'] = self.rain[y][next(iter(
                    self.rain[y].keys()))]
            # self.rain = OrderedDict(
            # 	(row[1].lower(), {row[0].lower(): [float(val) for val in row[2:]]}) for row in csvreader
            # )
            # print 'circles', self.rain['2013'].keys()
            # self.rain['0'] = self.rain[next(iter(self.rain.keys()))]

            et0_file_data = [
                float(row["ET0"]) for row in csv.DictReader(
                    open(os.path.join(path, ET0_CSV_FILENAME)))
            ]
            self.et0 = set_et0_from_et0_file_data(et0_file_data)
            self.sowing_threshold = self.dlg.sowing_threshold.value()
            self.monsoon_end_date_index = self.dlg.monsoon_end.value() + 122
            self.rain_sum_monsoon = {
                year: {
                    circle:
                    sum(self.rain[year][circle]
                        [START_DATE_INDEX:self.monsoon_end_date_index + 1])
                    for circle in self.rain[year].keys()
                }
                for year in self.rain.keys()
            }
            # 'year':self.rain[key]['year'],'sum':sum(self.rain[key]['daily_rain'][START_DATE_INDEX : self.monsoon_end_date_index+1])} for circle in self.rain.keys()}

            # self.crop_names = self.dlg.crops
            # self.rabi_crop_names = self.dlg.rabi_crops
            # for urgent requirement of all crops
            self.crop_names = dict_crop
            self.rabi_crop_names = dict_rabi_crop
            if len(self.crop_names) == 0: raise Exception('No crop selected')
            self.output_configuration = {}
Beispiel #5
0
class KharifModel:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

		:param iface: An interface instance that will be passed to this class
			which provides the hook by which you can manipulate the QGIS
			application at run time.
		:type iface: QgsInterface
		"""
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'KharifModel_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Kharif Model')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'KharifModel')
        self.toolbar.setObjectName(u'KharifModel')

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

		We implement this ourselves since we do not inherit QObject.

		:param message: String for translation.
		:type message: str, QString

		:returns: Translated version of message.
		:rtype: QString
		"""
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('KharifModel', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

		:param icon_path: Path to the icon for this action. Can be a resource
			path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
		:type icon_path: str

		:param text: Text that should be shown in menu items for this action.
		:type text: str

		:param callback: Function to be called when the action is triggered.
		:type callback: function

		:param enabled_flag: A flag indicating if the action should be enabled
			by default. Defaults to True.
		:type enabled_flag: bool

		:param add_to_menu: Flag indicating whether the action should also
			be added to the menu. Defaults to True.
		:type add_to_menu: bool

		:param add_to_toolbar: Flag indicating whether the action should also
			be added to the toolbar. Defaults to True.
		:type add_to_toolbar: bool

		:param status_tip: Optional text to show in a popup when mouse pointer
			hovers over the action.
		:type status_tip: str

		:param parent: Parent widget for the new action. Defaults None.
		:type parent: QWidget

		:param whats_this: Optional text to show in the status bar when the
			mouse pointer hovers over the action.

		:returns: The action that was created. Note that the action is also
			added to self.actions list.
		:rtype: QAction
		"""

        # Create the dialog (after translation) and keep reference
        self.dlg = KharifModelDialog(crops=dict_crop.keys())

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/KharifModel/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'Kharif Model'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&Kharif Model'), action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def run(self):
        """Run method that performs all the real work"""

        #~path = 'C:/Users/Sudhanshu/Downloads/Hivre_Bajar'
        #~ path = 'C:/Users/Rahul/Desktop/Gondala1'
        #~ path = 'C:/Users/Rahul/Desktop/BW_new'
        path = ''
        debugging = path != ''
        if debugging:
            zones_layer = self.iface.addVectorLayer(path + '/Zones.shp',
                                                    'Zones', 'ogr')
            soil_layer = self.iface.addVectorLayer(path + '/Soil.shp',
                                                   'Soil Cover', 'ogr')
            lulc_layer = self.iface.addVectorLayer(path + '/LULC.shp',
                                                   'Land-Use-Land-Cover',
                                                   'ogr')
            cadastral_layer = self.iface.addVectorLayer(
                path + '/Cadastral.shp', 'Cadastral Map', 'ogr')
            slope_layer = self.iface.addRasterLayer(path + '/Slope.tif',
                                                    'Slope')
            #~ drainage_layer = self.iface.addRasterLayer(path + '/Drainage.shp', 'Drainage', 'ogr')

            rainfall_csv = path + '/Rainfall.csv'
            sowing_threshold = 30
            crop = 'soyabean'
            interval_points = [50, 100]
            monsoon_end_date_index = MONSOON_END_DATE_INDEX

        else:
            self.dlg.show()
            if self.dlg.exec_() == QFileDialog.Rejected: return

            path = self.dlg.folder_path.text()
            zones_layer = self.iface.addVectorLayer(
                self.dlg.zones_layer_filename.text(), 'Zones', 'ogr')
            soil_layer = self.iface.addVectorLayer(
                self.dlg.soil_layer_filename.text(), 'Soil Cover', 'ogr')
            lulc_layer = self.iface.addVectorLayer(
                self.dlg.lulc_layer_filename.text(), 'Land-Use-Land-Cover',
                'ogr')
            cadastral_layer = self.iface.addVectorLayer(
                self.dlg.cadastral_layer_filename.text(), 'Cadastral Map',
                'ogr')
            slope_layer = self.iface.addRasterLayer(
                self.dlg.slope_layer_filename.text(), 'Slope')
            if self.dlg.drainage_layer_filename.text() != '':
                drainage_layer = self.iface.addRasterLayer(
                    self.dlg.drainage_layer_filename.text(), 'Drainage', 'ogr')

            rainfall_csv = self.dlg.rainfall_csv_filename.text()
            sowing_threshold = self.dlg.sowing_threshold.value()
            monsoon_end_date_index = self.dlg.monsoon_end.value() + 123
            crop = self.dlg.crop_combo_box.currentText()
            interval_points = [
                int(
                    self.dlg.colour_code_intervals_list_widget.item(
                        i).text().split('-')[0])
                for i in range(
                    1, self.dlg.colour_code_intervals_list_widget.count())
            ]

            #~ print path, zones_layer, soil_layer, lulc_layer, cadastral_layer, slope_layer, drainage_layer, rainfall_csv

        #~ start_qdate = self.dlg.from_date_edit.date()
        #~ date_with_index_0 = QDate(start_qdate.year(), 6, 1).dayOfYear()
        #~ start_date_index = start_qdate.dayOfYear() - date_with_index_0
        #~ end_qdate = self.dlg.to_date_edit.date()
        #~ end_date_index = end_qdate.dayOfYear() - date_with_index_0

        pointwise_output_csv_filename = '/kharif_model_pointwise_output.csv'
        zonewise_budget_csv_filename = '/kharif_model_zonewise_budget.csv'
        zonewise_budget_csv_filename_LU = '/kharif_model_zonewise_LU_budget.csv'
        zonewise_budget_areawise_csv_filename = '/kharif_model_zonewise_budget_area.csv'
        cadastral_vulnerability_csv_filename = '/kharif_model_cadastral_vulnerability.csv'
        model_calculator = KharifModelCalculator(path, zones_layer, soil_layer,
                                                 lulc_layer, cadastral_layer,
                                                 slope_layer, rainfall_csv)

        model_calculator.calculate(crop, pointwise_output_csv_filename,
                                   zonewise_budget_csv_filename,
                                   zonewise_budget_csv_filename_LU,
                                   zonewise_budget_areawise_csv_filename,
                                   cadastral_vulnerability_csv_filename,
                                   sowing_threshold, monsoon_end_date_index)
        uri = 'file:///' + path + pointwise_output_csv_filename + '?delimiter=%s&crs=epsg:32643&xField=%s&yField=%s' % (
            ',', 'X', 'Y')
        kharif_model_output_layer = QgsVectorLayer(uri, 'Kharif Model Output',
                                                   'delimitedtext')
        graduated_symbol_renderer_range_list = []
        ET_D_max = max([
            point.budget.PET_minus_AET_crop_end
            for point in model_calculator.output_grid_points
        ])
        opacity = 1
        intervals_count = self.dlg.colour_code_intervals_list_widget.count()
        for i in range(intervals_count):
            percent_interval_start_text, percent_interval_end_text = self.dlg.colour_code_intervals_list_widget.item(
                i).text().split('-')
            interval_min = 0 if percent_interval_start_text == '0' else (
                int(percent_interval_start_text) * ET_D_max / 100.0 + 0.01)
            interval_max = (int(percent_interval_end_text) * ET_D_max / 100.0)
            label = "{0:.2f} - {1:.2f}".format(interval_min, interval_max)
            colour = QColor(
                int(255 * (1 - (i + 1.0) / (intervals_count + 1.0))), 0,
                0)  # +1 done to tackle boundary cases
            symbol = QgsSymbolV2.defaultSymbol(
                kharif_model_output_layer.geometryType())
            symbol.setColor(colour)
            symbol.setAlpha(opacity)
            interval_range = QgsRendererRangeV2(interval_min, interval_max,
                                                symbol, label)
            graduated_symbol_renderer_range_list.append(interval_range)
        renderer = QgsGraduatedSymbolRendererV2(
            '', graduated_symbol_renderer_range_list)
        renderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
        renderer.setClassAttribute('Crop duration PET-AET')
        kharif_model_output_layer.setRendererV2(renderer)
        QgsMapLayerRegistry.instance().addMapLayer(kharif_model_output_layer)

        QgsVectorFileWriter.writeAsVectorFormat(
            kharif_model_output_layer, path + '/kharif_et_deficit.shp',
            "utf-8", None, "ESRI Shapefile")

        #Dislpaying for long kharif crops
        if (crop in long_kharif_crops):
            kharif_model_monsoon_end_output_layer = QgsVectorLayer(
                uri, 'Kharif Model Monsoon End Output', 'delimitedtext')
            graduated_symbol_renderer_range_list = []
            ET_D_max = max([
                point.budget.PET_minus_AET_monsoon_end
                for point in model_calculator.output_grid_points
            ])
            opacity = 1
            intervals_count = self.dlg.colour_code_intervals_list_widget.count(
            )
            geometry_type = kharif_model_monsoon_end_output_layer.geometryType(
            )
            for i in range(intervals_count):
                percent_interval_start_text, percent_interval_end_text = self.dlg.colour_code_intervals_list_widget.item(
                    i).text().split('-')
                interval_min = 0 if percent_interval_start_text == '0' else (
                    int(percent_interval_start_text) * ET_D_max / 100.0 + 0.01)
                interval_max = (int(percent_interval_end_text) * ET_D_max /
                                100.0)
                label = "{0:.2f} - {1:.2f}".format(interval_min, interval_max)
                colour = QColor(
                    int(255 * (1 - (i + 1.0) / (intervals_count + 1.0))), 0,
                    0)  # +1 done to tackle boundary cases
                symbol = QgsSymbolV2.defaultSymbol(geometry_type)
                symbol.setColor(colour)
                symbol.setAlpha(opacity)
                interval_range = QgsRendererRangeV2(interval_min, interval_max,
                                                    symbol, label)
                graduated_symbol_renderer_range_list.append(interval_range)
            renderer = QgsGraduatedSymbolRendererV2(
                '', graduated_symbol_renderer_range_list)
            renderer.setMode(QgsGraduatedSymbolRendererV2.EqualInterval)
            renderer.setClassAttribute('Monsoon PET-AET')
            kharif_model_monsoon_end_output_layer.setRendererV2(renderer)
            QgsMapLayerRegistry.instance().addMapLayer(
                kharif_model_monsoon_end_output_layer)
            QgsVectorFileWriter.writeAsVectorFormat(
                kharif_model_monsoon_end_output_layer,
                path + '/kharif_post_monsoon_et_deficit.shp', "utf-8", None,
                "ESRI Shapefile")

        self.iface.actionHideAllLayers().trigger()
        self.iface.legendInterface().setLayerVisible(zones_layer, True)
        if 'drainage_layer' in locals():
            self.iface.legendInterface().setLayerVisible(drainage_layer, True)
        if (crop in long_kharif_crops):
            self.iface.legendInterface().setLayerVisible(
                kharif_model_monsoon_end_output_layer, True)
        self.iface.legendInterface().setLayerVisible(kharif_model_output_layer,
                                                     True)
        self.iface.mapCanvas().setExtent(zones_layer.extent())
        self.iface.mapCanvas().mapRenderer().setDestinationCrs(
            zones_layer.crs())

        self.iface.mapCanvas().refresh()

        if self.dlg.save_image_group_box.isChecked():
            QTimer.singleShot(
                1000, lambda: self.iface.mapCanvas().saveAsImage(
                    self.dlg.save_image_filename.text()))
Beispiel #6
0
class KharifModel:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

		:param iface: An interface instance that will be passed to this class
			which provides the hook by which you can manipulate the QGIS
			application at run time.
		:type iface: QgsInterface
		"""
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'KharifModel_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Kharif Model - Multicrop')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'KharifModelMulticrop')
        self.toolbar.setObjectName(u'KharifModelMulticrop')

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

		We implement this ourselves since we do not inherit QObject.

		:param message: String for translation.
		:type message: str, QString

		:returns: Translated version of message.
		:rtype: QString
		"""
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('KharifModelMulticrop', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

		:param icon_path: Path to the icon for this action. Can be a resource
			path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
		:type icon_path: str

		:param text: Text that should be shown in menu items for this action.
		:type text: str

		:param callback: Function to be called when the action is triggered.
		:type callback: function

		:param enabled_flag: A flag indicating if the action should be enabled
			by default. Defaults to True.
		:type enabled_flag: bool

		:param add_to_menu: Flag indicating whether the action should also
			be added to the menu. Defaults to True.
		:type add_to_menu: bool

		:param add_to_toolbar: Flag indicating whether the action should also
			be added to the toolbar. Defaults to True.
		:type add_to_toolbar: bool

		:param status_tip: Optional text to show in a popup when mouse pointer
			hovers over the action.
		:type status_tip: str

		:param parent: Parent widget for the new action. Defaults None.
		:type parent: QWidget

		:param whats_this: Optional text to show in the status bar when the
			mouse pointer hovers over the action.

		:returns: The action that was created. Note that the action is also
			added to self.actions list.
		:rtype: QAction
		"""

        # Create the dialog (after translation) and keep reference
        self.dlg = KharifModelDialog(crops=dict_crop.keys())

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/KharifModelMulticrop/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'Kharif Model - Multicrop'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&Kharif Model - Multicrop'),
                                        action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def run(self):
        """Run method that performs all the real work"""

        if PLUGIN_MODE == 'DEBUG':
            if not os.path.exists(DEBUG_BASE_FOLDER_PATH):
                raise Exception(
                    'Set DEBUG_BASE_FOLDER_PATH for the debug dataset')
            paths = [DEBUG_BASE_FOLDER_PATH]
        elif PLUGIN_MODE == 'REAL':
            paths = ['']
        else:
            if not os.path.exists(TEST_SUITE_BASE_FOLDER_PATH):
                raise Exception(
                    'Set TEST_SUITE_BASE_FOLDER_PATH for the debug dataset')
            paths = [
                base_path
                for base_path in os.listdir(TEST_SUITE_BASE_FOLDER_PATH)
                if os.path.isdir(base_path)
            ]
        for path in paths:
            if self.fetch_inputs(path) is False: return

            self.modelCalculator = KharifModelCalculator(
                self.path, self.et0, **self.input_layers)
            self.modelCalculator.calculate(
                self.rain,
                self.crop_names,
                self.sowing_threshold,
                monsoon_end_date_index=self.monsoon_end_date_index)

            pointwise_output_csv_filepath = os.path.join(
                self.base_path, POINTWISE_OUTPUT_CSV_FILENAME)

            op = KharifModelOutputProcessor()
            op.output_point_results_to_csv(
                self.modelCalculator.output_grid_points,
                pointwise_output_csv_filepath,
                crops=[crop.name for crop in self.modelCalculator.crops])
            zonewise_budgets = op.compute_zonewise_budget(
                self.modelCalculator.zone_points_dict,
                self.modelCalculator.zone_points_dict_current_fallow,
                self.modelCalculator.zone_points_dict_diff_LU,
                self.modelCalculator.zones_layer)
            op.output_zonewise_budget_to_csv(
                zonewise_budgets, self.modelCalculator.crops,
                self.rabi_crop_names, self.modelCalculator.currnet_fallow,
                self.modelCalculator.LULC_pseudo_crops.values(),
                os.path.join(self.base_path, ZONEWISE_BUDGET_CSV_FILENAME),
                sum(self.rain[START_DATE_INDEX:self.monsoon_end_date_index +
                              1]))
            op.compute_and_output_cadastral_vulnerability_to_csv(
                self.crop_names, self.modelCalculator.output_cadastral_points,
                os.path.join(self.base_path,
                             CADESTRAL_VULNERABILITY_CSV_FILENAME))
            # kharif_model_crop_end_output_layer = \
            # 	op.render_and_save_pointwise_output_layer(
            # 		pointwise_output_csv_filepath,
            # 		'Kharif Model Crop End Output',
            # 		'Crop duration PET-AET',
            # 		self.output_configuration['graduated_rendering_interval_points'],
            # 		shapefile_path=os.path.join(self.base_path, 'kharif_crop_duration_et_deficit.shp')
            # 	)
            # if(crop in long_kharif_crops):
            # 	kharif_model_monsoon_end_output_layer = \
            # 		op.render_and_save_pointwise_output_layer(
            # 			pointwise_output_csv_filepath,
            # 			'Kharif Model Monsoon End Output',
            # 			'Monsoon PET-AET',
            # 			self.output_configuration['graduated_rendering_interval_points'],
            # 			shapefile_path=os.path.join(self.base_path, 'kharif_monsoon_et_deficit.shp')
            # 		)
            for i in range(len(self.crop_names)):
                op.compute_and_display_cadastral_vulnerability(
                    self.modelCalculator.cadastral_layer,
                    self.modelCalculator.output_grid_points,
                    self.modelCalculator.output_cadastral_points, i,
                    self.crop_names[i], self.path)

    # self.iface.actionHideAllLayers().trigger()
    # 	self.iface.legendInterface().setLayerVisible(self.input_layers['zones_layer'], True)
    # 	if 'drainage_layer' in locals():	self.iface.legendInterface().setLayerVisible(self.input_layers['drainage_layer'], True)
    # 	if (crop in long_kharif_crops):		self.iface.legendInterface().setLayerVisible(kharif_model_monsoon_end_output_layer, True)
    # 	self.iface.legendInterface().setLayerVisible(kharif_model_crop_end_output_layer, True)
    # 	self.iface.mapCanvas().setExtent(self.input_layers['zones_layer'].extent())
    # 	self.iface.mapCanvas().mapRenderer().setDestinationCrs(self.input_layers['zones_layer'].crs())

    #~ if self.dlg.save_image_group_box.isChecked():
    #~ QTimer.singleShot(1000, lambda :	self.iface.mapCanvas().saveAsImage(self.dlg.save_image_filename.text()))

    def fetch_inputs(self, path):
        def set_et0_from_et0_file_data(et0_file_data):
            et0 = []
            for i in range(0, len(et0_file_data)):
                if (i in [0, 3, 5, 10]): et0.extend([et0_file_data[i]] * 30)
                elif i == 8: et0.extend([et0_file_data[i]] * 28)
                else: et0.extend([et0_file_data[i]] * 31)
            return et0

        if path != '':
            self.base_path = self.path = path
            self.input_layers = {}
            self.input_layers['zones_layer'] = self.iface.addVectorLayer(
                os.path.join(path, 'Zones.shp'), 'Zones', 'ogr')
            self.input_layers['soil_layer'] = self.iface.addVectorLayer(
                os.path.join(path, 'Soil.shp'), 'Soil Cover', 'ogr')
            self.input_layers['lulc_layer'] = self.iface.addVectorLayer(
                os.path.join(path, 'LULC.shp'), 'Land-Use-Land-Cover', 'ogr')
            self.input_layers['cadastral_layer'] = self.iface.addVectorLayer(
                os.path.join(path, 'Cadastral.shp'), 'Cadastral Map', 'ogr')
            self.input_layers['slope_layer'] = self.iface.addRasterLayer(
                os.path.join(path, 'Slope.tif'), 'Slope')
            #~ self.input_layers['drainage_layer'] = self.iface.addRasterLayer(os.path.join(path, 'Drainage.shp'), 'Drainage', 'ogr')

            self.rain = [
                float(row["Rainfall"]) for row in csv.DictReader(
                    open(os.path.join(path, RAINFALL_CSV_FILENAME)))
            ]
            et0_file_data = [
                float(row["ET0"]) for row in csv.DictReader(
                    open(os.path.join(path, ET0_CSV_FILENAME)))
            ]
            self.et0 = set_et0_from_et0_file_data(et0_file_data)
            self.sowing_threshold = DEFAULT_SOWING_THRESHOLD
            self.monsoon_end_date_index = MONSOON_END_DATE_INDEX
            if not OVERRIDE_FILECROPS_BY_DEBUG_OR_TEST_CROPS and os.path.exists(
                    os.path.join(path, CROPS_FILENAME)):
                self.crop_names = open(os.path.join(path, CROPS_FILENAME),
                                       'r').read().split(',')
                print(self.crop_names)
                if len(self.crop_names) == 0:
                    raise Exception('No crop selected')
            else:
                self.crop_names = DEBUG_OR_TEST_CROPS
            self.output_configuration = {}
            self.output_configuration[
                'graduated_rendering_interval_points'] = DEBUG_OR_TEST_GRADUATED_RENDERING_INTERVAL_POINTS

        else:
            self.dlg.show()
            if self.dlg.exec_() == QFileDialog.Rejected: return False

            path = self.path = self.base_path = self.dlg.folder_path.text()
            self.input_layers = {}
            self.input_layers['zones_layer'] = self.iface.addVectorLayer(
                self.dlg.zones_layer_filename.text(), 'Zones', 'ogr')
            self.input_layers['soil_layer'] = self.iface.addVectorLayer(
                self.dlg.soil_layer_filename.text(), 'Soil Cover', 'ogr')
            self.input_layers['lulc_layer'] = self.iface.addVectorLayer(
                self.dlg.lulc_layer_filename.text(), 'Land-Use-Land-Cover',
                'ogr')
            self.input_layers['cadastral_layer'] = self.iface.addVectorLayer(
                self.dlg.cadastral_layer_filename.text(), 'Cadastral Map',
                'ogr')
            self.input_layers['slope_layer'] = self.iface.addRasterLayer(
                self.dlg.slope_layer_filename.text(), 'Slope')
            if self.dlg.drainage_layer_filename.text() != '':
                self.drainage_layer = self.iface.addVectorLayer(
                    self.dlg.drainage_layer_filename.text(), 'Drainage', 'ogr')
            self.rain = [
                float(row["Rainfall"]) for row in csv.DictReader(
                    open(str(self.dlg.rainfall_csv_filename.text())))
            ]
            et0_file_data = [
                float(row["ET0"]) for row in csv.DictReader(
                    open(os.path.join(path, ET0_CSV_FILENAME)))
            ]
            self.et0 = set_et0_from_et0_file_data(et0_file_data)
            self.sowing_threshold = self.dlg.sowing_threshold.value()
            self.monsoon_end_date_index = self.dlg.monsoon_end.value() + 122

            self.crop_names = self.dlg.crops
            self.rabi_crop_names = self.dlg.rabi_crops
            if len(self.crop_names) == 0: raise Exception('No crop selected')
            self.output_configuration = {}
            self.output_configuration[
                'graduated_rendering_interval_points'] = [
                    int(
                        self.dlg.colour_code_intervals_list_widget.item(
                            i).text().split('-')[0])
                    for i in range(
                        1, self.dlg.colour_code_intervals_list_widget.count())
                ]
 def setUp(self):
     """Runs before each test."""
     self.dialog = KharifModelDialog(None)