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

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

gyors

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