00001 /** 00002 \file Robots/LoBot/misc/LoDataset.H 00003 \brief An object to store the list of parsed metrics logs, or 00004 "experiments," and provide thread-safe access to this list along with 00005 a suitable API for analyzing the metrics. 00006 00007 This file defines a class that implements an interface for storing the 00008 list of parsed metrics logs and providing thread-safe access to this 00009 list. 00010 00011 The Robolocust metrics log dataset program enumerates the list of log 00012 files in the individual directories specified as command line 00013 arguments to it. Then, it creates multiple threads to load and parse 00014 all these log files in parallel. Once an individual log has been 00015 parsed, the loader thread that loaded it will need to know where to 00016 store the resulting lobot::Experiment object that encapsulates the 00017 parsed log. 00018 00019 The lobot::Dataset class provides a data structure for storing the 00020 parsed experiments. Since the metlogs making up a dataset are all 00021 loaded in parallel, lobot::Dataset provides thread-safe API's to 00022 collect the parsing results as they become available. 00023 00024 In addition to the above-mentioned collection API, the lobot::Dataset 00025 class also provides various functions that support the necessary data 00026 analysis on the metrics collected from the trajectory recording 00027 experiments. 00028 */ 00029 00030 // //////////////////////////////////////////////////////////////////// // 00031 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00032 // by the University of Southern California (USC) and the iLab at USC. // 00033 // See http://iLab.usc.edu for information about this project. // 00034 // //////////////////////////////////////////////////////////////////// // 00035 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00036 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00037 // in Visual Environments, and Applications'' by Christof Koch and // 00038 // Laurent Itti, California Institute of Technology, 2001 (patent // 00039 // pending; application number 09/912,225 filed July 23, 2001; see // 00040 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00041 // //////////////////////////////////////////////////////////////////// // 00042 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00043 // // 00044 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00045 // redistribute it and/or modify it under the terms of the GNU General // 00046 // Public License as published by the Free Software Foundation; either // 00047 // version 2 of the License, or (at your option) any later version. // 00048 // // 00049 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00050 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00051 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00052 // PURPOSE. See the GNU General Public License for more details. // 00053 // // 00054 // You should have received a copy of the GNU General Public License // 00055 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00056 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00057 // Boston, MA 02111-1307 USA. // 00058 // //////////////////////////////////////////////////////////////////// // 00059 // 00060 // Primary maintainer for this file: mviswana usc edu 00061 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/metlog/LoDataset.H $ 00062 // $Id: LoDataset.H 13934 2010-09-14 23:17:01Z mviswana $ 00063 // 00064 00065 #ifndef LOBOT_METRICS_DATASET_DOT_H 00066 #define LOBOT_METRICS_DATASET_DOT_H 00067 00068 //------------------------------ HEADERS -------------------------------- 00069 00070 // lobot headers 00071 #include "Robots/LoBot/metlog/LoPointTypes.H" 00072 #include "Robots/LoBot/thread/LoMutex.H" 00073 00074 // Standard C++ headers 00075 #include <vector> 00076 00077 //----------------------------- NAMESPACE ------------------------------- 00078 00079 namespace lobot { 00080 00081 //------------------------- CLASS DEFINITION ---------------------------- 00082 00083 // Forward declarations 00084 class Experiment ; 00085 00086 /** 00087 \class lobot::Dataset 00088 \brief A thread-safe container for storing parsed metlogs and 00089 performing various operations on them. 00090 00091 Multiple instances of the lobot::MetlogLoader class are used to load 00092 and parse an LGMD trajectory dataset's individual metlogs in parallel. 00093 Each parsed metlog is stored in a lobot::Experiment object. The 00094 lobot::Dataset class is used to collect all the parsed metlogs, i.e., 00095 experiments, and put them in a thread-safe container. 00096 00097 Additionally, this class also provides various API's to support the 00098 necessary number crunching operations on the experiments to aid in 00099 their analysis. 00100 00101 NOTE: The lobot::MetlogLoader class is responsible for creating the 00102 individual lobot::Experiment objects corresponding to each of the 00103 metlogs in a dataset. However, once it is done parsing the metlog and 00104 filling in the data in the Experiment object, it will hand the object 00105 over to the Dataset, which will then take over "ownership" of the 00106 Experiment. That is, modules that create Experiment objects should not 00107 delete those objects if they hand them over to a Dataset. 00108 */ 00109 class Dataset { 00110 // Prevent copy and assignment 00111 Dataset(const Dataset&) ; 00112 Dataset& operator=(const Dataset&) ; 00113 00114 /// The whole idea behind this class is to keep track of a list of 00115 /// parsed metrics logs, i.e., "experiments." 00116 //@{ 00117 typedef std::vector<Experiment*> List ; 00118 mutable List m_list ; 00119 mutable List::const_iterator m_next ; 00120 //@} 00121 00122 /// When a loader thread is done processing one metlog, it will add 00123 /// the resulting Experiment object to an instance of this class. 00124 /// Since multiple loader threads can use this object, we need a mutex 00125 /// to ensure that they don't step on each others' toes. 00126 /// 00127 /// We use the same mutex when we're dealing with correspondence 00128 /// finder threads, which need to retrieve the experiments one-by-one. 00129 Mutex m_mutex ; 00130 00131 public: 00132 /// Constructor. 00133 Dataset() ; 00134 00135 /// This method adds a parsed metlog, i.e., an Experiment, to its 00136 /// internal data structure. It is thread-safe and is meant to be used 00137 /// by lobot::MetlogLoader. 00138 void add(Experiment*) ; 00139 00140 /// This function returns the number of experiments currently part of 00141 /// the dataset. 00142 int size() const {return m_list.size() ;} 00143 00144 /// Check if the dataset is empty. 00145 bool empty() const {return m_list.empty() ;} 00146 00147 /// This method returns the "reference experiment" for different 00148 /// criteria. 00149 /// 00150 /// Each dataset consists of several experiments. Each experiment 00151 /// contains a variety of point lists. One of these point lists 00152 /// records the robot's trajectory from start location to goal; 00153 /// another records the points at which the robot's LGMD-based 00154 /// extrication behaviour kicked in; another marks the locations where 00155 /// the robot's avoidance algorithms failed and made it bump into an 00156 /// obstacle; so on and so forth. 00157 /// 00158 /// To make this discussion a little more concrete and clear, let us 00159 /// say we are interested in computing the average trajectory from 00160 /// start to goal across all the experiments in a dataset. Each 00161 /// experiment will have a different number of points recorded in its 00162 /// trajectory list. To find the average path, we will have to somehow 00163 /// "normalize" all the recorded trajectories so that they all have 00164 /// the same number of points. 00165 /// 00166 /// To effect this "normalization," we find the trajectory containing 00167 /// the number of points that is the median of all the trajectories. 00168 /// The corresponding experiment is regarded as the "reference" and 00169 /// all average computations are made w.r.t. to this reference. 00170 /// 00171 /// This method returns the reference experiment for the specified 00172 /// point list. The return value is a const pointer to an Experiment 00173 /// object contained in the dataset. Clients should consider this 00174 /// object read-only, i.e., they should refrain from casting away the 00175 /// constness of the returned pointer and changing the returned object 00176 /// in any way. Clients should also not delete the pointer returned by 00177 /// this function. 00178 /// 00179 /// An invocation of this function prior to the addition of any parsed 00180 /// experiment objects to the dataset will result in a 00181 /// lobot::misc_error exception with the LOGIC_ERROR code. 00182 /// 00183 /// WARNING: This method alters the dataset object's internal state. 00184 /// It is most definitely not thread-safe. It is meant to be called by 00185 /// the lomet program's main thread and not from one of its helper 00186 /// threads. 00187 const Experiment* find_refexp(PointListName) const ; 00188 00189 /// This method returns the next experiment that needs to be 00190 /// processed. It is meant to be used by the correspondence finder 00191 /// threads. 00192 const Experiment* next() const ; 00193 00194 /// Since an experiment contains several different point lists, full 00195 /// analysis of a dataset requires invocation of the point 00196 /// correspondence finder procedure several times. Before we start the 00197 /// multithreaded correspondence finding procedure, we should first 00198 /// rewind the dataset so that the correspondence finder threads start 00199 /// off processing from the first experiment in the dataset. This 00200 /// method implements the dataset rewinding described above. 00201 /// 00202 /// This method is meant to be used by the lomet main program right 00203 /// before it launches the multiple correspondence finder threads. 00204 /// Note that it is not thread-safe and should not be called from any 00205 /// of lomet's helper threads. 00206 /// 00207 /// WARNING: If this function is called before any experiments have 00208 /// been added to the dataset, it will throw a lobot::misc_error with 00209 /// LOGIC_ERROR as the code. 00210 void rewind() ; 00211 00212 /// This is the exception object thrown when we reach the end of the 00213 /// experiment list. This exception serves as the signal to the 00214 /// correspondence finder threads that all the experiments have been 00215 /// processed. 00216 struct eol {} ; 00217 00218 /// Clean-up. 00219 ~Dataset() ; 00220 00221 /// Debug support: dump each of the experiments to see what data they 00222 /// contain and allow users to verify whether that matches the 00223 /// original log files properly. 00224 void dump() const ; 00225 } ; 00226 00227 //----------------------------------------------------------------------- 00228 00229 } // end of namespace encapsulating this file's definitions 00230 00231 #endif 00232 00233 /* So things look consistent in everyone's emacs... */ 00234 /* Local Variables: */ 00235 /* indent-tabs-mode: nil */ 00236 /* End: */