[docs]classSI(Evaluator,Serializable):"""Evaluate a simulated device's self-interference power."""__device:SimulatedDevice_input_hook:Hook[ProcessedSimulatedDeviceInput]_input:ProcessedSimulatedDeviceInput|Nonedef__init__(self,device:SimulatedDevice)->None:""" Args: device: The device to evaluate. """# Initialize the base classEvaluator.__init__(self)self.plot_scale="log"# Register input hookself.__device=deviceself._input_hook=device.simulated_input_callbacks.add_callback(self.__input_callback)def__input_callback(self,input:ProcessedSimulatedDeviceInput)->None:"""Callback function notifying the evaluator of a new input."""self._input=input@property@overridedefabbreviation(self)->str:return"SI"@property@overridedeftitle(self)->str:return"Self-Interference"
[docs]@overridedefevaluate(self)->PowerEvaluation:ifself._inputisNone:raiseRuntimeError("Self-interference evaluator could not fetch input. Has the device received data?")returnPowerEvaluation(self._input.leaking_signal.power)
[docs]@overridedefgenerate_result(self,grid:Sequence[GridDimension],artifacts:np.ndarray)->PowerResult:# Find the maximum number of receive ports over all artifactsmax_ports=max(max(artifact.power.sizeforartifactinartifacts)forartifactsinartifacts.flat)mean_powers=np.zeros((*artifacts.shape,max_ports),dtype=np.float64)forgrid_index,artifactsinnp.ndenumerate(artifacts):forartifactinartifacts:mean_powers[grid_index]+=artifact.powernum_artifacts=len(artifacts)ifnum_artifacts>0:mean_powers[grid_index]/=len(artifacts)returnPowerResult(mean_powers,grid,self)
[docs]classSSINR(SI):"""Signal to self-interfernce plus noise power ratio evaluator."""@property@overridedefabbreviation(self)->str:return"SSINR"@property@overridedeftitle(self)->str:return"Signal to Self-Interference plus Noise Power Ratio"
[docs]@overridedefevaluate(self)->PowerEvaluation:ifself._inputisNone:raiseRuntimeError("SSINR evaluator could not fetch input. Has the device received data?")# Power of the noise realization per receive channelnoise_power=self._input.noise_realization.power# Power of the self-interferencesi_power=self._input.leaking_signal.power# Power of the useful signal# ToDo: The definition of impinging signals is inconsistentsignal_power=np.zeros(self._input.impinging_signals[0].num_streams,dtype=np.float64)forsignalinself._input.impinging_signals:signal_power+=signal.power# SSINRssinr=signal_power/(si_power+noise_power)returnPowerEvaluation(ssinr)