#include "model/optical_graph/OpticalWavelength.h" #include "model/optical_graph/OpticalNode.h" #include "model/optical_graph/OpticalLaser.h" #include "model/optical_graph/OpticalModulator.h" #include "model/optical_graph/OpticalFilter.h" #include "model/optical_graph/OpticalDetector.h" #include "model/optical_graph/OpticalWavelength.h" #include #include namespace DSENT { using std::list; using std::min; OpticalWavelength::OpticalWavelength(const String& instance_name_, const WavelengthGroup& wavelengths_) : m_instance_name_(instance_name_), m_wavelengths_(wavelengths_) { m_data_paths_ = new vector; } OpticalWavelength::~OpticalWavelength() { delete m_data_paths_; } const String& OpticalWavelength::getInstanceName() const { return m_instance_name_; } void OpticalWavelength::addDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_) { // Expected wavelengths check ASSERT(laser_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + " -> " + laser_->getInstanceName() + " is not expecting the set wavelengths!"); ASSERT(modulator_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + " -> " + modulator_->getInstanceName() + " is not expecting the set wavelengths!"); ASSERT(detector_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + " -> " + detector_->getInstanceName() + " is not expecting the set wavelengths!"); // Check to see if the modulator and laser already have a data path entry bool entry_exists = false; for (unsigned int i = 0; i < m_data_paths_->size(); ++i) { OpticalDataPath& current = m_data_paths_->at(i); bool current_laser = current.laser == laser_; bool current_modulator = current.modulator == modulator_; ASSERT((current_modulator && current_laser) || !current_modulator, "[Error] " + getInstanceName() + " -> Modulator is the same, but laser is different?"); // If it is already in the table if (current_modulator) { entry_exists = true; current.detectors.push_back(detector_); current.losses.push_back(loss_); } } // If it wasn't found, add the entry if (!entry_exists) m_data_paths_->push_back(OpticalDataPath(laser_, modulator_, detector_, loss_)); return; } const vector* OpticalWavelength::getDataPaths() const { return (const vector*) m_data_paths_; } WavelengthGroup OpticalWavelength::getWavelengths() const { return m_wavelengths_; } double OpticalWavelength::getLaserPower(unsigned int number_detectors_) const { ASSERT(number_detectors_ > 0, "[Error] " + getInstanceName() + " -> Number of detectors must be non-zero!"); // Find the number of actual wavelengths int number_wavelengths = getWavelengths().second - getWavelengths().first + 1; // Laser power sum double laser_power_sum = 0; // Loop through all data paths for (unsigned int i = 0; i < getDataPaths()->size(); ++i) { // Get the current data_path const OpticalDataPath& current_path = getDataPaths()->at(i); // Create data structure holding the worstcase detectors list* detectors = new list(); // Get the extinction ratio of the modulator double ER_dB = current_path.modulator->getExtinctionRatio(); // Get the insertion loss of the modulator double IR_dB = current_path.modulator->getInsertionLoss(); // Walk through all detectors in a data path for (unsigned int j = 0; j < current_path.detectors.size(); ++j) { // Convert sensitivity, extinction ratio, and path loss to a required laser power double current_laser_power = current_path.detectors[j]->getSensitivity(ER_dB) * std::pow(10.0, (current_path.losses[j] + IR_dB) / 10.0) * 1.0 / (1.0 - pow(10, -ER_dB / 10)); // Add the laser power detectors->push_back(current_laser_power); } // Cap the number of detectors number_detectors_ = std::min(number_detectors_, (unsigned int) current_path.detectors.size()); // Sort the detectors list in ascending order, only necessary if the number // of detectors is < total number of detectors if (number_detectors_ < detectors->size()) detectors->sort(); // Sum up the laser power from the worst-case detectors list::reverse_iterator iter = detectors->rbegin(); for (unsigned int j = 0; j < number_detectors_; ++j) { laser_power_sum += (*iter) / current_path.laser->getEfficiency(); ++iter; } delete detectors; } return number_wavelengths * laser_power_sum; } } // namespace DSENT