// toiinterpolator.cc // Eric Aubourg CEA/DAPNIA/SPP octobre 1999 #include "toiinterpolator.h" #include "toimanager.h" #include "archexc.h" TOIInterpolator::TOIInterpolator() { } string TOIInterpolator::getName() { return("TOIInterpolator 1.0"); } bool TOIInterpolator::canProduce(TOI const& toi) { // 1. Already in cache ? map >::const_iterator j = neededTOIs.find(toi); if (j != neededTOIs.end()) return true; // 2. Should have interp if (toi.options.find("interp") == toi.options.end()) return false; // 3. Can get non interp TOI toi2 = toi; toi2.options.erase("interp"); TOIProducer* prod = TOIManager::findTOIProducer(toi2); set opts = prod->getAvailOptions(toi2); if (opts.find("interp") != opts.end()) return false; // already handled if (opts.find("repet") != opts.end()) return false; // not compatible ! map fullInputTOI; fullInputTOI[toi2] = prod; neededTOIs[toi] = fullInputTOI; return true; } set TOIInterpolator::reqTOIFor(TOI const& toi) { set x; if (!canProduce(toi)) return x; x.insert((*neededTOIs[toi].begin()).first); return x; } bool TOIInterpolator::canGetValue(long sampleNum, TOI const& toi) { map & inp = neededTOIs[toi]; TOIProducer* prod = (*inp.begin()).second; TOI const& inTOI = (*inp.begin()).first; if (prod->canGetValue(sampleNum, inTOI)) return true; // direct if (prod->canGetPrevValue(sampleNum, inTOI) && prod->canGetNextValue(sampleNum, inTOI)) return true; return false; } bool TOIInterpolator::canGetValueLater(long sampleNum, TOI const& toi) { map & inp = neededTOIs[toi]; TOIProducer* prod = (*inp.begin()).second; TOI const& inTOI = (*inp.begin()).first; if (prod->canGetValue(sampleNum, inTOI)) return false; // direct if (prod->canGetValueLater(sampleNum, inTOI)) return true; // direct if (!prod->canGetPrevValue(sampleNum, inTOI)) return false; // no hope if (prod->canGetNextValue(sampleNum, inTOI)) return false; // can get now return true; } double TOIInterpolator::getValue(long sampleNum, TOI const& toi) { map & inp = neededTOIs[toi]; TOIProducer* prod = (*inp.begin()).second; TOI const& inTOI = (*inp.begin()).first; if (prod->canGetValue(sampleNum, inTOI)) return prod->getValue(sampleNum, inTOI); // direct long sn1 = sampleNum; double v1 = prod->getPrevValue(sn1, inTOI); long sn2 = sampleNum; double v2 = prod->getNextValue(sn2, inTOI); if (sn1 == sn2) throw ArchExc("Inconsistence in interp, sn1==sn2"); return v1 + (v2-v1) * (sampleNum-sn1) / (sn2-sn1); } void TOIInterpolator::propagateLowBound(TOI const& toi, long sampleNum) { CHKPROD map & inp = neededTOIs[toi]; TOIProducer* prod = (*inp.begin()).second; TOI const& inTOI = (*inp.begin()).first; if (prod->canGetPrevValue(sampleNum,toi)) { prod->getPrevValue(sampleNum, toi); sampleNum--; prod->wontNeedEarlier(toi, this, sampleNum); } }