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

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

Deplacement init toiiter pour eviter 2 archeopsfiles

File size: 17.5 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 <dirent.h>
8#include <iostream.h>
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
20 files.clear();
21
22 isOnBoardRecorder = false;
23
24 imes=0;
25
26 tStart = -9.e99;
27 tEnd = 9.e99;
28
29 tBlock0 = -1;
30 perEch = -1;
31 // Values for Trapani 99 = default values
32 tBlock0 = 1376.8358818;
33 perEch = 0.005836818076;
34
35 trigMask = 0;
36 rawIter = NULL;
37 interp = NULL;
38 lastSample = -1;
39 maxLookAhead = 10000;
40
41 auxGPS = NULL;
42
43 initDone = false;
44}
45
46TOIIter::TOIIter(TOIIter const& x) {
47 directory = x.directory;
48 files = x.files;
49 // curFile = x.curFile; // $CHECK$ DANGER !!
50 curFile = files.find(*(x.curFile));
51 isOnBoardRecorder = x.isOnBoardRecorder;
52 imes = x.imes;
53 tStart = x.tStart;
54 tEnd = x.tEnd;
55 tBlock0 = x.tBlock0;
56 perEch = x.perEch;
57 trigMask = x.trigMask;
58 infos = x.infos;
59
60 if (x.file)
61 file = new ArcheopsFile(*x.file);
62 else
63 file = NULL;
64
65 if (x.rawIter) {
66 rawIter = new TOIIter(*x.rawIter);
67 interp = new TOIInterpolator[infos.size()];
68 for (int i=0; i<infos.size(); i++)
69 interp[i] = x.interp[i];
70 } else {
71 rawIter = NULL;
72 interp = NULL;
73 }
74
75 lastSample = x.lastSample;
76 maxLookAhead = x.maxLookAhead;
77
78 auxGPS = x.auxGPS;
79 if (auxGPS) auxGPS = auxGPS->clone();
80
81 initDone = x.initDone;
82}
83
84TOIIter::~TOIIter() {
85 delete file;
86 delete rawIter;
87 delete[] interp;
88 delete auxGPS;
89}
90
91#ifdef __MWERKS__
92#define filesep ':'
93#else
94#define filesep '/'
95#endif
96
97void TOIIter::Init() {
98 if (initDone) return;
99 initDone = true;
100 // On a soit un repertoire, soit une liste de fichiers....
101 if (directory == "") {
102 if (files.empty()) { // Ni repertoire, ni fichiers
103 cerr << "toiiter : pas de repertoire, pas de fichiers" << endl;
104 exit(-1);
105 } else {
106 // On a deja une liste de fichiers
107 }
108 } else { // On a un repertoire a explorer
109 // On cherche soit les fichiers dans le repertoire donne, soit des fichiers
110 // dans un sous-repertoire "arch-YY_MM_DD". Les fichiers ont un nom en
111 // "hYY_MM_DD-hh_mm_ss".
112 // Pour l'enregistreur de vol, les fichiers ont un nom en ARKxxxxxx.DAT
113 if (directory[directory.length()-1] != filesep)
114 directory += filesep;
115 DIR* dir = opendir(directory.c_str());
116 struct dirent* ent;
117 while ((ent = readdir(dir)) != NULL) {
118 // si c'est un repertoire, avec un nom de jour, il faut l'explorer...
119 if (!strncmp(ent->d_name, "arch-", 5)) {
120 double mjd = ArcheopsFile::decodeMJD(ent->d_name+5) - 2./24.; // ENTIER + .5 en temps local!
121 if (mjd >= tStart - 1. && mjd <= tEnd) {
122 string direc2 = directory + ent->d_name + filesep;
123 DIR* dir2 = opendir(direc2.c_str());
124 struct dirent* ent2;
125 while ((ent2 = readdir(dir2)) != NULL) {
126 if (*ent2->d_name == 'h') {
127 double mjd2 = ArcheopsFile::decodeMJD(ent->d_name+1) - 2./24.;
128 if (mjd2 >= tStart - 1./24. && mjd2 <= tEnd) {
129 files.insert(direc2 + ent2->d_name);
130 }
131 }
132 }
133 }
134 } else {
135 if (!isOnBoardRecorder && *ent->d_name == 'h') {
136 double mjd = ArcheopsFile::decodeMJD(ent->d_name+1) - 2./24.; // $CHECK$ UTCOffset
137 if (mjd >= tStart - 1./24. && mjd <= tEnd) {
138 files.insert(directory + ent->d_name);
139 }
140 } else if (isOnBoardRecorder) {
141 if (strncmp(ent->d_name, "ARK", 3) && strncmp(ent->d_name, "ark", 3)) continue;
142 char * sfx = ent->d_name + strlen(ent->d_name) - 4;
143 if (strcmp(sfx, ".DAT") && strcmp(sfx, ".dat")) continue;
144 files.insert(directory + ent->d_name);
145 }
146 }
147 }
148 closedir(dir);
149 }
150
151 ScanFiles();
152
153 curFile = files.begin();
154 file = new ArcheopsFile((*curFile).c_str());
155 cout << "opening file " << (*curFile).c_str() << endl;
156
157 // On avance jusqu'a avoir au moins un bloc param et un bloc reglage,
158 // car on ne peut rien faire sans...
159 // Si on a des donnees de l'enregistreur de vol, pas de bloc param, et
160 // on en simule un
161 double oldTStart = tStart;
162 tStart = -9.e99; // pour init, on accepte des blocs avant tstart....
163
164 if (!file->lastParam()) {
165 if (isOnBoardRecorder) {
166 extern param_bolo parametr;
167 block_type_param block;
168 block.param = parametr;
169 valide_block((block_type_modele*)&block, block_param, 0);
170 file->forceBlock((block_type_modele*)&block);
171 } else {
172 file->nextBlock(block_param_mask);
173 }
174 }
175 if (!file->lastReglage()) file->nextBlock(block_reglage_mask);
176
177 // On cherche un bloc GPS pour avoir la correspondance timestamp/UTC.
178 // Pour le moment, on se fonde sur le premier bloc GPS. On pourra faire
179 // mieux en prenant le min de tous les delta_T, a condition d'avoir un
180 // peu plus de details sur la facon dont le GPS est lu.
181
182 if (tBlock0 < 0) {
183 tBlock0 = file->getStartMJD();
184
185 file->pushMark();
186 if (file->lastGPS() || file->nextBlock(block_gps_mask)) {
187 // le temps du bloc courant, en secondes
188 double dt = file->blockNum() * file->perBlock();
189 tBlock0 = file->getGPSMJD() - dt/86400.;
190 } else { // pas de bloc GPS...
191 tBlock0 = file->getStartMJD();
192 }
193 file->popMark();
194 }
195 tStart = oldTStart; // on restaure
196
197 if (perEch < 0)
198 perEch = file->perEchant();
199
200 bool hasInterp = false;
201
202 trigMask = 0;
203 for (vector<info>::iterator i = infos.begin(); i != infos.end(); i++) {
204 if ((*i).interpolated) hasInterp = true;
205 if ((*i).triggering) {
206 switch ((*i).kind) {
207 case boloTens:
208 case boloRaw:
209 trigMask |= block_bolo_mask;
210 break;
211 case gpsTime:
212 case longitude:
213 case latitude:
214 case altitude:
215 trigMask |= block_gps_mask;
216 break;
217 case azimut:
218 file->needSSTProcessMask(SSTHandler::findPeriod);
219 trigMask |= block_sst_mask;
220 break;
221 case sstStarZ:
222 case sstStarF:
223 file->needSSTProcessMask(SSTHandler::findStars);
224 trigMask |= block_sst_mask;
225 break;
226 case sstDiode:
227 file->needSSTProcessMask(SSTHandler::rmveOffset);
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 = tBlock0 + smp * 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 ou bloc sst ?
362 if (trigMask & (block_bolo_mask | block_sst_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 sstStarZ:
417 case sstStarF:
418 return (file->lastSST() != NULL) && (file->getSSTStarZ(index, imes) >= 0);
419 case gyroRaw:
420 return (file->lastGyro() != NULL);
421 case gpsTime:
422 return file->hasGPSTime();
423 case longitude:
424 case latitude:
425 return file->hasGPSPos();
426 case altitude:
427 return file->hasGPSAlt();
428 case tsid:
429 return file->hasGPSPos();
430 case azimut:
431 case alphaAxis:
432 case deltaAxis:
433 return false;
434 //return (file->lastGPS() != NULL && file->lastSST() != NULL);
435 case alphaSst:
436 case deltaSst:
437 case alphaBolo:
438 case deltaBolo:
439 return false;
440
441 case boloTemp:
442 return false;
443 }
444 return false;
445}
446
447double TOIIter::getValue(int column) {
448 if (!initDone) Init();
449 if (column < 0 || column >= infos.size()) return -1;
450 TOIKind kind = infos[column].kind;
451 if (auxGPS &&
452 (kind == longitude || kind == latitude || kind == altitude || kind == tsid)) {
453 double lat,lon,alt;
454 if (auxGPS->getLocation(getMJD(), lat, lon, alt)) return -99999;
455 if (kind == longitude) return lon;
456 if (kind == latitude) return lat;
457 if (kind == altitude) return alt;
458 if (kind == tsid) {
459 tSid.setLongitude(lon);
460 return tSid.getLST(getMJD());
461 }
462 }
463 if (rawIter) {
464 if (infos[column].interpolated)
465 return interp[column].getIValue(lastSample);
466 else
467 return interp[column].getEValue(lastSample);
468 }
469 int index = infos[column].index;
470 switch (kind) {
471 case sampleNum:
472 return getSampleIndex();
473 case internalTime:
474 return getSampleIndex() * perEch;
475 case mjd:
476 return getMJD();
477 case boloTens:
478 return file->getMuVBolo(index, imes);
479 case boloRaw:
480 return file->getRawBolo(index, imes);
481 case sstDiode:
482 return file->getSSTSignal(index, imes);
483 case sstChannel:
484 return file->getSSTRawSignal(index, imes);
485 case sstStarZ:
486 return file->getSSTStarZ(index, imes);
487 case sstStarF:
488 return file->getSSTStarF(index, imes);
489 case gyroRaw:
490 return file->getGyro(index, imes);
491 case gpsTime:
492 return file->getGPSUTC();
493 case longitude:
494 return file->getGPSLong();
495 case latitude:
496 return file->getGPSLat();
497 case altitude:
498 return file->getGPSAlt();
499 case tsid:
500 tSid.setLongitude(file->getGPSLong());
501 return tSid.getLST(getMJD());
502 case azimut:
503 return file->getAzimut(imes);
504 case alphaAxis:
505 return file->getAlpha(imes);
506 case deltaAxis:
507 return file->getDelta(imes);
508 }
509 return -1;
510}
511
512bool TOIIter::newValue(int column) {
513 if (!initDone) Init();
514 if (column < 0 || column >= infos.size()) return false;
515 TOIKind kind = infos[column].kind;
516 if (auxGPS &&
517 (kind == longitude || kind == latitude || kind == altitude)) {
518 return true;
519 }
520 if (rawIter) {
521 return interp[column].isNewValue(lastSample);
522 }
523 switch (kind) {
524 case sampleNum:
525 case internalTime:
526 case mjd:
527 case tsid:
528 return true;
529 case boloTens:
530 return file->blockNum() == file->getBoloBlockNum();
531 case boloRaw:
532 return file->blockNum() == file->getBoloBlockNum();
533 case sstChannel:
534 case sstDiode:
535 case sstStarZ:
536 case sstStarF:
537 return file->blockNum() == file->getSSTBlockNum();
538 case gyroRaw:
539 return file->blockNum() == file->getGyroBlockNum();
540 case gpsTime:
541 return file->blockNum() == file->getGPSBlockNum() && imes==0;
542 case longitude:
543 return file->blockNum() == file->getGPSBlockNum() && imes==0;
544 case latitude:
545 return file->blockNum() == file->getGPSBlockNum() && imes==0;
546 case altitude:
547 return file->blockNum() == file->getGPSBlockNum() && imes==0;
548 case azimut:
549 return true; // $CHECK$ with SSTHandler
550 case alphaAxis:
551 return true; // $CHECK$ with SSTHandler
552 case deltaAxis:
553 return true; // $CHECK$ with SSTHandler
554 }
555 return false;
556}
557
558bool TOIIter::extendValue(int column) {
559 return (!infos[column].interpolated && !newValue(column));
560}
561
562bool TOIIter::interpValue(int column) {
563 return (infos[column].interpolated && !newValue(column));
564}
565
566bool TOIIter::isTrig(int column) {
567 if (column < 0 || column >= infos.size()) return false;
568 return infos[column].triggering;
569}
570
571
572TOIKind TOIIter::getKind(int column) {
573 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
574 return infos[column].kind;
575}
576
577int TOIIter::getIndex(int column) {
578 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
579 return infos[column].index;
580}
581
582int TOIIter::getColTOI(TOIKind kind, int index) {
583 for (int i=0; i<infos.size(); i++)
584 if (infos[i].kind == kind && infos[i].index == index)
585 return i;
586 return -1;
587}
588
589bool TOIIter::canGetTOI(TOIKind kind, int index) {
590 int col = getColTOI(kind, index);
591 if (col<0) return false;
592 return canGetValue(col);
593}
594
595double TOIIter::getTOI(TOIKind kind, int index) {
596 int col = getColTOI(kind, index);
597 if (col<0) return -9.e99;
598 return getValue(col);
599}
600
601
602int TOIIter::getBlockSampleIndex() {
603 return imes;
604}
605
606int TOIIter::getSampleIndex() {
607 if (!initDone) Init();
608 if (file) {
609 return file->blockNum() * file->nEchBlock() + imes;
610 } else {
611 return lastSample;
612 }
613}
614
615double TOIIter::getMJD() {
616 if (!initDone) Init();
617 int sample = getSampleIndex();
618 return tBlock0 + sample*perEch/86400.;
619}
620
621bool TOIIter::fetchAhead() { // Seulement si delegation
622 if (!rawIter) return false;
623 if (!rawIter->Next()) return false;
624 long sample = rawIter->getSampleIndex();
625 for (int i=0; i<infos.size(); i++) {
626 if (rawIter->canGetValue(i) && rawIter->newValue(i)) {
627 interp[i].enterValue(rawIter->getValue(i), sample);
628 }
629 }
630 return true;
631}
632
633block_type_param* TOIIter::lastParam() {
634 if (!initDone) Init();
635 if (file) return file->lastParam();
636 else return rawIter->lastParam();
637}
638
639
Note: See TracBrowser for help on using the repository browser.