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
RevLine 
[350]1// toiiter.cc
2// Eric Aubourg CEA/DAPNIA/SPP juillet 1999
3
4
[310]5#include "toiiter.h"
[315]6#include "toiinterpolator.h"
[310]7#include <dirent.h>
[342]8#include <iostream.h>
[310]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
[342]20 files.clear();
21
22 isOnBoardRecorder = false;
23
24 imes=0;
25
[310]26 tStart = -9.e99;
[342]27 tEnd = 9.e99;
[310]28
29 tBlock0 = -1;
[342]30 perEch = -1;
[350]31 // Values for Trapani 99 = default values
32 tBlock0 = 1376.8358818;
33 perEch = 0.005836818076;
[315]34
[342]35 trigMask = 0;
[315]36 rawIter = NULL;
37 interp = NULL;
38 lastSample = -1;
[342]39 maxLookAhead = 10000;
[358]40
41 auxGPS = NULL;
[393]42
43 initDone = false;
[310]44}
45
46TOIIter::TOIIter(TOIIter const& x) {
47 directory = x.directory;
48 files = x.files;
[342]49 // curFile = x.curFile; // $CHECK$ DANGER !!
50 curFile = files.find(*(x.curFile));
51 isOnBoardRecorder = x.isOnBoardRecorder;
[310]52 imes = x.imes;
53 tStart = x.tStart;
54 tEnd = x.tEnd;
55 tBlock0 = x.tBlock0;
[342]56 perEch = x.perEch;
[310]57 trigMask = x.trigMask;
58 infos = x.infos;
59
[315]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;
[358]77
78 auxGPS = x.auxGPS;
79 if (auxGPS) auxGPS = auxGPS->clone();
[393]80
81 initDone = x.initDone;
[310]82}
83
84TOIIter::~TOIIter() {
85 delete file;
[315]86 delete rawIter;
87 delete[] interp;
[358]88 delete auxGPS;
[310]89}
90
[342]91#ifdef __MWERKS__
92#define filesep ':'
93#else
94#define filesep '/'
95#endif
96
[310]97void TOIIter::Init() {
[393]98 if (initDone) return;
99 initDone = true;
[350]100 // On a soit un repertoire, soit une liste de fichiers....
[310]101 if (directory == "") {
[350]102 if (files.empty()) { // Ni repertoire, ni fichiers
103 cerr << "toiiter : pas de repertoire, pas de fichiers" << endl;
104 exit(-1);
[342]105 } else {
[350]106 // On a deja une liste de fichiers
[342]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;
[310]115 DIR* dir = opendir(directory.c_str());
116 struct dirent* ent;
117 while ((ent = readdir(dir)) != NULL) {
[342]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) {
[350]141 if (strncmp(ent->d_name, "ARK", 3) && strncmp(ent->d_name, "ark", 3)) continue;
[342]142 char * sfx = ent->d_name + strlen(ent->d_name) - 4;
[350]143 if (strcmp(sfx, ".DAT") && strcmp(sfx, ".dat")) continue;
[342]144 files.insert(directory + ent->d_name);
145 }
146 }
[310]147 }
148 closedir(dir);
149 }
[350]150
151 ScanFiles();
152
153 curFile = files.begin();
154 file = new ArcheopsFile((*curFile).c_str());
155 cout << "opening file " << (*curFile).c_str() << endl;
[310]156
[342]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
[350]161 double oldTStart = tStart;
162 tStart = -9.e99; // pour init, on accepte des blocs avant tstart....
163
[342]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 }
[310]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
[342]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.
[310]181
[342]182 if (tBlock0 < 0) {
183 tBlock0 = file->getStartMJD();
[315]184
[342]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();
[310]194 }
[350]195 tStart = oldTStart; // on restaure
[342]196
197 if (perEch < 0)
198 perEch = file->perEchant();
[315]199
200 bool hasInterp = false;
[310]201
202 trigMask = 0;
203 for (vector<info>::iterator i = infos.begin(); i != infos.end(); i++) {
[315]204 if ((*i).interpolated) hasInterp = true;
[310]205 if ((*i).triggering) {
206 switch ((*i).kind) {
207 case boloTens:
208 case boloRaw:
209 trigMask |= block_bolo_mask;
210 break;
[342]211 case gpsTime:
[310]212 case longitude:
213 case latitude:
[342]214 case altitude:
[310]215 trigMask |= block_gps_mask;
216 break;
217 case azimut:
[315]218 file->needSSTProcessMask(SSTHandler::findPeriod);
[310]219 trigMask |= block_sst_mask;
220 break;
[315]221 case sstStarZ:
222 case sstStarF:
223 file->needSSTProcessMask(SSTHandler::findStars);
[310]224 trigMask |= block_sst_mask;
225 break;
[350]226 case sstDiode:
[315]227 file->needSSTProcessMask(SSTHandler::rmveOffset);
228 trigMask |= block_sst_mask;
229 break;
[350]230 case sstChannel:
[342]231 trigMask |= block_sst_mask;
232 break;
233 case gyroRaw:
234 trigMask |= block_gyro_mask;
235 break;
[315]236 case alphaAxis:
237 case deltaAxis:
238 case alphaBolo:
239 case deltaBolo:
240 file->needSSTProcessMask(SSTHandler::findAxis);
241 trigMask |= block_sst_mask;
242 break;
[310]243 }
244 }
245 }
246
247 if (trigMask & (block_bolo_mask | block_sst_mask)) {
248 imes = 9999;
249 } else {
250 imes = 0;
251 }
[315]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 }
[310]261}
262
[350]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
[310]301bool TOIIter::NextFile() {
[315]302 if (rawIter)
303 return rawIter->NextFile();
304
[342]305 if (files.empty()) {
[310]306 return false;
307 } else {
308 if (curFile == files.end()) return false;
309 curFile++;
310 if (curFile == files.end()) return false;
[342]311 cout << "opening file " << (*curFile).c_str() << endl;
[310]312 ArcheopsFile* newfile = new ArcheopsFile((*curFile).c_str());
313 newfile->grabLastBlocs(*file);
314 delete file;
315 file = newfile;
316 return true;
317 }
318}
319
[350]320
[310]321bool TOIIter::Next() {
[393]322 if (!initDone) Init();
[350]323 while (1) {
324 if (!NextSample()) return false; // end of files
[358]325 double t = getMJD();
[350]326 if (t < tStart) continue;
327 if (t > tEnd) return false;
328 return true;
329 }
330}
331
332bool TOIIter::NextSample() {
[315]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 }
[310]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...
[315]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 ?
[393]373 if (NextFile()) file->nextBlock(); // fichier suivant
374 else return false; // tout fini
[315]375 }
376 }
377 return true;
378 }
379 if (!NextFile()) return false;
[310]380 }
381}
382
[315]383/* double TOIIter::getTime() { // MJD
[310]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 }
[315]388 */
[310]389
[315]390bool TOIIter::canGetValue(int column) {
[393]391 if (!initDone) Init();
[315]392 if (column < 0 || column >= infos.size()) return false;
[358]393 TOIKind kind = infos[column].kind;
394 if (auxGPS &&
[363]395 (kind == longitude || kind == latitude || kind == altitude || kind == tsid)) {
[358]396 double dummy;
397 return auxGPS->getLocation(getMJD(), dummy, dummy, dummy) == 0;
398 }
[315]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:
[350]406 case mjd:
[315]407 return true;
408 case boloTens:
[342]409 if (imes==0 && file->llastBolo()==NULL) return false;
410 return file->lastBolo() != NULL;
[315]411 case boloRaw:
412 return file->lastBolo() != NULL;
[350]413 case sstDiode:
414 case sstChannel:
[315]415 return file->lastSST() != NULL;
[342]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();
[315]423 case longitude:
424 case latitude:
[342]425 return file->hasGPSPos();
426 case altitude:
427 return file->hasGPSAlt();
[363]428 case tsid:
429 return file->hasGPSPos();
[315]430 case azimut:
431 case alphaAxis:
432 case deltaAxis:
[363]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;
[315]443 }
444 return false;
445}
446
447double TOIIter::getValue(int column) {
[393]448 if (!initDone) Init();
[310]449 if (column < 0 || column >= infos.size()) return -1;
[358]450 TOIKind kind = infos[column].kind;
451 if (auxGPS &&
[363]452 (kind == longitude || kind == latitude || kind == altitude || kind == tsid)) {
[358]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;
[363]457 if (kind == altitude) return alt;
458 if (kind == tsid) {
459 tSid.setLongitude(lon);
460 return tSid.getLST(getMJD());
461 }
[358]462 }
[315]463 if (rawIter) {
464 if (infos[column].interpolated)
465 return interp[column].getIValue(lastSample);
466 else
467 return interp[column].getEValue(lastSample);
468 }
[310]469 int index = infos[column].index;
470 switch (kind) {
[315]471 case sampleNum:
[358]472 return getSampleIndex();
[315]473 case internalTime:
[358]474 return getSampleIndex() * perEch;
[350]475 case mjd:
[358]476 return getMJD();
[310]477 case boloTens:
478 return file->getMuVBolo(index, imes);
479 case boloRaw:
480 return file->getRawBolo(index, imes);
[350]481 case sstDiode:
[315]482 return file->getSSTSignal(index, imes);
[350]483 case sstChannel:
[342]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();
[310]493 case longitude:
[342]494 return file->getGPSLong();
[310]495 case latitude:
[342]496 return file->getGPSLat();
497 case altitude:
498 return file->getGPSAlt();
[363]499 case tsid:
500 tSid.setLongitude(file->getGPSLong());
501 return tSid.getLST(getMJD());
[315]502 case azimut:
[310]503 return file->getAzimut(imes);
[315]504 case alphaAxis:
[310]505 return file->getAlpha(imes);
[315]506 case deltaAxis:
[310]507 return file->getDelta(imes);
508 }
509 return -1;
[315]510}
[310]511
[315]512bool TOIIter::newValue(int column) {
[393]513 if (!initDone) Init();
[310]514 if (column < 0 || column >= infos.size()) return false;
[358]515 TOIKind kind = infos[column].kind;
516 if (auxGPS &&
517 (kind == longitude || kind == latitude || kind == altitude)) {
518 return true;
519 }
[342]520 if (rawIter) {
521 return interp[column].isNewValue(lastSample);
522 }
[310]523 switch (kind) {
[315]524 case sampleNum:
525 case internalTime:
[350]526 case mjd:
[363]527 case tsid:
[315]528 return true;
[310]529 case boloTens:
[315]530 return file->blockNum() == file->getBoloBlockNum();
[310]531 case boloRaw:
[315]532 return file->blockNum() == file->getBoloBlockNum();
[350]533 case sstChannel:
534 case sstDiode:
[342]535 case sstStarZ:
536 case sstStarF:
[315]537 return file->blockNum() == file->getSSTBlockNum();
[342]538 case gyroRaw:
539 return file->blockNum() == file->getGyroBlockNum();
540 case gpsTime:
541 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[310]542 case longitude:
[315]543 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[310]544 case latitude:
[315]545 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[342]546 case altitude:
547 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[315]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
[310]554 }
555 return false;
[315]556}
[310]557
[315]558bool TOIIter::extendValue(int column) {
559 return (!infos[column].interpolated && !newValue(column));
560}
[310]561
[315]562bool TOIIter::interpValue(int column) {
563 return (infos[column].interpolated && !newValue(column));
564}
[342]565
566bool TOIIter::isTrig(int column) {
567 if (column < 0 || column >= infos.size()) return false;
568 return infos[column].triggering;
569}
570
[310]571
[315]572TOIKind TOIIter::getKind(int column) {
[310]573 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
574 return infos[column].kind;
[315]575}
[310]576
[315]577int TOIIter::getIndex(int column) {
[310]578 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
579 return infos[column].index;
[315]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
[310]601
[315]602int TOIIter::getBlockSampleIndex() {
[310]603 return imes;
[315]604}
605
606int TOIIter::getSampleIndex() {
[393]607 if (!initDone) Init();
[342]608 if (file) {
609 return file->blockNum() * file->nEchBlock() + imes;
610 } else {
611 return lastSample;
612 }
[315]613}
[358]614
615double TOIIter::getMJD() {
[393]616 if (!initDone) Init();
[358]617 int sample = getSampleIndex();
618 return tBlock0 + sample*perEch/86400.;
619}
[315]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++) {
[342]626 if (rawIter->canGetValue(i) && rawIter->newValue(i)) {
[315]627 interp[i].enterValue(rawIter->getValue(i), sample);
[342]628 }
[315]629 }
630 return true;
631}
632
[342]633block_type_param* TOIIter::lastParam() {
[393]634 if (!initDone) Init();
[342]635 if (file) return file->lastParam();
636 else return rawIter->lastParam();
637}
638
639
Note: See TracBrowser for help on using the repository browser.