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

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

nouvelles toi

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