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