Dictionaries

Name

Dictionaries -- Describe dictionaries used by SpecTcl

Synopsis


#include <Dictionary.h>
template <class T>
class DictionaryObserver 
{
public:
  virtual void onAdd(std::string   name,   T& item) {}
  virtual void onRemove( std::string name,    T& item) {}

};

template <class T>
class CDictionaryObserverManager 
{
  void addObserver(DictionaryObserver<T>* observer);
  void removeObserver(DictionaryObserver<T>* observer);
  void invokeAdd(const std::string name, T& item);
  void invokeRemove(const std::string name, T& item);

};

template <class T>
class CDictionary      
{
  DictionaryIterator Lookup(std::string sName);
  ConstDictionaryIterator Lookup(std::string sName);
  template<class Predicate>
    DictionaryIterator FindMatch(Predicate p);
  template<class Predicate>
    ConstDictionaryIterator FindMatch(Predicate p);
  void Enter(std::string sName, T& Item);
  void Remove(std::string rsName);

  DictionaryIterator begin();
  ConstDictionaryIterator begin() const;
  DictionaryIterator end();
  ConstDictionaryIterator end() const ;

  UInt_t size() const;
  void addObserver(DictionaryObserver<T>* observer);
  void removeObserver(DictionaryObserver<T>* observer);
};

        

#include <DictionaryException>
class CDictionaryException  : public CException        
{
public:
  enum {
    knDuplicateKey,
    knDuplicateId,
    knNoSuchId,
    knNoSuchKey,
    knWrongGateType
  };
  
public:
  CDictionaryException(Int_t nReason, const char* pDoing, 
		       const char* pName);
  CDictionaryException(Int_t nReason, const char* pDoing, 
		       const std::string& rName);
  CDictionaryException(Int_t nReason, const std::string& rDoing,
		       const char* pName);
  CDictionaryException(Int_t nReason, const std::string& rDoing,
		       const std::string& rName);
  CDictionaryException(Int_t nReason, const char* pDoing,
		       UInt_t nId) ;
  CDictionaryException(Int_t nReason, const std::string& rDoing,
		       UInt_t nId) ;

  virtual   const char* ReasonText ()  const;
  virtual   Int_t ReasonCode () const  ;
};

        

#include <CFitDictionary.h>
class CFitDictionary {
public:
  typedef std::map<std::string, CSpectrumFit*> FitMap;
  typedef FitMap::iterator      iterator;

  class CObserver {
  public:
    virtual void Add(CSpectrumFit& fit) =0;
    virtual void Delete(CSpectrumFit& fit) = 0;
    virtual void Update(CSpectrumFit& fit) = 0;

  };

  typedef std::list<CObserver*> ObserverList;

  static CFitDictionary& getInstance();

  void add(CSpectrumFit& fit);
  void addOrReplace(CSpectrumFit& fit);
  void Delete(std::string name);

  iterator begin();
  iterator end();
  size_t   size();
  iterator find(std::string name);
  void     erase(iterator here);
  void     erase(iterator first, iterator last);

  void updateFits(std::string name=std::string("*")); 

  void addObserver(CObserver& obs);
  void removeObserver(CObserver& obs);
 
};

        

DESCRIPTION

This page describes SpecTcl dictionaries and their related classes.

The CDictionary class is a templated class that associates names with arbitrary objects. It adds to the std::map class the ability to maintain a set of observers. Observers are objects that are informed of changes in the dictionary (specifically the addition and removal of items from the dictionary).

Closely related to the CDictionary class, therefore are DictionaryObserver, the templated base class of observers. Applications will subclass this and provide the appropriate template arguments for the dictionary used to make use of them. Note that in most cases where SpecTcl uses a dictionary, it provides a typedef for the observer base class that already has provided the template parameters.

CDictionaryObserverManager is actually usable by wrapers of any name/value container (e.g. hashes and multimaps). It maintains a list of observer and provides methods to invoke the observers it maintains.

The CDictionaryException class provides an exception derived from CException SpecTcl throws for many dictionary use violations. These are not normally thrown by the dictionary itself but by SpecTcl code that provides a higher level API to specific dictionaries.

For example, the CHistogrammer throws these if there is an attempt to duplicate the name or id of a dictionary entry.

The CFitDictionary provides a dictionary that manages SpecTcl fit objects. In addition, the observers maintained by fit dictionaries, contain a callback that is invoked if a fit is modified, as well as if it is added or removed from the dictionary.

CDictionaryObserverManager

void addObserver( DictionaryObserver<T>* observer);

Adds an observer to the list of observers managed by this object. Observers are an ordered list. The new observer is added to the end of the list.

void removeObserver( DictionaryObserver<T>* observer);

