| [350] | 1 | // toiiter.cc
 | 
|---|
 | 2 | // Eric Aubourg         CEA/DAPNIA/SPP   juillet 1999
 | 
|---|
 | 3 | 
 | 
|---|
| [534] | 4 | #include "ark.h"
 | 
|---|
| [350] | 5 | 
 | 
|---|
| [310] | 6 | #include "toiiter.h"
 | 
|---|
| [534] | 7 | #include "toimanager.h"
 | 
|---|
 | 8 | #include "toiproducer.h"
 | 
|---|
| [394] | 9 | #include "archparam.h"
 | 
|---|
| [534] | 10 | #include "asigps.h"
 | 
|---|
 | 11 | #include "toiauxgpsproducer.h"
 | 
|---|
| [342] | 12 | #include <iostream.h>
 | 
|---|
| [534] | 13 | #include <fstream.h>
 | 
|---|
| [310] | 14 | 
 | 
|---|
| [534] | 15 | #define CHK_INITED if (initDone) \
 | 
|---|
 | 16 |         throw ArchExc("Trying to modify TOIIter after init done.");
 | 
|---|
| [310] | 17 | 
 | 
|---|
 | 18 | TOIIter::TOIIter() {
 | 
|---|
| [534] | 19 |   mjdStart = -999999999;
 | 
|---|
 | 20 |   mjdEnd   =  999999999;
 | 
|---|
 | 21 |   utcStart = -999999999;
 | 
|---|
 | 22 |   utcEnd   =  999999999;
 | 
|---|
 | 23 |   sStart   = -999999999;
 | 
|---|
 | 24 |   sEnd     =  999999999;
 | 
|---|
| [342] | 25 | 
 | 
|---|
| [534] | 26 |   underSample = 1;
 | 
|---|
 | 27 |   curSample = -1;
 | 
|---|
 | 28 |   
 | 
|---|
 | 29 |   initDone = false;
 | 
|---|
 | 30 |   incDone  = false;
 | 
|---|
 | 31 | }
 | 
|---|
| [342] | 32 | 
 | 
|---|
| [534] | 33 | #ifdef __MWERKS__
 | 
|---|
 | 34 | #pragma mark -
 | 
|---|
 | 35 | #endif
 | 
|---|
 | 36 | 
 | 
|---|
 | 37 | void TOIIter::addDirectory(string dir) {
 | 
|---|
 | 38 |   CHK_INITED
 | 
|---|
 | 39 |   fset.addDirectory(dir);
 | 
|---|
| [310] | 40 | }
 | 
|---|
 | 41 | 
 | 
|---|
| [534] | 42 | void TOIIter::addFile(string fn) {
 | 
|---|
 | 43 |   CHK_INITED
 | 
|---|
 | 44 |   fset.addFile(fn);
 | 
|---|
 | 45 | }
 | 
|---|
| [310] | 46 | 
 | 
|---|
| [534] | 47 | void TOIIter::setMJDInterval(double tStart, double tEnd) {
 | 
|---|
 | 48 |   CHK_INITED
 | 
|---|
 | 49 |   if (tStart>0) mjdStart = tStart;
 | 
|---|
 | 50 |   if (tEnd>0)   mjdEnd = tEnd;
 | 
|---|
| [310] | 51 | }
 | 
|---|
 | 52 | 
 | 
|---|
| [534] | 53 | void TOIIter::setUTCInterval(double tStart, double tEnd) {
 | 
|---|
 | 54 |   CHK_INITED
 | 
|---|
 | 55 |   if (tStart>0) utcStart = tStart;
 | 
|---|
 | 56 |   if (tEnd>0)   utcEnd = tEnd;
 | 
|---|
| [310] | 57 | }
 | 
|---|
 | 58 | 
 | 
|---|
| [534] | 59 | void TOIIter::setSNInterval(long tStart, long tEnd) {
 | 
|---|
 | 60 |   CHK_INITED
 | 
|---|
 | 61 |   if (tStart>0) sStart = tStart;
 | 
|---|
 | 62 |   if (tEnd>0)   sEnd = tEnd;
 | 
|---|
 | 63 | }
 | 
