Hi,
I am trying to compile a C++ code (not mine) initially compiled on OSX, and I am trying to get it compiled on Ubuntu (11.04). I have absolutely no experience in C++, nor am I required to learn C++ (I usually do all my coding in Python)
The person I got the code from used a "Build script" to compile the code, opf which I need to convert to a linux compatible form. I've inserted the original build script below:
rm -f *.o
g++-mp-4.4 -c -O -m64 -Dintel_osx -I/usr/local/difmap2.4k/include splitc.cc
g++-mp-4.4 -o splitc splitc.o -L/usr/local/difmap2.4k/lib -lsphere -L/usr/local/difmap2.4k/lib -llogio -L/usr/local/difmap2.4k/lib -lpager -L/usr/local/difmap2.4k/lib -lcpgplot -L/opt/local/lib -lpng -lpgplot -L/usr/X11/lib -lX11 -L/usr/local/difmap2.4k/lib -lfits -L/usr/local/difmap2.4k/lib -lrecio -L/usr/local/difmap2.4k/lib -lscrfil -L/usr/local/difmap2.4k/lib -lslalib -ltecla -lcurses /opt/local/lib/gcc44/gcc/x86_64-apple-darwin11/4.4.6/libgcc.a /System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation /System/Library/Frameworks/AppKit.framework/Versions/Current/AppKit -lm
Now here's my version for Ubuntu:
rm -f *.o
g++-4.5 -c -O -I/usr/local/uvf_difmap/include splitc.cc
g++-4.5 -o splitc splitc.o -L/usr/local/uvf_difmap/lib/libsphere -L/usr/local/uvf_difmap/lib/liblogio -L/usr/local/uvf_difmap/lib/libpager -L/usr/local/uvf_difmap/lib/libcpgplot -L/usr/lib/x86_64-linux-gnu/libpng -L/usr/lib/libpgplot -L/usr/lib/x86_64-linux-gnu/libX11 -L/usr/local/uvf_difmap/lib/libfits -L/usr/local/uvf_difmap/lib/librecio -L/usr/local/uvf_difmap/lib/libscrfil -L/usr/local/uvf_difmap/lib/libslalib -L/usr/local/uvf_difmap/libtecla -L/usr/lib/libcurses /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5/libgcc.a
Question: How do I run this "build script"? Searching on google gives me no help/information.
Since I did not know how to run the build script I decided to enter each line separately into the terminal, which did not work, but gave me the following errors:
hayden@roo:/usr/local/uvf_difmap/split_src$ sudo g++-4.5 -c -O -I/usr/local/uvf_difmap/include splitc.cc
splitc.cc: In member function ‘bool fitsfile::open()’:
splitc.cc:288:48: warning: deprecated conversion from string constant to ‘char*’
splitc.cc: In member function ‘bool fitsfile::copyHistory(fitsfile&)’:
splitc.cc:523:81: warning: deprecated conversion from string constant to ‘char*’
splitc.cc:525:68: warning: deprecated conversion from string constant to ‘char*’
And the second line:
hayden@roo:/usr/local/uvf_difmap/split_src$ sudo g++-4.5 -o splitc splitc.o -L/usr/local/uvf_difmap/lib/libsphere -L/usr/local/uvf_difmap/lib/liblogio -L/usr/local/uvf_difmap/lib/libpager -L/usr/local/uvf_difmap/lib/libcpgplot -L/usr/lib/x86_64-linux-gnu/libpng -L/usr/lib/libpgplot -L/usr/lib/x86_64-linux-gnu/libX11 -L/usr/local/uvf_difmap/lib/libfits -L/usr/local/uvf_difmap/lib/librecio -L/usr/local/uvf_difmap/lib/libscrfil -L/usr/local/uvf_difmap/lib/libslalib -L/usr/local/uvf_difmap/lib/libtecla -L/usr/lib/libcurses /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5/libgcc.a
splitc.o: In function `fitsfile::~fitsfile()':
splitc.cc:(.text+0x651): undefined reference to `del_Fits(Fits*)'
splitc.o: In function `fitsfile::init()':
splitc.cc:(.text+0x7f0): undefined reference to `find_gpar(PHdu*, char const*, int, int)'
splitc.cc:(.text+0x872): undefined reference to `find_axis(PHdu*, char const*, int, int)'
splitc.o: In function `fitsfile::closeData()':
splitc.cc:(.text+0x9d8): undefined reference to `end_data(Fits*, Hdu*)'
splitc.o: In function `fitsfile::close()':
splitc.cc:(.text+0xa14): undefined reference to `del_Fits(Fits*)'
splitc.o: In function `fitsfile::addAntennae(fitsfile&, int)':
splitc.cc:(.text+0xae8): undefined reference to `dup_Hdu(Fits*, Hdu*, Fits*)'
splitc.o: In function `fitsfile::split(fitsfile&, double)':
splitc.cc:(.text+0xe7e): undefined reference to `rgroup(Fits*, PHdu*, long, long, long, Fittype, int, char*, void*)'
splitc.cc:(.text+0xf0e): undefined reference to `rimage(Fits*, PHdu*, long, long, long, Fittype, int, char*, void*)'
splitc.cc:(.text+0xfbf): undefined reference to `get_axis(PHdu*, int)'
splitc.cc:(.text+0x11c9): undefined reference to `wgroup(Fits*, PHdu*, long, long, long, Fittype, int, char*, void*)'
splitc.cc:(.text+0x125a): undefined reference to `wimage(Fits*, PHdu*, long, long, long, Fittype, int, char*, void*)'
splitc.o: In function `fitsfile::freq()':
splitc.cc:(.text+0x136f): undefined reference to `get_axis(PHdu*, int)'
splitc.o: In function `fitsfile::open()':
splitc.cc:(.text+0x13d8): undefined reference to `del_Fits(Fits*)'
splitc.cc:(.text+0x13fe): undefined reference to `new_Fits(char const*, int, int, int, int)'
splitc.cc:(.text+0x14b2): undefined reference to `find_table(Fits*, char*, int, Hdu*)'
splitc.o: In function `fitsfile::copyHistory(fitsfile&)':
splitc.cc:(.text+0x150d): undefined reference to `new_hline(Hdu*, int)'
splitc.cc:(.text+0x1534): undefined reference to `wcomkey(Fits*, Hdu*, char*, int, char*, char*)'
splitc.cc:(.text+0x155b): undefined reference to `get_key(Fits*, Hdu*, char*, Fittype, Seektype, Fitkey*)'
splitc.o: In function `fitsfile::create(fitsfile&, int)':
splitc.cc:(.text+0x15b2): undefined reference to `del_Fits(Fits*)'
splitc.cc:(.text+0x15d8): undefined reference to `new_Fits(char const*, int, int, int, int)'
splitc.cc:(.text+0x15f6): undefined reference to `copy_Hdu(Hdu*)'
splitc.cc:(.text+0x1669): undefined reference to `add_Hdu(Fits*, Hdu*)'
splitc.cc:(.text+0x16c2): undefined reference to `end_header(Fits*, Hdu*)'
collect2: ld returned 1 exit status
Sorry for the long post, but I've exhausted all other options.
cheers,
H
Here's the code split.cc if anyone's interested.
#include <libfits.h>
#include <stdio.h>
#include <stdlib.h>
//#include <values.h>
#include <vector>
#include <string>
#include <string.h>
#include <iostream>
using namespace std;
void showProgress(int size, float fraction)
{
cout << "|";
fraction += 0.005;
int filled = (int)((float)size * fraction);
int unfilled = size - filled;
for(int i = 0; i < filled; i++)
cout << "#";
for(int i = 0; i < unfilled; i++)
cout << "-";
cout << "| ";
cout << (int)(fraction * 100.0) << "%";
for(int i = 0; i < size + 2 + 3 + ((fraction > 0.995) ? 4 : 3); i++)
cout << "\b";
cout.flush();
}
void finalizeProgress(int size)
{
cout << "Done!";
for(int i = 0; i < size + 4; i++)
cout << " ";
cout << "\n";
}
class fitsfile
{
enum
{
eUU = 0,
eVV,
eWW,
eBaseline,
eDate
} EGroup;
enum
{
eComplex = 0,
eStokes,
eFreq,
eRA,
eDec
} EAxis;
typedef struct
{
string name;
int index;
} SGroup;
typedef struct
{
string name;
int index;
int expectedSize;
int size;
} SAxis;
public:
fitsfile(string filename);
~fitsfile();
bool create(fitsfile &ref, int nGroups);
bool open();
bool isCompatibleWith(fitsfile &ref);
bool split(fitsfile &fitsin, double refFreq);
int addAntennae(fitsfile &fitsin, int startSubChan);
bool closeData();
void close();
const char * name();
int groups();
int freqs();
int stokes();
int groupSize();
int elemSize();
double freq();
protected:
bool init();
bool getPrimary();
Phdu * primary();
bool copyHistory(fitsfile &ref);
private:
string m_filename;
Fits * m_fits;
SGroup m_group[5];
SAxis m_axis[5];
Phdu * m_phdu; // Primary Header Data Unit
Thdu * m_thdu; // Primary Header Data Unit
int m_subChan;
int m_groupOfs;
};
fitsfile::fitsfile(string filename)
: m_filename(filename),
m_fits(NULL),
m_phdu(NULL),
m_thdu(NULL),
m_subChan(0),
m_groupOfs(0)
{
const string groupParNames[5] = { "UU", "VV", "WW", "BASELINE", "DATE" };
const string axisNames[5] = { "COMPLEX", "STOKES", "FREQ", "RA", "DEC" };
const int axisSize[5] = { 3, -1, -1, 1, 1 };
for(int i = 0; i < 5; i++)
{
m_group[i].name = groupParNames[i];
m_group[i].index = -1;
}
for(int i = 0; i < 5; i++)
{
m_axis[i].name = axisNames[i];
m_axis[i].index = -1;
m_axis[i].size = -1;
m_axis[i].expectedSize = axisSize[i];
}
}
fitsfile::~fitsfile()
{
if(m_fits)
{
del_Fits(m_fits);
}
m_fits = NULL;
}
bool fitsfile::create(fitsfile &ref, int nGroups)
{
if(m_fits)
{
del_Fits(m_fits);
m_fits = NULL;
}
m_fits = new_Fits(m_filename.c_str(), 0, 0, 0, 0);
if(m_fits == NULL)
{
return false;
}
m_phdu = (Phdu *)copy_Hdu((Hdu *)ref.m_phdu);
if(m_phdu == NULL)
{
cerr << "Failed to create new primary HDU.\n";
return false;
}
if(!init())
{
return false;
}
m_phdu->gcount = nGroups;
m_phdu->dims[m_axis[eFreq].index] = 1;
if(add_Hdu(m_fits, (Hdu *)m_phdu))
{
cerr << "Failed to add primary header to the FITS file.\n";
return false;
}
if(!copyHistory(ref))
{
cerr << "Failed to copy history to the FITS file.\n";
return false;
}
if(end_header(m_fits, (Hdu *)m_phdu))
{
cerr << "Failed to add primary header to the FITS file.\n";
return false;
}
return true;
}
// Check that the input file is compatible with the reference file.
bool fitsfile::isCompatibleWith(fitsfile &ref)
{
// It is expected that the dimension of the stokes axis should be the same in all input files.
if(stokes() != ref.stokes())
{
cerr << "Error: The input files have an incompatible number of stokes parameters.\n";
return false;
}
// It is also expected that the input files also have the same number of group parameters.
if(groupSize() != ref.groupSize())
{
cerr << "Error: The input files have an incompatible numbers of group parameters.\n";
return false;
}
return true;
}
bool fitsfile::init()
{
for(int group_index = 0; group_index < sizeof(m_group) / sizeof(SGroup); group_index++)
{
int ngroup = find_gpar(m_phdu, m_group[group_index].name.c_str(), m_group[group_index].name.length(), 1);
if(ngroup == 0)
{
cerr << "ERROR: Expected to find a group parameter '" << m_group[group_index].name << "'.\n";
return false;
}
ngroup--;
m_group[group_index].index = ngroup;
}
for(int axis_index = 0; axis_index < sizeof(m_axis) / sizeof(SAxis); axis_index++)
{
int naxis = find_axis(m_phdu, m_axis[axis_index].name.c_str(), m_axis[axis_index].name.length(), 1);
if(naxis == 0)
{
cerr << "ERROR: Couldn't find the axis '" << m_axis[axis_index].name << "'.\n";
return false;
}
naxis--;
if(m_axis[axis_index].expectedSize != -1 && m_axis[axis_index].expectedSize != m_phdu->dims[naxis])
{
cerr << "ERROR: Expected the axis '" << m_axis[axis_index].name;
cerr << "' to have a dimension of " << m_axis[axis_index].expectedSize;
cerr << " but actually has " << m_phdu->dims[naxis] << "\n";
return false;
}
m_axis[axis_index].index = naxis;
m_axis[axis_index].size = m_phdu->dims[naxis];
}
return true;
}
bool fitsfile::open()
{
if(m_fits)
{
del_Fits(m_fits);
m_fits = NULL;
}
m_fits = new_Fits(m_filename.c_str(), 1, 1, 0, 0);
if(m_fits == NULL)
{
return false;
}
if(!getPrimary())
{
cerr << "ERROR: Failed to find a primary header.\n";
return false;
}
if(m_phdu->naxis < 6)
{
cerr << "ERROR: Insufficient axis.\n";
return false;
}
if(m_phdu->groups == 0 || m_phdu->gcount < 5)
{
cerr << "ERROR: Insufficient group information.\n";
return false;
}
if(!init())
{
return false;
}
/* Shouldn't really care about this ...
if(m_axis[eFreq].size < 2)
{
cerr << "ERROR: Multiple frequency channels were not found so how can they be split?\n";
return false;
}*/
m_thdu = find_table(m_fits, "AIPS AN", 0, NULL);
if(m_thdu == NULL)
{
cerr << "ERROR: Could find an AIPS AN table.\n";
return false;
}
return true;
}
bool fitsfile::split(fitsfile &fitsin, double refFreq)
{
int elemsize = fitsin.elemSize();
int grpsize = fitsin.groupSize();
int ngroups = fitsin.groups();
int newelemsize = elemSize();
double *groups = new double [ngroups * grpsize];
double *elems = new double [ngroups * elemsize];
double *tempgroup = new double [grpsize];
double *tempelem = new double [newelemsize];
if(groups == NULL || elems == NULL || tempgroup == NULL || tempelem == NULL)
{
cerr << "ERROR: Insufficient memory.\n";
if(groups)
delete groups;
if(elems)
delete elems;
if(tempgroup)
delete tempgroup;
if(tempelem)
delete tempelem;
return false;
}
cout << "Reading " << ngroups * fitsin.freqs() * fitsin.stokes() << " visibilities from " << fitsin.name() << "\n";
int nGroup, nFreq;
int scale = ngroups / 50;
for(nGroup = 0; nGroup < ngroups; nGroup++)
{
// Read the group and image data for the current group.
if(rgroup(fitsin.m_fits, fitsin.m_phdu, nGroup, 0, grpsize, DAT_DBL, 1, NULL, groups + nGroup * grpsize) != grpsize)
{
cerr << "ERROR: Failed to read group data from input file.\n";
delete groups;
delete elems;
delete tempgroup;
delete tempelem;
return false;
}
if(rimage(fitsin.m_fits, fitsin.m_phdu, nGroup, 0, elemsize, DAT_DBL, 1, NULL, elems + nGroup * elemsize) != elemsize)
{
cerr << "ERROR: Failed to read image data from input file.\n";
delete groups;
delete elems;
delete tempgroup;
delete tempelem;
return false;
}
if(nGroup % scale == 0)
{
showProgress(20, (float)nGroup / (float)ngroups);
//cout << "*";
//cout.flush();
}
}
finalizeProgress(20);
// cout << "Read the equivalent of " << fitsin.groups() * fitsin.freqs() * fitsin.stokes() << " visibilities.\n";
// Get the IF for this file.
Imaxis *freqAxis = get_axis(fitsin.m_phdu, fitsin.m_axis[eFreq].index + 1);
double IFFreq = freqAxis->crval;
double IFBW = freqAxis->cdelt;
cout << "Splitting " << fitsin.freqs() << " frequency channels into sub-arrays.\n";
for(nFreq = 0; nFreq < fitsin.freqs(); nFreq++)
{
double fscale = (IFFreq + (double)nFreq * IFBW) / refFreq;
showProgress(20, (float)nFreq / (float)fitsin.freqs());
// cout << "Writing Channel Frequency = " << (IFFreq + nFreq * IFBW) / 1.0e6 << " MHz ";
// cout << "(" << fscale * 100.0 << "% of Reference) as sub-array " << m_subChan + 1 << ".\n";
for(nGroup = 0; nGroup < ngroups; nGroup++)
{
memcpy(tempgroup, groups + nGroup * grpsize, sizeof(double) * grpsize);
memcpy(tempelem, elems + nGroup * elemsize + nFreq * newelemsize, sizeof(double) * newelemsize);
// Set up the sub-array number and date for the next frequency channel.
tempgroup[m_group[eBaseline].index] += (double)m_subChan / 100.0;
// For some reason the AIPS examples I have seem to add sub-chan*5 to
// each of the times stamps. Initially this was included but I have also
// tried experiments without this factor and the output was still OK. So
// for now I am now longer included this "fudge".
// tempgroup[m_group[eDate].index] += (double)m_subChan * 5.0;
tempgroup[m_group[eUU].index] *= fscale;
tempgroup[m_group[eVV].index] *= fscale;
tempgroup[m_group[eWW].index] *= fscale;
// Write the group and image data for the current group of the current sub-array.
if(wgroup(m_fits, m_phdu, m_groupOfs /*m_subChan * ngroups*/ + nGroup, 0, grpsize, DAT_DBL, 1, NULL, tempgroup) != grpsize)
{
cerr << "ERROR: Failed to write group data to output file.\n";
delete groups;
delete elems;
delete tempgroup;
delete tempelem;
return false;
}
if(wimage(m_fits, m_phdu, m_groupOfs /*m_subChan * ngroups*/ + nGroup, 0, newelemsize, DAT_DBL, 1, NULL, tempelem) != newelemsize)
{
cerr << "ERROR: Failed to write image data to output file.\n";
delete groups;
delete elems;
delete tempgroup;
delete tempelem;
return false;
}
}
m_subChan++;
m_groupOfs += ngroups;
}
finalizeProgress(20);
delete groups;
delete elems;
delete tempgroup;
delete tempelem;
return true;
}
bool fitsfile::closeData()
{
if(end_data(m_fits, (Hdu *)m_phdu) != 0)
{
cerr << "ERROR: Failed to close data section of primary HDU.\n";
return false;
}
return true;
}
void fitsfile::close()
{
if(m_fits != NULL)
{
del_Fits(m_fits);
m_fits = NULL;
m_phdu = NULL;
m_thdu = NULL;
}
}
int fitsfile::addAntennae(fitsfile &fitsin, int startSubChan)
{
cout << "Creating AIPS AN Tables for sub-arrays " << startSubChan + 1 << " - " << startSubChan + fitsin.freqs() << "\n";
// Duplicate the AIPS AN table once for each sub-array created for
// the input file (ie. the No. of original channels).
for(int nSub = startSubChan + 1; nSub < startSubChan + fitsin.freqs() + 1; nSub++)
{
Hdu *anhdu = dup_Hdu(fitsin.m_fits, (Hdu *)(fitsin.m_thdu), m_fits);
anhdu->extver = nSub;
if(anhdu == NULL)
{
cerr << "ERROR: Failed to create new AIPS AN table.\n";
return -1;
}
}
return startSubChan + fitsin.freqs();
}
const char *fitsfile::name()
{
return m_filename.c_str();
}
int fitsfile::groups()
{
return m_phdu ? m_phdu->gcount : 0;
}
int fitsfile::freqs()
{
return m_axis[eFreq].size;
}
int fitsfile::stokes()
{
return m_axis[eStokes].size;
}
int fitsfile::groupSize()
{
return m_phdu->pcount;
}
int fitsfile::elemSize()
{
int elemsize = 1;
for(int i = 1; i < m_phdu->naxis; i++)
elemsize *= m_phdu->dims[i];
return elemsize;
}
double fitsfile::freq()
{
Imaxis *freqAxis;
freqAxis = get_axis(m_phdu, m_axis[eFreq].index + 1);
return freqAxis->crval;
}
bool fitsfile::getPrimary()
{
m_phdu = NULL;
Hdu *hdu = NULL;
if(m_fits == NULL)
return false;
for(hdu = m_fits->hdu; hdu != NULL; hdu = hdu->next)
{
if(hdu->type == F_PRIMARY)
{
m_phdu = (Phdu *)hdu;
return true;
}
}
return false;
}
bool fitsfile::copyHistory(fitsfile &ref)
{
Fitkey key; // Keyword value pair returned by get_key()
// Rewind to the first line of the primary HDU.
new_hline((Hdu *)ref.m_phdu, 0);
// Read and record one history line at a time.
while(get_key(ref.m_fits, (Hdu *)ref.m_phdu, "HISTORY", DAT_COM, EOH_SEEK, &key) == KEY_FOUND)
{
if(wcomkey(m_fits, (Hdu *)m_phdu, "HISTORY", 0, KEYSTR(key), NULL) != 0)
return false;
}
return true;
}
int main(int argc, char *argv[])
{
vector<fitsfile> fitsin;
vector<fitsfile> fitsout;
for(int i = 1; i < argc; i++)
{
if(strcmp(argv[i], "-o") == 0)
{
if(i + 1 < argc)
{
fitsout.push_back(fitsfile(argv[++i]));
}
}
else
{
fitsin.push_back(fitsfile(argv[i]));
}
}
if(fitsout.size() != 1 || fitsin.size() == 0)
{
cout << "Usage " << argv[0] << "input-fits-file1[ ... input-fits-fileN] -o output-fits-file\n";
return 1;
}
cout << "Using " << fitsin[0].name() << " as the reference data set.\n";
// Open all of the input files and calculate the number of
// groups in the new file assuming that all frequency
// channels are to be converted to sub-channels.
int nGroups = 0;
for(int i = 0; i < fitsin.size(); i++)
{
if(!fitsin[i].open())
{
cerr << "ERROR: Failed to open " << fitsin[i].name();
return 1;
}
if(i > 0)
{
if(!fitsin[i].isCompatibleWith(fitsin[0]))
{
cerr << "ERROR: The dimensions of " << fitsin[i].name() << " is not compatible with " << fitsin[0].name() << ".\n";
return 1;
}
}
nGroups += fitsin[i].groups() * fitsin[i].freqs();
}
// Create the new fits file.
fitsout[0].create(fitsin[0], nGroups);
// Get the reference frequency
double refFreq = fitsin[0].freq();
cout << "Reference frequency = " << refFreq / 1.0e6 << " MHz.\n\n";
for(int i = 0; i < fitsin.size(); i++)
{
if(!fitsout[0].split(fitsin[i], refFreq))
{
cerr << "ERROR: Failed to split frequency channels into sub-arrarys.\n";
return 1;
}
}
fitsout[0].closeData();
int nSubChan = 0;
for(int i = 0; i < fitsin.size(); i++)
{
nSubChan = fitsout[0].addAntennae(fitsin[i], nSubChan);
if(nSubChan == -1)
{
return 1;
}
}
fitsout[0].close();
cout << "\nA total of " << nGroups * fitsin[0].stokes() << " visibilities were written.\n\n";
return 0;
}