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