Ejemplo n.º 1
0
 def setUp(self) -> None:
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore")
         self.env = grid2op.make("rte_case118_example",
                                 backend=LightSimBackend(),
                                 test=True)
     self.nb_bus = self.env.n_sub
Ejemplo n.º 2
0
 def setUp(self) -> None:
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore")
         self.env = grid2op.make("l2rpn_neurips_2020_track2",
                                 backend=LightSimBackend(),
                                 test=True)
     self.nb_bus = self.env.n_sub
Ejemplo n.º 3
0
def make_env():
    env_name = "l2rpn_icaps_2021"
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore")
        fake_env = grid2op.make(env_name, test=True)
    param = fake_env.parameters
    param.NO_OVERFLOW_DISCONNECTION = True
    env = grid2op.make(env_name + "_small",
                       backend=LightSimBackend(),
                       param=param)
    return env
Ejemplo n.º 4
0
def create_env(env, seed):
    environment = grid2op.make(env,
                               reward_class=ConstantReward,
                               backend=LightSimBackend())
    # for mix in list(environment.keys()):
    # cr = environment[mix].get_reward_instance()
    # cr.addReward("redisp", RedispReward(), 0.1)
    # cr.addReward("economic", EconomicReward(), 0.1)
    # cr.addReward("overflow", CloseToOverflowReward(), 0.1)
    # cr.addReward("gameplay", GameplayReward(), 0.1)
    # cr.addReward("recolines", LinesReconnectedReward(), 0.1)
    # cr.addReward("l2rpn", L2RPNReward(), .6 / float(environment.n_line))
    # Initialize custom rewards
    # cr.set_range(-1.0, 1.0)

    # cr.initialize(environment[mix])
    environment.seed(seed)
    return environment
