/* ************************************************************************ * * co.C - * * Copyright (c) 1995 * * ETH Zuerich * Institut fuer Molekularbiologie und Biophysik * ETH-Hoenggerberg * CH-8093 Zuerich * * All Rights Reserved * * Date of last modification : 95/09/15 * Pathname of SCCS file : /export/home3/cb/garant-1.0/src/SCCS/s.co.C * SCCS identification : 1.3 * ************************************************************************ */ /**************************************************************************/ /* co.cc */ /* */ /* coherences and list of coherences */ /**************************************************************************/ #include #include #include #include "wert.h" #include "log.h" #include "global.h" #include "atom.h" #include "co.h" #include "specTypes.h" #include "parser.h" #include "erPeak.h" #include "frag.h" #include "functions.h" /* Names of observable nuclei */ char name_nuclei[NR_NUCLEI][10] = {"Proton","Carbon","Nitrogen","Phosphor"}; /* selection distribution for expected chemical shifts */ float expectScore[] = { 1.0, 0.98, 0.95, 0.90, 0.8, 0.6, 0.5, 0.15, 0.001 }; /* number of entries in the distributions */ #define RESOLUTION 8 float expDistr(Wert f, float shift) { int index; if(f.v != 0.0) { index = (int)floor(fabs((f.x-shift)/f.v/4.0) * RESOLUTION); if(index > RESOLUTION) index = RESOLUTION; } else { index = RESOLUTION; } return expectScore[index]; } void LiCo::print(int off) { Log log; char str[MAXLINE]; sprintf(str,"%*sList of coherences:\n",off,""); log.w(str); Index::print(off+3); } void LiCo::listDif(char *t, float tol) { Coherence *co; Log log; char name[MAXNAME]; char str[MAXLINE]; float diff; Iterator i; Wert expected; int nrOk=0,nrBad=0; co = (Coherence *)startPars(i,t); while(co != 0) { if(co->meanF.valid() && co->firstAt()->frag->type == DESTFRAG) { expected=co->expFreq(); diff=expected.x - co->meanF.x; if(diff>tol || diff<(-tol)) { co->fullNameGet(name); if(co->assF.x != BAD_PPM) sprintf(str,"\n %15s at %7.3g, loaded %7.3g, deviation %7.3g", name,co->meanF.x, expected.x, diff); else sprintf(str,"\n %15s at %7.3g, expected %7.3g, deviation %7.3g", name,co->meanF.x, expected.x, diff); log.w(str); nrBad++; } else { nrOk++; } } co = (Coherence *)nextPars(i,t); } sprintf(str,"\n... %d coherences within tolerance, %d outside of tolerance", nrOk,nrBad); log.w(str); } int LiCo::compare(const Element *c1,const Element *c2) { int res; Atom *a1,*a2; res = c2->t - c1->t; a2 = ((Coherence *)c2)->nuclei[0]; a1 = ((Coherence *)c1)->nuclei[0]; if(!res) res = a2->frag->nrExt - a1->frag->nrExt; if(!res) res = strcmp(a2->name, a1->name); if(!res) res = a2->frag->type - a1->frag->type; if(!res) res = a2->nr - a1->nr; return(res); } int LiCo::compare(int nrExt, char *name, int type, const Coherence *c2) { int res; Atom *a2; a2 = ((Coherence *)c2)->nuclei[0]; res = a2->frag->nrExt - nrExt; if(!res) res = strcmp(a2->name, name); if(!res) res = a2->frag->type - type; return(res); } Coherence *LiCo::find(int nrExt,char *name,int type) { int i,j,res; // element if(n==0) return(0); i=0; j=n-1; cur=0; res=1; while(i<=j && res !=0) { cur = (i+j)/2; res=compare(nrExt,name,type,(Coherence *)l[cur]); if(res < 0) i=cur+1; else j=cur-1; } if(res==0) return((Coherence *)l[cur]); else if(res<0) {cur++; return(0); } else return(0); } OrdLiCo::OrdLiCo(LiCo &list) : Index(list.getn()) { Coherence *co; remove(); co = (Coherence *)list.start(); while(co != 0) { add(co); co = (Coherence *)list.next(); } sort(); } int OrdLiCo::compare(const Element *c1,const Element *c2) { int res=0; float diff; diff = ((Coherence *)c2)->meanF.x - ((Coherence *)c1)->meanF.x; if(diff < 0) res = -1; if(diff > 0) res = 1; if(!res) { res = ((Coherence *)c2)->nuclei[0]->nr - ((Coherence *)c1)->nuclei[0]->nr; } return(res); } CoAss::CoAss() { measF = new float[usedSpec.used]; } Coherence::Coherence(): nrErPeak(0), nuclei(0) { int i; t=COHERENCE; nrErPeak = 0; maxErPeak = 8; peaks = new ErPeak*[maxErPeak]; status = UNASSIGNED; fixed=0; measF = new Mean[usedSpec.used]; for(i=0;inr].valid()) return Wert(measF[spec->nr].x,spec->type->accPick[dim]); else if(meanF.valid()) return Wert(meanF.x,spec->type->accSpec[dim]); else return Wert(BAD_PPM); } void Coherence::expRange(float &low, float &up) { float del; if(assF.x != BAD_PPM) { del = 3.0*assF.v + assF.randomv(); low = assF.x-del; up = assF.x+del; } else { del = 3.0*expF.v + expF.randomv(); low = expF.x - del; up = expF.x + del; } //printf("[%7.3g,%7.3g] ",low,up); //print(3); } void Coherence::meanRange(Spectrum *spec,int dim, float &low, float &up) { if(measF[spec->nr].valid()) { low = measF[spec->nr].x - spec->type->accPick[dim]; up = measF[spec->nr].x + spec->type->accPick[dim]; } else { low = meanF.x - spec->type->accSpec[dim]; up = meanF.x + spec->type->accSpec[dim]; } } void Coherence::notifyNewFreq(float w,float, float *,Spectrum *spec, int decision) { int i; if(decision == RESET) { meanF = Mean(); for(i=0;inr].add(w); status = ASSIGNED; } void Coherence::notifyFreqReset(float w, Spectrum *spec) { int i; meanF.sub(w); if(!meanF.valid()) for(i=0;inr].sub(w); } } void Coherence::print(int off) { Log log; char str[MAXLINE]; if(meanF.valid()) sprintf(str,"%*sCoherence at %7.3g:\n",off,"",meanF.v); else sprintf(str,"%*sundefined Coherence:\n",off,""); log.w(str); nuclei[0]->print(off+3); } void Coherence::setAss(int nr) { int i; for(i=0;igetAss(); if(ass != 0) { for(j=0;jspec->type->dim;j++) { if(peaks[i]->liCo[j] == this) { measF[peaks[i]->spec->nr].add(ass->w[j]); meanF.add(ass->w[j]); x += ass->w[j]; x2 += ass->w[j] * ass->w[j]; n++; } } } } if(n>1) { x /= n; x2 /= n; s = (x2 - x*x) / (n-1.0); if(s<0.0000001) s = 0.0; meanF.v = sqrt(s); } if(meanF.valid()) status = ASSIGNED; else status = UNASSIGNED; return(meanF.valid()); } void Coherence::updateScores() { int i,idim,ip, it; int deviation; float partPeaks,partFreq; float partAss, partDev; float partDegen; float pExist; float pMutInf; float temp; Peak *peak; ErPeak *erPeak; float freq; int dim; int dimP[NREXP]; partPeaks=0.0; partAss=0; partDegen=0; partDev=0.0; mutInf=0.0; localScore=0.0; if(meanF.valid()) { for(i=0;idim; for(idim=0;idimaccPick[idim], freq + usedSpec.li[i].type->accPick[idim]); while(peak!=0) { if(peak->p->nrAss>0) { for(ip=0;ipp->nrAsslinks;ip++) { erPeak = peak->p->asslink[ip]; if(erPeak->getAss()==peak) { /* folding */ deviation = (int)(fabs(peak->w[idim]-freq) / usedSpec.li[i].type->accPick[idim] * MAX_DEV * RES_SCORE); if(deviation>=MAX_DEV * RES_SCORE) deviation = MAX_DEV * RES_SCORE - 1; pExist = erPeak->pExist / peak->p->nrAss; pMutInf = erPeak->spec->type->importance * erPeak->importance * erPeak->pExist; if(erPeak->getCo(idim)==this) { dimP[i]=idim; temp = usedSpec.li[i].bonusAss[idim][deviation]; partAss += temp*pExist; erPeak->mutInf += temp*pMutInf; } else { temp = usedSpec.li[i].penDegen[idim][deviation]; partDegen += temp*pExist; erPeak->mutInf += temp*pMutInf; } } } } peak=usedSpec.li[i].liPeakDim[idim].nextRange(); } } } erPeak=startPeak(it); while(erPeak != 0) { if(erPeak->type == DESTFRAG && (erPeak->getAss() || erPeak->isPresent())) { pExist = erPeak->pExist; pMutInf = erPeak->spec->type->importance * erPeak->importance * erPeak->pExist; temp = erPeak->spec->bonusPeak / dim; partPeaks += temp*pExist; erPeak->mutInf += temp*pMutInf; } erPeak=nextPeak(it); } if(assF.x != BAD_PPM && assF.v>0.0) { freq = fabs(meanF.x - assF.x) / assF.v; partFreq = bonusFreq - 0.5 * freq * freq; } else if(expF.v>0.0) { freq = fabs(meanF.x - expF.x) / expF.v; partFreq = bonusFreq - 0.5 * freq * freq; } else { partFreq=0.0; } for(i=0;i=0) { freq = fabs(meanF.x - measF[i].x) / usedSpec.li[i].type->accPick[dimP[i]] * MAX_DEV; partDev += usedSpec.li[i].bonusDevMean[dimP[i]] - 0.5 * freq * freq; } } mutInf=partFreq+partDev; localScore = partPeaks+partAss+partDegen+partFreq+partDev; } if(nrErPeak>0) { localScore = (localScore - sumPeakP) / nrErPeak; } if(maxScorespec->bonusPeak * peaks[i]->pExist / // peaks[i]->spec->type->dim; sumPeakP += peaks[i]->spec->bonusAss[0][0] * peaks[i]->pExist; } } int Coherence::cpMeanToAss() { if(meanF.valid()) assF = meanF; return meanF.valid(); } void Coherence::resetAssF() { assF = BAD_PPM; } Atom *Coherence::start(Iterator &) { return 0; } Atom *Coherence::next(Iterator &) { return 0; } ErPeak *Coherence::startPeak(int &i) { i=0; if(nrErPeak) return peaks[0]; else return 0; } ErPeak *Coherence::nextPeak(int &i) { i++; if(istatPseudo != PSEUDOCO) { pseudo->insert(co); co->pseudo->insert(this); statPseudo=PSEUDOCO; } else { co2=(Coherence *)co->pseudo->start(); while(co2!=0) { addCoToPseudo(co2); co2=(Coherence *)co->pseudo->next(); } } } int Coherence::pseudIdentical(Coherence *co) { int res=0; if(firstAt()->frag->type == co->firstAt()->frag->type) { if(this == co) { res=1; } else if(statPseudo==PSEUDON) { if(co->statPseudo==PSEUDON && co->pseudCo==pseudCo || co->statPseudo!=PSEUDON && co==pseudCo) res=1; } else if(co->statPseudo==PSEUDON && this==co->pseudCo) { res=1; } if(statPseudo==PSEUDON && co->statPseudo==PSEUDON && co->pseudCo==pseudCo) { res=1; } } return res; } int Coherence::floatIdentical(Coherence *co) { int res=0; Atom *floatAt,*at1,*at2; at1=firstAt(); at2=co->firstAt(); if(at1!=0 && at2 !=0) { if(at1->pseud.getn()==0) { res = (at1->frag->nrExt == at2->frag->nrExt && strcmp(at1->name,at2->name)==0); } else { floatAt=(Atom *)at1->pseud.start(); while(!res && floatAt) { res = (floatAt->frag->nrExt == at2->frag->nrExt && strcmp(floatAt->name,at2->name)==0); floatAt=(Atom *)at1->pseud.next(); } } } return res; } int Coherence::floatEquivalent(Coherence *co) { int res=0; Atom *floatAt,*at1,*at2; at1=firstAt(); at2=co->firstAt(); if(at1!=0 && at2 !=0) { if(at1->pseud.getn()==0) { res = (at1->frag->equiv(at2->frag) && strcmp(at1->name,at2->name)==0); } else { floatAt=(Atom *)at1->pseud.start(); while(!res && floatAt) { res = (floatAt->frag->equiv(at2->frag) && strcmp(floatAt->name,at2->name)==0); floatAt=(Atom *)at1->pseud.next(); } } } return res; } int Coherence::subEqual(Coherence *co) { int res; res= (firstAt()->frag->nrExt == co->firstAt()->frag->nrExt && strcmp(firstAt()->name,co->firstAt()->name)==0); return res; } void Coherence::turnOnPseud() { Coherence *co,*co2; ErPeak *peak,*peak2; int i1,i2; Iterator it1,it2; /* deactivate all co's */ co=(Coherence *)pseudo->start(it1); while(co != 0) { co->pseudCo=this; co->statPseudo=PSEUDON; co=(Coherence *)pseudo->next(it1); } /* of each set of identical peaks, deactivate all but one */ co=(Coherence *)pseudo->start(it1); while(co != 0) { peak = co->startPeak(i1); while(peak!=0) { if(peak->active) { co2=(Coherence *)pseudo->start(it2); while(co2 != 0) { peak2=co2->startPeak(i2); while(peak2 != 0 && co2 != co) { if(peak!=peak2 && peak->type==peak2->type && peak->pseudIdentical(peak2)) { peak->addPseudo(peak2); peak2->active=FALSE; } peak2=co2->nextPeak(i2); } co2=(Coherence *)pseudo->next(it2); } } peak = co->nextPeak(i1); } co=(Coherence *)pseudo->next(it1); } } void Coherence::turnOffPseud() { Coherence *co; ErPeak *peak; int i; Log log; char str[MAXLINE]; char name[MAXLINE]; co=(Coherence *)pseudo->start(); while(co != 0) { /* activate all peaks */ peak = co->startPeak(i); while(peak!=0) { if(peak->active && peak->liPseud != 0) delete peak->liPseud; peak->active = TRUE; peak->liPseud=0; peak = co->nextPeak(i); } /* activate all co's */ if(co->statPseudo != PSEUDOFF) { co->pseudCo->fullNameGet(name); sprintf(str,"\nWARNING: inconsistent use of pseudo atom %s",name); log.warn(-1,str); } co->pseudCo=0; co->statPseudo=PSEUDOFF; co=(Coherence *)pseudo->next(); } } int Coherence::sortFloatAss(Coherence *co1, Coherence *co2) { Coherence *exchCo; ErPeak *p1,*p2; int ip1,ip2; int res; int idim; int first; int cnt=0; Peak *ass1, *ass2; int exchSt1,exchSt2; if(co1->firstAt()->nr < co2->firstAt()->nr) { exchCo=co1; co1=co2; co2=exchCo; } if(co1->meanF.valid() && !co1->fixed && !co2->fixed && (!co2->meanF.valid() || co1->meanF.x < co2->meanF.x)) { //printf("Exchanging: %7.3f %7.3f to",co1->meanF.x,co2->meanF.x); p1=co1->startPeak(ip1); while(p1 != 0 ) { /* exchange only if canonical peak */ idim=0; while(idimspec->type->dim && p1->getCo(idim) != co1 && p1->getCo(idim) != co2) idim++; if(p1->getCo(idim)==co1) res=0; else res=1; p2=co2->startPeak(ip2); while(p2!=0 && p1->type==DESTFRAG && !res) { if(p1 != p2 && p1->spec==p2->spec && p2->type==DESTFRAG) { idim=0; res=1; first=1; while(res && idimspec->type->dim) { res=0; if(p1->getCo(idim) == p2->getCo(idim) || (p1->getCo(idim)==co1 && p2->getCo(idim)==co2) || (p1->getCo(idim)==co2 && p2->getCo(idim)==co1)) { res=1; idim++; } } if(res) { cnt++; /* get and retract old assignments */ ass1=p1->getAss(); exchSt1=p1->status; if(ass1) ass1->p->retractAsslink(p1->asslinkindex); ass2=p2->getAss(); exchSt2=p2->status; if(ass2) ass2->p->retractAsslink(p2->asslinkindex); /* set exchanged assignments */ p1->setAss(ass2); p1->status=exchSt2; if(ass2) ass2->p->establishAsslink(p1); p2->setAss(ass1); p2->status=exchSt1; if(ass1) ass1->p->establishAsslink(p2); } } p2=co2->nextPeak(ip2); } p1=co1->nextPeak(ip1); } co1->updateFreq(); co2->updateFreq(); //printf("into %7.3f %7.3f\n",co1->meanF.x,co2->meanF.x); //co1->print(5); //co2->print(5); } return cnt; } SQCo::SQCo(Atom *a, float prob, Wert freq) { t = SQCO; nuclei = new Atom*[1]; nuclei[0] = a; pUnass=prob; expF = freq; meanF = Mean(); assF = BAD_PPM; /* set type of nuclie */ if(strcmp(a->atype,"PSEUD") == 0 || strcmp(a->atype,"H_ALI") == 0 || strcmp(a->atype,"H_AMI") == 0 || strcmp(a->atype,"H_ARO") == 0 || strcmp(a->atype,"H_SUL") == 0 || strcmp(a->atype,"H_OXY") == 0) { typeNucleus=PROTON; } else if(strcmp(a->atype,"C_ALI") == 0 || strcmp(a->atype,"C_BYL") == 0 || strcmp(a->atype,"C_ARO") == 0 || strcmp(a->atype,"C_VIN") == 0) { typeNucleus=CARBON; } else if(strcmp(a->atype,"N_AMI") == 0 || strcmp(a->atype,"N_AMO") == 0) { typeNucleus=NITROGEN; } else if(strcmp(a->atype,"P_ALI") == 0) { typeNucleus=PHOSPHOR; } } int SQCo::equiv(Coherence *co) { return nuclei[0]->equiv(co->nuclei[0]); } SQCo *newRs(LiCo &liCo, Atom *a, float p) { SQCo *ret; ret = (SQCo *)liCo.find(a->frag->nrExt,a->name,a->frag->type); if(!ret) { ret = new SQCo(a,p,a->w); (void)liCo.insert(ret); a->addCo(ret); } return(ret); } void SQCo::print(int off) { printf("%*sCoherence at %7.3f+/-%7.3f; assigned: %7.3f+/-%7.3f; acore: %7.3g\n", off,"",meanF.x,meanF.v,assF.x,assF.v,bonusFreq); nuclei[0]->print(off+3); } int SQCo::match(char *t) { int nrRes,tb,ib; Parser pars; char n[MAXLINE]; fullNameGet(n); nrRes = UNDEFINED_RES_NR; return pars.coherence(t,0,tb,n,0,ib,nrRes); } void SQCo::nameGet(char *name,int &nrAa) { char dummy[MAXLINE]; nuclei[0]->fullname(name,dummy,nrAa); } void SQCo::nameSet(char *name) { nuclei[0]->nameSet(name); } void SQCo::fullNameGet(char *name) { if(statPseudo==PSEUDON) pseudCo->nuclei[0]->fullNameGet(name); else nuclei[0]->fullNameGet(name); } void SQCo::shortNameGet(char *name) { if(statPseudo==PSEUDON) pseudCo->nuclei[0]->shortNameGet(name); else nuclei[0]->shortNameGet(name); } Atom *SQCo::start(Iterator &) { return nuclei[0]; } Atom *SQCo::next(Iterator &) { return 0; }