ENSDF++ 1.1
An easy, fast and simple way to run querys towards the ENSDF database, written in C++.
Public Member Functions | Protected Member Functions | Protected Attributes
ENSDF Class Reference

Loads all information in the ENSDF data files, and creates Isotop object from them asynchronously. More...

#include <ENSDF.h>

Inheritance diagram for ENSDF:
VerbosePrinterEventEnabled

List of all members.

Public Member Functions

 ENSDF (vector< string > filenames, VerbosePrinter *toRegister=NULL, unsigned int numberOfThreads=5)
 Constructor, creates the ENSDF object and loads all Isotop objects asynchronously into memory.
 ~ENSDF ()
 Destructor, deletes Isotop objects to prevent memory leaks.
const IsotopgetIsotop (const Nukleid isotopeToGet) const
const map< Nukleid, Isotop * > getAllIsotopes () const
int getNumberOfIsotops () const

Protected Member Functions

NukleidgetNucleidFromString (string stringToGetIsotopeFrom)
 Tries to identify a Nukleid object in an ENSDF record string (80 characters). Returns NULL if no Nukleid object could be created.
list< list< string > > splitInDataSets (list< string > allDatasets)
 Takes all ENSDF information as input, and splits it Dataset's based on the End of dataset records.
bool isEmptyString (string toCheck)
 Checks if a string is empty or not.
void threadFlush (vector< list< pair< Nukleid, list< list< string > > * > > > toFlush)
 Creates the working threads which creates all isotope objects, and waits for them to return.

Protected Attributes

map< Nukleid, Isotop * > myNucleidIsotopeMap
 A register of all Isotop objects.

Detailed Description

Loads all information in the ENSDF data files, and creates Isotop object from them asynchronously.

Author:
Rikard Lundmark
Note:
The more CPU power you have, the faster initialization.
Loading the entire ENSDF database requires lots memory, we recommend at least 2 GB free when starting the program.

Definition at line 85 of file ENSDF.h.


Constructor & Destructor Documentation

ENSDF::ENSDF ( vector< string >  filenames,
VerbosePrinter toRegister = NULL,
unsigned int  numberOfThreads = 5 
)

Constructor, creates the ENSDF object and loads all Isotop objects asynchronously into memory.

Note:
May take several minutes.
Parameters:
filenamesA list of all the files which contains the ENSDF data. These files will be loaded in whole upon construction.
Note:
If any non-ENSDF files are entered here, an exception will be thrown and the object will not initialize correctly.
Parameters:
toRegisterUsed to communicate with the user.
numberOfThreadsNumber of working threads. You usually need

Definition at line 6 of file ENSDF.cpp.

References getNucleidFromString(), NULL, VerbosePrinterEventEnabled::registerListener(), splitInDataSets(), threadFlush(), Nukleid::toString(), and VerbosePrinterEventEnabled::vPrint().

{
  registerListener(toRegister);
  vPrint(3, "Loading ENSDF files.\n");
  list<string> myIsotopes;
  for(vector<string>::iterator it = filenames.begin(); it < filenames.end(); it++)
    {
      vPrint(6,"Now loading file: \"%s\" into memory\n",it->c_str());
      FILE * myFile;
      myFile = fopen ((*it).c_str() , "r");
      char line[100];
      
      if(myFile==NULL)
        perror("The opened file is null");
      
      while (fgets(line, 100, myFile) != NULL) 
        {
          string myString(line);
          myIsotopes.push_back(myString);
        }
      if(myFile!=NULL)
        fclose(myFile);
    }
  list< list<string> > allDatasets = splitInDataSets(myIsotopes); //contains all datasets, one entry for each dataset.
  
  map< Nukleid, list< list<string> > > datasetsSortedByIsotope; //the outer list contains one entry for each isotope. Now fill this...

  vPrint(3,"Identifying isotopes for each dataset.\n");
  for(list< list<string> >::iterator myIterator = allDatasets.begin(); myIterator!=allDatasets.end(); myIterator++)
    {
      Nukleid * myNucleid = NULL;
      list<string>::iterator subIterator = myIterator->begin();
      while(myNucleid == NULL && subIterator != myIterator->end())
        {
          myNucleid = getNucleidFromString(*subIterator);
          subIterator++;
        }
      if(myNucleid==NULL) //if this occurs, we cannot obtain any more information...
        {
          throw DataFileException("Error parsing data file: SubIterator went out of bounds");
        }
      datasetsSortedByIsotope[Nukleid(*myNucleid)].push_back(*myIterator);
      delete myNucleid;
    }
  allDatasets = list< list<string> >();
  vPrint(3, "Creating isotope objects\n");
  int iter = 0;
  vector<list<pair<Nukleid, list<list<string> > * > > > toFlush;
  for(unsigned int i = 0; i<numberOfThreads; i++)
    {
      toFlush.push_back(list< pair < Nukleid, list< list< string > > * > >());
    }
  int flushAdress = 0;
  for(map<Nukleid, list< list<string> > >::iterator myIterator = datasetsSortedByIsotope.begin(); myIterator!=datasetsSortedByIsotope.end(); myIterator++)
    {
      Nukleid myNukleid = myIterator->first;
      vPrint(12,"Preparing to create isotope object for nucleid %s (%d of %d).\n",myNukleid.toString().c_str(), ++iter, datasetsSortedByIsotope.size());
      toFlush[(flushAdress++)%numberOfThreads].push_back(make_pair(myNukleid, &(myIterator->second)));
    }
  threadFlush(toFlush);
  //to free memory.
  datasetsSortedByIsotope=map<Nukleid,list< list<string> > >();
  vPrint(3,"Done creating ENSDF object\n");
  return;
}

Member Function Documentation

