263 const std::vector<MHz_u>& centerFrequencies,
266 MHz_u guardBandwidth,
270 const std::vector<bool>& puncturedSubchannels)
273 (channelWidth ==
MHz_u{160} && centerFrequencies.size() <= 2),
274 "PSD for non-contiguous channels is only possible when the total width is 160 "
275 "MHz and cannot be made of more than 2 segments");
277 << channelWidth << txPower << guardBandwidth << minInnerBand << minOuterBand
279 const Hz_u carrierSpacing{312500};
281 GetSpectrumModel(centerFrequencies, channelWidth, carrierSpacing, guardBandwidth));
284 guardBandwidth /= centerFrequencies.size();
285 const auto nGuardBands =
286 static_cast<uint32_t>(((
MHzToHz(2 * guardBandwidth)) / carrierSpacing) + 0.5);
287 const auto nAllocatedBands =
289 const auto separationWidth = std::abs(centerFrequencies.back() - centerFrequencies.front());
290 const auto unallocatedWidth =
291 separationWidth >
Hz_u{0} ? (separationWidth - (channelWidth / 2)) : 0;
292 const auto nUnallocatedBands =
293 static_cast<uint32_t>((
MHzToHz(unallocatedWidth) / carrierSpacing) + 0.5);
295 (nAllocatedBands + nGuardBands + nUnallocatedBands + 1),
296 "Unexpected number of bands " << c->GetSpectrumModel()->GetNumBands());
298 std::size_t numAllocatedSubcarriersPer20MHz = 52;
299 NS_ASSERT(puncturedSubchannels.empty() || (puncturedSubchannels.size() == num20MhzBands));
300 const auto txPowerPerBand = (txPower / numAllocatedSubcarriersPer20MHz) / num20MhzBands;
301 NS_LOG_DEBUG(
"Power per band " << txPowerPerBand <<
"W");
303 std::size_t numSubcarriersPer20MHz =
MHzToHz(
MHz_u{20}) / carrierSpacing;
304 std::size_t numUnallocatedSubcarriersPer20MHz =
305 numSubcarriersPer20MHz - numAllocatedSubcarriersPer20MHz;
306 std::vector<std::vector<WifiSpectrumBandIndices>> subBandsPerSegment(
307 centerFrequencies.size());
308 for (std::size_t i = 0; i < centerFrequencies.size(); ++i)
310 subBandsPerSegment.at(i).resize(
311 num20MhzBands * 2 / centerFrequencies.size());
314 std::vector<std::vector<WifiSpectrumBandIndices>> puncturedBandsPerSegment;
315 uint32_t start = (nGuardBands / 2) + (numUnallocatedSubcarriersPer20MHz / 2);
318 for (
auto& subBands : subBandsPerSegment)
320 puncturedBandsPerSegment.emplace_back();
321 for (
auto it = subBands.begin(); it != subBands.end();)
323 stop = start + (numAllocatedSubcarriersPer20MHz / 2) - 1;
324 *it = std::make_pair(start, stop);
328 stop = start + (numAllocatedSubcarriersPer20MHz / 2) - 1;
329 *it = std::make_pair(start, stop);
331 start = stop + numUnallocatedSubcarriersPer20MHz;
333 if (!puncturedSubchannels.empty() && puncturedSubchannels.at(index++))
335 puncturedBandsPerSegment.back().emplace_back(puncturedStart, puncturedStop);
338 start += nUnallocatedBands;
342 auto innerSlopeWidth =
static_cast<uint32_t>(
343 (
Hz_u{2e6} / carrierSpacing) +
346 const auto puncturedSlopeWidth =
360 puncturedBandsPerSegment,
361 puncturedSlopeWidth);
480 const std::vector<MHz_u>& centerFrequencies,
483 MHz_u guardBandwidth,
487 const std::vector<bool>& puncturedSubchannels)
490 centerFrequencies.size() == 1 || channelWidth ==
MHz_u{160},
491 "PSD for non-contiguous channels is only possible when the total width is 160 MHz");
493 << channelWidth << txPower << guardBandwidth << minInnerBand << minOuterBand
495 const Hz_u carrierSpacing{78125};
497 GetSpectrumModel(centerFrequencies, channelWidth, carrierSpacing, guardBandwidth));
500 guardBandwidth /= centerFrequencies.size();
501 const auto nGuardBands =
502 static_cast<uint32_t>(((
MHzToHz(2 * guardBandwidth)) / carrierSpacing) + 0.5);
503 const auto separationWidth = std::abs(centerFrequencies.back() - centerFrequencies.front());
504 const auto unallocatedWidth =
505 separationWidth >
Hz_u{0} ? (separationWidth - (channelWidth / 2)) : 0;
506 const auto nUnallocatedBands =
507 static_cast<uint32_t>((
MHzToHz(unallocatedWidth) / carrierSpacing) + 0.5);
508 const auto nAllocatedBands =
511 (nAllocatedBands + nGuardBands + nUnallocatedBands + 1),
512 "Unexpected number of bands " << c->GetSpectrumModel()->GetNumBands());
513 Watt_u txPowerPerBand{0.0};
523 auto innerSlopeWidth =
526 std::vector<std::vector<WifiSpectrumBandIndices>> subBandsPerSegment(
527 centerFrequencies.size());
529 switch (
static_cast<uint16_t
>(channelWidth))
533 txPowerPerBand = txPower / 242;
534 innerSlopeWidth =
static_cast<uint32_t>((
Hz_u{5e5} / carrierSpacing) +
539 start1 = (nGuardBands / 2) + 6;
540 stop1 = start1 + 121 - 1;
542 stop2 = start2 + 121 - 1;
543 subBandsPerSegment.at(0).emplace_back(start1, stop1);
544 subBandsPerSegment.at(0).emplace_back(start2, stop2);
548 txPowerPerBand = txPower / 484;
552 start1 = (nGuardBands / 2) + 12;
553 stop1 = start1 + 242 - 1;
555 stop2 = start2 + 242 - 1;
556 subBandsPerSegment.at(0).emplace_back(start1, stop1);
557 subBandsPerSegment.at(0).emplace_back(start2, stop2);
561 txPowerPerBand = txPower / 996;
565 start1 = (nGuardBands / 2) + 12;
566 stop1 = start1 + 498 - 1;
568 stop2 = start2 + 498 - 1;
569 subBandsPerSegment.at(0).emplace_back(start1, stop1);
570 subBandsPerSegment.at(0).emplace_back(start2, stop2);
574 "It is not possible to create a PSD made of more than 2 segments for a width "
577 txPowerPerBand = txPower / (2 * 996);
578 start1 = (nGuardBands / 2) + 12;
579 stop1 = start1 + 498 - 1;
581 stop2 = start2 + 498 - 1;
582 start3 = stop2 + (2 * 12) + nUnallocatedBands;
583 stop3 = start3 + 498 - 1;
585 stop4 = start4 + 498 - 1;
586 subBandsPerSegment.at(0).emplace_back(start1, stop1);
587 subBandsPerSegment.at(0).emplace_back(start2, stop2);
588 subBandsPerSegment.at(subBandsPerSegment.size() - 1).emplace_back(start3, stop3);
589 subBandsPerSegment.at(subBandsPerSegment.size() - 1).emplace_back(start4, stop4);
593 NS_FATAL_ERROR(
"ChannelWidth " << channelWidth <<
" unsupported");
598 auto puncturedSlopeWidth =
601 std::vector<std::vector<WifiSpectrumBandIndices>> puncturedBandsPerSegment;
602 std::size_t subcarriersPerSuband = (
MHzToHz(
MHz_u{20}) / carrierSpacing);
604 uint32_t stop = start + subcarriersPerSuband - 1;
605 if (!puncturedSubchannels.empty())
607 for (std::size_t i = 0; i < subBandsPerSegment.size(); ++i)
609 puncturedBandsPerSegment.emplace_back();
612 std::size_t prevPsdIndex = 0;
613 for (std::size_t i = 0; i < puncturedSubchannels.size(); ++i)
615 std::size_t psdIndex = (puncturedBandsPerSegment.size() == 1)
617 : ((i < (puncturedSubchannels.size() / 2)) ? 0 : 1);
618 if (psdIndex != prevPsdIndex)
620 start += nUnallocatedBands;
621 stop += nUnallocatedBands;
623 if (puncturedSubchannels.at(i))
625 puncturedBandsPerSegment.at(psdIndex).emplace_back(start, stop);
628 stop = start + subcarriersPerSuband - 1;
629 prevPsdIndex = psdIndex;
642 puncturedBandsPerSegment,
643 puncturedSlopeWidth);
695 const std::vector<std::vector<WifiSpectrumBandIndices>>& allocatedSubBandsPerSegment,
703 const std::vector<std::vector<WifiSpectrumBandIndices>>& puncturedBandsPerSegment,
707 "Only PSDs for up to 2 frequency segments are supported");
708 NS_ASSERT(puncturedBandsPerSegment.empty() ||
709 (puncturedBandsPerSegment.size() == allocatedSubBandsPerSegment.size()));
711 << allocatedSubBandsPerSegment.front().back().second << maskBand.first
712 << maskBand.second << txPowerPerBand << nGuardBands << innerSlopeWidth
713 << minInnerBand << minOuterBand << lowestPoint << puncturedSlopeWidth);
714 uint32_t numSubBands = allocatedSubBandsPerSegment.front().size();
715 uint32_t numBands = c->GetSpectrumModel()->GetNumBands();
716 uint32_t numMaskBands = maskBand.second - maskBand.first + 1;
717 NS_ASSERT(numSubBands && numBands && numMaskBands);
718 NS_LOG_LOGIC(
"Power per band " << txPowerPerBand <<
"W");
721 dBm_u txPowerRef{10.0 * std::log10(txPowerPerBand * 1000.0)};
722 dBm_u txPowerInnerBandMin{txPowerRef + minInnerBand};
723 dBm_u txPowerMiddleBandMin{txPowerRef + minOuterBand};
724 dBm_u txPowerOuterBandMin{txPowerRef +
731 uint32_t middleSlopeWidth = outerSlopeWidth - (innerSlopeWidth / 2);
733 std::vector<WifiSpectrumBandIndices> outerBandsLeft;
734 std::vector<WifiSpectrumBandIndices> middleBandsLeft;
735 std::vector<WifiSpectrumBandIndices> flatJunctionsLeft;
736 std::vector<WifiSpectrumBandIndices> innerBandsLeft;
737 std::vector<WifiSpectrumBandIndices> allocatedSubBands;
738 std::vector<WifiSpectrumBandIndices> innerBandsRight;
739 std::vector<WifiSpectrumBandIndices> flatJunctionsRight;
740 std::vector<WifiSpectrumBandIndices> middleBandsRight;
741 std::vector<WifiSpectrumBandIndices> outerBandsRight;
742 std::optional<WifiSpectrumBandIndices> betweenPsdsBand;
744 allocatedSubBands.emplace_back(allocatedSubBandsPerSegment.front().front().first,
745 allocatedSubBandsPerSegment.front().back().second);
746 outerBandsLeft.emplace_back(maskBand.first,
748 maskBand.first + outerSlopeWidth - 1);
749 middleBandsLeft.emplace_back(outerBandsLeft.front().second + 1,
750 outerBandsLeft.front().second + middleSlopeWidth);
751 innerBandsLeft.emplace_back(allocatedSubBands.front().first - innerSlopeWidth,
752 allocatedSubBands.front().first -
754 flatJunctionsLeft.emplace_back(middleBandsLeft.front().second + 1,
755 innerBandsLeft.front().first -
758 flatJunctionsLeft.front().second - flatJunctionsLeft.front().first + 1;
759 innerBandsRight.emplace_back(allocatedSubBands.front().second + 1,
760 allocatedSubBands.front().second + innerSlopeWidth);
761 flatJunctionsRight.emplace_back(innerBandsRight.front().second + 1,
762 innerBandsRight.front().second + flatJunctionWidth);
763 middleBandsRight.emplace_back(flatJunctionsRight.front().second + 1,
764 flatJunctionsRight.front().second + middleSlopeWidth);
765 outerBandsRight.emplace_back(middleBandsRight.front().second + 1,
766 middleBandsRight.front().second + outerSlopeWidth);
768 if (allocatedSubBandsPerSegment.size() > 1)
770 const auto offset = (((allocatedSubBandsPerSegment.front().back().second -
771 allocatedSubBandsPerSegment.front().front().first) /
773 (allocatedSubBandsPerSegment.back().front().first -
774 allocatedSubBandsPerSegment.front().back().second) +
775 ((allocatedSubBandsPerSegment.back().back().second -
776 allocatedSubBandsPerSegment.back().front().first) /
778 outerBandsLeft.emplace_back(outerBandsLeft.front().first + offset,
779 outerBandsLeft.front().second + offset);
780 middleBandsLeft.emplace_back(middleBandsLeft.front().first + offset,
781 middleBandsLeft.front().second + offset);
782 flatJunctionsLeft.emplace_back(flatJunctionsLeft.front().first + offset,
783 flatJunctionsLeft.front().second + offset);
784 innerBandsLeft.emplace_back(innerBandsLeft.front().first + offset,
785 innerBandsLeft.front().second + offset);
786 allocatedSubBands.emplace_back(allocatedSubBands.front().first + offset,
787 allocatedSubBands.front().second + offset);
788 innerBandsRight.emplace_back(innerBandsRight.front().first + offset,
789 innerBandsRight.front().second + offset);
790 flatJunctionsRight.emplace_back(flatJunctionsRight.front().first + offset,
791 flatJunctionsRight.front().second + offset);
792 middleBandsRight.emplace_back(middleBandsRight.front().first + offset,
793 middleBandsRight.front().second + offset);
794 outerBandsRight.emplace_back(outerBandsRight.front().first + offset,
795 outerBandsRight.front().second + offset);
796 betweenPsdsBand.emplace(middleBandsRight.front().first, middleBandsLeft.back().second);
799 std::ostringstream ss;
800 for (std::size_t i = 0; i < allocatedSubBandsPerSegment.size(); ++i)
802 if (allocatedSubBandsPerSegment.size() > 1)
804 ss <<
"PSD" << i + 1 <<
": ";
806 ss <<
"outerBandLeft=[" << outerBandsLeft.at(i).first <<
";" << outerBandsLeft.at(i).second
808 <<
"middleBandLeft=[" << middleBandsLeft.at(i).first <<
";"
809 << middleBandsLeft.at(i).second <<
"] "
810 <<
"flatJunctionLeft=[" << flatJunctionsLeft.at(i).first <<
";"
811 << flatJunctionsLeft.at(i).second <<
"] "
812 <<
"innerBandLeft=[" << innerBandsLeft.at(i).first <<
";" << innerBandsLeft.at(i).second
814 <<
"allocatedBand=[" << allocatedSubBands.at(i).first <<
";"
815 << allocatedSubBands.at(i).second <<
"] ";
816 if (!puncturedBandsPerSegment.empty() && !puncturedBandsPerSegment.at(i).empty())
818 ss <<
"puncturedBands=[" << puncturedBandsPerSegment.at(i).front().first <<
";"
819 << puncturedBandsPerSegment.at(i).back().second <<
"] ";
821 ss <<
"innerBandRight=[" << innerBandsRight.at(i).first <<
";"
822 << innerBandsRight.at(i).second <<
"] "
823 <<
"flatJunctionRight=[" << flatJunctionsRight.at(i).first <<
";"
824 << flatJunctionsRight.at(i).second <<
"] "
825 <<
"middleBandRight=[" << middleBandsRight.at(i).first <<
";"
826 << middleBandsRight.at(i).second <<
"] "
827 <<
"outerBandRight=[" << outerBandsRight.at(i).first <<
";"
828 << outerBandsRight.at(i).second <<
"] ";
830 if (allocatedSubBandsPerSegment.size() > 1)
833 <<
"outerBandLeft=[" << outerBandsLeft.front().first <<
";"
834 << outerBandsLeft.front().second <<
"] "
835 <<
"middleBandLeft=[" << middleBandsLeft.front().first <<
";"
836 << middleBandsLeft.front().second <<
"] "
837 <<
"flatJunctionLeft=[" << flatJunctionsLeft.front().first <<
";"
838 << flatJunctionsLeft.front().second <<
"] "
839 <<
"innerBandLeft=[" << innerBandsLeft.front().first <<
";"
840 << innerBandsLeft.front().second <<
"] "
841 <<
"allocatedBandInPsd1=[" << allocatedSubBands.front().first <<
";"
842 << allocatedSubBands.front().second <<
"] ";
843 if (!puncturedBandsPerSegment.empty() && !puncturedBandsPerSegment.front().empty())
845 ss <<
"puncturedBandsInPsd1=[" << puncturedBandsPerSegment.front().front().first <<
";"
846 << puncturedBandsPerSegment.front().back().second <<
"] ";
848 ss <<
"flatJunctionRightPsd1=[" << flatJunctionsRight.front().first <<
";"
849 << flatJunctionsRight.front().second <<
"] "
850 <<
"linearSum=[" << betweenPsdsBand->first <<
";" << betweenPsdsBand->second <<
"] "
851 <<
"flatJunctionLeftPsd2=[" << flatJunctionsLeft.back().first <<
";"
852 << flatJunctionsLeft.back().second <<
"] "
853 <<
"innerBandLeftPsd2=[" << innerBandsLeft.back().first <<
";"
854 << innerBandsLeft.back().second <<
"] "
855 <<
"allocatedBandInPsd2=[" << allocatedSubBands.back().first <<
";"
856 << allocatedSubBands.back().second <<
"] ";
857 if (!puncturedBandsPerSegment.empty() && !puncturedBandsPerSegment.back().empty())
859 ss <<
"puncturedBandsInPsd2=[" << puncturedBandsPerSegment.back().front().first <<
";"
860 << puncturedBandsPerSegment.back().back().second <<
"] ";
862 ss <<
"innerBandRight=[" << innerBandsRight.back().first <<
";"
863 << innerBandsRight.back().second <<
"] "
864 <<
"flatJunctionRight=[" << flatJunctionsRight.back().first <<
";"
865 << flatJunctionsRight.back().second <<
"] "
866 <<
"middleBandRight=[" << middleBandsRight.back().first <<
";"
867 << middleBandsRight.back().second <<
"] "
868 <<
"outerBandRight=[" << outerBandsRight.back().first <<
";"
869 << outerBandsRight.back().second <<
"] ";
872 NS_ASSERT(maskBand.second == outerBandsRight.back().second);
874 ((allocatedSubBandsPerSegment.back().back().second -
875 allocatedSubBandsPerSegment.front().front().first +
877 + 2 * (innerSlopeWidth + middleSlopeWidth + outerSlopeWidth + flatJunctionWidth)));
880 double innerSlope = (-1.0 * minInnerBand) / innerSlopeWidth;
881 double middleSlope = (-1.0 * (minOuterBand - minInnerBand)) / middleSlopeWidth;
882 double outerSlope = (txPowerMiddleBandMin - txPowerOuterBandMin) / outerSlopeWidth;
883 double puncturedSlope = (-1.0 * minInnerBand) / puncturedSlopeWidth;
886 Watt_u previousTxPower{0.0};
887 std::vector<Watt_u> txPowerValues(numBands);
888 NS_ASSERT(txPowerValues.size() == numBands);
889 for (
size_t i = 0; i < numBands; ++i)
892 (allocatedSubBandsPerSegment.size() == 1) ? 0 : ((i < (numBands / 2)) ? 0 : 1);
894 if (i < maskBand.first || i > maskBand.second)
898 else if (betweenPsdsBand.has_value() &&
899 (i <= betweenPsdsBand->second && i >= betweenPsdsBand->first))
902 std::vector<Watt_u> txPowerWPsds(2);
903 if (i <= middleBandsRight.at(0).second && i >= middleBandsRight.at(0).first)
906 DbmToW(txPowerInnerBandMin -
907 ((i - middleBandsRight.at(0).first + 1) *
910 else if (i <= outerBandsRight.at(0).second && i >= outerBandsRight.at(0).first)
913 DbmToW(txPowerMiddleBandMin -
914 ((i - outerBandsRight.at(0).first + 1) *
917 else if (i > outerBandsRight.at(0).second)
919 txPower =
DbmToW(txPowerOuterBandMin);
927 if (i < outerBandsLeft.at(1).first)
929 txPower =
DbmToW(txPowerOuterBandMin);
931 else if (i <= outerBandsLeft.at(1).second && i >= outerBandsLeft.at(1).first)
934 DbmToW(txPowerOuterBandMin + ((i - outerBandsLeft.at(1).first) * outerSlope));
936 else if (i <= middleBandsLeft.at(1).second && i >= middleBandsLeft.at(1).first)
938 txPowerWPsds.at(1) =
DbmToW(txPowerMiddleBandMin +
939 ((i - middleBandsLeft.at(1).first) * middleSlope));
946 txPower = std::accumulate(txPowerWPsds.cbegin(), txPowerWPsds.cend(),
Watt_u{0.0});
947 txPower = std::max(
DbmToW(txPowerRef - 25.0), txPower);
948 txPower = std::min(
DbmToW(txPowerRef - 20.0), txPower);
950 else if (i <= outerBandsLeft.at(psdIndex).second &&
951 i >= outerBandsLeft.at(psdIndex)
954 txPower =
DbmToW(txPowerOuterBandMin +
955 ((i - outerBandsLeft.at(psdIndex).first) * outerSlope));
957 else if (i <= middleBandsLeft.at(psdIndex).second &&
958 i >= middleBandsLeft.at(psdIndex).first)
960 txPower =
DbmToW(txPowerMiddleBandMin +
961 ((i - middleBandsLeft.at(psdIndex).first) * middleSlope));
963 else if ((i <= flatJunctionsLeft.at(psdIndex).second &&
964 i >= flatJunctionsLeft.at(psdIndex).first) ||
965 (i <= flatJunctionsRight.at(psdIndex).second &&
966 i >= flatJunctionsRight.at(psdIndex).first))
968 txPower =
DbmToW(txPowerInnerBandMin);
970 else if (i <= innerBandsLeft.at(psdIndex).second && i >= innerBandsLeft.at(psdIndex).first)
972 txPower = (!puncturedBandsPerSegment.empty() &&
973 !puncturedBandsPerSegment.at(psdIndex).empty() &&
974 (puncturedBandsPerSegment.at(psdIndex).front().first <=
975 allocatedSubBandsPerSegment.at(psdIndex).front().first))
976 ?
DbmToW(txPowerInnerBandMin)
978 DbmToW(txPowerInnerBandMin +
979 ((i - innerBandsLeft.at(psdIndex).first) * innerSlope));
981 else if ((i <= allocatedSubBandsPerSegment.at(psdIndex).back().second &&
982 i >= allocatedSubBandsPerSegment.at(psdIndex).front().first))
985 bool insideSubBand =
false;
986 for (
uint32_t j = 0; !insideSubBand && j < numSubBands;
989 insideSubBand = (i <= allocatedSubBandsPerSegment.at(psdIndex)[j].second) &&
990 (i >= allocatedSubBandsPerSegment.at(psdIndex)[j].first);
994 bool insidePuncturedSubBand =
false;
996 std::size_t puncturedBandSize = !puncturedBandsPerSegment.empty()
997 ? puncturedBandsPerSegment.at(psdIndex).size()
999 for (; !insidePuncturedSubBand && j < puncturedBandSize;
1002 insidePuncturedSubBand =
1003 (i <= puncturedBandsPerSegment.at(psdIndex).at(j).second) &&
1004 (i >= puncturedBandsPerSegment.at(psdIndex).at(j).first);
1006 if (insidePuncturedSubBand)
1009 (puncturedBandsPerSegment.at(psdIndex)
1010 .at(puncturedBandsPerSegment.at(psdIndex).size() - 1)
1012 puncturedSlopeWidth);
1013 if (i >= startPuncturedSlope)
1015 txPower =
DbmToW(txPowerInnerBandMin +
1016 ((i - startPuncturedSlope) * puncturedSlope));
1021 DbmToW(txPowerInnerBandMin),
1023 ((i - puncturedBandsPerSegment.at(psdIndex).at(0).first) *
1029 txPower = txPowerPerBand;
1034 txPower =
DbmToW(txPowerInnerBandMin);
1037 else if (i <= innerBandsRight.at(psdIndex).second &&
1038 i >= innerBandsRight.at(psdIndex).first)
1043 DbmToW(txPowerRef - ((i - innerBandsRight.at(psdIndex).first + 1) *
1046 else if (i <= middleBandsRight.at(psdIndex).second &&
1047 i >= middleBandsRight.at(psdIndex).first)
1049 txPower =
DbmToW(txPowerInnerBandMin -
1050 ((i - middleBandsRight.at(psdIndex).first + 1) *
1053 else if (i <= outerBandsRight.at(psdIndex).second &&
1054 i >= outerBandsRight.at(psdIndex).first)
1056 txPower =
DbmToW(txPowerMiddleBandMin -
1057 ((i - outerBandsRight.at(psdIndex).first + 1) *
1064 NS_LOG_LOGIC(i <<
" -> " << (10 * std::log10(txPower / txPowerPerBand)));
1065 previousTxPower = txPower;
1066 txPowerValues.at(i) = txPower;
1070 auto vit = c->ValuesBegin();
1071 auto bit = c->ConstBandsBegin();
1072 const auto invBandwidth = 1 / (bit->fh - bit->fl);
1073 for (
auto txPowerValue : txPowerValues)
1075 *vit = txPowerValue * invBandwidth;
1080 for (
const auto& allocatedSubBands : allocatedSubBandsPerSegment)
1082 NS_LOG_INFO(
"Added signal power to subbands " << allocatedSubBands.front().first <<
"-"
1083 << allocatedSubBands.back().second);