source: Sophya/trunk/Poubelle/archTOI.old/toiiter.cc@ 358

Last change on this file since 358 was 358, checked in by ansari, 26 years ago

auxilliary GPS

File size: 16.8 KB
RevLine 
[350]1// toiiter.cc
2// Eric Aubourg CEA/DAPNIA/SPP juillet 1999
3
4
[310]5#include "toiiter.h"
[315]6#include "toiinterpolator.h"
[310]7#include <dirent.h>
[342]8#include <iostream.h>
[310]9
10// Format bloc GPS
11// $GPGGA,hhmmss.ss,ddmm.mmmm,n,dddmm.mmmm,e,q,ss,y.y,a.a,z,
12
13TOIIter::TOIIter() {
14 // Toutes les valeurs initialisees par defaut. Le TOISvr les positionnera,
15 // puis lancera l'initialisation
16
17 file = NULL;
18 directory = "";
19
[342]20 files.clear();
21
22 isOnBoardRecorder = false;
23
24 imes=0;
25
[310]26 tStart = -9.e99;
[342]27 tEnd = 9.e99;
[310]28
29 tBlock0 = -1;
[342]30 perEch = -1;
[350]31 // Values for Trapani 99 = default values
32 tBlock0 = 1376.8358818;
33 perEch = 0.005836818076;
[315]34
[342]35 trigMask = 0;
[315]36 rawIter = NULL;
37 interp = NULL;
38 lastSample = -1;
[342]39 maxLookAhead = 10000;
[358]40
41 auxGPS = NULL;
[310]42
43}
44
45TOIIter::TOIIter(TOIIter const& x) {
46 directory = x.directory;
47 files = x.files;
[342]48 // curFile = x.curFile; // $CHECK$ DANGER !!
49 curFile = files.find(*(x.curFile));
50 isOnBoardRecorder = x.isOnBoardRecorder;
[310]51 imes = x.imes;
52 tStart = x.tStart;
53 tEnd = x.tEnd;
54 tBlock0 = x.tBlock0;
[342]55 perEch = x.perEch;
[310]56 trigMask = x.trigMask;
57 infos = x.infos;
58
[315]59 if (x.file)
60 file = new ArcheopsFile(*x.file);
61 else
62 file = NULL;
63
64 if (x.rawIter) {
65 rawIter = new TOIIter(*x.rawIter);
66 interp = new TOIInterpolator[infos.size()];
67 for (int i=0; i<infos.size(); i++)
68 interp[i] = x.interp[i];
69 } else {
70 rawIter = NULL;
71 interp = NULL;
72 }
73
74 lastSample = x.lastSample;
75 maxLookAhead = x.maxLookAhead;
[358]76
77 auxGPS = x.auxGPS;
78 if (auxGPS) auxGPS = auxGPS->clone();
[310]79}
80
81TOIIter::~TOIIter() {
82 delete file;
[315]83 delete rawIter;
84 delete[] interp;
[358]85 delete auxGPS;
[310]86}
87
[342]88#ifdef __MWERKS__
89#define filesep ':'
90#else
91#define filesep '/'
92#endif
93
[310]94void TOIIter::Init() {
[350]95 // On a soit un repertoire, soit une liste de fichiers....
[310]96 if (directory == "") {
[350]97 if (files.empty()) { // Ni repertoire, ni fichiers
98 cerr << "toiiter : pas de repertoire, pas de fichiers" << endl;
99 exit(-1);
[342]100 } else {
[350]101 // On a deja une liste de fichiers
[342]102 }
103 } else { // On a un repertoire a explorer
104 // On cherche soit les fichiers dans le repertoire donne, soit des fichiers
105 // dans un sous-repertoire "arch-YY_MM_DD". Les fichiers ont un nom en
106 // "hYY_MM_DD-hh_mm_ss".
107 // Pour l'enregistreur de vol, les fichiers ont un nom en ARKxxxxxx.DAT
108 if (directory[directory.length()-1] != filesep)
109 directory += filesep;
[310]110 DIR* dir = opendir(directory.c_str());
111 struct dirent* ent;
112 while ((ent = readdir(dir)) != NULL) {
[342]113 // si c'est un repertoire, avec un nom de jour, il faut l'explorer...
114 if (!strncmp(ent->d_name, "arch-", 5)) {
115 double mjd = ArcheopsFile::decodeMJD(ent->d_name+5) - 2./24.; // ENTIER + .5 en temps local!
116 if (mjd >= tStart - 1. && mjd <= tEnd) {
117 string direc2 = directory + ent->d_name + filesep;
118 DIR* dir2 = opendir(direc2.c_str());
119 struct dirent* ent2;
120 while ((ent2 = readdir(dir2)) != NULL) {
121 if (*ent2->d_name == 'h') {
122 double mjd2 = ArcheopsFile::decodeMJD(ent->d_name+1) - 2./24.;
123 if (mjd2 >= tStart - 1./24. && mjd2 <= tEnd) {
124 files.insert(direc2 + ent2->d_name);
125 }
126 }
127 }
128 }
129 } else {
130 if (!isOnBoardRecorder && *ent->d_name == 'h') {
131 double mjd = ArcheopsFile::decodeMJD(ent->d_name+1) - 2./24.; // $CHECK$ UTCOffset
132 if (mjd >= tStart - 1./24. && mjd <= tEnd) {
133 files.insert(directory + ent->d_name);
134 }
135 } else if (isOnBoardRecorder) {
[350]136 if (strncmp(ent->d_name, "ARK", 3) && strncmp(ent->d_name, "ark", 3)) continue;
[342]137 char * sfx = ent->d_name + strlen(ent->d_name) - 4;
[350]138 if (strcmp(sfx, ".DAT") && strcmp(sfx, ".dat")) continue;
[342]139 files.insert(directory + ent->d_name);
140 }
141 }
[310]142 }
143 closedir(dir);
144 }
[350]145
146 ScanFiles();
147
148 curFile = files.begin();
149 file = new ArcheopsFile((*curFile).c_str());
150 cout << "opening file " << (*curFile).c_str() << endl;
[310]151
[342]152 // On avance jusqu'a avoir au moins un bloc param et un bloc reglage,
153 // car on ne peut rien faire sans...
154 // Si on a des donnees de l'enregistreur de vol, pas de bloc param, et
155 // on en simule un
[350]156 double oldTStart = tStart;
157 tStart = -9.e99; // pour init, on accepte des blocs avant tstart....
158
[342]159 if (!file->lastParam()) {
160 if (isOnBoardRecorder) {
161 extern param_bolo parametr;
162 block_type_param block;
163 block.param = parametr;
164 valide_block((block_type_modele*)&block, block_param, 0);
165 file->forceBlock((block_type_modele*)&block);
166 } else {
167 file->nextBlock(block_param_mask);
168 }
169 }
[310]170 if (!file->lastReglage()) file->nextBlock(block_reglage_mask);
171
172 // On cherche un bloc GPS pour avoir la correspondance timestamp/UTC.
173 // Pour le moment, on se fonde sur le premier bloc GPS. On pourra faire
[342]174 // mieux en prenant le min de tous les delta_T, a condition d'avoir un
175 // peu plus de details sur la facon dont le GPS est lu.
[310]176
[342]177 if (tBlock0 < 0) {
178 tBlock0 = file->getStartMJD();
[315]179
[342]180 file->pushMark();
181 if (file->lastGPS() || file->nextBlock(block_gps_mask)) {
182 // le temps du bloc courant, en secondes
183 double dt = file->blockNum() * file->perBlock();
184 tBlock0 = file->getGPSMJD() - dt/86400.;
185 } else { // pas de bloc GPS...
186 tBlock0 = file->getStartMJD();
187 }
188 file->popMark();
[310]189 }
[350]190 tStart = oldTStart; // on restaure
[342]191
192 if (perEch < 0)
193 perEch = file->perEchant();
[315]194
195 bool hasInterp = false;
[310]196
197 trigMask = 0;
198 for (vector<info>::iterator i = infos.begin(); i != infos.end(); i++) {
[315]199 if ((*i).interpolated) hasInterp = true;
[310]200 if ((*i).triggering) {
201 switch ((*i).kind) {
202 case boloTens:
203 case boloRaw:
204 trigMask |= block_bolo_mask;
205 break;
[342]206 case gpsTime:
[310]207 case longitude:
208 case latitude:
[342]209 case altitude:
[310]210 trigMask |= block_gps_mask;
211 break;
212 case azimut:
[315]213 file->needSSTProcessMask(SSTHandler::findPeriod);
[310]214 trigMask |= block_sst_mask;
215 break;
[315]216 case sstStarZ:
217 case sstStarF:
218 file->needSSTProcessMask(SSTHandler::findStars);
[310]219 trigMask |= block_sst_mask;
220 break;
[350]221 case sstDiode:
[315]222 file->needSSTProcessMask(SSTHandler::rmveOffset);
223 trigMask |= block_sst_mask;
224 break;
[350]225 case sstChannel:
[342]226 trigMask |= block_sst_mask;
227 break;
228 case gyroRaw:
229 trigMask |= block_gyro_mask;
230 break;
[315]231 case alphaAxis:
232 case deltaAxis:
233 case alphaBolo:
234 case deltaBolo:
235 file->needSSTProcessMask(SSTHandler::findAxis);
236 trigMask |= block_sst_mask;
237 break;
[310]238 }
239 }
240 }
241
242 if (trigMask & (block_bolo_mask | block_sst_mask)) {
243 imes = 9999;
244 } else {
245 imes = 0;
246 }
[315]247
248 if (hasInterp) {
249 rawIter = new TOIIter(*this);
250 interp = new TOIInterpolator[infos.size()];
251 for (int i=0; i<infos.size(); i++) {
252 rawIter->infos[i].interpolated = false;
253 }
254 delete file; file = NULL; // on ne travaille plus sur le fichier directement...
255 }
[310]256}
257
[350]258void TOIIter::ScanFiles() {
259 file1stSamp.clear();
260 cout << "Scanning all files" << endl;
261 // Petite astuce pour les STL non conformes comme celles de digital
262 // qui ne supportent pas files.erase(i) suivi de i++....
263 set<string> copy = files;
264 for (set<string>::iterator i = copy.begin(); i != copy.end(); i++) {
265 ArcheopsFile fich((*i).c_str());
266 if (fich.nextBlock()) {
267 file1stSamp[*i] = fich.blockNum()*72; // premier numsample
268 cout << "File " << *i << " 1st sample = " << fich.blockNum()*72 << endl;
269 } else {
270 cout << "File " << *i << " unrecoverable, skipping" << endl;
271 files.erase(*i);
272 }
273 }
274 cout << "Scan done" << endl;
275
276 // Et maintenant, on ne garde que ceux qui tombent dans l'intervalle...
277 copy = files;
278 string prev="";
279 for (set<string>::iterator i = copy.begin(); i != copy.end(); i++) {
280 double smp = file1stSamp[*i];
281 double t = tBlock0 + smp * perEch/86400.;
282 if (t>tEnd) { // premier echantillon apres tEnd
283 files.erase(*i);
284 prev = "";
285 continue;
286 }
287 if (t<tStart) { // premier echantillon avant tStart -> on vire le precedent si existe
288 if (prev != "") {
289 files.erase(prev);
290 }
291 }
292 prev = *i;
293 }
294}
295
[310]296bool TOIIter::NextFile() {
[315]297 if (rawIter)
298 return rawIter->NextFile();
299
[342]300 if (files.empty()) {
[310]301 return false;
302 } else {
303 if (curFile == files.end()) return false;
304 curFile++;
305 if (curFile == files.end()) return false;
[342]306 cout << "opening file " << (*curFile).c_str() << endl;
[310]307 ArcheopsFile* newfile = new ArcheopsFile((*curFile).c_str());
308 newfile->grabLastBlocs(*file);
309 delete file;
310 file = newfile;
311 return true;
312 }
313}
314
[350]315
[310]316bool TOIIter::Next() {
[350]317 while (1) {
318 if (!NextSample()) return false; // end of files
[358]319 double t = getMJD();
[350]320 if (t < tStart) continue;
321 if (t > tEnd) return false;
322 return true;
323 }
324}
325
326bool TOIIter::NextSample() {
[315]327 if (rawIter) { // Delegation pour interpolation
328 // Trouve prochain sample disponible
329 for (int k=0; k<2; k++) {
330 long smp = 2147483647L;
331 for (int i=0; i<infos.size(); i++) {
332 long ss = interp[i].nextSample(lastSample+1);
333 if (ss > 0 && ss < smp) smp=ss;
334 }
335 if (smp != 2147483647L) {
336 lastSample = smp;
337 break;
338 }
339 if (!fetchAhead()) // tout le monde etait en bout de course,
340 return false; // on lit un echantillon, ca suffit, d'ou le k<2
341 }
342 // Verifie que tous les interpolateurs ont assez de donnees pour
343 // trouver la valeur correspondante
344 for (int i=0; i<infos.size(); i++) {
345 //rif (infos[i].interpolated)
346 while (interp[i].needMoreDataFor(lastSample) &&
347 rawIter->getSampleIndex() - lastSample < maxLookAhead)
348 if (!fetchAhead()) return false;
349 }
350
351 // On est pret...
352 return true;
353 }
[310]354
355 // trigger sur info indexee dans bloc bolo ou bloc sst ?
356 if (trigMask & (block_bolo_mask | block_sst_mask)) {
357 imes++;
358 if (imes < file->nEchBlock()) return true;
359 imes = 0;
360 }
361
362 // soit pas d'info indexee, soit fin bloc courant...
[315]363 while (1) {
364 if (file->nextBlock(trigMask)) {
365 while (file->sameBlockNumAhead()) { // tant que meme numero de bloc, on lit
366 if (!file->nextBlock()) { // fin de fichier ?
367 if (NextFile()) file->nextBlock();
368 else break;
369 }
370 }
371 return true;
372 }
373 if (!NextFile()) return false;
[310]374 }
375}
376
[315]377/* double TOIIter::getTime() { // MJD
[310]378 // le temps du bloc courant, en secondes
379 double dt = file->blockNum() * file->perBlock();
380 return tBlock0 + dt/86400. + imes*file->perEchant()/86400.;
381 }
[315]382 */
[310]383
[315]384bool TOIIter::canGetValue(int column) {
385 if (column < 0 || column >= infos.size()) return false;
[358]386 TOIKind kind = infos[column].kind;
387 if (auxGPS &&
388 (kind == longitude || kind == latitude || kind == altitude)) {
389 double dummy;
390 return auxGPS->getLocation(getMJD(), dummy, dummy, dummy) == 0;
391 }
[315]392 if (rawIter) {
393 return interp[column].canGet(lastSample);
394 }
395 int index = infos[column].index;
396 switch (kind) {
397 case sampleNum:
398 case internalTime:
[350]399 case mjd:
[315]400 return true;
401 case boloTens:
[342]402 if (imes==0 && file->llastBolo()==NULL) return false;
403 return file->lastBolo() != NULL;
[315]404 case boloRaw:
405 return file->lastBolo() != NULL;
[350]406 case sstDiode:
407 case sstChannel:
[315]408 return file->lastSST() != NULL;
[342]409 case sstStarZ:
410 case sstStarF:
411 return (file->lastSST() != NULL) && (file->getSSTStarZ(index, imes) >= 0);
412 case gyroRaw:
413 return (file->lastGyro() != NULL);
414 case gpsTime:
415 return file->hasGPSTime();
[315]416 case longitude:
417 case latitude:
[342]418 return file->hasGPSPos();
419 case altitude:
420 return file->hasGPSAlt();
[315]421 case azimut:
422 case alphaAxis:
423 case deltaAxis:
424 return (file->lastGPS() != NULL && file->lastSST() != NULL);
425 }
426 return false;
427}
428
429double TOIIter::getValue(int column) {
[310]430 if (column < 0 || column >= infos.size()) return -1;
[358]431 TOIKind kind = infos[column].kind;
432 if (auxGPS &&
433 (kind == longitude || kind == latitude || kind == altitude)) {
434 double lat,lon,alt;
435 if (auxGPS->getLocation(getMJD(), lat, lon, alt)) return -99999;
436 if (kind == longitude) return lon;
437 if (kind == latitude) return lat;
438 if (kind == altitude) return alt;
439 }
[315]440 if (rawIter) {
441 if (infos[column].interpolated)
442 return interp[column].getIValue(lastSample);
443 else
444 return interp[column].getEValue(lastSample);
445 }
[310]446 int index = infos[column].index;
447 switch (kind) {
[315]448 case sampleNum:
[358]449 return getSampleIndex();
[315]450 case internalTime:
[358]451 return getSampleIndex() * perEch;
[350]452 case mjd:
[358]453 return getMJD();
[310]454 case boloTens:
455 return file->getMuVBolo(index, imes);
456 case boloRaw:
457 return file->getRawBolo(index, imes);
[350]458 case sstDiode:
[315]459 return file->getSSTSignal(index, imes);
[350]460 case sstChannel:
[342]461 return file->getSSTRawSignal(index, imes);
462 case sstStarZ:
463 return file->getSSTStarZ(index, imes);
464 case sstStarF:
465 return file->getSSTStarF(index, imes);
466 case gyroRaw:
467 return file->getGyro(index, imes);
468 case gpsTime:
469 return file->getGPSUTC();
[310]470 case longitude:
[342]471 return file->getGPSLong();
[310]472 case latitude:
[342]473 return file->getGPSLat();
474 case altitude:
475 return file->getGPSAlt();
[315]476 case azimut:
[310]477 return file->getAzimut(imes);
[315]478 case alphaAxis:
[310]479 return file->getAlpha(imes);
[315]480 case deltaAxis:
[310]481 return file->getDelta(imes);
482 }
483 return -1;
[315]484}
[310]485
[315]486bool TOIIter::newValue(int column) {
[310]487 if (column < 0 || column >= infos.size()) return false;
[358]488 TOIKind kind = infos[column].kind;
489 if (auxGPS &&
490 (kind == longitude || kind == latitude || kind == altitude)) {
491 return true;
492 }
[342]493 if (rawIter) {
494 return interp[column].isNewValue(lastSample);
495 }
[310]496 switch (kind) {
[315]497 case sampleNum:
498 case internalTime:
[350]499 case mjd:
[315]500 return true;
[310]501 case boloTens:
[315]502 return file->blockNum() == file->getBoloBlockNum();
[310]503 case boloRaw:
[315]504 return file->blockNum() == file->getBoloBlockNum();
[350]505 case sstChannel:
506 case sstDiode:
[342]507 case sstStarZ:
508 case sstStarF:
[315]509 return file->blockNum() == file->getSSTBlockNum();
[342]510 case gyroRaw:
511 return file->blockNum() == file->getGyroBlockNum();
512 case gpsTime:
513 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[310]514 case longitude:
[315]515 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[310]516 case latitude:
[315]517 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[342]518 case altitude:
519 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[315]520 case azimut:
521 return true; // $CHECK$ with SSTHandler
522 case alphaAxis:
523 return true; // $CHECK$ with SSTHandler
524 case deltaAxis:
525 return true; // $CHECK$ with SSTHandler
[310]526 }
527 return false;
[315]528}
[310]529
[315]530bool TOIIter::extendValue(int column) {
531 return (!infos[column].interpolated && !newValue(column));
532}
[310]533
[315]534bool TOIIter::interpValue(int column) {
535 return (infos[column].interpolated && !newValue(column));
536}
[342]537
538bool TOIIter::isTrig(int column) {
539 if (column < 0 || column >= infos.size()) return false;
540 return infos[column].triggering;
541}
542
[310]543
[315]544TOIKind TOIIter::getKind(int column) {
[310]545 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
546 return infos[column].kind;
[315]547}
[310]548
[315]549int TOIIter::getIndex(int column) {
[310]550 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
551 return infos[column].index;
[315]552}
553
554int TOIIter::getColTOI(TOIKind kind, int index) {
555 for (int i=0; i<infos.size(); i++)
556 if (infos[i].kind == kind && infos[i].index == index)
557 return i;
558 return -1;
559}
560
561bool TOIIter::canGetTOI(TOIKind kind, int index) {
562 int col = getColTOI(kind, index);
563 if (col<0) return false;
564 return canGetValue(col);
565}
566
567double TOIIter::getTOI(TOIKind kind, int index) {
568 int col = getColTOI(kind, index);
569 if (col<0) return -9.e99;
570 return getValue(col);
571}
572
[310]573
[315]574int TOIIter::getBlockSampleIndex() {
[310]575 return imes;
[315]576}
577
578int TOIIter::getSampleIndex() {
[342]579 if (file) {
580 return file->blockNum() * file->nEchBlock() + imes;
581 } else {
582 return lastSample;
583 }
[315]584}
[358]585
586double TOIIter::getMJD() {
587 int sample = getSampleIndex();
588 return tBlock0 + sample*perEch/86400.;
589}
[315]590
591bool TOIIter::fetchAhead() { // Seulement si delegation
592 if (!rawIter) return false;
593 if (!rawIter->Next()) return false;
594 long sample = rawIter->getSampleIndex();
595 for (int i=0; i<infos.size(); i++) {
[342]596 if (rawIter->canGetValue(i) && rawIter->newValue(i)) {
[315]597 interp[i].enterValue(rawIter->getValue(i), sample);
[342]598 }
[315]599 }
600 return true;
601}
602
[342]603block_type_param* TOIIter::lastParam() {
604 if (file) return file->lastParam();
605 else return rawIter->lastParam();
606}
607
608
Note: See TracBrowser for help on using the repository browser.