|---|
 | 64 | 
 | 
|---|
 | 65 | void TOIIter::setUnderSample(int n) {
 | 
|---|
 | 66 |   CHK_INITED
 | 
|---|
 | 67 |   if (n<=1) n=1;
 | 
|---|
 | 68 |   underSample = n;
 | 
|---|
 | 69 | }
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 | int TOIIter::getUnderSample() {
 | 
|---|
 | 72 |   return underSample;
 | 
|---|
 | 73 | }
 | 
|---|
 | 74 | 
 | 
|---|
 | 75 | void TOIIter::addTOI(TOI& toi, bool trg) {
 | 
|---|
 | 76 |   CHK_INITED
 | 
|---|
 | 77 |   TOIProducer* prod = TOIManager::findTOIProducer(toi);
 | 
|---|
 | 78 |   if (!prod) throw ArchExc("Cannot produce " + toi.fullName());
 | 
|---|
 | 79 |   prod->addTOI(toi, this);
 | 
|---|
 | 80 |   request.push_back(TOIInfo(toi,prod,trg?1:0));
 | 
|---|
 | 81 | }
 | 
|---|
 | 82 | 
 | 
|---|
| [342] | 83 | #ifdef __MWERKS__
 | 
|---|
| [534] | 84 | #pragma mark -
 | 
|---|
| [342] | 85 | #endif
 | 
|---|
 | 86 | 
 | 
|---|
| [310] | 87 | 
 | 
|---|
| [534] | 88 | void TOIIter::registerReqHandler(RequestHandler* h) {
 | 
|---|
 | 89 |   CHK_INITED
 | 
|---|
 | 90 |   handlers.push_back(h);
 | 
|---|
 | 91 | }
 | 
|---|
| [315] | 92 | 
 | 
|---|
 | 93 | 
 | 
|---|
| [534] | 94 | void TOIIter::readReq(istream& str) {
 | 
|---|
 | 95 |   CHK_INITED
 | 
|---|
 | 96 |    if (!incDone) defaultInclude();
 | 
|---|
 | 97 |    string line;
 | 
|---|
 | 98 |    while (str) {
 | 
|---|
 | 99 |      getline(str,line);
 | 
|---|
 | 100 |      if (!str) break;
 | 
|---|
 | 101 |      if (line.substr(0,4)=="#END" && (line.length()==4 || line[5] == ' ')) break;
 | 
|---|
 | 102 |      if (line[0] != '@' && line[0] != '#') continue;
 | 
|---|
 | 103 |      if (!processRequest(line)) {
 | 
|---|
 | 104 |        throw ArchExc("Unrecognized directive " + line);
 | 
|---|
 | 105 |      }
 | 
|---|
 | 106 |    }
 | 
|---|
| [310] | 107 | }
 | 
|---|
 | 108 | 
 | 
|---|
| [534] | 109 | 
 | 
|---|
 | 110 | bool TOIIter::processRequest(string line) {
 | 
|---|
 | 111 |   if (line[0] == '#') {
 | 
|---|
 | 112 |     int x = line.find(' ');
 | 
|---|
 | 113 |     string keyw = line.substr(0, x);
 | 
|---|
 | 114 |     string args = (x>0) ? line.substr(x) : string("");
 | 
|---|
 | 115 |     bool handled = processOption(keyw,args);
 | 
|---|
 | 116 |     for (list<RequestHandler*>::iterator i = handlers.begin(); 
 | 
|---|
 | 117 |          i != handlers.end(); i++) {
 | 
|---|
 | 118 |       handled |= (*i)->processOption(keyw,args);
 | 
|---|
| [350] | 119 |     }
 | 
|---|
| [534] | 120 |     return handled;
 | 
|---|
| [350] | 121 |   }
 | 
|---|
| [534] | 122 | 
 | 
|---|
 | 123 |   if (line[0] == '@') {
 | 
|---|
 | 124 |     TOI toi(line.substr(1));
 | 
|---|
 | 125 |     // if (kind  == sampleNum || kind == mjd || kind == mutc) notrig = true;
 | 
|---|
 | 126 |     bool handled = processTOIReq(toi,line);
 | 
|---|
 | 127 |     for (list<RequestHandler*>::iterator i = handlers.begin(); 
 | 
|---|
 | 128 |          i != handlers.end(); i++) {
 | 
|---|
 | 129 |       handled |= (*i)->processTOIReq(toi,line);
 | 
|---|
| [350] | 130 |     }
 | 
|---|
| [534] | 131 |     return handled;
 | 
|---|
| [350] | 132 |   }
 | 
|---|
| [534] | 133 |   return false;
 | 
|---|
| [350] | 134 | }
 | 
