OpticalWavelength.cc revision 10447
1 2#include "model/optical_graph/OpticalWavelength.h" 3#include "model/optical_graph/OpticalNode.h" 4#include "model/optical_graph/OpticalLaser.h" 5#include "model/optical_graph/OpticalModulator.h" 6#include "model/optical_graph/OpticalFilter.h" 7#include "model/optical_graph/OpticalDetector.h" 8#include "model/optical_graph/OpticalWavelength.h" 9#include <list> 10#include <cmath> 11 12namespace DSENT 13{ 14 using std::list; 15 using std::min; 16 17 OpticalWavelength::OpticalWavelength(const String& instance_name_, const WavelengthGroup& wavelengths_) 18 : m_instance_name_(instance_name_), m_wavelengths_(wavelengths_) 19 { 20 m_data_paths_ = new vector<OpticalDataPath>; 21 } 22 23 OpticalWavelength::~OpticalWavelength() 24 { 25 delete m_data_paths_; 26 } 27 28 const String& OpticalWavelength::getInstanceName() const 29 { 30 return m_instance_name_; 31 } 32 33 void OpticalWavelength::addDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_) 34 { 35 // Expected wavelengths check 36 ASSERT(laser_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + 37 " -> " + laser_->getInstanceName() + " is not expecting the set wavelengths!"); 38 ASSERT(modulator_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + 39 " -> " + modulator_->getInstanceName() + " is not expecting the set wavelengths!"); 40 ASSERT(detector_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + 41 " -> " + detector_->getInstanceName() + " is not expecting the set wavelengths!"); 42 43 // Check to see if the modulator and laser already have a data path entry 44 bool entry_exists = false; 45 for (unsigned int i = 0; i < m_data_paths_->size(); ++i) 46 { 47 OpticalDataPath& current = m_data_paths_->at(i); 48 bool current_laser = current.laser == laser_; 49 bool current_modulator = current.modulator == modulator_; 50 51 ASSERT((current_modulator && current_laser) || !current_modulator, "[Error] " + 52 getInstanceName() + " -> Modulator is the same, but laser is different?"); 53 54 // If it is already in the table 55 if (current_modulator) 56 { 57 entry_exists = true; 58 current.detectors.push_back(detector_); 59 current.losses.push_back(loss_); 60 } 61 } 62 63 // If it wasn't found, add the entry 64 if (!entry_exists) 65 m_data_paths_->push_back(OpticalDataPath(laser_, modulator_, detector_, loss_)); 66 return; 67 } 68 69 const vector<OpticalDataPath>* OpticalWavelength::getDataPaths() const 70 { 71 return (const vector<OpticalDataPath>*) m_data_paths_; 72 } 73 74 WavelengthGroup OpticalWavelength::getWavelengths() const 75 { 76 return m_wavelengths_; 77 } 78 79 double OpticalWavelength::getLaserPower(unsigned int number_detectors_) const 80 { 81 ASSERT(number_detectors_ > 0, "[Error] " + getInstanceName() + 82 " -> Number of detectors must be non-zero!"); 83 // Find the number of actual wavelengths 84 int number_wavelengths = getWavelengths().second - getWavelengths().first + 1; 85 // Laser power sum 86 double laser_power_sum = 0; 87 // Loop through all data paths 88 for (unsigned int i = 0; i < getDataPaths()->size(); ++i) 89 { 90 // Get the current data_path 91 const OpticalDataPath& current_path = getDataPaths()->at(i); 92 // Create data structure holding the worstcase detectors 93 list<double>* detectors = new list<double>(); 94 // Get the extinction ratio of the modulator 95 double ER_dB = current_path.modulator->getExtinctionRatio(); 96 // Get the insertion loss of the modulator 97 double IR_dB = current_path.modulator->getInsertionLoss(); 98 // Walk through all detectors in a data path 99 for (unsigned int j = 0; j < current_path.detectors.size(); ++j) 100 { 101 // Convert sensitivity, extinction ratio, and path loss to a required laser power 102 double current_laser_power = current_path.detectors[j]->getSensitivity(ER_dB) * 103 std::pow(10.0, (current_path.losses[j] + IR_dB) / 10.0) * 104 1.0 / (1.0 - pow(10, -ER_dB / 10)); 105 106 // Add the laser power 107 detectors->push_back(current_laser_power); 108 } 109 // Cap the number of detectors 110 number_detectors_ = std::min(number_detectors_, (unsigned int) current_path.detectors.size()); 111 // Sort the detectors list in ascending order, only necessary if the number 112 // of detectors is < total number of detectors 113 if (number_detectors_ < detectors->size()) 114 detectors->sort(); 115 // Sum up the laser power from the worst-case detectors 116 list<double>::reverse_iterator iter = detectors->rbegin(); 117 for (unsigned int j = 0; j < number_detectors_; ++j) 118 { 119 laser_power_sum += (*iter) / current_path.laser->getEfficiency(); 120 ++iter; 121 } 122 delete detectors; 123 } 124 return number_wavelengths * laser_power_sum; 125 } 126 127} // namespace DSENT 128 129 130