static inline void apply(CoordinateType& longitude1, CoordinateType& latitude1, CoordinateType& longitude2, CoordinateType& latitude2, bool band) { normalize::apply(longitude1, latitude1, false); normalize::apply(longitude2, latitude2, false); if (math::equals(latitude1, constants::min_latitude()) && math::equals(latitude2, constants::min_latitude())) { // box degenerates to the south pole longitude1 = longitude2 = CoordinateType(0); } else if (math::equals(latitude1, constants::max_latitude()) && math::equals(latitude2, constants::max_latitude())) { // box degenerates to the north pole longitude1 = longitude2 = CoordinateType(0); } else if (band) { // the box is a band between two small circles (parallel // to the equator) on the spheroid longitude1 = constants::min_longitude(); longitude2 = constants::max_longitude(); } else if (longitude1 > longitude2) { // the box crosses the antimeridian, so we need to adjust // the longitudes longitude2 += constants::period(); } #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE BOOST_GEOMETRY_ASSERT(! math::larger(latitude1, latitude2)); BOOST_GEOMETRY_ASSERT(! math::smaller(latitude1, constants::min_latitude())); BOOST_GEOMETRY_ASSERT(! math::larger(latitude2, constants::max_latitude())); #endif BOOST_GEOMETRY_ASSERT(! math::larger(longitude1, longitude2)); BOOST_GEOMETRY_ASSERT(! math::smaller(longitude1, constants::min_longitude())); BOOST_GEOMETRY_ASSERT (! math::larger(longitude2 - longitude1, constants::period())); }
static inline void apply(CoordinateType& longitude, CoordinateType& latitude, bool normalize_poles = true) { #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE // normalize latitude if (math::larger(latitude, constants::half_period())) { latitude = normalize_up(latitude); } else if (math::smaller(latitude, -constants::half_period())) { latitude = normalize_down(latitude); } // fix latitude range if (latitude < constants::min_latitude()) { latitude = -constants::half_period() - latitude; longitude -= constants::half_period(); } else if (latitude > constants::max_latitude()) { latitude = constants::half_period() - latitude; longitude -= constants::half_period(); } #endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE // normalize longitude apply(longitude); // finally normalize poles if (normalize_poles) { if (math::equals(math::abs(latitude), constants::max_latitude())) { // for the north and south pole we set the longitude to 0 // (works for both radians and degrees) longitude = CoordinateType(0); } } #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE BOOST_GEOMETRY_ASSERT(! math::larger(constants::min_latitude(), latitude)); BOOST_GEOMETRY_ASSERT(! math::larger(latitude, constants::max_latitude())); #endif // BOOST_GEOMETRY_NORMALIZE_LATITUDE BOOST_GEOMETRY_ASSERT(math::smaller(constants::min_longitude(), longitude)); BOOST_GEOMETRY_ASSERT(! math::larger(longitude, constants::max_longitude())); }
static inline CoordinateType max_latitude() { return CoordinateType(90.0); }
static inline CoordinateType min_latitude() { return CoordinateType(-90.0); }
static inline CoordinateType max_longitude() { return CoordinateType(180.0); }
static inline CoordinateType min_longitude() { return CoordinateType(-180.0); }
static inline CoordinateType half_period() { return CoordinateType(180.0); }
static inline CoordinateType period() { return CoordinateType(360.0); }
void DrawCommandExecuteOpenGL::Draw( size_t UseVertexCount, size_t StartVertex ) { { const GLuint prog = m_ShaderProgramID; m_Ext.glLinkProgram( prog ); m_Ext.glUseProgram( prog ); } const std::vector<INPUT_ELEMENT>& InputElement = static_cast<InputLayoutOpenGL*>(m_pInputLayout.get())->Element; std::vector<GLenum> EnableList; for( int i=0; i<(int)InputElement.size(); ++i ) { const INPUT_ELEMENT& ele = InputElement[i]; const DECLUSAGE decl = INPUT_ELEMENTSemanticNametoDECLUSAGE( ele.SemanticName.c_str() ); const VERTEXBUFFER& v = m_VertexBuffer[ele.SlotNo]; const GLint cpv = CoordinatePerVertex( ele.Type ); const GLenum type = CoordinateType( ele.Type ); const GLsizei stride = v.Stride; const int offset = ele.Offset; m_Ext.glBindBuffer( GL_ARRAY_BUFFER, v.pBuffer->GetID() ); switch( decl ) { case DECLUSAGE_POSITION: { EnableList.push_back( GL_VERTEX_ARRAY ); m_Ext.glVertexPointer( cpv, type, stride, (const GLvoid*)(offset) ); } break; case DECLUSAGE_NORMAL: { } break; case DECLUSAGE_COLOR: { EnableList.push_back( GL_COLOR_ARRAY ); m_Ext.glColorPointer( cpv, type, stride, (const GLvoid*)(offset) ); } break; case DECLUSAGE_TEXCOORD: { EnableList.push_back( GL_TEXTURE_COORD_ARRAY ); m_Ext.glTexCoordPointer( cpv, type, stride, (const GLvoid*)(offset) ); const int idx = ele.SemanticIndex; { char buf[256]; sprintf( buf, "texture%0d", idx ); const GLint tex_pos = m_Ext.glGetUniformLocation(m_ShaderProgramID, buf); m_Ext.glUniform1i(tex_pos,idx); } } break; } } for( int i=0; i<(int)EnableList.size(); ++i ) { m_Dll.glEnableClientState( EnableList[i] ); } m_Ext.glActiveTexture( GL_TEXTURE0 ); m_Ext.glDrawArrays( m_PrimitiveTopology, 0, UseVertexCount ); for( int i=0; i<(int)EnableList.size(); ++i ) { m_Dll.glDisableClientState( EnableList[i] ); } }
void IsotopeModel::setSamples(const EmpiricalFormula & formula) { typedef std::vector<DoubleReal> ContainerType; ContainerType isotopes_exact; isotope_distribution_ = formula.getIsotopeDistribution(max_isotope_); isotope_distribution_.trimRight(trim_right_cutoff_); isotope_distribution_.renormalize(); // compute the average mass (-offset) CoordinateType isotopes_mean = 0; Int i = 0; for (IsotopeDistribution::iterator iter = isotope_distribution_.begin(); iter != isotope_distribution_.end(); ++iter, ++i) { isotopes_exact.push_back(iter->second); isotopes_mean += iter->second * i; } isotopes_mean *= isotope_distance_ / charge_; // (Need not divide by sum of probabilities, which is 1.) /// // "stretch" the averagine isotope distribution (so we can add datapoints between isotope peaks) /// size_t isotopes_exact_size = isotopes_exact.size(); isotopes_exact.resize(size_t((isotopes_exact_size - 1) * isotope_distance_ / interpolation_step_ + 1.6)); // round up a bit more for (Size i = isotopes_exact_size - 1; i; --i) { // we don't need to move the 0-th entry isotopes_exact[size_t(CoordinateType(i) * isotope_distance_ / interpolation_step_ / charge_ + 0.5)] = isotopes_exact[i]; isotopes_exact[i] = 0; } //// // compute the Gaussian/Cauchy distribution (to be added for widening the averagine isotope distribution) //// ContainerType peak_shape_values_y; // fill a container with CoordinateType points (x values) CoordinateType peak_width = 0.0; if (param_.getValue("isotope:mode:mode") == "Gaussian") { // Actual width for values in the smooth table for normal distribution peak_width = isotope_stdev_ * 4.0; // MAGIC alert, num stdev for smooth table for normal distribution ContainerType peak_shape_values_x; for (DoubleReal coord = -peak_width; coord <= peak_width; coord += interpolation_step_) { peak_shape_values_x.push_back(coord); } // compute normal approximation at these CoordinateType points (y values) Math::BasicStatistics<> normal_widening_model; normal_widening_model.setSum(1); normal_widening_model.setMean(0); normal_widening_model.setVariance(isotope_stdev_ * isotope_stdev_); normal_widening_model.normalApproximation(peak_shape_values_y, peak_shape_values_x); } else if (param_.getValue("isotope:mode:mode") == "Lorentzian") { peak_width = isotope_lorentz_fwhm_ * 8.0; // MAGIC alert: Lorentzian has infinite support, but we need to stop sampling at some point: 8*FWHM for (DoubleReal coord = -peak_width; coord <= peak_width; coord += interpolation_step_) { boost::math::cauchy_distribution<double> cauchy(0., isotope_lorentz_fwhm_ / 2.0); double x = boost::math::pdf(cauchy, coord); //double y = gsl_ran_cauchy_pdf(coord, isotope_lorentz_fwhm_/2.0); peak_shape_values_y.push_back(x); //cauchy is using HWHM not FWHM } } /// // fold the Gaussian/Lorentzian at each averagine peak, i.e. fill linear interpolation /// const ContainerType & left = isotopes_exact; const ContainerType & right = peak_shape_values_y; ContainerType & result = interpolation_.getData(); result.clear(); SignedSize r_max = std::min(SignedSize(left.size() + right.size() - 1), SignedSize(2 * peak_width / interpolation_step_ * max_isotope_ + 1)); result.resize(r_max, 0); // we loop backwards because then the small products tend to come first // (for better numerics) for (SignedSize i = left.size() - 1; i >= 0; --i) { if (left[i] == 0) continue; for (SignedSize j = std::min(r_max - i, SignedSize(right.size())) - 1; j >= 0; --j) { result[i + j] += left[i] * right[j]; } } monoisotopic_mz_ = mean_ - isotopes_mean; interpolation_.setMapping(interpolation_step_, peak_width / interpolation_step_, monoisotopic_mz_); //std::cerr << "mono now: " << monoisotopic_mz_ << " mono easy: " << formula.getMonoWeight()/formula.getCharge() << "\n"; // scale data so that integral over distribution equals one // multiply sum by interpolation_step_ -> rectangular approximation of integral IntensityType factor = scaling_ / (interpolation_step_ * std::accumulate(result.begin(), result.end(), IntensityType(0))); for (ContainerType::iterator iter = result.begin(); iter != result.end(); ++iter) { *iter *= factor; } }
void ExtendedIsotopeModel::setSamples() { // MAGIC alert, num stdev for smooth table for normal distribution CoordinateType normal_widening_num_stdev = 4.; // Actual width for values in the smooth table for normal distribution CoordinateType normal_widening_width = isotope_stdev_ * normal_widening_num_stdev; typedef std::vector<double> ContainerType; ContainerType isotopes_exact; CoordinateType mass = monoisotopic_mz_ * charge_; Int C_num = Int(0.5 + mass * averagine_[C]); Int N_num = Int(0.5 + mass * averagine_[N]); Int O_num = Int(0.5 + mass * averagine_[O]); Int H_num = Int(0.5 + mass * averagine_[H]); Int S_num = Int(0.5 + mass * averagine_[S]); String form(""); if (C_num) form.append("C").append(String(C_num)); if (H_num) form.append("H").append(String(H_num)); if (N_num) form.append("N").append(String(N_num)); if (O_num) form.append("O").append(String(O_num)); if (S_num) form.append("S").append(String(S_num)); EmpiricalFormula formula(form); IsotopeDistribution isotope_distribution = formula.getIsotopeDistribution(CoarseIsotopePatternGenerator(max_isotope_)); isotope_distribution.trimRight(trim_right_cutoff_); isotope_distribution.renormalize(); // compute the average mass (-offset) for (IsotopeDistribution::iterator iter = isotope_distribution.begin(); iter != isotope_distribution.end(); ++iter) { isotopes_exact.push_back(iter->getIntensity()); } // "stretch" the averagine isotope distribution Size isotopes_exact_size = isotopes_exact.size(); isotopes_exact.resize(Size((isotopes_exact_size - 1) * isotope_distance_ / interpolation_step_ + 1.6)); // round up a bit more for (Size i = isotopes_exact_size - 1; i; --i) { // we don't need to move the 0-th entry isotopes_exact[Size(CoordinateType(i) * isotope_distance_ / interpolation_step_ / charge_ + 0.5)] = isotopes_exact[i]; isotopes_exact[i] = 0; } // compute the normal distribution (to be added for widening the averagine isotope distribution) Math::BasicStatistics<> normal_widening_model; normal_widening_model.setSum(1); normal_widening_model.setMean(0); normal_widening_model.setVariance(isotope_stdev_ * isotope_stdev_); // fill a container with CoordinateType points ContainerType normal_widening_coordinate; for (double coord = -normal_widening_width; coord <= normal_widening_width; coord += interpolation_step_ ) { normal_widening_coordinate.push_back(coord); } // compute normal approximation at these CoordinateType points ContainerType normal_widening; normal_widening_model.normalApproximation(normal_widening, normal_widening_coordinate); // fill linear interpolation const ContainerType & left = isotopes_exact; const ContainerType & right = normal_widening; ContainerType & result = interpolation_.getData(); result.clear(); Int rMax = std::min(Int(left.size() + right.size() - 1), Int(2 * normal_widening_width / interpolation_step_ * max_isotope_ + 1)); result.resize(rMax, 0); // we loop backwards because then the small products tend to come first // (for better numerics) for (SignedSize i = left.size() - 1; i >= 0; --i) { if (left[i] == 0) continue; for (SignedSize j = std::min<SignedSize>(rMax - i, right.size()) - 1; j >= 0; --j) { result[i + j] += left[i] * right[j]; } } // set interpolation interpolation_.setMapping(interpolation_step_, normal_widening_width / interpolation_step_, monoisotopic_mz_); // scale data so that integral over distribution equals one // multiply sum by interpolation_step_ -> rectangular approximation of integral IntensityType factor = scaling_ / interpolation_step_ / std::accumulate(result.begin(), result.end(), IntensityType(0)); for (ContainerType::iterator iter = result.begin(); iter != result.end(); ++iter) { *iter *= factor; } }