1 /* Copyright (c) 2012 Massachusetts Institute of Technology
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
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"
38 OpticalWavelength::OpticalWavelength(const String
& instance_name_
, const WavelengthGroup
& wavelengths_
)
39 : m_instance_name_(instance_name_
), m_wavelengths_(wavelengths_
)
41 m_data_paths_
= new vector
<OpticalDataPath
>;
44 OpticalWavelength::~OpticalWavelength()
49 const String
& OpticalWavelength::getInstanceName() const
51 return m_instance_name_
;
54 void OpticalWavelength::addDataPath(OpticalLaser
* laser_
, OpticalModulator
* modulator_
, OpticalDetector
* detector_
, double loss_
)
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!");
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
)
68 OpticalDataPath
& current
= m_data_paths_
->at(i
);
69 bool current_laser
= current
.laser
== laser_
;
70 bool current_modulator
= current
.modulator
== modulator_
;
72 ASSERT((current_modulator
&& current_laser
) || !current_modulator
, "[Error] " +
73 getInstanceName() + " -> Modulator is the same, but laser is different?");
75 // If it is already in the table
76 if (current_modulator
)
79 current
.detectors
.push_back(detector_
);
80 current
.losses
.push_back(loss_
);
84 // If it wasn't found, add the entry
86 m_data_paths_
->push_back(OpticalDataPath(laser_
, modulator_
, detector_
, loss_
));
90 const vector
<OpticalDataPath
>* OpticalWavelength::getDataPaths() const
92 return (const vector
<OpticalDataPath
>*) m_data_paths_
;
95 WavelengthGroup
OpticalWavelength::getWavelengths() const
97 return m_wavelengths_
;
100 double OpticalWavelength::getLaserPower(unsigned int number_detectors_
) const
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;
107 double laser_power_sum
= 0;
108 // Loop through all data paths
109 for (unsigned int i
= 0; i
< getDataPaths()->size(); ++i
)
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
)
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));
127 // Add the laser power
128 detectors
->push_back(current_laser_power
);
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())
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
)
140 laser_power_sum
+= (*iter
) / current_path
.laser
->getEfficiency();
145 return number_wavelengths
* laser_power_sum
;