Changeset 14715 for trunk/FACT++/src


Ignore:
Timestamp:
12/03/12 14:40:26 (12 years ago)
Author:
lyard
Message:
changed behavior. Now if service format changes, a new file is opened
Location:
trunk/FACT++/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/Fits.cc

    r14238 r14715  
    125125    {//if we arrived here, this means that the columns descriptions could not be parsed
    126126        ostringstream str;
    127         str << "Expected " << dataFormat.size() << " descriptions of columns, got " << desc.size()-1 << " for service: ";
     127        str << "Expected " << dataFormat.size() << " descriptions of columns, got " << (int)(desc.size())-1 << " for service: ";
    128128        if (desc.size() > 0)
    129129            str << desc[0].name;
     
    208208        {
    209209            Close();
    210             return false;
     210            //if the file already exist, then the column names must have changed
     211            //let's move the file and try to open it again.
     212            string fileNameWithoutFits = fFileName.substr(0, fileName.size()-4);
     213            int counter = 0;
     214            while (counter < 100)
     215            {
     216                ostringstream newFileName;
     217                newFileName << fileNameWithoutFits << counter << ".fits";
     218                ifstream testStream(newFileName.str().c_str());
     219                if (!testStream)
     220                {
     221                    if (rename(fFileName.c_str(), newFileName.str().c_str()))
     222                        return false;
     223                    break;
     224                }
     225                counter++;
     226            }
     227            if (counter == 100)
     228                return false;
     229            //now we open it again.
     230            fFile = new FitsFile(*fMess);
     231            if (file == NULL)
     232            {
     233                if (!fFile->OpenFile(fileName, true))
     234                    return false;
     235                fNumOpenFitsFiles = fitsCounter;
     236                (*fNumOpenFitsFiles)++;
     237            }
     238            else
     239            {
     240                if (!fFile->SetFile(file))
     241                    return false;
     242            }
     243            //YES, we must also redo that thing here...
     244            //concatenate the standard and data columns
     245            //do it the inneficient way first: its easier and faster to code.
     246            for (unsigned int i=0;i<fStandardColDesc.size();i++)
     247            {
     248                fFile->AddColumn(fStandardColDesc[i].name, fStandardFormats[i],
     249                                 fStandardColDesc[i].unit);
     250            }
     251
     252            for (unsigned int i=0; i<fDataColDesc.size(); i++)
     253            {
     254                string name = fDataColDesc[i].name;
     255                if (name.empty())
     256                {
     257                    ostringstream stt;
     258                    stt << "Data" << i;
     259                    name = stt.str();
     260                }
     261        //cout << endl << "#####adding column: " << name << " " << fDataFormats[i] << " " << fDataColDesc[i].unit << endl << endl;
     262                fFile->AddColumn(name, fDataFormats[i], fDataColDesc[i].unit);
     263            }
     264            if (!fFile->OpenNewTable(tableName, 100))
     265            {
     266                Close();
     267                return false;
     268            }
    211269        }
    212270
    213271        fCopyBuffer.resize(fFile->GetDataSize());
    214272//write header comments
     273
    215274        ostringstream str;
    216275        for (unsigned int i=0;i<fStandardColDesc.size();i++)
     
    240299            fFile->WriteKeyNT(str.str(), fDataColDesc[i].comment, "");
    241300        }
     301
    242302        fFile->WriteKeyNT("COMMENT", fTableDesc, "");
    243303
     
    250310            fEndMjD = Time().Mjd();
    251311        }
     312
    252313        return fFile->GetNumRows()==0 ? WriteHeaderKeys() : true;
    253314    }
    254315    catch (const CCfits::FitsException &e)
    255316    {
     317        cout << "Exception !" << endl;
    256318        fMess->Error("Opening or creating table '"+tableName+"' in '"+fileName+"': "+e.message());
    257319
     
    323385        shift += fStandardNumBytes[i];
    324386    }
    325 
    326387    try
    327388    {
     
    339400    // This is not necessary, is it?
    340401    // fFile->fTable->makeThisCurrent();
    341 
    342402    if (!fFile->AddRow())
    343403    {
     
    346406        return false;
    347407    }
    348 
    349408    if (!fFile->WriteData(fCopyBuffer))
    350409    {
     
    352411        return false;
    353412    }
    354 
    355413    const double tm = *reinterpret_cast<double*>(fStandardPointers[0]);
    356414
     
    385443    if (!fFile)
    386444        return;
    387 
    388445    if (fFile->IsOpen() && fFile->IsOwner())
    389446    {
     
    395452                          "Time when last event received");
    396453    }
    397 
    398454    if (fFile->IsOwner())
    399455    {
     
    401457            (*fNumOpenFitsFiles)--;
    402458    }
    403 
    404459    const string name = fFile->GetName();
    405 
    406460    delete fFile;
    407461    fFile = NULL;
    408 
    409462    fMess->Info("Closed: "+name);
    410 
    411463//    fMess = NULL;
    412464}
  • trunk/FACT++/src/FitsFile.cc

    r14615 r14715  
    9999        return false;
    100100    }
    101 
    102101    // fFileName = fileName;
    103102    if (!allow_open && access(filename.c_str(), F_OK)==0)
     
    106105        return false;
    107106    }
    108 
    109107    //create the FITS object
    110108    try
     
    117115        return false;
    118116    }
    119 
    120117    /*
    121118     "SIMPLE  =                    T / file does conform to FITS standard             "
     
    299296            // Go through the fTable instead as colName is empty (yes, it is !)
    300297            const map<string,CCfits::Column*> &cMap = table->column();
     298
     299            //check that the existing columns are the same as the ones we want to write
     300            for (map<string, CCfits::Column*>::const_iterator mapIt = cMap.begin(); mapIt != cMap.end(); mapIt++)
     301            {
     302                bool found = false;
     303                for (unsigned int ii=0;ii<fColNames.size();ii++)
     304                {
     305                    if (mapIt->first == fColNames[ii])
     306                    {
     307                        found = true;
     308                        if (mapIt->second->format() != fColTypes[ii])
     309                        {
     310                            Error("Column "+fColNames[ii]+" has wrong format ("+fColTypes[ii]+" vs "+mapIt->second->format()+" in file)");
     311                            return false;
     312                        }
     313                    }
     314                }
     315                if (!found)
     316                {
     317                    Error("Column "+mapIt->first+" only exist in written file");
     318                    return false;
     319                }
     320            }
     321            //now we know that all the file's columns are requested. Let's do it the other way around
     322            for (unsigned int ii=0;ii<fColNames.size();ii++)
     323            {
     324                bool found = false;
     325                for (map<string, CCfits::Column*>::const_iterator mapIt = cMap.begin(); mapIt != cMap.end(); mapIt++)
     326                {
     327                    if (fColNames[ii] == mapIt->first)
     328                    {
     329                        found = true;
     330                        if (fColTypes[ii] != mapIt->second->format())
     331                        {
     332                            Error("Column "+fColNames[ii]+" has wrong format ("+fColTypes[ii]+" vs "+mapIt->second->format()+" in file)");
     333                            return false;
     334                        }
     335                    }
     336                }
     337                if (!found)
     338                {
     339                    Error("Column "+fColNames[ii]+" only exist in requested description");
     340                    return false;
     341                }
     342            }
    301343
    302344            for (map<string,CCfits::Column*>::const_iterator cMapIt = cMap.begin();
  • trunk/FACT++/src/datalogger.cc

    r14574 r14715  
    131131    ///the converter for outputting the data according to the format
    132132    shared_ptr<Converter> fConv;
     133    ///the original format string. So that we can check if format is changing over time
     134    string format;
    133135    ///the current run number used by this subscription
    134136    int32_t runNumber;
     
    500502void DataLogger::AddService(const Service& svc)
    501503{
    502     const string& server = svc.server;
     504    const string& serverr = svc.server;
     505    //FIX in order to get rid of the '+' that sometimes makes it all the way to me
     506    string server = serverr;
     507    if (server.size() > 0 && server[0] == '+')
     508        Error("Got a service beginning with +. This is not supposed to happen");
    503509    const string& service = svc.service;
    504510    const bool isCmd = svc.iscmd;
     
    518524    if (list.find(service) != list.end())
    519525    {
    520   //      Error("Service " + server + "/" + service + " is already in the dataLogger's list... ignoring update.");
     526        if (list[service].format != svc.format)
     527        {
     528            cout << "Format has changed ! taking appropriate measures" << endl;
     529            if (list[service].nightlyFile.IsOpen())
     530            {
     531                string fileName = list[service].nightlyFile.GetName();
     532                if (fileName == "")
     533                {
     534                    cout << "Something went wrong." << endl;
     535                    return;
     536                }
     537                list[service].nightlyFile.Close();
     538                string fileNameWithoutFits = fileName.substr(0, fileName.size()-4);
     539                int counter=0;
     540                while (counter < 100)
     541                {
     542                    ostringstream newFileName;
     543                    newFileName << fileNameWithoutFits << counter << ".fits";
     544                    ifstream testStream(newFileName.str());
     545                    if (!testStream) //fileName available
     546                    {
     547                        rename(fileName.c_str(), newFileName.str().c_str());
     548                        break;
     549                    }
     550                    counter++;
     551                }
     552                if (counter==100)
     553                    Error("Tried to find a replacement file for 100 trials. Aborting");
     554                //reallocate the fits buffer...
     555                list[service].fitsBufferAllocated = false;
     556            }
     557            list[service].fConv = shared_ptr<Converter>(new Converter(Out(), svc.format));
     558            list[service].format = svc.format;
     559        }
     560        if (fDebugIsOn)
     561            Debug("Service " + server + "/" + service + " is already in the dataLogger's list... ignoring update.");
    521562        return;
    522563    }
     
    529570    list[service].server  = server;
    530571    list[service].service = service;
     572    list[service].format = svc.format;
    531573    list[service].index = servicesCounter;
    532574    fNumSubAndFitsData.numSubscriptions++;
     
    11061148    fRunNumber.back().time = time;
    11071149
    1108     ostringstream str;
    1109     str << "The new run number is: " << fRunNumber.back().runNumber;
    1110     Message(str);
    1111 
     1150    if (fDebugIsOn)
     1151    {
     1152        ostringstream str;
     1153        str << "The new run number is: " << fRunNumber.back().runNumber;
     1154        Debug(str);
     1155    }
    11121156    if (GetCurrentState() != kSM_Logging && GetCurrentState() != kSM_WaitingRun )
    11131157        return;
     
    12411285    const Time cTime(evt.GetTime());
    12421286    fQuality = evt.GetQoS();
    1243 /*    //I had strange surprises with the quality from Dim before. Double check that the value is indeed valid.
    1244     if (fQuality != kMessage &&
    1245         fQuality != kInfo &&
    1246         fQuality != kWarn &&
    1247         fQuality != kError &&
    1248         fQuality != kFatal &&
    1249         fQuality != kComment &&
    1250         fQuality != kDebug)
    1251         fQuality = kError;
    1252 */
     1287
    12531288    fMjD = cTime.Mjd() ? cTime.Mjd()-40587 : 0;
    12541289
Note: See TracChangeset for help on using the changeset viewer.