OpticalWavelength.cc revision 10448
1/* Copyright (c) 2012 Massachusetts Institute of Technology 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 * THE SOFTWARE. 20 */ 21 22 23#include "model/optical_graph/OpticalWavelength.h" 24#include "model/optical_graph/OpticalNode.h" 25#include "model/optical_graph/OpticalLaser.h" 26#include "model/optical_graph/OpticalModulator.h" 27#include "model/optical_graph/OpticalFilter.h" 28#include "model/optical_graph/OpticalDetector.h" 29#include "model/optical_graph/OpticalWavelength.h" 30#include <list> 31#include <cmath> 32 33namespace DSENT 34{ 35 using std::list; 36 using std::min; 37 38 OpticalWavelength::OpticalWavelength(const String& instance_name_, const WavelengthGroup& wavelengths_) 39 : m_instance_name_(instance_name_), m_wavelengths_(wavelengths_) 40 { 41 m_data_paths_ = new vector<OpticalDataPath>; 42 } 43 44 OpticalWavelength::~OpticalWavelength() 45 { 46 delete m_data_paths_; 47 } 48 49 const String& OpticalWavelength::getInstanceName() const 50 { 51 return m_instance_name_; 52 } 53 54 void OpticalWavelength::addDataPath(OpticalLaser* laser_, OpticalModulator* modulator_, OpticalDetector* detector_, double loss_) 55 { 56 // Expected wavelengths check 57 ASSERT(laser_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + 58 " -> " + laser_->getInstanceName() + " is not expecting the set wavelengths!"); 59 ASSERT(modulator_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + 60 " -> " + modulator_->getInstanceName() + " is not expecting the set wavelengths!"); 61 ASSERT(detector_->isExpected(getWavelengths()), "[Error] " + getInstanceName() + 62 " -> " + detector_->getInstanceName() + " is not expecting the set wavelengths!"); 63 64 // Check to see if the modulator and laser already have a data path entry 65 bool entry_exists = false; 66 for (unsigned int i = 0; i < m_data_paths_->size(); ++i) 67 { 68 OpticalDataPath& current = m_data_paths_->at(i); 69 bool current_laser = current.laser == laser_; 70 bool current_modulator = current.modulator == modulator_; 71 72 ASSERT((current_modulator && current_laser) || !current_modulator, "[Error] " + 73 getInstanceName() + " -> Modulator is the same, but laser is different?"); 74 75 // If it is already in the table 76 if (current_modulator) 77 { 78 entry_exists = true; 79 current.detectors.push_back(detector_); 80 current.losses.push_back(loss_); 81 } 82 } 83 84 // If it wasn't found, add the entry 85 if (!entry_exists) 86 m_data_paths_->push_back(OpticalDataPath(laser_, modulator_, detector_, loss_)); 87 return; 88 } 89 90 const vector<OpticalDataPath>* OpticalWavelength::getDataPaths() const 91 { 92 return (const vector<OpticalDataPath>*) m_data_paths_; 93 } 94 95 WavelengthGroup OpticalWavelength::getWavelengths() const 96 { 97 return m_wavelengths_; 98 } 99 100 double OpticalWavelength::getLaserPower(unsigned int number_detectors_) const 101 { 102 ASSERT(number_detectors_ > 0, "[Error] " + getInstanceName() + 103 " -> Number of detectors must be non-zero!"); 104 // Find the number of actual wavelengths 105 int number_wavelengths = getWavelengths().second - getWavelengths().first + 1; 106 // Laser power sum 107 double laser_power_sum = 0; 108 // Loop through all data paths 109 for (unsigned int i = 0; i < getDataPaths()->size(); ++i) 110 { 111 // Get the current data_path 112 const OpticalDataPath& current_path = getDataPaths()->at(i); 113 // Create data structure holding the worstcase detectors 114 list<double>* detectors = new list<double>(); 115 // Get the extinction ratio of the modulator 116 double ER_dB = current_path.modulator->getExtinctionRatio(); 117 // Get the insertion loss of the modulator 118 double IR_dB = current_path.modulator->getInsertionLoss(); 119 // Walk through all detectors in a data path 120 for (unsigned int j = 0; j < current_path.detectors.size(); ++j) 121 { 122 // Convert sensitivity, extinction ratio, and path loss to a required laser power 123 double current_laser_power = current_path.detectors[j]->getSensitivity(ER_dB) * 124 std::pow(10.0, (current_path.losses[j] + IR_dB) / 10.0) * 125 1.0 / (1.0 - pow(10, -ER_dB / 10)); 126 127 // Add the laser power 128 detectors->push_back(current_laser_power); 129 } 130 // Cap the number of detectors 131 number_detectors_ = std::min(number_detectors_, (unsigned int) current_path.detectors.size()); 132 // Sort the detectors list in ascending order, only necessary if the number 133 // of detectors is < total number of detectors 134 if (number_detectors_ < detectors->size()) 135 detectors->sort(); 136 // Sum up the laser power from the worst-case detectors 137 list<double>::reverse_iterator iter = detectors->rbegin(); 138 for (unsigned int j = 0; j < number_detectors_; ++j) 139 { 140 laser_power_sum += (*iter) / current_path.laser->getEfficiency(); 141 ++iter; 142 } 143 delete detectors; 144 } 145 return number_wavelengths * laser_power_sum; 146 } 147 148} // namespace DSENT 149 150 151