mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-10-31 01:57:54 +00:00 
			
		
		
		
	Merge pull request #281 from jktjkt/no-convenience-access
Remove property aliases
This commit is contained in:
		| @@ -154,8 +154,8 @@ class Roadm(Node): | |||||||
|         #all ingress channels in xpress are set to this power level |         #all ingress channels in xpress are set to this power level | ||||||
|         #but add channels are not, so we define an effective loss |         #but add channels are not, so we define an effective loss | ||||||
|         #in the case of add channels |         #in the case of add channels | ||||||
|         self.effective_pch_out_db = min(pref.pi, self.params.target_pch_out_db) |         self.effective_pch_out_db = min(pref.p_spani, self.params.target_pch_out_db) | ||||||
|         self.effective_loss = pref.pi - self.effective_pch_out_db |         self.effective_loss = pref.p_spani - self.effective_pch_out_db | ||||||
|         carriers_power = array([c.power.signal +c.power.nli+c.power.ase for c in carriers]) |         carriers_power = array([c.power.signal +c.power.nli+c.power.ase for c in carriers]) | ||||||
|         carriers_att = list(map(lambda x : lin2db(x*1e3)-self.params.target_pch_out_db, carriers_power)) |         carriers_att = list(map(lambda x : lin2db(x*1e3)-self.params.target_pch_out_db, carriers_power)) | ||||||
|         exceeding_att = -min(list(filter(lambda x: x < 0, carriers_att)), default = 0) |         exceeding_att = -min(list(filter(lambda x: x < 0, carriers_att)), default = 0) | ||||||
| @@ -163,17 +163,17 @@ class Roadm(Node): | |||||||
|         for carrier_att, carrier in zip(carriers_att, carriers) : |         for carrier_att, carrier in zip(carriers_att, carriers) : | ||||||
|             pwr = carrier.power |             pwr = carrier.power | ||||||
|             pwr = pwr._replace( signal = pwr.signal/carrier_att, |             pwr = pwr._replace( signal = pwr.signal/carrier_att, | ||||||
|                                 nonlinear_interference = pwr.nli/carrier_att, |                                 nli = pwr.nli/carrier_att, | ||||||
|                                 amplified_spontaneous_emission = pwr.ase/carrier_att) |                                 ase = pwr.ase/carrier_att) | ||||||
|             yield carrier._replace(power=pwr) |             yield carrier._replace(power=pwr) | ||||||
|  |  | ||||||
|     def update_pref(self, pref): |     def update_pref(self, pref): | ||||||
|         return pref._replace(p_span0=pref.p0, p_spani=self.effective_pch_out_db) |         return pref._replace(p_span0=pref.p_span0, p_spani=self.effective_pch_out_db) | ||||||
|  |  | ||||||
|     def __call__(self, spectral_info): |     def __call__(self, spectral_info): | ||||||
|         carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers)) |         carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers)) | ||||||
|         pref = self.update_pref(spectral_info.pref) |         pref = self.update_pref(spectral_info.pref) | ||||||
|         return spectral_info.update(carriers=carriers, pref=pref) |         return spectral_info._replace(carriers=carriers, pref=pref) | ||||||
|  |  | ||||||
| FusedParams = namedtuple('FusedParams', 'loss') | FusedParams = namedtuple('FusedParams', 'loss') | ||||||
|  |  | ||||||
| @@ -211,17 +211,17 @@ class Fused(Node): | |||||||
|         for carrier in carriers: |         for carrier in carriers: | ||||||
|             pwr = carrier.power |             pwr = carrier.power | ||||||
|             pwr = pwr._replace(signal=pwr.signal/attenuation, |             pwr = pwr._replace(signal=pwr.signal/attenuation, | ||||||
|                                nonlinear_interference=pwr.nli/attenuation, |                                nli=pwr.nli/attenuation, | ||||||
|                                amplified_spontaneous_emission=pwr.ase/attenuation) |                                ase=pwr.ase/attenuation) | ||||||
|             yield carrier._replace(power=pwr) |             yield carrier._replace(power=pwr) | ||||||
|  |  | ||||||
|     def update_pref(self, pref): |     def update_pref(self, pref): | ||||||
|         return pref._replace(p_span0=pref.p0, p_spani=pref.pi - self.loss) |         return pref._replace(p_span0=pref.p_span0, p_spani=pref.p_spani - self.loss) | ||||||
|  |  | ||||||
|     def __call__(self, spectral_info): |     def __call__(self, spectral_info): | ||||||
|         carriers = tuple(self.propagate(*spectral_info.carriers)) |         carriers = tuple(self.propagate(*spectral_info.carriers)) | ||||||
|         pref = self.update_pref(spectral_info.pref) |         pref = self.update_pref(spectral_info.pref) | ||||||
|         return spectral_info.update(carriers=carriers, pref=pref) |         return spectral_info._replace(carriers=carriers, pref=pref) | ||||||
|  |  | ||||||
| FiberParams = namedtuple('FiberParams', 'type_variety length loss_coef length_units \ | FiberParams = namedtuple('FiberParams', 'type_variety length loss_coef length_units \ | ||||||
|                                          att_in con_in con_out dispersion gamma') |                                          att_in con_in con_out dispersion gamma') | ||||||
| @@ -327,11 +327,6 @@ class Fiber(Node): | |||||||
|         if not (loc in ('in', 'out') and attr in ('nli', 'signal', 'total', 'ase')): |         if not (loc in ('in', 'out') and attr in ('nli', 'signal', 'total', 'ase')): | ||||||
|             yield None |             yield None | ||||||
|             return |             return | ||||||
|         power_dict = { |  | ||||||
|                         'nli':      'nonlinear_interference', |  | ||||||
|                         'ase':      'amplified_spontaneous_emission' |  | ||||||
|                     } |  | ||||||
|         attr = power_dict.get(attr, attr) |  | ||||||
|         loc_attr = 'carriers_'+loc |         loc_attr = 'carriers_'+loc | ||||||
|         for c in getattr(self, loc_attr) : |         for c in getattr(self, loc_attr) : | ||||||
|             if attr == 'total': |             if attr == 'total': | ||||||
| @@ -361,11 +356,11 @@ class Fiber(Node): | |||||||
|  |  | ||||||
|     def _psi(self, carrier, interfering_carrier): |     def _psi(self, carrier, interfering_carrier): | ||||||
|         """Calculates eq. 123 from `arXiv:1209.0394 <https://arxiv.org/abs/1209.0394>`__""" |         """Calculates eq. 123 from `arXiv:1209.0394 <https://arxiv.org/abs/1209.0394>`__""" | ||||||
|         if carrier.num_chan == interfering_carrier.num_chan: # SCI |         if carrier.channel_number == interfering_carrier.channel_number: # SCI | ||||||
|             psi = arcsinh(0.5 * pi**2 * self.asymptotic_length |             psi = arcsinh(0.5 * pi**2 * self.asymptotic_length | ||||||
|                               * abs(self.beta2()) * carrier.baud_rate**2) |                               * abs(self.beta2()) * carrier.baud_rate**2) | ||||||
|         else: # XCI |         else: # XCI | ||||||
|             delta_f = carrier.freq - interfering_carrier.freq |             delta_f = carrier.frequency - interfering_carrier.frequency | ||||||
|             psi = arcsinh(pi**2 * self.asymptotic_length * abs(self.beta2()) |             psi = arcsinh(pi**2 * self.asymptotic_length * abs(self.beta2()) | ||||||
|                                 * carrier.baud_rate * (delta_f + 0.5 * interfering_carrier.baud_rate)) |                                 * carrier.baud_rate * (delta_f + 0.5 * interfering_carrier.baud_rate)) | ||||||
|             psi -= arcsinh(pi**2 * self.asymptotic_length * abs(self.beta2()) |             psi -= arcsinh(pi**2 * self.asymptotic_length * abs(self.beta2()) | ||||||
| @@ -403,8 +398,8 @@ class Fiber(Node): | |||||||
|         for carrier in carriers: |         for carrier in carriers: | ||||||
|             pwr = carrier.power |             pwr = carrier.power | ||||||
|             pwr = pwr._replace(signal=pwr.signal/attenuation, |             pwr = pwr._replace(signal=pwr.signal/attenuation, | ||||||
|                                nonlinear_interference=pwr.nli/attenuation, |                                nli=pwr.nli/attenuation, | ||||||
|                                amplified_spontaneous_emission=pwr.ase/attenuation) |                                ase=pwr.ase/attenuation) | ||||||
|             carrier = carrier._replace(power=pwr) |             carrier = carrier._replace(power=pwr) | ||||||
|             chan.append(carrier) |             chan.append(carrier) | ||||||
|  |  | ||||||
| @@ -416,20 +411,20 @@ class Fiber(Node): | |||||||
|             pwr = carrier.power |             pwr = carrier.power | ||||||
|             carrier_nli = self._gn_analytic(carrier, *carriers) |             carrier_nli = self._gn_analytic(carrier, *carriers) | ||||||
|             pwr = pwr._replace(signal=pwr.signal/self.lin_attenuation/attenuation, |             pwr = pwr._replace(signal=pwr.signal/self.lin_attenuation/attenuation, | ||||||
|                                nonlinear_interference=(pwr.nli+carrier_nli)/self.lin_attenuation/attenuation, |                                nli=(pwr.nli+carrier_nli)/self.lin_attenuation/attenuation, | ||||||
|                                amplified_spontaneous_emission=pwr.ase/self.lin_attenuation/attenuation) |                                ase=pwr.ase/self.lin_attenuation/attenuation) | ||||||
|             yield carrier._replace(power=pwr) |             yield carrier._replace(power=pwr) | ||||||
|  |  | ||||||
|     def update_pref(self, pref): |     def update_pref(self, pref): | ||||||
|         self.pch_out_db = round(pref.pi - self.loss, 2) |         self.pch_out_db = round(pref.p_spani - self.loss, 2) | ||||||
|         return pref._replace(p_span0=pref.p0, p_spani=self.pch_out_db) |         return pref._replace(p_span0=pref.p_span0, p_spani=self.pch_out_db) | ||||||
|  |  | ||||||
|     def __call__(self, spectral_info): |     def __call__(self, spectral_info): | ||||||
|         self.carriers_in = spectral_info.carriers |         self.carriers_in = spectral_info.carriers | ||||||
|         carriers = tuple(self.propagate(*spectral_info.carriers)) |         carriers = tuple(self.propagate(*spectral_info.carriers)) | ||||||
|         pref = self.update_pref(spectral_info.pref) |         pref = self.update_pref(spectral_info.pref) | ||||||
|         self.carriers_out = carriers |         self.carriers_out = carriers | ||||||
|         return spectral_info.update(carriers=carriers, pref=pref) |         return spectral_info._replace(carriers=carriers, pref=pref) | ||||||
|  |  | ||||||
| class EdfaParams: | class EdfaParams: | ||||||
|     def __init__(self, **params): |     def __init__(self, **params): | ||||||
| @@ -563,11 +558,6 @@ class Edfa(Node): | |||||||
|         if not (loc in ('in', 'out') and attr in ('nli', 'signal', 'total', 'ase')): |         if not (loc in ('in', 'out') and attr in ('nli', 'signal', 'total', 'ase')): | ||||||
|             yield None |             yield None | ||||||
|             return |             return | ||||||
|         power_dict = { |  | ||||||
|                         'nli':      'nonlinear_interference', |  | ||||||
|                         'ase':      'amplified_spontaneous_emission' |  | ||||||
|                     } |  | ||||||
|         attr = power_dict.get(attr, attr) |  | ||||||
|         loc_attr = 'carriers_'+loc |         loc_attr = 'carriers_'+loc | ||||||
|         for c in getattr(self, loc_attr) : |         for c in getattr(self, loc_attr) : | ||||||
|             if attr == 'total': |             if attr == 'total': | ||||||
| @@ -594,19 +584,19 @@ class Edfa(Node): | |||||||
|         """in power mode: delta_p is defined and can be used to calculate the power target |         """in power mode: delta_p is defined and can be used to calculate the power target | ||||||
|         This power target is used calculate the amplifier gain""" |         This power target is used calculate the amplifier gain""" | ||||||
|         if self.delta_p is not None: |         if self.delta_p is not None: | ||||||
|             self.target_pch_out_db = round(self.delta_p + pref.p0, 2) |             self.target_pch_out_db = round(self.delta_p + pref.p_span0, 2) | ||||||
|             self.effective_gain = self.target_pch_out_db - pref.pi |             self.effective_gain = self.target_pch_out_db - pref.p_spani | ||||||
|  |  | ||||||
|         """check power saturation and correct effective gain & power accordingly:"""             |         """check power saturation and correct effective gain & power accordingly:"""             | ||||||
|         self.effective_gain = min(   |         self.effective_gain = min(   | ||||||
|                                     self.effective_gain,  |                                     self.effective_gain,  | ||||||
|                                     self.params.p_max - (pref.pi + pref.neq_ch) |                                     self.params.p_max - (pref.p_spani + pref.neq_ch) | ||||||
|                                     ) |                                     ) | ||||||
|         #print(self.uid, self.effective_gain, self.operational.gain_target) |         #print(self.uid, self.effective_gain, self.operational.gain_target) | ||||||
|         self.effective_pch_out_db = round(pref.pi + self.effective_gain, 2) |         self.effective_pch_out_db = round(pref.p_spani + self.effective_gain, 2) | ||||||
|  |  | ||||||
|         """check power saturation and correct target_gain accordingly:""" |         """check power saturation and correct target_gain accordingly:""" | ||||||
|         #print(self.uid, self.effective_gain, self.pin_db, pref.pi) |         #print(self.uid, self.effective_gain, self.pin_db, pref.p_spani) | ||||||
|         self.nf = self._calc_nf() |         self.nf = self._calc_nf() | ||||||
|         self.gprofile = self._gain_profile(pin) |         self.gprofile = self._gain_profile(pin) | ||||||
|  |  | ||||||
| @@ -844,17 +834,17 @@ class Edfa(Node): | |||||||
|         for gain, carrier_ase, carrier in zip(gains, carrier_ases, carriers): |         for gain, carrier_ase, carrier in zip(gains, carrier_ases, carriers): | ||||||
|             pwr = carrier.power |             pwr = carrier.power | ||||||
|             pwr = pwr._replace(signal=pwr.signal*gain/att, |             pwr = pwr._replace(signal=pwr.signal*gain/att, | ||||||
|                                nonlinear_interference=pwr.nli*gain/att, |                                nli=pwr.nli*gain/att, | ||||||
|                                amplified_spontaneous_emission=(pwr.ase+carrier_ase)*gain/att) |                                ase=(pwr.ase+carrier_ase)*gain/att) | ||||||
|             yield carrier._replace(power=pwr) |             yield carrier._replace(power=pwr) | ||||||
|  |  | ||||||
|     def update_pref(self, pref): |     def update_pref(self, pref): | ||||||
|         return pref._replace(p_span0=pref.p0, |         return pref._replace(p_span0=pref.p_span0, | ||||||
|                             p_spani=pref.pi + self.effective_gain - self.out_voa) |                             p_spani=pref.p_spani + self.effective_gain - self.out_voa) | ||||||
|  |  | ||||||
|     def __call__(self, spectral_info): |     def __call__(self, spectral_info): | ||||||
|         self.carriers_in = spectral_info.carriers |         self.carriers_in = spectral_info.carriers | ||||||
|         carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers)) |         carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers)) | ||||||
|         pref = self.update_pref(spectral_info.pref) |         pref = self.update_pref(spectral_info.pref) | ||||||
|         self.carriers_out = carriers |         self.carriers_out = carriers | ||||||
|         return spectral_info.update(carriers=carriers, pref=pref) |         return spectral_info._replace(carriers=carriers, pref=pref) | ||||||
|   | |||||||
| @@ -16,50 +16,26 @@ from json import loads | |||||||
| from gnpy.core.utils import load_json | from gnpy.core.utils import load_json | ||||||
| from gnpy.core.equipment import automatic_nch, automatic_spacing | from gnpy.core.equipment import automatic_nch, automatic_spacing | ||||||
|  |  | ||||||
| class ConvenienceAccess: | class Power(namedtuple('Power', 'signal nli ase')): | ||||||
|  |  | ||||||
|     def __init_subclass__(cls): |  | ||||||
|         for abbrev, field in getattr(cls, '_ABBREVS', {}).items(): |  | ||||||
|             setattr(cls, abbrev, property(lambda self, f=field: getattr(self, f))) |  | ||||||
|  |  | ||||||
|     def update(self, **kwargs): |  | ||||||
|         for abbrev, field in getattr(self, '_ABBREVS', {}).items(): |  | ||||||
|             if abbrev in kwargs: |  | ||||||
|                 kwargs[field] = kwargs.pop(abbrev) |  | ||||||
|         return self._replace(**kwargs) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Power(namedtuple('Power', 'signal nonlinear_interference amplified_spontaneous_emission'), ConvenienceAccess): |  | ||||||
|     """carriers power in W""" |     """carriers power in W""" | ||||||
|     _ABBREVS = {'nli': 'nonlinear_interference', |  | ||||||
|                 'ase': 'amplified_spontaneous_emission',} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class Channel(namedtuple('Channel', 'channel_number frequency baud_rate roll_off power'), ConvenienceAccess): | class Channel(namedtuple('Channel', 'channel_number frequency baud_rate roll_off power')): | ||||||
|  |     pass | ||||||
|  |  | ||||||
|     _ABBREVS = {'channel':  'channel_number', |  | ||||||
|                 'num_chan': 'channel_number', |  | ||||||
|                 'ffs':      'frequency', |  | ||||||
|                 'freq':     'frequency',} |  | ||||||
|  |  | ||||||
| class Pref(namedtuple('Pref', 'p_span0, p_spani, neq_ch '), ConvenienceAccess): | class Pref(namedtuple('Pref', 'p_span0, p_spani, neq_ch ')): | ||||||
|     """noiseless reference power in dBm:  |     """noiseless reference power in dBm:  | ||||||
|     p0: inital target carrier power |     p_span0: inital target carrier power | ||||||
|     pi: carrier power after element i |     p_spani: carrier power after element i | ||||||
|     neqch: equivalent channel count in dB""" |     neq_ch: equivalent channel count in dB""" | ||||||
|  |  | ||||||
|     _ABBREVS = {'p0' :  'p_span0', |  | ||||||
|                 'pi' :  'p_spani'} |  | ||||||
|  |  | ||||||
| class SpectralInformation(namedtuple('SpectralInformation', 'pref carriers'), ConvenienceAccess): | class SpectralInformation(namedtuple('SpectralInformation', 'pref carriers')): | ||||||
|  |  | ||||||
|     def __new__(cls, pref, carriers): |     def __new__(cls, pref, carriers): | ||||||
|         return super().__new__(cls, pref, carriers) |         return super().__new__(cls, pref, carriers) | ||||||
|  |  | ||||||
| def merge_input_spectral_information(*si): |  | ||||||
|     """mix channel combs of different baud rates and power""" |  | ||||||
|     #TODO |  | ||||||
|     pass |  | ||||||
|  |  | ||||||
| def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing): | def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing): | ||||||
|     # pref in dB : convert power lin into power in dB |     # pref in dB : convert power lin into power in dB | ||||||
| @@ -86,11 +62,11 @@ if __name__ == '__main__': | |||||||
|     si = SpectralInformation() |     si = SpectralInformation() | ||||||
|     spacing = 0.05 # THz |     spacing = 0.05 # THz | ||||||
|  |  | ||||||
|     si = si.update(carriers=tuple(Channel(f+1, 191.3+spacing*(f+1), 32e9, 0.15, Power(1e-3, f, 1)) for f in range(96))) |     si = si._replace(carriers=tuple(Channel(f+1, 191.3+spacing*(f+1), 32e9, 0.15, Power(1e-3, f, 1)) for f in range(96))) | ||||||
|  |  | ||||||
|     print(f'si = {si}') |     print(f'si = {si}') | ||||||
|     print(f'si = {si.carriers[0].power.nli}') |     print(f'si = {si.carriers[0].power.nli}') | ||||||
|     print(f'si = {si.carriers[20].power.nli}') |     print(f'si = {si.carriers[20].power.nli}') | ||||||
|     si2 = si.update(carriers=tuple(c.update(power = c.power.update(nli = c.power.nli * 1e5)) |     si2 = si._replace(carriers=tuple(c._replace(power = c.power._replace(nli = c.power.nli * 1e5)) | ||||||
|                               for c in si.carriers)) |                               for c in si.carriers)) | ||||||
|     print(f'si2 = {si2}') |     print(f'si2 = {si2}') | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jan Kundrát
					Jan Kundrát