<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Meshed AC-DC example
This example has a 3-node AC network coupled via AC-DC converters to a 3-node DC network. There is also a single point-to-point DC using the Link component.
The data files for this example are in the examples folder of the github repository
Step1:  We inspect the topology of the network. Therefore use the function determine_network_topology and inspect the subnetworks in network.sub_networks.
Step2:  The network covers 10 time steps. These are given by the snapshots attribute.
Step3:  There are 6 generators in the network, 3 wind and 3 gas. All are attached to buses
Step4:  We see that the generators have different capital and marginal costs. All of them have a p_nom_extendable set to True, meaning that capacities can be extended in the optimization.
The wind generators have a per unit limit for each time step, given by the weather potentials at the site.
Step5:  Alright now we know how the network looks like, where the generators and lines are. Now, let's perform a optimization of the operation and capacities.
Step6:  The objective is given by
Step7:  Why is this number negative? It considers the starting point of the optimization, thus the existent capacities given by network.generators.p_nom are taken into account.  
The real system cost are given by
Step8:  The optimal capacities are given by p_nom_opt for generators, links and storages and s_nom_opt for lines.
Let's look how the optimal capacities for the generators look like.
Step9:  Their production is again given as a time-series in network.generators_t.
Step10:  What are the Locational Marginal Prices in the network. From the optimization these are given for each bus and snapshot.
Step11:  We can inspect futher quantities as the active power of AC-DC converters and HVDC link.
Step12:  ...or the active power injection per bus.
<ASSISTANT_TASK:>
Python Code:
import pypsa
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
%matplotlib inline
plt.rc("figure", figsize=(8, 8))
network = pypsa.examples.ac_dc_meshed(from_master=True)
# get current type (AC or DC) of the lines from the buses
lines_current_type = network.lines.bus0.map(network.buses.carrier)
lines_current_type
network.plot(
    line_colors=lines_current_type.map(lambda ct: "r" if ct == "DC" else "b"),
    title="Mixed AC (blue) - DC (red) network - DC (cyan)",
    color_geomap=True,
    jitter=0.3,
)
plt.tight_layout()
network.links.loc["Norwich Converter", "p_nom_extendable"] = False
Explanation: Meshed AC-DC example
This example has a 3-node AC network coupled via AC-DC converters to a 3-node DC network. There is also a single point-to-point DC using the Link component.
The data files for this example are in the examples folder of the github repository: https://github.com/PyPSA/PyPSA.
End of explanation
network.determine_network_topology()
network.sub_networks["n_branches"] = [
    len(sn.branches()) for sn in network.sub_networks.obj
]
network.sub_networks["n_buses"] = [len(sn.buses()) for sn in network.sub_networks.obj]
network.sub_networks
Explanation: We inspect the topology of the network. Therefore use the function determine_network_topology and inspect the subnetworks in network.sub_networks.
End of explanation
network.snapshots
Explanation: The network covers 10 time steps. These are given by the snapshots attribute.
End of explanation
network.generators
Explanation: There are 6 generators in the network, 3 wind and 3 gas. All are attached to buses:
End of explanation
network.generators_t.p_max_pu.plot.area(subplots=True)
plt.tight_layout()
Explanation: We see that the generators have different capital and marginal costs. All of them have a p_nom_extendable set to True, meaning that capacities can be extended in the optimization.
The wind generators have a per unit limit for each time step, given by the weather potentials at the site.
End of explanation
network.lopf();
Explanation: Alright now we know how the network looks like, where the generators and lines are. Now, let's perform a optimization of the operation and capacities.
End of explanation
network.objective
Explanation: The objective is given by:
End of explanation
network.objective + network.objective_constant
Explanation: Why is this number negative? It considers the starting point of the optimization, thus the existent capacities given by network.generators.p_nom are taken into account.  
The real system cost are given by
End of explanation
network.generators.p_nom_opt.div(1e3).plot.bar(ylabel="GW", figsize=(8, 3))
plt.tight_layout()
Explanation: The optimal capacities are given by p_nom_opt for generators, links and storages and s_nom_opt for lines.
Let's look how the optimal capacities for the generators look like.
End of explanation
network.generators_t.p.div(1e3).plot.area(subplots=True, ylabel="GW")
plt.tight_layout()
Explanation: Their production is again given as a time-series in network.generators_t.
End of explanation
network.buses_t.marginal_price.mean(1).plot.area(figsize=(8, 3), ylabel="Euro per MWh")
plt.tight_layout()
Explanation: What are the Locational Marginal Prices in the network. From the optimization these are given for each bus and snapshot.
End of explanation
network.links_t.p0
network.lines_t.p0
Explanation: We can inspect futher quantities as the active power of AC-DC converters and HVDC link.
End of explanation
network.buses_t.p
Explanation: ...or the active power injection per bus.
End of explanation
<END_TASK>