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

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

Gestion TRANGE, MJD0, PERECH....

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