Changeset 16443 for trunk


Ignore:
Timestamp:
05/29/13 22:02:43 (11 years ago)
Author:
lyard
Message:
more tweaks to factfits
Location:
trunk
Files:
4 edited

Legend:

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

    r16418 r16443  
    633633    {
    634634        _transposedBuffer[i] = new char[_rowWidth*_numRowsPerTile];
    635         _compressedBuffer[i] = new char[_rowWidth*_numRowsPerTile + 1024*1024]; //use a bit more memory, in case the compression algorithms uses more
     635        _compressedBuffer[i] = new char[_rowWidth*_numRowsPerTile + _columns.size()]; //use a bit more memory for compression flags
    636636        if (_transposedBuffer[i] == NULL || _compressedBuffer[i] == NULL)
    637637            return false;
     
    736736    header.push_back(HeaderEntry("CHECKSUM", "'0000000000000000'  ", "Checksum for the whole HDU"));
    737737    header.push_back(HeaderEntry("DATASUM" ,  "         0"         , "Checksum for the data block"));
    738     header.push_back(HeaderEntry("EXTNAME" , "'DrsCalib'          ", "name of this binary table extension"));
     738    header.push_back(HeaderEntry("EXTNAME" , "'IntCalibration'    ", "name of this binary table extension"));
    739739    header.push_back(HeaderEntry("TTYPE1"  , "'OffsetCalibration' ", "label for field   1"));
    740740    header.push_back(HeaderEntry("TFORM1"  , "'1474560I'          ", "data format of field: 2-byte INTEGER"));
     
    10711071        setHeaderKey(HeaderEntry("TFIELDS", _columns.size(), "number of fields in each row"));
    10721072        int64_t heapSize = 0;
    1073         uint32_t compressedOffset = 0;
     1073        int64_t compressedOffset = 0;
    10741074        for (uint32_t i=0;i<_catalog.size();i++)
    10751075            for (uint32_t j=0;j<_catalog[i].size();j++)
     
    10771077                heapSize += _catalog[i][j].first;
    10781078                //set the catalog offsets to their actual values
     1079                if (compressedOffset < 0) return false;
    10791080                _catalog[i][j].second = compressedOffset;
    10801081                compressedOffset += _catalog[i][j].first;
     
    11981199        previousHuffmanSize = huffmanOutput.size();
    11991200    }
    1200     memcpy(&dest[huffmanOffset], huffmanOutput.data(), huffmanOutput.size());
    1201     return huffmanOutput.size() + huffmanOffset;
     1201    const size_t totalSize = huffmanOutput.size() + huffmanOffset;
     1202
     1203    //only copy if not larger than not-compressed size
     1204    if (totalSize < numRows*sizeOfElems*numRowElems)
     1205        memcpy(&dest[huffmanOffset], huffmanOutput.data(), huffmanOutput.size());
     1206
     1207    return totalSize;
    12021208}
    12031209
     
    17311737            for (int j=0;j<1440;j++)
    17321738            {
    1733                 int thisStartCell = reinterpret_cast<int16_t*>(&buffer[startCellOffset])[j];
     1739                const int thisStartCell = reinterpret_cast<int16_t*>(&buffer[startCellOffset])[j];
     1740                if (thisStartCell > -1)
    17341741                for (int k=0;k<numSlices;k++)
    17351742                    reinterpret_cast<int16_t*>(&buffer[dataOffset])[numSlices*j + k] -= drsCalib16[1024*j + (thisStartCell+k)%1024];
     
    17451752
    17461753    inFile.close();
    1747     outFile.close();
     1754    if (!outFile.close())
     1755    {
     1756        cout << "Something went wrong while writing the catalog: negative index" << endl;
     1757        return false;
     1758    }
     1759
    17481760    delete[] drsCalib16;
    17491761
     
    17621774
    17631775    //get a compressed reader
    1764     factfits verifyFile(fileNameOut, tableName, false);
     1776//TEMP try to copy the file too
     1777//    string copyName("/scratch/copyFile.fz");
     1778    string copyName("");
     1779    factfits verifyFile(fileNameOut, copyName, tableName, false);
    17651780
    17661781    //and the header of the compressed file
  • trunk/Mars/mcore/factfits.h

    r16418 r16443  
    2121    // Default constructor
    2222    factfits(const string& fname, const string& tableName="", bool force=false) :
    23         zfits(fname, tableName, force)
     23        zfits(fname, tableName, force),
     24        fOffsetCalibration(0),
     25        fOffsetStartCellData(0),
     26        fOffsetData(0),
     27        fNumRoi(0)
    2428    {
    2529        if (init())
     
    2933    // Alternative constructor
    3034    factfits(const string& fname, const string& fout, const string& tableName, bool force=false) :
    31         zfits(fname, fout, tableName, force)
     35        zfits(fname, fout, tableName, force),
     36        fOffsetCalibration(0),
     37        fOffsetStartCellData(0),
     38        fOffsetData(0),
     39        fNumRoi(0)
    3240    {
    3341        if (init())
     
    3543    }
    3644
    37     //
    38 #if !defined(__MARS__) && !defined(__CINT__)
    39     bool GetRow(size_t row, bool check=true)
    40 #else
    41     bool GetRowNum(size_t row, bool check=true)
    42 #endif
     45private:
     46
     47    void StageRow(size_t row, char* dest)
    4348    {
    44 #if !defined(__MARS__) && !defined(__CINT__)
    45         if (!zfits::GetRow(row, check))
    46             return false;
    47 #else
    48         if (!zfits::GetRowNum(row, check))
    49             return false;
    50 #endif
     49        zfits::StageRow(row, dest);
    5150        // This file does not contain fact data or no calibration to be applied
    52         if (fOffsetCalibration.empty())
    53             return true;
     51         if (fOffsetCalibration.empty())
     52             return;
    5453
    55         //re-get the pointer to the data to access the offsets
    56         const uint8_t offset = (row*fTable.bytes_per_row)%4;
     54         //re-get the pointer to the data to access the offsets
     55         const uint8_t offset = (row*fTable.bytes_per_row)%4;
    5756
    58         int16_t *startCell = reinterpret_cast<int16_t*>(fBufferRow.data() + offset + fOffsetStartCellData);
     57         int16_t *startCell = reinterpret_cast<int16_t*>(fBufferRow.data() + offset + fOffsetStartCellData);
     58         int16_t *data      = reinterpret_cast<int16_t*>(fBufferRow.data() + offset + fOffsetData);
    5959
    60         const Pointers::iterator dtaIt = fPointers.find("Data");
    61         if (dtaIt == fPointers.end()) return true;
    62         int16_t *data      = reinterpret_cast<int16_t*>(dtaIt->second);
    63 
    64         for (uint32_t i=0; i<1440*1024; i+=1024, startCell++)
    65         {
    66             for (uint32_t j=0; j<fNumRoi; j++, data++)
    67                 *data += fOffsetCalibration[i + (*startCell+j)%1024];
    68         }
    69 
    70         return true;
     60         for (uint32_t i=0; i<1440*1024; i+=1024, startCell++)
     61         {
     62             if ((*startCell) > -1)
     63             for (uint32_t j=0; j<fNumRoi; j++, data++)
     64                 *data += fOffsetCalibration[i + (*startCell+j)%1024];
     65         }
    7166    }
    72 
    73 private:
    7467
    7568    bool init()
     
    10497    void readDrsCalib(const string& fileName)
    10598    {
    106         zfits calib(fileName, "DrsCalib");
     99        //should not be mandatory, but improves the perfs a lot when reading not compressed, gzipped files
     100        if (!IsCompressedFITS())
     101            return;
     102
     103        zfits calib(fileName, "IntCalibration");
     104
    107105        if (calib.bad())
    108106        {
     
    119117            clear(rdstate()|ios::badbit);
    120118#ifdef __EXCEPTIONS
    121             throw runtime_error("Table 'DrsCalib' found, but not with one row as expected");
     119            throw runtime_error("Table 'IntCalibration' found, but not with one row as expected");
    122120#else
    123             gLog << ___err___ << "ERROR - Table 'DrsCalib' found, but not with one row as expected" << endl;
     121            gLog << ___err___ << "ERROR - Table 'IntCalibration' found, but not with one row as expected" << endl;
    124122            return;
    125123#endif
     
    164162    vector<int16_t> fOffsetCalibration; ///< integer values of the drs calibration used for compression
    165163
     164    size_t fOffsetStartCellData;
    166165    size_t fOffsetData;
    167     size_t fOffsetStartCellData;
    168166
    169167    uint16_t fNumRoi;
  • trunk/Mars/mcore/fits.h

    r16426 r16443  
    612612                peek();
    613613                if (eof() && !bad() && !tableName.empty())
     614                {
     615                    cout << "END OF FILE !" << endl;
    614616                    break;
    615 
     617                }
    616618                // FIXME: Set limit on memory consumption
    617619                const int rc = ReadBlock(block);
     
    741743    }
    742744
     745    virtual void WriteRowToCopyFile(size_t row)
     746    {
     747        if (row==fRow+1 && !fTable.isCompressed)
     748        {
     749            const uint8_t offset = (row*fTable.bytes_per_row)%4;
     750
     751            fChkData.add(fBufferRow);
     752            if (fCopy.is_open() && fCopy.good())
     753                fCopy.write(fBufferRow.data()+offset, fTable.bytes_per_row);
     754            if (!fCopy)
     755                clear(rdstate()|ios::badbit);
     756        }
     757        else
     758            if (fCopy.is_open())
     759                clear(rdstate()|ios::badbit);
     760    }
    743761    uint8_t ReadRow(size_t row)
    744762    {
     
    764782        StageRow(row, fBufferRow.data()+offset);
    765783
    766         if (row==fRow+1)
    767         {
    768             fChkData.add(fBufferRow);
    769             if (fCopy.is_open() && fCopy.good())
    770                 fCopy.write(fBufferRow.data()+offset, fTable.bytes_per_row);
    771             if (!fCopy)
    772                 clear(rdstate()|ios::badbit);
    773         }
    774         else
    775             if (fCopy.is_open())
    776                 clear(rdstate()|ios::badbit);
     784        WriteRowToCopyFile(row);
    777785
    778786        fRow = row;
  • trunk/Mars/mcore/zfits.h

    r16426 r16443  
    3333        fNumRowsPerTile(0),
    3434        fCurrentRow(-1),
    35         fHeapOff(0)
     35        fHeapOff(0),
     36        fTileSize(0)
    3637    {
    3738        InitCompressionReading();
     
    4748              fNumRowsPerTile(0),
    4849              fCurrentRow(-1),
    49               fHeapOff(0)
     50              fHeapOff(0),
     51              fTileSize(0)
    5052    {
    5153        InitCompressionReading();
     
    6062        fRow++;
    6163        return true;
     64    }
     65protected:
     66
     67    //  Stage the requested row to internal buffer
     68    //  Does NOT return data to users
     69    virtual void StageRow(size_t row, char* dest)
     70    {
     71        if (!fTable.isCompressed)
     72        {
     73            fits::StageRow(row, dest);
     74            return;
     75        }
     76
     77        ReadBinaryRow(row, dest);
    6278    }
    6379
     
    8298    }
    8399
    84     //  Stage the requested row to internal buffer
    85     //  Does NOT return data to users
    86     void StageRow(size_t row, char* dest)
    87     {
    88         if (!fTable.isCompressed)
    89         {
    90             fits::StageRow(row, dest);
    91             return;
    92         }
    93 
    94         ReadBinaryRow(row, dest);
    95     }
    96 
    97100    // Copy decompressed data to location requested by user
    98101    void MoveColumnDataToUserSpace(char* dest, const char* src, const Table::Column& c)
     
    118121
    119122    vector<vector<pair<int64_t, int64_t> > > fCatalog;///< Catalog, i.e. the main table that points to the compressed data.
     123    vector<size_t> fTileSize; ///< size in bytes of each compressed tile
     124    vector<vector<size_t> > fTileOffsets; ///< offset from start of tile of a given compressed column
    120125
    121126    void AllocateBuffers()
     
    127132
    128133        fTransposedBuffer.resize(fTable.bytes_per_row*fNumRowsPerTile);
    129         fCompressedBuffer.resize(fTable.bytes_per_row*fNumRowsPerTile + 1024*1024); //use a bit more memory, in case the compression algorithms uses more
     134        fCompressedBuffer.resize(fTable.bytes_per_row*fNumRowsPerTile + fTable.num_cols); //use a bit more memory for compression flags
    130135    }
    131136
     
    139144        fCatalog.resize(fNumTiles);
    140145
     146        const streampos catalogStart = tellg();
     147
     148        //do the actual reading
    141149        for (uint32_t i=0;i<fNumTiles;i++)
    142150            for (uint32_t j=0;j<fTable.num_cols;j++)
     
    147155                int64_t tempValues[2] = {0,0};
    148156                revcpy<8>(reinterpret_cast<char*>(tempValues), readBuf, 2);
    149 
     157                if (tempValues[0] < 0 || tempValues[1] < 0)
     158                {
     159#ifdef __EXCEPTIONS
     160                    throw runtime_error("ERROR: negative value in the catalog");
     161#else
     162                    gLog << ___err ___ << "ERROR: negative value in the catalog" << endl;
     163                    return;
     164#endif
     165                }
    150166                //add catalog entry
    151167                fCatalog[i].emplace_back(tempValues[0], tempValues[1]);
    152168            }
    153169
     170        //compute the total size of each compressed tile
     171        fTileSize.resize(fNumTiles);
     172        fTileOffsets.resize(fNumTiles);
     173        for (uint32_t i=0;i<fNumTiles;i++)
     174        {
     175            fTileSize[i] = 0;
     176            for (uint32_t j=0;j<fTable.num_cols;j++)
     177            {
     178                fTileSize[i] += fCatalog[i][j].first;
     179                fTileOffsets[i].emplace_back(fCatalog[i][j].second - fCatalog[i][0].second);
     180            }
     181        }
    154182        //see if there is a gap before heap data
    155183        fHeapOff = tellg()+fTable.GetHeapShift();
    156     }
    157 
     184
     185        if (!fCopy.is_open())
     186            return;
     187
     188        //write catalog and heap gap to target file
     189        seekg(catalogStart);
     190
     191        const size_t catSize = fTable.GetHeapShift() + fTable.total_bytes;
     192
     193        vector<char> buf(catSize);
     194        read(buf.data(), catSize);
     195
     196        fCopy.write(buf.data(), catSize);
     197        if (!fCopy)
     198            clear(rdstate()|ios::badbit);
     199    }
     200    //overrides fits.h method with empty one
     201    //work is done in ReadBinaryRow because it requires volatile data from ReadBinaryRow
     202    virtual void WriteRowToCopyFile(size_t )
     203    {
     204
     205    }
    158206    // Compressed versin of the read row
    159207    bool ReadBinaryRow(const size_t &rowNum, char *bufferToRead)
     
    164212        const uint32_t requestedTile = rowNum/fNumRowsPerTile;
    165213        const uint32_t currentTile   = fCurrentRow/fNumRowsPerTile;
     214        const size_t   previousRow   = fCurrentRow;
    166215
    167216        fCurrentRow = rowNum;
     
    171220        {
    172221            //read yet another chunk from the file
    173             //the size that we should read is in the catalog. we should sum up the sizes of all columns
    174             const uint32_t currentCatRow = fCurrentRow/fNumRowsPerTile;
    175 
    176             int64_t sizeToRead  = 0;
    177             for (uint32_t i=0;i<fCatalog[currentCatRow].size();i++)
    178                 sizeToRead += fCatalog[currentCatRow][i].first;
     222            const int64_t sizeToRead = fTileSize[requestedTile];
    179223
    180224            //skip to the beginning of the tile
    181             seekg(fHeapOff+fCatalog[currentCatRow][0].second);
     225            seekg(fHeapOff+fCatalog[requestedTile][0].second);
    182226            read(fCompressedBuffer.data(), sizeToRead);
    183227
     228            if (fCurrentRow == previousRow+1 &&
     229                fCopy.is_open() &&
     230                fCopy.good())
     231            {
     232                fCopy.write(fCompressedBuffer.data(), sizeToRead);
     233                if (!fCopy)
     234                    clear(rdstate()|ios::badbit);
     235            }
     236            else
     237                if (fCopy.is_open())
     238                    clear(rdstate()|ios::badbit);
     239
    184240            const uint32_t thisRoundNumRows = (GetNumRows()<fCurrentRow + fNumRowsPerTile) ? GetNumRows()%fNumRowsPerTile : fNumRowsPerTile;
    185241
    186242            //uncompress it
    187             UncompressBuffer(currentCatRow, thisRoundNumRows);
     243            UncompressBuffer(requestedTile, thisRoundNumRows);
    188244
    189245            // pointer to column (source buffer)
     
    301357
    302358            //get the compression flag
    303             const int64_t compressedOffset = fCatalog[catalogCurrentRow][i].second - fCatalog[catalogCurrentRow][0].second;
     359            const int64_t compressedOffset = fTileOffsets[catalogCurrentRow][i];//fCatalog[catalogCurrentRow][i].second - fCatalog[catalogCurrentRow][0].second;
    304360            const char    compressedFlag   = fCompressedBuffer[compressedOffset];
    305361
Note: See TracChangeset for help on using the changeset viewer.