IMP  2.0.1
The Integrative Modeling Platform
FormFactorTable.h
Go to the documentation of this file.
1 /**
2  * \file IMP/saxs/FormFactorTable.h \brief A class for computation of
3  * atomic and residue level form factors for SAXS calculations
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPSAXS_FORM_FACTOR_TABLE_H
10 #define IMPSAXS_FORM_FACTOR_TABLE_H
11 
12 #include <IMP/saxs/saxs_config.h>
13 
14 #include <IMP/Particle.h>
15 #include <IMP/base_types.h>
16 #include <IMP/atom/Residue.h>
17 #include <IMP/atom/Atom.h>
18 #include <IMP/atom/element.h>
19 #include <IMP/algebra/utility.h>
20 
21 #include <iostream>
22 #include <vector>
23 
24 IMPSAXS_BEGIN_NAMESPACE
25 
26 //! type of the form factors for profile calculations
27 /*
28  ALL_ATOMS - all atoms including hydrogens
29  HEAVY_ATOMS - no hydrogens, all other atoms included
30  CA_ATOMS - residue level, residue represented by CA
31 */
32 enum FormFactorType { ALL_ATOMS, HEAVY_ATOMS, CA_ATOMS };
33 
34 /**
35  class that deals with form factor computation
36  two form factors are supported:
37  (i) zero form factors for faster approximated calculations
38  (ii) full form factors for slower accurate calculations
39 
40  Each form factor can be divided into two parts: vacuum and dummy.
41  dummy is an approximated excluded volume (solvent) form factor.
42  The approximation is done using Fraser, MacRae and Suzuki (1978) model.
43 */
44 class IMPSAXSEXPORT FormFactorTable {
45 public:
46  //! default constructor
48 
49  //! constructor with form factor table file (required for full form factors)
50  FormFactorTable(const String& table_name, Float min_q, Float max_q,
51  Float delta_q);
52 
53  // 1. Zero form factors
54 
55  //! get f(0), ie q=0 for real space profile calculation
56  Float get_form_factor(Particle* p, FormFactorType ff_type=HEAVY_ATOMS) const;
57 
58  //! f(0) in vacuum
59  Float get_vacuum_form_factor(Particle* p,
60  FormFactorType ff_type=HEAVY_ATOMS) const;
61 
62  //! f(0) for solvent
63  Float get_dummy_form_factor(Particle* p,
64  FormFactorType ff_type=HEAVY_ATOMS) const;
65 
66  //! f(0) for water
67  Float get_water_form_factor() const { return zero_form_factors_[OH2]; }
68 
69  //! f(0) for water in vacuum
71  return vacuum_zero_form_factors_[OH2];
72  }
73 
74  //! f(0) for water (solvent)
76  return dummy_zero_form_factors_[OH2];
77  }
78 
79  // 2. Full form factors
80 
81  //! full form factor for reciprocal space profile calculation
82  const Floats& get_form_factors(Particle* p,
83  FormFactorType ff_type = HEAVY_ATOMS) const;
84 
85  //! for reciprocal space profile calculation
86  const Floats& get_vacuum_form_factors(Particle* p,
87  FormFactorType ff_type = HEAVY_ATOMS) const;
88 
89  //! for reciprocal space profile calculation
90  const Floats& get_dummy_form_factors(Particle* p,
91  FormFactorType ff_type = HEAVY_ATOMS) const;
92 
93  //! full water form factor
94  const Floats& get_water_form_factors() const { return form_factors_[OH2]; }
95 
96  //! full water vacuum form factor
98  return vacuum_form_factors_[OH2];
99  }
100 
101  //! full water dummy form factor
103  return dummy_form_factors_[OH2];
104  }
105 
106  //! radius
107  Float get_radius(Particle* p, FormFactorType ff_type=HEAVY_ATOMS) const;
108 
109  //! volume
110  Float get_volume(Particle* p, FormFactorType ff_type=HEAVY_ATOMS) const;
111 
112  //! print tables
113  void show(std::ostream &out=std::cout, std::string prefix="") const;
114 
115  // electron density of solvent - default=0.334 e/A^3 (H2O)
116  static Float rho_;
117 
118 private:
119  // atom types for heavy atoms according to the number of hydrogens
120  // connected to them
121  // ALL_ATOM_SIZE is number of types needed for all atom representation
122  // this indexing is used in form_factors arrays
123  enum FormFactorAtomType {
124  H, He, Li, Be, B, C, N, O, F, Ne, // periodic table, lines 1-2 (10)
125  Na, Mg, Al, Si, P, S, Cl, Ar, // line 3 (8)
126  K, Ca, Cr, Mn, Fe, Co, Ni, Cu, Zn, Se, Br, // line 4 (11)
127  I, Ir, Pt, Au, Hg, ALL_ATOM_SIZE = 34,
128  CH=34, CH2=35, CH3=36, NH=37, NH2=38, NH3=39, OH=40, OH2=41, SH=42,
129  HEAVY_ATOM_SIZE=43, UNK=44};
130 
131  // map between atom element and FormFactorAtomType
132  static std::map<atom::Element, FormFactorAtomType> element_ff_type_map_;
133 
134  struct FormFactor {
135  FormFactor() {}
136  FormFactor(double ff, double vacuum_ff, double dummy_ff) :
137  ff_(ff), vacuum_ff_(vacuum_ff), dummy_ff_(dummy_ff) {}
138  double ff_, vacuum_ff_, dummy_ff_;
139  };
140 
141  // map between residue type and residue level form factors
142  static std::map<atom::ResidueType, FormFactor> residue_type_form_factor_map_;
143 
144  // form factors for q=0, the order as in the FormFactorAtomType enum
145  static Float zero_form_factors_[];
146 
147  static Float vacuum_zero_form_factors_[];
148  // those represent excluded volume
149  static Float dummy_zero_form_factors_[];
150 
151  // a key for storing zero form factor in Particle as attribute
152  static IntKey form_factor_type_key_;
153 
154  // class for storing form factors solvation table
155  class AtomFactorCoefficients {
156  public:
157  String atom_type_;
158  Float a_[5];
159  Float b_[5];
160  Float c_;
161  Float excl_vol_;
162  };
163 
164  // read entry
165  friend std::istream& operator>>(std::istream& s,
166  AtomFactorCoefficients& atom_factor_coefficients);
167 
168  // write entry
169  friend std::ostream& operator<<(std::ostream& s,
170  const AtomFactorCoefficients& atom_factor_coefficients);
171 
172 private:
173  int read_form_factor_table(const String& table_name);
174 
175  void init_element_form_factor_map();
176 
177  void init_residue_type_form_factor_map();
178 
179  void compute_form_factors_all_atoms();
180 
181  void compute_form_factors_heavy_atoms();
182 
183  float get_form_factor(atom::ResidueType rt) const;
184 
185  float get_vacuum_form_factor(atom::ResidueType rt) const;
186 
187  float get_dummy_form_factor(atom::ResidueType rt) const;
188 
189  FormFactorAtomType get_form_factor_atom_type(atom::Element e) const;
190 
191  FormFactorAtomType get_form_factor_atom_type(Particle* p,
192  FormFactorType ff_type) const;
193 
194  FormFactorAtomType get_carbon_atom_type(const atom::AtomType& atom_type,
195  const atom::ResidueType& residue_type) const;
196 
197  FormFactorAtomType get_nitrogen_atom_type(const atom::AtomType& atom_type,
198  const atom::ResidueType& residue_type) const;
199 
200  FormFactorAtomType get_oxygen_atom_type(const atom::AtomType& atom_type,
201  const atom::ResidueType& residue_type) const;
202 
203  FormFactorAtomType get_sulfur_atom_type(const atom::AtomType& atom_type,
204  const atom::ResidueType& residue_type) const;
205 
206 private:
207  // read from lib file
208  std::vector<AtomFactorCoefficients> form_factors_coefficients_;
209 
210  // table of full form factors for 14 atom types
211  std::vector<Floats> form_factors_;
212 
213  // vacuum full form factors for 14 atom types
214  std::vector<Floats> vacuum_form_factors_;
215 
216  // dummy full form factors for 14 atom types
217  std::vector<Floats> dummy_form_factors_;
218 
219  // min/max q and sampling resolution for form factor computation
220  Float min_q_, max_q_, delta_q_;
221 
222  WarningContext warn_context_;
223 };
224 
225 IMPSAXSEXPORT FormFactorTable* default_form_factor_table();
226 
227 IMPSAXS_END_NAMESPACE
228 
229 #endif /* IMPSAXS_FORM_FACTOR_TABLE_H */