Index: trunk/Poubelle/archTOI.old/toiinterpolator.cc
===================================================================
--- trunk/Poubelle/archTOI.old/toiinterpolator.cc	(revision 350)
+++ trunk/Poubelle/archTOI.old/toiinterpolator.cc	(revision 555)
@@ -1,82 +1,100 @@
 // toiinterpolator.cc
-// Eric Aubourg         CEA/DAPNIA/SPP   juillet 1999
+// Eric Aubourg         CEA/DAPNIA/SPP   octobre 1999
 
 
 #include "toiinterpolator.h"
+#include "toimanager.h"
+#include "archexc.h"
 
-void TOIInterpolator::enterValue(double value, long sample)
-{
-  // $CHECK$ sample > back.sample
-  if (!hist.empty() && sample == hist.back().t) return; // pour eviter /0
-  hist.push_back(pair(value, sample));
+TOIInterpolator::TOIInterpolator() {
 }
 
-bool TOIInterpolator::needMoreDataFor(long sample)
-{
-  if (hist.empty()) return true;
-  int xx = hist.back().t;
-  return (hist.empty() || sample > xx);
+
+string TOIInterpolator::getName() {
+  return("TOIInterpolator 1.0");
 }
 
-bool TOIInterpolator::canGet(long sample)
-{
-  return (!hist.empty() && (sample >= hist.front().t && sample <= hist.back().t));
+bool TOIInterpolator::canProduce(TOI const& toi) {
+  // 1. Already in cache ?
+  map<TOI, map<TOI, TOIProducer*> >::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<string> 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<TOI, TOIProducer*> fullInputTOI;
+  fullInputTOI[toi2] = prod;
+  neededTOIs[toi] = fullInputTOI;
+  return true;
 }
 
-double TOIInterpolator::getEValue(long sample) // can forget before sample
-{
-  if (!canGet(sample)) return -9.e99;   // user should have checked before
-  deque<pair>::iterator i = hist.begin();
-  while ((*i).t < sample) i++;
-  if ((*i).t > sample) i--;
-  double value = (*i).val;
-  if (i != hist.begin()) {
-    i--;
-    hist.erase(hist.begin(), i);
-  }
-  return value;
+set<TOI> TOIInterpolator::reqTOIFor(TOI const& toi) {
+  set<TOI> x;
+  if (!canProduce(toi)) return x;
+  x.insert((*neededTOIs[toi].begin()).first);
+  return x;
 }
 
-double TOIInterpolator::getIValue(long sample) // can forget before sample
-{
-  if (!canGet(sample)) return -9.e99;   // user should have checked before
+bool TOIInterpolator::canGetValue(long sampleNum, TOI const& toi) {
+  map<TOI, TOIProducer*> & inp = neededTOIs[toi];
+  TOIProducer* prod  = (*inp.begin()).second;
+  TOI const&   inTOI = (*inp.begin()).first;
   
-  deque<pair>::iterator i = hist.begin();
-  while ((*i).t < sample) i++;
-  double value;
-  if ((*i).t == sample) {
-    value = (*i).val;
-  } else {    
-    long samp2 = (*i).t;
-    double val2 = (*i).val;
-    i--;
-    long samp1 = (*i).t;
-    double val1 = (*i).val;
-    value = val1 + (val2-val1)*(sample-samp1)/(samp2-samp1);
-  }
-  if (i != hist.begin()) {
-    i--;
-    hist.erase(hist.begin(), i);
-  }
-  return value;
-}
-
-bool TOIInterpolator::isNewValue(long sample) 
-{
-  deque<pair>::iterator i = hist.begin();
-  while (i!=hist.end()) {
-    if ((*i).t == sample) return true;
-    if ((*i).t > sample) return false;
-    i++;
-  }
+  if (prod->canGetValue(sampleNum, inTOI)) return true; // direct
+  if (prod->canGetPrevValue(sampleNum, inTOI) &&
+      prod->canGetNextValue(sampleNum, inTOI)) return true;
   return false;
 }
 
-
-long TOIInterpolator::nextSample(long sampleMin)
-{
-  for (deque<pair>::iterator i = hist.begin(); i<hist.end(); i++) 
-    if ((*i).t >= sampleMin) return (*i).t;
-  return -1;
+bool TOIInterpolator::canGetValueLater(long sampleNum, TOI const& toi) {
+  map<TOI, TOIProducer*> & 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<TOI, TOIProducer*> & 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<TOI, TOIProducer*> & 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);
+  }
+}
+
