![]() |
ENSDF++ 1.1
An easy, fast and simple way to run querys towards the ENSDF database, written in C++.
|
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 }