#include "toiiter.h" #include "toiinterpolator.h" #include // Format bloc GPS // $GPGGA,hhmmss.ss,ddmm.mmmm,n,dddmm.mmmm,e,q,ss,y.y,a.a,z, TOIIter::TOIIter() { // Toutes les valeurs initialisees par defaut. Le TOISvr les positionnera, // puis lancera l'initialisation file = NULL; directory = ""; fileName = ""; tStart = -9.e99; tEnd = -9.e99; tBlock0 = -1; rawIter = NULL; interp = NULL; lastSample = -1; maxLookAhead = 1000; } TOIIter::TOIIter(TOIIter const& x) { directory = x.directory; fileName = x.fileName; files = x.files; curFile = x.curFile; imes = x.imes; tStart = x.tStart; tEnd = x.tEnd; tBlock0 = x.tBlock0; trigMask = x.trigMask; infos = x.infos; if (x.file) file = new ArcheopsFile(*x.file); else file = NULL; if (x.rawIter) { rawIter = new TOIIter(*x.rawIter); interp = new TOIInterpolator[infos.size()]; for (int i=0; id_name); } closedir(dir); curFile = files.begin(); file = new ArcheopsFile((*curFile).c_str()); } if (!file->lastParam()) file->nextBlock(block_param_mask); if (!file->lastReglage()) file->nextBlock(block_reglage_mask); // On cherche un bloc GPS pour avoir la correspondance timestamp/UTC. // Pour le moment, on se fonde sur le premier bloc GPS. On pourra faire // mieux en prenant le min de tous les delta_T. tBlock0 = file->getStartMJD(); file->pushMark(); if (file->lastGPS() || file->nextBlock(block_gps_mask)) { // le temps du bloc courant, en secondes double dt = file->blockNum() * file->perBlock(); tBlock0 = file->getGPSMJD() - dt/86400.; } else { // pas de bloc GPS... tBlock0 = file->getStartMJD(); } file->popMark(); bool hasInterp = false; trigMask = 0; for (vector::iterator i = infos.begin(); i != infos.end(); i++) { if ((*i).interpolated) hasInterp = true; if ((*i).triggering) { switch ((*i).kind) { case boloTens: case boloRaw: trigMask |= block_bolo_mask; break; case longitude: case latitude: trigMask |= block_gps_mask; break; case azimut: file->needSSTProcessMask(SSTHandler::findPeriod); trigMask |= block_sst_mask; break; case sstStarZ: case sstStarF: file->needSSTProcessMask(SSTHandler::findStars); trigMask |= block_sst_mask; break; case sstSignal: file->needSSTProcessMask(SSTHandler::rmveOffset); trigMask |= block_sst_mask; break; case alphaAxis: case deltaAxis: case alphaBolo: case deltaBolo: file->needSSTProcessMask(SSTHandler::findAxis); trigMask |= block_sst_mask; break; } } } if (trigMask & (block_bolo_mask | block_sst_mask)) { imes = 9999; } else { imes = 0; } if (hasInterp) { rawIter = new TOIIter(*this); interp = new TOIInterpolator[infos.size()]; for (int i=0; iinfos[i].interpolated = false; } delete file; file = NULL; // on ne travaille plus sur le fichier directement... } } bool TOIIter::NextFile() { if (rawIter) return rawIter->NextFile(); if (directory == "") { return false; } else { if (curFile == files.end()) return false; curFile++; if (curFile == files.end()) return false; ArcheopsFile* newfile = new ArcheopsFile((*curFile).c_str()); newfile->grabLastBlocs(*file); delete file; file = newfile; return true; } } bool TOIIter::Next() { if (rawIter) { // Delegation pour interpolation // Trouve prochain sample disponible for (int k=0; k<2; k++) { long smp = 2147483647L; for (int i=0; i 0 && ss < smp) smp=ss; } if (smp != 2147483647L) { lastSample = smp; break; } if (!fetchAhead()) // tout le monde etait en bout de course, return false; // on lit un echantillon, ca suffit, d'ou le k<2 } // Verifie que tous les interpolateurs ont assez de donnees pour // trouver la valeur correspondante for (int i=0; igetSampleIndex() - lastSample < maxLookAhead) if (!fetchAhead()) return false; } // On est pret... return true; } // trigger sur info indexee dans bloc bolo ou bloc sst ? if (trigMask & (block_bolo_mask | block_sst_mask)) { imes++; if (imes < file->nEchBlock()) return true; imes = 0; } // soit pas d'info indexee, soit fin bloc courant... while (1) { if (file->nextBlock(trigMask)) { while (file->sameBlockNumAhead()) { // tant que meme numero de bloc, on lit if (!file->nextBlock()) { // fin de fichier ? if (NextFile()) file->nextBlock(); else break; } } return true; } if (!NextFile()) return false; } } /* double TOIIter::getTime() { // MJD // le temps du bloc courant, en secondes double dt = file->blockNum() * file->perBlock(); return tBlock0 + dt/86400. + imes*file->perEchant()/86400.; } */ bool TOIIter::canGetValue(int column) { if (column < 0 || column >= infos.size()) return false; if (rawIter) { return interp[column].canGet(lastSample); } TOIKind kind = infos[column].kind; int index = infos[column].index; switch (kind) { case sampleNum: case internalTime: case utc: return true; case boloTens: case boloRaw: return file->lastBolo() != NULL; case sstSignal: return file->lastSST() != NULL; case longitude: case latitude: return file->lastGPS() != NULL; case azimut: case alphaAxis: case deltaAxis: return (file->lastGPS() != NULL && file->lastSST() != NULL); } return false; } double TOIIter::getValue(int column) { if (column < 0 || column >= infos.size()) return -1; if (rawIter) { if (infos[column].interpolated) return interp[column].getIValue(lastSample); else return interp[column].getEValue(lastSample); } TOIKind kind = infos[column].kind; int index = infos[column].index; switch (kind) { case sampleNum: return file->blockNum() * file->nEchBlock() + imes; case internalTime: return (file->blockNum() * file->nEchBlock() + imes) * file->perEchant(); case utc: /* printf("utc: %d %d %g %g %g\n",file->blockNum(), (file->blockNum() * file->nEchBlock() + imes), file->perEchant(), (file->blockNum() * file->nEchBlock() + imes) * file->perEchant()/86400., tBlock0+(file->blockNum() * file->nEchBlock() + imes) * file->perEchant()/86400.); */ return tBlock0+(file->blockNum() * file->nEchBlock() + imes) * file->perEchant()/86400.; case boloTens: return file->getMuVBolo(index, imes); case boloRaw: return file->getRawBolo(index, imes); case sstSignal: return file->getSSTSignal(index, imes); case longitude: return file->getGPSLong(); // $CHECK$ TBD gerer interpolation (dans file) case latitude: return file->getGPSLat(); // $CHECK$ TBD gerer interpolation (dans file) case azimut: return file->getAzimut(imes); case alphaAxis: return file->getAlpha(imes); case deltaAxis: return file->getDelta(imes); } return -1; } bool TOIIter::newValue(int column) { if (column < 0 || column >= infos.size()) return false; TOIKind kind = infos[column].kind; switch (kind) { case sampleNum: case internalTime: case utc: return true; case boloTens: return file->blockNum() == file->getBoloBlockNum(); case boloRaw: return file->blockNum() == file->getBoloBlockNum(); case sstSignal: return file->blockNum() == file->getSSTBlockNum(); case longitude: return file->blockNum() == file->getGPSBlockNum() && imes==0; case latitude: return file->blockNum() == file->getGPSBlockNum() && imes==0; case azimut: return true; // $CHECK$ with SSTHandler case alphaAxis: return true; // $CHECK$ with SSTHandler case deltaAxis: return true; // $CHECK$ with SSTHandler } return false; } bool TOIIter::extendValue(int column) { return (!infos[column].interpolated && !newValue(column)); } bool TOIIter::interpValue(int column) { return (infos[column].interpolated && !newValue(column)); } TOIKind TOIIter::getKind(int column) { if (column < 0 || column >= infos.size()) return (TOIKind)-1; return infos[column].kind; } int TOIIter::getIndex(int column) { if (column < 0 || column >= infos.size()) return (TOIKind)-1; return infos[column].index; } int TOIIter::getColTOI(TOIKind kind, int index) { for (int i=0; iblockNum() * file->nEchBlock() + imes; } bool TOIIter::fetchAhead() { // Seulement si delegation if (!rawIter) return false; if (!rawIter->Next()) return false; long sample = rawIter->getSampleIndex(); for (int i=0; icanGetValue(i) && rawIter->newValue(i)) interp[i].enterValue(rawIter->getValue(i), sample); } return true; }