1 // ***************************************************************************
2 // BamIndexFactory_p.cpp (c) 2011 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 21 March 2011 (DB)
7 // ---------------------------------------------------------------------------
8 // Provides interface for generating BamIndex implementations
9 // ***************************************************************************
11 #include <api/BamAux.h>
12 #include <api/internal/BamIndexFactory_p.h>
13 #include <api/internal/BamStandardIndex_p.h>
14 #include <api/internal/BamToolsIndex_p.h>
15 using namespace BamTools;
16 using namespace BamTools::Internal;
21 // generates index filename from BAM filename (depending on requested type)
22 // if type is unknown, returns empty string
23 const string BamIndexFactory::CreateIndexFilename(const string& bamFilename,
24 const BamIndex::IndexType& type)
27 case ( BamIndex::STANDARD ) : return ( bamFilename + BAI_EXTENSION );
28 case ( BamIndex::BAMTOOLS ) : return ( bamFilename + BTI_EXTENSION );
30 fprintf(stderr, "BamIndexFactory ERROR: unknown index type %u\n", type);
35 // creates a new BamIndex object, depending on extension of @indexFilename
36 BamIndex* BamIndexFactory::CreateIndexFromFilename(const string& indexFilename) {
38 // if file doesn't exist, return null index
39 if ( !BamTools::FileExists(indexFilename) )
42 // get file extension from index filename, including dot (".EXT")
43 // if can't get file extension, return null index
44 const string extension = FileExtension(indexFilename);
45 if ( extension.empty() )
48 // create index based on extension
49 if ( extension == BAI_EXTENSION ) return new BamStandardIndex;
50 else if ( extension == BTI_EXTENSION ) return new BamToolsIndex;
54 // creates a new BamIndex, object of requested @type
55 BamIndex* BamIndexFactory::CreateIndexOfType(const BamIndex::IndexType& type) {
57 case ( BamIndex::STANDARD ) : return new BamStandardIndex;
58 case ( BamIndex::BAMTOOLS ) : return new BamToolsIndex;
60 fprintf(stderr, "BamIndexFactory ERROR: unknown index type %u\n", type);
65 // retrieves file extension (including '.')
66 const string BamIndexFactory::FileExtension(const string& filename) {
68 // if filename cannot contain valid path + extension, return empty string
69 if ( filename.empty() || filename.length() <= 4 )
72 // look for last dot in filename
73 size_t lastDotPosition = filename.find_last_of('.');
75 // if none found, return empty string
76 if ( lastDotPosition == string::npos )
79 // return substring from last dot position
80 return filename.substr(lastDotPosition);
83 // returns name of existing index file that corresponds to @bamFilename
84 // will defer to @preferredType if possible, if not will attempt to load any supported type
85 // returns empty string if not found
86 const string BamIndexFactory::FindIndexFilename(const string& bamFilename,
87 const BamIndex::IndexType& preferredType)
89 // try to find index of preferred type first
90 // return index filename if found
91 string indexFilename = CreateIndexFilename(bamFilename, preferredType);
92 if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
95 // couldn't find preferred type, try the other supported types
96 // return index filename if found
97 if ( preferredType != BamIndex::STANDARD ) {
98 indexFilename = CreateIndexFilename(bamFilename, BamIndex::STANDARD);
99 if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
100 return indexFilename;
102 if ( preferredType != BamIndex::BAMTOOLS ) {
103 indexFilename = CreateIndexFilename(bamFilename, BamIndex::BAMTOOLS);
104 if ( !indexFilename.empty() && BamTools::FileExists(indexFilename) )
105 return indexFilename;
108 // otherwise couldn't find any index matching this filename