예제 #1
0
/**
 * Fill in dependency list for all MathExpns on reactions.
 * Note that when a MathExpn updates, it alters a further
 * molecule, that may be a substrate for another reaction.
 * So we need to also add further dependent reactions.
 * In principle we might also cascade to deeper MathExpns. Later.
 */
void Gsolve::fillMathDep()
{
	// create map of funcs that depend on specified molecule.
	vector< vector< unsigned int > > funcMap( stoichPtr_->getNumAllPools());
	unsigned int numFuncs = stoichPtr_->getNumFuncs();
	for ( unsigned int i = 0; i < numFuncs; ++i ) {
		const FuncTerm *f = stoichPtr_->funcs( i );
		vector< unsigned int > molIndex;
		unsigned int numMols = f->getReactants( molIndex );
		for ( unsigned int j = 0; j < numMols; ++j )
			funcMap[ molIndex[j] ].push_back( i );
	}
	// The output of each func is a mol indexed as 
	// numVarMols + numBufMols + i
	unsigned int funcOffset = 
			stoichPtr_->getNumVarPools() + stoichPtr_->getNumBufPools();
	unsigned int numRates = stoichPtr_->getNumRates();
	sys_.dependentMathExpn.resize( numRates );
	vector< unsigned int > indices;
	for ( unsigned int i = 0; i < numRates; ++i ) {
		vector< unsigned int >& dep = sys_.dependentMathExpn[ i ];
		dep.resize( 0 );
		// Extract the row of all molecules that depend on the reac.
		const int* entry;
		const unsigned int* colIndex;
		unsigned int numInRow = 
				sys_.transposeN.getRow( i, &entry, &colIndex );
		for ( unsigned int j = 0; j < numInRow; ++j ) {
			unsigned int molIndex = colIndex[j];
			vector< unsigned int >& funcs = funcMap[ molIndex ];
			dep.insert( dep.end(), funcs.begin(), funcs.end() );
			for ( unsigned int k = 0; k < funcs.size(); ++k ) {
				unsigned int outputMol = funcs[k] + funcOffset;
				// Insert reac deps here. Columns are reactions.
				vector< int > e; // Entries: we don't need.
				vector< unsigned int > c; // Column index: the reactions.
				stoichPtr_->getStoichiometryMatrix().
						getRow( outputMol, e, c );
				// Each of the reacs (col entries) depend on this func.
				vector< unsigned int > rdep = sys_.dependency[i];
				rdep.insert( rdep.end(), c.begin(), c.end() );
			}
		}
	}
}
예제 #2
0
파일: main.cpp 프로젝트: UnixJunkie/pharao
//*--------------------------------------------------------------------------*//
//* MAIN                                                                MAIN *//
//*--------------------------------------------------------------------------*//
int main(int argc, char* argv[])
{  
   // Initialise random number generator
	srandom(time(NULL));
	clock_t t0 = clock();
   
   // Print header
   printHeader();
	
	// Read options
   Options uo = parseCommandLine(argc,argv);
   if(!uo.noHybrid)
   {
      if(uo.funcGroupVec[AROM] && uo.funcGroupVec[LIPO])
      {
         uo.funcGroupVec[HYBL] = true;
      }
      if(uo.funcGroupVec[HDON] && uo.funcGroupVec[HACC])
      {
         uo.funcGroupVec[HYBH] = true;
      }
   }
   std::cerr << uo.print() << std::endl;
   
   if (uo.version)
   {
		printHeader();
		exit(0);
	}
   
	if (uo.help)
   {
		printUsage();
		exit(0);
	}
	
	// Db file and pharmacophore out are mandatory elements
	if (uo.dbInpFile.empty())
   {
		mainErr("Missing database file. This is a required option (-d).");
	}
   
	if (uo.pharmOutFile.empty() && uo.molOutFile.empty() && uo.scoreOutFile.empty())
   {
		mainErr("No output file defined. So there is actually no use to compute anything at all.");
	}	
   
	if ((uo.pharmOutFile.empty() && uo.scoreOutFile.empty()) && !uo.molOutFile.empty())
   {
		mainErr("No file defined to write pharmacophore information.");
	}	
	
	if (uo.refInpFile.empty() && uo.pharmOutFile.empty() && uo.molOutFile.empty() && !uo.scoreOutFile.empty())
   {
		mainErr("Only score file requested when no reference is given. Unable to generate this output.");
	}	
  
	// Reference variables
   Pharmacophore refPharm;
   refPharm.clear();
   std::string refId;
   double refVolume(0.0);
   int refSize(0);
	int exclSize(0);
  
	// Database variables
   std::vector<Result*> resList;
   Pharmacophore dbPharm;
   std::string dbId;
   double dbVolume(0.0);
   int dbSize(0);
  
   //----------------------------------------------------------------------------
	//...(A).. Process the reference
   //----------------------------------------------------------------------------
  
	if (!uo.refInpFile.empty())
	{
      //-------------------------------------------------------
      //...(1).. get reference pharmacophore
      //-------------------------------------------------------
    
      if (uo.refInpType == UNKNOWN)
      {
         std::string ext(getExt(uo.refInpFile));
         if (ext == ".phar")
         {
            uo.refInpType = PHAR;
         }
         else 
         {
            uo.refInpType = MOL;
         }
      }
		
      if (uo.refInpType == MOL)
      {
         OpenBabel::OBMol m;
         OpenBabel::OBConversion* reader = new OpenBabel::OBConversion();
         reader->SetInFormat(reader->FormatFromExt(uo.refInpFile.c_str()));
         if (!reader->Read(&m, uo.refInpStream))
         {
            mainErr("Unable to read reference molecule");
         }
         calcPharm(&m, &refPharm, uo);
         refId = m.GetTitle();
         delete reader;
         reader = NULL;
      }
      else if (uo.refInpType == PHAR)
      {
         PharmacophoreReader* reader = new PharmacophoreReader();
         refPharm = reader->read(uo.refInpStream, refId);
         if (refPharm.empty())
         {
            mainErr("Error reading reference pharmacophore");
         }
         delete reader;
         reader = NULL;
      }
      else
      {
         mainErr("Unknown format of reference molecule.");
      }
		
      //-------------------------------------------------------
		//...(2).. process reference pharmacophore
      //-------------------------------------------------------
		
      if (uo.merge)
      {
         pharMerger.merge(refPharm);
      }
    
      refSize = refPharm.size();
      for (unsigned int i(0); i < refSize; ++i)
		{
         if (refPharm[i].func == EXCL)
         {
				// extract overlap with exclusion spheres
				for (unsigned int j(0); j < refPharm.size(); ++j)
            {
					if (refPharm[j].func != EXCL)
               {
						refVolume -= VolumeOverlap(refPharm[i], refPharm[j], !uo.noNormal);
					}
				}
				exclSize++;
			}
         else
         {
				// add point self-overlap
				refVolume += VolumeOverlap(refPharm[i], refPharm[i], !uo.noNormal);
			}
      }
      
      if(!uo.isQuiet)
      {
         std::cerr << "Reference pharmacophore " << refId << std::endl;
         std::cerr << "   number of points:            " << refSize - exclSize << std::endl;
			std::cerr << "   number of exclusion spheres: " << exclSize << std::endl;
         std::cerr << "   totalvolume:                 " << refVolume << std::endl;
      }
	}

   //----------------------------------------------------------------------------
	//...(B).. Process the database file
   //----------------------------------------------------------------------------

   // DB files
   if (uo.dbInpType == UNKNOWN)
   {
      std::string ext(getExt(uo.dbInpFile));
      if (ext==".phar")
      {
         uo.dbInpType = PHAR;
      }
      else
      {
         uo.dbInpType = MOL;
      }
   }
	
	// local storage of the rotation matrix
	SiMath::Matrix rotMat(3,3,0.0);

   unsigned int molCount(0);
   
   OpenBabel::OBConversion* molReader = NULL;
	PharmacophoreReader* pharmReader = NULL;
   
   if (uo.dbInpType == PHAR)
   {
      pharmReader = new PharmacophoreReader();
   }
   else if (uo.dbInpType == MOL)
   {
      molReader = new OpenBabel::OBConversion();
      molReader->SetInFormat(molReader->FormatFromExt(uo.dbInpFile.c_str()));
      molReader->SetInStream(uo.dbInpStream);
   }
   else
   {
      mainErr("Unknown format of db file.");
   }

   bool done(false);
   OpenBabel::OBMol m;
   while (!done)
   {	
      dbPharm.clear();
      m.Clear();

      if (uo.dbInpType == MOL)
      {
         if (!molReader->Read(&m))
         {
            done = true;
            break;
         }
         else
         {
            calcPharm(&m, &dbPharm, uo);
            dbId = m.GetTitle();
         }
      }
      else
      {
         if (uo.dbInpStream->eof())
         {
            done = true;
            break;
         }
         else
         {
            dbPharm = pharmReader->read(uo.dbInpStream, dbId);
         }
      }
      if (dbPharm.empty())
      {
         continue;
      }

      ++molCount;
      if (!uo.isQuiet )
      {
         if ((molCount % 10) == 0)
         {
            std::cerr << "." << std::flush;
         }
         if ((molCount % 500) == 0)
         {
            std::cerr << molCount << std::endl << std::flush;
         }
      }

			
      if (uo.merge)
      {
         pharMerger.merge(dbPharm);
      }
      
      if (uo.refInpFile.empty())
      {
         if (!(uo.isQuiet))
         {
            printProgress(molCount);
         } 
         if( !uo.pharmOutFile.empty())
         {
            uo.pharmOutWriter->write(dbPharm, uo.pharmOutStream, dbId);
         }
         continue;
      }

      //-------------------------------------------------------
      //...(1).. Alignment
      //-------------------------------------------------------
      
      dbSize = dbPharm.size();
      dbVolume = 0.0;
      for (unsigned int i(0); i < dbSize; ++i) 
      {
         if (dbPharm[i].func == EXCL)
         {
            continue;
         }
         dbVolume += VolumeOverlap(dbPharm[i], dbPharm[i], !uo.noNormal);
      }
			
      // Create a result structure
      Result res;
      res.refId           = refId;
      res.refVolume       = refVolume;
      res.dbId            = dbId;
      res.dbVolume        = dbVolume;
      res.overlapVolume   = 0.0;
      res.exclVolume      = 0.0;
      res.resMol          = m;
      res.resPharSize     = 0;
			
      if (uo.scoreOnly)
      {
         FunctionMapping funcMap(&refPharm, &dbPharm, uo.epsilon);
         PharmacophoreMap fMap = funcMap.getNextMap();
         double volBest(-9999.999);
         
         // loop over all reference points
         while (!fMap.empty())
         {
            double newVol(0.0);
            double exclVol(0.0);
            for (PharmacophoreMap::iterator itP = fMap.begin(); itP != fMap.end(); ++itP) 
            {
               if ((itP->first)->func == EXCL)
               {
                  exclVol += VolumeOverlap((itP->first), (itP->second), !uo.noNormal);					
               }
               else if (((itP->first)->func == (itP->second)->func ) || 
                       (((itP->first)->func == HYBH || 
                         (itP->first)->func == HDON || 
                         (itP->first)->func == HACC) 
                     && ((itP->second)->func == HDON || 
                         (itP->second)->func == HACC ||
                         (itP->second)->func == HYBH))
                     || (((itP->first)->func == HYBL || 
                          (itP->first)->func == AROM || 
                          (itP->first)->func == LIPO)
                      && ((itP->second)->func == AROM || 
                          (itP->second)->func == LIPO || 
                          (itP->second)->func == HYBL)))
               {
                  newVol += VolumeOverlap((itP->first),(itP->second), !uo.noNormal);
               }
            }
					
            if ((newVol - exclVol) > volBest)
            {
               res.resPhar.clear();
               res.resPharSize = 0;
               for (PharmacophoreMap::iterator itP = fMap.begin(); itP != fMap.end(); ++itP) 
               {
                  // add point to resulting pharmacophore
                  PharmacophorePoint p(itP->second);
                  (res.resPhar).push_back(p);
                  ++res.resPharSize;
               }						
               res.overlapVolume = newVol;
               res.exclVolume = exclVol;
               volBest = newVol - exclVol;
            }
            // get the next map
            fMap.clear();
            fMap = funcMap.getNextMap();
         }
      }
      else
      {
         FunctionMapping funcMap(&refPharm, &dbPharm, uo.epsilon);
         PharmacophoreMap fMap = funcMap.getNextMap();
         PharmacophoreMap bestMap;
				
         // default solution
         SolutionInfo best;
         best.volume = -999.9;
         
         // rotor is set to no rotation 
         best.rotor.resize(4);
         best.rotor = 0.0;
         best.rotor[0] = 1.0;
				
         double bestScore = -1000;
         int mapSize(fMap.size());
         int maxSize = mapSize - 3;
				
         while (!fMap.empty())
         {
            int msize = fMap.size();
            
            // add the exclusion spheres to the alignment procedure
            if (uo.withExclusion)
            {
               for (unsigned int i(0); i < refSize ; ++i)
               {
                  if (refPharm[i].func != EXCL)
                  {
                     continue;
                  }
                  for (unsigned int j(0); j < dbSize; ++j)
                  {
                     if (dbPharm[j].func == EXCL)
                     {
                        continue;
                     }
                     fMap.insert(std::make_pair(&(refPharm[i]), &(dbPharm[j])));
                  }
               }
            }
					
            // Only align if the expected score has any chance of being larger 
            // than best score so far
            if ((msize > maxSize)
            && (((double) msize / (refSize - exclSize + dbSize - msize)) > bestScore))
            {
               Alignment align(fMap);
               SolutionInfo r = align.align(!uo.noNormal);

               if (best.volume < r.volume)
               {
                  best = r;
                  bestScore = best.volume / (refVolume + dbVolume - best.volume);
                  bestMap = fMap;
                  mapSize = msize;
               }
            }
            else
            {
               // Level of mapping site to low
               break;
            }
	
            if (bestScore > 0.98)
            {
               break;
            }
					
            // Get the next map
            fMap.clear();
            fMap = funcMap.getNextMap();
         }
				
         // Transform the complete pharmacophore and the molecule towards the 
         // best alignment
         rotMat = quat2Rotation(best.rotor);
         positionPharmacophore(dbPharm, rotMat, best);
         positionMolecule(&res.resMol, rotMat, best);
				
         // Update result
         res.info = best;

         // Compute overlap volume between exlusion spheres and pharmacophore 
         // points
         for (int i(0); i < refSize; ++i) 
         {
            if (refPharm[i].func != EXCL)
            {
               continue;
            }
            for (int j(0); j < dbSize; ++j)
            {
               res.exclVolume += VolumeOverlap(refPharm[i], dbPharm[j], !uo.noNormal);
            }
         }
				
         // make copy of the best map and compute the volume overlap
         for (PharmacophoreMap::iterator itP = bestMap.begin(); itP != bestMap.end(); ++itP) 
         {
            if(((itP->first)->func == EXCL) || ((itP->second)->func == EXCL))
            { 
               continue; 
            }
					
            // compute overlap
            res.overlapVolume += VolumeOverlap(itP->first, itP->second, !uo.noNormal);
					
            // add point to resulting pharmacophore
				PharmacophorePoint p(itP->second);
            (res.resPhar).push_back(p);
            ++res.resPharSize;
         }
      }
			
      // update scores
      res.info.volume = res.overlapVolume - res.exclVolume;
      if (res.info.volume > 0.0)
      {
         res.tanimoto = res.info.volume / (res.refVolume + res.dbVolume - res.info.volume);
         res.tversky_ref = res.info.volume / res.refVolume;
         res.tversky_db = res.info.volume / res.dbVolume;
      }

      switch (uo.rankby) 
      {
         case TANIMOTO:
            res.rankbyScore = res.tanimoto;
            break;
         case TVERSKY_REF:
            res.rankbyScore = res.tversky_ref;
            break;
         case TVERSKY_DB:
            res.rankbyScore = res.tversky_db;
            break;
      }

      //-------------------------------------------------------
      //...(5).. Generate output
      //-------------------------------------------------------
      if (uo.cutOff != 0.0)
      {
         if (res.rankbyScore < uo.cutOff)
         {
            continue;
         }
      }

      if (uo.best != 0)
      {
         addBest(res, uo, resList);
      }
      else 
      { 
         if (!uo.molOutFile.empty())
         { 
            logOut(&res, uo);
         }
         if (!uo.pharmOutFile.empty())
         {
            logPharmacophores(&res, uo);
         }
         if (!uo.scoreOutFile.empty())
         {
            logScores(&res, uo);
         }
      }
   }

   if (molReader)
   {
      delete molReader;
      molReader = NULL;
   }
   if (pharmReader)
   {
      delete pharmReader;
      pharmReader = NULL;
   }
  
   //----------------------------------------------------------------------------
   //...(C).. Process best list (if defined)
   //----------------------------------------------------------------------------

   if (uo.best != 0)
   {
      std::vector<Result*>::iterator itR;
      for (itR = resList.begin(); itR != resList.end(); ++itR) 
      {
         Result* res(*itR);
         if (!uo.molOutFile.empty())
         {
            logOut(res, uo);
         }
         if (!uo.pharmOutFile.empty())
         {
            logPharmacophores(res, uo);
         }
         if (!uo.scoreOutFile.empty())
         {
            logScores(res, uo);
         }
         delete res;
      }
   }

   // done processing database
   if (!uo.isQuiet)
   {
      if (uo.refInpFile.empty())
      {
         std::cerr << std::endl;
         std::cerr << "Processed " << molCount << " molecules";
         double tt = (double)(clock() - t0 )/CLOCKS_PER_SEC;
         std::cerr << " in " << tt << " seconds (";
         std::cerr << molCount/tt << " molecules per second)." << std::endl;
      }
      else
      {
         std::cerr << std::endl;
         std::cerr << "Processed " << molCount << " molecules" << std::endl;
         double tt = (double)(clock() - t0 )/CLOCKS_PER_SEC;
         std::cerr << molCount << " alignments in " << tt << " seconds (";
         std::cerr << molCount/tt << " alignments per second)." << std::endl;
      }
   }
	
   exit(0);

}