std::initializer_list<const char*>*
Aliases;
71 template<eTestNames _Name>
204eTestNames
GetName()
const override{
returnm_props->Name; }
205string_view
GetSName()
const override{
returnm_props->sName; }
210 bool Empty()
const{
returnm_Objs.empty(); }
228 template<eTestNames _Name>
232 template<eTestNames _Name>
280vector<pair<size_t, size_t>>
NRuns;
296 typedeflist<pair<CRef<CDiscrepancyObject>,
string>>
TGenesList;
313 voidSummarize()
override;
326eHasRearranged = 1 << 0,
327eHasSatFeat = 1 << 1,
328eHasNonSatFeat = 1 << 2
335 voidAddTest(eTestNames name)
override;
337 voidAddTest(string_view name)
override;
338 voidPush(
const CSerialObject& root,
const string& fname)
override;
339 void Parse()
override{ ParseAll(*m_RootNode); }
340 voidParse(
const CSerialObject& root,
const string& fname);
341 voidParseObject(
const CBioseq& root);
345 voidParseStream(
CObjectIStream& stream,
const string& fname,
boolskip,
const string& default_header =
kEmptyStr)
override;
346 voidParseStrings(
const string& fname)
override;
348 unsignedSummarize()
override;
351 voidAutofixFile(vector<CDiscrepancyObject*>&fixes,
const string& default_header);
356CParseNode* FindNode(
constCRefNode& obj);
364 const string&
CurrentText()
const{
returnm_CurrentNode->m_Ref->m_Text; }
368 unsigned char ReadFlags()
const{
returnm_CurrentNode->m_Flags; }
371objects::CScope&
GetScope()
const{
return const_cast<objects::CScope&
>(*m_Scope); }
374 voidSetSuspectRules(
const string& name,
boolread =
true)
override;
379 static boolIsUnculturedNonOrganelleName(
const string& taxname);
380 static boolHasLineage(
const CBioSource& biosrc,
const string& def_lineage,
const string&
type);
381 boolHasLineage(
const CBioSource* biosrc,
const string& lineage)
const;
383 boolIsEukaryotic(
const CBioSource* biosrc)
const;
384 boolIsProkaryotic(
const CBioSource* biosrc)
const;
385 boolIsBacterial(
const CBioSource* biosrc)
const;
386 boolIsViral(
const CBioSource* biosrc)
const;
393 constvector<CConstRef<CSeqdesc>>&
GetSetBiosources()
const{
returnm_CurrentNode->m_SetBiosources; }
395 static stringGetGenomeName(
unsigned n);
396 static stringGetAminoacidName(
const CSeq_feat& feat);
397 static boolIsBadLocusTagFormat(string_view locus_tag);
398 boolIsRefseq()
const;
402 stringGetProdForFeature(
const CSeq_feat& feat);
403 voidCollectFeature(
const CSeq_feat& feat);
404 voidClearFeatureList();
405 constvector<const CSeq_feat*>&
FeatAll() {
returnm_FeatAll; }
406 constvector<const CSeq_feat*>&
FeatGenes() {
returnm_FeatGenes; }
407 constvector<const CSeq_feat*>&
FeatPseudo() {
returnm_FeatPseudo; }
408 constvector<const CSeq_feat*>&
FeatCDS() {
returnm_FeatCDS; }
409 constvector<const CSeq_feat*>&
FeatMRNAs() {
returnm_FeatMRNAs; }
410 constvector<const CSeq_feat*>&
FeatRRNAs() {
returnm_FeatRRNAs; }
411 constvector<const CSeq_feat*>&
FeatTRNAs() {
returnm_FeatTRNAs; }
412 constvector<const CSeq_feat*>&
Feat_RNAs() {
returnm_Feat_RNAs; }
413 constvector<const CSeq_feat*>&
FeatExons() {
returnm_FeatExons; }
414 constvector<const CSeq_feat*>&
FeatIntrons() {
returnm_FeatIntrons; }
415 constvector<const CSeq_feat*>&
FeatMisc() {
returnm_FeatMisc; }
427CRefNode* ContainingSet(CRefNode& ref);
439 const CPub*
AuthPub(
const CAuth_list*
a)
const{
auto& apm = m_CurrentNode->m_AuthorPubMap;
autoit = apm.find(
a);
returnit == apm.end() ?
nullptr: it->second; }
519node = follow ? node->
m_Parent:
nullptr;
526node = follow ? node->
m_Parent:
nullptr;
542 constvector<const CBioSource*>&
GetBiosources()
const{
returnm_CurrentNode->m_Biosources; }
543 constvector<const CPubdesc*>&
GetPubdescs()
const{
returnm_CurrentNode->m_Pubdescs; }
544 constvector<const CAuth_list*>&
GetAuthors()
const{
returnm_CurrentNode->m_Authors; }
586 boolCanFixBioseq_set();
588 boolCanFixSeq_annot();
589 boolCanFixSeqdesc();
590 boolCanFixSubmit_block();
591 boolCanFixBioseq(
CRefNode& refnode);
592 boolCanFixBioseq_set(
CRefNode& refnode);
593 boolCanFixFeat(
CRefNode& refnode);
594 boolCanFixDesc(
CRefNode& refnode);
595 boolCanFixSubmit_block(
CRefNode& refnode);
596 voidAutofixBioseq();
597 voidAutofixBioseq_set();
598 voidAutofixSeq_annot();
599 voidAutofixSeq_descr();
600 voidAutofixSubmit_block();
608 #define ADD_DISCREPANCY_TYPE(type) vector<CDiscrepancyCore*> m_All_##type; 651 caseeSeqSet_NucProt:
652 caseeSeqSet_GenProd:
662 static const char*
names[] =
691 stringGetText()
const;
692 stringGetBioseqLabel()
const;
700eKnownPseudo = 1 << 1,
702eKnownProduct = 1 << 3
708m_Ref->m_Parent.Reset(parent->m_Ref);
714new_node->m_Obj = &seqdesc;
715m_Descriptors.push_back(new_node);
716m_DescriptorMap[&seqdesc] = new_node;
719m_Biosources.push_back(biosrc);
720m_BiosourceMap[biosrc] = new_node;
722 if(seqdesc.
IsPub()) {
724m_Pubdescs.push_back(pub);
725m_PubdescMap[pub] = new_node;
727 for(
auto& it : pub->
GetPub().
Get()) {
728 if(it->IsSetAuthors()) {
730m_Authors.push_back(auth);
731m_AuthorMap[auth] = new_node;
732m_AuthorPubMap[auth] = &*it;
742new_node->m_Obj = &feat;
743m_Features.push_back(new_node);
744m_FeatureMap[&feat] = new_node;
747m_Biosources.push_back(biosrc);
748m_BiosourceMap[biosrc] = new_node;
752m_Pubdescs.push_back(pub);
753m_PubdescMap[pub] = new_node;
755 for(
auto& it : pub->
GetPub().
Get()) {
756 if(it->IsSetAuthors()) {
758m_Authors.push_back(auth);
759m_AuthorMap[auth] = new_node;
760m_AuthorPubMap[auth] = &*it;
773 bool InGenProdSet()
const{
returnm_Type == eSeqSet_GenProd ?
true: m_Parent ? m_Parent->InGenProdSet() :
false; }
804 string Path() {
returnm_Parent ? m_Parent->
Path() +
" => "+ TypeName(m_Type) +
": "+ to_string(m_Index) : TypeName(m_Type) +
": "+ to_string(m_Index); }
809 voidParseAll(CParseNode& node);
810 voidPopulate(CParseNode& node);
811 voidPopulateBioseq(CParseNode& node);
812 voidPopulateSeqSet(CParseNode& node);
813 voidPopulateSubmit(CParseNode& node);
816 voidPushNode(EObjType);
817 void PopNode() { m_CurrentNode.Reset(m_CurrentNode->m_Parent); }
824 stringProdForFeature(
const CParseNode& node);
834: m_Ref(ref), m_Fix(fix), m_More(more) {}
842 string GetShort()
const override{
returnm_Ref->GetBioseqLabel(); }
845 string GetText()
const override{
returnm_Ref->GetText(); }
848 for(
autoref = m_Ref; ref; ref = ref->m_Parent) {
855 stringGetFeatureType()
const override;
857 stringGetLocation()
const override;
871 switch(m_Ref->m_Type) {
883 bool CanAutofix()
const override{
returnm_Fix && !m_Fixed; }
884 bool IsFixed()
const override{
returnm_Fixed; }
904 boolm_Fixed {
false};
925 #define DISCREPANCY_CASE_FULL(name, sname, type, group, descr, aliases_ptr) \ 926 static constexpr CDiscrepancyCaseProps s_testcase_props_##name = { \ 927 CDiscrepancyVisitorImpl<eTestNames::name>::Create, \ 928 eTestTypes::type, eTestNames::name, sname, descr, group, aliases_ptr}; \ 930 const CDiscrepancyCaseProps* \ 931 CDiscrepancyCasePropsRef<eTestNames::name>::props = &s_testcase_props_##name; \ 932 template<> void CDiscrepancyVisitorImpl<eTestNames::name>::Visit(NCBI_UNUSED CDiscrepancyContext& context) 934 #define DISCREPANCY_CASE(name, type, group, descr) \ 935 DISCREPANCY_CASE_FULL(name, #name, type, group, descr, nullptr) 937 #define DISCREPANCY_CASE0(name, sname, type, group, descr) \ 938 DISCREPANCY_CASE_FULL(name, sname, type, group, descr, nullptr) 940 #define DISCREPANCY_CASE1(name, type, group, descr, ...) \ 941 static constexpr std::initializer_list<const char*> g_aliases_ ##name = { __VA_ARGS__ }; \ 942 DISCREPANCY_CASE_FULL(name, #name, type, group, descr, &g_aliases_ ##name) 945 #define DISCREPANCY_SUMMARIZE(name) \ 946 template<> void CDiscrepancyVisitorImpl<eTestNames::name>::Summarize() 949 #define DISCREPANCY_AUTOFIX(name) \ 951 CRef<CAutofixReport> \ 952 CDiscrepancyVisitorImpl<eTestNames::name>::Autofix(CDiscrepancyObject* obj, CDiscrepancyContext& context) conststatic CRef< CScope > m_Scope
User-defined methods of the data storage class.
User-defined methods of the data storage class.
@Auth_list.hpp User-defined methods of the data storage class.
static const CDiscrepancyCaseProps * props
virtual TReportObjectList GetObjects() const =0
const vector< const CPubdesc * > & GetPubdescs() const
CRef< CBioseq > m_AF_Bioseq
vector< CDiscrepancyObject * > * m_Fixes
CSeqdesc_run GetAllSeqdesc()
CConstRef< CSeqdesc > m_Current_Seqdesc
CRef< CSeq_descr > m_AF_Seq_descr
const vector< const CSeq_feat * > & FeatTRNAs()
vector< const CSeq_feat * > m_Feat_RNAs
const vector< const CSeq_feat * > & FeatExons()
unsigned char ReadFlags() const
CRef< objects::CScope > m_Scope
const string & CurrentText() const
ct::const_bitset< static_cast< size_t >eTestTypes::max_num_types), eTestTypes > m_Enabled
CDiscrepancyContext(objects::CScope &scope)
TDiscrepancyCoreMap m_Tests
CRef< CBioseq_set > m_AF_Bioseq_set
const vector< CConstRef< CSeqdesc > > & GetSetBiosources() const
CRef< CSimpleTypeObject< string > > m_Current_Submit_block_StringObj
CRef< CParseNode > m_RootNode
CRef< feature::CFeatTree > m_FeatTree
CConstRef< CPub > m_Current_Pub
const vector< const CSeq_feat * > & FeatGenes()
CRef< CParseNode > m_CurrentNode
vector< const CSeq_feat * > m_FeatAll
CConstRef< CSubmit_block > m_Current_Submit_block
bool InGenProdSet() const
vector< const CSeq_feat * > m_FeatRRNAs
CConstRef< CSeqdesc > GetTitle() const
objects::CScope & GetScope() const
CConstRef< CSeq_feat > m_Current_Seq_feat
const vector< const CBioSource * > & GetBiosources() const
vector< const CSeq_feat * > m_FeatCDS
const vector< const CSeq_feat * > & FeatMRNAs()
const CPub * AuthPub(const CAuth_list *a) const
CConstRef< CBioseq > m_Current_Bioseq
const CSeqSummary & GetSeqSummary()
CBioseq_Handle m_Current_Bioseq_Handle
static bool InGenProdSet(const CParseNode *node)
const vector< const CAuth_list * > & GetAuthors() const
const vector< const CSeq_feat * > & Feat_RNAs()
CSeq_feat_run GetAllFeat()
const vector< const CSeq_feat * > & FeatPseudo()
const CBioseq & CurrentBioseq() const
vector< const CSeq_feat * > m_FeatGenes
static string TypeName(EObjType n)
CBioseq_set_Handle GetBioseq_setHandle(const CBioseq_set &bss)
CConstRef< CSeqdesc > GetBiosource() const
const vector< const CSeq_feat * > & FeatCDS()
vector< const CSeq_feat * > m_FeatMRNAs
map< const CRefNode *, CParseNode * > m_NodeMap
const vector< const CSeq_feat * > & FeatAll()
const vector< const CSeq_feat * > & FeatIntrons()
CRef< CSimpleTypeObject< string > > m_Current_Cit_sub_StringObj
CRef< CSeq_annot > m_AF_Seq_annot
static bool InNucProtSet(const CParseNode *node)
CConstRef< CSuspect_rule_set > m_OrganelleProductRules
CBioseq_EditHandle GetBioseqHandle(const CBioseq &bs)
vector< const CSeq_feat * > m_FeatTRNAs
const vector< const CSeq_feat * > & FeatRRNAs()
vector< const CSeq_feat * > m_FeatExons
CConstRef< CSeqdesc > GetMolinfo() const
CSeqdesc_vec GetSeqdesc()
const CBioseq_set & CurrentBioseq_set() const
const vector< const CSeq_feat * > & FeatMisc()
const CObject * GetMore(CReportObj &obj)
vector< CConstRef< CBioseq_set > > m_Bioseq_set_Stack
CRef< CSubmit_block > m_AF_Submit_block
CConstRef< CPub_equiv > m_Current_Pub_equiv
CConstRef< CSuspect_rule_set > m_ProductRules
void PropagateFlags(unsigned char f)
vector< const CSeq_feat * > m_FeatIntrons
vector< const CSeq_feat * > m_FeatPseudo
static bool IsSeqSet(EObjType n)
vector< const CSeq_feat * > m_FeatMisc
eTestTypes GetType() const override
virtual CRef< CAutofixReport > Autofix(CDiscrepancyObject *obj, CDiscrepancyContext &context) const =0
virtual void Visit(CDiscrepancyContext &context)=0
eTestNames GetName() const override
const CDiscrepancyCaseProps * m_props
CDiscrepancyCore(const CDiscrepancyCaseProps *props)
string_view GetSName() const override
TReportItemList m_ReportItems
virtual void Summarize()=0
string_view GetDescription() const override
const TReportItemList & GetReport() const override
CDiscrepancyItem(string_view title, const string &name, const string &msg, const string &xml, const string &unit, size_t count)
string_view GetTitle() const override
bool IsExtended() const override
size_t GetCount() const override
TReportObjectList & SetDetails()
TReportObjectList GetDetails() const override
bool IsInfo() const override
bool IsReal() const override
void SetAutofix(bool value)
bool IsFatal() const override
string GetUnit() const override
TReportItemList GetSubitems() const override
CDiscrepancyItem(const string &msg)
string GetStr() const override
string GetXml() const override
string GetMsg() const override
bool CanAutofix() const override
ESeverity GetSeverity() const override
bool IsSummary() const override
friend bool operator<(const CReportObjPtr &one, const CReportObjPtr &another)
CRef< CDiscrepancyContext::CRefNode > m_Ref
string GetBioseqLabel() const override
string GetPath() const override
void SetMoreInfo(CObject *data) override
string GetShort() const override
bool IsFixed() const override
bool CanAutofix() const override
CConstRef< CObject > m_More
CConstRef< CObject > GetMoreInfo()
string GetText() const override
CRef< CDiscrepancyContext::CRefNode > m_Fix
CRef< CDiscrepancyCore > m_Case
EType GetType() const override
CDiscrepancyObject(CDiscrepancyContext::CRefNode *ref, CDiscrepancyContext::CRefNode *fix=nullptr, const CObject *more=nullptr)
TDiscrepancyCoreMap m_Tests
void Visit(CDiscrepancyContext &context) override
CRef< CAutofixReport > Autofix(CDiscrepancyObject *, CDiscrepancyContext &) const override
void Summarize() override
CDiscrepancyPrivateData< _Name > m_private
static CRef< CDiscrepancyCore > Create()
@Pubdesc.hpp User-defined methods of the data storage class.
static void Add(TReportObjectList &list, TReportObjectSet &hash, CReportObj &obj, bool unique=true)
CReportNode(const string &name)
bool Exist(CReportObj &obj)
CReportNode & Merge(CReportNode &other)
CReportNode & Add(CReportObj &obj, bool unique=true)
CReportNode & NoRec(bool b=true)
map< string, CRef< CReportNode > > TNodeMap
CReportNode & Summ(bool b=true)
TReportObjectList & GetObjects()
CReportNode & Ext(bool b=true)
CReportNode & operator[](const string &name)
CReportNode & Severity(CReportItem::ESeverity s)
CRef< CReportItem > Export(CDiscrepancyCore &test, bool unique=true) const
CReportItem::ESeverity m_Severity
static bool Exist(TReportObjectSet &hash, CReportObj &obj)
bool Exist(const string &name) const
CReportNode & Add(TReportObjectList &objs, bool unique=true)
void Copy(CRef< CReportNode > other)
static CRef< CReportObj > Create(CRef< CDiscrepancyCore > disc_core, const CReportObj &obj, bool autofix)
namespace ncbi::objects::
Base class for all serializable objects.
const_iterator end() const
const_iterator find(const key_type &key) const
vector< CRef< CReportItem > > TReportItemList
vector< CRef< CReportObj > > TReportObjectList
CConstRef< objects::CSuspect_rule_set > GetProductRules(const string &name="")
CConstRef< objects::CSuspect_rule_set > GetOrganelleProductRules(const string &name="")
void UnitTest_FLATFILE_FIND()
Checking that FLATFILE_FIND.inc is in sync with kSpellFixes If the array is changed,...
map< eTestNames, CRef< CDiscrepancyCore > > TDiscrepancyCoreMap
list< pair< CRef< CDiscrepancyObject >, string > > TGenesList
CDiscrepancyContext - manage and run the list of tests.
set< CReportObjPtr > TReportObjectSet
map< string, TGenesList > TGeneLocusMap
#define ADD_DISCREPANCY_TYPE(type)
std::ofstream out("events_result.xml")
main entry point for tests
static const struct name_t names[]
#define test(a, b, c, d, e)
static int RunTests(void)
Code to iterate through all tests to run.
static const char location[]
sequence::ECompare Compare(const CSeq_loc &loc1, const CSeq_loc &loc2, CScope *scope)
Returns the sequence::ECompare containment relationship between CSeq_locs.
bool IsPseudo(const CSeq_feat &feat, CScope &scope)
Determines whether given feature is pseudo, using gene associated with feature if necessary Checks to...
CConstRef< CSeq_feat > GetGeneForFeature(const CSeq_feat &feat, CScope &scope)
Finds gene for feature, but obeys SeqFeatXref directives.
CBioseq_set_Handle GetBioseq_setHandle(const CBioseq_set &seqset, EMissing action=eMissing_Default)
CBioseq_EditHandle GetBioseqEditHandle(const CBioseq &bioseq)
Get edit handle for the specified object Throw an exception if object is not found,...
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define END_SCOPE(ns)
End the previously defined scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
#define BEGIN_SCOPE(ns)
Define a new scope.
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
IO_PREFIX::streampos CNcbiStreampos
Portable alias for streampos.
#define NCBI_DISCREPANCY_EXPORT
const Tdata & Get(void) const
Get the member data.
const TPub & GetPub(void) const
Get the variant data.
bool IsSetData(void) const
the specific data Check if a value has been assigned to Data data member.
const TData & GetData(void) const
Get the Data member data.
bool IsPub(void) const
Check if variant Pub is selected.
const TBiosrc & GetBiosrc(void) const
Get the variant data.
bool IsBiosrc(void) const
Check if variant Biosrc is selected.
const TTitle & GetTitle(void) const
Get the variant data.
const TSource & GetSource(void) const
Get the variant data.
const TPub & GetPub(void) const
Get the variant data.
bool IsSource(void) const
Check if variant Source is selected.
bool IsPub(void) const
Check if variant Pub is selected.
bool IsSetPub(void) const
the citation(s) Check if a value has been assigned to Pub data member.
const TPub & GetPub(void) const
Get the Pub member data.
const TMolinfo & GetMolinfo(void) const
Get the variant data.
static string GetProductName(const CProt_ref &prot)
const GenericPointer< typename T::ValueType > T2 value
string GetLocusTag(const CSeq_feat &f, const LocMap &loc_map)
string GetProduct(const CProt_ref &prot_ref)
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
const std::initializer_list< const char * > * Aliases
CConstRef< CSeqdesc > m_Molinfo
CParseNode & AddDescriptor(const CSeqdesc &seqdesc)
CConstRef< CSeqdesc > m_Title
vector< CRef< CParseNode > > m_Children
CParseNode(EObjType type, unsigned index, CParseNode *parent=nullptr)
map< const CBioSource *, CParseNode * > m_BiosourceMap
vector< const CBioSource * > m_Biosources
vector< CRef< CParseNode > > m_Features
void SetType(EObjType type)
bool InGenProdSet() const
vector< const CPubdesc * > m_Pubdescs
vector< CRef< CParseNode > > m_Descriptors
CConstRef< CSerialObject > m_Obj
CParseNode & AddFeature(const CSeq_feat &feat)
vector< CConstRef< CSeqdesc > > m_SetBiosources
map< const CSeq_feat *, CParseNode * > m_FeatureMap
CConstRef< CSeqdesc > m_Biosource
const CParseNode * m_Gene
map< const CSeqdesc *, CParseNode * > m_DescriptorMap
map< const CAuth_list *, CParseNode * > m_AuthorMap
shared_ptr< CSeqSummary > m_BioseqSummary
map< const CPubdesc *, CParseNode * > m_PubdescMap
CConstRef< CSeqdesc > GetBiosource() const
CConstRef< CSeqdesc > GetMolinfo() const
CConstRef< CSeqdesc > GetTitle() const
vector< const CAuth_list * > m_Authors
map< const CAuth_list *, const CPub * > m_AuthorPubMap
CRef< CRefNode > m_Parent
CRefNode(EObjType type, unsigned index)
const CSeq_feat & operator*()
vector< CRef< CParseNode > >::iterator it
bool operator!=(const iterator &x) const
bool operator==(const iterator &x) const
CSeq_feat_run(CParseNode &n)
bool operator==(const iterator &x) const
bool operator!=(const iterator &x) const
const CSeq_feat & operator*()
vector< CRef< CParseNode > >::iterator it
iterator(vector< CRef< CParseNode >>::iterator x)
CSeq_feat_vec(CParseNode &n)
bool operator==(const iterator &x) const
const CSeqdesc & operator*()
bool operator!=(const iterator &x) const
vector< CRef< CParseNode > >::iterator it
CSeqdesc_run(CParseNode &n)
iterator(vector< CRef< CParseNode >>::iterator x)
bool operator==(const iterator &x) const
vector< CRef< CParseNode > >::iterator it
bool operator!=(const iterator &x) const
const CSeqdesc & operator*()
CSeqdesc_vec(CParseNode &n)
friend bool operator<(const CReportObjPtr &one, const CReportObjPtr &another)
CReportObjPtr(const CReportObj *p)
vector< pair< size_t, size_t > > NRuns
size_t _CBposition[WINDOW_SIZE]
static const size_t WINDOW_SIZE
size_t _CBscore[WINDOW_SIZE]
CSimpleTypeObject(const T &v)
string GetTextObjectDescription(const CSeq_feat &sf, CScope &scope)
static CS_CONTEXT * context
void Merge(wxMenu &menu_1, const wxMenu &menu_2)
merges all items form menu_2 into menu_1, preserving the structure if possible
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4