|---|
 | 135 | 
 | 
|---|
| [534] | 136 | 
 | 
|---|
 | 137 | bool TOIIter::processTOIReq(TOI& toi,string)
 | 
|---|
 | 138 | {
 | 
|---|
 | 139 |   TOI toi2 = toi;
 | 
|---|
 | 140 |   bool trg=true;
 | 
|---|
 | 141 |   if (toi.options.find("notrig") != toi.options.end()) {
 | 
|---|
 | 142 |     toi2.options.erase("notrig");
 | 
|---|
 | 143 |     trg=false;
 | 
|---|
 | 144 |   } 
 | 
|---|
 | 145 |   addTOI(toi2, trg);
 | 
|---|
 | 146 |   toi.unit = toi2.unit;
 | 
|---|
 | 147 |   return true;
 | 
|---|
 | 148 | } 
 | 
|---|
 | 149 | 
 | 
|---|
 | 150 | 
 | 
|---|
 | 151 | bool TOIIter::processOption(string key, string arg)
 | 
|---|
 | 152 | {
 | 
|---|
 | 153 |   if (arg.length()>0 && arg[0] == ' ') {
 | 
|---|
 | 154 |     arg = arg.substr(arg.find_first_not_of(' '));
 | 
|---|
 | 155 |   }
 | 
|---|
 | 156 |   if (key == "#MJDRANGE") {
 | 
|---|
 | 157 |     double tmin, tmax;
 | 
|---|
 | 158 |     sscanf(arg.c_str(), "%lg %lg", &tmin, &tmax);
 | 
|---|
 | 159 |     setMJDInterval(tmin, tmax);
 | 
|---|
 | 160 |   } else if (key == "#UTCRANGE") {
 | 
|---|
 | 161 |     double tmin, tmax;
 | 
|---|
 | 162 |     sscanf(arg.c_str(), "%lg %lg", &tmin, &tmax);
 | 
|---|
 | 163 |     setUTCInterval(tmin, tmax);
 | 
|---|
 | 164 |   } else if (key == "#SNRANGE") {
 | 
|---|
 | 165 |     long tmin, tmax;
 | 
|---|
 | 166 |     sscanf(arg.c_str(), "%ld %ld", &tmin, &tmax);
 | 
|---|
 | 167 |     setSNInterval(tmin, tmax);
 | 
|---|
 | 168 |   } else if (key == "#PATH") {
 | 
|---|
 | 169 |     addDirectory(arg);
 | 
|---|
 | 170 |   } else if (key == "#FILE") {
 | 
|---|
 | 171 |     addFile(arg);
 | 
|---|
 | 172 |   } else if (key == "#UNDERSAMPLE") {
 | 
|---|
 | 173 |     setUnderSample(atoi(arg.c_str()));
 | 
|---|
 | 174 |   } else if (key == "#MJD0") {
 | 
|---|
 | 175 |     double t0;
 | 
|---|
 | 176 |     sscanf(arg.c_str(), "%lg", &t0);
 | 
|---|
 | 177 |     archParam.acq.tBlock0 = t0;
 | 
|---|
 | 178 |   } else if (key == "#UTCORIGIN") {
 | 
|---|
 | 179 |     double t0;
 | 
|---|
 | 180 |     sscanf(arg.c_str(), "%lg", &t0);
 | 
|---|
 | 181 |     archParam.acq.utcOrigin = t0;
 | 
|---|
 | 182 |   } else if (key == "#PERECH") {
 | 
|---|
 | 183 |     double t0;
 | 
|---|
 | 184 |     sscanf(arg.c_str(), "%lg", &t0);
 | 
|---|
 | 185 |     archParam.acq.perEch = t0;
 | 
|---|
 | 186 |   } else if (key == "#ASIGPS") {
 | 
|---|
 | 187 |     ASIGPS* gps = new ASIGPS(arg);
 | 
|---|
 | 188 |     TOIManager::registerProducer(new TOIAuxGPSProducer(gps));
 | 
|---|
 | 189 |     //    gps->FitsDump("GPSDump.fits");
 | 
|---|
 | 190 |   } else if (key == "#INCLUDE") {
 | 
|---|
 | 191 |     ifstream f(arg.c_str());
 | 
|---|
 | 192 |     readReq(f);
 | 
|---|
 | 193 |   } else {
 | 
|---|
| [310] | 194 |     return false;
 | 
|---|
 | 195 |   }
 | 
|---|
| [426] | 196 |   return true;
 | 
|---|
 | 197 | }
 | 
