def run_ding0(self, session, mv_grid_districts_no=None, debug=False, export_figures=False):
        """ Let DING0 run by shouting at this method (or just call
            it from NetworkDing0 instance). This method is a wrapper
            for the main functionality of DING0.

        Parameters
        ----------
        session : sqlalchemy.orm.session.Session
            Database session
        mv_grid_districts_no : List of Integers
            List of MV grid_districts/stations to be imported (if empty,
            all grid_districts & stations are imported)
        debug : bool, defaults to False
            If True, information is printed during process
        export_figures : bool, defaults to False
            If True, figures are shown or exported (default path: ~/.ding0/) during run.

        Returns
        -------
        msg : str
            Message of invalidity of a grid district

        Notes
        -----
        The steps performed in this method are to be kept in the given order
        since there are hard dependencies between them. Short description of
        all steps performed:
        
        * STEP 1: Import MV Grid Districts and subjacent objects
        
            Imports MV Grid Districts, HV-MV stations, Load Areas, LV Grid Districts
            and MV-LV stations, instantiates and initiates objects.
            
        * STEP 2: Import generators
        
            Conventional and renewable generators of voltage levels 4..7 are imported
            and added to corresponding grid.
        
        * STEP 3: Parametrize grid
        
            Parameters of MV grid are set such as voltage level and cable/line types
            according to MV Grid District's characteristics.
        
        * STEP 4: Validate MV Grid Districts
        
            Tests MV grid districts for validity concerning imported data such as
            count of Load Areas.
        
        * STEP 5: Build LV grids
        
            Builds LV grids for every non-aggregated LA in every MV Grid District
            using model grids.
        
        * STEP 6: Build MV grids
        
            Builds MV grid by performing a routing on Load Area centres to build
            ring topology.
        
        * STEP 7: Connect MV and LV generators
        
            Generators are connected to grids, used approach depends on voltage
            level.
        
        * STEP 8: Set IDs for all branches in MV and LV grids
        
            While IDs of imported objects can be derived from dataset's ID, branches
            are created in steps 5+6 and need unique IDs (e.g. for PF calculation).
        
        * STEP 9: Relocate switch disconnectors in MV grid
        
            Switch disconnectors are set during routing process (step 6) according
            to the load distribution within a ring. After further modifications of
            the grid within step 6+7 they have to be relocated (note: switch
            disconnectors are called circuit breakers in DING0 for historical reasons).
        
        * STEP 10: Open all switch disconnectors in MV grid
        
            Under normal conditions, rings are operated in open state (half-rings).
            Furthermore, this is required to allow powerflow for MV grid.
        
        * STEP 11: Do power flow analysis of MV grid
        
            The technically working MV grid created in step 6 was extended by satellite
            loads and generators. It is finally tested again using powerflow calculation.
        
        * STEP 12: Reinforce MV grid
        
            MV grid is eventually reinforced persuant to results from step 11.

        STEP 13: Close all switch disconnectors in MV grid
            The rings are finally closed to hold a complete graph (if the SDs are open,
            the edges adjacent to a SD will not be exported!)
        """
        if debug:
            start = time.time()

        # STEP 1: Import MV Grid Districts and subjacent objects
        self.import_mv_grid_districts(session,
                                      mv_grid_districts_no=mv_grid_districts_no)

        # STEP 2: Import generators
        self.import_generators(session, debug=debug)

        # STEP 3: Parametrize MV grid
        self.mv_parametrize_grid(debug=debug)

        # STEP 4: Validate MV Grid Districts
        msg = self.validate_grid_districts()

        # STEP 5: Build LV grids
        self.build_lv_grids()

        # STEP 6: Build MV grids
        self.mv_routing(debug=False)
        if export_figures:
            grid = self._mv_grid_districts[0].mv_grid
            plot_mv_topology(grid, subtitle='Routing completed', filename='1_routing_completed.png')

        # STEP 7: Connect MV and LV generators
        self.connect_generators(debug=False)
        if export_figures:
            plot_mv_topology(grid, subtitle='Generators connected', filename='2_generators_connected.png')

        # STEP 8: Set IDs for all branches in MV and LV grids
        self.set_branch_ids()

        # STEP 9: Relocate switch disconnectors in MV grid
        self.set_circuit_breakers(debug=debug)
        if export_figures:
            plot_mv_topology(grid, subtitle='Circuit breakers relocated', filename='3_circuit_breakers_relocated.png')
    
        # STEP 10: Open all switch disconnectors in MV grid
        self.control_circuit_breakers(mode='open')
    
        # STEP 11: Do power flow analysis of MV grid
        self.run_powerflow(session, method='onthefly', export_pypsa=False, debug=debug)
        if export_figures:
            plot_mv_topology(grid, subtitle='PF result (load case)',
                             filename='4_PF_result_load.png',
                             line_color='loading', node_color='voltage', testcase='load')
            plot_mv_topology(grid, subtitle='PF result (feedin case)',
                             filename='5_PF_result_feedin.png',
                             line_color='loading', node_color='voltage', testcase='feedin')
    
        # STEP 12: Reinforce MV grid
        self.reinforce_grid()

        # STEP 13: Close all switch disconnectors in MV grid
        self.control_circuit_breakers(mode='close')

        if export_figures:
            plot_mv_topology(grid, subtitle='Final grid PF result (load case)',
                             filename='6_final_grid_PF_result_load.png',
                             line_color='loading', node_color='voltage', testcase='load')
            plot_mv_topology(grid, subtitle='Final grid PF result (feedin case)',
                             filename='7_final_grid_PF_result_feedin.png',
                             line_color='loading', node_color='voltage', testcase='feedin')

        if debug:
            logger.info('Elapsed time for {0} MV Grid Districts (seconds): {1}'.format(
                str(len(mv_grid_districts_no)), time.time() - start))

        return msg