1 /* $Id: showdefline.cpp 620199 2020-11-17 18:41:11Z zaretska $
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:  Jian Ye
27  *
28  * File Description:
29  *   Display blast defline
30  *
31  */
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbiexpt.hpp>
34 #include <corelib/ncbiutil.hpp>
35 #include <corelib/ncbistre.hpp>
36 #include <corelib/ncbireg.hpp>
37 
38 #include <objmgr/object_manager.hpp>
39 #include <objmgr/scope.hpp>
40 #include <objmgr/util/sequence.hpp>
41 #include <objects/seq/Bioseq.hpp>
42 #include <objects/seq/Seq_descr.hpp>
43 #include <objects/seq/Seqdesc.hpp>
44 #include <objects/seqloc/Seq_id.hpp>
45 
46 #include <objects/seqalign/Seq_align_set.hpp>
47 #include <objects/seqalign/Score.hpp>
48 #include <objects/seqalign/Std_seg.hpp>
49 #include <objects/seqalign/Dense_diag.hpp>
50 #include <objects/seqalign/Dense_seg.hpp>
51 #include <objects/blastdb/Blast_def_line.hpp>
52 #include <objects/blastdb/Blast_def_line_set.hpp>
53 #include <objects/blastdb/defline_extra.hpp>
54 
55 #include <objtools/align_format/showdefline.hpp>
56 #include <objtools/align_format/align_format_util.hpp>
57 #include <objtools/blast/seqdb_reader/seqdb.hpp>    // for CSeqDB::ExtractBlastDefline
58 
59 #include <stdio.h>
60 #include <html/htmlhelper.hpp>
61 
62 
63 BEGIN_NCBI_SCOPE
64 USING_SCOPE(objects);
65 USING_SCOPE(sequence);
66 BEGIN_SCOPE(align_format)
67 
68 //margins constant
69 
70 static string kOneSpaceMargin = " ";
71 static string kTwoSpaceMargin = "  ";
72 
73 //const strings
74 static const string kHeader = "Sequences producing significant alignments:";
75 static const string kScore = "Score";
76 static const string kE = "E";
77 static const string kBits =
78     (getenv("CTOOLKIT_COMPATIBLE") ? "(bits)" : "(Bits)");
79 static const string kEvalue = "E value";
80 static const string kValue = "Value";
81 static const string kN = "N";
82 static const string kRepeatHeader = "Sequences used in model and found again:";
83 static const string kNewSeqHeader = "Sequences not found previously or not pr\
84 eviously below threshold:";
85 static const string kMaxScore = "Max score";
86 static const string kTotalScore = "Total score";
87 static const string kTotal = "Total";
88 static const string kIdentity = "Max ident";
89 static const string kPercent = "Percent";
90 static const string kHighest = "Highest";
91 static const string kQuery = "Query";
92 static const string kCoverage = "Query coverage";
93 static const string kEllipsis = "...";
94 
95 static const string kMax = "Max";
96 static const string kIdentLine2  = "Ident";
97 static const string kScoreLine2 = "Score";
98 static const string kQueryCov = "Query";
99 static const string kQueryCovLine2 = "cover";
100 static const string kPerc = "Per.";
101 static const string kAccession = "Accession";
102 static const string kDescription = "Description";
103 static const string kScientific = "Scientific";
104 static const string kCommon = "Common";
105 static const string kName = "Name";
106 static const string kAccAbbr = "Acc.";
107 static const string kLenAbbr = "Len";
108 static const string kTaxid = "Taxid";
109 
110 //psiblast related
111 static const string kPsiblastNewSeqGif = "<IMG SRC=\"images/new.gif\" \
112 WIDTH=30 HEIGHT=15 ALT=\"New sequence mark\">";
113 
114 static const string kPsiblastNewSeqBackgroundGif = "<IMG SRC=\"images/\
115 bg.gif\" WIDTH=30 HEIGHT=15 ALT=\" \">";
116 
117 static const string kPsiblastCheckedBackgroundGif = "<IMG SRC=\"images\
118 /bg.gif\" WIDTH=15 HEIGHT=15 ALT=\" \">";
119 
120 static const string kPsiblastCheckedGif = "<IMG SRC=\"images/checked.g\
121 if\" WIDTH=15 HEIGHT=15 ALT=\"Checked mark\">";
122 
123 static const string kPsiblastEvalueLink = "<a name = Evalue></a>";
124 
125 static const string  kPsiblastCheckboxChecked = "<INPUT TYPE=\"checkbox\" NAME\
126 =\"checked_GI\" VALUE=\"%d\" CHECKED>  <INPUT TYPE=\"hidden\" NAME =\"good_G\
127 I\" VALUE = \"%d\">";
128 
129 static const string  kPsiblastCheckbox =  "<INPUT TYPE=\"checkbox\" NAME=\"ch\
130 ecked_GI\" VALUE=\"%d\">  ";
131 
132 //Max length of title string for the the link
133 static const int kMaxDescrLength = 4096;
134 
135 string
GetSeqIdListString(const list<CRef<objects::CSeq_id>> & id,bool show_gi)136 CShowBlastDefline::GetSeqIdListString(const list<CRef<objects::CSeq_id> >& id,
137                                       bool show_gi)
138 {
139     string id_string = NcbiEmptyString;
140     bool found_gi = false;
141 
142     CRef<CSeq_id> best_id = FindBestChoice(id, CSeq_id::Score);
143 
144     if (show_gi) {
145         ITERATE(list<CRef<CSeq_id> >, itr, id) {
146              if ((*itr)->IsGi()) {
147                 id_string += (*itr)->AsFastaString();
148                 found_gi = true;
149                 break;
150              }
151         }
152     }
153 
154     if (best_id.NotEmpty()  &&  !best_id->IsGi() ) {
155          if (found_gi)
156              id_string += "|";
157 
158          if (best_id->IsLocal()) {
159              string id_token;
160              best_id->GetLabel(&id_token, CSeq_id::eContent, 0);
161              id_string += id_token;
162          }
163          else
164              id_string += best_id->AsFastaString();
165     }
166 
167     return id_string;
168 }
169 
170 void
GetSeqIdList(const objects::CBioseq_Handle & bh,list<CRef<objects::CSeq_id>> & ids)171 CShowBlastDefline::GetSeqIdList(const objects::CBioseq_Handle& bh,
172                                 list<CRef<objects::CSeq_id> >& ids)
173 {
174     ids.clear();
175 
176 
177     vector< CConstRef<CSeq_id> > original_seqids;
178 
179     ITERATE(CBioseq_Handle::TId, itr, bh.GetId()) {
180       original_seqids.push_back(itr->GetSeqId());
181     }
182 
183     // Check for ids of type "gnl|BL_ORD_ID". These are the artificial ids
184     // created in a BLAST database when it is formatted without indexing.
185     // For such ids, create new fake local Seq-ids, saving the first token of
186     // the Bioseq's title, if it's available.
187     GetSeqIdList(bh,original_seqids,ids);
188 }
189 
190 
191 
192 void
GetSeqIdList(const objects::CBioseq_Handle & bh,vector<CConstRef<CSeq_id>> & original_seqids,list<CRef<objects::CSeq_id>> & ids)193 CShowBlastDefline::GetSeqIdList(const objects::CBioseq_Handle& bh,
194                                 vector< CConstRef<CSeq_id> > &original_seqids,
195                                 list<CRef<objects::CSeq_id> >& ids)
196 {
197     ids.clear();
198     ITERATE(vector< CConstRef<CSeq_id> >, itr, original_seqids) {
199         CRef<CSeq_id> next_seqid(new CSeq_id());
200         string id_token = NcbiEmptyString;
201 
202         if (((*itr)->IsGeneral() &&
203             (*itr)->AsFastaString().find("gnl|BL_ORD_ID")
204             != string::npos) ||
205 		(*itr)->AsFastaString().find("lcl|Subject_") != string::npos) {
206             vector<string> title_tokens;
207             string defline = sequence::CDeflineGenerator().GenerateDefline(bh);
208             if (defline != NcbiEmptyString) {
209                 id_token =
210                     NStr::Split(defline, " ", title_tokens)[0];
211             }
212         }
213         if (id_token != NcbiEmptyString) {
214             // Create a new local id with a label containing the extracted
215             // token and save it in the next_seqid instead of the original
216             // id.
217             CObject_id* obj_id = new CObject_id();
218             obj_id->SetStr(id_token);
219             next_seqid->SetLocal(*obj_id);
220         } else {
221             next_seqid->Assign(**itr);
222         }
223         ids.push_back(next_seqid);
224     }
225 }
226 
227 void
GetBioseqHandleDeflineAndId(const CBioseq_Handle & handle,list<TGi> & use_this_gi,string & seqid,string & defline,bool show_gi,TGi this_gi_first)228 CShowBlastDefline::GetBioseqHandleDeflineAndId(const CBioseq_Handle& handle,
229                                                list<TGi>& use_this_gi,
230                                                string& seqid, string& defline,
231                                                bool show_gi /* = true */,
232                                                TGi this_gi_first /* = -1 */)
233 {
234     // Retrieve the CBlast_def_line_set object and save in a CRef, preventing
235     // its destruction; then extract the list of CBlast_def_line objects.
236     if( !handle ) return; //  No bioseq for this handle ( deleted accession ? )
237     CRef<CBlast_def_line_set> bdlRef =
238         CSeqDB::ExtractBlastDefline(handle);
239 
240     if(bdlRef.Empty()){
241         list<CRef<objects::CSeq_id> > ids;
242         GetSeqIdList(handle, ids);
243         seqid = GetSeqIdListString(ids, show_gi);
244         defline = sequence::CDeflineGenerator().GenerateDefline(handle);
245     } else {
246         bdlRef->PutTargetGiFirst(this_gi_first);
247         const list< CRef< CBlast_def_line > >& bdl = bdlRef->Get();
248         bool is_first = true;
249         ITERATE(list<CRef<CBlast_def_line> >, iter, bdl) {
250             const CBioseq::TId& cur_id = (*iter)->GetSeqid();
251             TGi cur_gi =  FindGi(cur_id);
252             TGi gi_in_use_this_gi = ZERO_GI;
253             ITERATE(list<TGi>, iter_gi, use_this_gi){
254                 if(cur_gi == *iter_gi){
255                     gi_in_use_this_gi = *iter_gi;
256                     break;
257                 }
258             }
259             if(use_this_gi.empty() || gi_in_use_this_gi > ZERO_GI) {
260                 if (is_first)
261                     seqid = GetSeqIdListString(cur_id, show_gi);
262 
263                 if((*iter)->IsSetTitle()){
264                     if(is_first){
265                         defline = (*iter)->GetTitle();
266                     } else {
267                         string concat_acc;
268                         CConstRef<CSeq_id> wid =
269                             FindBestChoice(cur_id, CSeq_id::WorstRank);
270                         wid->GetLabel(&concat_acc, CSeq_id::eFasta, 0);
271                         if( show_gi && cur_gi > ZERO_GI){
272                             defline = defline + " >" + "gi|" +
273                                 NStr::NumericToString(cur_gi) + "|" +
274                                 concat_acc + " " + (*iter)->GetTitle();
275                         } else {
276                             defline = defline + " >" + concat_acc + " " +
277                                 (*iter)->GetTitle();
278                         }
279                     }
280                     is_first = false;
281                 }
282             }
283         }
284     }
285 }
286 
s_LimitDescrLength(string & descr,size_t maxDescrLength=kMaxDescrLength)287 static void s_LimitDescrLength(string &descr, size_t maxDescrLength = kMaxDescrLength)
288 {
289 	if(descr.length() > maxDescrLength) {
290         descr = descr.substr(0,maxDescrLength);
291         size_t end = NStr::Find(descr," ",NStr::eNocase,NStr::eReverseSearch);
292 
293         if(end != NPOS) {
294             descr = descr.substr(0,end);
295             descr += "...";
296         }
297     }
298 
299 }
300 
x_InitLinkOutInfo(SDeflineInfo * sdl,CBioseq::TId & cur_id,int blast_rank,bool getIdentProteins)301 void CShowBlastDefline::x_InitLinkOutInfo(SDeflineInfo* sdl,
302                                             CBioseq::TId& cur_id,
303                                             int blast_rank,
304                                             bool getIdentProteins)
305 {
306 
307     bool is_mixed_database = (m_IsDbNa == true && m_Ctx)? CAlignFormatUtil::IsMixedDatabase(*m_Ctx): false;
308     if (m_DeflineTemplates && m_DeflineTemplates->advancedView && !is_mixed_database)  return;
309 
310 
311     string linkout_list;
312 
313     sdl->linkout = CAlignFormatUtil::GetSeqLinkoutInfo(cur_id,
314                                     &m_LinkoutDB,
315                                     m_MapViewerBuildName,
316                                     sdl->gi);
317     if(!m_LinkoutDB) {
318         m_Option &= ~eLinkout;
319         return;
320     }
321 
322 
323     if(m_LinkoutOrder.empty()) {
324         m_ConfigFile.reset(new CNcbiIfstream(".ncbirc"));
325         m_Reg.reset(new CNcbiRegistry(*m_ConfigFile));
326         if(!m_BlastType.empty()) m_LinkoutOrder = m_Reg->Get(m_BlastType,"LINKOUT_ORDER");
327         m_LinkoutOrder = (!m_LinkoutOrder.empty()) ? m_LinkoutOrder : kLinkoutOrderStr;
328     }
329     if (m_DeflineTemplates == NULL || !m_DeflineTemplates->advancedView) {
330         if(m_Option & eRealtedInfoLinks){
331             string user_url = m_Reg.get() ? m_Reg->Get(m_BlastType, "TOOL_URL") : kEmptyStr;
332             sdl->linkout_list =  CAlignFormatUtil::GetFullLinkoutUrl(cur_id,
333                                                             m_Rid,
334                                                             m_CddRid,
335                                                             m_EntrezTerm,
336                                                             m_IsDbNa,
337                                                             false,
338                                                             true,
339                                                             blast_rank,
340                                                             m_LinkoutOrder,
341                                                             sdl->taxid,
342                                                             m_Database,
343                                                             m_QueryNumber,
344                                                             user_url,
345                                                             m_PreComputedResID,
346                                                             m_LinkoutDB,
347                                                             m_MapViewerBuildName,
348                                                             getIdentProteins);
349         }
350         else {
351              sdl->linkout_list =  CAlignFormatUtil::GetLinkoutUrl(sdl->linkout,
352                                                          cur_id,
353                                                          m_Rid,
354                                                          m_CddRid,
355                                                          m_EntrezTerm,
356                                                          m_IsDbNa,
357                                                          ZERO_GI,
358                                                          true,
359                                                          false,
360                                                          blast_rank,
361                                                          m_PreComputedResID);
362         }
363     }
364 }
365 
366 
x_FillDeflineAndId(const CBioseq_Handle & handle,const CSeq_id & aln_id,list<string> & use_this_seqid,SDeflineInfo * sdl,int blast_rank)367 void CShowBlastDefline::x_FillDeflineAndId(const CBioseq_Handle& handle,
368                                            const CSeq_id& aln_id,
369                                            list<string> &use_this_seqid,
370                                            SDeflineInfo* sdl,
371                                            int blast_rank)
372 {
373     if( !handle ) return; // invalid handle.
374 
375     const CRef<CBlast_def_line_set> bdlRef = CSeqDB::ExtractBlastDefline(handle);
376     const list< CRef< CBlast_def_line > > &bdl = (bdlRef.Empty()) ? list< CRef< CBlast_def_line > >() : bdlRef->Get();
377 
378     CRef<CSeq_id> wid;
379     sdl->defline = NcbiEmptyString;
380 
381     sdl->gi = ZERO_GI;
382     sdl->id_url = NcbiEmptyString;
383     sdl->score_url = NcbiEmptyString;
384     sdl->linkout = 0;
385     sdl->is_new = false;
386     sdl->was_checked = false;
387     sdl->taxid = ZERO_TAX_ID;
388     //get psiblast stuff
389 
390     if(m_SeqStatus){
391         string aln_id_str;
392         aln_id.GetLabel(&aln_id_str, CSeq_id::eContent);
393         PsiblastSeqStatus seq_status = eUnknown;
394 
395         TIdString2SeqStatus::const_iterator itr = m_SeqStatus->find(aln_id_str);
396         if ( itr != m_SeqStatus->end() ){
397             seq_status = itr->second;
398         }
399         if((m_PsiblastStatus == eFirstPass) ||
400            ((m_PsiblastStatus == eRepeatPass) && (seq_status & eRepeatSeq))
401            || ((m_PsiblastStatus == eNewPass) && (seq_status & eRepeatSeq))){
402             if(!(seq_status & eGoodSeq)){
403                 sdl->is_new = true;
404             }
405             if(seq_status & eCheckedSeq){
406                 sdl->was_checked = true;
407             }
408         }
409     }
410     //get id (sdl->id, sdl-gi)
411     sdl->id = CAlignFormatUtil::GetDisplayIds(handle,aln_id,use_this_seqid,&sdl->gi,&sdl->taxid,&sdl->textSeqID);
412     sdl->alnIDFasta = aln_id.AsFastaString();
413 
414     //get linkout****
415     if((m_Option & eLinkout)){
416         bool getIdentProteins = !m_IsDbNa && bdl.size() > 1;
417         for(list< CRef< CBlast_def_line > >::const_iterator iter = bdl.begin();
418             iter != bdl.end(); iter++){
419             CBioseq::TId& cur_id = (CBioseq::TId &)(*iter)->GetSeqid();
420             TGi cur_gi =  FindGi(cur_id);
421             bool match = false;
422             if(!use_this_seqid.empty()){
423                 wid = FindBestChoice(cur_id, CSeq_id::WorstRank);
424                 match = CAlignFormatUtil::MatchSeqInSeqList(cur_gi, wid, use_this_seqid);
425             }
426             if((use_this_seqid.empty() && sdl->gi == cur_gi) || match) {
427                 x_InitLinkOutInfo(sdl,cur_id,blast_rank,getIdentProteins); //only initialized if !(m_DeflineTemplates->advancedView && !is_mixed_database)
428                 break;
429             }
430         }
431         //The following is the case when for whatever reason the seq is not found in Blast database (bdl list is empty) and is retrived from genbank
432         if(bdl.size()  == 0) {
433             CBioseq::TId& cur_id = (CBioseq::TId &) handle.GetBioseqCore()->GetId();
434             x_InitLinkOutInfo(sdl,cur_id,blast_rank,getIdentProteins); //only initialized if !(m_DeflineTemplates->advancedView && !is_mixed_database)
435         }
436     }
437 
438     //get score and id url
439     if(m_Option & (eHtml | eShowCSVDescr)){
440         bool useTemplates = m_DeflineTemplates != NULL;
441         bool advancedView = (m_DeflineTemplates != NULL) ? m_DeflineTemplates->advancedView : false;
442         string accession;
443         sdl->id->GetLabel(&accession, CSeq_id::eContent);
444         sdl->score_url = !useTemplates ? "<a href=#" : "";
445         if (!useTemplates && m_PositionIndex >= 0) {
446             sdl->score_url += "_" + NStr::IntToString(m_PositionIndex) + "_";
447         }
448         sdl->score_url += sdl->gi == ZERO_GI ? accession :
449             NStr::NumericToString(sdl->gi);
450         sdl->score_url += !useTemplates ? ">" : "";
451 
452 		string user_url = m_Reg.get() ? m_Reg->Get(m_BlastType, "TOOL_URL") : kEmptyStr;
453 		//blast_rank = num_align + 1
454 		CRange<TSeqPos> seqRange = ((int)m_ScoreList.size() >= blast_rank)? m_ScoreList[blast_rank - 1]->subjRange : CRange<TSeqPos>(0,0);
455         bool flip = ((int)m_ScoreList.size() >= blast_rank) ? m_ScoreList[blast_rank - 1]->flip : false;
456         CAlignFormatUtil::SSeqURLInfo seqUrlInfo(user_url,m_BlastType,m_IsDbNa,m_Database,m_Rid,
457                                                  m_QueryNumber,sdl->gi, accession, 0, //linkout = 0, not used any more
458                                                  blast_rank,false,(m_Option & eNewTargetWindow) ? true : false,seqRange,flip);
459         seqUrlInfo.resourcesUrl = m_Reg.get() ? m_Reg->Get(m_BlastType, "RESOURCE_URL") : kEmptyStr;
460         seqUrlInfo.useTemplates = useTemplates;
461         seqUrlInfo.advancedView = advancedView;
462 
463         if(sdl->id->Which() == CSeq_id::e_Local && (m_Option & eHtml)){
464             //get taxid info for local blast db such as igblast db
465             ITERATE(list<CRef<CBlast_def_line> >, iter_bdl, bdl) {
466                 if ((*iter_bdl)->IsSetTaxid() && (*iter_bdl)->CanGetTaxid()){
467                     seqUrlInfo.taxid = (*iter_bdl)->GetTaxid();
468                     break;
469                 }
470             }
471         }
472         sdl->id_url = CAlignFormatUtil::GetIDUrl(&seqUrlInfo,aln_id,*m_ScopeRef);
473     }
474 
475     //get defline
476     sdl->defline = CDeflineGenerator().GenerateDefline(m_ScopeRef->GetBioseqHandle(*(sdl->id)));
477 	sdl->fullDefline = sdl->defline;
478     if (!(bdl.empty())) {
479         for(list< CRef< CBlast_def_line > >::const_iterator iter = bdl.begin();
480             iter != bdl.end(); iter++){
481             const CBioseq::TId& cur_id = (*iter)->GetSeqid();
482             TGi cur_gi =  FindGi(cur_id);
483             wid = FindBestChoice(cur_id, CSeq_id::WorstRank);
484             bool match = CAlignFormatUtil::MatchSeqInSeqList(cur_gi, wid, use_this_seqid);
485             if(use_this_seqid.empty() || match) {
486 
487                 if((*iter)->IsSetTitle()){
488                     bool id_used_already = false;
489                     ITERATE(CBioseq::TId, iter_id, cur_id) {
490                         if ((*iter_id)->Match(*(sdl->id))) {
491                             id_used_already = true;
492                             break;
493                         }
494                     }
495                     if (!id_used_already) {
496                         string concat_acc;
497                         wid = FindBestChoice(cur_id, CSeq_id::WorstRank);
498                         wid->GetLabel(&concat_acc, CSeq_id::eFasta, 0);
499                         if( (m_Option & eShowGi) && cur_gi > ZERO_GI){
500                             sdl->fullDefline =  sdl->fullDefline + " >" + "gi|" +
501                                 NStr::NumericToString(cur_gi) + "|" +
502                                 concat_acc + " " + (*iter)->GetTitle();
503                         } else {
504                             sdl->fullDefline = sdl->fullDefline + " >" + concat_acc +
505                                 " " +
506                                 (*iter)->GetTitle();
507                         }
508                         if(sdl->fullDefline.length() > kMaxDescrLength) {
509                             break;
510                         }
511                     }
512                 }
513             }
514         }
515     }
516 }
517 
518 //Constructor
CShowBlastDefline(const CSeq_align_set & seqalign,CScope & scope,size_t line_length,size_t num_defline_to_show,bool translated_nuc_alignment,CRange<TSeqPos> * master_range)519 CShowBlastDefline::CShowBlastDefline(const CSeq_align_set& seqalign,
520                                      CScope& scope,
521                                      size_t line_length,
522                                      size_t num_defline_to_show,
523                                      bool translated_nuc_alignment,
524                                      CRange<TSeqPos>* master_range):
525 
526     m_AlnSetRef(&seqalign),
527     m_ScopeRef(&scope),
528     m_LineLen(line_length),
529     m_NumToShow(num_defline_to_show),
530     m_TranslatedNucAlignment(translated_nuc_alignment),
531     m_SkipFrom(-1),
532     m_SkipTo(-1),
533     m_MasterRange(master_range),
534     m_LinkoutDB(NULL)
535 {
536 
537     m_Option = 0;
538     m_EntrezTerm = NcbiEmptyString;
539     m_QueryNumber = 0;
540     m_Rid = NcbiEmptyString;
541     m_CddRid = NcbiEmptyString;
542     m_IsDbNa = true;
543     m_BlastType = NcbiEmptyString;
544     m_PsiblastStatus = eFirstPass;
545     m_SeqStatus = NULL;
546     m_Ctx = NULL;
547     m_StructureLinkout = false;
548     if(m_MasterRange) {
549         if(m_MasterRange->GetFrom() >= m_MasterRange->GetTo()) {
550             m_MasterRange = NULL;
551         }
552     }
553     m_DeflineTemplates = NULL;
554     m_StartIndex = 0;
555     m_PositionIndex = -1;
556     m_AppLogInfo = NULL;
557 }
558 
~CShowBlastDefline()559 CShowBlastDefline::~CShowBlastDefline()
560 {
561     ITERATE(vector<SScoreInfo*>, iter, m_ScoreList){
562         delete *iter;
563     }
564 
565     ITERATE(vector<SDeflineFormattingInfo*>, iter, m_SdlFormatInfoVec){
566         delete *iter;
567     }
568 
569 }
570 
571 
Init(void)572 void CShowBlastDefline::Init(void)
573 {
574 	if (m_DeflineTemplates != NULL) {
575         x_InitDeflineTable();
576     }
577     else {
578         x_InitDefline();
579     }
580 }
581 
582 
Display(CNcbiOstream & out)583 void CShowBlastDefline::Display(CNcbiOstream & out)
584 {
585     if (m_DeflineTemplates != NULL) {
586         if(m_Option & eHtml) {//text
587             x_DisplayDeflineTableTemplate(out);
588         }
589         else if(m_Option & eShowCSVDescr) {
590             x_DisplayDeflineTableTemplateCSV(out);
591         }
592         else {//text
593             x_DisplayDeflineTableTemplateText(out);
594         }
595     }
596     else {
597         x_DisplayDefline(out);
598     }
599 }
600 
x_CheckForStructureLink()601 bool CShowBlastDefline::x_CheckForStructureLink()
602 {
603       bool struct_linkout = false;
604       int count = 0;
605       const int k_CountMax = 200; // Max sequences to check.
606 
607       ITERATE(vector<SScoreInfo*>, iter, m_ScoreList) {
608           const CBioseq_Handle& handle = m_ScopeRef->GetBioseqHandle(*(*iter)->id);
609 	  if( !handle ) continue;  // invalid handle.
610           const CRef<CBlast_def_line_set> bdlRef = CSeqDB::ExtractBlastDefline(handle);
611           const list< CRef< CBlast_def_line > > &bdl = (bdlRef.Empty()) ? list< CRef< CBlast_def_line > >() : bdlRef->Get();
612           for(list< CRef< CBlast_def_line > >::const_iterator bdl_iter = bdl.begin();
613               bdl_iter != bdl.end() && struct_linkout == false; bdl_iter++){
614               if ((*bdl_iter)->IsSetLinks())
615               {
616                  for (list< int >::const_iterator link_iter = (*bdl_iter)->GetLinks().begin();
617                       link_iter != (*bdl_iter)->GetLinks().end(); link_iter++)
618                  {
619                       if (*link_iter & eStructure) {
620                          struct_linkout = true;
621                          break;
622                       }
623                  }
624               }
625           }
626           if (struct_linkout == true || count > k_CountMax)
627             break;
628           count++;
629       }
630       return struct_linkout;
631 }
632 
633 //size_t max_score_len = kBits.size(), max_evalue_len = kValue.size();
634 //size_t max_sum_n_len =1;
635 //size_t m_MaxScoreLen , m_MaxEvalueLen,m_MaxSumNLen;
636 //bool m_StructureLinkout
x_InitDefline(void)637 void CShowBlastDefline::x_InitDefline(void)
638 {
639     /*Note we can't just show each alnment as we go because we will
640       need to show defline only once for all hsp's with the same id*/
641 
642     bool is_first_aln = true;
643     size_t num_align = 0;
644     CConstRef<CSeq_id> previous_id, subid;
645 
646     m_MaxScoreLen = kBits.size();
647     m_MaxEvalueLen = kValue.size();
648     m_MaxSumNLen =1;
649 
650     m_MaxPercentIdentityLen = kIdentity.size();
651     m_MaxQueryCoverLen = kCoverage.size();
652     m_MaxTotalScoreLen = kTotal.size();
653 
654 
655 
656     if(m_Option & eHtml){
657         m_ConfigFile.reset(new CNcbiIfstream(".ncbirc"));
658         m_Reg.reset(new CNcbiRegistry(*m_ConfigFile));
659     }
660     bool master_is_na = false;
661     //prepare defline
662 
663     int ialn = 0;
664     for (CSeq_align_set::Tdata::const_iterator
665              iter = m_AlnSetRef->Get().begin();
666          iter != m_AlnSetRef->Get().end() && num_align < m_NumToShow;
667          iter++, ialn++){
668         if (ialn < m_SkipTo && ialn >= m_SkipFrom) continue;
669 
670         if (is_first_aln) {
671             _ASSERT(m_ScopeRef);
672             CBioseq_Handle bh = m_ScopeRef->GetBioseqHandle((*iter)->GetSeq_id(0));
673             _ASSERT(bh);
674             master_is_na = bh.GetBioseqCore()->IsNa();
675         }
676         subid = &((*iter)->GetSeq_id(1));
677         if(is_first_aln || (!is_first_aln && !subid->Match(*previous_id))) {
678             SScoreInfo* sci = x_GetScoreInfo(**iter, num_align);
679             if(sci){
680                 m_ScoreList.push_back(sci);
681                 if(m_MaxScoreLen < sci->bit_string.size()){
682                     m_MaxScoreLen = sci->bit_string.size();
683                 }
684                 if(m_MaxEvalueLen < sci->evalue_string.size()){
685                     m_MaxEvalueLen = sci->evalue_string.size();
686                 }
687 
688                 if(m_MaxTotalScoreLen < sci->total_bit_string.size()){
689                     m_MaxTotalScoreLen = sci->total_bit_string.size();
690                 }
691                 int percent_identity = CAlignFormatUtil::GetPercentMatch(sci->match,sci->align_length);
692                 if(m_MaxPercentIdentityLen < NStr::IntToString(percent_identity).size()) {
693                     m_MaxPercentIdentityLen = NStr::IntToString(percent_identity).size();
694                 }
695 
696                 if( m_MaxSumNLen < NStr::IntToString(sci->sum_n).size()){
697                     m_MaxSumNLen = NStr::IntToString(sci->sum_n).size();
698                 }
699             }
700             num_align++;
701         }
702         is_first_aln = false;
703         previous_id = subid;
704 
705     }
706 
707 
708     if((m_Option & eLinkout) && (m_Option & eHtml) && !m_IsDbNa && !master_is_na)
709         m_StructureLinkout = x_CheckForStructureLink();
710 }
711 
712 
713 
x_DisplayDefline(CNcbiOstream & out)714 void CShowBlastDefline::x_DisplayDefline(CNcbiOstream & out)
715 {
716     bool use_long_seqids = (m_Option & eLongSeqId) != 0;
717 
718     if(!(m_Option & eNoShowHeader)) {
719         if((m_PsiblastStatus == eFirstPass) ||
720            (m_PsiblastStatus == eRepeatPass)){
721             CAlignFormatUtil::AddSpace(out, m_LineLen + kTwoSpaceMargin.size());
722             if(m_Option & eHtml){
723                 if((m_Option & eShowNewSeqGif)){
724                     out << kPsiblastNewSeqBackgroundGif;
725                     out << kPsiblastCheckedBackgroundGif;
726                 }
727                 if (m_Option & eCheckbox) {
728                     out << kPsiblastNewSeqBackgroundGif;
729                     out << kPsiblastCheckedBackgroundGif;
730                 }
731             }
732             out << kScore;
733             CAlignFormatUtil::AddSpace(out, m_MaxScoreLen - kScore.size());
734             CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
735 
736 
737             if (m_Option & eShowTotalScore) {
738                 out << kTotal;
739                 CAlignFormatUtil::AddSpace(out, m_MaxTotalScoreLen - kTotal.size());
740                 CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
741             }
742             if (m_Option & eShowQueryCoverage) {
743                 out << kQueryCov;
744                 CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
745             }
746 
747             CAlignFormatUtil::AddSpace(out, 2); //E align to l of value
748             out << kE;
749 
750             if (m_Option & eShowPercentIdent) {
751                 CAlignFormatUtil::AddSpace(out, m_MaxEvalueLen - kValue.size());
752                 CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
753                 CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
754                 CAlignFormatUtil::AddSpace(out, kOneSpaceMargin.size());
755                 out << kMax;//"Max" - "ident" -second line
756             }
757 
758             out << "\n";
759             out << kHeader;
760             if(m_Option & eHtml){
761                 if((m_Option & eShowNewSeqGif)){
762                     out << kPsiblastNewSeqBackgroundGif;
763                     out << kPsiblastCheckedBackgroundGif;
764                 }
765                 if (m_Option & eCheckbox) {
766                     out << kPsiblastNewSeqBackgroundGif;
767                     out << kPsiblastCheckedBackgroundGif;
768                 }
769             }
770             CAlignFormatUtil::AddSpace(out, m_LineLen - kHeader.size());
771             CAlignFormatUtil::AddSpace(out, kOneSpaceMargin.size());
772             out << kBits;
773             //in case m_MaxScoreLen > kBits.size()
774             CAlignFormatUtil::AddSpace(out, m_MaxScoreLen - kBits.size());
775             CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
776 
777 
778             if (m_Option & eShowTotalScore) {
779                 CAlignFormatUtil::AddSpace(out, kOneSpaceMargin.size());
780                 out << kScoreLine2;//"score"
781                 CAlignFormatUtil::AddSpace(out, m_MaxTotalScoreLen - kTotal.size());
782                 CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
783             }
784             if (m_Option & eShowQueryCoverage) {
785                 out << kQueryCovLine2;//"cov"
786                 CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
787                 CAlignFormatUtil::AddSpace(out, kOneSpaceMargin.size());
788             }
789 
790             out << kValue;
791             if((m_Option & eShowSumN) || (m_Option & eShowPercentIdent)){
792                 CAlignFormatUtil::AddSpace(out, m_MaxEvalueLen - kValue.size());
793                 CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
794             }
795             if(m_Option & eShowSumN){
796                 out << kN;
797             }
798             if (m_Option & eShowPercentIdent) {
799                 out << kIdentLine2;//"ident"
800             }
801             out << "\n";
802         }
803         if(m_PsiblastStatus == eRepeatPass){
804             out << kRepeatHeader << "\n";
805         }
806         if(m_PsiblastStatus == eNewPass){
807             out << kNewSeqHeader << "\n";
808         }
809         out << "\n";
810     }
811 
812     bool first_new =true;
813     ITERATE(vector<SScoreInfo*>, iter, m_ScoreList){
814         SDeflineInfo* sdl = x_GetDeflineInfo((*iter)->id, (*iter)->use_this_seqid, (*iter)->blast_rank);
815         size_t line_length = 0;
816         string line_component;
817         if ((m_Option & eHtml) && (sdl->gi > ZERO_GI)){
818             if((m_Option & eShowNewSeqGif)) {
819                 if (sdl->is_new) {
820                     if (first_new) {
821                         first_new = false;
822                         out << kPsiblastEvalueLink;
823                     }
824                     out << kPsiblastNewSeqGif;
825 
826                 } else {
827                     out << kPsiblastNewSeqBackgroundGif;
828                 }
829                 if (sdl->was_checked) {
830                     out << kPsiblastCheckedGif;
831 
832                 } else {
833                     out << kPsiblastCheckedBackgroundGif;
834                 }
835             }
836             char buf[256];
837             if((m_Option & eCheckboxChecked)){
838                 sprintf(buf, kPsiblastCheckboxChecked.c_str(), sdl->gi,
839                         sdl->gi);
840                 out << buf;
841             } else if (m_Option & eCheckbox) {
842                 sprintf(buf, kPsiblastCheckbox.c_str(), sdl->gi);
843                 out << buf;
844             }
845         }
846 
847 
848         if((m_Option & eHtml) && (sdl->id_url != NcbiEmptyString)) {
849             out << sdl->id_url;
850         }
851         if(m_Option & eShowGi){
852             if(sdl->gi > ZERO_GI){
853                 line_component = "gi|" + NStr::NumericToString(sdl->gi) + "|";
854                 out << line_component;
855                 line_length += line_component.size();
856             }
857         }
858         if(!sdl->id.Empty()){
859             if(!(sdl->id->AsFastaString().find("gnl|BL_ORD_ID") != string::npos ||
860 		sdl->id->AsFastaString().find("lcl|Subject_") != string::npos)){
861                 string idStr;
862                 if (use_long_seqids || ((m_Option & eShowGi) && !sdl->id->IsGi())) {
863                     idStr = sdl->id->AsFastaString();
864                 }
865                 else {
866                     idStr = CAlignFormatUtil::GetBareId(*sdl->id) + " ";
867                 }
868             	if (strncmp(idStr.c_str(), "lcl|", 4) == 0) {
869             		idStr = sdl->id->AsFastaString().substr(4);
870             	}
871                 out << idStr;
872                 line_length += idStr.size();
873             }
874         }
875         if((m_Option & eHtml) && (sdl->id_url != NcbiEmptyString)) {
876             out << "</a>";
877         }
878         line_component = (line_component.empty() ? "" : "  ") + sdl->defline;
879         string actual_line_component;
880         if(line_component.size()+line_length > m_LineLen){
881             actual_line_component = line_component.substr(0, m_LineLen -
882                                                           line_length - 3);
883             actual_line_component += kEllipsis;
884         } else {
885             actual_line_component = line_component.substr(0, m_LineLen -
886                                                           line_length);
887         }
888         if (m_Option & eHtml) {
889             out << CHTMLHelper::HTMLEncode(actual_line_component);
890         } else {
891             out << actual_line_component;
892         }
893         line_length += actual_line_component.size();
894         //pad the short lines
895         CAlignFormatUtil::AddSpace(out, m_LineLen - line_length);
896         out << kTwoSpaceMargin;
897 
898         if((m_Option & eHtml) && (sdl->score_url != NcbiEmptyString)) {
899             out << sdl->score_url;
900         }
901         out << (*iter)->bit_string;
902         if((m_Option & eHtml) && (sdl->score_url != NcbiEmptyString)) {
903             out << "</a>";
904         }
905         CAlignFormatUtil::AddSpace(out, m_MaxScoreLen - (*iter)->bit_string.size());
906         if (m_Option & eShowTotalScore) {
907             out << kTwoSpaceMargin << kOneSpaceMargin << (*iter)->total_bit_string;
908             CAlignFormatUtil::AddSpace(out, m_MaxTotalScoreLen -
909                                    (*iter)->total_bit_string.size());
910         }
911 
912         if (m_Option & eShowQueryCoverage) {
913             //int percent_coverage = 100*(*iter)->master_covered_length/m_QueryLength;
914             int percent_coverage = (*iter)->percent_coverage;
915 
916             out << kTwoSpaceMargin << percent_coverage << "%";
917             //minus one due to % sign
918             CAlignFormatUtil::AddSpace(out, kQueryCov.size() -
919                                        NStr::IntToString(percent_coverage).size() - 1);
920         }
921 
922 
923         out << kTwoSpaceMargin << (*iter)->evalue_string;
924         CAlignFormatUtil::AddSpace(out, m_MaxEvalueLen - (*iter)->evalue_string.size());
925 
926         if(m_Option & eShowSumN){
927             out << kTwoSpaceMargin << (*iter)->sum_n;
928             CAlignFormatUtil::AddSpace(out, m_MaxSumNLen -
929                      NStr::IntToString((*iter)->sum_n).size());
930         }
931         if(m_Option & eShowPercentIdent){
932             int percent_identity =(int) (0.5 + (*iter)->percent_identity);
933             if(percent_identity > 100) {
934                 percent_identity = min(99, percent_identity);
935             }
936             out << kTwoSpaceMargin << percent_identity <<"%";
937             CAlignFormatUtil::AddSpace(out, m_MaxPercentIdentityLen -
938                                            NStr::IntToString(percent_identity).size());
939         }
940         if((m_Option & eLinkout) && (m_Option & eHtml)){
941             bool is_first = true;
942             ITERATE(list<string>, iter_linkout, sdl->linkout_list){
943                 if(is_first){
944                     out << kOneSpaceMargin;
945                     is_first = false;
946                 }
947                 out << *iter_linkout;
948             }
949         }
950         out <<"\n";
951         delete sdl;
952     }
953 }
954 
DisplayBlastDefline(CNcbiOstream & out)955 void CShowBlastDefline::DisplayBlastDefline(CNcbiOstream & out)
956 {
957     x_InitDeflineTable();
958     if(m_StructureLinkout){
959         char buf[512];
960         string  mapCDDParams = (NStr::Find(m_CddRid,"data_cache") != NPOS) ? "" : "blast_CD_RID=" + m_CddRid;
961         sprintf(buf, kStructure_Overview, m_Rid.c_str(),
962                         0, 0, mapCDDParams.c_str(), "overview",
963                         m_EntrezTerm == NcbiEmptyString ?
964                         "none": m_EntrezTerm.c_str());
965         out << buf <<"\n\n";
966     }
967     x_DisplayDefline(out);
968 }
969 
s_DisplayDescrColumnHeader(CNcbiOstream & out,int currDisplaySort,string query_buf,int columnDisplSort,int columnHspSort,string columnText,int max_data_len,bool html)970 static void s_DisplayDescrColumnHeader(CNcbiOstream & out,
971                                        int currDisplaySort,
972                                        string query_buf,
973                                        int columnDisplSort,
974                                        int columnHspSort,
975                                        string columnText,
976                                        int max_data_len,
977                                        bool html)
978 
979 
980 {
981     if (html) {
982         if(currDisplaySort == columnDisplSort) {
983             out << "<th class=\"sel\">";
984         }
985         else {
986             out << "<th>";
987         }
988 
989         out << "<a href=\"Blast.cgi?"
990             << "CMD=Get&" << query_buf
991             << "&DISPLAY_SORT=" << columnDisplSort
992             << "&HSP_SORT=" << columnHspSort
993             << "#sort_mark\">";
994 
995     }
996     out << columnText;
997     if (html) {
998         out << "</a></th>\n";
999     }
1000     else {
1001         CAlignFormatUtil::AddSpace(out, max_data_len - columnText.size());
1002         CAlignFormatUtil::AddSpace(out, kTwoSpaceMargin.size());
1003     }
1004 
1005 }
1006 
x_InitDeflineTable(void)1007 void CShowBlastDefline::x_InitDeflineTable(void)
1008 {
1009     /*Note we can't just show each alnment as we go because we will
1010       need to show defline only once for all hsp's with the same id*/
1011 
1012     bool is_first_aln = true;
1013     size_t num_align = 0;
1014     CConstRef<CSeq_id> previous_id, subid;
1015     m_MaxScoreLen = kBits.size();
1016     m_MaxEvalueLen = kValue.size();
1017     m_MaxSumNLen =1;
1018     m_MaxTotalScoreLen = kTotal.size();
1019     m_MaxPercentIdentityLen = kIdentity.size();
1020     int percent_identity = 0;
1021     m_MaxQueryCoverLen = kQueryCov.size();
1022 
1023 
1024     if(m_Option & eHtml){
1025         m_ConfigFile.reset(new CNcbiIfstream(".ncbirc"));
1026         m_Reg.reset(new CNcbiRegistry(*m_ConfigFile));
1027         if(!m_BlastType.empty()) m_LinkoutOrder = m_Reg->Get(m_BlastType,"LINKOUT_ORDER");
1028         m_LinkoutOrder = (!m_LinkoutOrder.empty()) ? m_LinkoutOrder : kLinkoutOrderStr;
1029     }
1030 
1031     CSeq_align_set hit;
1032     m_QueryLength = 1;
1033     bool master_is_na = false;
1034     //prepare defline
1035 
1036     int ialn = 0;
1037     for (CSeq_align_set::Tdata::const_iterator
1038              iter = m_AlnSetRef->Get().begin();
1039          iter != m_AlnSetRef->Get().end() && num_align < m_NumToShow;
1040          iter++, ialn++){
1041 
1042         if (ialn < m_SkipTo && ialn >= m_SkipFrom) continue;
1043         if (is_first_aln) {
1044             m_QueryLength = m_MasterRange ?
1045                 m_MasterRange->GetLength() :
1046                 m_ScopeRef->GetBioseqHandle((*iter)->GetSeq_id(0)).GetBioseqLength();
1047             master_is_na = m_ScopeRef->GetBioseqHandle((*iter)->GetSeq_id(0)).
1048                 GetBioseqCore()->IsNa();
1049         }
1050 
1051         subid = &((*iter)->GetSeq_id(1));
1052 
1053         // This if statement is working on the last CSeq_align_set, stored in "hit"
1054         // This is confusing and the loop should probably be restructured at some point.
1055         if(!is_first_aln && !(subid->Match(*previous_id))) {
1056             SScoreInfo* sci = x_GetScoreInfoForTable(hit, num_align);
1057             if(sci){
1058                 m_ScoreList.push_back(sci);
1059                 if(m_MaxScoreLen < sci->bit_string.size()){
1060                     m_MaxScoreLen = sci->bit_string.size();
1061                 }
1062                 if(m_MaxTotalScoreLen < sci->total_bit_string.size()){
1063                     m_MaxTotalScoreLen = sci->total_bit_string.size();
1064                 }
1065                 percent_identity = CAlignFormatUtil::GetPercentMatch(sci->match,sci->align_length);
1066                 if(m_MaxPercentIdentityLen < NStr::IntToString(percent_identity).size()) {
1067                     m_MaxPercentIdentityLen = NStr::IntToString(percent_identity).size();
1068                 }
1069                 if(m_MaxEvalueLen < sci->evalue_string.size()){
1070                     m_MaxEvalueLen = sci->evalue_string.size();
1071                 }
1072 
1073                 if( m_MaxSumNLen < NStr::IntToString(sci->sum_n).size()){
1074                     m_MaxSumNLen = NStr::IntToString(sci->sum_n).size();
1075                 }
1076                 hit.Set().clear();
1077             }
1078 
1079             num_align++; // Only increment if new subject ID found.
1080         }
1081         if (num_align < m_NumToShow) { //no adding if number to show already reached
1082             hit.Set().push_back(*iter);
1083         }
1084         is_first_aln = false;
1085         previous_id = subid;
1086     }
1087 
1088     //the last hit
1089     SScoreInfo* sci = x_GetScoreInfoForTable(hit, num_align);
1090     if(sci){
1091          m_ScoreList.push_back(sci);
1092         if(m_MaxScoreLen < sci->bit_string.size()){
1093             m_MaxScoreLen = sci->bit_string.size();
1094         }
1095         if(m_MaxTotalScoreLen < sci->total_bit_string.size()){
1096             m_MaxScoreLen = sci->total_bit_string.size();
1097         }
1098         percent_identity = CAlignFormatUtil::GetPercentMatch(sci->match,sci->align_length);
1099         if(m_MaxPercentIdentityLen < NStr::IntToString(percent_identity).size()) {
1100             m_MaxPercentIdentityLen =  NStr::IntToString(percent_identity).size();
1101         }
1102         if(m_MaxEvalueLen < sci->evalue_string.size()){
1103             m_MaxEvalueLen = sci->evalue_string.size();
1104         }
1105 
1106         if( m_MaxSumNLen < NStr::IntToString(sci->sum_n).size()){
1107             m_MaxSumNLen = NStr::IntToString(sci->sum_n).size();
1108         }
1109         hit.Set().clear();
1110     }
1111 
1112     if((m_Option & eLinkout) && (m_Option & eHtml) && !m_IsDbNa && !master_is_na)
1113         m_StructureLinkout = x_CheckForStructureLink();
1114 
1115 }
1116 
x_DisplayDeflineTable(CNcbiOstream & out)1117 void CShowBlastDefline::x_DisplayDeflineTable(CNcbiOstream & out)
1118 {
1119     //This is max number of columns in the table - later should be probably put in enum DisplayOption
1120         if((m_PsiblastStatus == eFirstPass) ||
1121            (m_PsiblastStatus == eRepeatPass)){
1122 
1123             if(m_Option & eHtml){
1124                 if((m_Option & eShowNewSeqGif)){
1125                     out << kPsiblastNewSeqBackgroundGif;
1126                     out << kPsiblastCheckedBackgroundGif;
1127                 }
1128                 if (m_Option & eCheckbox) {
1129                     out << kPsiblastNewSeqBackgroundGif;
1130                     out << kPsiblastCheckedBackgroundGif;
1131                 }
1132             }
1133             //This is done instead of code displaying titles
1134             if(!(m_Option & eNoShowHeader)) {
1135 
1136                 if(m_Option & eHtml){
1137 
1138                     out << "<b>";
1139                 }
1140                 out << kHeader << "\n";
1141                 if(m_Option & eHtml){
1142                     out << "</b>";
1143                     out << "(Click headers to sort columns)\n";
1144                 }
1145             }
1146             if(m_Option & eHtml){
1147                 out << "<div id=\"desctbl\">" << "<table id=\"descs\">" << "\n" << "<thead>" << "\n";
1148                 out << "<tr class=\"first\">" << "\n" << "<th>Accession</th>" << "\n" << "<th>Description</th>" << "\n";
1149             }
1150 
1151             string query_buf;
1152             map< string, string> parameters_to_change;
1153             parameters_to_change.insert(map<string, string>::
1154                                         value_type("DISPLAY_SORT", ""));
1155             parameters_to_change.insert(map<string, string>::
1156                                         value_type("HSP_SORT", ""));
1157             CAlignFormatUtil::BuildFormatQueryString(*m_Ctx,
1158                                                      parameters_to_change,
1159                                                      query_buf);
1160 
1161             parameters_to_change.clear();
1162 
1163             string display_sort_value = m_Ctx->GetRequestValue("DISPLAY_SORT").
1164                 GetValue();
1165             int display_sort = display_sort_value == NcbiEmptyString ?
1166                 CAlignFormatUtil::eEvalue : NStr::StringToInt(display_sort_value);
1167 
1168             s_DisplayDescrColumnHeader(out,display_sort,query_buf,CAlignFormatUtil::eHighestScore,CAlignFormatUtil::eScore,kMaxScore,m_MaxScoreLen,m_Option & eHtml);
1169 
1170             s_DisplayDescrColumnHeader(out,display_sort,query_buf,CAlignFormatUtil::eTotalScore,CAlignFormatUtil::eScore,kTotalScore,m_MaxTotalScoreLen,m_Option & eHtml);
1171             s_DisplayDescrColumnHeader(out,display_sort,query_buf,CAlignFormatUtil::eQueryCoverage,CAlignFormatUtil::eHspEvalue,kCoverage,m_MaxQueryCoverLen,m_Option & eHtml);
1172             s_DisplayDescrColumnHeader(out,display_sort,query_buf,CAlignFormatUtil::eEvalue,CAlignFormatUtil::eHspEvalue,kEvalue,m_MaxEvalueLen,m_Option & eHtml);
1173             if(m_Option & eShowPercentIdent){
1174                 s_DisplayDescrColumnHeader(out,display_sort,query_buf,CAlignFormatUtil::ePercentIdentity,CAlignFormatUtil::eHspPercentIdentity,kIdentity,m_MaxPercentIdentityLen,m_Option & eHtml);
1175             }else {
1176             }
1177 
1178             if(m_Option & eShowSumN){
1179                 out << "<th>" << kN << "</th>" << "\n";
1180 
1181             }
1182             if (m_Option & eLinkout) {
1183                 out << "<th>Links</th>\n";
1184                 out << "</tr>\n";
1185                 out << "</thead>\n";
1186             }
1187         }
1188 
1189     if (m_Option & eHtml) {
1190         out << "<tbody>\n";
1191     }
1192 
1193     x_DisplayDeflineTableBody(out);
1194 
1195     if (m_Option & eHtml) {
1196     out << "</tbody>\n</table></div>\n";
1197     }
1198 }
1199 
x_DisplayDeflineTableBody(CNcbiOstream & out)1200 void CShowBlastDefline::x_DisplayDeflineTableBody(CNcbiOstream & out)
1201 {
1202     int percent_identity = 0;
1203     int tableColNumber = (m_Option & eShowPercentIdent) ? 9 : 8;
1204     bool first_new =true;
1205     int prev_database_type = 0, cur_database_type = 0;
1206     bool is_first = true;
1207     // Mixed db is genomic + transcript and this does not apply to proteins.
1208     bool is_mixed_database = false;
1209     if (m_IsDbNa == true)
1210        is_mixed_database = CAlignFormatUtil::IsMixedDatabase(*m_Ctx);
1211 
1212     map< string, string> parameters_to_change;
1213     string query_buf;
1214     if (is_mixed_database && m_Option & eHtml) {
1215         parameters_to_change.insert(map<string, string>::
1216                                     value_type("DATABASE_SORT", ""));
1217         CAlignFormatUtil::BuildFormatQueryString(*m_Ctx,
1218                                                  parameters_to_change,
1219                                                  query_buf);
1220     }
1221     ITERATE(vector<SScoreInfo*>, iter, m_ScoreList){
1222         SDeflineInfo* sdl = x_GetDeflineInfo((*iter)->id, (*iter)->use_this_seqid, (*iter)->blast_rank);
1223         size_t line_length = 0;
1224         string line_component;
1225         cur_database_type = (sdl->linkout & eGenomicSeq);
1226         if (is_mixed_database) {
1227             if (is_first) {
1228                 if (m_Option & eHtml) {
1229                     out << "<tr>\n<th colspan=\"" << tableColNumber<< "\" class=\"l sp\">";
1230                 }
1231                 if (cur_database_type) {
1232                     out << "Genomic sequences";
1233                 } else {
1234                     out << "Transcripts";
1235                 }
1236                 if (!(m_Option & eHtml)) {
1237                     out << ":\n";
1238                 }
1239                 if (m_Option & eHtml) {
1240                     out << "</th></tr>\n";
1241                 }
1242             } else if (prev_database_type != cur_database_type) {
1243                 if (m_Option & eHtml) {
1244                     out << "<tr>\n<th colspan=\"" << tableColNumber<< "\" class=\"l sp\">";
1245                 }
1246                 if (cur_database_type) {
1247                     out << "Genomic sequences";
1248                 } else {
1249                     out << "Transcripts";
1250                 }
1251                 if (m_Option & eHtml) {
1252                     out << "<span class=\"slink\">"
1253                         << " [<a href=\"Blast.cgi?CMD=Get&"
1254                         << query_buf
1255                         << "&DATABASE_SORT=";
1256                     if (cur_database_type) {
1257                         out << CAlignFormatUtil::eGenomicFirst;
1258                     } else {
1259                         out << CAlignFormatUtil::eNonGenomicFirst;
1260                     }
1261                     out << "#sort_mark\">show first</a>]</span>";
1262                 }
1263                 else {
1264                     out << ":\n";
1265                 }
1266                 if (m_Option & eHtml) {
1267                     out << "</th></tr>\n";
1268                 }
1269             }
1270         }
1271         prev_database_type = cur_database_type;
1272         is_first = false;
1273         if (m_Option & eHtml) {
1274             out << "<tr>\n";
1275             out << "<td class=\"l\">\n";
1276         }
1277         if ((m_Option & eHtml) && (sdl->gi > ZERO_GI)){
1278             if((m_Option & eShowNewSeqGif)) {
1279                 if (sdl->is_new) {
1280                     if (first_new) {
1281                         first_new = false;
1282                         out << kPsiblastEvalueLink;
1283                     }
1284                     out << kPsiblastNewSeqGif;
1285 
1286                 } else {
1287                     out << kPsiblastNewSeqBackgroundGif;
1288                 }
1289                 if (sdl->was_checked) {
1290                     out << kPsiblastCheckedGif;
1291 
1292                 } else {
1293                     out << kPsiblastCheckedBackgroundGif;
1294                 }
1295             }
1296             char buf[256];
1297             if((m_Option & eCheckboxChecked)){
1298                 sprintf(buf, kPsiblastCheckboxChecked.c_str(), sdl->gi,
1299                         sdl->gi);
1300                 out << buf;
1301             } else if (m_Option & eCheckbox) {
1302                 sprintf(buf, kPsiblastCheckbox.c_str(), sdl->gi);
1303                 out << buf;
1304             }
1305         }
1306 
1307 
1308         if((m_Option & eHtml) && (sdl->id_url != NcbiEmptyString)) {
1309             out << sdl->id_url;
1310         }
1311         if(m_Option & eShowGi){
1312             if(sdl->gi > ZERO_GI){
1313                 line_component = "gi|" + NStr::NumericToString(sdl->gi) + "|";
1314                 out << line_component;
1315                 line_length += line_component.size();
1316             }
1317         }
1318         if(!sdl->id.Empty()){
1319             if(!(sdl->id->AsFastaString().find("gnl|BL_ORD_ID") != string::npos ||
1320 		sdl->id->AsFastaString().find("lcl|Subject_") != string::npos)){
1321                 string id_str;
1322                 sdl->id->GetLabel(&id_str, CSeq_id::eContent);
1323                 out << id_str;
1324                 line_length += id_str.size();
1325             }
1326         }
1327         if((m_Option & eHtml) && (sdl->id_url != NcbiEmptyString)) {
1328             out << "</a>";
1329         }
1330         if (m_Option & eHtml) {
1331             out << "</td><td class=\"lim l\"><div class=\"lim\">";
1332         }
1333         line_component = "  " + sdl->defline;
1334         string actual_line_component;
1335         actual_line_component = line_component;
1336 
1337         if (m_Option & eHtml) {
1338             out << CHTMLHelper::HTMLEncode(actual_line_component);
1339             out << "</div></td><td>";
1340         } else {
1341             out << actual_line_component;
1342         }
1343 
1344         if((m_Option & eHtml) && (sdl->score_url != NcbiEmptyString)) {
1345             out << sdl->score_url;
1346         }
1347         out << (*iter)->bit_string;
1348         if((m_Option & eHtml) && (sdl->score_url != NcbiEmptyString)) {
1349             out << "</a>";
1350         }
1351         if(m_Option & eHtml) {
1352             out << "</td>";
1353             out << "<td>" << (*iter)->total_bit_string << "</td>";
1354         }
1355         if (!(m_Option & eHtml)) {
1356             CAlignFormatUtil::AddSpace(out, m_MaxScoreLen - (*iter)->bit_string.size());
1357 
1358             out << kTwoSpaceMargin << kOneSpaceMargin << (*iter)->total_bit_string;
1359             CAlignFormatUtil::AddSpace(out, m_MaxTotalScoreLen -
1360                                    (*iter)->total_bit_string.size());
1361         }
1362 
1363                 int percent_coverage = 100*(*iter)->master_covered_length/m_QueryLength;
1364         if (m_Option & eHtml) {
1365             out << "<td>" << percent_coverage << "%</td>";
1366         }
1367         else {
1368             out << kTwoSpaceMargin << percent_coverage << "%";
1369 
1370             //minus one due to % sign
1371             CAlignFormatUtil::AddSpace(out, m_MaxQueryCoverLen -
1372                                        NStr::IntToString(percent_coverage).size() - 1);
1373         }
1374 
1375         if (m_Option & eHtml) {
1376             out << "<td>" << (*iter)->evalue_string << "</td>";
1377         }
1378         else {
1379             out << kTwoSpaceMargin << (*iter)->evalue_string;
1380             CAlignFormatUtil::AddSpace(out, m_MaxEvalueLen - (*iter)->evalue_string.size());
1381         }
1382         if(m_Option & eShowPercentIdent){
1383             percent_identity = CAlignFormatUtil::GetPercentMatch((*iter)->match,(*iter)->align_length);
1384             if (m_Option & eHtml) {
1385                 out << "<td>" << percent_identity << "%</td>";
1386             }
1387             else {
1388                 out << kTwoSpaceMargin << percent_identity <<"%";
1389 
1390                 CAlignFormatUtil::AddSpace(out, m_MaxPercentIdentityLen -
1391                                            NStr::IntToString(percent_identity).size());
1392             }
1393         }
1394         //???
1395         if(m_Option & eShowSumN){
1396             if (m_Option & eHtml) {
1397                 out << "<td>";
1398             }
1399             out << kTwoSpaceMargin << (*iter)->sum_n;
1400             if (m_Option & eHtml) {
1401                 out << "</td>";
1402             } else {
1403                 CAlignFormatUtil::AddSpace(out, m_MaxSumNLen -
1404                                            NStr::IntToString((*iter)->sum_n).size());
1405             }
1406         }
1407 
1408         if((m_Option & eLinkout) && (m_Option & eHtml)){
1409 
1410             out << "<td>";
1411             bool first_time = true;
1412             ITERATE(list<string>, iter_linkout, sdl->linkout_list){
1413                 if(first_time){
1414                     out << kOneSpaceMargin;
1415                     first_time = false;
1416                 }
1417                 out << *iter_linkout;
1418             }
1419             out << "</td>";
1420         }
1421         if (m_Option & eHtml) {
1422             out << "</tr>";
1423         }
1424         if (!(m_Option & eHtml)) {
1425             out <<"\n";
1426         }
1427         delete sdl;
1428     }
1429 }
1430 
1431 
DisplayBlastDeflineTable(CNcbiOstream & out)1432 void CShowBlastDefline::DisplayBlastDeflineTable(CNcbiOstream & out)
1433 {
1434     x_InitDeflineTable();
1435     if(m_StructureLinkout){
1436         char buf[512];
1437         sprintf(buf, kStructure_Overview, m_Rid.c_str(),
1438                         0, 0, m_CddRid.c_str(), "overview",
1439                         m_EntrezTerm == NcbiEmptyString ?
1440                         "none": m_EntrezTerm.c_str());
1441         out << buf <<"\n\n";
1442     }
1443     x_DisplayDeflineTable(out);
1444 }
1445 
1446 CShowBlastDefline::SScoreInfo*
x_GetScoreInfo(const CSeq_align & aln,int blast_rank)1447 CShowBlastDefline::x_GetScoreInfo(const CSeq_align& aln, int blast_rank)
1448 {
1449     string evalue_buf, bit_score_buf, total_bit_score_buf, raw_score_buf;
1450     int score = 0;
1451     double bits = 0;
1452     double evalue = 0;
1453     int sum_n = 0;
1454     int num_ident = 0;
1455     list<string> use_this_seq;
1456 
1457     use_this_seq.clear();
1458     CAlignFormatUtil::GetAlnScores(aln, score, bits, evalue, sum_n,
1459                                        num_ident, use_this_seq);
1460 
1461     CAlignFormatUtil::GetScoreString(evalue, bits, 0, score,
1462                               evalue_buf, bit_score_buf, total_bit_score_buf,
1463                               raw_score_buf);
1464 
1465     auto_ptr<SScoreInfo> score_info(new SScoreInfo);
1466     score_info->sum_n = sum_n == -1 ? 1:sum_n ;
1467     score_info->id = &(aln.GetSeq_id(1));
1468 
1469     score_info->use_this_seqid = use_this_seq;
1470 
1471     score_info->bit_string = bit_score_buf;
1472     score_info->raw_score_string = raw_score_buf;
1473     score_info->evalue_string = evalue_buf;
1474     score_info->id = &(aln.GetSeq_id(1));
1475     score_info->blast_rank = blast_rank+1;
1476     score_info->subjRange = CRange<TSeqPos>(0,0);
1477     score_info->flip = false;
1478     return score_info.release();
1479 }
1480 
1481 CShowBlastDefline::SScoreInfo*
x_GetScoreInfoForTable(const CSeq_align_set & aln,int blast_rank)1482 CShowBlastDefline::x_GetScoreInfoForTable(const CSeq_align_set& aln, int blast_rank)
1483 {
1484     string evalue_buf, bit_score_buf, total_bit_score_buf, raw_score_buf;
1485 
1486     if(aln.Get().empty())
1487         return NULL;
1488 
1489     auto_ptr<SScoreInfo> score_info(new SScoreInfo);
1490 
1491     auto_ptr<CAlignFormatUtil::SSeqAlignSetCalcParams> seqSetInfo( CAlignFormatUtil::GetSeqAlignSetCalcParamsFromASN(aln));
1492     if(seqSetInfo->hspNum == 0) {//calulated params are not in ASN - calculate now
1493         seqSetInfo.reset( CAlignFormatUtil::GetSeqAlignSetCalcParams(aln,m_QueryLength,m_TranslatedNucAlignment));
1494     }
1495 
1496     CAlignFormatUtil::GetScoreString(seqSetInfo->evalue, seqSetInfo->bit_score, seqSetInfo->total_bit_score, seqSetInfo->raw_score,
1497                               evalue_buf, bit_score_buf, total_bit_score_buf,
1498                               raw_score_buf);
1499     score_info->id = seqSetInfo->id;
1500 
1501     score_info->total_bit_string = total_bit_score_buf;
1502     score_info->bit_string = bit_score_buf;
1503     score_info->evalue_string = evalue_buf;
1504     score_info->percent_coverage = seqSetInfo->percent_coverage;
1505     score_info->percent_identity = seqSetInfo->percent_identity;
1506     score_info->hspNum = seqSetInfo->hspNum;
1507     score_info->totalLen = seqSetInfo->totalLen;
1508 
1509     score_info->use_this_seqid = seqSetInfo->use_this_seq;
1510     score_info->sum_n = seqSetInfo->sum_n == -1 ? 1:seqSetInfo->sum_n ;
1511 
1512     score_info->raw_score_string = raw_score_buf;//check if used
1513     score_info->match = seqSetInfo->match; //check if used
1514     score_info->align_length = seqSetInfo->align_length;//check if used
1515     score_info->master_covered_length = seqSetInfo->master_covered_length;//check if used
1516 
1517 
1518     score_info->subjRange = seqSetInfo->subjRange;    //check if used
1519     score_info->flip = seqSetInfo->flip;//check if used
1520 
1521     score_info->blast_rank = blast_rank+1;
1522 
1523     return score_info.release();
1524 }
1525 
1526 vector <CShowBlastDefline::SDeflineInfo*>
GetDeflineInfo(vector<CConstRef<CSeq_id>> & seqIds)1527 CShowBlastDefline::GetDeflineInfo(vector< CConstRef<CSeq_id> > &seqIds)
1528 {
1529     vector <CShowBlastDefline::SDeflineInfo*>  sdlVec;
1530     for(size_t i = 0; i < seqIds.size(); i++) {
1531         list<string> use_this_seq;
1532         CShowBlastDefline::SDeflineInfo* sdl = x_GetDeflineInfo(seqIds[i], use_this_seq, i + 1 );
1533         sdlVec.push_back(sdl);
1534     }
1535     return sdlVec;
1536 }
1537 
1538 
1539 
1540 CShowBlastDefline::SDeflineInfo*
x_GetDeflineInfo(CConstRef<CSeq_id> id,list<string> & use_this_seqid,int blast_rank)1541 CShowBlastDefline::x_GetDeflineInfo(CConstRef<CSeq_id> id, list<string> &use_this_seqid, int blast_rank)
1542 {
1543     SDeflineInfo* sdl = NULL;
1544     sdl = new SDeflineInfo;
1545     sdl->id = id;
1546     sdl->defline = "Unknown";
1547 
1548     try{
1549         const CBioseq_Handle& handle = m_ScopeRef->GetBioseqHandle(*id);
1550         x_FillDeflineAndId(handle, *id, use_this_seqid, sdl, blast_rank);
1551     } catch (const CException&){
1552         sdl->defline = "Unknown";
1553         sdl->is_new = false;
1554         sdl->was_checked = false;
1555         sdl->linkout = 0;
1556 
1557         if((*id).Which() == CSeq_id::e_Gi){
1558             sdl->gi = (*id).GetGi();
1559         } else {
1560             sdl->gi = ZERO_GI;
1561         }
1562         sdl->id = id;
1563         if(m_Option & eHtml){
1564             _ASSERT(m_Reg.get());
1565 
1566             string user_url= m_Reg->Get(m_BlastType, "TOOL_URL");
1567             string accession;
1568             sdl->id->GetLabel(&accession, CSeq_id::eContent);
1569             CRange<TSeqPos> seqRange(0,0);
1570             CAlignFormatUtil::SSeqURLInfo seqUrlInfo(user_url,m_BlastType,m_IsDbNa,m_Database,m_Rid,
1571                                                      m_QueryNumber,sdl->gi,accession,0,blast_rank,false,(m_Option & eNewTargetWindow) ? true : false,seqRange,false,ZERO_TAX_ID);
1572             sdl->id_url = CAlignFormatUtil::GetIDUrl(&seqUrlInfo,*id,*m_ScopeRef);
1573             sdl->score_url = NcbiEmptyString;
1574         }
1575     }
1576 
1577     return sdl;
1578 }
1579 
x_DisplayDeflineTableTemplate(CNcbiOstream & out)1580 void CShowBlastDefline::x_DisplayDeflineTableTemplate(CNcbiOstream & out)
1581 {
1582     bool first_new =true;
1583     int prev_database_type = 0, cur_database_type = 0;
1584     bool is_first = true;
1585 
1586     // Mixed db is genomic + transcript and this does not apply to proteins.
1587     bool is_mixed_database = (m_Ctx && m_IsDbNa == true)? CAlignFormatUtil::IsMixedDatabase(*m_Ctx): false;
1588     string rowType = "odd";
1589     string subHeaderID;
1590     ITERATE(vector<SScoreInfo*>, iter, m_ScoreList){
1591         SDeflineInfo* sdl = x_GetDeflineInfo((*iter)->id, (*iter)->use_this_seqid, (*iter)->blast_rank);
1592         cur_database_type = (sdl->linkout & eGenomicSeq);
1593         string subHeader;
1594         bool formatHeaderSort = !is_first && (prev_database_type != cur_database_type);
1595         if (is_mixed_database && (is_first || formatHeaderSort)) {
1596             subHeader = x_FormatSeqSetHeaders(cur_database_type, formatHeaderSort);
1597             subHeaderID = cur_database_type ? "GnmSeq" : "Transcr";
1598             //This is done for 508 complience
1599             subHeader = CAlignFormatUtil::MapTemplate(subHeader,"defl_header_id",subHeaderID);
1600         }
1601         prev_database_type = cur_database_type;
1602 
1603         string defLine = x_FormatDeflineTableLine(sdl,*iter,first_new);
1604 
1605         //This is done for 508 complience
1606         defLine = CAlignFormatUtil::MapTemplate(defLine,"defl_header_id",subHeaderID);
1607 
1608         string firstSeq = (is_first) ? "firstSeq" : "";
1609         defLine = CAlignFormatUtil::MapTemplate(defLine,"firstSeq",firstSeq);
1610         defLine = CAlignFormatUtil::MapTemplate(defLine,"trtp",rowType);
1611 
1612         rowType = (rowType == "odd") ? "even" : "odd";
1613 
1614         if(!subHeader.empty()) {
1615             defLine = subHeader + defLine;
1616         }
1617         is_first = false;
1618         out << defLine;
1619 
1620         delete sdl;
1621     }
1622 }
1623 
1624 SSeqDBTaxInfo taxInfo;
s_GetTaxonomyInfoForTaxID(TTaxId sdlTaxid,SSeqDBTaxInfo & taxInfo)1625 static void s_GetTaxonomyInfoForTaxID(TTaxId sdlTaxid, SSeqDBTaxInfo &taxInfo)
1626 {
1627     string taxid;
1628     if(sdlTaxid > 0) {
1629         taxid = NStr::IntToString(sdlTaxid);
1630         try{
1631             CSeqDB::GetTaxInfo(sdlTaxid, taxInfo);
1632         } catch (const CException&){
1633             taxInfo.common_name = "Unknown";
1634             taxInfo.scientific_name  = "Unknown";
1635             taxInfo.blast_name  = "Unknown";
1636         }
1637     }
1638 }
1639 
x_DisplayDeflineTableTemplateCSV(CNcbiOstream & out)1640 void CShowBlastDefline::x_DisplayDeflineTableTemplateCSV(CNcbiOstream & out)
1641 {
1642     ITERATE(vector<SScoreInfo*>, iter, m_ScoreList){
1643         SDeflineInfo* sdl = x_GetDeflineInfo((*iter)->id, (*iter)->use_this_seqid, (*iter)->blast_rank);
1644         string defLine = m_DeflineTemplates->defLineTmpl;
1645         string seqid;
1646         if(!sdl->id.Empty()){
1647             if(!(sdl->id->AsFastaString().find("gnl|BL_ORD_ID") != string::npos ||sdl->id->AsFastaString().find("lcl|Subject_") != string::npos)) {
1648                 sdl->id->GetLabel(&seqid, CSeq_id::eContent);
1649             }
1650         }
1651 
1652         if(sdl->id_url != NcbiEmptyString) {
1653 	        string seqInfo  = CAlignFormatUtil::MapTemplate(m_DeflineTemplates->seqInfoTmpl,"dfln_url",sdl->id_url);
1654             seqInfo = CAlignFormatUtil::MapTemplate(seqInfo,"dfln_seqid",seqid);
1655             defLine = CAlignFormatUtil::MapTemplate(defLine,"seq_info",seqInfo);
1656         }
1657         else {
1658             defLine = CAlignFormatUtil::MapTemplate(defLine,"seq_info",seqid);
1659         }
1660 
1661 	    string descr = (!sdl->defline.empty()) ? sdl->defline : "None provided";
1662 	    s_LimitDescrLength(descr);
1663         if(NStr::Find(descr,",") != NPOS) {
1664             descr = "\"" + descr + "\"";
1665         }
1666 	    defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_defline",descr);
1667 
1668         SSeqDBTaxInfo taxInfo;
1669         s_GetTaxonomyInfoForTaxID(sdl->taxid, taxInfo);
1670         defLine = CAlignFormatUtil::MapTemplate(defLine,"common_name",taxInfo.common_name);
1671         defLine = CAlignFormatUtil::MapTemplate(defLine,"scientific_name",taxInfo.scientific_name);
1672         defLine = CAlignFormatUtil::MapTemplate(defLine,"taxid",NStr::IntToString(sdl->taxid));
1673 
1674 
1675         defLine = CAlignFormatUtil::MapTemplate(defLine,"score_info",(*iter)->bit_string);
1676         defLine = CAlignFormatUtil::MapTemplate(defLine,"total_bit_string",(*iter)->total_bit_string);
1677         defLine = CAlignFormatUtil::MapTemplate(defLine,"percent_coverage",NStr::IntToString((*iter)->percent_coverage) + "%");
1678         defLine = CAlignFormatUtil::MapTemplate(defLine,"evalue_string",(*iter)->evalue_string);
1679 
1680         defLine = CAlignFormatUtil::MapTemplate(defLine,"percent_identity",NStr::DoubleToString((*iter)->percent_identity,2));
1681         int len = sequence::GetLength(*sdl->id, m_ScopeRef);
1682         defLine = CAlignFormatUtil::MapTemplate(defLine,"acclen",NStr::IntToString(len));
1683         //defLine = CAlignFormatUtil::MapTemplate(defLine,"seq_info",seqid);
1684 
1685         out << defLine;
1686         delete sdl;
1687     }
1688 
1689 }
1690 
1691 
x_DisplayDeflineTableTemplateText(CNcbiOstream & out)1692 void CShowBlastDefline::x_DisplayDeflineTableTemplateText(CNcbiOstream & out)
1693 {
1694         m_MaxPercentIdentityLen = kIdentLine2.size() + 1;
1695         m_MaxAccLength = 16;
1696         m_MaxTaxonomyNameLength = 15;
1697         m_MaxTaxidLength = 10;
1698         m_AccLenLength = 10;
1699 
1700         string descrHeader = CAlignFormatUtil::MapSpaceTemplate(m_DeflineTemplates->deflineTxtHeader,"descr_hd1"," ",m_LineLen); //empty string
1701         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"sciname_hd1",kScientific,m_MaxTaxonomyNameLength);
1702         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"comname_hd1",kCommon,m_MaxTaxonomyNameLength);
1703         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"taxid_hd1"," ",m_MaxTaxidLength);
1704         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"score_hd1",kMax,m_MaxScoreLen);
1705         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"total_hd1",kTotal,m_MaxTotalScoreLen);
1706         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"querycov_hd1",kQueryCov,m_MaxQueryCoverLen);
1707         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"evalue_hd1","  " + kE + "  ",m_MaxEvalueLen);
1708         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"percident_hd1",kPerc,m_MaxPercentIdentityLen);
1709         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"acclen_hd1",kAccAbbr,m_AccLenLength);
1710         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"acc_hd1"," ",m_MaxAccLength);
1711         //kBits 	kTotalLine2 kQueryCovLine2 kValue kIdentLine2
1712         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"descr_hd2",kDescription,m_LineLen);
1713         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"sciname_hd2",kName,m_MaxTaxonomyNameLength);
1714         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"comname_hd2",kName,m_MaxTaxonomyNameLength);
1715         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"taxid_hd2",kTaxid,m_MaxTaxidLength);
1716         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"score_hd2",kScoreLine2,m_MaxScoreLen);
1717         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"total_hd2",kScoreLine2,m_MaxTotalScoreLen);
1718         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"querycov_hd2",kQueryCovLine2,m_MaxQueryCoverLen);
1719         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"evalue_hd2",kValue,m_MaxEvalueLen);
1720         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"percident_hd2",kIdentLine2,m_MaxPercentIdentityLen);
1721         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"acclen_hd2",kLenAbbr,m_AccLenLength);
1722         descrHeader = CAlignFormatUtil::MapSpaceTemplate(descrHeader,"acc_hd2",kAccession,m_MaxAccLength);
1723 
1724         out << descrHeader;
1725 
1726     ITERATE(vector<SScoreInfo*>, iter, m_ScoreList){
1727         SDeflineInfo* sdl = x_GetDeflineInfo((*iter)->id, (*iter)->use_this_seqid, (*iter)->blast_rank);
1728         string defLine = m_DeflineTemplates->defLineTmpl;
1729         string seqid;
1730         if(!sdl->id.Empty()){
1731             if(!(sdl->id->AsFastaString().find("gnl|BL_ORD_ID") != string::npos ||sdl->id->AsFastaString().find("lcl|Subject_") != string::npos)) {
1732                 sdl->id->GetLabel(&seqid, CSeq_id::eContent);
1733             }
1734         }
1735 
1736         string descr = (!sdl->defline.empty()) ? sdl->defline : "None provided";
1737 	    s_LimitDescrLength(descr,m_LineLen);
1738 	    defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"dfln_defline",descr, m_LineLen);
1739         SSeqDBTaxInfo taxInfo;
1740         s_GetTaxonomyInfoForTaxID(sdl->taxid, taxInfo);
1741         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"common_name",taxInfo.common_name,m_MaxTaxonomyNameLength);
1742         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"scientific_name",taxInfo.scientific_name,m_MaxTaxonomyNameLength);
1743         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"taxid",NStr::IntToString(sdl->taxid),m_MaxTaxidLength);
1744         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"score_info",(*iter)->bit_string,m_MaxScoreLen);
1745         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"total_bit_string",(*iter)->total_bit_string,m_MaxTotalScoreLen);
1746         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"percent_coverage",NStr::IntToString((*iter)->percent_coverage) + "%",m_MaxQueryCoverLen);
1747         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"evalue_string",(*iter)->evalue_string,m_MaxEvalueLen);
1748         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"percent_identity",NStr::DoubleToString((*iter)->percent_identity,2),m_MaxPercentIdentityLen);
1749 
1750         int len = sequence::GetLength(*sdl->id, m_ScopeRef);
1751         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"acclen",NStr::IntToString(len),m_AccLenLength);
1752         defLine = CAlignFormatUtil::MapSpaceTemplate(defLine,"seq_info",seqid,m_MaxAccLength);
1753 
1754 
1755         out << defLine;
1756         delete sdl;
1757     }
1758 }
1759 
1760 
x_FormatSeqSetHeaders(int isGenomicSeq,bool formatHeaderSort)1761 string CShowBlastDefline::x_FormatSeqSetHeaders(int isGenomicSeq, bool formatHeaderSort)
1762 {
1763     string seqSetType = isGenomicSeq ? "Genomic sequences" : "Transcripts";
1764     string subHeader = CAlignFormatUtil::MapTemplate(m_DeflineTemplates->subHeaderTmpl,"defl_seqset_type",seqSetType);
1765     if (formatHeaderSort) {
1766         int database_sort = isGenomicSeq ? CAlignFormatUtil::eGenomicFirst : CAlignFormatUtil::eNonGenomicFirst;
1767         string deflnSubHeaderSort = CAlignFormatUtil::MapTemplate(m_DeflineTemplates->subHeaderSort,"database_sort",database_sort);
1768         subHeader = CAlignFormatUtil::MapTemplate(subHeader,"defl_header_sort",deflnSubHeaderSort);
1769     }
1770     else {
1771         subHeader = CAlignFormatUtil::MapTemplate(subHeader,"defl_header_sort","");
1772     }
1773     return subHeader;
1774 }
1775 
1776 
x_FormatDeflineTableLine(SDeflineInfo * sdl,SScoreInfo * iter,bool & first_new)1777 string CShowBlastDefline::x_FormatDeflineTableLine(SDeflineInfo* sdl,SScoreInfo* iter,bool &first_new)
1778 {
1779     string defLine = (((m_Option & eCheckboxChecked) || (m_Option & eCheckbox))) ? x_FormatPsi(sdl, first_new) : m_DeflineTemplates->defLineTmpl;
1780     string dflGi = (m_Option & eShowGi) && (sdl->gi > ZERO_GI) ? "gi|" + NStr::NumericToString(sdl->gi) + "|" : "";
1781     string seqid;
1782     if(!sdl->id.Empty()){
1783         if(!(sdl->id->AsFastaString().find("gnl|BL_ORD_ID") != string::npos ||
1784 		sdl->id->AsFastaString().find("lcl|Subject_") != string::npos)) {
1785             sdl->id->GetLabel(&seqid, CSeq_id::eContent);
1786         }
1787     }
1788 
1789     if(sdl->id_url != NcbiEmptyString) {
1790 		string seqInfo  = CAlignFormatUtil::MapTemplate(m_DeflineTemplates->seqInfoTmpl,"dfln_url",sdl->id_url);
1791         string trgt = (m_Option & eNewTargetWindow) ? "TARGET=\"EntrezView\"" : "";
1792         seqInfo = CAlignFormatUtil::MapTemplate(seqInfo,"dfln_target",trgt);
1793         defLine = CAlignFormatUtil::MapTemplate(defLine,"seq_info",seqInfo);
1794         defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_gi",dflGi);
1795         defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_seqid",seqid);
1796     }
1797     else {
1798         defLine = CAlignFormatUtil::MapTemplate(defLine,"seq_info",dflGi + seqid);
1799     }
1800 
1801     string descr = (!sdl->defline.empty()) ? sdl->defline : "None provided";
1802 	s_LimitDescrLength(descr);
1803 	defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_defline",CHTMLHelper::HTMLEncode(descr));
1804 
1805 	descr = (!sdl->fullDefline.empty()) ? sdl->fullDefline : seqid;
1806 	s_LimitDescrLength(descr);
1807 	defLine = CAlignFormatUtil::MapTemplate(defLine,"full_dfln_defline",CHTMLHelper::HTMLEncode(descr));
1808     if(sdl->score_url != NcbiEmptyString) {
1809         string scoreInfo  = CAlignFormatUtil::MapTemplate(m_DeflineTemplates->scoreInfoTmpl,"score_url",sdl->score_url);
1810         scoreInfo = CAlignFormatUtil::MapTemplate(scoreInfo,"bit_string",iter->bit_string);
1811         scoreInfo = CAlignFormatUtil::MapTemplate(scoreInfo,"score_seqid",seqid);
1812         defLine = CAlignFormatUtil::MapTemplate(defLine,"score_info",scoreInfo);
1813     }
1814     else {
1815         defLine = CAlignFormatUtil::MapTemplate(defLine,"score_info",iter->bit_string);
1816     }
1817     /*****************This block of code is for future use with AJAX begin***************************/
1818     string deflId,deflFrmID,deflFastaSeq,deflAccs;
1819     if(sdl->gi == ZERO_GI) {
1820         sdl->id->GetLabel(& deflId, CSeq_id::eContent);
1821         deflFrmID =  CAlignFormatUtil::GetLabel(sdl->id);//Just accession without db part like GNOMON: or ti:
1822         deflFastaSeq = NStr::TruncateSpaces(sdl->alnIDFasta);
1823         deflAccs = sdl->id->AsFastaString();
1824     }
1825     else {
1826         deflFrmID = deflId = NStr::NumericToString(sdl->gi);
1827         deflFastaSeq = "gi|" + NStr::NumericToString(sdl->gi);
1828         deflFastaSeq = NStr::TruncateSpaces(sdl->alnIDFasta);
1829         sdl->id->GetLabel(&deflAccs, CSeq_id::eContent);
1830     }
1831     SSeqDBTaxInfo taxInfo;
1832     s_GetTaxonomyInfoForTaxID(sdl->taxid, taxInfo);
1833     defLine = CAlignFormatUtil::MapTemplate(defLine,"common_name",taxInfo.common_name);
1834     defLine = CAlignFormatUtil::MapTemplate(defLine,"scientific_name",taxInfo.scientific_name);
1835     defLine = CAlignFormatUtil::MapTemplate(defLine,"blast_name",taxInfo.blast_name);
1836     defLine = CAlignFormatUtil::MapTemplate(defLine,"taxid",NStr::IntToString(sdl->taxid));
1837 
1838     int len = sequence::GetLength(*sdl->id, m_ScopeRef);
1839     defLine = CAlignFormatUtil::MapTemplate(defLine,"acclen",NStr::IntToString(len));
1840     //Setup applog info structure
1841     if(m_AppLogInfo && (m_AppLogInfo->currInd < m_AppLogInfo->topMatchesNum)) {
1842         m_AppLogInfo->deflIdVec.push_back(deflId);
1843         m_AppLogInfo->accVec.push_back(deflAccs);
1844         m_AppLogInfo->taxidVec.push_back(NStr::NumericToString(sdl->taxid));
1845         m_AppLogInfo->queryCoverageVec.push_back(NStr::IntToString(iter->percent_coverage));
1846         m_AppLogInfo->percentIdentityVec.push_back(NStr::DoubleToString(iter->percent_identity));
1847         m_AppLogInfo->currInd++;
1848     }
1849 
1850     //If gi - deflFrmID and deflId are the same and equal to gi "555",deflFastaSeq will have "gi|555"
1851     //If gnl - deflFrmID=number, deflId=ti:number,deflFastaSeq=gnl|xxx
1852     //like  "268252125","ti:268252125","gnl|ti|961433.m" or "961433.m" and "GNOMON:961433.m" "gnl|GNOMON|961433.m"
1853     defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_id",deflId);
1854     defLine = CAlignFormatUtil::MapTemplate(defLine,"dflnFrm_id",deflFrmID);
1855     defLine = CAlignFormatUtil::MapTemplate(defLine,"dflnFASTA_id",deflFastaSeq);
1856     defLine = CAlignFormatUtil::MapTemplate(defLine,"dflnAccs",deflAccs);
1857     defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_rid",m_Rid);
1858     defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_hspnum",iter->hspNum);
1859     defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_alnLen",iter->totalLen);
1860     defLine = CAlignFormatUtil::MapTemplate(defLine,"dfln_blast_rank",m_StartIndex + iter->blast_rank);
1861 
1862 	/*****************This block of code is for future use with AJAX end***************************/
1863 
1864     defLine = CAlignFormatUtil::MapTemplate(defLine,"total_bit_string",iter->total_bit_string);
1865 
1866 
1867     defLine = CAlignFormatUtil::MapTemplate(defLine,"percent_coverage",NStr::IntToString(iter->percent_coverage));
1868 
1869     defLine = CAlignFormatUtil::MapTemplate(defLine,"evalue_string",iter->evalue_string);
1870 
1871     if(m_Option & eShowPercentIdent){
1872         defLine = CAlignFormatUtil::MapTemplate(defLine,"percent_identity",NStr::DoubleToString(iter->percent_identity,2));
1873     }
1874 
1875     if(m_Option & eShowSumN){
1876         defLine = CAlignFormatUtil::MapTemplate(defLine,"sum_n",NStr::IntToString(iter->sum_n));
1877     }
1878 
1879 	string links;
1880     //sdl->linkout_list may contain linkouts + mapview link + seqview link
1881     ITERATE(list<string>, iter_linkout, sdl->linkout_list){
1882         links += *iter_linkout;
1883     }
1884     defLine = CAlignFormatUtil::MapTemplate(defLine,"linkout",links);
1885 
1886     return defLine;
1887 }
1888 
x_FormatPsi(SDeflineInfo * sdl,bool & first_new)1889 string CShowBlastDefline::x_FormatPsi(SDeflineInfo* sdl, bool &first_new)
1890 {
1891     string defline = m_DeflineTemplates->defLineTmpl;
1892     string show_new,psi_new,psi_new_accesible,show_checked,replaceBy,psiNewSeq;
1893     if((m_Option & eShowNewSeqGif)) {
1894         replaceBy = (sdl->is_new && first_new) ? m_DeflineTemplates->psiFirstNewAnchorTmpl : "";
1895         first_new = (sdl->is_new && first_new) ? false : first_new;
1896         if (!sdl->is_new) {
1897             show_new = "hidden";
1898         }
1899         if (sdl->is_new && m_StepNumber > 1) {
1900             psi_new = "psi_new";
1901             psi_new_accesible = "psiNw";
1902             psiNewSeq = "on";
1903         }
1904         else {
1905             psiNewSeq = "off";
1906         }
1907 
1908         if(!sdl->was_checked) {
1909             show_checked = "hidden";
1910         }
1911         string psiUsedToBuildPssm = (sdl->was_checked) ? "on" : "off";
1912 
1913 
1914         defline = CAlignFormatUtil::MapTemplate(defline,"first_new",replaceBy);
1915         defline = CAlignFormatUtil::MapTemplate(defline,"psi_new_gi",show_new);
1916         defline = CAlignFormatUtil::MapTemplate(defline,"psi_new_gi_hl",psi_new);
1917         defline = CAlignFormatUtil::MapTemplate(defline,"psi_new_gi_accs",psi_new_accesible);//insert for accesibilty
1918         defline = CAlignFormatUtil::MapTemplate(defline,"psi_checked_gi",show_checked);
1919 
1920         defline = CAlignFormatUtil::MapTemplate(defline,"psi_new_seq",psiNewSeq);
1921         defline = CAlignFormatUtil::MapTemplate(defline,"psi_used_in_pssm",psiUsedToBuildPssm);
1922     }
1923 
1924     replaceBy = (m_Option & eCheckboxChecked) ? m_DeflineTemplates->psiGoodGiHiddenTmpl : "";//<@psi_good_gi@>
1925     defline = CAlignFormatUtil::MapTemplate(defline,"psi_good_gi",replaceBy);
1926 
1927     replaceBy = (m_Option & eCheckboxChecked) ? "checked=\"checked\"" : "";
1928     defline = CAlignFormatUtil::MapTemplate(defline,"gi_checked",replaceBy);
1929     if(sdl->gi > ZERO_GI) {
1930         defline = CAlignFormatUtil::MapTemplate(defline,"psiGi",NStr::NumericToString(sdl->gi));
1931     }
1932     else {
1933         defline = CAlignFormatUtil::MapTemplate(defline,"psiGi",sdl->textSeqID);
1934     }
1935 
1936     return defline;
1937 }
1938 
1939 
1940 
1941 
x_InitFormattingInfo(SScoreInfo * sci)1942 void CShowBlastDefline::x_InitFormattingInfo(SScoreInfo* sci)
1943 {
1944     SDeflineFormattingInfo* sdlFormatInfo = new SDeflineFormattingInfo;
1945     SDeflineInfo* sdl = x_GetDeflineInfo(sci->id, sci->use_this_seqid, sci->blast_rank);
1946 
1947                 string dflGi = (m_Option & eShowGi) && (sdl->gi > ZERO_GI) ? "gi|" + NStr::NumericToString(sdl->gi) + "|" : "";
1948                 string seqid;
1949                 if(!sdl->id.Empty()){
1950                     if(!(sdl->id->AsFastaString().find("gnl|BL_ORD_ID") != string::npos || sdl->id->AsFastaString().find("lcl|Subject_") != string::npos)) {
1951                         sdl->id->GetLabel(&seqid, CSeq_id::eContent);
1952                     }
1953                 }
1954 
1955 		        sdlFormatInfo->dfln_url = sdl->id_url;
1956 
1957                 sdlFormatInfo->dfln_rid = m_Rid;
1958                 sdlFormatInfo->dfln_gi = dflGi;
1959                 sdlFormatInfo->dfln_seqid = seqid;
1960 
1961 
1962                 string descr = (!sdl->defline.empty()) ? sdl->defline : "None provided";
1963 	            s_LimitDescrLength(descr);
1964 
1965                 sdlFormatInfo->dfln_defline = CHTMLHelper::HTMLEncode(descr);
1966 
1967 	            descr = (!sdl->fullDefline.empty()) ? sdl->fullDefline : seqid;
1968 	            s_LimitDescrLength(descr);
1969                 sdlFormatInfo->full_dfln_defline = CHTMLHelper::HTMLEncode(descr);
1970 
1971 
1972 
1973                 string deflId,deflFrmID,deflFastaSeq,deflAccs;
1974                 if(sdl->gi == ZERO_GI) {
1975                     sdl->id->GetLabel(& deflId, CSeq_id::eContent);
1976                     deflFrmID =  CAlignFormatUtil::GetLabel(sdl->id);//Just accession without db part like GNOMON: or ti:
1977                     deflFastaSeq = NStr::TruncateSpaces(sdl->alnIDFasta);
1978                     deflAccs = sdl->id->AsFastaString();
1979                 }
1980                 else {
1981                     deflFrmID = deflId = NStr::NumericToString(sdl->gi);
1982                     deflFastaSeq = "gi|" + NStr::NumericToString(sdl->gi);
1983                     deflFastaSeq = NStr::TruncateSpaces(sdl->alnIDFasta);
1984                     sdl->id->GetLabel(&deflAccs, CSeq_id::eContent);
1985                 }
1986 
1987                 sdlFormatInfo->dfln_id = deflId;
1988                 sdlFormatInfo->dflnFrm_id = deflFrmID;
1989                 sdlFormatInfo->dflnFASTA_id = deflFastaSeq;
1990                 sdlFormatInfo->dflnAccs =deflAccs;
1991 
1992                 sdlFormatInfo->score_info = sci->bit_string;
1993                 sdlFormatInfo->dfln_hspnum =  NStr::IntToString(sci->hspNum);
1994                 sdlFormatInfo->dfln_alnLen =  NStr::NumericToString(sci->totalLen);
1995                 sdlFormatInfo->dfln_blast_rank =  NStr::IntToString(m_StartIndex + sci->blast_rank);
1996 	            sdlFormatInfo->total_bit_string = sci->total_bit_string;
1997                 sdlFormatInfo->percent_coverage = NStr::IntToString(sci->percent_coverage);
1998                 sdlFormatInfo->evalue_string = sci->evalue_string;
1999                 sdlFormatInfo->percent_identity = NStr::DoubleToString(sci->percent_identity);
2000                 m_SdlFormatInfoVec.push_back(sdlFormatInfo);
2001 }
2002 
2003 
GetFormattingInfo(void)2004 vector <CShowBlastDefline::SDeflineFormattingInfo *> CShowBlastDefline::GetFormattingInfo(void)
2005 {
2006     /*Note we can't just show each alnment as we go because we will
2007       need to show defline only once for all hsp's with the same id*/
2008 
2009     bool is_first_aln = true;
2010     size_t num_align = 0;
2011     CConstRef<CSeq_id> previous_id, subid;
2012 
2013     CSeq_align_set hit;
2014     m_QueryLength = 1;
2015 
2016     //prepare defline
2017 
2018 
2019     for (CSeq_align_set::Tdata::const_iterator iter = m_AlnSetRef->Get().begin();
2020          iter != m_AlnSetRef->Get().end() && num_align < m_NumToShow;
2021          iter++)
2022     {
2023 
2024         if (is_first_aln) {
2025             m_QueryLength = m_MasterRange ? m_MasterRange->GetLength() : m_ScopeRef->GetBioseqHandle((*iter)->GetSeq_id(0)).GetBioseqLength();
2026         }
2027 
2028         subid = &((*iter)->GetSeq_id(1));
2029 
2030         if(!is_first_aln && !(subid->Match(*previous_id))) {
2031 
2032             SScoreInfo* sci = x_GetScoreInfoForTable(hit, num_align);
2033             if(sci) {
2034                 x_InitFormattingInfo(sci);
2035                 hit.Set().clear();
2036             }
2037 
2038             num_align++; // Only increment if new subject ID found.
2039         }
2040         if (num_align < m_NumToShow) { //no adding if number to show already reached
2041             hit.Set().push_back(*iter);
2042         }
2043         is_first_aln = false;
2044         previous_id = subid;
2045     }
2046     //the last hit
2047     SScoreInfo* sci = x_GetScoreInfoForTable(hit, num_align);
2048 
2049     if(sci) {
2050         x_InitFormattingInfo(sci);
2051         hit.Set().clear();
2052     }
2053 
2054     return m_SdlFormatInfoVec;
2055 }
2056 
2057 
2058 END_SCOPE(align_format)
2059 END_NCBI_SCOPE
2060