|---|
| [350] | 198 | 
 | 
|---|
| [534] | 199 | 
 | 
|---|
 | 200 | void TOIIter::defaultInclude() {
 | 
|---|
 | 201 |   incDone = true;
 | 
|---|
| [625] | 202 |   processRequest("#REQVERSION V_231199");
 | 
|---|
| [534] | 203 |   processRequest("#MJD0 1376.8358818");
 | 
|---|
 | 204 |   processRequest("#PERECH 0.005836818076");
 | 
|---|
 | 205 |   processRequest("#UTCORIGIN 1376.5");
 | 
|---|
 | 206 |   processRequest("#ASIGPS ASI_GPS_archeops1999.ascii");
 | 
|---|
| [612] | 207 |   processRequest("#COMMENT Archtoi V3 -- novembre 1999 -- Eric Aubourg CEA/DAPNIA");
 | 
|---|
| [625] | 208 |   processRequest("#COMMENT **** WARNING ****");
 | 
|---|
 | 209 |   processRequest("#COMMENT SST attitude reconstruction should be ok where provided");
 | 
|---|
 | 210 |   processRequest("#COMMENT     Gaps remain to be dealt with");
 | 
|---|
 | 211 |   processRequest("#COMMENT Focal plane geometry is theoric");
 | 
|---|
 | 212 |   processRequest("#COMMENT Bolo 1 aligned with SST using Jupiter (ONE crossing)");
 | 
|---|
 | 213 |   processRequest("#COMMENT => statistical error on pendulation at that instant");
 | 
|---|
 | 214 |   processRequest("#COMMENT    might induce systematic error on bolo 1 attitude");
 | 
|---|
 | 215 |   processRequest("#COMMENT gyros calibrated with galactic crossings only");
 | 
|---|
 | 216 |   processRequest("#COMMENT    algorithm = integral of gyro = delta Az");
 | 
|---|
 | 217 |   processRequest("#COMMENT    Warning : slope found on z gyro applied to x and y");
 | 
|---|
 | 218 |   processRequest("#COMMENT    offsets found on x and y applied (average) to z");
 | 
|---|
| [350] | 219 | }
 | 
|---|
 | 220 | 
 | 
|---|
| [534] | 221 | #ifdef __MWERKS__
 | 
|---|
 | 222 | #pragma mark -
 | 
|---|
 | 223 | #endif
 | 
|---|
| [310] | 224 | 
 | 
