ENSDF++ 1.1
An easy, fast and simple way to run querys towards the ENSDF database, written in C++.
ENSDF.cpp
Go to the documentation of this file.
00001 #include "ENSDF.h"
00002 
00003 /* Creates the ENSDF object. 
00004  * Arguments: vector<string> filenames, the filenames that contains the ENSDF database.
00005  */
00006 ENSDF::ENSDF(vector<string> filenames, VerbosePrinter * toRegister, unsigned int numberOfThreads)
00007 {
00008   registerListener(toRegister);
00009   vPrint(3, "Loading ENSDF files.\n");
00010   list<string> myIsotopes;
00011   for(vector<string>::iterator it = filenames.begin(); it < filenames.end(); it++)
00012     {
00013       vPrint(6,"Now loading file: \"%s\" into memory\n",it->c_str());
00014       FILE * myFile;
00015       myFile = fopen ((*it).c_str() , "r");
00016       char line[100];
00017       
00018       if(myFile==NULL)
00019         perror("The opened file is null");
00020       
00021       while (fgets(line, 100, myFile) != NULL) 
00022         {
00023           string myString(line);
00024           myIsotopes.push_back(myString);
00025         }
00026       if(myFile!=NULL)
00027         fclose(myFile);
00028     }
00029   list< list<string> > allDatasets = splitInDataSets(myIsotopes); //contains all datasets, one entry for each dataset.
00030   
00031   map< Nukleid, list< list<string> > > datasetsSortedByIsotope; //the outer list contains one entry for each isotope. Now fill this...
00032 
00033   vPrint(3,"Identifying isotopes for each dataset.\n");
00034   for(list< list<string> >::iterator myIterator = allDatasets.begin(); myIterator!=allDatasets.end(); myIterator++)
00035     {
00036       Nukleid * myNucleid = NULL;
00037       list<string>::iterator subIterator = myIterator->begin();
00038       while(myNucleid == NULL && subIterator != myIterator->end())
00039         {
00040           myNucleid = getNucleidFromString(*subIterator);
00041           subIterator++;
00042         }
00043       if(myNucleid==NULL) //if this occurs, we cannot obtain any more information...
00044         {
00045           throw DataFileException("Error parsing data file: SubIterator went out of bounds");
00046         }
00047       datasetsSortedByIsotope[Nukleid(*myNucleid)].push_back(*myIterator);
00048       delete myNucleid;
00049     }
00050   allDatasets = list< list<string> >();
00051   vPrint(3, "Creating isotope objects\n");
00052   int iter = 0;
00053   vector<list<pair<Nukleid, list<list<string> > * > > > toFlush;
00054   for(unsigned int i = 0; i<numberOfThreads; i++)
00055     {
00056       toFlush.push_back(list< pair < Nukleid, list< list< string > > * > >());
00057     }
00058   int flushAdress = 0;
00059   for(map<Nukleid, list< list<string> > >::iterator myIterator = datasetsSortedByIsotope.begin(); myIterator!=datasetsSortedByIsotope.end(); myIterator++)
00060     {
00061       Nukleid myNukleid = myIterator->first;
00062       vPrint(12,"Preparing to create isotope object for nucleid %s (%d of %d).\n",myNukleid.toString().c_str(), ++iter, datasetsSortedByIsotope.size());
00063       toFlush[(flushAdress++)%numberOfThreads].push_back(make_pair(myNukleid, &(myIterator->second)));
00064     }
00065   threadFlush(toFlush);
00066   //to free memory.
00067   datasetsSortedByIsotope=map<Nukleid,list< list<string> > >();
00068   vPrint(3,"Done creating ENSDF object\n");
00069   return;
00070 }
00071 
00072 ENSDF::~ENSDF()
00073 {
00074   for(map<Nukleid, Isotop* >::iterator it = myNucleidIsotopeMap.begin(); it!=myNucleidIsotopeMap.end(); it++)
00075     {
00076       delete it->second;
00077       it->second = NULL;
00078     }
00079 }
00080 
00081 void ENSDF::threadFlush(vector<list<pair<Nukleid, list<list<string> > *> > > toFlush)
00082 {
00083   list<pthread_t *> myThreads;
00084   list<pair<Nukleid, Isotop*> > myIsotopes;
00085   int iret1;
00086   for(vector<list< pair < Nukleid, list< list< string > > * > > >::iterator it = toFlush.begin(); it!=toFlush.end(); it++)
00087     {
00088       pthread_t * mySingleThread = new pthread_t();
00089       list< pair< Isotop**, list< list< string > > * > > * myP = 
00090         new list < pair < Isotop**, list< list< string > > * > >();
00091 
00092       for(list< pair < Nukleid, list< list< string> > * > >::iterator iq = it->begin(); iq!=it->end(); iq++)
00093         {
00094           myP->push_back(pair < Isotop**, list< list< string > > * > (&myNucleidIsotopeMap[iq->first], iq->second));
00095         }
00096       vPrint(7,"Creating worker thread...\n");
00097       iret1 = pthread_create( mySingleThread, NULL, loadIsotope, (void*)myP);
00098       if(iret1!=0)
00099         perror("ERROR creating thread.\n");
00100       
00101       myThreads.push_back(mySingleThread);
00102     }
00103   for(list<pthread_t *>::iterator it = myThreads.begin(); it!=myThreads.end(); it++)
00104     {
00105       vPrint(7,"Waiting for thread to finish.\n");
00106       pthread_join(**it, NULL);
00107       vPrint(7,"Thread finished.\n");
00108       delete *it;
00109       *it = NULL;
00110     }
00111   return;
00112 }
00113 
00114 
00115 void * loadIsotope(void * ptr)
00116 {
00117   list< pair<Isotop**, list<list<string> >* > > * toCreateFrom
00118     = (list< pair<Isotop**, list<list<string> >* > > * ) ptr; 
00119   for(list<pair<Isotop**, list< list< string> >* > >::iterator it = toCreateFrom->begin(); it!=toCreateFrom->end(); it++)
00120     *(it->first)= new Isotop(*(it->second));
00121   delete toCreateFrom;
00122   ptr = NULL;
00123   toCreateFrom = NULL;
00124   return (void*)NULL; //quick and dirty
00125 }
00126 
00127 
00128 /* Returns a specific isotope, if we are asked for it.
00129  * Arguments: a nucleid object describing the isotope we want to get.
00130  * Returns: an isotope object with the ENSDF datasets concerning this nucleid.
00131  */
00132 const Isotop * ENSDF::getIsotop(const Nukleid nucleidToGet) const
00133 {
00134   if(myNucleidIsotopeMap.find(nucleidToGet)!=myNucleidIsotopeMap.end())
00135     return myNucleidIsotopeMap.find(nucleidToGet)->second;
00136   else
00137     return NULL;
00138 }
00139 
00140 /* Returns the total number of isotops stored.
00141  */
00142 int ENSDF::getNumberOfIsotops() const
00143 {
00144   return myNucleidIsotopeMap.size();
00145 }
00146 
00147 const map< Nukleid, Isotop*> ENSDF::getAllIsotopes() const
00148 {
00149   return myNucleidIsotopeMap;
00150 }
00151 
00152 
00153 /* Returns a list containing the data sets found in the input list.
00154  * Arguments: A list containing all the data sets found in the ENSDF, with a blank line between data sets.
00155  * Returns: a list containing all the data sets found in the input list.
00156  */
00157 list< list<string> > ENSDF::splitInDataSets(list<string> allDatasets)
00158 {
00159   list< list<string> > toReturn;
00160   list<string> currentDataset;
00161   for(list<string>::iterator it = allDatasets.begin(); it!=allDatasets.end(); ++it)
00162     {
00163       if(isEmptyString(*it))
00164         {
00165           if(!currentDataset.empty())
00166             {
00167               toReturn.push_back(currentDataset);
00168               currentDataset.clear();
00169             }
00170         }
00171       else
00172         {
00173           currentDataset.push_back(*it);
00174         }
00175     }
00176   if(!currentDataset.empty())
00177     {
00178       toReturn.push_back(currentDataset);
00179       currentDataset.clear();
00180     }
00181   return toReturn;
00182 }
00183 
00184 /* Checks if a string is empty
00185  * Arguments: the string to check for emptiness.
00186  * Returns: true if the string to check only contains ' ' and '\n'
00187  */
00188 bool ENSDF::isEmptyString(string toCheck)
00189 {
00190   for(unsigned int i = 0; i<toCheck.size(); i++)
00191     {
00192       if(toCheck.at(i)!=' ' && toCheck.at(i)!='\n')
00193         return false;
00194     }
00195   return true;
00196 }
00197 
00198 /* Returns an isotope object corresponding to a 80 character long ENSDF entry string.
00199  * Arguments: the string to create the isotope object from
00200  * Returns: The isotope object corresponding to the argument, or NULL if the argument string was invalid.
00201  */
00202 Nukleid * ENSDF::getNucleidFromString(string stringToGetIsotopeFrom)
00203 {
00204   try
00205     {
00206       Nukleid * myNukleid = new Nukleid(stringToGetIsotopeFrom.substr(0,5));
00207       return myNukleid;
00208     }
00209   catch(exception &e)
00210     {
00211       return NULL;
00212     }
00213 }
 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