Skip to content
Snippets Groups Projects
Select Git revision
  • 882b681e38dcbcc12715c07ce6be7f151940bbb2
  • master default protected
  • develop protected
  • cmake_boost_refactor
  • ubuntu_ci
  • mmtf
  • non-orthogonal-maps
  • no_boost_filesystem
  • data_viewer
  • 2.11.1
  • 2.11.0
  • 2.10.0
  • 2.9.3
  • 2.9.2
  • 2.9.1
  • 2.9.0
  • 2.8.0
  • 2.7.0
  • 2.6.1
  • 2.6.0
  • 2.6.0-rc4
  • 2.6.0-rc3
  • 2.6.0-rc2
  • 2.6.0-rc
  • 2.5.0
  • 2.5.0-rc2
  • 2.5.0-rc
  • 2.4.0
  • 2.4.0-rc2
29 results

entity_to_density.cc

Blame
  • user avatar
    Marco Biasini authored
    e1be0cc5
    History
    entity_to_density.cc 14.91 KiB
    #include <sstream>
    #include <cmath>
    
    #include <boost/filesystem/fstream.hpp>
    #include <boost/filesystem/convenience.hpp>
    #include <boost/algorithm/string.hpp>
    
    #include <ost/log.hh>
    #include <ost/platform.hh>
    #include <ost/img/alg/dft.hh>
    #include <ost/mol/mol.hh>
    
    #include "entity_to_density.hh"
    
    namespace ost { namespace mol { namespace alg {
    
    namespace detail {
    
    struct AtomScatteringProps {
     String element;
      Real atomic_weight;
      Real c;
      Real a1;
      Real a2;
      Real a3;
      Real a4;
      Real b1;
      Real b2;
      Real b3;
      Real b4;
    };
    
    typedef std::vector<AtomScatteringProps> AtomScatteringPropsTable;
    
    void FillAtomScatteringPropsTable(AtomScatteringPropsTable& table)
    {
      AtomScatteringProps atom_props;
    
      String ost_root=GetSharedDataPath();
      String filename = "/atom_scattering_properties.txt";
      String fullpath = ost_root+filename;
      boost::filesystem::path loc(fullpath);
      boost::filesystem::ifstream infile(loc);
      if (!infile) {
        String msg;
        std::stringstream msgstr(msg);
        msgstr << "Couldn't find " << fullpath << std::endl;
        throw ost::Error(msg);
      }
      String line;
      std::getline(infile, line);
      std::getline(infile, line);
      std::getline(infile, line);
      std::getline(infile, line);
      std::getline(infile, line);
      while (std::getline(infile, line))
      {
       std::stringstream line_stream(line);
       line_stream >> atom_props.element
                   >> atom_props.atomic_weight
                   >> atom_props.c
                   >> atom_props.a1
                   >> atom_props.a2
                   >> atom_props.a3
                   >> atom_props.a4
                   >> atom_props.b1
                   >> atom_props.b2
                   >> atom_props.b3
                   >> atom_props.b4;
        table.push_back(atom_props);
      }
    };
    
    
    Real ScatteringFactor (Real frequency, const AtomScatteringProps& props,
                             Real source_wavelength)
    {
       Real scattering_factor =
                 props.a1*exp(-props.b1*frequency*frequency) +
                 props.a2*exp(-props.b2*frequency*frequency) +
                 props.a3*exp(-props.b3*frequency*frequency) +
                 props.a4*exp(-props.b4*frequency*frequency) +
                 props.c;
    
       return scattering_factor;
    }
    
    
    class EntityToDensityHelperBase
    {
    
    public:
    
      EntityToDensityHelperBase (const ost::mol::EntityView entity_view,
                                 Real falloff_start,
                                 Real falloff_end,
                                 Real source_wavelength,
                                 geom::Vec3 map_start,
                                 geom::Vec3 map_end
                                 ):
          entity_view_(entity_view),
          falloff_start_frequency_(1.0/falloff_start),
          falloff_end_frequency_(1.0/falloff_end),
          source_wavelength_(source_wavelength),
          map_start_(map_start),map_end_(map_end)
      {
        if (scattering_props_table_loaded_ == false)
        {
          FillAtomScatteringPropsTable(scatt_props_table_);
          scattering_props_table_loaded_ = true;
        }
      }
    
      void VisitState(img::ComplexHalfFrequencyImageState& is) const
      {
    
        geom::Vec3 frequency_sampling =
                 is.GetSampling().GetFrequencySampling();
    
        Real minus_2_pi = -2.0*M_PI;
    
        uint x_limit = ceil(falloff_end_frequency_ / frequency_sampling[0]);
        uint y_limit = ceil(falloff_end_frequency_ / frequency_sampling[1]);
        uint z_limit = ceil(falloff_end_frequency_ / frequency_sampling[2]);
         img::Extent reduced_extent = img::Extent
                 (img::Point(-static_cast<int>(x_limit),-static_cast<int>(y_limit),0),
                  img::Point(x_limit,y_limit,z_limit));
    
    
        for (ChainViewList::const_iterator ci = entity_view_.GetChainList().begin(),
            ce = entity_view_.GetChainList().end(); ci != ce; ++ci) {
        for (ResidueViewList::const_iterator ri = ci->GetResidueList().begin(),
              re = ci->GetResidueList().end(); ri != re; ++ri) {
        for (AtomViewList::const_iterator ai = ri->GetAtomList().begin(),
              ae = ri->GetAtomList().end(); ai!= ae; ++ai) {
          AtomScatteringPropsTable::iterator table_iter =
                                                 scatt_props_table_.begin();
          bool found = false;
          while (found != true && table_iter!=scatt_props_table_.end())
          {
            if ( (*table_iter).element == (*ai).GetElement())
            {        
              geom::Vec3 coord = ai->GetPos();
    
              if (coord[0] >= map_start_[0] &&
                  coord[0] <= map_end_[0] &&
                  coord[1] >= map_start_[1] &&
                  coord[1] <= map_end_[1] &&
                  coord[2] >= map_start_[2] &&
                  coord[2] <= map_end_[2])
              {
    
                // This part of the code assumes that the three axes
                // of the map are at right angles and the origin at 0,0,0.
                // Eventually, when maps and images will be merged,
                // it will substituted by the map's xyz2uvw method
    
                geom::Vec3 adjusted_coord  = coord-map_start_;
    
                for (img::ExtentIterator mp_it(reduced_extent);
                   !mp_it.AtEnd();++mp_it)
                {
                  img::Point mp_it_point = img::Point(mp_it);
    
                  geom::Vec3 frequency_sampling =
                      is.GetSampling().GetFrequencySampling();
    
                  geom::Vec3 mp_it_vec = geom::Vec3(
                    (mp_it_point[0]*frequency_sampling[0]),
                    (mp_it_point[1]*frequency_sampling[1]),
                    (mp_it_point[2]*frequency_sampling[2])
                  );
    
                  Real frequency = Length(mp_it_vec);
    
                  Real sigma = (falloff_end_frequency_ -
                                  falloff_start_frequency_)/3.0;
    
                  if (frequency <= falloff_end_frequency_)
                  {
                    Real falloff_term = 1.0;
                    if (sigma!=0 && frequency >= falloff_start_frequency_)
                    {
                      falloff_term=exp(-(frequency-falloff_start_frequency_)*
                                            (frequency-falloff_start_frequency_)/
                                            (2.0*sigma*sigma));
                    }
                    AtomScatteringProps scatt_props = (*table_iter);
                    Real scatt_fact = ScatteringFactor(frequency,
                                                         scatt_props,
                                                         source_wavelength_);
    
                    Real amp_term = scatt_fact*falloff_term;
                    Real exp = minus_2_pi * geom::Dot(mp_it_vec,adjusted_coord);
                    Real real = amp_term *std::cos(exp);
                    Real imag = amp_term *std::sin(exp);
                    is.Value(mp_it) = is.Value(mp_it)+Complex(real,imag);
    
                  }
                }
              }
            }
            ++table_iter;
          }
        }}} // loop over atoms
      }
    
      template <typename T, class D>
      void VisitState(img::ImageStateImpl<T,D>& is) const
      {
        assert(false);
      }
    
      static String GetAlgorithmName() {return "EntityToDensityHelper"; }
    
    private:
    
      ost::mol::alg::DensityType density_type_;
      Real limit_;
      ost::mol::EntityView entity_view_;
      Real falloff_start_frequency_;
      Real falloff_end_frequency_;
      static AtomScatteringPropsTable scatt_props_table_;
      static bool scattering_props_table_loaded_;
      Real source_wavelength_;
      geom::Vec3 map_start_;
      geom::Vec3 map_end_;
    
    };
    
    AtomScatteringPropsTable EntityToDensityHelperBase::scatt_props_table_ =
              AtomScatteringPropsTable();
    bool EntityToDensityHelperBase::scattering_props_table_loaded_ = false;
    
    typedef img::ImageStateConstModIPAlgorithm<EntityToDensityHelperBase>
            EntityToDensityHelper;
    
    
    
    class EntityToDensityRosettaHelperBase
    {
    
    public:
    
      EntityToDensityRosettaHelperBase (const ost::mol::EntityView entity_view,
                                 const ost::mol::alg::DensityType& density_type,
                                 Real resolution):
          density_type_(density_type), entity_view_(entity_view),
          resolution_(resolution)
      {
        if (scattering_props_table_loaded_ == false)
        {
         FillAtomScatteringPropsTable(scatt_props_table_);
         scattering_props_table_loaded_ = true;
        }
      }
    
      void VisitState(img::RealSpatialImageState& is) const
      {
        geom::Vec3 map_start=is.IndexToCoord(is.GetExtent().GetStart());
        geom::Vec3 map_end=is.IndexToCoord(is.GetExtent().GetEnd());
        mol::EntityView effective_entity_view=entity_view_;
        Real k,C;
    
        if (density_type_ == HIGH_RESOLUTION)
        {
          k = (M_PI*M_PI)/(resolution_*resolution_);
          C = sqrt((M_PI*M_PI*M_PI)/(k*k*k));
          effective_entity_view = entity_view_;
    
        } else {  // ROSETTA LOW RESOLUTION
    
          k = (M_PI*M_PI)/((2.4+0.8*resolution_)*(2.4+0.8*resolution_));
          C = sqrt((M_PI*M_PI*M_PI)/(k*k*k));
    
          effective_entity_view = entity_view_.Select("aname=CA and peptide=true");
        }
    
        Real sigma = sqrt(1.0/(2.0*k));
        Real four_sigma_squared = 16.0*sigma*sigma;
        Real four_sigma = 4.0*sigma;
    
        geom::Vec3 sampling = is.GetSampling().GetPixelSampling();
        img::Extent is_extent = is.GetExtent();
    
        for (ChainViewList::const_iterator ci = effective_entity_view.GetChainList().begin(),
            ce = effective_entity_view.GetChainList().end(); ci != ce; ++ci) {
        for (ResidueViewList::const_iterator ri = ci->GetResidueList().begin(),
            re = ci->GetResidueList().end(); ri != re; ++ri) {
        for (AtomViewList::const_iterator ai = ri->GetAtomList().begin(),
            ae = ri->GetAtomList().end(); ai!= ae; ++ai) {
          AtomScatteringPropsTable::iterator table_iter =
                                                 scatt_props_table_.begin();
          bool found = false;
          while (found != true && table_iter!=scatt_props_table_.end()) {
            if ((*table_iter).element == ai->GetElement()) {
              found = true;
              Real a = (*table_iter).atomic_weight;
              geom::Vec3 coord = ai->GetPos();
              if (coord[0] >= map_start[0] &&
                  coord[0] <= map_end[0] &&
                  coord[1] >= map_start[1] &&
                  coord[1] <= map_end[1] &&
                  coord[2] >= map_start[2] &&
                  coord[2] <= map_end[2])
              {
    
                geom::Vec3 adjusted_coord  = coord-map_start;
                geom::Vec3 pixel_coord=is.CoordToIndex(coord);
                img::Point rounded_pixel_coord(round(pixel_coord[0]),
                                                round(pixel_coord[1]),
                                                round(pixel_coord[2]));
    
                uint x_limit = ceil(2.0*four_sigma/sampling[0])+1;
                uint y_limit = ceil(2.0*four_sigma/sampling[1])+1;
                uint z_limit = ceil(2.0*four_sigma/sampling[2])+1;
    
                img::Extent reduced_extent = img::Extent
                                          (img::Size(x_limit,y_limit,z_limit),
                                          rounded_pixel_coord);
    
                img::Extent iteration_extent=
                                      img::Overlap(is_extent,reduced_extent);
    
                for (img::ExtentIterator mp_it(iteration_extent);
                  !mp_it.AtEnd();++mp_it)
                {
    
                  img::Point mp_it_point = img::Point(mp_it);
    
                  geom::Vec3 mp_it_vec = geom::Vec3(
                    (mp_it_point[0]*sampling[0]),
                    (mp_it_point[1]*sampling[1]),
                    (mp_it_point[2]*sampling[2])
                  );
    
                  Real distance_squared = Length2(mp_it_vec-adjusted_coord);
    
                  if (distance_squared <= four_sigma_squared)
                  {
                    Real exp_term = exp(-k*distance_squared);
                    Real value = C * a * exp_term;
                    is.Value(mp_it_point) = is.Value(mp_it_point) + value;
                  }
                }
              }
            }
            ++table_iter;
          }
        }}}
      }
    
      template <typename T, class D>
      void VisitState(img::ImageStateImpl<T,D>& is) const
      {
        assert(false);
      }
    
      static String GetAlgorithmName() { return "EntityToDensityRosettaHelper"; }
    
    private:
    
      ost::mol::alg::DensityType density_type_;
      ost::mol::EntityView entity_view_;
      Real resolution_;
      static AtomScatteringPropsTable scatt_props_table_;
      static bool scattering_props_table_loaded_;
    };
    
    AtomScatteringPropsTable EntityToDensityRosettaHelperBase::scatt_props_table_ =
              AtomScatteringPropsTable();
    bool EntityToDensityRosettaHelperBase::scattering_props_table_loaded_ = false;
    
    typedef img::ImageStateConstModIPAlgorithm<EntityToDensityRosettaHelperBase>
        EntityToDensityRosettaHelper;
    
    
    } // namespace
    
    void EntityToDensityScattering(const mol::EntityView& entity_view,
                                         img::MapHandle& map,
                                         Real falloff_start,
                                         Real falloff_end,
                                         bool clear_map_flag,
                                         Real source_wavelength)
    {
      if(falloff_start<=0.0) throw ost::Error("Invalid falloff start");
      if(falloff_end<=0.0 || falloff_end>falloff_start)
         throw ost::Error("Invalid falloff end");
    
     geom ::Vec3 rs_sampl = map.GetSpatialSampling();
      geom ::Vec3 abs_orig = map.GetAbsoluteOrigin();
      geom::Vec3 map_start = geom::Vec3(abs_orig[0]+map.GetExtent().GetStart()[0]*rs_sampl[0],
                                        abs_orig[1]+map.GetExtent().GetStart()[1]*rs_sampl[1],
                                        abs_orig[2]+map.GetExtent().GetStart()[2]*rs_sampl[2]);
    
      geom::Vec3 map_end = geom::Vec3(abs_orig[0]+map.GetExtent().GetEnd()[0]*rs_sampl[0],
                                      abs_orig[1]+map.GetExtent().GetEnd()[1]*rs_sampl[1],
                                      abs_orig[2]+map.GetExtent().GetEnd()[2]*rs_sampl[2]);
      detail::EntityToDensityHelper e_to_d_helper(entity_view,
                                                  falloff_start,
                                                  falloff_end,
                                                  source_wavelength, map_start,map_end);
      if (clear_map_flag==true) {
        img::MapHandle mm=img::CreateImage(img::Extent(map.GetSize(),
                                           img::Point(0,0)),
                                           img::COMPLEX,img::HALF_FREQUENCY);
        // swap newly created map into place
        mm.SetSpatialSampling(map.GetSpatialSampling());
        mm.SetAbsoluteOrigin(map.GetAbsoluteOrigin());
        map.Swap(mm);
      } else {
        map.ApplyIP(img::alg::DFT());
      }
    
      map.ApplyIP(e_to_d_helper);
      map.ApplyIP(img::alg::DFT());
    }
    
    
    void EntityToDensityRosetta(const mol::EntityView& entity_view,
                                img::MapHandle& map,
                                const DensityType& density_type,
                                Real resolution,
                                bool clear_map_flag,
                                Real source_wavelength)
    
    {
      if(resolution <=0.0) throw ost::Error("Invalid resolution");
      if (clear_map_flag==true) {
        img::MapHandle mm=img::CreateImage(img::Extent(img::Point(0,0),
                                           map.GetSize()));
        // swap newly created map into place
        mm.SetSpatialSampling(map.GetSpatialSampling());
        mm.SetAbsoluteOrigin(map.GetAbsoluteOrigin());
        map.Swap(mm);
      }
    
      detail::EntityToDensityRosettaHelper e_to_d_r_helper
                                                    (entity_view,density_type,
                                                    resolution);
      map.ApplyIP(e_to_d_r_helper);
    }
    
    
    }}} // ns