const map< Nukleid, Isotop * > ENSDF::getAllIsotopes ( ) const
Returns:
a map containing all Isotop objects in this ENSDF object.

Definition at line 147 of file ENSDF.cpp.

References myNucleidIsotopeMap.

Referenced by ENSDF_TEST::ENSDF_ReadsCorrectNumberOfIsotopes_AssertTrue(), DataQueryIsomer::RunQuery(), and DataQueryBetaGamma::RunQuery().

{
  return myNucleidIsotopeMap;
}
const Isotop * ENSDF::getIsotop ( const Nukleid  isotopeToGet) const
Returns:
the Isotop object corresponding to the Nukleid object specified, or NULL if there was no such isotop object.
Parameters:
isotopeToGetThe Nukleid object to find a matching Isotop object for.

Definition at line 132 of file ENSDF.cpp.

References myNucleidIsotopeMap, and NULL.

{
  if(myNucleidIsotopeMap.find(nucleidToGet)!=myNucleidIsotopeMap.end())
    return myNucleidIsotopeMap.find(nucleidToGet)->second;
  else
    return NULL;
}
Nukleid * ENSDF::getNucleidFromString ( string  stringToGetIsotopeFrom) [protected]

Tries to identify a Nukleid object in an ENSDF record string (80 characters). Returns NULL if no Nukleid object could be created.

Parameters:
stringToGetIsotopeFromThe 80 character ENSDF record string to find the Nukleid object from (usually the Nukleid identified by the first 5 characters).

Definition at line 202 of file ENSDF.cpp.

References NULL.

Referenced by ENSDF().

{
  try
    {
      Nukleid * myNukleid = new Nukleid(stringToGetIsotopeFrom.substr(0,5));
      return myNukleid;
    }
  catch(exception &e)
    {
      return NULL;
    }
}
int ENSDF::getNumberOfIsotops ( ) const
Returns:
The number of Isotop object in this ENSDF object.

Definition at line 142 of file ENSDF.cpp.

References myNucleidIsotopeMap.

Referenced by ENSDF_TEST::ENSDF_ReadsCorrectNumberOfIsotopes_AssertTrue().

{
  return myNucleidIsotopeMap.size();
}
bool ENSDF::isEmptyString ( string  toCheck) [protected]

Checks if a string is empty or not.

Parameters:
toCheckThe string to check for empty-ness

Definition at line 188 of file ENSDF.cpp.

Referenced by splitInDataSets().

{
  for(unsigned int i = 0; i<toCheck.size(); i++)
    {
      if(toCheck.at(i)!=' ' && toCheck.at(i)!='\n')
        return false;
    }
  return true;
}
list< list< string > > ENSDF::splitInDataSets ( list< string >  allDatasets) [protected]

Takes all ENSDF information as input, and splits it Dataset's based on the End of dataset records.

Returns:
A list of lists of strings, where each inner list corresponds to a dataset.
Parameters:
allDatasetsThe ENSDF information to split in datasets. Each string in the list should be an 80 character ENSDF record.

Definition at line 157 of file ENSDF.cpp.

References isEmptyString().

Referenced by ENSDF().

{
  list< list<string> > toReturn;
  list<string> currentDataset;
  for(list<string>::iterator it = allDatasets.begin(); it!=allDatasets.end(); ++it)
    {
      if(isEmptyString(*it))
        {
          if(!currentDataset.empty())
            {
              toReturn.push_back(currentDataset);
              currentDataset.clear();
            }
        }
      else
        {
          currentDataset.push_back(*it);
        }
    }
  if(!currentDataset.empty())
    {
      toReturn.push_back(currentDataset);
      currentDataset.clear();
    }
  return toReturn;
}
void ENSDF::threadFlush ( vector< list< pair< Nukleid, list< list< string > > * > > >  toFlush) [protected]

Creates the working threads which creates all isotope objects, and waits for them to return.

Note:
This is usually the most slow part of the creation process (therefore the multi-threading).
Parameters:
toFlushThe information needed to create all Isotop objects.

Definition at line 81 of file ENSDF.cpp.

References loadIsotope(), myNucleidIsotopeMap, NULL, and VerbosePrinterEventEnabled::vPrint().

Referenced by ENSDF().

{
  list<pthread_t *> myThreads;
  list<pair<Nukleid, Isotop*> > myIsotopes;
  int iret1;
  for(vector<list< pair < Nukleid, list< list< string > > * > > >::iterator it = toFlush.begin(); it!=toFlush.end(); it++)
    {
      pthread_t * mySingleThread = new pthread_t();
      list< pair< Isotop**, list< list< string > > * > > * myP = 
        new list < pair < Isotop**, list< list< string > > * > >();

      for(list< pair < Nukleid, list< list< string> > * > >::iterator iq = it->begin(); iq!=it->end(); iq++)
        {
          myP->push_back(pair < Isotop**, list< list< string > > * > (&myNucleidIsotopeMap[iq->first], iq->second));
        }
      vPrint(7,"Creating worker thread...\n");
      iret1 = pthread_create( mySingleThread, NULL, loadIsotope, (void*)myP);
      if(iret1!=0)
        perror("ERROR creating thread.\n");
      
      myThreads.push_back(mySingleThread);
    }
  for(list<pthread_t *>::iterator it = myThreads.begin(); it!=myThreads.end(); it++)
    {
      vPrint(7,"Waiting for thread to finish.\n");
      pthread_join(**it, NULL);
      vPrint(7,"Thread finished.\n");
      delete *it;
      *it = NULL;
    }
  return;
}

The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Enumerations Enumerator Defines

Back to the main page of the Precalibrated Ion Beam Identification Detector project

Created by Rikard Lundmark