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

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

Gestion tsid

File size: 17.2 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}
44
45TOIIter::TOIIter(TOIIter const& x) {
46 directory = x.directory;
47 files = x.files;
48 // curFile = x.curFile; // $CHECK$ DANGER !!
49 curFile = files.find(*(x.curFile));
50 isOnBoardRecorder = x.isOnBoardRecorder;
51 imes = x.imes;
52 tStart = x.tStart;
53 tEnd = x.tEnd;
54 tBlock0 = x.tBlock0;
55 perEch = x.perEch;
56 trigMask = x.trigMask;
57 infos = x.infos;
58
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;
76
77 auxGPS = x.auxGPS;
78 if (auxGPS) auxGPS = auxGPS->clone();
79}
80
81TOIIter::~TOIIter() {
82 delete file;
83 delete rawIter;
84 delete[] interp;
85 delete auxGPS;
86}
87
88#ifdef __MWERKS__
89#define filesep ':'
90#else
91#define filesep '/'
92#endif
93
94void TOIIter::Init() {
95 // On a soit un repertoire, soit une liste de fichiers....
96 if (directory == "") {
97 if (files.empty()) { // Ni repertoire, ni fichiers
98 cerr << "toiiter : pas de repertoire, pas de fichiers" << endl;
99 exit(-1);
100 } else {
101 // On a deja une liste de fichiers
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;
110 DIR* dir = opendir(directory.c_str());
111 struct dirent* ent;
112 while ((ent = readdir(dir)) != NULL) {
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) {
136 if (strncmp(ent->d_name, "ARK", 3) && strncmp(ent->d_name, "ark", 3)) continue;
137 char * sfx = ent->d_name + strlen(ent->d_name) - 4;
138 if (strcmp(sfx, ".DAT") && strcmp(sfx, ".dat")) continue;
139 files.insert(directory + ent->d_name);
140 }
141 }
142 }
143 closedir(dir);
144 }
145
146 ScanFiles();
147
148 curFile = files.begin();
149 file = new ArcheopsFile((*curFile).c_str());
150 cout << "opening file " << (*curFile).c_str() << endl;
151
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
156 double oldTStart = tStart;
157 tStart = -9.e99; // pour init, on accepte des blocs avant tstart....
158
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 }
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
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.
176
177 if (tBlock0 < 0) {
178 tBlock0 = file->getStartMJD();
179
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();
189 }
190 tStart = oldTStart; // on restaure
191
192 if (perEch < 0)
193 perEch = file->perEchant();
194
195 bool hasInterp = false;
196
197 trigMask = 0;
198 for (vector<info>::iterator i = infos.begin(); i != infos.end(); i++) {
199 if ((*i).interpolated) hasInterp = true;
200 if ((*i).triggering) {
201 switch ((*i).kind) {
202 case boloTens:
203 case boloRaw:
204 trigMask |= block_bolo_mask;
205 break;
206 case gpsTime:
207 case longitude:
208 case latitude:
209 case altitude:
210 trigMask |= block_gps_mask;
211 break;
212 case azimut:
213 file->needSSTProcessMask(SSTHandler::findPeriod);
214 trigMask |= block_sst_mask;
215 break;
216 case sstStarZ:
217 case sstStarF:
218 file->needSSTProcessMask(SSTHandler::findStars);
219 trigMask |= block_sst_mask;
220 break;
221 case sstDiode:
222 file->needSSTProcessMask(SSTHandler::rmveOffset);
223 trigMask |= block_sst_mask;
224 break;
225 case sstChannel:
226 trigMask |= block_sst_mask;
227 break;
228 case gyroRaw:
229 trigMask |= block_gyro_mask;
230 break;
231 case alphaAxis:
232 case deltaAxis:
233 case alphaBolo:
234 case deltaBolo:
235 file->needSSTProcessMask(SSTHandler::findAxis);
236 trigMask |= block_sst_mask;
237 break;
238 }
239 }
240 }
241
242 if (trigMask & (block_bolo_mask | block_sst_mask)) {
243 imes = 9999;
244 } else {
245 imes = 0;
246 }
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 }
256}
257
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
296bool TOIIter::NextFile() {
297 if (rawIter)
298 return rawIter->NextFile();
299
300 if (files.empty()) {
301 return false;
302 } else {
303 if (curFile == files.end()) return false;
304 curFile++;
305 if (curFile == files.end()) return false;
306 cout << "opening file " << (*curFile).c_str() << endl;
307 ArcheopsFile* newfile = new ArcheopsFile((*curFile).c_str());
308 newfile->grabLastBlocs(*file);
309 delete file;
310 file = newfile;
311 return true;
312 }
313}
314
315
316bool TOIIter::Next() {
317 while (1) {
318 if (!NextSample()) return false; // end of files
319 double t = getMJD();
320 if (t < tStart) continue;
321 if (t > tEnd) return false;
322 return true;
323 }
324}
325
326bool TOIIter::NextSample() {
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 }
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...
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;
374 }
375}
376
377/* double TOIIter::getTime() { // MJD
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 }
382 */
383
384bool TOIIter::canGetValue(int column) {
385 if (column < 0 || column >= infos.size()) return false;
386 TOIKind kind = infos[column].kind;
387 if (auxGPS &&
388 (kind == longitude || kind == latitude || kind == altitude || kind == tsid)) {
389 double dummy;
390 return auxGPS->getLocation(getMJD(), dummy, dummy, dummy) == 0;
391 }
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:
399 case mjd:
400 return true;
401 case boloTens:
402 if (imes==0 && file->llastBolo()==NULL) return false;
403 return file->lastBolo() != NULL;
404 case boloRaw:
405 return file->lastBolo() != NULL;
406 case sstDiode:
407 case sstChannel:
408 return file->lastSST() != NULL;
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();
416 case longitude:
417 case latitude:
418 return file->hasGPSPos();
419 case altitude:
420 return file->hasGPSAlt();
421 case tsid:
422 return file->hasGPSPos();
423 case azimut:
424 case alphaAxis:
425 case deltaAxis:
426 return false;
427 //return (file->lastGPS() != NULL && file->lastSST() != NULL);
428 case alphaSst:
429 case deltaSst:
430 case alphaBolo:
431 case deltaBolo:
432 return false;
433
434 case boloTemp:
435 return false;
436 }
437 return false;
438}
439
440double TOIIter::getValue(int column) {
441 if (column < 0 || column >= infos.size()) return -1;
442 TOIKind kind = infos[column].kind;
443 if (auxGPS &&
444 (kind == longitude || kind == latitude || kind == altitude || kind == tsid)) {
445 double lat,lon,alt;
446 if (auxGPS->getLocation(getMJD(), lat, lon, alt)) return -99999;
447 if (kind == longitude) return lon;
448 if (kind == latitude) return lat;
449 if (kind == altitude) return alt;
450 if (kind == tsid) {
451 tSid.setLongitude(lon);
452 return tSid.getLST(getMJD());
453 }
454 }
455 if (rawIter) {
456 if (infos[column].interpolated)
457 return interp[column].getIValue(lastSample);
458 else
459 return interp[column].getEValue(lastSample);
460 }
461 int index = infos[column].index;
462 switch (kind) {
463 case sampleNum:
464 return getSampleIndex();
465 case internalTime:
466 return getSampleIndex() * perEch;
467 case mjd:
468 return getMJD();
469 case boloTens:
470 return file->getMuVBolo(index, imes);
471 case boloRaw:
472 return file->getRawBolo(index, imes);
473 case sstDiode:
474 return file->getSSTSignal(index, imes);
475 case sstChannel:
476 return file->getSSTRawSignal(index, imes);
477 case sstStarZ:
478 return file->getSSTStarZ(index, imes);
479 case sstStarF:
480 return file->getSSTStarF(index, imes);
481 case gyroRaw:
482 return file->getGyro(index, imes);
483 case gpsTime:
484 return file->getGPSUTC();
485 case longitude:
486 return file->getGPSLong();
487 case latitude:
488 return file->getGPSLat();
489 case altitude:
490 return file->getGPSAlt();
491 case tsid:
492 tSid.setLongitude(file->getGPSLong());
493 return tSid.getLST(getMJD());
494 case azimut:
495 return file->getAzimut(imes);
496 case alphaAxis:
497 return file->getAlpha(imes);
498 case deltaAxis:
499 return file->getDelta(imes);
500 }
501 return -1;
502}
503
504bool TOIIter::newValue(int column) {
505 if (column < 0 || column >= infos.size()) return false;
506 TOIKind kind = infos[column].kind;
507 if (auxGPS &&
508 (kind == longitude || kind == latitude || kind == altitude)) {
509 return true;
510 }
511 if (rawIter) {
512 return interp[column].isNewValue(lastSample);
513 }
514 switch (kind) {
515 case sampleNum:
516 case internalTime:
517 case mjd:
518 case tsid:
519 return true;
520 case boloTens:
521 return file->blockNum() == file->getBoloBlockNum();
522 case boloRaw:
523 return file->blockNum() == file->getBoloBlockNum();
524 case sstChannel:
525 case sstDiode:
526 case sstStarZ:
527 case sstStarF:
528 return file->blockNum() == file->getSSTBlockNum();
529 case gyroRaw:
530 return file->blockNum() == file->getGyroBlockNum();
531 case gpsTime:
532 return file->blockNum() == file->getGPSBlockNum() && imes==0;
533 case longitude:
534 return file->blockNum() == file->getGPSBlockNum() && imes==0;
535 case latitude:
536 return file->blockNum() == file->getGPSBlockNum() && imes==0;
537 case altitude:
538 return file->blockNum() == file->getGPSBlockNum() && imes==0;
539 case azimut:
540 return true; // $CHECK$ with SSTHandler
541 case alphaAxis:
542 return true; // $CHECK$ with SSTHandler
543 case deltaAxis:
544 return true; // $CHECK$ with SSTHandler
545 }
546 return false;
547}
548
549bool TOIIter::extendValue(int column) {
550 return (!infos[column].interpolated && !newValue(column));
551}
552
553bool TOIIter::interpValue(int column) {
554 return (infos[column].interpolated && !newValue(column));
555}
556
557bool TOIIter::isTrig(int column) {
558 if (column < 0 || column >= infos.size()) return false;
559 return infos[column].triggering;
560}
561
562
563TOIKind TOIIter::getKind(int column) {
564 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
565 return infos[column].kind;
566}
567
568int TOIIter::getIndex(int column) {
569 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
570 return infos[column].index;
571}
572
573int TOIIter::getColTOI(TOIKind kind, int index) {
574 for (int i=0; i<infos.size(); i++)
575 if (infos[i].kind == kind && infos[i].index == index)
576 return i;
577 return -1;
578}
579
580bool TOIIter::canGetTOI(TOIKind kind, int index) {
581 int col = getColTOI(kind, index);
582 if (col<0) return false;
583 return canGetValue(col);
584}
585
586double TOIIter::getTOI(TOIKind kind, int index) {
587 int col = getColTOI(kind, index);
588 if (col<0) return -9.e99;
589 return getValue(col);
590}
591
592
593int TOIIter::getBlockSampleIndex() {
594 return imes;
595}
596
597int TOIIter::getSampleIndex() {
598 if (file) {
599 return file->blockNum() * file->nEchBlock() + imes;
600 } else {
601 return lastSample;
602 }
603}
604
605double TOIIter::getMJD() {
606 int sample = getSampleIndex();
607 return tBlock0 + sample*perEch/86400.;
608}
609
610bool TOIIter::fetchAhead() { // Seulement si delegation
611 if (!rawIter) return false;
612 if (!rawIter->Next()) return false;
613 long sample = rawIter->getSampleIndex();
614 for (int i=0; i<infos.size(); i++) {
615 if (rawIter->canGetValue(i) && rawIter->newValue(i)) {
616 interp[i].enterValue(rawIter->getValue(i), sample);
617 }
618 }
619 return true;
620}
621
622block_type_param* TOIIter::lastParam() {
623 if (file) return file->lastParam();
624 else return rawIter->lastParam();
625}
626
627
Note: See TracBrowser for help on using the repository browser.