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

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

findstar DY qui sort des etoiles

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