// archfileset.cc // Eric Aubourg CEA/DAPNIA/SPP septembre 1999 #include #include #include "archfileset.h" #include "archparam.h" #include "toiproducer.h" #include "toimanager.h" ArchFileSet::ArchFileSet() { file = NULL; trigMask = block_reglage_mask | block_param_mask | TOIManager::trigMask; sStart = -999999999; sEnd = 999999999; mjdStart = -999999999; mjdEnd = 999999999; initDone = false; endFound = false; } ArchFileSet::ArchFileSet(ArchFileSet const& x) { directories = x.directories; filenames = x.filenames; if (x.initDone && x.curFile != x.filenames.end()) curFile = filenames.find(*(x.curFile)); trigMask = x.trigMask; sStart = x.sStart; sEnd = x.sEnd; mjdStart = x.mjdStart; mjdEnd = x.mjdEnd; if (x.file) file = new ArcheopsFile(*x.file); else file = NULL; initDone = x.initDone; endFound = x.endFound; } ArchFileSet::~ArchFileSet() { delete file; } void ArchFileSet::setSNumRange(long start, long end) { sStart = start; sEnd = end; } void ArchFileSet::setMJDRange(double start, double end) { mjdStart = start; mjdEnd = end; } void ArchFileSet::addFile(string fn) { filenames.insert(fn); } void ArchFileSet::addDirectory(string fn) { directories.insert(fn); } #ifdef __MWERKS__ #pragma mark - #endif #ifdef __MWERKS__ #define filesep ':' #else #define filesep '/' #endif void ArchFileSet::init() { if (initDone) return; initDone = true; trigMask |= TOIManager::trigMask; // build files from directories for (set::iterator i = directories.begin(); i != directories.end(); i++) { string directory = *i; if (directory[directory.length()-1] != filesep) directory += filesep; DIR* dir = opendir(directory.c_str()); struct dirent* ent; while ((ent = readdir(dir)) != NULL) { // si c'est un repertoire, avec un nom de jour, il faut l'explorer... if (!strncmp(ent->d_name, "arch-", 5)) { double mjd = ArcheopsFile::decodeMJD(ent->d_name+5) - 2./24.; // ENTIER + .5 en temps local! if (mjd >= mjdStart - 1. && mjd <= mjdEnd) { string direc2 = directory + ent->d_name + filesep; DIR* dir2 = opendir(direc2.c_str()); struct dirent* ent2; while ((ent2 = readdir(dir2)) != NULL) { if (*ent2->d_name == 'h') { double mjd2 = ArcheopsFile::decodeMJD(ent->d_name+1) - 2./24.; if (mjd2 >= mjdStart - 1./24. && mjd2 <= mjdEnd) { filenames.insert(direc2 + ent2->d_name); } } } } } // "arch-" else if (*ent->d_name == 'h') { double mjd = ArcheopsFile::decodeMJD(ent->d_name+1) - 2./24.; // $CHECK$ UTCOffset if (mjd >= mjdStart - 1./24. && mjd <= mjdEnd) { filenames.insert(directory + ent->d_name); } } // "h*" else if (!strncmp(ent->d_name, "ARK", 3) || !strncmp(ent->d_name, "ark", 3)) { char * sfx = ent->d_name + strlen(ent->d_name) - 4; if (!strcmp(sfx, ".DAT") || !strcmp(sfx, ".dat")) { filenames.insert(directory + ent->d_name); } } } // readdir closedir(dir); } // iterate on dirs scanFiles(); if (filenames.empty()) { throw ArchExc("No files in fileset"); } curFile = filenames.begin(); file = new ArcheopsFile((*curFile).c_str()); cout << "opening file " << (*curFile).c_str() << endl; extern param_bolo parametr; block_type_param block; block.param = parametr; valide_block((block_type_modele*)&block, block_param, 0); file->forceBlock((block_type_modele*)&block); if (!file->lastReglage()) file->nextBlock(block_reglage_mask); } void ArchFileSet::scanFiles() { file1stSamp.clear(); cout << "Scanning all files" << endl; // Petite astuce pour les STL non conformes comme celles de digital // qui ne supportent pas files.erase(i) suivi de i++.... set copy = filenames; for (set::iterator i = copy.begin(); i != copy.end(); i++) { ArcheopsFile fich((*i).c_str()); if (fich.nextBlock()) { file1stSamp[*i] = fich.blockNum()*72; // premier numsample cout << "File " << *i << " 1st sample = " << fich.blockNum()*72 << " UTC " << archParam.acq.SN2UTC(fich.blockNum()*72) << endl; } else { cout << "File " << *i << " unrecoverable, skipping" << endl; filenames.erase(*i); } } cout << "Scan done" << endl; // Et maintenant, on ne garde que ceux qui tombent dans l'intervalle... copy = filenames; string prev=""; for (set::iterator i = copy.begin(); i != copy.end(); i++) { double smp = file1stSamp[*i]; double t = archParam.acq.tBlock0 + smp * archParam.acq.perEch/86400.; if (t>mjdEnd || smp>sEnd) { // premier echantillon apres tEnd filenames.erase(*i); prev = ""; continue; } if (t on vire le precedent si existe if (prev != "") { filenames.erase(prev); } } prev = *i; } } bool ArchFileSet::nextFile() { if (filenames.empty()) { return false; } else { if (curFile == filenames.end()) return false; curFile++; if (curFile == filenames.end()) return false; cout << "opening file " << (*curFile).c_str() << endl; ArcheopsFile* newfile = new ArcheopsFile((*curFile).c_str()); newfile->grabLastBlocs(*file); delete file; file = newfile; return true; } } bool ArchFileSet::next() { if (endFound) return false; if (!initDone) init(); while (1) { long got = nextSample(); if (!got) {endFound=true; return false;} // end of files double t = getMJD(); if (t < mjdStart) continue; if (t > mjdEnd) {endFound=true; return false;} long s = getSampleIndex(); if (s < sStart) continue; if (s > sEnd) {endFound=true; return false;} // On envoie les nouvelles donnees aux producers interesses for (map::iterator i = TOIManager::activeLLProducers.begin(); i != TOIManager::activeLLProducers.end(); i++) { if (got & ((*i).second)) (*i).first->handleBlock(this); } return true; } } long ArchFileSet::getSampleIndex() { if (!initDone) init(); return file->blockNum() * nb_per_block*2; } double ArchFileSet::getMJD() { if (!initDone) init(); int sample = getSampleIndex(); return archParam.acq.SN2MJD(sample); } long ArchFileSet::nextSample() { while (1) { long got = 0; if (file->nextBlock(trigMask)) { got |= 1 << type_block(file->currentBlock()); while (file->sameBlockNumAhead()) { // tant que meme numero de bloc, on lit if (!file->nextBlock()) { // fin de fichier ? if (nextFile()) file->nextBlock(); // fichier suivant else return 0; // tout fini } got |= 1 << type_block(file->currentBlock()); } return got; } if (!nextFile()) return 0; } } #ifdef __MWERKS__ #pragma mark - #endif block_type_param* ArchFileSet::lastParam() { if (!file) return NULL; return file->lastParam(); } block_type_journal* ArchFileSet::lastJournal() { if (!file) return NULL; return file->lastJournal(); } block_type_reglage* ArchFileSet::lastReglage() { if (!file) return NULL; return file->lastReglage(); } block_type_dilution* ArchFileSet::lastDilution() { if (!file) return NULL; return file->lastDilution(); } block_type_gps* ArchFileSet::lastGPS() { if (!file) return NULL; return file->lastGPS(); } block_type_une_periode* ArchFileSet::lastUnePeriode() { if (!file) return NULL; return file->lastUnePeriode(); } block_type_synchro_sol* ArchFileSet::lastSynchroSol() { if (!file) return NULL; return file->lastSynchroSol(); } block_type_pointage_sol* ArchFileSet::lastPointageSol() { if (!file) return NULL; return file->lastPointageSol(); } block_type_bolo* ArchFileSet::lastBolo() { if (!file) return NULL; return file->lastBolo(); } block_type_gyro* ArchFileSet::lastGyro() { if (!file) return NULL; return file->lastGyro(); } block_type_sst* ArchFileSet::lastSST() { if (!file) return NULL; return file->lastSST(); } block_type_bolo_comprime* ArchFileSet::lastBoloComp() { if (!file) return NULL; return file->lastBoloComp(); } block_type_gyro_comprime* ArchFileSet::lastGyroComp() { if (!file) return NULL; return file->lastGyroComp(); } block_type_sst_comprime* ArchFileSet::lastSSTComp() { if (!file) return NULL; return file->lastSSTComp(); }