User Manual, Developers Guide and API Documentation

GeneratorMMPP.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <CONSTANZE/GeneratorMMPP.hpp>
00029 #include <CONSTANZE/Generator.hpp>
00030 #include <CONSTANZE/Binding.hpp>
00031 #include <CONSTANZE/ConstanzeComponent.hpp>
00032 
00033 #include <WNS/module/Base.hpp>
00034 #include <WNS/distribution/Distribution.hpp>
00035 #include <WNS/node/Node.hpp>
00036 
00037 #include <fstream>
00038 
00039 using namespace constanze;
00040 using namespace wns::markovchain;
00041 
00042 // objects of these classes are created by name:
00043 // the names are specified in Constanze.py as __plugin__
00044 STATIC_FACTORY_REGISTER_WITH_CREATOR(constanze::GeneratorMMPP, constanze::GeneratorBase, "MMPP", wns::PyConfigViewCreator);
00045 STATIC_FACTORY_REGISTER_WITH_CREATOR(constanze::GeneratorMMPP, constanze::GeneratorBase, "CTMMPP", wns::PyConfigViewCreator);
00046 
00047 /*************************** Generator *******************************/
00048 
00049 GeneratorMMPP::GeneratorMMPP( const wns::pyconfig::View& config) :
00050     GeneratorBase(config), // config goes into pyco (member)
00051     MarkovContinuousTimeTraffic(config.get<int>("numberOfChains")), // other base class
00052     //numberOfChains(config.get<int>("numberOfChains")), // already in MarkovBase class
00053     targetRate(0.0),
00054     loggerName(config.get<std::string>("logger.name"))
00055 {
00056     assure(config.knows("rateScale"),"missing rateScale parameter");
00057     assure(config.knows("targetRate"),"missing targetRate parameter");
00058     assure((config.isNone("rateScale") && !config.isNone("targetRate"))
00059            || (!config.isNone("rateScale") && config.isNone("targetRate")),
00060            "rateScale and targetRate are mutually exclusive. Set one to None!");
00061     if (!config.isNone("rateScale")) {
00062         rateScale=config.get<double>("rateScale"); // in MarkovContinuosTimeTraffic class
00063     } else {
00064         targetRate=config.get<double>("targetRate");
00065     }
00066     assure(rateScale>0.0,"bad rateScale");
00067     transitionScale=config.get<double>("transitionScale"); // in MarkovContinuousTime class
00068     assure(transitionScale>0.0,"bad transitionScale");
00069     // we have two loggers, one from each base class
00070     //logger = log; // from MarkovBase::logger GeneratorBase::log
00071     logger = wns::logger::Logger(log.getModuleName(), loggerName + ".CTMC");
00072     logger.setLevel(log.getLevel()); // copy logging level
00073 
00074     // sub structure "mmppParams":
00075     wns::pyconfig::View mmppParamsConfig(config, "mmppParams");
00076     int startState = mmppParamsConfig.get<int>("startState"); // valid for all chains
00077     bool fromFile  = mmppParamsConfig.get<bool>("fromFile");
00078     std::string transitionDistributionSpec;
00079     if (mmppParamsConfig.knows("transitionDistribution")
00080         && !mmppParamsConfig.isNone("transitionDistribution")) {
00081         transitionDistributionSpec = mmppParamsConfig.get<std::string>("transitionDistribution");
00082     } else {
00083         transitionDistributionSpec = "NegExp(X)";
00084     }
00085 
00086     MESSAGE_BEGIN(NORMAL, log, m, "New GeneratorMMPP: ");
00087     m << "C=" << numberOfChains << ", rs=" << rateScale << ", ts=" << transitionScale
00088       << ", TD=" << transitionDistributionSpec;
00089     MESSAGE_END();
00090 
00091     if (fromFile) { // read parameters from GDF file (format used in Opnet)
00092         // examples are in ./framework/libwns--main--3.0/PyConfig/wns/markov/*.gdf
00093         std::string filename = mmppParamsConfig.get<std::string>("filename");
00094         MESSAGE_BEGIN(NORMAL, log, m, "reading from ");
00095         m << "filename=" << filename;
00096         MESSAGE_END();
00097         //std::fstream in(filename.c_str(),std::ios::in); // opens automatically
00098         std::ifstream in(filename.c_str()); // opens automatically
00099         assure(in.good(),"error opening file "+filename);
00100         MarkovContinuousTimeTraffic::readNumberOfStates(in);
00101         MarkovContinuousTimeTraffic::readStatesFromFile(in);
00102         MarkovContinuousTimeTraffic::readTransitionsFromFile(in);
00103         in.close();
00104         for(int chain=0; chain<numberOfChains; chain++)
00105             startStates[chain]=startState; // here: one value for all
00106     } else { // params from class MMPPparams
00107         int numberOfStates = mmppParamsConfig.get<int>("numberOfStates");
00108         assure(mmppParamsConfig.len("transitionMatrix") == numberOfStates, "transitionMatrix: wrong dimension");
00109         assure(mmppParamsConfig.len("stateList") == numberOfStates, "stateList: wrong dimension");
00110         setNumberOfStates(numberOfStates);
00111         if (!mmppParamsConfig.knows("startStates")
00112             || mmppParamsConfig.isNone("startStates")) { // no startStates[] specified
00113             for(int chain=0; chain<numberOfChains; chain++)
00114                 startStates[chain] = startState;
00115         } else { // startStates[] specified as an array
00116             assure(mmppParamsConfig.len("startStates") == numberOfChains, "startStates: wrong dimension");
00117             for(int chain=0; chain<numberOfChains; chain++) {
00118                 int aStartState = mmppParamsConfig.get<int>("startStates", chain);
00119                 startStates[chain] = aStartState;
00120             }
00121         } // else: startStates[] specified as an array
00122         for(int state=0; state < numberOfStates; state++) {
00123             // get the state specifications:
00124             wns::pyconfig::View stateConfig = mmppParamsConfig.get("stateList", state);
00125             vectorOfStates[state] = TrafficSpec(stateConfig); // inherited member
00126 
00127             // the following lines in MESSAGE_BEGIN/MESSAGE_END are
00128             // only for showing the parameters of the state:
00129             MESSAGE_BEGIN(NORMAL, log, m, "State["<<state<<"]: ");
00130             m << "iat=" << *(vectorOfStates[state].getInterArrivalTimeDistribution())
00131               << ", packetSize=" << *(vectorOfStates[state].getPacketSizeDistribution())
00132               << ", mean=" << vectorOfStates[state].getMeanRate() * rateScale << " bits/s";
00133             MESSAGE_END();
00134 
00135             // get the matrix specification:
00136             std::stringstream index;
00137             index << state;
00138             std::string subviewName = "transitionMatrix" +
00139                 std::string("[") + index.str() + std::string("]");
00140             for(int col = 0; col < numberOfStates; ++col) {
00141                 double rate = mmppParamsConfig.get<double>(subviewName,col);
00142                 // rate *= transitionScale; // done here or in Markov* classes?
00143                 //MESSAGE_SINGLE(NORMAL, log,"r["<<state<<","<<col<<"]="<<rate);
00144                 setTransitionMatrixElement(state,col,rate);
00145             } // column
00146         } // forall rows (=states)
00147     } // else: taken from MMPPparams
00148     setTransitionDistributionSpec(transitionDistributionSpec); // can only be done after numberOfStates is known
00149     // now we have all parameters inside
00150     calculateStateProbabilities(); // also determines meanRate
00151     // use calculated meanRate to scale with rateScale to achieve targetRate
00152     if (!config.isNone("targetRate")) { // targetRate given
00153         assure(meanRate>0.0,"meanRate must be >0");
00154         rateScale = targetRate / meanRate;
00155         MESSAGE_SINGLE(NORMAL, log, "scaling for targetRate="<< targetRate << " => rateScale=" << rateScale);
00156         // recalculate mean, min, max:
00157         calculateStateProbabilities();
00158     } else {
00159         targetRate = meanRate; // from MarkovContinuousTimeTraffic
00160     }
00161 } // constructor
00162 
00163 
00164 GeneratorMMPP::~GeneratorMMPP()
00165 {
00166     MESSAGE_SINGLE(VERBOSE, log, "~GeneratorMMPP()");
00167     cancelAllTimeouts(); // remove state transition events (from MultipleTimeout.hpp)
00168 }
00169 
00170 // begin of the traffic generation
00171 void GeneratorMMPP::start()
00172 {
00173     MESSAGE_SINGLE(NORMAL, log, "GeneratorMMPP::start()");
00174     // now we know the binding:
00175     //SubGenerator aSubGenerator(binding,log,NULL,NULL,rateScale); // empty
00176     SubGenerator aSubGenerator(this,log,NULL,NULL,rateScale); // empty
00177     subGenerators = std::vector<SubGenerator>(numberOfChains,aSubGenerator); // empty constructor needed here
00178     for(int chain=0; chain<numberOfChains; chain++) {
00179         wns::logger::Logger logSub("CONSTANZE", loggerName + ".Subgen[" + stringify(chain) + "]");
00180         subGenerators[chain].reconfigLogger(logSub);
00181     }
00182     startEvents(); // prepares matrix and runs events
00183 }
00184 
00185 // end of the traffic generation
00186 void GeneratorMMPP::stop()
00187 {
00188     MESSAGE_SINGLE(NORMAL, log, "GeneratorMMPP::stop()");
00189     //cancelAllTimeouts(); // remove state transition events (from MultipleTimeout.hpp)
00190     // use a method in MarkovContinuousTime:
00191     stopMarkovProcess();
00192     for(int chain=0; chain<numberOfChains; chain++)
00193         subGenerators[chain].stop();
00194 }
00195 
00196 void GeneratorMMPP::stateChangeNotification(const int &chainNumber) {
00197     //int newState = actualStates[chainNumber];
00198     int newState = getActualStateIndex(chainNumber);
00199     MESSAGE_SINGLE(NORMAL, log, "GeneratorMMPP::stateChangeNotification(chain="<<chainNumber<<") to state "<<newState);
00200     //TrafficSpec newTrafficSpec = vectorOfStates[newState];
00201         const TrafficSpec *newTrafficSpec = getStateContent(newState);
00202     // reconfig automatically starts events:
00203     subGenerators[chainNumber].reconfig(
00204         newTrafficSpec->getInterArrivalTimeDistribution(),
00205         newTrafficSpec->getPacketSizeDistribution());
00206 }
00207 
00208 /* onTimeout() is handled by the parent class. A hook would be like that:
00209 void GeneratorMMPP::onTimeout(const int &chainNumber) {
00210    MarkovContinuousTimeTraffic::onTimeout(chainNumber); // parent class
00211 } // onTimeout()
00212 */
00213 
00214 

Generated on Thu May 24 03:32:15 2012 for openWNS by  doxygen 1.5.5