1511 if (!conf.DoParse(argc, argv,
printHelp))
1515 string fileNameIn =
"";
1516 string fileNameOut =
"";
1517 string drsFileName =
"";
1518 uint32_t numRowsPerTile = 100;
1519 bool displayText=
true;
1522 if (conf.Get<
bool>(
"quiet")) displayText =
false;
1523 const vector<string> inputFileNameVec = conf.Vec<
string>(
"inputFile");
1524 if (inputFileNameVec.size() != 1)
1527 if (inputFileNameVec.size() == 0) cout <<
"no";
1528 else cout << inputFileNameVec.size();
1529 cout <<
" input file(s) given. Expected one. Aborting. Input:" << endl;;
1530 for (
unsigned int i=0;
i<inputFileNameVec.size();
i++)
1531 cout << inputFileNameVec[
i] << endl;
1536 fileNameIn = inputFileNameVec[0];
1539 if (conf.Has(
"drs")) drsFileName = conf.Get<
string>(
"drs");
1542 bool verifyDataPlease =
false;
1543 if (conf.Has(
"verify")) verifyDataPlease = conf.Get<
bool>(
"verify");
1547 if (conf.Has(
"output"))
1548 fileNameOut = conf.Get<
string>(
"output");
1551 size_t pos = fileNameIn.find(
".fits");
1552 if (pos == string::npos)
1554 cout <<
"ERROR: input file does not seems ot be fits. Aborting." << endl;
1557 fileNameOut = fileNameIn +
".fz";
1562 const vector<string> columnsCompression = conf.Vec<
string>(
"compression");
1565 vector<std::pair<string, string>> compressions;
1566 for (
unsigned int i=0;
i<columnsCompression.size();
i++)
1568 size_t pos = columnsCompression[
i].find_first_of(
"=");
1569 if (pos == string::npos)
1571 cout <<
"ERROR: Something wrong occured while parsing " << columnsCompression[
i] <<
". Aborting." << endl;
1574 string comp = columnsCompression[
i].substr(pos+1);
1575 if (comp !=
"UNCOMPRESSED" && comp !=
"AMPLITUDE" && comp !=
"HUFFMAN" &&
1576 comp !=
"SMOOTHMAN" && comp !=
"INT_WAVELET")
1578 cout <<
"Unkown compression scheme requested (" << comp <<
"). Aborting." << endl;
1581 compressions.push_back(make_pair(columnsCompression[
i].substr(0, pos), comp));
1585 if (conf.Has(
"rowPerTile")) numRowsPerTile = conf.Get<
unsigned int>(
"rowPerTile");
1594 if (inFile.IsCompressedFITS())
1596 cout <<
"ERROR: input file is already a compressed fits. Cannot be compressed again: Aborting." << endl;
1601 uint32_t originalNumRows = inFile.GetNumRows();
1602 uint32_t numTiles = (originalNumRows%numRowsPerTile) ? (originalNumRows/numRowsPerTile)+1 : originalNumRows/numRowsPerTile;
1606 unsigned int numThreads = 1;
1607 if (conf.Has(
"threads"))
1609 numThreads = conf.Get<
unsigned int>(
"threads");
1610 outFile.setNumWorkingThreads(numThreads);
1613 if (!outFile.open(fileNameOut))
1615 cout <<
"Error: could not open " << fileNameOut <<
" for writing" << endl;
1622 if (drsFileName !=
"")
1626 drsFile =
new factfits(drsFileName);
1630 cout <<
"Error: could not open " << drsFileName <<
" for calibration" << endl;
1638 cout <<
"**********************" << endl;
1639 cout <<
"Will compress from : " << fileNameIn << endl;
1640 cout <<
"to : " << fileNameOut << endl;
1641 if (drsFileName !=
"")
1642 cout <<
"while calibrating with: " << drsFileName << endl;
1643 cout <<
"Compression will use : " << numThreads <<
" worker threads" << endl;
1644 cout <<
"Data will be verified : ";
1645 if (verifyDataPlease)
1646 cout <<
"yes" << endl;
1648 cout <<
"no (WARNING !)" << endl;
1649 cout <<
"**********************" << endl;
1658 uint32_t rowWidth = inFile.GetUInt(
"NAXIS1");
1659 char*
buffer =
new char[rowWidth + 12];
1660 memset(buffer, 0, 4);
1667 cout <<
"Input file has " << columns.size() <<
" columns and " << inFile.GetNumRows() <<
" rows" << endl;
1670 uint32_t totalRowWidth = 0;
1671 for (uint32_t
i=0;
i<sortedColumns.size();
i++)
1675 str <<
"TTYPE" <<
i+1;
1676 string colName = inFile.GetStr(str.str());
1679 cout <<
"Column " << colName;
1680 for (uint32_t j=colName.size();j<21;j++)
1688 vector<uint16_t> rawProcessings(1);
1690 vector<uint16_t> smoothmanProcessings(2);
1695 totalRowWidth += sortedColumns[
i].bytes;
1698 bool explicitRequest =
false;
1699 for (
unsigned int j=0;j<compressions.size();j++)
1701 if (compressions[j].
first == colName)
1703 explicitRequest =
true;
1704 if (displayText) cout << compressions[j].second << endl;
1705 if (compressions[j].
second ==
"UNCOMPRESSED")
1707 if (compressions[j].
second ==
"SMOOTHMAN")
1713 if (explicitRequest)
continue;
1715 if (colName !=
"Data")
1717 if (displayText) cout <<
"UNCOMPRESSED" << endl;
1722 if (displayText) cout <<
"SMOOTHMAN" << endl;
1729 for (fits::Table::Keys::const_iterator i=header.begin(); i!= header.end(); i++)
1731 string k = i->first;
1732 if (k ==
"XTENSION" || k ==
"BITPIX" || k ==
"PCOUNT" || k ==
"GCOUNT" || k ==
"TFIELDS")
1734 if (k ==
"CHECKSUM")
1745 if (k ==
"TTYPE" || k ==
"TFORM")
1747 string tmpKey = i->second.fitsString;
1749 outFile.setHeaderKey(tmpKey);
1754 outFile.setHeaderKey(i->second.fitsString);
1761 int16_t* drsCalib16 = NULL;
1764 int32_t startCellOffset = -1;
1765 if (drsFileName !=
"")
1767 drsCalib16 =
new int16_t[1440*1024];
1768 float* drsCalibFloat = NULL;
1771 drsCalibFloat =
reinterpret_cast<float*
>(drsFile->
SetPtrAddress(
"BaselineMean"));
1775 cout <<
"Could not find column BaselineMean in drs calibration file " << drsFileName <<
". Aborting" << endl;
1781 for (uint32_t i=0;i<1440*1024;i++)
1782 drsCalib16[i] = (int16_t)(drsCalibFloat[
i]*4096.f/2000.f);
1786 for (fits::Table::Columns::const_iterator it=columns.begin(); it!= columns.end(); it++)
1787 if (it->first ==
"StartCellData")
1789 startCellOffset = it->second.offset;
1790 if (it->second.type !=
'I')
1792 cout <<
"Wrong type for the StartCellData Column: " << it->second.type <<
" instead of I expected"<< endl;
1797 if (startCellOffset == -1)
1799 cout <<
"WARNING: Could not find StartCellData in input file " << fileNameIn <<
". Doing it uncalibrated"<< endl;
1804 outFile.setDrsCalib(drsCalib16);
1812 if (displayText) cout <<
"Converting file..." << endl;
1815 int32_t dataOffset = -1;
1818 for (fits::Table::Columns::const_iterator it=columns.begin(); it!= columns.end(); it++)
1819 if (it->first ==
"Data")
1821 numSlices = it->second.num;
1822 dataOffset = it->second.offset;
1824 if (numSlices % 1440 != 0)
1826 cout <<
"seems like the number of samples is not a multiple of 1440. Aborting." << endl;
1829 if (dataOffset == -1)
1831 cout <<
"Could not find the column Data in the input file. Aborting." << endl;
1838 vector<void*> readPointers;
1839 vector<int32_t> readOffsets;
1840 vector<int32_t> readElemSize;
1841 vector<int32_t> readNumElems;
1842 for (fits::Table::Columns::const_iterator it=columns.begin(); it!= columns.end(); it++)
1844 readPointers.push_back(inFile.SetPtrAddress(it->first));
1845 readOffsets.push_back(it->second.offset);
1846 readElemSize.push_back(it->second.size);
1847 readNumElems.push_back(it->second.num);
1852 ostringstream wrongChannels;
1853 map<int, int> wrongChannelsMap;
1854 map<int, int> wrongChannelsLastValues;
1855 for (uint32_t i=0;i<1440;i++)
1857 wrongChannelsMap[
i] = 0;
1858 wrongChannelsLastValues[
i] = 0;
1860 for (uint32_t i=0;i<inFile.GetNumRows();i++)
1862 if (displayText) cout <<
"\r Row " << i+1 << flush;
1863 if (!inFile.GetNextRow())
1865 cout <<
"ERROR: file has less rows than advertized. aborting" << endl;
1870 for (fits::Table::Columns::const_iterator it=columns.begin(); it!= columns.end();it++)
1872 memcpy(&buffer[readOffsets[count]], readPointers[count], readElemSize[count]*readNumElems[count]);
1876 char* checkSumPointer =
buffer;
1877 const int chkOffset = (i*totalRowWidth)%4;
1878 checkSumPointer -= chkOffset;
1879 uint32_t sizeToChecksum = totalRowWidth + chkOffset;
1880 if (sizeToChecksum%4 != 0)
1882 int32_t extraBytes = 4 - (sizeToChecksum%4);
1883 memset(checkSumPointer+sizeToChecksum, 0, extraBytes);
1884 sizeToChecksum += extraBytes;
1886 rawsum.
add(checkSumPointer, sizeToChecksum,
false);
1888 if (startCellOffset != -1)
1890 for (
int j=0;j<1440;j++)
1892 const int thisStartCell =
reinterpret_cast<int16_t*
>(&buffer[startCellOffset])[j];
1893 if (thisStartCell > 1023)
1895 wrongChannelsMap[j]++;
1896 wrongChannelsLastValues[j] = thisStartCell;
1899 if (thisStartCell < 0)
continue;
1900 for (
int k=0;k<numSlices;k++)
1901 reinterpret_cast<int16_t*>(&buffer[dataOffset])[numSlices*j + k] -= drsCalib16[1024*j + (thisStartCell+k)%1024];
1904 outFile.writeBinaryRow(buffer);
1907 if (wrongChannels.str() !=
"")
1909 cout <<
"ERROR: Wrong channels: ";
1910 for (uint32_t i=0;i<1440;i++)
1912 if (wrongChannelsMap[i] != 0)
1913 cout << i <<
"(" << wrongChannelsMap[
i] <<
"|" << wrongChannelsLastValues[
i] <<
") ";
1918 ostringstream strSum;
1919 strSum << rawsum.
val();
1923 string tableName = inFile.GetStr(
"EXTNAME");
1925 if (displayText) cout << endl <<
"Done. Flushing output file..." << endl;
1928 if (!outFile.close())
1930 cout <<
"Something went wrong while writing the catalog: negative index" << endl;
1934 if (drsCalib16 != NULL)
1935 delete[] drsCalib16;
1937 if (displayText) cout <<
"Done." << endl;
1943 if (verifyDataPlease)
1945 if (displayText) cout <<
"Now verify data..." << endl;
1954 string copyName(
"");
1955 factfits verifyFile(fileNameOut, copyName, tableName,
false);
1961 ofits reconstructedFile;
1964 string reconstructedName = fileNameOut+
".recons";
1965 reconstructedName =
"/dev/null";
1966 reconstructedFile.
open(reconstructedName.c_str(),
false);
1969 string origChecksumStr;
1980 for (fits::Table::Keys::const_iterator it=header2.begin(); it!= header2.end(); it++)
1982 string k = it->first;
1983 if (k ==
"XTENSION" || k ==
"BITPIX" || k ==
"PCOUNT" || k ==
"GCOUNT" ||
1984 k ==
"TFIELDS" || k ==
"ZTABLE" || k ==
"ZNAXIS1" || k ==
"ZNAXIS2" ||
1985 k ==
"ZHEAPPTR" || k ==
"ZPCOUNT" || k ==
"ZTILELEN" || k ==
"THEAP" ||
1986 k ==
"CHECKSUM" || k ==
"DATASUM" || k ==
"FCTCPVER" || k ==
"ZHEAP")
1993 reconstructedFile.
SetKeyComment(
"CHECKSUM", it->second.comment);
1994 origChecksumStr = it->second.value;
2004 reconstructedFile.
SetKeyComment(
"DATASUM", it->second.comment);
2005 origDatasum = it->second.value;
2011 tableName = it->second.value;
2022 if (k ==
"TFORM" || k ==
"NAXIS" || k ==
"ZCTYP" )
2027 if (k ==
"ZFORM" || k ==
"ZTYPE")
2029 string tmpKey = it->second.fitsString;
2031 reconstructedFile.SetKeyFromFitsString(tmpKey);
2035 reconstructedFile.SetKeyFromFitsString(it->second.fitsString);
2038 if (tableName ==
"")
2040 cout <<
"Error: table name from file " << fileNameOut <<
" could not be found. Aborting" << endl;
2045 for (uint32_t numCol=1; numCol<10000; numCol++)
2049 if (!verifyFile.HasKey(
"TTYPE"+str.str()))
break;
2051 string ttype = verifyFile.GetStr(
"TTYPE"+str.str());
2052 string tform = verifyFile.GetStr(
"ZFORM"+str.str());
2053 char type = tform[tform.size()-1];
2054 string number = tform.substr(0, tform.size()-1);
2055 int numElems = atoi(number.c_str());
2057 if (number ==
"") numElems=1;
2059 reconstructedFile.
AddColumn(numElems, type, ttype,
"",
"",
false);
2069 readPointers.clear();
2070 readOffsets.clear();
2071 readElemSize.clear();
2072 readNumElems.clear();
2073 for (fits::Table::Columns::const_iterator it=columns.begin(); it!= columns.end(); it++)
2075 readPointers.push_back(verifyFile.SetPtrAddress(it->first));
2076 readOffsets.push_back(it->second.offset);
2077 readElemSize.push_back(it->second.size);
2078 readNumElems.push_back(it->second.num);
2083 while (i<=verifyFile.GetNumRows() && verifyFile.GetNextRow())
2086 for (fits::Table::Columns::const_iterator it=columns.begin(); it!= columns.end();it++)
2088 memcpy(&buffer[readOffsets[count]], readPointers[count], readElemSize[count]*readNumElems[count]);
2091 if (displayText) cout <<
"\r Row " << i << flush;
2092 reconstructedFile.
WriteRow(buffer, rowWidth);
2096 if (displayText) cout << endl;
2101 if (!verifyFile.IsFileOk())
2102 cout <<
"ERROR: file checksums seems wrong" << endl;
2104 if (!reconstructedFile.
close())
2106 cout <<
"ERROR: disk probably full..." << endl;
2111 std::pair<string, int> origChecksum = make_pair(origChecksumStr, atoi(origDatasum.c_str()));
2112 std::pair<string, int> newChecksum = reconstructedFile.
GetChecksumData();
2115 if (origChecksum.second != newChecksum.second)
2117 cout <<
"ERROR: datasums are NOT identical: " << (uint32_t)(origChecksum.second) <<
" vs " << (uint32_t)(newChecksum.second) << endl;
2120 if (origChecksum.first != newChecksum.first)
2122 cout <<
"WARNING: checksums are NOT Identical: " << origChecksum.first <<
" vs " << newChecksum.first << endl;
2126 if (
true) cout <<
"Ok" << endl;
std::vector< Column > SortedColumns
void * SetPtrAddress(const std::string &name)
std::map< std::string, Column > Columns
std::pair< std::string, int > GetChecksumData()
int64_t second
offset of this column in the tile, from the start of the heap area
bool SetKeyComment(const std::string &key, const std::string &comment)
virtual bool AddColumn(uint32_t cnt, char typechar, const std::string &name, const std::string &unit, const std::string &comment="", bool addHeaderKeys=true)
int64_t first
Size of this column in the tile.
BlockHeader(uint64_t s=0, char o=kOrderByRow, unsigned char n=1)
bool GetNextRow(bool check=true)
virtual void open(const char *filename, bool addEXTNAMEKey=true)
std::map< std::string, Entry > Keys
Commandline parsing, resource file parsing and database access.
void setupConfiguration(Configuration &conf)
virtual bool WriteTableHeader(const char *name="DATA")
bool add(const char *buf, size_t len, bool big_endian=true)
virtual bool WriteRow(const void *ptr, size_t cnt, bool byte_swap=true)