Ignore:
Timestamp:
Oct 9, 2008, 6:29:34 PM (17 years ago)
Author:
Frederik Heber <heber@…>
Children:
4959f1
Parents:
4a434c
git-author:
Frederik Heber <heber@…> (10/09/08 18:27:56)
git-committer:
Frederik Heber <heber@…> (10/09/08 18:29:34)
Message:

BUGFIXES: CyclicStructureAnalysis() now compatible to disconnected subgraphs, AssignKeySetsToFragment() and FillBondStructureFromReference() memory cleanup corrected

+ molecule::DepthFirstSearchAnalysis() now just returns BackEdgeStack, not MinimumRingSize. CyclicStructureAnalysis() is called during FragmentMolecule(), after subgraphs bonds list have been filled by FillBondStructureFromReference().
+ new function molecule::PickLocalBackEdges(), as the BackEdgeStack returned by DepthFirstSearchAnalysis() co
ntains only global bonds, not the local ones for the subgraph, we have to step through it and pick the right
ones out.
+ molecule::FragmentMolecule() now calls molecule::CyclicStructureAnalysis() separately for each subgraph, along with a BackEdgeStack filled by PickLocalBackEdges(), and allocates&initialises MinimumRingSize array. Als
o AssignKeySetsToFragment() frees the LocalListOfAtoms now (FreeList=true), now longer after the following wh
ile
+ molecule::CyclicStructureAnalysis() takes a local BackEdgeStack and analysis the subgraphs cycles, returnin
g minimum ring size
+ MoleculeLeafClass::AssignKeySetsToFragment() now frees memory for ListOfLocalAtoms when FreeList is set. BUGFIX: test of first key was testing against ..->nr != -1. However, LocalListOfAtoms was not even initialised correctly to NULL, hence ...->nr pointed in some cases to nowhere. Now it test atom* against NULL.
+ MoleculeLeafClass::FillBondStructureFromReference() now frees memory for ListOfLocalAtoms when FreeList is set correctly (only free initial pointer when FragmentCounter == 0, also it was decreased not before but after freeing, hence we free'd the wrong list). Also, father replaced by GetTrueFather() (makes the function moregenerally useable, was not a bug).
+ ParseCommandLineOptions() option 'D': adapted to changes in DepthFirstSearchAnalysis() in a similar manner
to FragmentMolecule()
+ molecule::CountCyclicBonds() adapted but does not perform CyclicStructureAnalysis()
+ molecule::CreateAdjacencyList() counts the bonds that could not be brought to covalently corrected degree (i.e. the remaining ionic atoms)
+ molecule::CreateListOfBondsPerAtom() prints atom names and number, which is helpful as name contains global

and number contains local number (helped in finding above bugs)

+ CreateFatherLookupTable(): BUGFIX: LookupTable was not initialised to NULL (see above)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/molecules.cpp

    r4a434c r1bd619  
    20812081  int *MinimumRingSize = NULL;
    20822082  MoleculeLeafClass *Subgraphs = NULL;
     2083  class StackClass<bond *> *BackEdgeStack = NULL;
    20832084  bond *Binder = first;
    20842085  if ((Binder->next != last) && (Binder->next->Type == Undetermined)) {
    20852086    *out << Verbose(0) << "No Depth-First-Search analysis performed so far, calling ..." << endl;
    2086     Subgraphs = DepthFirstSearchAnalysis(out, MinimumRingSize);
     2087    Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    20872088    while (Subgraphs->next != NULL) {
    20882089      Subgraphs = Subgraphs->next;
     
    20972098      No++;   
    20982099  }
     2100  delete(BackEdgeStack);
    20992101  return No;
    21002102};
     
    21782180  double *matrix = ReturnFullMatrixforSymmetric(cell_size);
    21792181  Vector x;
     2182  int FalseBondDegree = 0;
    21802183 
    21812184  BondDistance = bonddistance; // * ((IsAngstroem) ? 1. : 1./AtomicLengthToAngstroem);
     
    21962199      j += i+1;
    21972200      divisor[i] = (int)floor(cell_size[j]/bonddistance); // take smaller value such that size of linked cell is at least bonddistance
    2198       *out << Verbose(1) << "divisor[" << i << "]  = " << divisor[i] << "." << endl;
     2201      //*out << Verbose(1) << "divisor[" << i << "]  = " << divisor[i] << "." << endl;
    21992202    }
    22002203    // 2a. allocate memory for the cell list
     
    22212224      }
    22222225      index = n[2] + (n[1] + n[0] * divisor[1]) * divisor[2];
    2223       *out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
     2226      //*out << Verbose(1) << "Atom " << *Walker << " goes into cell number [" << n[0] << "," << n[1] << "," << n[2] << "] = " << index << "." << endl;
    22242227      // add copy atom to this cell
    22252228      if (CellList[index] == NULL)  // allocate molecule if not done
     
    22632266                        distance =   OtherWalker->x.PeriodicDistance(&(Walker->x), cell_size);
    22642267                        if ((OtherWalker->father->nr > Walker->father->nr) && (distance <= MaxDistance*MaxDistance) && (distance >= MinDistance*MinDistance)) { // create bond if distance is smaller
    2265                           *out << Verbose(0) << "Adding Bond between " << *Walker << " and " << *OtherWalker << "." << endl;
     2268                          //*out << Verbose(0) << "Adding Bond between " << *Walker << " and " << *OtherWalker << "." << endl;
    22662269                          AddBond(Walker->father, OtherWalker->father, 1);  // also increases molecule::BondCount
    22672270                          BondCount++;
     
    23222325              ListOfBondsPerAtom[Walker->nr][CandidateBondNo]->BondDegree++;
    23232326              *out << Verbose(2) << "Increased bond degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
    2324             }
     2327            } else
     2328              *out << Verbose(2) << "Could not find correct degree for bond " << *ListOfBondsPerAtom[Walker->nr][CandidateBondNo] << "." << endl;
     2329              FalseBondDegree++;
    23252330          }
    23262331                    }
     
    23292334                } else
    23302335                        *out << Verbose(1) << "BondCount is " << BondCount << ", no bonds between any of the " << AtomCount << " atoms." << endl;
    2331           *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << "." << endl;
     2336          *out << Verbose(1) << "I detected " << BondCount << " bonds in the molecule with distance " << bonddistance << ", " << FalseBondDegree << " bonds could not be corrected." << endl;
    23322337               
    23332338          // output bonds for debugging (if bond chain list was correctly installed)
     
    23502355 * We use the algorithm from [Even, Graph Algorithms, p.62].
    23512356 * \param *out output stream for debugging
    2352  * \param *&MinimumRingSize contains smallest ring size in molecular structure on return or -1 if no rings were found
     2357 * \param *&BackEdgeStack NULL pointer to StackClass with all the found back edges, allocated and filled on return
    23532358 * \return list of each disconnected subgraph as an individual molecule class structure
    23542359 */
    2355 MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, int *&MinimumRingSize)
    2356 {
    2357   class StackClass<atom *> *AtomStack;
    2358   AtomStack = new StackClass<atom *>(AtomCount);
    2359   class StackClass<bond *> *BackEdgeStack = new StackClass<bond *> (BondCount);
     2360MoleculeLeafClass * molecule::DepthFirstSearchAnalysis(ofstream *out, class StackClass<bond *> *&BackEdgeStack)
     2361{
     2362  class StackClass<atom *> *AtomStack = new StackClass<atom *>(AtomCount);
     2363  BackEdgeStack = new StackClass<bond *> (BondCount);
    23602364  MoleculeLeafClass *SubGraphs = new MoleculeLeafClass(NULL);
    23612365  MoleculeLeafClass *LeafWalker = SubGraphs;
     
    24892493    LeafWalker->Leaf->Output(out);
    24902494    *out << endl;
    2491    
     2495
    24922496    // step on to next root
    24932497    while ((Root != end) && (Root->GraphNr != -1)) {
     
    25072511  }
    25082512
    2509   // analysis of the cycles (print rings, get minimum cycle length)
    2510   CyclicStructureAnalysis(out, BackEdgeStack, MinimumRingSize);
    25112513
    25122514  *out << Verbose(1) << "Final graph info for each atom is:" << endl;
     
    25462548 * as cyclic and print out the cycles.
    25472549 * \param *out output stream for debugging
    2548  * \param *BackEdgeStack stack with all back edges found during DFS scan
     2550 * \param *BackEdgeStack stack with all back edges found during DFS scan. Beware: This stack contains the bonds from the total molecule, not from the subgraph!
    25492551 * \param *&MinimumRingSize contains smallest ring size in molecular structure on return or -1 if no rings were found, if set is maximum search distance
    25502552 * \todo BFS from the not-same-LP to find back to starting point of tributary cycle over more than one bond
     
    25672569    ColorList[i] = white;
    25682570  }
    2569   MinimumRingSize = new int[AtomCount];
    2570   for(int i=AtomCount;i--;)
    2571     MinimumRingSize[i] = AtomCount;
    2572 
    25732571 
    25742572  *out << Verbose(1) << "Back edge list - ";
     
    33723370        MoleculeListClass *BondFragments = NULL;
    33733371  int *SortIndex = NULL;
    3374   int *MinimumRingSize = NULL;
     3372  int *MinimumRingSize = new int[AtomCount];
    33753373  int FragmentCounter;
    33763374  MoleculeLeafClass *MolecularWalker = NULL;
     
    33783376  fstream File;
    33793377  bool FragmentationToDo = true;
     3378  class StackClass<bond *> *BackEdgeStack = NULL, *LocalBackEdgeStack = NULL;
    33803379  bool CheckOrder = false;
    33813380  Graph **FragmentList = NULL;
     
    34093408
    34103409  // ===== 2. perform a DFS analysis to gather info on cyclic structure and a list of disconnected subgraphs =====
    3411   Subgraphs = DepthFirstSearchAnalysis(out, MinimumRingSize);
     3410  Subgraphs = DepthFirstSearchAnalysis(out, BackEdgeStack);
    34123411  // fill the bond structure of the individually stored subgraphs
    34133412  Subgraphs->next->FillBondStructureFromReference(out, this, (FragmentCounter = 0), ListOfLocalAtoms, false);  // we want to keep the created ListOfLocalAtoms
    3414 
     3413  // analysis of the cycles (print rings, get minimum cycle length) for each subgraph
     3414  for(int i=AtomCount;i--;)
     3415    MinimumRingSize[i] = AtomCount;
     3416  MolecularWalker = Subgraphs;
     3417  FragmentCounter = 0;
     3418  while (MolecularWalker->next != NULL) {
     3419    MolecularWalker = MolecularWalker->next;
     3420    *out << Verbose(0) << "Analysing the cycles of subgraph " << MolecularWalker->Leaf << " with nr. " << FragmentCounter << "." << endl;
     3421    LocalBackEdgeStack = new StackClass<bond *> (MolecularWalker->Leaf->BondCount);
     3422//    // check the list of local atoms for debugging
     3423//    *out << Verbose(0) << "ListOfLocalAtoms for this subgraph is:" << endl;
     3424//    for (int i=0;i<AtomCount;i++)
     3425//      if (ListOfLocalAtoms[FragmentCounter][i] == NULL)
     3426//        *out << "\tNULL";
     3427//      else
     3428//        *out << "\t" << ListOfLocalAtoms[FragmentCounter][i]->Name;
     3429    MolecularWalker->Leaf->PickLocalBackEdges(out, ListOfLocalAtoms[FragmentCounter++], BackEdgeStack, LocalBackEdgeStack);
     3430    MolecularWalker->Leaf->CyclicStructureAnalysis(out, LocalBackEdgeStack, MinimumRingSize);
     3431    delete(LocalBackEdgeStack);
     3432  }
     3433 
    34153434  // ===== 3. if structure still valid, parse key set file and others =====
    34163435  FragmentationToDo = FragmentationToDo && ParseKeySetFile(out, configuration->configpath, ParsedFragmentList);
     
    34213440  // =================================== Begin of FRAGMENTATION ===============================
    34223441  // ===== 6a. assign each keyset to its respective subgraph =====
    3423   Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), false);
     3442  Subgraphs->next->AssignKeySetsToFragment(out, this, ParsedFragmentList, ListOfLocalAtoms, FragmentList, (FragmentCounter = 0), true);
    34243443
    34253444  // ===== 6b. prepare and go into the adaptive (Order<0), single-step (Order==0) or incremental (Order>0) cycle
     
    34583477  delete[](MinimumRingSize);
    34593478 
    3460   // free the index lookup list
    3461   for (int i=FragmentCounter;i--;)
    3462     Free((void **)&ListOfLocalAtoms[i], "molecule::FragmentMolecule - *ListOfLocalAtoms[]");
    3463   Free((void **)&ListOfLocalAtoms, "molecule::FragmentMolecule - **ListOfLocalAtoms");
    34643479
    34653480  // ==================================== End of FRAGMENTATION ============================================
     
    35353550};
    35363551
     3552
     3553/** Picks from a global stack with all back edges the ones in the fragment.
     3554 * \param *out output stream for debugging
     3555 * \param **ListOfLocalAtoms array of father atom::nr to local atom::nr (reverse of atom::father)
     3556 * \param *ReferenceStack stack with all the back egdes
     3557 * \param *LocalStack stack to be filled
     3558 * \return true - everything ok, false - ReferenceStack was empty
     3559 */
     3560bool molecule::PickLocalBackEdges(ofstream *out, atom **ListOfLocalAtoms, class StackClass<bond *> *&ReferenceStack, class StackClass<bond *> *&LocalStack)
     3561{
     3562  bool status = true;
     3563  if (ReferenceStack->IsEmpty()) {
     3564    cerr << "ReferenceStack is empty!" << endl;
     3565    return false;
     3566  }
     3567  bond *Binder = ReferenceStack->PopFirst();
     3568  bond *FirstBond = Binder;   // mark the first bond, so that we don't loop through the stack indefinitely
     3569  atom *Walker = NULL, *OtherAtom = NULL;
     3570  ReferenceStack->Push(Binder);
     3571 
     3572  do {  // go through all bonds and push local ones
     3573    Walker = ListOfLocalAtoms[Binder->leftatom->nr];  // get one atom in the reference molecule
     3574    if (Walker == NULL) // if this Walker exists in the subgraph ...
     3575      continue;
     3576    for(int i=0;i<NumberOfBondsPerAtom[Walker->nr];i++) {    // go through the local list of bonds
     3577      OtherAtom = ListOfBondsPerAtom[Walker->nr][i]->GetOtherAtom(Walker);
     3578      if (OtherAtom == ListOfLocalAtoms[Binder->rightatom->nr]) { // found the bond
     3579        LocalStack->Push(ListOfBondsPerAtom[Walker->nr][i]);
     3580        break;
     3581      }
     3582    }
     3583    Binder = ReferenceStack->PopFirst();  // loop the stack for next item
     3584    ReferenceStack->Push(Binder);
     3585  } while (FirstBond != Binder);
     3586 
     3587  return status;
     3588};
     3589
    35373590/** Stores pairs (Atom::nr, Atom::AdaptiveOrder) into file.
    35383591 * Atoms not present in the file get "-1".
     
    36773730  while (Walker->next != end) {
    36783731    Walker = Walker->next;
    3679     *out << Verbose(4) << "Atom " << Walker->Name << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
     3732    *out << Verbose(4) << "Atom " << Walker->Name << "/" << Walker->nr << " with " << NumberOfBondsPerAtom[Walker->nr] << " bonds: ";
    36803733    TotalDegree = 0;
    36813734    for (int j=0;j<NumberOfBondsPerAtom[Walker->nr];j++) {
Note: See TracChangeset for help on using the changeset viewer.