BALL  1.4.1
assignBondOrderProcessor.h
Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 
00005 #ifndef BALL_STRUCTURE_ASSIGNBONDORDERPROCESSOR_H
00006 #define BALL_STRUCTURE_ASSIGNBONDORDERPROCESSOR_H
00007 
00008 #ifndef BALL_CONCEPT_PROCESSOR_H
00009   #include <BALL/CONCEPT/processor.h>
00010 #endif
00011 
00012 #ifndef BALL_KERNEL_ATOMCONTAINER_H
00013   #include <BALL/KERNEL/atomContainer.h>
00014 #endif
00015 
00016 #ifndef BALL_DATATYPE_HASHMAP_H
00017   #include <BALL/DATATYPE/hashMap.h>
00018 #endif
00019 
00020 #ifndef BALL_DATATYPE_HASHSET_H
00021   #include <BALL/DATATYPE/hashSet.h>
00022 #endif
00023 
00024 #ifndef BALL_KERNEL_BOND_H
00025   #include <BALL/KERNEL/bond.h>
00026 #endif
00027 
00028 #ifndef BALL_DATATYPE_OPTIONS_H
00029 # include <BALL/DATATYPE/options.h>
00030 #endif
00031 
00032 #ifndef BALL_COMMON_LIMITS_H
00033 # include <BALL/COMMON/limits.h>
00034 #endif
00035 
00036 #ifndef BALL_COMMON_EXCEPTION_H
00037 # include <BALL/COMMON/exception.h>
00038 #endif
00039 
00040 #ifndef BALL_SYSTEM_TIMER_H
00041 # include <BALL/SYSTEM/timer.h>
00042 #endif
00043 
00044 #ifndef BALL_STRUCTURE_BONDORDERS_BONDORDERASSIGNMENTSTRATEGY_H
00045 # include <BALL/STRUCTURE/BONDORDERS/bondOrderAssignmentStrategy.h>
00046 #endif
00047 
00048 #ifndef BALL_STRUCTURE_BONDORDERS_BONDORDERASSIGNMENT_H
00049 # include <BALL/STRUCTURE/BONDORDERS/bondOrderAssignment.h>
00050 #endif
00051 
00052 #ifndef BALL_STRUCTURE_BONDORDERS_PARTIALBONDORDERASSIGNMENT_H
00053 # include <BALL/STRUCTURE/BONDORDERS/partialBondOrderAssignment.h>
00054 #endif
00055 
00056 #include <map>
00057 #include <vector>
00058 
00059 namespace BALL
00060 {
00092   class BALL_EXPORT AssignBondOrderProcessor
00093     : public UnaryProcessor<AtomContainer>
00094   {
00095     protected:
00096       friend class PartialBondOrderAssignment;
00097       friend class BondOrderAssignment;
00098 
00099       class PQ_Entry_;
00100       friend class PQ_Entry_;
00101 
00102       friend class BondOrderAssignmentStrategy;
00103 
00104       friend class AStarBondOrderStrategy;
00105       friend class BranchAndBoundBondOrderStrategy;
00106       friend class FPTBondOrderStrategy;
00107       friend class ILPBondOrderStrategy;
00108       friend class KGreedyBondOrderStrategy;
00109 
00110     public:
00111 
00115 
00116       struct BALL_EXPORT Option
00117       {
00121         static const char* OVERWRITE_SINGLE_BOND_ORDERS;
00122 
00127         static const char* OVERWRITE_DOUBLE_BOND_ORDERS;
00128 
00133         static const char* OVERWRITE_TRIPLE_BOND_ORDERS;
00134 
00144         static const char* OVERWRITE_SELECTED_BONDS;
00145 
00150         static const char* ADD_HYDROGENS;             //TODO
00151 
00156         static const char* COMPUTE_ALSO_CONNECTIVITY; //TODO
00157 
00162         static const char* CONNECTIVITY_CUTOFF;       //TODO 
00163 
00166         static const char* USE_FINE_PENALTY;
00167 
00170         static const char* KEKULIZE_RINGS;
00171 
00174         static const char* ALGORITHM;
00175 
00178         static const char* INIFile;
00179 
00182         static const char* MAX_BOND_ORDER;
00183 
00190         static const char* MAX_NUMBER_OF_SOLUTIONS;
00191 
00197         static const char* COMPUTE_ALSO_NON_OPTIMAL_SOLUTIONS;
00198 
00204         static const char* BOND_LENGTH_WEIGHTING;
00205 
00210         static const char* APPLY_FIRST_SOLUTION;
00211 
00212       };
00213 
00215       struct BALL_EXPORT Default
00216       {
00217         static const bool OVERWRITE_SINGLE_BOND_ORDERS;
00218         static const bool OVERWRITE_DOUBLE_BOND_ORDERS;
00219         static const bool OVERWRITE_TRIPLE_BOND_ORDERS;
00220         static const bool OVERWRITE_SELECTED_BONDS;
00221         static const bool ADD_HYDROGENS;
00222         static const bool COMPUTE_ALSO_CONNECTIVITY;
00223         static const float CONNECTIVITY_CUTOFF;
00224         static const bool USE_FINE_PENALTY;
00225         static const bool KEKULIZE_RINGS;
00226         static const String ALGORITHM;
00227         static const String INIFile;
00228         static const int MAX_BOND_ORDER;
00229         static const int MAX_NUMBER_OF_SOLUTIONS;
00230         static const bool COMPUTE_ALSO_NON_OPTIMAL_SOLUTIONS;
00231         static const float BOND_LENGTH_WEIGHTING;
00232         static const bool APPLY_FIRST_SOLUTION;
00233       };
00234 
00235       struct BALL_EXPORT Algorithm
00236       {
00240         static const String A_STAR;
00241 
00252         static const String ILP;
00253 
00279         static const String FPT;
00280 
00281         static const String K_GREEDY;
00282         static const String BRANCH_AND_BOUND;
00283       };
00284 
00286 
00290 
00292       AssignBondOrderProcessor();
00293 
00294       // constructor with parameter filename //TODO
00295       //AssignBondOrderProcessor(const String& file_name) throw(Exception::FileNotFound);
00296 
00298       virtual ~AssignBondOrderProcessor();
00300 
00304 
00306       virtual bool start();
00307 
00313       void clear();
00314 
00328       virtual Processor::Result operator ()(AtomContainer& ac);
00329 
00331       virtual bool finish();
00332 
00334 
00338 
00347       Size getNumberOfAddedHydrogens(Position i)
00348       {
00349         if (i >= solutions_.size())
00350         {
00351           Log.error() << "AssignBondOrderProcessor: No solution with index " << i << std::endl;
00352           return 0;
00353         }
00354         int num_hydrogens = 0;
00355 
00356         HashMap<Atom*, int>::Iterator it = solutions_[i].number_of_virtual_hydrogens.begin();
00357         for (; it != solutions_[i].number_of_virtual_hydrogens.end(); it++)
00358           num_hydrogens += it->second;
00359         return num_hydrogens;
00360       }
00361 
00371       Size getNumberOfComputedSolutions() {return solutions_.size();}
00372 
00373 
00376       AtomContainer* getAtomContainer() {return ac_;}
00377 
00380       AtomContainer const* getAtomContainer() const {return ac_;}
00381 
00390       const System& getSolution(Position i) throw(Exception::IndexOverflow);
00391 
00399       float getTotalCharge(Position i)
00400       {
00401         if (i >= solutions_.size())
00402         {
00403           Log.error() << "AssignBondOrderProcessor: No solution with index " << i << std::endl;
00404 
00405           return Limits<float>::max();
00406         }
00407         else
00408         {
00409           return getTotalCharge_(solutions_[i]);
00410         }
00411       }
00412 
00418       float getTotalPenalty(Position i=0)
00419       {
00420         if (i >= solutions_.size())
00421         {
00422           Log.error() << "AssignBondOrderProcessor: No solution with index " << i << std::endl;
00423 
00424           return Limits<float>::max();
00425         }
00426         else
00427           return getTotalPenalty_(solutions_[i]);
00428       }
00429 
00430       /* Returns the number of node expansions before solution i was found.
00431        *
00432        * param    i  index of the solution, whose number of node expansions should be returned.
00433        * return  int -   number of node expansions before solution i was found.   
00434        */
00435       int getNumberOfNodeExpansions(Position i)
00436       {
00437         if (i >= solutions_.size())
00438         {
00439           Log.error() << "AssignBondOrderProcessor: No solution with index " << i << std::endl;
00440 
00441           return -1;
00442         }
00443         else
00444           return getNumberOfNodeExpansions_(solutions_[i]);
00445       }
00446 
00447       /* Returns the number of node expansions before solution i was found.
00448        *
00449        * param    i  index of the solution, whose  queue size should be returned. 
00450        * return  int -  queue size when solution i was found.  
00451        */
00452       int getQueueSize(Position i)
00453       {
00454         if (i >= solutions_.size())
00455         {
00456           Log.error() << "AssignBondOrderProcessor: No solution with index " << i << std::endl;
00457 
00458           return -1;
00459         }
00460         else
00461           return getQueueSize_(solutions_[i]);
00462       }
00463 
00476       bool apply(Position i);
00477 
00483       void resetBondOrders();
00484 
00492       bool computeNextSolution(bool apply_solution = true);
00493 
00496       void setDefaultOptions();
00497 
00500       bool hasValidOptions(){return readOptions_();}
00501 
00508       float evaluatePenalty(AtomContainer* ac);
00510 
00514 
00515       Options options;
00516 
00518 
00519     protected:
00520 
00526       bool readOptions_();
00527 
00528 
00533       bool readAtomPenalties_() throw(Exception::FileNotFound());
00534 
00543       bool preassignPenaltyClasses_();
00544 
00551       int getPenaltyClass_(Atom* atom);
00552 
00553 
00569       bool precomputeBondLengthPenalties_();
00570 
00582       float computeVirtualHydrogens_(Atom* atom);
00583 
00586       //TODO: move to solution!
00587       bool apply_(BondOrderAssignment& solution);
00588 
00591       void storeOriginalConfiguration_();
00592 
00593       /* Returns the queue's size at the moment the given solution was found.
00594        *
00595        * param   sol  solution, whose queue size should be returned. 
00596        * return  int -  queue size when the given solution was found.  
00597        */
00598       int getQueueSize_(const BondOrderAssignment& sol){return sol.getQueueSize();}
00599 
00606       float getTotalCharge_(const BondOrderAssignment& sol)
00607       {
00608         if (sol.valid)
00609         {
00610           return sol.total_charge;
00611         }
00612         else
00613         {
00614           return 0;
00615         }
00616       }
00617 
00624       float getTotalPenalty_(const BondOrderAssignment& sol)
00625       {
00626         return sol.coarsePenalty();
00627       }
00628 
00629       /* Returns the number of node expansions before the given solution was found.
00630        *
00631        * param   sol  solution, whose number of node expansions should be returned. 
00632        * return  int -  number of node expansions before solution i was found.  
00633        */
00634       int getNumberOfNodeExpansions_(const BondOrderAssignment& sol){return sol.getNumberOfNodeExpansions();}
00635 
00637       bool valid_;
00638 
00640       bool evaluation_mode_;
00641 
00642       // Map for storing the bonds fixed orders
00643       // if a bond is free, the map returns 0
00644       std::map<Bond*, short> bond_fixed_;
00645 
00646       // all free bonds in the atom container
00647       std::vector<Bond*> free_bonds_;
00648 
00649       // Map for storing the bonds associated index (all bonds)
00650       HashMap<Bond*, Index> bond_to_index_;
00651 
00652       // Vector for mapping from variable indices onto bonds (all bonds)
00653       std::vector<Bond*> index_to_bond_;
00654 
00655 
00656 
00657       // ***************** datastructures for virtual hydrogen bonds ****************** 
00658       //
00659       //  NOTE: a single virtual bond represents ALL possible hydrogen 
00660       //        bonds for a given atom
00661       //
00662       // the atoms with upto n possible additional hydrogens
00663       HashMap<Atom*, int> number_of_virtual_hydrogens_;
00664       //
00665       // the max number of virtual hydrogens per virtual bond index
00666       std::vector<int> virtual_bond_index_to_number_of_virtual_hydrogens_;
00667       //  
00668       // the number of virtual bonds
00669       Size num_of_virtual_bonds_;
00670       //
00671       // the virtual bond index assigned to this atom!
00672       vector<Atom*> virtual_bond_index_to_atom_;
00673       HashMap<Atom*, int> atom_to_virtual_bond_index_;
00674       //
00675       //
00676       // a virtual dummy bond
00677       Bond* virtual_bond_;
00678 
00679       // ******************* general datastructures *********************
00680 
00681       // the number of bonds given (free + fixed!)
00682       Position total_num_of_bonds_;
00683 
00684       // num of free bonds without virtual bonds!
00685       int num_of_free_bonds_;
00686 
00687       // store for all atom-indices the atoms fixed valences 
00688       std::vector<Position> fixed_val_;
00689 
00690       // storing the solutions
00691       vector<BondOrderAssignment> solutions_;
00692 
00693       // the original conformation before we computed anything
00694       // this is a vector because we can have multiple molecules...
00695       vector<BondOrderAssignment> starting_configuration_;
00696 
00697       // the inverse of the atom type penalty normalization factor
00698       float atom_type_normalization_factor_;
00699 
00700       // the inverse of the bond length penalty normalization factor
00701       float bond_length_normalization_factor_;
00702 
00703       // denotes the index of the last applied solution
00704       // -1 if there was no valid solution applied
00705       int last_applied_solution_;
00706 
00707       // the AtomContainer, the processor is operating on
00708       AtomContainer* ac_;
00709 
00710       // max bond order to consider
00711       int max_bond_order_;
00712 
00713       // balance parameter between atom type and bond length penalty
00714       float alpha_;
00715 
00716       // the max number of solutions to compute 
00717       int max_number_of_solutions_;
00718 
00719       // flag to indicate, whether also non-optimal solutions should be computed 
00720       bool compute_also_non_optimal_solutions_;
00721 
00722       // flag for adding missing hydrogens
00723       bool add_missing_hydrogens_;
00724 
00725       // flag for computing also the bond connectivity
00726       bool compute_also_connectivity_;
00727 
00728       // flag for using fine penalties derived from 3d information
00729       bool use_fine_penalty_;
00730 
00731       // ////////              general stuff                      /////////
00732 
00733 
00734       // The penalty administration datastructures.
00735       //  filled by readAtomPenalties_
00736       //  organized in imaginarey blocks of length  
00737       //  block_to_length_[i], starting from 
00738       //  block_to_start_idx_[i] associating 
00739       //  block_to_start_valence_[i] to the start_idx
00740       vector<int> penalties_;
00741       vector<Position> block_to_start_idx_;
00742       vector<Size> block_to_length_;
00743       vector<int> block_to_start_valence_;
00744       // stores the defining element and the SMART-string of each block
00745       vector<std::pair<String, String> > block_definition_;
00746 
00747 
00748       // Stores which atom belongs to which penalty block.
00749       // The first vector element of each atom block denotes the penalty block 
00750       // assigned to the atom without any additional VIRTUAL Hydrogens,
00751       // the second element with one additional Hydrogen and so on. 
00752       vector< vector<int> > atom_to_block_;
00753 
00754       // Stores the possible bond lengths penalties per order.
00755       HashMap<Bond*, vector<float> > bond_lengths_penalties_;
00756 
00757       Timer timer_;
00758 
00759       AssignBondOrderProcessor(const AssignBondOrderProcessor& abop);
00760       AssignBondOrderProcessor& operator = (const AssignBondOrderProcessor& abop);
00761 
00762       // The strategies this class can use
00763       StringHashMap<boost::shared_ptr<BondOrderAssignmentStrategy> > strategies_;
00764     };
00765 
00766 } // namespace BALL 
00767 
00768 
00769 #endif // BALL_STRUCTURE_ASSIGNBONDORDERPROCESSOR_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines