User Manual, Developers Guide and API Documentation

GeneratorARMA.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/GeneratorARMA.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/ldk/helper/FakePDU.hpp>
00036 #include <WNS/node/Node.hpp>
00037 
00038 #include <fstream>
00039 
00040 using namespace constanze;
00041 using namespace wns::markovchain;
00042 
00043 // objects of these classes are created by name:
00044 // the names are specified in Constanze.py as __plugin__
00045 STATIC_FACTORY_REGISTER_WITH_CREATOR(constanze::GeneratorARMA, constanze::GeneratorBase, "ARMA", wns::PyConfigViewCreator);
00046 
00047 /*************************** Generator *******************************/
00048 
00049 GeneratorARMA::GeneratorARMA( const wns::pyconfig::View& config) :
00050     GeneratorBase(config), // config goes into pyco (member)
00051     MarkovDiscreteTimeTraffic(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 MarkovDiscreteTimeTraffic class
00063     } else {
00064         targetRate=config.get<double>("targetRate");
00065     }
00066     assure(rateScale>0.0,"bad rateScale");
00067     slotTime=config.get<double>("slotTime");
00068     assure(slotTime>0.0,"bad slotTime");
00069     // we have two loggers, one from each base class
00070     //logger = log; // from MarkovBase::logger GeneratorBase::log
00071     //logger = wns::logger::Logger("CONST", loggerName + ".DTMC");
00072     logger = wns::logger::Logger(log.getModuleName(), loggerName + ".DTMC");
00073     logger.setLevel(log.getLevel()); // copy logging level
00074 
00075     // sub structure "mmppParams":
00076     wns::pyconfig::View mmppParamsConfig(config, "mmppParams");
00077     int startState = mmppParamsConfig.get<int>("startState"); // valid for all chains
00078     bool fromFile  = mmppParamsConfig.get<bool>("fromFile");
00079 
00080     MESSAGE_BEGIN(NORMAL, log, m, "New GeneratorDTMMPP: ");
00081     m << "C=" << numberOfChains << ", slotTime=" << slotTime << "s, rs=" << rateScale;
00082     MESSAGE_END();
00083 
00084     if (fromFile) { // read parameters from GDF file (format used in Opnet)
00085         // examples are in ./framework/libwns--main--3.0/PyConfig/wns/markov/*.gdf
00086         std::string filename = mmppParamsConfig.get<std::string>("filename");
00087         MESSAGE_BEGIN(NORMAL, log, m, "reading from ");
00088         m << "filename=" << filename;
00089         MESSAGE_END();
00090         //std::fstream in(filename.c_str(),std::ios::in); // opens automatically
00091         std::ifstream in(filename.c_str()); // opens automatically
00092         assure(in.good(),"error opening file "+filename);
00093         MarkovDiscreteTimeTraffic::readNumberOfStates(in);
00094         MarkovDiscreteTimeTraffic::readStatesFromFile(in);
00095         MarkovDiscreteTimeTraffic::readTransitionsFromFile(in);
00096         in.close();
00097         for(int chain=0; chain<numberOfChains; chain++)
00098             startStates[chain]=startState; // here: one value for all
00099     } else { // params from class DTMMPPparams
00100         int numberOfStates = mmppParamsConfig.get<int>("numberOfStates");
00101         assure(mmppParamsConfig.len("transitionMatrix") == numberOfStates, "transitionMatrix: wrong dimension");
00102         assure(mmppParamsConfig.len("stateList") == numberOfStates, "stateList: wrong dimension");
00103         setNumberOfStates(numberOfStates);
00104         if (!mmppParamsConfig.knows("startStates")
00105             || mmppParamsConfig.isNone("startStates")) { // no startStates[] specified
00106             for(int chain=0; chain<numberOfChains; chain++)
00107                 startStates[chain] = startState;
00108         } else { // startStates[] specified as an array
00109             assure(mmppParamsConfig.len("startStates") == numberOfChains, "startStates: wrong dimension");
00110             for(int chain=0; chain<numberOfChains; chain++) {
00111                 int aStartState = mmppParamsConfig.get<int>("startStates", chain);
00112                 startStates[chain] = aStartState;
00113             }
00114         } // else: startStates[] specified as an array
00115         for(int state=0; state < numberOfStates; state++) {
00116             // get the state specifications:
00117                         wns::pyconfig::View stateConfig = mmppParamsConfig.get("stateList", state);
00118             vectorOfStates[state] = TrafficSpec(stateConfig); // inherited member
00119 
00120             // the following lines in MESSAGE_BEGIN/MESSAGE_END are
00121             // only for showing the parameters of the state:
00122             MESSAGE_BEGIN(NORMAL, log, m, "State["<<state<<"]: ");
00123             m << "iat=" << *(vectorOfStates[state].getInterArrivalTimeDistribution())
00124               << ", packetSize=" << *(vectorOfStates[state].getPacketSizeDistribution())
00125               << ", mean=" << vectorOfStates[state].getMeanRate() * rateScale << " bits/s";
00126             MESSAGE_END();
00127 
00128             // get the matrix specification:
00129             std::stringstream index;
00130             index << state;
00131             std::string subviewName = "transitionMatrix" +
00132                 std::string("[") + index.str() + std::string("]");
00133                         for(int col = 0; col < numberOfStates; ++col) {
00134                 double rate = mmppParamsConfig.get<double>(subviewName,col);
00135                 // rate *= transitionScale; // done here or in Markov* classes?
00136                 //MESSAGE_SINGLE(NORMAL, log,"r["<<state<<","<<col<<"]="<<rate);
00137                 setTransitionMatrixElement(state,col,rate);
00138             } // column
00139                 } // forall rows (=states)
00140     } // else: taken from MMPPparams
00141     // now we have all parameters inside
00142     calculateStateProbabilities(); // also determines meanRate
00143     // use calculated meanRate to scale with rateScale to achieve targetRate
00144     if (!config.isNone("targetRate")) { // targetRate given
00145         assure(meanRate>0.0,"meanRate must be >0");
00146         rateScale = targetRate / meanRate;
00147         MESSAGE_SINGLE(NORMAL, log, "scaling for targetRate="<< targetRate << " => rateScale=" << rateScale);
00148         // recalculate mean, min, max:
00149         calculateStateProbabilities();
00150     } else {
00151         targetRate = meanRate; // from MarkovDiscreteTimeTraffic
00152     }
00153 } // constructor
00154 
00155 
00156 GeneratorARMA::~GeneratorARMA()
00157 {
00158     MESSAGE_SINGLE(VERBOSE, log, "~GeneratorDTMMPP()");
00159     if (hasTimeoutSet()) cancelTimeout();
00160     // remove state transition events (from CanTimeout.hpp)
00161 }
00162 
00163 // begin of the traffic generation
00164 void GeneratorARMA::start()
00165 {
00166     MESSAGE_SINGLE(NORMAL, log, "GeneratorDTMMPP::start()");
00167     // now we know the binding:
00168     SubGenerator aSubGenerator(this,log,NULL,NULL,rateScale); // empty
00169     subGenerators = std::vector<SubGenerator>(numberOfChains,aSubGenerator); // empty constructor needed here
00170     for(int chain=0; chain<numberOfChains; chain++) {
00171         wns::logger::Logger logSub(log.getModuleName(), loggerName + ".Subgen[" + stringify(chain) + "]");
00172         logSub.setLevel(log.getLevel()); // copy logging level
00173         subGenerators[chain].reconfigLogger(logSub);
00174     }
00175     startEvents(); // prepares matrix and runs events
00176 }
00177 
00178 void GeneratorARMA::stateChangeNotification(const int &chainNumber) {
00179     //int newState = actualStates[chainNumber];
00180     int newState = getActualStateIndex(chainNumber);
00181     MESSAGE_SINGLE(NORMAL, log, "GeneratorDTMMPP::stateChangeNotification("<<chainNumber<<") to state "<<newState);
00182     //TrafficSpec newTrafficSpec = vectorOfStates[newState];
00183         const TrafficSpec *newTrafficSpec = getStateContent(newState);
00184     // reconfig automatically starts events:
00185     subGenerators[chainNumber].reconfig(
00186         newTrafficSpec->getInterArrivalTimeDistribution(),
00187         newTrafficSpec->getPacketSizeDistribution());
00188 }
00189 
00190 /* onTimeout() is handled by the parent class. A hook would be like that:
00191 void GeneratorMMPP::onTimeout(const int &chainNumber) {
00192    MarkovDiscreteTimeTraffic::onTimeout(chainNumber); // parent class
00193 } // onTimeout()
00194 */
00195 
00196 // end of the traffic generation
00197 void GeneratorARMA::stop()
00198 {
00199     MESSAGE_SINGLE(NORMAL, log, "GeneratorDTMMPP::stop()");
00200     //cancelAllTimeouts(); // remove state transition events (from MultipleTimeout.hpp)
00201     // use a method in MarkovDiscreteTime:
00202     stopMarkovProcess();
00203     for(int chain=0; chain<numberOfChains; chain++)
00204         subGenerators[chain].stop();
00205 }
00206 
00207 
00208 

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