|---|
| [534] | 225 | void TOIIter::init() {
 | 
|---|
 | 226 |   if (initDone) return;
 | 
|---|
 | 227 |   initDone = true;
 | 
|---|
 | 228 |  
 | 
|---|
 | 229 |   if (utcStart > 0) {
 | 
|---|
 | 230 |     double t = (utcStart/24.) + archParam.acq.utcOrigin;
 | 
|---|
 | 231 |     if (t > mjdStart) mjdStart=t;
 | 
|---|
| [310] | 232 |   }
 | 
|---|
| [534] | 233 |   if (utcEnd > 0) {
 | 
|---|
 | 234 |     double t = (utcEnd/24.) + archParam.acq.utcOrigin;
 | 
|---|
 | 235 |     if (t < mjdEnd) mjdEnd=t;
 | 
|---|
| [310] | 236 |   }
 | 
|---|
 | 237 | 
 | 
|---|
| [619] | 238 |   // Let's add some time on each side, 90 seconds should be ok, at least
 | 
|---|
| [612] | 239 |   // for Trapani
 | 
|---|
 | 240 |   
 | 
|---|
| [619] | 241 |   double delT = 90. / 86400;
 | 
|---|
 | 242 |   long   delSN = long(90. / archParam.acq.perEch);
 | 
|---|
| [400] | 243 | 
 | 
|---|
| [612] | 244 |   fset.setMJDRange(mjdStart-delT, mjdEnd+delT);
 | 
|---|
 | 245 |   fset.setSNumRange(sStart-delSN, sEnd+delSN);
 | 
|---|
 | 246 | 
 | 
|---|
| [534] | 247 |   fset.init();
 | 
|---|
 | 248 |   //curSample = fset.getSampleIndex();
 | 
|---|
| [315] | 249 | }
 | 
|---|
| [342] | 250 | 
 | 
|---|
 | 251 | bool TOIIter::isTrig(int column) {
 | 
|---|
| [534] | 252 |   return (request[column].third & triggering) != 0;
 | 
|---|
| [342] | 253 | }
 | 
|---|
| [310] | 254 |  
 | 
|---|
| [534] | 255 | TOI TOIIter::getKind(int column) {
 | 
|---|
 | 256 |   return request[column].first;
 | 
|---|
| [315] | 257 | }
 | 
|---|
| [534] | 258 | 
 | 
|---|
 | 259 | long TOIIter::getSampleNum() {
 | 
|---|
 | 260 |   return curSample;
 | 
|---|
| [315] | 261 | }
 | 
|---|
 | 262 | 
 | 
|---|
| [534] | 263 | bool TOIIter::next() {
 | 
|---|
 | 264 |   if (!initDone) init();
 | 
|---|
 | 265 |   for (int ii=0; ii<underSample; ii++)
 | 
|---|
 | 266 |     if (!next1()) return false;
 | 
|---|
 | 267 |   
 | 
|---|
 | 268 |   return true;
 | 
|---|
| [315] | 269 | }
 | 
|---|
 | 270 | 
 | 
