#delphi #generics #биоинформатика
До сих пор, работая непосредственно с SAM-файлами, мы использовали массивы. Сейчас
хотим перейти на TDictionary, поскольку он гораздо удобнее в плане поиска. Возникают
вопросы:
1. Иерархия словаря. Как я вижу себе структуру, которая была бы удобна для поиска:
type
DataType = record
name,qual, info, seq:string;
data:array[1..30] of double;
paired, structured:boolean;
ref:integer;
end;
TData3 = TDictionary; // по имени референса
TData2 = TDictionary; // по позиции внутри хромосомы
TData1 = TDictionary; по хромосомам
var
dd: TData1;
тогда я могу достаточно быстро пробежаться вниз по дереву chr->pos->ref и все записи
будут уникальны. А для работы с переменной dd создаю свой класс, где будут все рутины.
Прав ли я, предполагая такую структуру?
Как правило, в большинстве биоинформатических утилит для обозначения хромосом используются
строковый тип ['1'...'22','X','Y','MT']. Формально, я могу TData1 определить как
type
TData1 = TDictionary ; по хромосомам
но боюсь, что выигрывая в удобстве, потеряю в скорости поиска. Так ли это?
Спасибо заранее за помощь!
Ответы
Ответ 1
Вначале отвечу на второй вопрос. По опыту, разницы в скорости не наблюдается. Более
того, удобнее оставлять сведения о хромосоме именно в текстовом виде, так как порой
приходится иметь дело со сложными именованиями хромосом, а не все утилиты поддерживают
таблицу номерного соответствия.
Более того, я предлагаю совместить первый и второй уровень вашего словаря, сделав
ключом сразу полную координату {chr, pos} в виде строки формируя её либо так Key:=
chr + ',' + IntToStr(pos), либо так Key:= chr + #9 + IntToStr(pos). Первый случай удобен
для экспорта в Excel или BED, второй - для SAM/BAM. Скорость поиска возрастёт, неудобств
при формировании ключа - минимум.
И ещё, отдельный класс создавать, на мой взгляд, не нужно. Наследуйте непосредственно
TDictionary, так будет гораздо удобнее.
Суммируя всё вышенаписанное, предлагаю сделать так:
type
DataType = record
name,qual, info, seq:string;
data:array[1..30] of double;
paired, structured:boolean;
ref:integer;
end;
TData3 = TDictionary; // по имени референса
TData1 = class(TDictionary); по хромосоме и позиции, ключ строится,
как описано выше
// переменные и методы класса, к данным первого уровня удобно обращаться без
разъименования.
end;
И встречный вопрос: ключ в TData3 и name в DataType у вас не одно и то же?