Removes an observer from the list of observers managed by this object. Note that while it is pathalogical, it is legal to register the same observer object more than once. If removeObserver is asked to remove an observer that is multiply registered, all instances of that observer are removed.

void invokeAdd(const std::string name, T& item);

Iterates over the list of observer objects this object maintains. For each observer, the onAdd method is invoked with the parameters passed to invokeAdd.

void invokeRemove(const std::string name, T& item);

Same as invokeAddd but each object's onRemove is called instead.

CDictionaryObserver

Note that this is a base class. Real observers are classes that inherit from this one.

virtual void onAdd( std::string name, T& item);

This method is invoked when an item is added to a dictionary. name is the name of the item (dictionary key), item refers to the item about to be added. Note that the base class implementation does nothing. If you don't need to observe dictionary additions simply don't override this method.

virtual void onRemove( std::string name, T& item);

This method is invoked when an item is about to be removed from a dictionary. name is the name (dictionary index) of the item and item refers to the item.

At the time this method is called, the item is still in the dictionary. The item is only removed from the dictionary after all observers have been invoked.

The base class implementation is empty. Therefore if your observer does not need to observer dictionary removals, simply don't override the implementation of this method.

CDictionary

DictionaryIterator Lookup( std::string sName); , ConstDictionaryIterator Lookup( std::string sName);

Returns a DictionaryIterator that points to a std::pair<std::string, T> object that has a name that is the same as sName. The first item of the pair should be equal to sName and is the name of the item in the dictionary. The second item of the pair should be the item which is associated with that key.

This method requires that T have a copy constructor or be trivially copy constructable. If there is no match for sName in the dictionary, the value returned by end is returned.

template<class Predicate> DictionaryIterator FindMatch( Predicate p); , template<class Predicate> ConstDictionaryIterator FindMatch( Predicate p);

Performs an search using an arbitrary predicate; p as the matching criterion. The return value is a dictionary iterator as described in Lookup above.

p is any class that implements the operator() taking as a single parameter a std::pair<std::string, T> object. The first item of the pair is the name of some entry in the dictionary. The second is the entry with that name. The predicate must return a value that can be converte to bool. If the return is true, the item is treated as satisfying the match. If not iteration continues with different pairs until either the entire container has been checked or a match is found.

void Enter( std::string sName, T& Item);

Adds Item to the dictionary indexed by sName. If an item already exists with that name it's overwitten. If T is a pointer to dynamically allocated objets, this results in memory leaks unless the dictionary is encapsulated by a derived class or front-ended by an API.

Many SpecTcl dictionaries live privately in enclosing classes like CHistogram. In some cases (e.g. the parameter and spectrum dictionaries), these classes impose an API that throws errors if duplicate entries are attempted.

void Remove( std::string rsName);

Removes the entry whose index is rsName. This does nothing if there is no entry with the index rsName.

Many SpecTcl dictionaries are encapsulated by other classes. In some cases those classes throw exceptions if attempts are made to remove nonexistent objects.

DictionaryIterator begin(); , const ConstDictionaryIterator begin (); , DictionaryIterator end(); , const ConstDictionaryIterator end ();

These methods support iteration over dictionary contents. DictionaryIterator and ConstDictionaryIterator are pointer like objects. They 'point' to std::pair<std::string, T> objects. The first item of the pair is a dictionary key. The second, the object stored at that key.

begin returns an iterator to the first element of the container. Currently, this is the one with the key that collates earliest. Incrementing an iterator points it to another element of the container. Currently, the iterator traverses the container in increasing collation order with respect to the key.

If an iterator points to the last element of the dict, incrementing it results in the same value returned from the end method. The iterators returned by these methods are compatible with the C++ standard library algorithms that accept container iterators.

const UInt_t size();

Returns the number of elements stored in the dictionary.

void addObserver( DictionaryObserver<T>* observer); , void removeObserver( DictionaryObserver<T>* observer);

These methods support observation of the dictionary. addObserver adds an observer that will be called when items are added or removed from the dictionary. Observers have been previously described.

removeObserver removes the observer from the list of observers that monitor the dictionary. While it is pathalogical, addObserver does not prevent you from adding the same observer object more than once. If have added a specific observer more than onece, removeObserver removes all instances of that observer from the dictionary's CDictionaryObserverManager object.


             
        

CDictionaryException

Before providing reference material to CDictionaryException, Let's first look at the public enum that provides the valid values for the reason code in the destructor:


  enum {
    knDuplicateKey,
    knDuplicateId,
    knNoSuchId,
    knNoSuchKey,
    knWrongGateType
  };
            
        

Not all values are used by the APIs in front of all dictionaries. These values have the following meanings:

knDuplicateKey

An attempt was made to insert an entry with a key that already exists in the dictionary.

