--- a/doc/manual/Makefile Fri Aug 09 04:35:13 2013 -0700
+++ b/doc/manual/Makefile Fri Aug 09 05:22:00 2013 -0700
@@ -39,6 +39,15 @@
source/tests.rst \
source/tracing.rst \
source/troubleshoot.rst \
+ ${SRC}/stats/doc/data-collection.rst \
+ ${SRC}/stats/doc/data-collection-overview.rst \
+ ${SRC}/stats/doc/statistics.rst \
+ ${SRC}/stats/doc/data-collection-helpers.rst \
+ ${SRC}/stats/doc/probe.rst \
+ ${SRC}/stats/doc/collector.rst \
+ ${SRC}/stats/doc/aggregator.rst \
+ ${SRC}/stats/doc/adaptor.rst \
+ ${SRC}/stats/doc/scope-and-limitations.rst \
# list all manual figure files that need to be copied to
# $SOURCETEMP/figures. For each figure to be included in all
@@ -52,11 +61,22 @@
figures/plot-2d.png \
figures/plot-2d-with-error-bars.png \
figures/plot-3d.png \
+ ${SRC}/stats/doc/Stat-framework-arch.png \
+ ${SRC}/stats/doc/Wifi-default.png \
+ ${SRC}/stats/doc/dcf-overview.dia \
+ ${SRC}/stats/doc/dcf-overview-with-aggregation.dia \
+ ${SRC}/stats/doc/gnuplot-example.png \
+ ${SRC}/stats/doc/file-example.png \
+ ${SRC}/stats/doc/seventh-packet-byte-count.png \
+ ${SRC}/stats/doc/gnuplot-helper-example.png \
+ ${SRC}/stats/doc/gnuplot-aggregator.png \
# specify figures from which .png and .pdf figures need to be
# generated (all dia and eps figures)
IMAGES_EPS = \
$(FIGURES)/software-organization.eps \
+ $(FIGURES)/dcf-overview.eps \
+ $(FIGURES)/dcf-overview-with-aggregation.eps \
# rescale pdf figures as necessary
$(FIGURES)/software-organization.pdf_width = 5in
--- a/doc/manual/source/index.rst Fri Aug 09 04:35:13 2013 -0700
+++ b/doc/manual/source/index.rst Fri Aug 09 05:22:00 2013 -0700
@@ -26,6 +26,8 @@
object-names
logging
tracing
+ data-collection
+ statistics
realtime
helpers
gnuplot
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/adaptor.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,48 @@
+.. include:: replace.txt
+
+.. heading hierarchy:
+ ************* Section (#.#)
+ ============= Subsection (#.#.#)
+ ############# Paragraph (no number)
+ ~~~~~~~~~~~~~ Sub-paragraph (no number)
+
+Adaptors
+********
+
+This section details the functionalities provided by the Adaptor
+class to an |ns3| simulation. This section is meant for users
+interested in developing simulations with the |ns3| tools and using
+the Data Collection Framework, of which the Adaptor class is a
+part, to generate data output with their simulation's results.
+
+Note: the term 'adaptor' may also be spelled 'adapter'; we chose
+the spelling aligned with the C++ standard.
+
+Adaptor Overview
+================
+
+An Adaptor is used to make connections between different types of DCF
+objects.
+
+To date, one Adaptor has been implemented:
+
+- TimeSeriesAdaptor
+
+Time Series Adaptor
+===================
+
+The TimeSeriesAdaptor lets Probes connect directly to Aggregators
+without needing any Collector in between.
+
+Both of the implemented DCF helpers utilize TimeSeriesAdaptors
+in order to take probed values of different types and output the
+current time plus the value with both converted to doubles.
+
+The role of the TimeSeriesAdaptor class is that of an adaptor, which
+takes raw-valued probe data of different types and outputs a tuple of
+two double values. The first is a timestamp, which may be set to
+different resolutions (e.g. Seconds, Milliseconds, etc.) in the future
+but which is presently hardcoded to Seconds.
+The second is the conversion of a non-double
+value to a double value (possibly with loss of precision).
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/aggregator.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,398 @@
+.. include:: replace.txt
+
+.. heading hierarchy:
+ ************* Section (#.#)
+ ============= Subsection (#.#.#)
+ ############# Paragraph (no number)
+ ~~~~~~~~~~~~~ Sub-paragraph (no number)
+
+Aggregators
+***********
+
+This section details the functionalities provided by the Aggregator
+class to an |ns3| simulation. This section is meant for users
+interested in developing simulations with the |ns3| tools and using
+the Data Collection Framework, of which the Aggregator class is a
+part, to generate data output with their simulation's results.
+
+Aggregator Overview
+===================
+
+An Aggregator object is supposed to be hooked to one or more trace
+sources in order to receive input. Aggregators are the end point of
+the data collected by the network of Probes and Collectors during the
+simulation. It is the Aggregator's job to take these values and
+transform them into their final output format such as plain text
+files, spreadsheet files, plots, or databases.
+
+Typically, an aggregator is connected to one or more Collectors. In
+this manner, whenever the Collectors' trace sources export new values,
+the Aggregator can process the value so that it can be used in the
+final output format where the data values will reside after the
+simulation.
+
+Note the following about Aggregators:
+
+* Aggregators may be dynamically turned on and off during the
+ simulation with calls to ``Enable()`` and ``Disable()``. For
+ example, the aggregating of data may be turned off during the
+ simulation warmup phase, which means those values won't be included
+ in the final output medium.
+* Aggregators receive data from Collectors via callbacks. When a
+ Collector is associated to an aggregator, a call to TraceConnect is
+ made to establish the Aggregator's trace sink method as a callback.
+
+To date, two Aggregators have been implemented:
+
+- GnuplotAggregator
+- FileAggregator
+
+GnuplotAggregator
+=================
+
+The GnuplotAggregator produces output files used to make gnuplots.
+
+The GnuplotAggregator will create 3 different files at the end of the
+simulation:
+
+- A space separated gnuplot data file
+- A gnuplot control file
+- A shell script to generate the gnuplot
+
+Creation
+########
+
+An object of type GnuplotAggregator will be created here to show what needs
+to be done.
+
+One declares a GnuplotAggregator in dynamic memory by using the smart
+pointer class (Ptr<T>). To create a GnuplotAggregator in dynamic
+memory with smart pointers, one just needs to call the |ns3| method
+``CreateObject()``. The following code from
+``src/stats/examples/gnuplot-aggregator-example.cc`` shows
+how to do this:
+
+::
+
+ string fileNameWithoutExtension = "gnuplot-aggregator";
+
+ // Create an aggregator.
+ Ptr<GnuplotAggregator> aggregator =
+ CreateObject<GnuplotAggregator> (fileNameWithoutExtension);
+
+The first argument for the constructor, fileNameWithoutExtension, is
+the name of the gnuplot related files to write with no extension.
+This GnuplotAggregator will create a space separated gnuplot data file
+named "gnuplot-aggregator.dat", a gnuplot control file named
+"gnuplot-aggregator.plt", and a shell script to generate the gnuplot
+named + "gnuplot-aggregator.sh".
+
+The gnuplot that is created can have its key in 4 different locations:
+
+- No key
+- Key inside the plot (the default)
+- Key above the plot
+- Key below the plot
+
+The following gnuplot key location enum values are allowed to specify the key's position:
+
+::
+
+ enum KeyLocation {
+ NO_KEY,
+ KEY_INSIDE,
+ KEY_ABOVE,
+ KEY_BELOW
+ };
+
+If it was desired to have the key below rather than the default position of inside, then you could do the following.
+
+::
+
+ aggregator->SetKeyLocation(GnuplotAggregator::KEY_BELOW);
+
+Examples
+########
+
+One example will be discussed in detail here:
+
+- Gnuplot Aggregator Example
+
+Gnuplot Aggregator Example
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An example that exercises the GnuplotAggregator can be found in
+``src/stats/examples/gnuplot-aggregator-example.cc``.
+
+The following 2-D gnuplot was created using the example.
+
+.. _gnuplot-aggregator:
+
+.. figure:: figures/gnuplot-aggregator.png
+
+ 2-D Gnuplot Created by gnuplot-aggregator-example.cc Example.
+
+This code from the example shows how to construct the
+GnuplotAggregator as was discussed above.
+
+::
+
+ void Create2dPlot ()
+ {
+ using namespace std;
+
+ string fileNameWithoutExtension = "gnuplot-aggregator";
+ string plotTitle = "Gnuplot Aggregator Plot";
+ string plotXAxisHeading = "Time (seconds)";
+ string plotYAxisHeading = "Double Values";
+ string plotDatasetLabel = "Data Values";
+ string datasetContext = "Dataset/Context/String";
+
+ // Create an aggregator.
+ Ptr<GnuplotAggregator> aggregator =
+ CreateObject<GnuplotAggregator> (fileNameWithoutExtension);
+
+Various GnuplotAggregator attributes are set including the 2-D dataset
+that will be plotted.
+
+::
+
+ // Set the aggregator's properties.
+ aggregator->SetTerminal ("png");
+ aggregator->SetTitle (plotTitle);
+ aggregator->SetLegend (plotXAxisHeading, plotYAxisHeading);
+
+ // Add a data set to the aggregator.
+ aggregator->Add2dDataset (datasetContext, plotDatasetLabel);
+
+ // aggregator must be turned on
+ aggregator->Enable ();
+
+Next, the 2-D values are calculated, and each one is individually
+written to the GnuplotAggregator using the ``Write2d()`` function.
+
+::
+
+ double time;
+ double value;
+
+ // Create the 2-D dataset.
+ for (time = -5.0; time <= +5.0; time += 1.0)
+ {
+ // Calculate the 2-D curve
+ //
+ // 2
+ // value = time .
+ //
+ value = time * time;
+
+ // Add this point to the plot.
+ aggregator->Write2d (datasetContext, time, value);
+ }
+
+ // Disable logging of data for the aggregator.
+ aggregator->Disable ();
+ }
+
+FileAggregator
+==============
+
+The FileAggregator sends the values it receives to a file.
+
+The FileAggregator can create 4 different types of files:
+
+- Formatted
+- Space separated (the default)
+- Comma separated
+- Tab separated
+
+Formatted files use C-style format strings and the sprintf() function
+to print their values in the file being written.
+
+Creation
+########
+
+An object of type FileAggregator will be created here to show what needs
+to be done.
+
+One declares a FileAggregator in dynamic memory by using the smart
+pointer class (Ptr<T>). To create a FileAggregator in dynamic memory
+with smart pointers, one just needs to call the |ns3| method
+CreateObject. The following code from
+``src/stats/examples/file-aggregator-example.cc`` shows how
+to do this:
+
+::
+
+ string fileName = "file-aggregator-formatted-values.txt";
+
+ // Create an aggregator that will have formatted values.
+ Ptr<FileAggregator> aggregator =
+ CreateObject<FileAggregator> (fileName, FileAggregator::FORMATTED);
+
+The first argument for the constructor, filename, is the name of the
+file to write; the second argument, fileType, is type of file to
+write. This FileAggregator will create a file named
+"file-aggregator-formatted-values.txt" with its values printed as
+specified by fileType, i.e., formatted in this case.
+
+The following file type enum values are allowed:
+
+::
+
+ enum FileType {
+ FORMATTED,
+ SPACE_SEPARATED,
+ COMMA_SEPARATED,
+ TAB_SEPARATED
+ };
+
+Examples
+########
+
+One example will be discussed in detail here:
+
+- File Aggregator Example
+
+File Aggregator Example
+~~~~~~~~~~~~~~~~~~~~~~~
+
+An example that exercises the FileAggregator can be found in
+``src/stats/examples/file-aggregator-example.cc``.
+
+The following text file with 2 columns of values separated by commas
+was created using the example.
+
+::
+
+ -5,25
+ -4,16
+ -3,9
+ -2,4
+ -1,1
+ 0,0
+ 1,1
+ 2,4
+ 3,9
+ 4,16
+ 5,25
+
+This code from the example shows how to construct the
+FileAggregator as was discussed above.
+
+::
+
+ void CreateCommaSeparatedFile ()
+ {
+ using namespace std;
+
+ string fileName = "file-aggregator-comma-separated.txt";
+ string datasetContext = "Dataset/Context/String";
+
+ // Create an aggregator.
+ Ptr<FileAggregator> aggregator =
+ CreateObject<FileAggregator> (fileName, FileAggregator::COMMA_SEPARATED);
+
+FileAggregator attributes are set.
+
+::
+
+ // aggregator must be turned on
+ aggregator->Enable ();
+
+Next, the 2-D values are calculated, and each one is individually
+written to the FileAggregator using the ``Write2d()`` function.
+
+::
+
+ double time;
+ double value;
+
+ // Create the 2-D dataset.
+ for (time = -5.0; time <= +5.0; time += 1.0)
+ {
+ // Calculate the 2-D curve
+ //
+ // 2
+ // value = time .
+ //
+ value = time * time;
+
+ // Add this point to the plot.
+ aggregator->Write2d (datasetContext, time, value);
+ }
+
+ // Disable logging of data for the aggregator.
+ aggregator->Disable ();
+ }
+
+The following text file with 2 columns of formatted values was also
+created using the example.
+
+::
+
+ Time = -5.000e+00 Value = 25
+ Time = -4.000e+00 Value = 16
+ Time = -3.000e+00 Value = 9
+ Time = -2.000e+00 Value = 4
+ Time = -1.000e+00 Value = 1
+ Time = 0.000e+00 Value = 0
+ Time = 1.000e+00 Value = 1
+ Time = 2.000e+00 Value = 4
+ Time = 3.000e+00 Value = 9
+ Time = 4.000e+00 Value = 16
+ Time = 5.000e+00 Value = 25
+
+This code from the example shows how to construct the
+FileAggregator as was discussed above.
+
+::
+
+ void CreateFormattedFile ()
+ {
+ using namespace std;
+
+ string fileName = "file-aggregator-formatted-values.txt";
+ string datasetContext = "Dataset/Context/String";
+
+ // Create an aggregator that will have formatted values.
+ Ptr<FileAggregator> aggregator =
+ CreateObject<FileAggregator> (fileName, FileAggregator::FORMATTED);
+
+FileAggregator attributes are set, including the C-style format string
+to use.
+
+::
+
+ // Set the format for the values.
+ aggregator->Set2dFormat ("Time = %.3e\tValue = %.0f");
+
+ // aggregator must be turned on
+ aggregator->Enable ();
+
+Next, the 2-D values are calculated, and each one is individually
+written to the FileAggregator using the ``Write2d()`` function.
+
+::
+
+ double time;
+ double value;
+
+ // Create the 2-D dataset.
+ for (time = -5.0; time <= +5.0; time += 1.0)
+ {
+ // Calculate the 2-D curve
+ //
+ // 2
+ // value = time .
+ //
+ value = time * time;
+
+ // Add this point to the plot.
+ aggregator->Write2d (datasetContext, time, value);
+ }
+
+ // Disable logging of data for the aggregator.
+ aggregator->Disable ();
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/collector.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,18 @@
+.. include:: replace.txt
+
+.. heading hierarchy:
+ ************* Section (#.#)
+ ============= Subsection (#.#.#)
+ ############# Paragraph (no number)
+ ~~~~~~~~~~~~~ Sub-paragraph (no number)
+
+Collectors
+**********
+
+This section is a placeholder to detail the functionalities provided by
+the Collector
+class to an |ns3| simulation, and gives examples on how to code them
+in a program.
+
+**Note:** As of ns-3.18, Collectors are still under development and
+not yet provided as part of the framework.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/data-collection-helpers.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,630 @@
+.. include:: replace.txt
+
+.. heading hierarchy:
+ ************* Section (#.#)
+ ============= Subsection (#.#.#)
+ ############# Paragraph (no number)
+ ~~~~~~~~~~~~~ Sub-paragraph (no number)
+
+Data Collection Helpers
+***********************
+
+The full flexibility of the data collection framework is provided by
+the interconnection of probes, collectors, and aggregators. Performing
+all of these interconnections leads to many configuration statements
+in user programs. For ease of use, some of the most common operations
+can be combined and encapsulated in helper functions. In addition,
+some statements involving |ns3| trace sources do not have Python
+bindings, due to limitations in the bindings.
+
+Data Collection Helpers Overview
+================================
+
+In this section, we provide an overview of some helper classes that
+have been created to ease the configuration of the data collection
+framework for some common use cases. The helpers allow users to form
+common operations with only a few statements in their C++ or Python
+programs. But, this ease of use comes at the cost of significantly
+less flexibility than low-level configuration can provide, and the
+need to explicitly code support for new Probe types into the helpers
+(to work around an issue described below).
+
+The emphasis on the current helpers is to marshal data out of |ns3|
+trace sources into gnuplot plots or text files, without a high degree
+of output customization or statistical processing (initially). Also,
+the use is constrained to the available probe types in |ns3|. Later
+sections of this documentation will go into more detail about creating
+new Probe types, as well as details about hooking together Probes,
+Collectors, and Aggregators in custom arrangements.
+
+To date, two Data Collection helpers have been implemented:
+
+- GnuplotHelper
+- FileHelper
+
+GnuplotHelper
+=============
+
+The GnuplotHelper is a helper class for producing output files used to
+make gnuplots. The overall goal is to provide the ability for users
+to quickly make plots from data exported in |ns3| trace sources. By
+default, a minimal amount of data transformation is performed; the
+objective is to generate plots with as few (default) configuration
+statements as possible.
+
+GnuplotHelper Overview
+######################
+
+The GnuplotHelper will create 3 different files at the end of the
+simulation:
+
+- A space separated gnuplot data file
+- A gnuplot control file
+- A shell script to generate the gnuplot
+
+There are two configuration statements that are needed to produce plots.
+The first statement configures the plot (filename, title, legends, and
+output type, where the output type defaults to PNG if unspecified):
+
+::
+
+ void ConfigurePlot (const std::string &outputFileNameWithoutExtension,
+ const std::string &title,
+ const std::string &xLegend,
+ const std::string &yLegend,
+ const std::string &terminalType = ".png");
+
+The second statement hooks the ``Probe`` of interest:
+
+::
+
+ void PlotProbe (const std::string &typeId,
+ const std::string &path,
+ const std::string &probeTraceSource,
+ const std::string &title);
+
+The arguments are as follows:
+
+* typeId: The |ns3| TypeId of the Probe
+* path: The path in the |ns3| configuration namespace to one or more probes
+* probeTraceSource: Which output of the probe should be connected to
+* title: The title to associate with the dataset (in the gnuplot legend)
+
+A variant on the PlotProbe above is to specify a fifth optional argument
+that controls where in the plot the key (legend) is placed.
+
+A fully worked example (from ``seventh.cc``) is shown below:
+
+::
+
+ // Create the gnuplot helper.
+ GnuplotHelper plotHelper;
+
+ // Configure the plot.
+ plotHelper.ConfigurePlot ("seventh-packet-byte-count",
+ "Packet Byte Count vs. Time",
+ "Time (Seconds)",
+ "Packet Byte Count",
+ "png");
+
+ // Plot the values generated by the probe.
+ plotHelper.PlotProbe ("ns3::Ipv4PacketProbe",
+ "/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
+ "OutputBytes",
+ "Packet Byte Count",
+ GnuplotAggregator::KEY_BELOW);
+
+Note that the path specified may contain wildcards. In this case, multiple
+datasets are plotted on one plot; one for each matched path.
+
+The main output produced will be three files:
+
+::
+
+ seventh-packet-byte-count.dat
+ seventh-packet-byte-count.plt
+ seventh-packet-byte-count.sh
+
+At this point, users can either hand edit the .plt file for further
+customizations, or just run it through gnuplot. Running
+`sh seventh-packet-byte-count.sh` simply runs the plot through gnuplot,
+as shown below.
+
+.. _seventh-packet-byte-count:
+
+.. figure:: figures/seventh-packet-byte-count.png
+
+ 2-D Gnuplot Created by seventh.cc Example.
+
+It can be seen that the key elements (legend, title, legend placement,
+xlabel, ylabel, and path for the data) are all placed on the plot.
+Since there were two matches to the configuration path provided, the
+two data series are shown:
+
+* Packet Byte Count-0 corresponds to /NodeList/0/$ns3::Ipv4L3Protocol/Tx
+* Packet Byte Count-1 corresponds to /NodeList/1/$ns3::Ipv4L3Protocol/Tx
+
+GnuplotHelper ConfigurePlot
+###########################
+
+The GnuplotHelper's ``ConfigurePlot()`` function can be used
+to configure plots.
+
+It has the following prototype:
+
+::
+
+ void ConfigurePlot (const std::string &outputFileNameWithoutExtension,
+ const std::string &title,
+ const std::string &xLegend,
+ const std::string &yLegend,
+ const std::string &terminalType = ".png");
+
+It has the following arguments:
+
++--------------------------------+------------------------------+
+| Argument | Description |
++================================+==============================+
+| outputFileNameWithoutExtension | Name of gnuplot related files|
+| | to write with no extension. |
++--------------------------------+------------------------------+
+| title | Plot title string to use for |
+| | this plot. |
++--------------------------------+------------------------------+
+| xLegend | The legend for the x |
+| | horizontal axis. |
++--------------------------------+------------------------------+
+| yLegend | The legend for the y |
+| | vertical axis. |
++--------------------------------+------------------------------+
+| terminalType | Terminal type setting string |
+| | for output. The default |
+| | terminal type is "png". |
++--------------------------------+------------------------------+
+
+The GnuplotHelper's ``ConfigurePlot()`` function configures plot
+related parameters for this gnuplot helper so
+that it will create a space separated gnuplot data file named
+outputFileNameWithoutExtension + ".dat", a gnuplot control file
+named outputFileNameWithoutExtension + ".plt", and a shell script
+to generate the gnuplot named outputFileNameWithoutExtension +
+".sh".
+
+An example of how to use this function can be seen in the
+``seventh.cc`` code described above where it was used as follows:
+
+::
+
+ plotHelper.ConfigurePlot ("seventh-packet-byte-count",
+ "Packet Byte Count vs. Time",
+ "Time (Seconds)",
+ "Packet Byte Count",
+ "png");
+
+GnuplotHelper PlotProbe
+#######################
+
+The GnuplotHelper's ``PlotProbe()`` function can be used
+to plot values generated by probes.
+
+It has the following prototype:
+
+::
+
+ void PlotProbe (const std::string &typeId,
+ const std::string &path,
+ const std::string &probeTraceSource,
+ const std::string &title,
+ enum GnuplotAggregator::KeyLocation keyLocation = GnuplotAggregator::KEY_INSIDE);
+
+It has the following arguments:
+
++------------------+------------------------------+
+| Argument | Description |
++==================+==============================+
+| typeId | The type ID for the probe |
+| | used when it is created. |
++------------------+------------------------------+
+| path | Config path to access the |
+| | probe. |
++------------------+------------------------------+
+| probeTraceSource | The probe trace source to |
+| | access. |
++------------------+------------------------------+
+| title | The title to be associated |
+| | to this dataset |
++------------------+------------------------------+
+| keyLocation | The location of the key in |
+| | the plot. The default |
+| | location is inside. |
++------------------+------------------------------+
+
+The GnuplotHelper's ``PlotProbe()`` function
+plots a dataset generated by hooking the |ns3| trace source with a
+probe, and then plotting the values from the probeTraceSource.
+The dataset will have the provided title, and will consist of
+the 'newValue' at each timestamp.
+
+If the config path has more than one match in the system because
+there is a wildcard, then one dataset for each match will
+be plotted. The dataset titles will be suffixed with the matched
+characters for each of the wildcards in the config path,
+separated by spaces. For example, if the proposed dataset title
+is the string "bytes", and there are two wildcards in the path,
+then dataset titles like "bytes-0 0" or "bytes-12 9" will be
+possible as labels for the datasets that are plotted.
+
+An example of how to use this function can be seen in the
+``seventh.cc`` code described above where it was used as follows:
+
+::
+
+ plotHelper.PlotProbe ("ns3::Ipv4PacketProbe",
+ "/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
+ "OutputBytes",
+ "Packet Byte Count",
+ GnuplotAggregator::KEY_BELOW);
+
+Other Examples
+##############
+
+Gnuplot Helper Example
+~~~~~~~~~~~~~~~~~~~~~~
+
+A slightly simpler example than the ``seventh.cc`` example can be
+found in ``src/stats/examples/gnuplot-helper-example.cc``. It
+is more of a toy example than ``seventh.cc`` because it has
+a made-up trace source created for demonstration purposes.
+
+The following 2-D gnuplot was created using the example.
+
+.. _gnuplot-helper-example:
+
+.. figure:: figures/gnuplot-helper-example.png
+
+ 2-D Gnuplot Created by gnuplot-helper-example.cc Example.
+
+In this example, there is an Emitter object that increments
+its counter at various random times and then emits the counter's
+value as a trace source.
+
+::
+
+ Ptr<Emitter> emitter = CreateObject<Emitter> ();
+ Names::Add ("/Names/Emitter", emitter);
+
+The following code is probing the Counter exported by the
+emitter object. This DoubleProbe is using a path in the
+configuration namespace to make the connection. Note that
+the emitter registered itself in the configuration namespace
+after it was created; otherwise, the ConnectByPath would not work.
+
+::
+
+ Ptr<DoubleProbe> probe = CreateObject<DoubleProbe> ();
+ probe->SetName ("PathProbe");
+ Names::Add ("/Names/Probe", probe);
+
+ // Note, no return value is checked here.
+ probe->ConnectByPath ("/Names/Emitter/Counter");
+
+Note that because there are no wildcards in the path
+used below, only 1 datastream was drawn in the plot.
+This single datastream in the plot is simply labeled
+"Emitter Count", with no extra suffixes like you would
+see if there were wildcards in the path.
+
+::
+
+ // Create the gnuplot helper.
+ GnuplotHelper plotHelper;
+
+ // Configure the plot.
+ plotHelper.ConfigurePlot ("gnuplot-helper-example",
+ "Emitter Counts vs. Time",
+ "Time (Seconds)",
+ "Emitter Count",
+ "png");
+
+ // Plot the values generated by the probe. The path that we provide
+ // helps to disambiguate the source of the trace.
+ plotHelper.PlotProbe ("ns3::DoubleProbe",
+ "/Names/Probe/Output",
+ "Output",
+ "Emitter Count",
+ GnuplotAggregator::KEY_INSIDE);
+
+FileHelper
+==========
+
+The FileHelper is a helper class used to put data values into a file.
+The overall goal is to provide the ability for users
+to quickly make formatted text files from data exported in |ns3|
+trace sources. By default, a minimal amount of data transformation is
+performed; the objective is to generate files with as few (default)
+configuration statements as possible.
+
+FileHelper Overview
+###################
+
+The FileHelper will create 1 or more text files at the end of the
+simulation.
+
+The FileHelper can create 4 different types of text files:
+
+- Formatted
+- Space separated (the default)
+- Comma separated
+- Tab separated
+
+Formatted files use C-style format strings and the sprintf() function
+to print their values in the file being written.
+
+The following text file with 2 columns of formatted values named
+``seventh-packet-byte-count-0.txt`` was created using more new
+code that was added to the original |ns3| Tutorial example's code.
+Only the first 10 lines of this file are shown here for brevity.
+
+::
+
+ Time (Seconds) = 1.000e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.004e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.004e+00 Packet Byte Count = 576
+ Time (Seconds) = 1.009e+00 Packet Byte Count = 576
+ Time (Seconds) = 1.009e+00 Packet Byte Count = 576
+ Time (Seconds) = 1.015e+00 Packet Byte Count = 512
+ Time (Seconds) = 1.017e+00 Packet Byte Count = 576
+ Time (Seconds) = 1.017e+00 Packet Byte Count = 544
+ Time (Seconds) = 1.025e+00 Packet Byte Count = 576
+ Time (Seconds) = 1.025e+00 Packet Byte Count = 544
+
+ ...
+
+The following different text file with 2 columns of formatted
+values named ``seventh-packet-byte-count-1.txt`` was also
+created using the same new code that was added to the original
+|ns3| Tutorial example's code. Only the first 10 lines of this
+file are shown here for brevity.
+
+::
+
+ Time (Seconds) = 1.002e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.007e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.013e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.020e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.028e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.036e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.045e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.053e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.061e+00 Packet Byte Count = 40
+ Time (Seconds) = 1.069e+00 Packet Byte Count = 40
+
+ ...
+
+The new code that was added to produce the two text files is below.
+More details about this API will be covered in a later section.
+
+Note that because there were 2 matches for the wildcard in the path,
+2 separate text files were created. The first text file, which is
+named "seventh-packet-byte-count-0.txt", corresponds to the
+wildcard match with the "*" replaced with "0". The second text file,
+which is named "seventh-packet-byte-count-1.txt", corresponds to
+the wildcard match with the "*" replaced with "1". Also, note that
+the function call to ``WriteProbe()`` will give an error message if
+there are no matches for a path that contains wildcards.
+
+::
+
+ // Create the file helper.
+ FileHelper fileHelper;
+
+ // Configure the file to be written.
+ fileHelper.ConfigureFile ("seventh-packet-byte-count",
+ FileAggregator::FORMATTED);
+
+ // Set the labels for this formatted output file.
+ fileHelper.Set2dFormat ("Time (Seconds) = %.3e\tPacket Byte Count = %.0f");
+
+ // Write the values generated by the probe.
+ fileHelper.WriteProbe ("ns3::Ipv4PacketProbe",
+ "/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
+ "OutputBytes");
+
+FileHelper ConfigureFile
+########################
+
+The FileHelper's ``ConfigureFile()`` function can be used
+to configure text files.
+
+It has the following prototype:
+
+::
+
+ void ConfigureFile (const std::string &outputFileNameWithoutExtension,
+ enum FileAggregator::FileType fileType = FileAggregator::SPACE_SEPARATED);
+
+It has the following arguments:
+
++--------------------------------+------------------------------+
+| Argument | Description |
++================================+==============================+
+| outputFileNameWithoutExtension | Name of output file to write |
+| | with no extension. |
++--------------------------------+------------------------------+
+| fileType | Type of file to write. The |
+| | default type of file is space|
+| | separated. |
++--------------------------------+------------------------------+
+
+The FileHelper's ``ConfigureFile()`` function configures text file
+related parameters for the file helper so that
+it will create a file named outputFileNameWithoutExtension plus
+possible extra information from wildcard matches plus ".txt" with
+values printed as specified by fileType. The default file type
+is space-separated.
+
+An example of how to use this function can be seen in the
+``seventh.cc`` code described above where it was used as follows:
+
+::
+
+ fileHelper.ConfigureFile ("seventh-packet-byte-count",
+ FileAggregator::FORMATTED);
+
+FileHelper WriteProbe
+#####################
+
+The FileHelper's ``WriteProbe()`` function can be used
+to write values generated by probes to text files.
+
+It has the following prototype:
+
+::
+
+ void WriteProbe (const std::string &typeId,
+ const std::string &path,
+ const std::string &probeTraceSource);
+
+It has the following arguments:
+
++------------------+------------------------------+
+| Argument | Description |
++==================+==============================+
+| typeId | The type ID for the probe |
+| | used when it is created. |
++------------------+------------------------------+
+| path | Config path to access the |
+| | probe. |
++------------------+------------------------------+
+| probeTraceSource | The probe trace source to |
+| | access. |
++------------------+------------------------------+
+
+The FileHelper's ``WriteProbe()`` function
+creates output text files generated by hooking the ns-3 trace source
+with a probe, and then writing the values from the
+probeTraceSource. The output file names will have the text stored
+in the member variable m_outputFileNameWithoutExtension plus ".txt",
+and will consist of the 'newValue' at each timestamp.
+
+If the config path has more than one match in the system because
+there is a wildcard, then one output file for each match
+will be created. The output file names will contain the text in
+m_outputFileNameWithoutExtension plus the matched characters for
+each of the wildcards in the config path, separated by dashes,
+plus ".txt". For example, if the value in
+m_outputFileNameWithoutExtension is the string
+"packet-byte-count", and there are two wildcards in the path,
+then output file names like "packet-byte-count-0-0.txt" or
+"packet-byte-count-12-9.txt" will be possible as names for the
+files that will be created.
+
+An example of how to use this function can be seen in the
+``seventh.cc`` code described above where it was used as follows:
+
+::
+
+ fileHelper.WriteProbe ("ns3::Ipv4PacketProbe",
+ "/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
+ "OutputBytes");
+
+Other Examples
+##############
+
+File Helper Example
+~~~~~~~~~~~~~~~~~~~
+
+A slightly simpler example than the ``seventh.cc`` example can be
+found in ``src/stats/examples/file-helper-example.cc``.
+This example only uses the FileHelper, not the FileHelper. It
+is also more of a toy example than ``seventh.cc`` because it has
+a made-up trace source created for demonstration purposes.
+
+The following text file with 2 columns of formatted values named
+``file-helper-example.txt`` was created using the example.
+Only the first 10 lines of this file are shown here for brevity.
+
+::
+
+ Time (Seconds) = 4.995e-01 Count = 1
+ Time (Seconds) = 1.463e+00 Count = 2
+ Time (Seconds) = 1.678e+00 Count = 3
+ Time (Seconds) = 3.972e+00 Count = 4
+ Time (Seconds) = 4.150e+00 Count = 5
+ Time (Seconds) = 8.066e+00 Count = 6
+ Time (Seconds) = 8.731e+00 Count = 7
+ Time (Seconds) = 9.807e+00 Count = 8
+ Time (Seconds) = 1.078e+01 Count = 9
+ Time (Seconds) = 1.083e+01 Count = 10
+
+ ...
+
+In this example, there is an Emitter object that increments
+its counter at various random times and then emits the counter's
+value as a trace source.
+
+::
+
+ Ptr<Emitter> emitter = CreateObject<Emitter> ();
+ Names::Add ("/Names/Emitter", emitter);
+
+The following code is probing the Counter exported by the
+emitter object. This DoubleProbe is using a path in the
+configuration namespace to make the connection. Note that
+the emitter registered itself in the configuration namespace
+after it was created; otherwise, the ConnectByPath would not work.
+
+::
+
+ Ptr<DoubleProbe> probe = CreateObject<DoubleProbe> ();
+ probe->SetName ("PathProbe");
+ Names::Add ("/Names/Probe", probe);
+
+ // Note, no return value is checked here.
+ probe->ConnectByPath ("/Names/Emitter/Counter");
+
+Note that because there are no wildcards in the path
+used below, only 1 text file was created.
+This single text file is simply named
+"file-helper-example.txt", with no extra suffixes like
+you would see if there were wildcards in the path.
+
+::
+
+ // Create the file helper.
+ FileHelper fileHelper;
+
+ // Configure the file to be written.
+ fileHelper.ConfigureFile ("file-helper-example",
+ FileAggregator::FORMATTED);
+
+ // Set the labels for this formatted output file.
+ fileHelper.Set2dFormat ("Time (Seconds) = %.3e\tCount = %.0f");
+
+ // Write the values generated by the probe. The path that we
+ // provide helps to disambiguate the source of the trace.
+ fileHelper.WriteProbe ("ns3::DoubleProbe",
+ "/Names/Probe/Output",
+ "Output");
+
+Scope and Limitations
+=====================
+
+Currently, only these Probes have been implemented and connected
+to the GnuplotHelper and to the FileHelper:
+
+- BooleanProbe
+- DoubleProbe
+- Uinteger8Probe
+- Uinteger16Probe
+- Uinteger32Probe
+- PacketProbe
+- ApplicationPacketProbe
+- Ipv4PacketProbe
+
+These Probes, therefore, are the only ones available to be used
+in ``PlotProbe()`` and ``WriteProbe()``.
+
+In the next few sections, we cover each of the fundamental object
+types (Probe, Collector, and Aggregator) in more detail, and show
+how they can be connected together using lower-level API.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/data-collection-overview.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,65 @@
+.. include:: replace.txt
+
+Design
+******
+
+The DCF consists of three basic classes:
+
+* *Probe* is a mechanism to instrument and control the output of
+ simulation data that is used to monitor interesting events. It
+ produces output in the form of one or more |ns3| trace sources.
+ Probe objects are hooked up to one or more trace *sinks* (called
+ *Collectors*), which process samples on-line and prepare them for
+ output.
+
+* *Collector* consumes the data generated by one or more Probe objects.
+ It performs transformations on the data, such as normalization, reduction, and
+ the computation of basic statistics. Collector objects do not produce
+ data that is directly output by the ns-3 run; instead, they output data
+ downstream to another type of object, called *Aggregator*, which performs
+ that function. Typically, Collectors output their data in the form of
+ trace sources as well, allowing collectors to be chained in series.
+
+* *Aggregator* is the end point of the data collected by a network of Probes and Collectors.
+ The main responsibility of the Aggregator is to marshal data and their
+ corresponding metadata, into different output
+ formats such as plain text files, spreadsheet files, or databases.
+
+All three of these classes provide the capability to dynamically turn themselves on or off throughout a simulation.
+
+Any standalone |ns3| simulation run that uses the DCF will typically create
+at least one instance of each of the three classes above.
+
+.. _dcf-overview:
+
+.. figure:: figures/dcf-overview.*
+
+ Data Collection Framework overview
+
+The overall flow of data processing is depicted in :ref:`dcf-overview`. On
+the left side, a running |ns3| simulation is depicted. In the course
+of running the simulation, data is made available by models through
+trace sources, or via other means. The diagram depicts that probes
+can be connected to these trace sources to receive data asynchronously,
+or probes can poll for data. Data is then passed to a collector object
+that transforms the data. Finally, an aggregator can be connected
+to the outputs of the collector, to generate plots, files, or databases.
+
+.. _dcf-overview-with-aggregation:
+
+.. figure:: figures/dcf-overview-with-aggregation.*
+
+ Data Collection Framework aggregation
+
+A variation on the above figure is provided
+in :ref:`dcf-overview-with-aggregation`.
+This second figure illustrates that the DCF objects may be chained
+together in a manner that downstream objects take inputs from multiple
+upstream objects. The figure conceptually shows that multiple probes
+may generate output that is fed into a single collector; as an example,
+a collector that outputs a ratio of two counters would typically acquire
+each counter data from separate probes. Multiple collectors can also
+feed into a single aggregator, which (as its name implies) may collect
+a number of data streams for inclusion into a single plot, file, or
+database.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/data-collection.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,36 @@
+.. include:: replace.txt
+
+Data Collection
+---------------
+
+This chapter describes the ns-3 Data Collection Framework (DCF), which
+provides capabilities to obtain data generated by models in the simulator,
+to perform on-line reduction and data processing, and to marshal raw
+or transformed data into various output formats.
+
+The framework presently supports standalone ns-3 runs that don't rely on
+any external program execution control. The objects provided by the
+DCF may be hooked to |ns3| trace sources to enable data processing.
+
+The source code for the classes lives in the directory ``src/stats``.
+
+This chapter is organized as follows. First, an overview of the architecture
+is presented. Next, the helpers for these classes are presented; this
+initial treatment should allow basic use of the data collection framework
+for many use cases. Users who wish to produce output outside of the
+scope of the current helpers, or who wish to create their own data
+collection objects, should read the remainder of the chapter, which
+goes into detail about all of the basic DCF object types and provides
+low-level coding examples.
+
+.. toctree::
+ :maxdepth: 1
+
+ data-collection-overview.rst
+ data-collection-helpers.rst
+ probe.rst
+ collector.rst
+ aggregator.rst
+ adaptor.rst
+ scope-and-limitations.rst
+
Binary file src/stats/doc/dcf-overview-with-aggregation.dia has changed
Binary file src/stats/doc/dcf-overview.dia has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/probe.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,468 @@
+.. include:: replace.txt
+
+.. heading hierarchy:
+ ************* Section (#.#)
+ ============= Subsection (#.#.#)
+ ############# Paragraph (no number)
+ ~~~~~~~~~~~~~ Sub-paragraph (no number)
+
+Probes
+******
+
+This section details the functionalities provided by the Probe class
+to an |ns3| simulation, and gives examples on how to code them in a
+program. This section is meant for users interested in developing
+simulations with the |ns3| tools and using the Data Collection
+Framework, of which the Probe class is a part, to generate data output
+with their simulation's results.
+
+Probe Overview
+==============
+
+A Probe object is supposed to be connected to a variable from the
+simulation whose values throughout the experiment are relevant to the user.
+The Probe will record what were values assumed by the variable throughout
+the simulation and pass such data to another member of the Data Collection
+Framework. While it is out of this section's scope to discuss what happens
+after the Probe produces its output, it is sufficient to say that, by the
+end of the simulation, the user will have detailed information about what
+values were stored inside the variable being probed during the simulation.
+
+Typically, a Probe is connected to an |ns3| trace source. In this manner,
+whenever the trace source exports a new value, the Probe consumes the
+value (and exports it downstream to another object via its own trace source).
+
+The Probe can be thought of as kind of a filter on trace sources. The
+main reasons for possibly hooking to a Probe rather than directly to a
+trace source are as follows:
+
+* Probes may be dynamically turned on and off during the simulation
+ with calls to ``Enable()`` and ``Disable()``. For example, the
+ outputting of data may be turned off during the simulation warmup
+ phase.
+* Probes may perform operations on the data to extract values from more
+ complicated structures; for instance, outputting the packet size value
+ from a received ns3::Packet.
+* Probes register a name in the ns3::Config namespace (using
+ ``Names::Add ()``) so that other objects may refer to them.
+* Probes provide a static method that allows one to manipulate a Probe
+ by name, such as what is done in ns2measure [Cic06]_ ::
+
+ Stat::put ("my_metric", ID, sample);
+
+ The ns-3 equivalent of the above ns2measure code is, e.g.::
+
+ DoubleProbe::SetValueByPath ("/path/to/probe", sample);
+
+Creation
+########
+
+Note that a Probe base class object can not be created because it
+is an abstract base class, i.e. it has pure virtual functions that
+have not been implemented. An object of type DoubleProbe,
+which is a subclass of the Probe class, will be created here to
+show what needs to be done.
+
+One declares a DoubleProbe in dynamic memory by using the smart pointer class
+(Ptr<T>). To create a DoubleProbe in dynamic memory with smart pointers, one
+just needs to call the |ns3| method ``CreateObject()``:
+
+::
+
+ Ptr<DoubleProbe> myprobe = CreateObject<DoubleProbe> ();
+
+The declaration above creates DoubleProbes using the default values for its
+attributes. There are four attributes in the DoubleProbe class; two in the
+base class object DataCollectionObject, and two in the Probe base class:
+
+* "Name" (DataCollectionObject), a StringValue
+* "Enabled" (DataCollectionObject), a BooleanValue
+* "Start" (Probe), a TimeValue
+* "Stop" (Probe), a TimeValue
+
+One can set such attributes at object creation by using the following
+method:
+
+::
+
+ Ptr<DoubleProbe> myprobe = CreateObjectWithAttributes<DoubleProbe> (
+ "Name", StringValue ("myprobe"),
+ "Enabled", BooleanValue (false),
+ "Start", TimeValue (Seconds (100.0)),
+ "Stop", TimeValue (Seconds (1000.0)));
+
+Start and Stop are Time variables which determine the interval of action
+of the Probe. The Probe will only output data if the current time of the
+Simulation is inside of that interval. The special time value of 0 seconds
+for Stop will disable this attribute (i.e. keep the Probe on for the whole
+simulation). Enabled is a flag that turns the
+Probe on or off, and must be set to true for the Probe to export data.
+The Name is the object's name in the DCF framework.
+
+Importing and exporting data
+############################
+
+|ns3| trace sources are strongly typed, so the mechanisms for hooking
+Probes to a trace source and for exporting data belong to its
+subclasses. For instance, the default distribution of |ns3| provides
+a class DoubleProbe that is designed to hook to a trace source
+exporting a double value. We'll next detail the operation of the
+DoubleProbe, and then discuss how other Probe classes may be defined
+by the user.
+
+DoubleProbe Overview
+====================
+
+The DoubleProbe connects to a double-valued |ns3| trace source, and itself
+exports a different double-valued |ns3| trace source.
+
+The following code, drawn from
+``src/stats/examples/double-probe-example.cc``, shows the basic
+operations of plumbing the DoubleProbe into a simulation, where it is
+probing a Counter exported by an emitter object (class Emitter).
+
+::
+
+ Ptr<Emitter> emitter = CreateObject<Emitter> ();
+ Names::Add ("/Names/Emitter", emitter);
+ ...
+
+ Ptr<DoubleProbe> probe1 = CreateObject<DoubleProbe> ();
+
+ // Connect the probe to the emitter's Counter
+ bool connected = probe1->ConnectByObject ("Counter", emitter);
+
+The following code is probing the same Counter exported by the same
+emitter object. This DoubleProbe, however, is using a path in the
+configuration namespace to make the connection. Note that the emitter
+registered itself in the configuration namespace after it was created;
+otherwise, the ConnectByPath would not work.
+
+::
+
+ Ptr<DoubleProbe> probe2 = CreateObject<DoubleProbe> ();
+
+ // Note, no return value is checked here
+ probe2->ConnectByPath ("/Names/Emitter/Counter");
+
+The next DoubleProbe shown that is shown below will have its value set using
+its path in the configuration namespace. Note that this time the
+DoubleProbe registered itself in the configuration namespace after it was
+created.
+
+::
+
+ Ptr<DoubleProbe> probe3 = CreateObject<DoubleProbe> ();
+ probe3->SetName ("StaticallyAccessedProbe");
+
+ // We must add it to the config database
+ Names::Add ("/Names/Probes", probe3->GetName (), probe3);
+
+The emitter's Count() function is now able to set the value for this DoubleProbe as follows:
+
+::
+
+ void
+ Emitter::Count (void)
+ {
+ ...
+ m_counter += 1.0;
+ DoubleProbe::SetValueByPath ("/Names/StaticallyAccessedProbe", m_counter);
+ ...
+ }
+
+The above example shows how the code calling the Probe does not have to
+have an explicit reference to the Probe, but can direct the value
+setting through the Config namespace. This is similar in functionality
+to the `Stat::Put` method introduced by ns2measure paper [Cic06]_, and allows
+users to temporarily insert Probe statements like `printf` statements within
+existing |ns3| models. Note that in order to be able to use the DoubleProbe in this example like this, 2 things were necessary:
+
+1. the stats module header file was included in the example .cc file
+2. the example was made dependent on the stats module in its wscript file.
+
+Analogous things need to be done in order to add other Probes in other places in the |ns3| code base.
+
+The values for the DoubleProbe can also be set using the function
+DoubleProbe::SetValue(), while the values for the DoubleProbe can be gotten
+using the function DoubleProbe::GetValue().
+
+The DoubleProbe exports double values in its "Output" trace source;
+a downstream object can hook a trace sink (NotifyViaProbe) to this as follows:
+
+::
+
+ connected = probe1->TraceConnect ("Output", probe1->GetName (), MakeCallback (&NotifyViaProbe));
+
+
+Other probes
+============
+
+Besides the DoubleProbe, the following Probes are also available:
+
+- Uinteger8Probe connects to an |ns3| trace source exporting an uint8_t.
+- Uinteger16Probe connects to an |ns3| trace source exporting an uint16_t.
+- Uinteger32Probe connects to an |ns3| trace source exporting an uint32_t.
+- PacketProbe connects to an |ns3| trace source exporting a packet.
+- ApplicationPacketProbe connects to an |ns3| trace source exporting a packet and a socket address.
+- Ipv4PacketProbe connects to an |ns3| trace source exporting a packet, an IPv4 object, and an interface.
+
+Creating new Probe types
+========================
+
+To create a new Probe type, you need to perform the following steps:
+
+- Be sure that your new Probe class is derived from the Probe base class.
+- Be sure that the pure virtual functions that your new Probe class
+ inherits from the Probe base class are implemented.
+- Find an existing Probe class that uses a trace source that is
+ closest in type to the type of trace source your Probe will be
+ using.
+- Copy that existing Probe class's header file (.h) and implementation
+ file (.cc) to two new files with names matching your new Probe.
+- Replace the types, arguments, and variables in the copied files with
+ the appropriate type for your Probe.
+- Make necessary modifications to make the code compile and to make it
+ behave as you would like.
+
+Examples
+========
+
+Two examples will be discussed in detail here:
+
+- Double Probe Example
+- IPv4 Packet Plot Example
+
+Double Probe Example
+####################
+
+The double probe example has been discussed previously. The example
+program can be found in
+``src/stats/examples/double-probe-example.cc``. To
+summarize what occurs in this program, there is an emitter that
+exports a counter that increments according to a Poisson process. In
+particular, two ways of emitting data are shown:
+
+1. through a traced variable hooked to one Probe:
+
+::
+
+ TracedValue<double> m_counter; // normally this would be integer type
+
+2. through a counter whose value is posted to a second Probe, referenced by its name in the Config system:
+
+::
+
+ void
+ Emitter::Count (void)
+ {
+ NS_LOG_FUNCTION (this);
+ NS_LOG_DEBUG ("Counting at " << Simulator::Now ().GetSeconds ());
+ m_counter += 1.0;
+ DoubleProbe::SetValueByPath ("/Names/StaticallyAccessedProbe", m_counter);
+ Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Count, this);
+ }
+
+Let's look at the Probe more carefully. Probes can receive their values
+in a multiple ways:
+
+1. by the Probe accessing the trace source directly and connecting
+ a trace sink to it
+2. by the Probe accessing the trace source through the config namespace
+ and connecting a trace sink to it
+3. by the calling code explicitly calling the Probe's `SetValue()` method
+4. by the calling code explicitly calling `SetValueByPath ("/path/through/Config/namespace", ...)`
+
+The first two techniques are expected to be the most common. Also in the
+example, the hooking of a normal callback function is shown,
+as is typically done in |ns3|. This callback function is not associated
+with a Probe object. We'll call this case 0) below.
+
+::
+
+ // This is a function to test hooking a raw function to the trace source
+ void
+ NotifyViaTraceSource (std::string context, double oldVal, double newVal)
+ {
+ NS_LOG_DEBUG ("context: " << context << " old " << oldVal << " new " << newVal);
+ }
+
+First, the emitter needs to be setup:
+
+::
+
+ Ptr<Emitter> emitter = CreateObject<Emitter> ();
+ Names::Add ("/Names/Emitter", emitter);
+
+ // The Emitter object is not associated with an ns-3 node, so
+ // it won't get started automatically, so we need to do this ourselves
+ Simulator::Schedule (Seconds (0.0), &Emitter::Start, emitter);
+
+The various DoubleProbes interact with the emitter in the example as
+shown below.
+
+Case 0):
+
+::
+
+ // The below shows typical functionality without a probe
+ // (connect a sink function to a trace source)
+ //
+ connected = emitter->TraceConnect ("Counter", "sample context", MakeCallback (&NotifyViaTraceSource));
+ NS_ASSERT_MSG (connected, "Trace source not connected");
+
+
+case 1):
+
+::
+
+ //
+ // Probe1 will be hooked directly to the Emitter trace source object
+ //
+
+ // probe1 will be hooked to the Emitter trace source
+ Ptr<DoubleProbe> probe1 = CreateObject<DoubleProbe> ();
+ // the probe's name can serve as its context in the tracing
+ probe1->SetName ("ObjectProbe");
+
+ // Connect the probe to the emitter's Counter
+ connected = probe1->ConnectByObject ("Counter", emitter);
+ NS_ASSERT_MSG (connected, "Trace source not connected to probe1");
+
+case 2):
+
+::
+
+ //
+ // Probe2 will be hooked to the Emitter trace source object by
+ // accessing it by path name in the Config database
+ //
+
+ // Create another similar probe; this will hook up via a Config path
+ Ptr<DoubleProbe> probe2 = CreateObject<DoubleProbe> ();
+ probe2->SetName ("PathProbe");
+
+ // Note, no return value is checked here
+ probe2->ConnectByPath ("/Names/Emitter/Counter");
+
+case 4) (case 3 is not shown in this example):
+
+::
+
+ //
+ // Probe3 will be called by the emitter directly through the
+ // static method SetValueByPath().
+ //
+ Ptr<DoubleProbe> probe3 = CreateObject<DoubleProbe> ();
+ probe3->SetName ("StaticallyAccessedProbe");
+ // We must add it to the config database
+ Names::Add ("/Names/Probes", probe3->GetName (), probe3);
+
+And finally, the example shows how the probes can be hooked to
+generate output:
+
+::
+
+ // The probe itself should generate output. The context that we provide
+ // to this probe (in this case, the probe name) will help to disambiguate
+ // the source of the trace
+ connected = probe3->TraceConnect ("Output", "/Names/Probes/StaticallyAccessedProbe/Output", MakeCallback (&NotifyViaProbe));
+ NS_ASSERT_MSG (connected, "Trace source not .. connected to probe3 Output");
+
+The following callback is hooked to the Probe in this example for
+illustrative purposes; normally, the Probe would be hooked to a
+Collector object.
+
+::
+
+ // This is a function to test hooking it to the probe output
+ void
+ NotifyViaProbe (std::string context, double oldVal, double newVal)
+ {
+ NS_LOG_DEBUG ("context: " << context << " old " << oldVal << " new " << newVal);
+ }
+
+
+IPv4 Packet Plot Example
+########################
+
+The IPv4 packet plot example is based on the fifth.cc example from the |ns3|
+Tutorial. It can be found in
+``src/stats/examples/ipv4-packet-plot-example.cc``.
+
+::
+
+ // ===========================================================================
+ //
+ // node 0 node 1
+ // +----------------+ +----------------+
+ // | ns-3 TCP | | ns-3 TCP |
+ // +----------------+ +----------------+
+ // | 10.1.1.1 | | 10.1.1.2 |
+ // +----------------+ +----------------+
+ // | point-to-point | | point-to-point |
+ // +----------------+ +----------------+
+ // | |
+ // +---------------------+
+
+
+
+We'll just look at the Probe, as it illustrates that Probes may also
+unpack values from structures (in this case, packets) and report
+those values as trace source outputs, rather than just passing through
+the same type of data.
+
+There are other aspects of this example that will be explained later in
+the documentation. The two types of data that are exported are the packet
+itself (`Output`) and a count of the number of bytes in the packet
+(`OutputBytes`).
+
+::
+
+ TypeId
+ Ipv4PacketProbe::GetTypeId ()
+ {
+ static TypeId tid = TypeId ("ns3::Ipv4PacketProbe")
+ .SetParent<Probe> ()
+ .AddConstructor<Ipv4PacketProbe> ()
+ .AddTraceSource ( "Output",
+ "The packet plus its IPv4 object and interface that serve as the output for this probe",
+ MakeTraceSourceAccessor (&Ipv4PacketProbe::m_output))
+ .AddTraceSource ( "OutputBytes",
+ "The number of bytes in the packet",
+ MakeTraceSourceAccessor (&Ipv4PacketProbe::m_outputBytes))
+ ;
+ return tid;
+ }
+
+
+When the Probe's trace sink gets a packet, if the Probe is enabled, then
+it will output the packet on its `Output` trace source, but it will also
+output the number of bytes on the `OutputBytes` trace source.
+
+::
+
+ void
+ Ipv4PacketProbe::TraceSink (Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t interface)
+ {
+ NS_LOG_FUNCTION (this << packet << ipv4 << interface);
+ if (IsEnabled ())
+ {
+ m_packet = packet;
+ m_ipv4 = ipv4;
+ m_interface = interface;
+ m_output (packet, ipv4, interface);
+
+ uint32_t packetSizeNew = packet->GetSize ();
+ m_outputBytes (m_packetSizeOld, packetSizeNew);
+ m_packetSizeOld = packetSizeNew;
+ }
+ }
+
+
+References
+==========
+
+.. [Cic06] Claudio Cicconetti, Enzo Mingozzi, Giovanni Stea, "An Integrated
+ Framework for Enabling Effective Data Collection and Statistical
+ Analysis with ns2, Workshop on ns-2 (WNS2), Pisa, Italy, October 2006.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/doc/scope-and-limitations.rst Fri Aug 09 05:22:00 2013 -0700
@@ -0,0 +1,50 @@
+.. include:: replace.txt
+
+.. heading hierarchy:
+ ************* Section (#.#)
+ ============= Subsection (#.#.#)
+ ############# Paragraph (no number)
+
+Scope/Limitations
+*****************
+
+This section discusses the scope and limitations of the Data
+Collection Framework.
+
+Currently, only these Probes have been implemented in DCF:
+
+- BooleanProbe
+- DoubleProbe
+- Uinteger8Probe
+- Uinteger16Probe
+- Uinteger32Probe
+- PacketProbe
+- ApplicationPacketProbe
+- Ipv4PacketProbe
+
+Currently, no Collectors are available in the DCF, although a
+BasicStatsCollector is under development.
+
+Currently, only these Aggregators have been implemented in DCF:
+
+- GnuplotAggregator
+- FileAggregator
+
+Currently, only this Adaptor has been implemented in DCF:
+
+Time-Series Adaptor.
+
+Future Work
+###########
+
+This section discusses the future work to be done on the Data
+Collection Framework.
+
+Here are some things that still need to be done:
+
+- Hook up more trace sources in |ns3| code to get more values out of the simulator.
+- Implement more types of Probes than there currently are.
+- Implement more than just the single current 2-D Collector, BasicStatsCollector.
+- Implement more Aggregators.
+- Implement more than just Adaptors.
+