//$MENU window=main;popup=edit;insertafter=bring selected entries to top;name=Assign VNTR's for selected entries
DIALOG dlg,dlg2;
XMLNODE xmldoc,rootnode,node,node1,node2;
integer i,j,k,expernr,x1,x2,finished,finished2,ok,vntrselnr,edit_isnew,nr,nr2,totcount,ctr;
string fprintlist,vntrcharsetname,vntrfragsetname,st,errorlist,vntrlist,vntrsel,error;
string str_vntr,str_offset,str_length,str_minval,str_maxval,str_tol,str_fprint;
string key;
charset cs,cs2;
fprint fpr;
integer vntrcount;
string vntr_name[],vntr_fprint[];
integer vntr_offset[],vntr_length[],vntr_minval[],vntr_maxval[],vntr_tol[];
float metric,vol,conc,ps,h,w;
integer bestrepcount,foundseveral,bestfeasible;
float bestbandh,bestdist,dist;
integer feasiblecount,feasible_ct[];
float feasible_metric[],feasible_h[];
if DbGetSoftwareVersion<"3.0" then {
Message("Invalid software version");
stop;
}
for i=1 to DbGetExperCount do
if DbGetExperClass(i)="FPR" then fprintlist=fprintlist+DbGetExperName(i)+" ";
vntrcharsetname="VNTR_vals";
vntrfragsetname="VNTR_frags";
//check if vntr char experiment is available
ok=0;
for i=1 to DbGetExperCount do
if (DbGetExperClass(i)="CHR") and (DbGetExperName(i)=vntrcharsetname) then ok=1;
if not(ok) then {
message("The character experiment '"+vntrcharsetname+"' will now be created");
DbCreateExperType(vntrcharsetname,"CHR");
expernr=0;for i=1 to DbGetExperCount do if (DbGetExperClass(i)="CHR") and (DbGetExperName(i)=vntrcharsetname) then expernr=i;
if expernr>0 then {
st="";
node=XMLNodeReadString(st,errorlist);
DbSetExperSettings(expernr,XMLNodeGetChild(node,"Charsettings"));
XMLNodeCloseDocument(node);
}
}
//check if vntr char fragment set experiment is available
ok=0;
for i=1 to DbGetExperCount do
if (DbGetExperClass(i)="CHR") and (DbGetExperName(i)=vntrfragsetname) then ok=1;
if not(ok) then {
message("The character experiment '"+vntrfragsetname+"' will now be created");
DbCreateExperType(vntrfragsetname,"CHR");
expernr=0;for i=1 to DbGetExperCount do if (DbGetExperClass(i)="CHR") and (DbGetExperName(i)=vntrfragsetname) then expernr=i;
if expernr>0 then {
st="";
node=XMLNodeReadString(st,errorlist);
DbSetExperSettings(expernr,XMLNodeGetChild(node,"Charsettings"));
XMLNodeCloseDocument(node);
}
}
//read file
vntrcount=0;
xmldoc=XMLNodeReadFile(DbGetPath+"\VNTR_sett.xml",error);
if (error="") and XMLNodeIsValid(xmldoc) then {
rootnode=XMLNodeGetChild(xmldoc,"VNTRSETT");
if XMLNodeIsValid(rootnode) then {
node1=XMLNodeGetChild(rootnode,"VNTRS");
if XMLNodeIsValid(node1) then {
for i=1 to XMLNodeGetChildCount(node1) do {
node2=XMLNodeGetChildByNr(node1,i);
vntrcount=vntrcount+1;
vntr_name[vntrcount]=XMLNodeGetText(XMLNodeGetChild(node2,"Name"));
vntr_fprint[vntrcount]=XMLNodeGetText(XMLNodeGetChild(node2,"FprintType"));
vntr_offset[vntrcount]=val(XMLNodeGetAttrib(node2,"Offset"));
vntr_length[vntrcount]=val(XMLNodeGetAttrib(node2,"RepeatLength"));
vntr_minval[vntrcount]=val(XMLNodeGetAttrib(node2,"MinCount"));
vntr_maxval[vntrcount]=val(XMLNodeGetAttrib(node2,"MaxCount"));
vntr_tol[vntrcount]=val(XMLNodeGetAttrib(node2,"Tolerance"));
}
}
}
}
XMLNodeCloseDocument(xmldoc);
//ask settings
finished=0;
while not(finished) do {
vntrlist=""; for i=1 to vntrcount do vntrlist=vntrlist+vntr_name[i]+" ";
DlgReset(dlg);
DlgAddText(dlg,"Defined VNTR's ("+str(vntrcount,0,0)+")",15,15,180,15);
DlgAddList(dlg,vntrlist,vntrsel,15,40,180,200,"LIST");
DlgAddButton(dlg,"Edit...",10,20,240,50,25);
DlgAddButton(dlg,"Add...",11,80,240,50,25);
DlgAddButton(dlg,"Delete...",12,140,240,50,25);
DlgAddButton(dlg,"Ok",91,230,20,80,25);
DlgAddButton(dlg,"Cancel",99,230,60,80,25);
DlgAddButton(dlg,"Assign...",92,230,140,80,25);
x1=DlgShow(dlg,"VNTR assign",350,320);
if (x1=99) or (x1=0) then stop;
if x1=91 then finished=1;
if x1=92 then finished=2;
edit_isnew=0;
vntrselnr=0;
for i=1 to vntrcount do if vntrsel=vntr_name[i] then vntrselnr=i;
//create new VNTR
if x1=11 then {
vntrcount=vntrcount+1;
j=0;ok=0;
while not(ok) do {
j=j+1;st=str(j,0,0);while length(st)<3 do st="0"+st;st="VNTR"+st;
ok=1; for i=1 to vntrcount do if st=vntr_name[i] then ok=0;
}
vntr_name[vntrcount]=st;
vntr_offset[vntrcount]=0;
vntr_length[vntrcount]=0;
vntr_minval[vntrcount]=0;vntr_maxval[vntrcount]=100;
vntr_tol[vntrcount]=0;
vntr_fprint[vntrcount]="";
vntrsel=st;vntrselnr=vntrcount;
x1=10;
edit_isnew=1;
}
//edit VNTR
if (x1=10) and (vntrselnr=0) then { Message("No VNTR selected!"); x1=-1; }
if x1=10 then {
str_vntr=vntr_name[vntrselnr];
str_offset=str(vntr_offset[vntrselnr],0,0);
str_length=str(vntr_length[vntrselnr],0,0);
str_minval=str(vntr_minval[vntrselnr],0,0);
str_maxval=str(vntr_maxval[vntrselnr],0,0);
str_tol=str(vntr_tol[vntrselnr],0,0);
str_fprint=vntr_fprint[vntrselnr];
DlgReset(dlg);
DlgAddText(dlg,"Name:",15,20,70,15);
DlgAddEdit(dlg,str_vntr,90,20,90,20);
DlgAddText(dlg,"Offset:",15,50,70,15);
DlgAddEdit(dlg,str_offset,90,50,90,20);
DlgAddText(dlg,"Repeat length:",15,80,70,15);
DlgAddEdit(dlg,str_length,90,80,90,20);
DlgAddText(dlg,"Copy range:",15,110,70,15);DlgAddText(dlg,"-",132,110,10,15);
DlgAddEdit(dlg,str_minval,90,110,35,20);
DlgAddEdit(dlg,str_maxval,145,110,35,20);
DlgAddText(dlg,"Tolerance:",15,140,70,15);
DlgAddEdit(dlg,str_tol,90,140,90,20);
DlgAddText(dlg,"Take from fingerprint type:",215,20,140,15);
DlgAddList(dlg,fprintlist,str_fprint,215,40,140,180,"DROP");
finished2=0;
while not(finished2) do {
x2=DlgShow(dlg,"Edit VNTR",370,210);
if x2=0 then finished2=1;
if x2=1 then {
finished2=1;
if finished2 then {
for i=1 to vntrcount do if (i<>vntrselnr) and (vntr_name[i]=str_vntr) then finished2=0;
if not(finished2) then message("There exists already a VNTR with this name");
}
if (finished2) and (val(str_length)<=0) then { message("Invalid repeat length");finished2=0; }
if (finished2) and (str_fprint="") then { message("You should provide a fingerprint type");finished2=0; }
if (finished2) and (2*val(str_tol)>=val(str_length)) then { message("Tolerance is too high");finished2=0; }
}
}
if edit_isnew and (x2=0) then vntrcount=vntrcount-1;
if x2=1 then {
vntr_name[vntrselnr]=str_vntr;
vntr_offset[vntrselnr]=val(str_offset);
vntr_length[vntrselnr]=val(str_length);
vntr_minval[vntrselnr]=val(str_minval);
vntr_maxval[vntrselnr]=val(str_maxval);
vntr_tol[vntrselnr]=val(str_tol);
vntr_fprint[vntrselnr]=str_fprint;
}
}
//delete existing VNTR
if (x1=12) and (vntrselnr=0) then { Message("No VNTR selected!"); x1=-1; }
if x1=12 then {
DlgReset(dlg);
DlgAddText(dlg,"Are you sure you want to remove VNTR '"+vntr_name[vntrselnr]+"'?",15,15,150,30);
x2=DlgShow(dlg,"Confirmation",300,120);
if x2=1 then {
vntrcount=vntrcount-1;
for i=vntrselnr to vntrcount do {
vntr_name[i]=vntr_name[i+1];
vntr_offset[i]=vntr_offset[i+1];
vntr_length[i]=vntr_length[i+1];
vntr_minval[i]=vntr_minval[i+1];
vntr_maxval[i]=vntr_maxval[i+1];
vntr_tol[i]=vntr_tol[i+1];
vntr_fprint[i]=vntr_fprint[i+1];
}
}
}
}
//save VNTR settings
if (x1=91) or (x1=92) then {
XMLNodeCreateDoc("VNTRSETT",xmldoc,rootnode);
node1=XMLNodeAddChild(rootnode,"VNTRS");
for i=1 to vntrcount do {
node2=XMLNodeAddChild(node1,"VNTR");
XMLNodeAddAttrib(node2,"Offset",str(vntr_offset[i],0,0));
XMLNodeAddAttrib(node2,"RepeatLength",str(vntr_length[i],0,0));
XMLNodeAddAttrib(node2,"MinCount",str(vntr_minval[i],0,0));
XMLNodeAddAttrib(node2,"MaxCount",str(vntr_maxval[i],0,0));
XMLNodeAddAttrib(node2,"Tolerance",str(vntr_tol[i],0,0));
XMLNodeAddText(XMLNodeAddChild(node2,"Name"),vntr_name[i]);
XMLNodeAddText(XMLNodeAddChild(node2,"FprintType"),vntr_fprint[i]);
}
XMLNodeToFile(xmldoc,DbGetPath+"\VNTR_sett.xml");
XMLNodeCloseDocument(xmldoc);
}
//assign VNTRs to selected entries
if x1=92 then {
for i=1 to vntrcount do if ChrSetFindChar(vntrcharsetname,vntr_name[i])=0 then ChrSetAddChar(vntrcharsetname,vntr_name[i],5000);
for i=1 to vntrcount do if ChrSetFindChar(vntrfragsetname,vntr_name[i])=0 then ChrSetAddChar(vntrfragsetname,vntr_name[i],2000);
totcount=0;
setbusy("Calculating VNTR's...");
for ctr=1 to DbGetEntryCount do if DbGetSel(DbGetEntryKey(ctr)) then {
totcount=totcount+1;
key=DbGetEntryKey(ctr);
if not(ChrLoad(cs,key,vntrcharsetname)) then
ChrCreate(cs,vntrcharsetname,"",key);
if not(ChrLoad(cs2,key,vntrfragsetname)) then
ChrCreate(cs2,vntrfragsetname,"",key);
for i=1 to vntrcount do {
nr=ChrFindName(cs,vntr_name[i]);
nr2=ChrFindName(cs2,vntr_name[i]);
if nr>0 then {
ChrSetAbsent(cs,nr);
if nr2>0 then ChrSetAbsent(cs2,nr2);
if not(FprLoadNorm(fpr,key,vntr_fprint[i])) then {
errorlist=errorlist+"Unable to load '"+vntr_fprint[i]+"' for entry '"+key+"'~n";
}
else {
bestrepcount=-1;bestbandh=0;bestdist=10000;foundseveral=0;
feasiblecount=0;
for j=1 to FprGetBandCount(fpr) do {
FprGetBandQuant(fpr,j,metric,vol,conc);
FprGetBandInfo(fpr,j,ps,h,w);
k=Floor((metric-vntr_offset[i])/vntr_length[i]+0.5);
dist=abs(metric-vntr_offset[i]-k*vntr_length[i]);
if (k>=vntr_minval[i]) and (k<=vntr_maxval[i]) and (dist<=vntr_tol[i]) then {
feasiblecount=feasiblecount+1;
feasible_metric[feasiblecount]=metric;
feasible_h[feasiblecount]=h;
feasible_ct[feasiblecount]=k;
if (bestrepcount>=0) and (k<>bestrepcount) then foundseveral=1;
if bestbandh<=h then { bestrepcount=k; bestbandh=h; bestdist=dist; bestfeasible=feasiblecount; }
}
}
if bestrepcount>0 then {
ChrSetVal(cs,nr,bestrepcount);
ChrSetVal(cs2,nr2,feasible_metric[bestfeasible]);
if foundseveral then {
errorlist=errorlist+"Found several feasible bands found for VNTR '"+vntr_name[i]+"' in entry '"+key+"' :~n";
for j=1 to feasiblecount do {
errorlist=errorlist+" "+str(feasible_ct[j],0,0)+"x ";
errorlist=errorlist+"Fragment: "+str(feasible_metric[j],0,1);
errorlist=errorlist+" ; Expected: "+str(feasible_ct[j]*vntr_length[i]+vntr_offset[i],0,0);
errorlist=errorlist+" ; Height: "+str(feasible_h[j],0,1);
if j=bestfeasible then errorlist=errorlist+" [*]";
errorlist=errorlist+"~n";
}
}
} else {
errorlist=errorlist+"No feasible bands found for VNTR '"+vntr_name[i]+"' in entry '"+key+"'~n";
}
}
}
}
ChrSave(cs);
ChrSave(cs2);
}
setbusy("");
if totcount=0 then {
Message("No entries are currently selected!");
}
if errorlist<>"" then {
DlgReset(dlg);
DlgAddEdit(dlg,errorlist,15,15,650,300);
DlgShow(dlg,"Error report",700,450);
}
}