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

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

Integration detecteur d'etoiles DY

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