|---|
| [534] | 271 | bool TOIIter::next1() {
 | 
|---|
 | 272 | // On tente de produire curSample+1 pour toutes les toi
 | 
|---|
 | 273 | // Eventuellement en avancant sur le fichier...
 | 
|---|
 | 274 | // Puis on regarde si une TOI triggering a eu une nouvelle
 | 
|---|
 | 275 | // valeur.
 | 
|---|
 | 276 | // Si on a epuise les fichiers de donnees, on s'arrete des qu'aucune
 | 
|---|
 | 277 | // TOI n'a de valeurs apres curSample...
 | 
|---|
| [612] | 278 |   if (curSample <= 0) curSample = sStart-1;  
 | 
|---|
 | 279 |   if (curSample <= 0) {
 | 
|---|
| [635] | 280 |     long sn = (long)(archParam.acq.MJD2SN(mjdStart) - 1);
 | 
|---|
| [612] | 281 |     if (sn > curSample) curSample = sn;
 | 
|---|
 | 282 |   }
 | 
|---|
 | 283 |   
 | 
|---|
| [534] | 284 |   if (curSample <= 0) curSample = fset.getSampleIndex()-1;
 | 
|---|
 | 285 |   
 | 
|---|
 | 286 |   if (curSample >= sEnd || archParam.acq.SN2MJD(curSample) >= mjdEnd) return false;
 | 
|---|
 | 287 |   
 | 
|---|
| [555] | 288 |   static long lastClean = 0;
 | 
|---|
 | 289 |   if (curSample - lastClean > 100) {
 | 
|---|
 | 290 |     for (int i=0; i<request.size(); i++)
 | 
|---|
 | 291 |       request[i].second->wontNeedEarlier(request[i].first, this, curSample);
 | 
|---|
 | 292 |     lastClean = curSample;
 | 
|---|
 | 293 |   }
 | 
|---|
| [534] | 294 | 
 | 
|---|
 | 295 |   bool endFound = false;
 | 
|---|
 | 296 |   while(1) {
 | 
|---|
 | 297 |     curSample++;
 | 
|---|
 | 298 |     for (vector<TOIInfo>::iterator i = request.begin(); i != request.end(); i++) {
 | 
|---|
 | 299 |       while ((*i).second->canGetValueLater(curSample, (*i).first)) {
 | 
|---|
 | 300 |         if (! fset.next()) {endFound = true; break;} //return false;
 | 
|---|
 | 301 |       }     
 | 
|---|
 | 302 |     }
 | 
|---|
| [614] | 303 |     if (endFound && curSample >= fset.getSampleIndex()+71) return false;
 | 
|---|
| [534] | 304 |     bool found=false;
 | 
|---|
| [612] | 305 |     //bool valuesAhead = false;
 | 
|---|
| [534] | 306 |     for (vector<TOIInfo>::iterator i = request.begin(); i != request.end(); i++) {
 | 
|---|
 | 307 |       if (((*i).third & triggering) == 0) continue;
 | 
|---|
 | 308 |       if ((*i).second->canGetValue(curSample, (*i).first)) {found=true;break;}
 | 
|---|
| [612] | 309 |       //if ((*i).second->lastSampleNum((*i).first)>curSample) valuesAhead=true;
 | 
|---|
| [534] | 310 |     }
 | 
|---|
 | 311 |     if (found) break;
 | 
|---|
 | 312 |   }
 | 
|---|
 | 313 |   return true;
 | 
|---|
| [315] | 314 | }
 | 
|---|
 | 315 | 
 | 
|---|
| [534] | 316 | int TOIIter::getColTOI(TOI const& toi) {
 | 
|---|
 | 317 |   for (int i=0; i<request.size(); i++)
 | 
|---|
 | 318 |     if (request[i].first == toi) return i;
 | 
|---|
 | 319 |   throw ArchExc("getColTOI : no such TOI " + toi.name);
 | 
|---|
| [315] | 320 | }
 | 
|---|
 | 321 | 
 | 
|---|
| [534] | 322 | bool TOIIter::canGetValue(int column) {
 | 
|---|
 | 323 |    TOIInfo& info = request[column];
 | 
|---|
 | 324 |    return(info.second->canGetValue(curSample, info.first));
 | 
|---|
| [315] | 325 | }
 | 
|---|
| [426] | 326 | 
 | 
|---|
| [534] | 327 | double TOIIter::getValue(int column) {
 | 
|---|
 | 328 |    TOIInfo& info = request[column];
 | 
|---|
 | 329 |    return(info.second->getValue(curSample, info.first));
 | 
|---|
| [315] | 330 | }
 | 
|---|
| [358] | 331 | 
 | 
|---|
| [534] | 332 | bool TOIIter::canGetValue(TOI const& toi) {
 | 
|---|
 | 333 |   return canGetValue(getColTOI(toi));
 | 
|---|
| [358] | 334 | }
 | 
|---|
| [315] | 335 | 
 | 
|---|
| [534] | 336 | double TOIIter::getValue(TOI const& toi) {
 | 
|---|
 | 337 |   return getValue(getColTOI(toi));
 | 
|---|
| [342] | 338 | }
 | 
|---|
 | 339 | 
 | 
|---|