//$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); } }