knDuplicateId

For dictionaries whose entries have unique integer ids stored in their objects: This value indicates an attempt to add an entry that has an id that matches an existing element of the dictionary. For example; Adding two parameters with the same Id throws this error.

knNoSuchId

This reason is used after a search by id results in no matching items. Note that other dictionary APIs may indicate without an error that there is no match (e.g. returning a null pointer or an end iterator)

knNoSuchKey

Similar to knNoSuchId this is thrown when a search for an item by name fails to locate a match.

knWrongGateType

This is not used in SpecTcl. It is intended for use when a gate of an incompatible type for some operation is selected.

CDictionaryException is essentially an CException class whose ReasonText and ReasonCode interpret the nReason code used to construct it as a member of the enum described above.

The class has as rich set of constructors. For the most part these match the constructors available for CException. The parameters nReason should be chosen from the reason enum described above. The pName and rName parameters are names of items nId parameters are relevant object Ids.

CFitDictionary>

CFitDictionary is a specialized dictionary that holds fits. It also provides an extended observer as a nested class; CFitDictionary::CObserver. The observer base class for fit dictionaries have the following pure virtual methods.

virtual =0 void Add( CSpectrumFit& fit);

Called when a fit is added to the dictionary. fit is the object that was added. Note that this object provides the needed methods to get the name of the fit as well as the name of the spectrum on which the fit is defined.

virtual = 0 void Delete( CSpectrumFit& fit);

Called when a fit is deleted (removed from the dictionary). This is called prior to the actual removal of the fit from the dictionary.

virtual = 0 void Update(( CSpectrumFit& fit);

Called when a fit is updated. Updating a fit means that its parameters are recomputed based on the current data in a spectrum. If a fit was created and then additional or new data were acquired, updating the fit is necessary to make the fit reflect the new channel values in the region of interest.

This method is called just after the update has been computed. One use is to maintain the display of a fit on a spectrum by a displayer.

Note that the fit dictionary is also a singleton class and therefore has private constructors and destructors.

static CFitDictionary& getInstance();

Returns the singleton instance of this class. If the dictionary has not yet been created, this will create it. If it has, a reference to the existing dictionary is returned.

void add( CSpectrumFit& fit);

Adds a new fit to the dictionary. Note that if the dictionary already has a fit named the same as fit, a CDictionaryException is thrown with the reason CDictionaryException::knDuplicateKey.

See addOrReplace below as well.

void addOrReplace( CSpectrumFit& fit);

Adds fit to the dictionary. If a fit with that name already exists it is replaced by this new fit. In that case observer Delete methods are called.

void Delete( std::string name);

Delets any fit with the name name. If there is no such fit, CDictionaryException with the reason CDictionaryException::knNoSuchkey is thrown.

iterator begin(); , iterator end();

These methods support iteration over the container that holds the fit dictionary. CFitDictionary::iterator is an pointer like object that points at std::pair<std::string, CSpectrumFit*> objects. The first element of the pair is the name of the fit while the second is a pointer to the fit object.

begin returns an iterator that points to the first element of the dictionary. Incrementing an iterator results in an interator that points at the next element of the dictionary. If the iterator points to the last element of the dictionary, incrementing it produces the value returned by end

These iterators are suitable for use in any of the C++ standard library algorithms that require iterators.

size_t size();

Returns the number of elements in the dictionary.

iterator find( std::string name);

Returns an iterator to the dictionary entry pair with the index name. If name is not found, the value returned from end is returned:


CFitDictionary& fitDict(CFitDictionary::getInstance());

CFitDictionary::iterator p = fitDict->find("foo");
if (p != fitDict.end()) {

std::string name = p->first;
CSpectrumFit* fit = p->second;

// Do something with what was found.
} else {
j  // Item was not found.
}
                    
void erase( iterator here); , void erase( iterator first, iterator last);

Removes items from the dictionary based on iterators. here is an iterator that points to the item to remove> first and last are iterators that define a range of items to remove. All items from first up to but not including last are removed.

Note that erase invalidates the iterator(s) it receives as parameters.

void updateFits( std::string name = std::string("*"));

Recomputes fits with current spectrum data for all fit names that match the glob pattter name. Note that the default value for this parameter, *, matches all fits.

Fits are defined on regions of interest in spectra. As spectra accumulate or are cleared and a new data set analyzed, they can be recomputed on the current data. SpecTcl establishes observers that propagate the changes to the fit information to its displayers so that the fitlines displayed on those spectra also automatically update.

void addObserver( CObserver& obs); , void removeObserver( CObserver& obs);

These methods manage observers that are monitoring the fit dictionary. addObserver adds the observer obs to end of the list of observers. removeObserver removes all instances of ojbs from the list of observers maintained by the dictionary.