1 /* $Id: blast_hitmatrix.cpp 617977 2020-10-08 18:29:47Z grichenk $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Irena Zaretskaya
27 *
28 * File Description:
29 */
30
31 #include <ncbi_pch.hpp>
32
33 #include <corelib/ncbistl.hpp>
34 #include <objtools/data_loaders/genbank/gbloader.hpp>
35
36 #include <util/image/image.hpp>
37 #include <util/image/image_util.hpp>
38 #include <util/image/image_io.hpp>
39
40 #include <objmgr/util/sequence.hpp>
41
42 #include <connect/services/netcache_api.hpp>
43 #include <gui/opengl/ftglfontmanager.hpp>
44 #include <gui/opengl/gltexturefont.hpp>
45 #include <gui/opengl/glrender.hpp>
46 #include <gui/opengl/glresmgr.hpp>
47 #include "blast_hitmatrix.hpp"
48
49 BEGIN_NCBI_SCOPE
50
x_InitObjectManager()51 void CBlastHitMatrix::x_InitObjectManager()
52 {
53 m_ObjMgr = CObjectManager::GetInstance();
54 CGBDataLoader::RegisterInObjectManager(*m_ObjMgr);
55
56 // create our object manager
57 m_Scope.Reset(new CScope(*m_ObjMgr));
58 m_Scope->AddDefaults();
59 }
60
61
x_InitPort()62 void CBlastHitMatrix::x_InitPort()
63 {
64 m_Port.SetViewport(TVPRect(0, 0, m_Width, m_Height));
65
66 TModelRect rc_m(0, 0, 1000, 1000);
67 CBioseq_Handle s_handle = m_DataSource->GetSubjectHandle();
68 if(s_handle) {
69 rc_m.SetHorz(0, s_handle.GetBioseqLength());
70 } else {
71 TSeqRange s_r = m_DataSource->GetSubjectHitsRange();
72 rc_m.SetHorz(s_r.GetFrom(), s_r.GetToOpen());
73 }
74
75 CBioseq_Handle q_handle = m_DataSource->GetQueryHandle();
76 if(q_handle) {
77 rc_m.SetVert(0, q_handle.GetBioseqLength());
78 } else {
79 TSeqRange q_r = m_DataSource->GetQueryHitsRange();
80 rc_m.SetVert(q_r.GetFrom(), q_r.GetToOpen());
81 }
82
83 m_Port.SetModelLimitsRect(rc_m);
84 }
85
86
CBlastHitMatrix(const list<CRef<CSeq_align>> & seqAligns,int height,int width,CImageIO::EType format,const string & font_path)87 CBlastHitMatrix::CBlastHitMatrix(const list< CRef< CSeq_align > > &seqAligns,
88 int height,
89 int width,
90 CImageIO::EType format,
91 const string& font_path)
92 {
93 ITERATE (CSeq_annot::TData::TAlign, iter, seqAligns) {
94 CRef< CSeq_align > seq_align = *iter;
95 m_Aligns.push_back(CConstRef<CSeq_align>(seq_align));
96 }
97 m_Height = height;
98 m_Width = width;
99 m_Format = format;
100 m_FileOut = false;
101 m_Thumbnail = false;
102
103 x_InitGraphics(font_path);
104 m_Renderer.reset(new CHitMatrixRenderer);
105 }
106
107
x_GetLabels(void)108 void CBlastHitMatrix::x_GetLabels(void)
109 {
110 for(size_t i=0; i < m_Aligns.size();i++) {
111 const CSeq_id& queryID = m_Aligns[i]->GetSeq_id(0);
112 /* Somehow code for IsLocal stopped working
113 if(queryID.IsLocal()) {
114 (*sequence::GetId(queryID,*m_Scope,sequence:: eGetId_Best).GetSeqId()).GetLabel(&m_QueryID);
115 }
116 else {
117 CLabel::GetLabel(queryID,&m_QueryID,CLabel::eDefault,m_Scope.GetPointer());
118 }
119 */
120 CLabel::GetLabel(queryID,&m_QueryID,CLabel::eDefault,m_Scope.GetPointer());
121 if(queryID.IsLocal()) {
122 m_QueryID = "lcl|" + m_QueryID;
123 }
124
125 const CSeq_id& subjectID = m_Aligns[i]->GetSeq_id(1);
126 /*
127 if(subjectID.IsLocal()) {
128 (*sequence::GetId(subjectID,*m_Scope,sequence:: eGetId_Best).GetSeqId()).GetLabel(&m_SubjectID);
129 }
130 else {
131 CLabel::GetLabel(subjectID,&m_SubjectID,CLabel::eDefault,m_Scope.GetPointer());
132 }
133 */
134 CLabel::GetLabel(subjectID,&m_SubjectID,CLabel::eDefault,m_Scope.GetPointer());
135 if(subjectID.IsLocal()) {
136 m_SubjectID = "lcl|" + m_SubjectID;
137 }
138 //m_SubjectID = "Subj: " + m_SubjectID;
139 break;
140 }
141 }
142
143
144 //extracting arguments, verifying and loading data
x_PreProcess(void)145 void CBlastHitMatrix::x_PreProcess(void)
146 {
147
148 x_InitObjectManager();
149 x_GetLabels();
150
151 // create a Data Source
152 CHitMatrixDSBuilder builder;
153 //builder.Init(*m_Scope, *m_Annot);
154 builder.Init(*m_Scope, m_Aligns);
155 m_DataSource = builder.CreateDataSource();
156 m_DataSource->SelectDefaultIds();
157
158 x_InitPort();
159
160 m_Renderer->ShowRulers(!m_Thumbnail);
161 m_Renderer->ShowGrid(!m_Thumbnail);
162 CRgbaColor cl("236 255 243");
163 m_Renderer->SetBackgroundColor(cl);
164 m_Renderer->Update(m_DataSource.GetPointer(), m_Port);
165 }
166
167
168
169
x_Render(void)170 void CBlastHitMatrix::x_Render(void)
171 {
172 if(m_Aligns.size() > 0) {
173 m_Renderer->Resize(m_Width, m_Height, m_Port);
174 if(m_Thumbnail) {
175 m_Renderer->GetBottomRuler().SetDisplayOptions(CRuler::fHideLabels);
176 m_Renderer->GetLeftRuler().SetDisplayOptions(CRuler::fHideLabels);
177 //m_Renderer.SetBackGroundColor(CRgbaColor("211 223 245"));
178 //m_Renderer.SetBackGroundColor(CRgbaColor("238 238 238"));
179 }
180 else {
181 m_Renderer->GetBottomRuler().SetDisplayOptions(CRuler::fShowTextLabel);
182 m_Renderer->GetLeftRuler().SetDisplayOptions(CRuler::fShowTextLabel);
183 m_Renderer->GetBottomRuler().SetTextLabel(m_QueryID);
184 m_Renderer->GetLeftRuler().SetTextLabel(m_SubjectID);
185 }
186
187
188 //m_Renderer.GetBottomRuler().SetColor(CRuler::eText,CRgbaColor(24,0,0));
189 //m_Renderer.GetLeftRuler().SetColor(CRuler::eBackground,CRgbaColor(175,238,238));
190 //m_Renderer.GetBottomRuler().SetColor(CRuler::eText,CRgbaColor(0,0,0));
191 //m_Renderer.GetLeftRuler().SetColor(CRuler::eBackground,CRgbaColor("173 255 47"));
192
193 // adjust visible space
194 m_Port.SetViewport(TVPRect(10, 10, m_Width, m_Height)); ///### this have to be eliminated
195 m_Port.ZoomAll();
196
197 m_Renderer->Render(m_Port);
198 }
199 }
200
Display(CNcbiOstream & out)201 bool CBlastHitMatrix::Display(CNcbiOstream & out)
202 {
203 bool success = x_RenderImage();
204 if(success) {
205 CImageIO::WriteImage(m_Context->GetBuffer(), out, m_Format);
206 }
207 return success;
208 }
209
210
WriteToFile(void)211 bool CBlastHitMatrix::WriteToFile(void)
212 {
213 bool success = x_RenderImage();
214 if(success) {
215 if(IsFileOut()) {
216 CImageIO::WriteImage(m_Context->GetBuffer(), m_File, m_Format);
217 }
218 else {//netcache
219 CNetCacheAPI nc_client("NC_HitMatrix", "blast_hitmatrix");
220 m_ImageKey = nc_client.PutData(m_Context->GetBuffer().GetData(), m_Width*m_Height*3);
221 }
222
223 }
224 return success;
225 }
226
227
x_RenderImage(void)228 bool CBlastHitMatrix::x_RenderImage(void)
229 {
230 bool success = false;
231 try {
232 // Clear any previously used OpenGL states
233 IRender& gl = GetGl();
234 gl.Clear();
235
236 x_PreProcess();
237
238 m_Context.Reset(new CGlOsContext(m_Width, m_Height));
239 m_Context->MakeCurrent();
240
241 x_Render();
242
243 glFinish();
244 m_Context->SetBuffer().SetDepth(3);
245 CImageUtil::FlipY(m_Context->SetBuffer());
246 success = true;
247 }
248 catch (CException& e) {
249 m_ErrorMessage = "Error rendering image:" + e.GetMsg();
250 }
251 catch (exception& e) {
252 m_ErrorMessage = "Error rendering image:" + (string)e.what();
253 }
254 catch (...) {
255 m_ErrorMessage = "Error rendering image: unknown error";
256 }
257 return success;
258 }
259
x_InitGraphics(const string & font_path)260 void CBlastHitMatrix::x_InitGraphics(const string& font_path)
261 {
262 try {
263 m_Context.Reset(new CGlOsContext(m_Width, m_Height));
264 m_Context->MakeCurrent();
265 #ifdef GLEW_MX
266 GLEWContext glew_context;
267 GLenum err = glewContextInit(&glew_context);
268 if (GLEW_OK != err) {
269 // Problem: Error creating glew context
270 _TRACE("Error creating glew context");
271 } else {
272 CGLGlewContext::GetInstance().SetGlewContext(&glew_context);
273 err = glewInit();
274 if (GLEW_OK != err) {
275 // Problem: glewInit failed, something is seriously wrong.
276 // No extenstions will be available.
277 _TRACE("Error loading opengl extensions");
278 }
279 }
280 #else
281 GLenum err = glewInit();
282 if (GLEW_OK != err)
283 {
284 _TRACE("Error initializing glew: " << glewGetErrorString(err));
285 }
286 #endif
287 // initialize OpenGL fonts
288 CFtglFontManager::Instance().SetDeviceResolution(72);
289 // path to find font files (they can be copied from svn
290 // gbench/trunk/src/gui/res/share/gbench/fonts
291 CFtglFontManager::Instance().SetFontPath(font_path.empty() ? "./"
292 : font_path);
293 CFtglFontManager::Instance().Clear();
294
295 CIRef<IRender> mgr = CGlResMgr::Instance().
296 GetRenderer( CGlResMgr::Instance().GetApiLevel());
297 if (mgr.IsNull()) {
298 ERR_POST(Error << "CGlRender object not available.");
299 NCBI_THROW(CException, eUnknown,
300 string("no CGlRender object not available"));
301
302 }
303 }
304 catch (CException& e) {
305 m_ErrorMessage = "Error during initialization: " + e.GetMsg();
306 }
307 catch (...) {
308 m_ErrorMessage = "Error during rendering initialization: unknown error";
309 }
310 }
311
312
313 END_NCBI_SCOPE
314
315
316
317