trace_graph.cpp
来自「ncbi源码」· C++ 代码 · 共 926 行 · 第 1/3 页
CPP
926 行
double aln_to = trans.GetAlnPosFromSeqPos(to + (b_neg ? 0 : 1)); glVertex2d(aln_to - offset_x, bottom_y - v); //glVertex2d(aln_to - offset_x, bottom_y); } else { TModelUnit seqpos = positions[sm_end]; double v = values[sm_end]; v *= amp; double aln_pos = trans.GetAlnPosFromSeqPos(seqpos); glVertex2d(aln_pos - offset_x, bottom_y - v); //glVertex2d(aln_pos - offset_x, bottom_y); } glEnd(); } }}/// Render signals for all channels as gradient-color bands with color intensity/// proprotional to signal strength.void CTraceGraph::x_RenderIntensityGraphs(CGlPane& pane, int y, int h, const TChunkVec& chunks){ //_TRACE("\nx_RenderIntensityGraphs"); const CTraceData::TPositions& positions = m_pData->GetPositions(); const TVPRect& rc_vp = pane.GetViewport(); const TModelRect rc_vis = pane.GetVisibleRect(); // calculate layout int av_h = h - 2 * kGraphOffsetY; // height available for intensity bands int band_h = av_h / 4; int off = (av_h - 4 * band_h) / 2; // rounding error compensation int top_y = rc_vp.Bottom() - (y + kGraphOffsetY + off); TModelUnit left = rc_vis.Left(); TModelUnit scale_x = pane.GetScaleX(); TVPUnit range_pix_start = rc_vp.Left(); TVPUnit range_pix_end = rc_vp.Right(); SChunkTranslator trans; glBegin(GL_LINES); int i_chunk = 0, n_chunks = chunks->size(); CConstRef<CAlnMap::CAlnChunk> chunk; // iterate by pixels,samples and chunks for( int pix = range_pix_start; pix <= range_pix_end && i_chunk < n_chunks; i_chunk++ ) { _ASSERT(i_chunk >=0 && i_chunk < n_chunks); chunk = (*chunks)[i_chunk]; if(chunk->GetType() & CAlnMap::fSeq) { // if chunk is aligned //calc samples range by chunk const TSignedSeqRange& ch_range = chunk->GetRange(); const TSignedSeqRange& ch_aln_range = chunk->GetAlnRange(); trans.Init(ch_range, ch_aln_range, m_pData->IsNegative()); // [from, to] - is sequence range for which graph is rendered double from = max(m_pData->GetSeqFrom(), ch_range.GetFrom()); double to = min(m_pData->GetSeqTo(), ch_range.GetTo()); double vis_from = trans.GetSeqPosFromAlnPos(rc_vis.Left()); double vis_to = trans.GetSeqPosFromAlnPos(rc_vis.Right()); if(vis_to < vis_from) { _ASSERT(m_pData->IsNegative()); swap(vis_from, vis_to); } from = max(from, vis_from); to = min(to, vis_to); // [sm_start, sm_end] - samples range being rendered int sm_start = x_FindSampleToLeft(from); int sm_end = x_FindSampleToRight(to + 1); sm_start = max(sm_start, 0); sm_end = min(sm_end, m_pData->GetSamplesCount() - 1); // calculate pixels range to render double aln_from = trans.GetAlnPosFromSeqPos(from); double aln_to = trans.GetAlnPosFromSeqPos(to); if(m_pData->IsNegative()) { swap(aln_from, aln_to); } aln_to += 1; TVPUnit pix_start = range_pix_start + (TVPUnit) floor((aln_from - left) / scale_x); TVPUnit pix_end = range_pix_start + (TVPUnit) ceil((aln_to - left) / scale_x); pix_start = max(pix_start, range_pix_start); pix_end = min(pix_end, range_pix_end); int sm_inc = m_pData->IsNegative() ? -1 : +1; int band_y = top_y; for( int i_ch = 0; i_ch < 4; i_ch++ ) { // for every channel (i_ch - channel index) int ch_index = (m_Props.m_bReverseColors && m_pData->IsNegative()) ? (i_ch ^ 2) : i_ch; int ch = CTraceData::eA + ch_index; const CTraceData::TValues& values = m_pData->GetValues((CTraceData::EChannel) ch); CTraceData::TSignalValue MaxSignal = m_pData->GetMax((CTraceData::EChannel) ch); double x1, x2, pix_x1, pix_x2; double v1, v2, s, dx, sum, sum_pix_x; int sample = m_pData->IsNegative() ? sm_end : sm_start; _ASSERT(sample >= 0); for( TVPUnit pix = pix_start; pix <= pix_end; pix++ ) { // for each pixel // calculate average value for "pix" pixel by integrating values // over the range [pix, pix+1] sum = 0; // integral from values by pix_x sum_pix_x = 0; // length of integrated range x1 = positions[sample]; if(m_pData->IsNegative()) x1 -= 1.0; pix_x1 = range_pix_start + (trans.GetAlnPosFromSeqPos(x1) - left) / scale_x; v1 = v2 = values[sample]; //##### if(pix_x1 < pix + 1) { bool b_next_point = m_pData->IsNegative() ? (sample > sm_start) : (sample < sm_end); if(b_next_point) { // there is second point available x2 = positions[sample + sm_inc]; if(m_pData->IsNegative()) x2 -= 1.0; pix_x2 = range_pix_start + (trans.GetAlnPosFromSeqPos(x2) - left) / scale_x; v2 = values[sample + sm_inc]; if(pix_x1 < pix) { // fisrt sample is to the left of this pixel // replace it fake interpolated sample at x = "pix" v1 += (v2 - v1) * (pix - pix_x1) / (pix_x2 - pix_x1); pix_x1 = pix; } } while(b_next_point && pix_x2 <= pix + 1) // while second point is inside pixel { dx = pix_x2 - pix_x1; s = 0.5 * (v1 + v2) * dx; _ASSERT(s >=0 && dx >= 0); sum += s; sum_pix_x += dx; sample += sm_inc; // advance, x2 becomes x1 pix_x1 = pix_x2; v1 = v2; b_next_point = m_pData->IsNegative() ? (sample > sm_start) : (sample < sm_end); if(b_next_point) { x2 = positions[sample + sm_inc]; if(m_pData->IsNegative()) x2 -= 1.0; pix_x2 = range_pix_start + (trans.GetAlnPosFromSeqPos(x2) - left) / scale_x; v2 = values[sample + sm_inc]; } else break; } _ASSERT(pix_x1 <= pix + 1); if(b_next_point && pix_x2 > pix + 1) { // second point is outside pixel dx = pix + 1 - pix_x1; _ASSERT(dx >= 0); double v = v1 + (v2 - v1) * dx / (pix_x2 - pix_x1); s = 0.5 * (v1 + v) * dx; _ASSERT(s >=0 && dx >= 0); sum += s; sum_pix_x += dx; } double av_v = (sum_pix_x) > 0 ? sum / sum_pix_x : 0; // render pixel double norm = (MaxSignal == 0) ? 0 : (av_v / MaxSignal); const CGlColor& col = GetColorByValue(norm, i_ch); glColorC(col); glVertex2d(pix, band_y); glVertex2d(pix, band_y - band_h - 1); } // if(pix < pix + 1) } band_y -= band_h; } } } glEnd();}// returns gradient color corresponding to normalized [0, 1.0] value "value" // for channel specified by "signal" const CGlColor& CTraceGraph::GetColorByValue(double value, int signal) const{ _ASSERT(value >= 0 && value <= 1.0); _ASSERT(signal >= 0 && signal <= 3); int i = (int) (value * kGradColors); i = min(i, kGradColors); int index = signal * kGradColors + i; return m_vSignalColors[index];}/// returns index of rightmost sample having m_SeqPos less then "pos"./// if "pos" is to the left of the trace range function returns -1,/// if "pos" is to the right of the trace range functions returns "n_samples"int CTraceGraph::x_FindSampleToLeft(double pos) const{ int n_samples = m_pData->GetSamplesCount(); if(pos < m_pData->GetSeqFrom() || n_samples == 0) { return -1; } else if(pos > m_pData->GetSeqTo()) { return n_samples; } else { const CTraceData::TPositions& positions = m_pData->GetPositions(); double scale = ((double) n_samples) / m_pData->GetSeqLength(); // calculate approximate sample index int i = (int) (scale * (pos - m_pData->GetSeqFrom())); i = min(i, n_samples - 1); i = max(i, 0); if(positions[i] > pos) { for( ; i > 0 && positions[i] > pos; i-- ) { } } else { for( ; ++i < n_samples && positions[i] < pos; ) { } i--; } return i; }}/// returns index of the leftmost sample having m_SeqPos greater than "pos"/// if "pos" is to the left of the trace range function returns -1,/// if "pos" is to the right of the trace range functions returns "n_samples"int CTraceGraph::x_FindSampleToRight(double pos) const{ int n_samples = m_pData->GetSamplesCount(); if(pos < m_pData->GetSeqFrom() || n_samples == 0) { return -1; } else if(pos > m_pData->GetSeqTo()) { return n_samples; } else { const CTraceData::TPositions& positions = m_pData->GetPositions(); double scale = ((double) n_samples) / m_pData->GetSeqLength(); // calculate approximate sample index int i = (int) (scale * (pos - m_pData->GetSeqFrom())); i = min(i, n_samples - 1); i = max(i, 0); if(positions[i] > pos) { for( ; i > 0 && positions[i] > pos; i-- ) { } i++; } else { for( ; ++i < n_samples && positions[i] < pos; ) { } } return i; }}END_NCBI_SCOPE/* * =========================================================================== * $Log: trace_graph.cpp,v $ * Revision 1000.1 2004/06/01 21:07:29 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9 * * Revision 1.9 2004/05/21 22:27:52 gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.8 2004/05/14 13:20:51 yazhuk * Implemented color reversing for traces on negative strand * * Revision 1.7 2004/05/10 17:46:35 yazhuk * Addressed GCC warnings * * Revision 1.6 2004/03/29 18:59:47 yazhuk * Added support for data loading and Properties management * * Revision 1.5 2004/03/26 14:59:49 yazhuk * Renamed EMode to ESignalStyle; a number of rendering improvements * * Revision 1.4 2004/03/25 13:05:50 dicuccio * Use _TRACE() instead of cout * * Revision 1.3 2004/03/11 17:50:41 dicuccio * Updated typedefs: dropped TDimension, TPosition, TIndex, TColor; use TSeqRange * instead of TRange * * Revision 1.2 2004/03/08 15:38:16 yazhuk * Implemented state management expanded/collapsed/hidden * * Revision 1.1 2004/03/02 15:13:51 yazhuk * Initial revision * * =========================================================================== */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?