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
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;
[310]40
41}
42
43TOIIter::TOIIter(TOIIter const& x) {
44 directory = x.directory;
45 files = x.files;
[342]46 // curFile = x.curFile; // $CHECK$ DANGER !!
47 curFile = files.find(*(x.curFile));
48 isOnBoardRecorder = x.isOnBoardRecorder;
[310]49 imes = x.imes;
50 tStart = x.tStart;
51 tEnd = x.tEnd;
52 tBlock0 = x.tBlock0;
[342]53 perEch = x.perEch;
[310]54 trigMask = x.trigMask;
55 infos = x.infos;
56
[315]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;
[310]74}
75
76TOIIter::~TOIIter() {
77 delete file;
[315]78 delete rawIter;
79 delete[] interp;
[310]80}
81
[342]82#ifdef __MWERKS__
83#define filesep ':'
84#else
85#define filesep '/'
86#endif
87
[310]88void TOIIter::Init() {
[350]89 // On a soit un repertoire, soit une liste de fichiers....
[310]90 if (directory == "") {
[350]91 if (files.empty()) { // Ni repertoire, ni fichiers
92 cerr << "toiiter : pas de repertoire, pas de fichiers" << endl;
93 exit(-1);
[342]94 } else {
[350]95 // On a deja une liste de fichiers
[342]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;
[310]104 DIR* dir = opendir(directory.c_str());
105 struct dirent* ent;
106 while ((ent = readdir(dir)) != NULL) {
[342]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) {
[350]130 if (strncmp(ent->d_name, "ARK", 3) && strncmp(ent->d_name, "ark", 3)) continue;
[342]131 char * sfx = ent->d_name + strlen(ent->d_name) - 4;
[350]132 if (strcmp(sfx, ".DAT") && strcmp(sfx, ".dat")) continue;
[342]133 files.insert(directory + ent->d_name);
134 }
135 }
[310]136 }
137 closedir(dir);
138 }
[350]139
140 ScanFiles();
141
142 curFile = files.begin();
143 file = new ArcheopsFile((*curFile).c_str());
144 cout << "opening file " << (*curFile).c_str() << endl;
[310]145
[342]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
[350]150 double oldTStart = tStart;
151 tStart = -9.e99; // pour init, on accepte des blocs avant tstart....
152
[342]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 }
[310]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
[342]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.
[310]170
[342]171 if (tBlock0 < 0) {
172 tBlock0 = file->getStartMJD();
[315]173
[342]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();
[310]183 }
[350]184 tStart = oldTStart; // on restaure
[342]185
186 if (perEch < 0)
187 perEch = file->perEchant();
[315]188
189 bool hasInterp = false;
[310]190
191 trigMask = 0;
192 for (vector<info>::iterator i = infos.begin(); i != infos.end(); i++) {
[315]193 if ((*i).interpolated) hasInterp = true;
[310]194 if ((*i).triggering) {
195 switch ((*i).kind) {
196 case boloTens:
197 case boloRaw:
198 trigMask |= block_bolo_mask;
199 break;
[342]200 case gpsTime:
[310]201 case longitude:
202 case latitude:
[342]203 case altitude:
[310]204 trigMask |= block_gps_mask;
205 break;
206 case azimut:
[315]207 file->needSSTProcessMask(SSTHandler::findPeriod);
[310]208 trigMask |= block_sst_mask;
209 break;
[315]210 case sstStarZ:
211 case sstStarF:
212 file->needSSTProcessMask(SSTHandler::findStars);
[310]213 trigMask |= block_sst_mask;
214 break;
[350]215 case sstDiode:
[315]216 file->needSSTProcessMask(SSTHandler::rmveOffset);
217 trigMask |= block_sst_mask;
218 break;
[350]219 case sstChannel:
[342]220 trigMask |= block_sst_mask;
221 break;
222 case gyroRaw:
223 trigMask |= block_gyro_mask;
224 break;
[315]225 case alphaAxis:
226 case deltaAxis:
227 case alphaBolo:
228 case deltaBolo:
229 file->needSSTProcessMask(SSTHandler::findAxis);
230 trigMask |= block_sst_mask;
231 break;
[310]232 }
233 }
234 }
235
236 if (trigMask & (block_bolo_mask | block_sst_mask)) {
237 imes = 9999;
238 } else {
239 imes = 0;
240 }
[315]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 }
[310]250}
251
[350]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
[310]290bool TOIIter::NextFile() {
[315]291 if (rawIter)
292 return rawIter->NextFile();
293
[342]294 if (files.empty()) {
[310]295 return false;
296 } else {
297 if (curFile == files.end()) return false;
298 curFile++;
299 if (curFile == files.end()) return false;
[342]300 cout << "opening file " << (*curFile).c_str() << endl;
[310]301 ArcheopsFile* newfile = new ArcheopsFile((*curFile).c_str());
302 newfile->grabLastBlocs(*file);
303 delete file;
304 file = newfile;
305 return true;
306 }
307}
308
[350]309
[310]310bool TOIIter::Next() {
[350]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() {
[315]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 }
[310]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...
[315]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;
[310]368 }
369}
370
[315]371/* double TOIIter::getTime() { // MJD
[310]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 }
[315]376 */
[310]377
[315]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:
[350]388 case mjd:
[315]389 return true;
390 case boloTens:
[342]391 if (imes==0 && file->llastBolo()==NULL) return false;
392 return file->lastBolo() != NULL;
[315]393 case boloRaw:
394 return file->lastBolo() != NULL;
[350]395 case sstDiode:
396 case sstChannel:
[315]397 return file->lastSST() != NULL;
[342]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();
[315]405 case longitude:
406 case latitude:
[342]407 return file->hasGPSPos();
408 case altitude:
409 return file->hasGPSAlt();
[315]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) {
[310]419 if (column < 0 || column >= infos.size()) return -1;
[315]420 if (rawIter) {
421 if (infos[column].interpolated)
422 return interp[column].getIValue(lastSample);
423 else
424 return interp[column].getEValue(lastSample);
425 }
[310]426 TOIKind kind = infos[column].kind;
427 int index = infos[column].index;
428 switch (kind) {
[315]429 case sampleNum:
430 return file->blockNum() * file->nEchBlock() + imes;
431 case internalTime:
[342]432 //return (file->blockNum() * file->nEchBlock() + imes) * file->perEchant();
433 return (file->blockNum() * file->nEchBlock() + imes) * perEch;
[350]434 case mjd:
435 /* printf("mjd: %d %d %g %g %g\n",file->blockNum(),
[315]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.); */
[342]440 //return tBlock0+(file->blockNum() * file->nEchBlock() + imes) * file->perEchant()/86400.;
441 return tBlock0+(file->blockNum() * file->nEchBlock() + imes) * perEch/86400.;
[310]442 case boloTens:
443 return file->getMuVBolo(index, imes);
444 case boloRaw:
445 return file->getRawBolo(index, imes);
[350]446 case sstDiode:
[315]447 return file->getSSTSignal(index, imes);
[350]448 case sstChannel:
[342]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();
[310]458 case longitude:
[342]459 return file->getGPSLong();
[310]460 case latitude:
[342]461 return file->getGPSLat();
462 case altitude:
463 return file->getGPSAlt();
[315]464 case azimut:
[310]465 return file->getAzimut(imes);
[315]466 case alphaAxis:
[310]467 return file->getAlpha(imes);
[315]468 case deltaAxis:
[310]469 return file->getDelta(imes);
470 }
471 return -1;
[315]472}
[310]473
[315]474bool TOIIter::newValue(int column) {
[310]475 if (column < 0 || column >= infos.size()) return false;
[342]476 if (rawIter) {
477 return interp[column].isNewValue(lastSample);
478 }
[310]479 TOIKind kind = infos[column].kind;
480 switch (kind) {
[315]481 case sampleNum:
482 case internalTime:
[350]483 case mjd:
[315]484 return true;
[310]485 case boloTens:
[315]486 return file->blockNum() == file->getBoloBlockNum();
[310]487 case boloRaw:
[315]488 return file->blockNum() == file->getBoloBlockNum();
[350]489 case sstChannel:
490 case sstDiode:
[342]491 case sstStarZ:
492 case sstStarF:
[315]493 return file->blockNum() == file->getSSTBlockNum();
[342]494 case gyroRaw:
495 return file->blockNum() == file->getGyroBlockNum();
496 case gpsTime:
497 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[310]498 case longitude:
[315]499 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[310]500 case latitude:
[315]501 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[342]502 case altitude:
503 return file->blockNum() == file->getGPSBlockNum() && imes==0;
[315]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
[310]510 }
511 return false;
[315]512}
[310]513
[315]514bool TOIIter::extendValue(int column) {
515 return (!infos[column].interpolated && !newValue(column));
516}
[310]517
[315]518bool TOIIter::interpValue(int column) {
519 return (infos[column].interpolated && !newValue(column));
520}
[342]521
522bool TOIIter::isTrig(int column) {
523 if (column < 0 || column >= infos.size()) return false;
524 return infos[column].triggering;
525}
526
[310]527
[315]528TOIKind TOIIter::getKind(int column) {
[310]529 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
530 return infos[column].kind;
[315]531}
[310]532
[315]533int TOIIter::getIndex(int column) {
[310]534 if (column < 0 || column >= infos.size()) return (TOIKind)-1;
535 return infos[column].index;
[315]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
[310]557
[315]558int TOIIter::getBlockSampleIndex() {
[310]559 return imes;
[315]560}
561
562int TOIIter::getSampleIndex() {
[342]563 if (file) {
564 return file->blockNum() * file->nEchBlock() + imes;
565 } else {
566 return lastSample;
567 }
[315]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++) {
[342]575 if (rawIter->canGetValue(i) && rawIter->newValue(i)) {
[315]576 interp[i].enterValue(rawIter->getValue(i), sample);
[342]577 }
[315]578 }
579 return true;
580}
581
[342]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.