if __name__ == "__main__":
    # hyper-parameters
    DATA_PATH = '../training_data_track1'  # for demo only, use your own dataset 即使用的环境
    SCENARIO_PATH = '../training_data_track1/chronics'
    SAVE_PATH = './'
    LINES2ATTACK = [45, 56, 0, 9, 13, 14, 18, 23, 27, 39]
    NUM_EPISODES = 1000  # each scenario runs 100 times for each attack (or to say, sample 100 points)

    for episode in range(NUM_EPISODES):
        # traverse all attacks
        for line_to_disconnect in LINES2ATTACK:
            try:
                # if lightsim2grid is available, use it.
                from lightsim2grid import LightSimBackend
                backend = LightSimBackend()
                env = grid2op.make(dataset=DATA_PATH,
                                   chronics_path=SCENARIO_PATH,
                                   backend=backend)
            except:
                env = grid2op.make(dataset=DATA_PATH,
                                   chronics_path=SCENARIO_PATH)
            # env.chronics_handler.shuffle(shuffler=lambda x: x[np.random.choice(len(x), size=len(x), replace=False)])  #太麻烦了
            env.chronics_handler.shuffle()
            # traverse all scenarios
            for chronic in range(len(os.listdir(SCENARIO_PATH))):
                env.reset()
                dst_step = episode * 72 + random.randint(
                    0, 72)  # a random sampling every 6 hours
                print(
                    '\n\n' + '*' * 50 +
Ejemplo n.º 6
0
def main():
    args = cli()

    # read arguments
    input_dir = args.input_path
    output_dir = args.output_path
    program_dir = args.program_path
    submission_dir = args.submission_path
    config_file = args.config_in
    with open(config_file, "r") as f:
        config = json.load(f)

    # create output dir if not existing
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    if DEBUG:
        print("input dir: {}".format(input_dir))
        print("output dir: {}".format(output_dir))
        print("program dir: {}".format(program_dir))
        print("submission dir: {}".format(submission_dir))

        print("input content", os.listdir(input_dir))
        print("output content", os.listdir(output_dir))
        print("program content", os.listdir(program_dir))
    print("Content received by codalab: {}".format(
        sorted(os.listdir(submission_dir))))

    submission_location = os.path.join(submission_dir, "submission")
    if not os.path.exists(submission_location):
        print(SUBMISSION_DIR_ERR)
        raise RuntimeError(SUBMISSION_DIR_ERR)

    # add proper directories to path
    sys.path.append(program_dir)
    sys.path.append(submission_dir)

    try:
        from submission import make_agent
    except Exception as exc_:
        print(MAKE_AGENT_ERR)
        print("The error was: {}".format(exc_))
        raise RuntimeError(MAKE_AGENT_ERR)

    try:
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            env_template = grid2op.make(input_dir,
                                        chronics_class=ChangeNothing,
                                        action_class=TopologyAndDispatchAction)

    except Exception as exc_:
        print(ENV_TEMPLATE_ERR)
        print("The error was: {}".format(exc_))
        raise RuntimeError(ENV_TEMPLATE_ERR)

    try:
        submitted_agent = make_agent(env_template, submission_location)
    except Exception as exc_:
        print(MAKE_AGENT_ERR2)
        print("The error was: {}".format(exc_))
        raise RuntimeError(MAKE_AGENT_ERR2)

    if not isinstance(submitted_agent, BaseAgent):
        print(BASEAGENT_ERR)
        raise RuntimeError(BASEAGENT_ERR)

    try:
        from submission import reward
    except:
        print(INFO_CUSTOM_REWARD)
        reward = RedispReward

    if not isinstance(reward, type):
        raise RuntimeError(REWARD_ERR)
    if not issubclass(reward, BaseReward):
        raise RuntimeError(REWARD_ERR2)

    try:
        from submission import other_rewards
    except:
        print(INFO_CUSTOM_OTHER)
        other_rewards = {}

    if args.key_score in other_rewards:
        print(KEY_OVERLOAD_WARN.format(args.key_score))
    other_rewards[args.key_score] = L2RPNSandBoxScore

    # create the backend
    try:
        from lightsim2grid.LightSimBackend import LightSimBackend
        backend = LightSimBackend()
    except:
        print(BACKEND_WARN)
        from grid2op.Backend import PandaPowerBackend
        backend = PandaPowerBackend()

    real_env = grid2op.make(input_dir,
                            reward_class=reward,
                            other_rewards=other_rewards,
                            backend=backend)

    runner = Runner(**real_env.get_params_for_runner(),
                    agentClass=None,
                    agentInstance=submitted_agent)
    # this is called after, so that no one can change this sequence
    np.random.seed(int(config["seed"]))
    max_int = np.iinfo(dt_int).max
    env_seeds = list(np.random.randint(max_int, size=int(args.nb_episode)))
    agent_seeds = list(np.random.randint(max_int, size=int(args.nb_episode)))
    path_save = os.path.abspath(output_dir)
    runner.run(
        nb_episode=args.nb_episode,
        path_save=path_save,
        max_iter=-1,
        env_seeds=env_seeds,
        agent_seeds=agent_seeds,
    )
    real_env.close()

    # Generate a gif if enabled
    if args.gif_episode is not None:
        gif_input = os.path.join(output_dir)
        write_gif(output_dir, gif_input, args.gif_episode, args.gif_start,
                  args.gif_end)

    if args.cleanup:
        cmds = [
            "find {} -name '*.npz' | xargs -i rm -rf {}",
            "find {} -name 'dict_*.json' | xargs -i rm -rf {}",
            "find {} -name '_parameters.json' | xargs -i rm -rf {}"
        ]
        for cmd in cmds:
            os.system(cmd.format(output_dir, "{}"))
    print("Done and data saved in : \"{}\"".format(path_save))
Ejemplo n.º 7
0
 def setUp(self) -> None:
     with warnings.catch_warnings():
         warnings.filterwarnings("ignore")
         self.env = grid2op.make(backend=LightSimBackend(), test=True)
Ejemplo n.º 8
0
                this_epi_scores = json.load(f)
            score_this_ep, nb_ts_survived, total_ts_tmp = \
                self._compute_episode_score(ep_id,
                                            meta=this_epi_meta,
                                            other_rewards=this_epi_scores,
                                            dn_metadata=meta_data_dn,
                                            no_ov_metadata=no_ov_metadata)
            all_scores.append(score_this_ep)
            ts_survived.append(nb_ts_survived)
            total_ts.append(total_ts_tmp)

        if need_delete:
            dir_tmp.cleanup()
        return all_scores, ts_survived, total_ts


if __name__ == "__main__":
    import grid2op
    from lightsim2grid import LightSimBackend
    from grid2op.Agent import RandomAgent, DoNothingAgent
    env = grid2op.make("l2rpn_case14_sandbox", backend=LightSimBackend())
    nb_scenario = 16
    my_score = ScoreL2RPN2020(env,
                              nb_scenario=nb_scenario,
                              env_seeds=[0 for _ in range(nb_scenario)],
                              agent_seeds=[0 for _ in range(nb_scenario)])

    my_agent = RandomAgent(env.action_space)
    my_agent = DoNothingAgent(env.action_space)
    print(my_score.get(my_agent))
Ejemplo n.º 9
0
# nb_sub = 6495
# case_name = "test_case2848rte.json"
# nb_sub = 2848
# case_name = "test_case118.json"
# nb_sub = 118
# case_name = "test_case14.json"
# nb_sub = 14
tol = 1e-4  # results are equal if they match up to tol

good_working_case = pn.case118()
good_working_case = pn.case14()

#### test if it works
print(f"Basic check for {case_name}")
real_init_file = pp.from_json(case_name)
backend = LightSimBackend()
backend.load_grid(case_name)
pp_net = backend.init_pp_backend._grid
# first i deactivate all slack bus in pp that are connected but not handled in ls
pp_net.ext_grid["in_service"].loc[:] = False
pp_net.ext_grid["in_service"].iloc[0] = True
conv = backend.runpf()
conv_pp = backend.init_pp_backend.runpf()

if not conv_pp:
    print(
        "Error: pandapower do not converge, impossible to perform the necessary checks"
    )
    sys.exit()
por_pp, qor_pp, vor_pp, aor_pp = copy.deepcopy(
    backend.init_pp_backend.lines_or_info())
Ejemplo n.º 10
0
    # start the runner
    res = runner.run(path_save=save_path,
                     nb_episode=nb_episode,
                     nb_process=nb_process,
                     max_iter=max_steps,
                     pbar=False)

    # Print summary
    print("Evaluation summary:")
    for _, chron_name, cum_reward, nb_time_step, max_ts in res:
        msg_tmp = "\tFor chronics located at {}\n".format(chron_name)
        msg_tmp += "\t\t - cumulative reward: {:.6f}\n".format(cum_reward)
        msg_tmp += "\t\t - number of time steps completed: {:.0f} / {:.0f}".format(
            nb_time_step, max_ts)
        print(msg_tmp)


if __name__ == "__main__":

    env = grid2op.make("data/input_data_local", backend=LightSimBackend())

    evaluate(env,
             model_name="beu",
             save_path="eval_results",
             logs_path="logs-train",
             nb_episode=24,
             nb_process=1,
             max_steps=2016,
             verbose=True,
             save_gif="eval_results")
Ejemplo n.º 11
0
    env_name = ENV_CASE[args.case]
    env_path = os.path.join(DATA_DIR, env_name)
    chronics_path = os.path.join(env_path, 'chronics')
    train_chronics, valid_chronics, test_chronics = DATA_SPLIT[args.case]
    dn_json_path = os.path.join(env_path, 'json')
    
    # select chronics
    dn_ffw = read_ffw_json(dn_json_path, train_chronics + valid_chronics, args.case)

    ep_infos = {}
    if os.path.exists(dn_json_path):
        for i in list(set(train_chronics+valid_chronics)):
            with open(os.path.join(dn_json_path, f'{i}.json'), 'r', encoding='utf-8') as f:
                ep_infos[i] = json.load(f)

    env = grid2op.make(env_path, test=True, reward_class=L2RPNSandBoxScore, backend=LightSimBackend(),
                other_rewards={'loss': LossReward})
    test_env = grid2op.make(env_path, test=True, reward_class=L2RPNSandBoxScore, backend=LightSimBackend(),
                other_rewards={'loss': LossReward})
    env.deactivate_forecast()
    test_env.deactivate_forecast()
    env.seed(args.seed)
    test_env.parameters.NB_TIMESTEP_OVERFLOW_ALLOWED = env.parameters.NB_TIMESTEP_OVERFLOW_ALLOWED = 3
    test_env.parameters.NB_TIMESTEP_RECONNECTION = env.parameters.NB_TIMESTEP_RECONNECTION = 12
    test_env.parameters.NB_TIMESTEP_COOLDOWN_LINE = env.parameters.NB_TIMESTEP_COOLDOWN_LINE = 3
    test_env.parameters.NB_TIMESTEP_COOLDOWN_SUB = env.parameters.NB_TIMESTEP_COOLDOWN_SUB = 3
    test_env.parameters.HARD_OVERFLOW_THRESHOLD = env.parameters.HARD_OVERFLOW_THRESHOLD = 200.0
    test_env.seed(59)
    chronic_num = len(test_chronics)
        
    print(env.parameters.__dict__)            
Ejemplo n.º 12
0
    def _aux_test(self, pn_net):
        with tempfile.TemporaryDirectory() as path:
            case_name = os.path.join(path, "this_case.json")
            pp.to_json(pn_net, case_name)

            real_init_file = pp.from_json(case_name)
            backend = LightSimBackend()
            with warnings.catch_warnings():
                warnings.filterwarnings("ignore")
                backend.load_grid(case_name)

        nb_sub = backend.n_sub
        pp_net = backend.init_pp_backend._grid
        # first i deactivate all slack bus in pp that are connected but not handled in ls
        pp_net.ext_grid["in_service"].loc[:] = False
        pp_net.ext_grid["in_service"].iloc[0] = True
        conv = backend.runpf()
        conv_pp = backend.init_pp_backend.runpf()

        assert conv_pp, "Error: pandapower do not converge, impossible to perform the necessary checks"
        assert conv, "Error: lightsim do not converge"

        por_pp, qor_pp, vor_pp, aor_pp = copy.deepcopy(
            backend.init_pp_backend.lines_or_info())
        pex_pp, qex_pp, vex_pp, aex_pp = copy.deepcopy(
            backend.init_pp_backend.lines_ex_info())

        # I- Check for divergence and equality of flows"
        por_ls, qor_ls, vor_ls, aor_ls = backend.lines_or_info()
        max_mis = np.max(np.abs(por_ls - por_pp))
        assert max_mis <= self.tol, f"Error: por do not match, maximum absolute error is {max_mis:.5f} MW"
        max_mis = np.max(np.abs(qor_ls - qor_pp))
        assert max_mis <= self.tol, f"Error: qor do not match, maximum absolute error is {max_mis:.5f} MVAr"
        max_mis = np.max(np.abs(vor_ls - vor_pp))
        assert max_mis <= self.tol, f"Error: vor do not match, maximum absolute error is {max_mis:.5f} kV"
        max_mis = np.max(np.abs(aor_ls - aor_pp))
        assert max_mis <= self.tol, f"Error: aor do not match, maximum absolute error is {max_mis:.5f} A"

        # "II - Check for possible solver issues"
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            pp.runpp(backend.init_pp_backend._grid, v_debug=True)
        v_tmp = backend.init_pp_backend._grid.res_bus[
            "vm_pu"].values[:nb_sub] + 0j
        v_tmp *= np.exp(
            1j * np.pi / 180. *
            backend.init_pp_backend._grid.res_bus["va_degree"].values[:nb_sub])
        v_tmp = np.concatenate((v_tmp, v_tmp))
        backend._grid.ac_pf(v_tmp, 1000, 1e-5)

        Y_pp = backend.init_pp_backend._grid._ppc["internal"]["Ybus"]
        Sbus = backend.init_pp_backend._grid._ppc["internal"]["Sbus"]
        pv_ = backend.init_pp_backend._grid._ppc["internal"]["pv"]
        pq_ = backend.init_pp_backend._grid._ppc["internal"]["pq"]
        max_iter = 10
        tol_this = 1e-8
        All_Vms = backend.init_pp_backend._grid._ppc["internal"]["Vm_it"]
        AllVas = backend.init_pp_backend._grid._ppc["internal"]["Va_it"]

        for index_V in range(All_Vms.shape[1] - 1, -1, -1):
            nb_iter = All_Vms.shape[1] - 1
            # i check from easiest to hardest, so from the last iteartion of pandapower to the first iteration of pandapower
            # take the same V as pandapower
            V_init = All_Vms[:, index_V] * (np.cos(AllVas[:, index_V]) +
                                            1j * np.sin(AllVas[:, index_V]))
            # V_init *= np.exp(1j * AllVas[:, 0])
            V_init_ref = copy.deepcopy(V_init)
            solver = ClassSolver()
            solver.solve(scipy.sparse.csc_matrix(Y_pp), V_init, Sbus, pv_, pq_,
                         max_iter, tol_this)
            time_for_nr = solver.get_timers()[3]
            if TIMER_INFO:
                print(
                    f"\t Info: Time to perform {nb_iter - index_V} NR iterations for a grid with {nb_sub} "
                    f"buses: {1000. * time_for_nr:.2f}ms")
            error_va = np.abs(
                solver.get_Va() -
                np.angle(backend.init_pp_backend._grid._ppc["internal"]["V"]))
            assert np.max(error_va) <= self.tol, f"Error: VA do not match for iteration {index_V}, maximum absolute " \
                                                 f"error is {np.max(error_va):.5f} rad"

            error_vm = np.abs(
                np.abs(solver.get_Vm() - np.abs(
                    backend.init_pp_backend._grid._ppc["internal"]["V"])))
            assert np.max(error_vm) <= self.tol, f"\t Error: VM do not match for iteration {index_V}, maximum absolute " \
                                                 f"error  is {np.max(error_vm):.5f} pu"
            solver.reset()

        if TIMER_INFO:
            print("")

        # 'III - Check the data conversion'
        pp_vect_converter = backend.init_pp_backend._grid._pd2ppc_lookups[
            "bus"][:nb_sub]
        pp_net = backend.init_pp_backend._grid

        # 1) Checking Sbus conversion
        Sbus_pp = backend.init_pp_backend._grid._ppc["internal"]["Sbus"]
        Sbus_pp_right_order = Sbus_pp[pp_vect_converter]
        Sbus_me = backend._grid.get_Sbus()
        error_p = np.abs(np.real(Sbus_me) - np.real(Sbus_pp_right_order))
        assert np.max(error_p) <= self.tol, f"\t Error: P do not match for Sbus, maximum absolute error is " \
                                            f"{np.max(error_p):.5f} MW, \t Error: significative difference for bus " \
                                            f"index (lightsim): {np.where(error_p > self.tol)[0]}"

        error_q = np.abs(np.imag(Sbus_me) - np.imag(Sbus_pp_right_order))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Sbus, maximum absolute error is " \
                                            f"{np.max(error_q):.5f} MVAr, \t Error: significative difference for bus " \
                                            f"index (lightsim): {np.where(error_q > self.tol)[0]}"

        # 2)  Checking Ybus conversion"
        Y_me = backend._grid.get_Ybus()
        Y_pp = backend.init_pp_backend._grid._ppc["internal"]["Ybus"]
        Y_pp_right_order = Y_pp[pp_vect_converter.reshape(nb_sub, 1),
                                pp_vect_converter.reshape(1, nb_sub)]
        error_p = np.abs(np.real(Y_me) - np.real(Y_pp_right_order))
        assert np.max(error_p) <= self.tol, f"Error: P do not match for Ybus, maximum absolute error " \
                                            f"is {np.max(error_p):.5f}"

        error_q = np.abs(np.imag(Y_me) - np.imag(Y_pp_right_order))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Ybus, maximum absolute error is " \
                                            f"{np.max(error_q):.5f}"

        # "IV - Check for the initialization (dc powerflow)"
        # 1) check that the results are same for dc lightsim and dc pandapower
        Vinit = np.ones(backend.nb_bus_total,
                        dtype=np.complex_) * pp_net["_options"]["init_vm_pu"]
        backend._grid.deactivate_result_computation()
        Vdc = backend._grid.dc_pf(Vinit, max_iter, tol_this)
        backend._grid.reactivate_result_computation()
        Ydc_me = backend._grid.get_Ybus()
        Sdc_me = backend._grid.get_Sbus()
        assert np.max(np.abs(V_init_ref[pp_vect_converter] - Vdc[:nb_sub])) <= 100.*self.tol,\
            f"\t Error for the DC approximation: resulting voltages are different " \
            f"{np.max(np.abs(V_init_ref[pp_vect_converter] - Vdc[:nb_sub])):.5f}pu"

        if np.max(np.abs(V_init_ref[pp_vect_converter] -
                         Vdc[:nb_sub])) >= self.tol:
            warnings.warn(
                "\t Warning: maximum difference after DC approximation is "
                "{np.max(np.abs(V_init_ref[pp_vect_converter] - Vdc[:nb_sub])):.5f} which is higher than "
                "the tolerance (this is just a warning because we noticed this could happen even if the "
                "results match perfectly. Probably some conversion issue with complex number and "
                "radian / degree.")
        # "2) check that the Sbus vector is same for PP and lightisim in DC"
        from pandapower.pd2ppc import _pd2ppc
        from pandapower.pf.run_newton_raphson_pf import _get_pf_variables_from_ppci
        from pandapower.pypower.idx_brch import F_BUS, T_BUS, BR_X, TAP, SHIFT, BR_STATUS
        from pandapower.pypower.idx_bus import VA, GS
        from pandapower.pypower.makeBdc import makeBdc
        from pandapower.pypower.makeSbus import makeSbus

        pp_net._pd2ppc_lookups = {
            "bus": np.array([], dtype=int),
            "ext_grid": np.array([], dtype=int),
            "gen": np.array([], dtype=int),
            "branch": np.array([], dtype=int)
        }
        # convert pandapower net to ppc
        ppc, ppci = _pd2ppc(pp_net)
        baseMVA, bus, gen, branch, ref, pv, pq, on, gbus, _, refgen = _get_pf_variables_from_ppci(
            ppci)
        Va0 = bus[:, VA] * (np.pi / 180.)
        B, Bf, Pbusinj, Pfinj = makeBdc(bus, branch)

        Pbus = makeSbus(baseMVA, bus, gen) - Pbusinj - bus[:, GS] / baseMVA
        Pbus_pp_ro = Pbus[pp_vect_converter]
        error_p = np.abs(np.real(Sdc_me) - np.real(Pbus_pp_ro))
        test_ok = True

        #### pandapower DC algo (yet another one)
        Va = copy.deepcopy(Va0)
        pvpq = np.r_[pv, pq]
        pvpq_matrix = B[pvpq.T, :].tocsc()[:, pvpq]
        ref_matrix = np.transpose(Pbus[pvpq] -
                                  B[pvpq.T, :].tocsc()[:, ref] * Va0[ref])
        Va[pvpq] = np.real(scipy.sparse.linalg.spsolve(pvpq_matrix,
                                                       ref_matrix))
        ####

        assert np.max(error_p) <= self.tol, f"\t Error: P do not match for Sbus (dc), maximum absolute error is " \
                                            f"{np.max(error_p):.5f} MW, \nError: significative difference for bus " \
                                            f"index (lightsim): {np.where(error_p > self.tol)[0]}"

        error_q = np.abs(np.imag(Sdc_me) - np.imag(Pbus_pp_ro))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Sbus (dc), maximum absolute error is " \
                                            f"{np.max(error_q):.5f} MVAr, \n\t Error: significative difference for " \
                                            f"bus index (lightsim): {np.where(error_q > self.tol)[0]}"

        # "3) check that the Ybus matrix is same for PP and lightisim in DC"
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore")
            pp.rundcpp(pp_net)
        Ydc_pp = backend.init_pp_backend._grid._ppc["internal"]["Bbus"]
        Ydc_pp_right_order = Ydc_pp[pp_vect_converter.reshape(nb_sub, 1),
                                    pp_vect_converter.reshape(1, nb_sub)]
        error_p = np.abs(np.real(Ydc_me) - np.real(Ydc_pp_right_order))
        assert np.max(error_p) <= self.tol, f"Error: P do not match for Ybus (dc mode), maximum absolute error " \
                                            f"is {np.max(error_p):.5f}"
        error_q = np.abs(np.imag(Ydc_me) - np.imag(Ydc_pp_right_order))
        assert np.max(error_q) <= self.tol, f"\t Error: Q do not match for Ybus (dc mdoe), maximum absolute error " \
                                            f"is {np.max(error_q):.5f}"

        # "3) check that lightsim ac pf init with pp dc pf give same results (than pp)"
        Vinit = np.ones(backend.nb_bus_total,
                        dtype=np.complex_) * pp_net["_options"]["init_vm_pu"]
        Vinit[:nb_sub] = V_init_ref[pp_vect_converter]
        conv = backend._grid.ac_pf(Vinit, max_iter, tol_this)
        assert conv.shape[
            0] > 0, "\t Error: the lightsim diverge when initialized with pandapower Vinit_dc"
        lpor, lqor, lvor, laor = backend._grid.get_lineor_res()
        tpor, tqor, tvor, taor = backend._grid.get_trafohv_res()
        tpex, tqex, tvex, taex = backend._grid.get_trafolv_res()
        nb_trafo = tpor.shape[0]
        nb_powerline = lpor.shape[0]
        p_or_me2 = np.concatenate((lpor, tpor))
        q_or_me2 = np.concatenate((lqor, tqor))
        v_or_me2 = np.concatenate((lvor, tvor))
        a_or_me2 = 1000. * np.concatenate((laor, taor))
        test_ok = True
        # pdb.set_trace()
        max_mis = np.max(np.abs(p_or_me2 - por_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: por do not match, maximum absolute error is {max_mis:.5f} MW"
        max_mis = np.max(np.abs(q_or_me2 - qor_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: qor do not match, maximum absolute error is {max_mis:.5f} MVAr"
        max_mis = np.max(np.abs(v_or_me2 - vor_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: vor do not match, maximum absolute error is {max_mis:.5f} kV"
        max_mis = np.max(np.abs(a_or_me2 - aor_pp))
        assert np.max(
            error_q
        ) <= self.tol, f"\t Error: aor do not match, maximum absolute error is {max_mis:.5f} A"

        # "V - Check trafo proper conversion to r,x, b"
        from lightsim2grid_cpp import GridModel, PandaPowerConverter, SolverType
        from pandapower.build_branch import _calc_branch_values_from_trafo_df, get_trafo_values
        from pandapower.build_branch import _calc_nominal_ratio_from_dataframe, _calc_r_x_y_from_dataframe
        from pandapower.build_branch import _calc_tap_from_dataframe, BASE_KV, _calc_r_x_from_dataframe

        # my trafo parameters
        converter = PandaPowerConverter()
        converter.set_sn_mva(pp_net.sn_mva)
        converter.set_f_hz(pp_net.f_hz)
        tap_neutral = 1.0 * pp_net.trafo["tap_neutral"].values
        tap_neutral[~np.isfinite(tap_neutral)] = 0.
        if np.any(tap_neutral != 0.):
            raise RuntimeError(
                "lightsim converter supposes that tap_neutral is 0 for the transformers"
            )
        tap_step_pct = 1.0 * pp_net.trafo["tap_step_percent"].values
        tap_step_pct[~np.isfinite(tap_step_pct)] = 0.
        tap_pos = 1.0 * pp_net.trafo["tap_pos"].values
        tap_pos[~np.isfinite(tap_pos)] = 0.
        shift_ = 1.0 * pp_net.trafo["shift_degree"].values
        shift_[~np.isfinite(shift_)] = 0.
        is_tap_hv_side = pp_net.trafo["tap_side"].values == "hv"
        is_tap_hv_side[~np.isfinite(is_tap_hv_side)] = True
        if np.any(pp_net.trafo["tap_phase_shifter"].values):
            raise RuntimeError(
                "ideal phase shifter are not modeled. Please remove all trafo with "
                "pp_net.trafo[\"tap_phase_shifter\"] set to True.")
        tap_angles_ = 1.0 * pp_net.trafo["tap_step_degree"].values
        tap_angles_[~np.isfinite(tap_angles_)] = 0.
        tap_angles_ = np.deg2rad(tap_angles_)
        trafo_r, trafo_x, trafo_b = \
            converter.get_trafo_param(tap_step_pct,
                                      tap_pos,
                                      tap_angles_,  # in radian !
                                      is_tap_hv_side,
                                      pp_net.bus.loc[pp_net.trafo["hv_bus"]]["vn_kv"],
                                      pp_net.bus.loc[pp_net.trafo["lv_bus"]]["vn_kv"],
                                      pp_net.trafo["vk_percent"].values,
                                      pp_net.trafo["vkr_percent"].values,
                                      pp_net.trafo["sn_mva"].values,
                                      pp_net.trafo["pfe_kw"].values,
                                      pp_net.trafo["i0_percent"].values,
                                      )
        # pandapower trafo parameters
        ppc = copy.deepcopy(pp_net._ppc)
        bus_lookup = pp_net["_pd2ppc_lookups"]["bus"]
        trafo_df = pp_net["trafo"]
        lv_bus = get_trafo_values(trafo_df, "lv_bus")
        vn_lv = ppc["bus"][bus_lookup[lv_bus], BASE_KV]
        vn_trafo_hv, vn_trafo_lv, shift_pp = _calc_tap_from_dataframe(
            pp_net, trafo_df)
        ratio = _calc_nominal_ratio_from_dataframe(ppc, trafo_df, vn_trafo_hv,
                                                   vn_trafo_lv, bus_lookup)
        r_t, x_t, b_t = _calc_r_x_y_from_dataframe(pp_net, trafo_df,
                                                   vn_trafo_lv, vn_lv,
                                                   pp_net.sn_mva)

        # check where there are mismatch if any
        val_r_pp = r_t
        val_r_me = trafo_r
        all_equals_r = np.abs(val_r_pp - val_r_me) <= self.tol
        if not np.all(all_equals_r):
            test_ok = False
            print(
                f"\t Error: some trafo resistance are not equal, max error: {np.max(np.abs(val_r_pp - val_r_me)):.5f}"
            )

        val_x_pp = x_t
        val_x_me = trafo_x
        all_equals_x = np.abs(val_x_pp - val_x_me) <= self.tol
        assert np.all(all_equals_x), f"\t Error: some trafo x are not equal, max error: " \
                                     f"{np.max(np.abs(val_x_pp - val_x_me)):.5f}"

        val_ib_pp = np.imag(b_t)
        val_ib_me = np.imag(trafo_b)
        all_equals_imag_b = np.abs(val_ib_pp - val_ib_me) <= self.tol
        assert np.all(all_equals_imag_b), f"\t Error: some trafo (imag) b are not equal, max error: " \
                                          f"{np.max(np.abs(val_ib_pp - val_ib_me)):.5f}"

        val_reb_pp = np.real(b_t)
        val_reb_me = np.real(trafo_b)
        all_equals_real_b = np.abs(val_reb_pp - val_reb_me) <= self.tol
        assert np.all(all_equals_real_b), f"\t Error: some trafo (real) b are not equal, max error: " \
                                          f"{np.max(np.abs(val_reb_pp - val_reb_me)):.5f}"