// ----------------------------------------------------------------------- // columns.cc: Define a set of columns for Duchamp output. // ----------------------------------------------------------------------- // Copyright (C) 2006, Matthew Whiting, ATNF // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. // // Duchamp is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License // along with Duchamp; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA // // Correspondence concerning Duchamp may be directed to: // Internet email: Matthew.Whiting [at] atnf.csiro.au // Postal address: Dr. Matthew Whiting // Australia Telescope National Facility, CSIRO // PO Box 76 // Epping NSW 1710 // AUSTRALIA // ----------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include namespace duchamp { namespace Column { Col::Col() { /// @brief Set the default values for the parameters. this->width=1; this->precision=0; this->name=" "; this->units=" "; this->type=UNKNOWN; } Col::~Col(){} Col::Col(const Col& c) { operator=(c); } Col& Col::operator=(const Col& c) { if(this==&c) return *this; this->width = c.width; this->precision = c.precision; this->name = c.name; this->units = c.units; this->type = c.type; return *this; } Col::Col(int num, int prec) { /// A specialised constructor that defines one of the default /// columns, as defined in the Column namespace /// \param num The number of the column to be constructed. /// Corresponds to the order of the columns in the const /// arrays in the Column namespace. /// \param prec The precision to use, if not the default. A value /// <0 or no value given results in the default being used. if((num>=0)&&(numwidth = defaultWidth[num]; if(prec<0) this->precision = defaultPrec[num]; else this->precision = prec; this->name = defaultName[num]; this->units = defaultUnits[num]; this->type = COLNAME(num); } else{ std::stringstream errmsg; errmsg << "Incorrect value for Col(num) --> num="<width = 1; this->precision = 0; this->name = " "; this->units = " "; this->type=UNKNOWN; } } Col::Col(std::string name, std::string units, int width, int prec) { /// A generic constructor designed to make a Column other than /// the predefined ones listed in the Column namespace /// \param name The title of the column /// \param units What units the column takes /// \param width The starting width /// \param prec The starting precision this->width = width; this->precision = prec; this->name = name; this->units = units; this->type = UNKNOWN; } //------------------------------------------------------------ void Col::changePrec(int p) { /// A direct way to alter the precision without having to use /// Col::upPrec(). If the precision increases, the width will /// increase by the same amount. If it decreases, no change is /// made to the width. /// \param p The new precision value. if(p > this->precision) this->width += (p-this->precision); this->precision = p; } //------------------------------------------------------------ void Col::printTitle(std::ostream &stream) { stream << std::setw(this->width) << std::setfill(' ') << this->name; } void Col::printUnits(std::ostream &stream) { stream << std::setw(this->width) << std::setfill(' ') << this->units; } void Col::printDash (std::ostream &stream) { stream << std::setw(this->width) << std::setfill('-') << "" << std::setfill(' '); } void Col::printBlank(std::ostream &stream) { stream << std::setw(this->width) << std::setfill(' ') << ""; } template void Col::printEntry(std::ostream &stream, T value) { /// \param stream Where the printing is done. /// \param value The value to be printed. stream << std::setprecision(this->precision) << std::setw(this->width) << std::setfill(' ') << value; } template void Col::printEntry(std::ostream &stream, int value); template void Col::printEntry(std::ostream &stream, long value); template void Col::printEntry(std::ostream &stream, unsigned value); template void Col::printEntry(std::ostream &stream, float value); template void Col::printEntry(std::ostream &stream, double value); template void Col::printEntry(std::ostream &stream, std::string value); bool Col::doCol(std::string tableType, bool flagFint) { /// @details Uses the info in the isFile etc arrays to /// determine whether a given column, referenced by the /// enumeration COLNAME, is used for a given table type. /// \param tableType The type of table: one of file, screen, log, votable. /// \param flagFint Whether to use FINT (true) or FTOT /// (false). This defaults to true, so need not be given. It only /// applies to the screen and votable cases -- both are written for the /// results file case. /// \return True if column is used for given table type. False /// otherwise. False if tableType not one of four listed. if(tableType == "file") return isFile[this->type]; else if(tableType == "screen"){ if(flagFint && this->type==FTOT) return false; if(!flagFint && this->type==FINT) return false; return isScreen[this->type]; } else if(tableType == "log") return isLog[this->type]; else if(tableType == "votable"){ if(flagFint && this->type==FTOT) return false; if(!flagFint && this->type==FINT) return false; return isVOTable[this->type]; } else return false; } std::vector getFullColSet(std::vector &objectList, FitsHeader &head) { /// @details A function that returns a std::vector of Col /// objects containing information on the columns necessary for /// output to the results file: /// Obj#,NAME,X,Y,Z,RA,DEC,VEL,w_RA,w_DEC,w_VEL,F_tot,F_int,F_peak, /// X1,X2,Y1,Y2,Z1,Z2,Npix,Flag, /// XAV,YAV,ZAV,XCENT,YCENT,ZCENT,XPEAK,YPEAK,ZPEAK /// /// Each object in the provided objectList is checked to see if it /// requires any column to be widened, or for that column to have /// its precision increased. /// /// Both Ftot and Fint are provided -- it is up to the calling /// function to determine which to use. /// /// \param objectList A std::vector list of Detection objects that the /// columns need to fit. /// \param head The FitsHeader object defining the World Coordinate /// System. /// \return A std::vector list of Col definitions. std::vector newset; // desired precisions for fluxes, velocities and SNR value int precVel,precFlux,precSNR; if(objectList.size()>0){ precVel=objectList[0].getVelPrec(); precFlux=objectList[0].getFpeakPrec(); // same as FintPrec at this point. precSNR=objectList[0].getSNRPrec(); } else { precVel = prVEL; precFlux = prFLUX; precSNR = prSNR; } // set up the default columns newset.push_back( Col(NUM) ); newset.push_back( Col(NAME) ); newset.push_back( Col(X) ); newset.push_back( Col(Y) ); newset.push_back( Col(Z) ); newset.push_back( Col(RA) ); newset.push_back( Col(DEC) ); newset.push_back( Col(RAJD) ); newset.push_back( Col(DECJD) ); newset.push_back( Col(VEL, precVel) ); newset.push_back( Col(WRA) ); newset.push_back( Col(WDEC) ); newset.push_back( Col(W50, precVel) ); newset.push_back( Col(W20, precVel) ); newset.push_back( Col(WVEL, precVel) ); newset.push_back( Col(FINT, precFlux) ); newset.push_back( Col(FTOT, precFlux) ); newset.push_back( Col(FPEAK, precFlux) ); newset.push_back( Col(SNRPEAK, precSNR) ); newset.push_back( Col(X1) ); newset.push_back( Col(X2) ); newset.push_back( Col(Y1) ); newset.push_back( Col(Y2) ); newset.push_back( Col(Z1) ); newset.push_back( Col(Z2) ); newset.push_back( Col(NPIX) ); newset.push_back( Col(FLAG) ); newset.push_back( Col(XAV) ); newset.push_back( Col(YAV) ); newset.push_back( Col(ZAV) ); newset.push_back( Col(XCENT) ); newset.push_back( Col(YCENT) ); newset.push_back( Col(ZCENT) ); newset.push_back( Col(XPEAK) ); newset.push_back( Col(YPEAK) ); newset.push_back( Col(ZPEAK) ); // Now test each object against each new column for( unsigned int obj = 0; obj < objectList.size(); obj++){ std::string tempstr; int tempwidth; float val,minval; // Obj# tempwidth = int( log10(objectList[obj].getID()) + 1) + 1; for(int i=newset[NUM].getWidth();i0.)){ minval = pow(10, -1. * (newset[X].getPrecision()+1)); if(val < minval) newset[X].upPrec(); } tempwidth = int( log10(val) + 1) + newset[X].getPrecision() + 2; for(int i=newset[X].getWidth();i0.)){ minval = pow(10, -1. * (newset[Y].getPrecision()+1)); if(val < minval) newset[Y].upPrec(); } tempwidth = int( log10(val) + 1) + newset[Y].getPrecision() + 2; for(int i=newset[Y].getWidth();i0.)){ minval = pow(10, -1. * (newset[Z].getPrecision()+1)); if((val>0.)&&(val < minval)) newset[Z].upPrec(); } tempwidth = int( log10(val) + 1) + newset[Z].getPrecision() + 2; for(int i=newset[Z].getWidth();i0) newset[VEL].setUnits("[" + head.getSpectralUnits() + "]"); tempwidth = newset[VEL].getUnits().size() + 1; for(int i=newset[VEL].getWidth();i0.)){ minval = pow(10, -1. * (newset[VEL].getPrecision()+1)); if(val < minval) newset[VEL].upPrec(); } tempwidth = int(log10(fabs(val)) + 1) + newset[VEL].getPrecision() + 2; if(val<0) tempwidth++; for(int i=newset[VEL].getWidth();i0.)){ minval = pow(10, -1. * (newset[WRA].getPrecision()+1)); if(val < minval) newset[WRA].upPrec(); } tempwidth = int( log10(fabs(val)) + 1) + newset[WRA].getPrecision() + 2; if(val<0) tempwidth++; for(int i=newset[WRA].getWidth();i0.)){ minval = pow(10, -1. * (newset[WDEC].getPrecision()+1)); if(val < minval) newset[WDEC].upPrec(); } tempwidth = int( log10(fabs(val)) + 1) + newset[WDEC].getPrecision() + 2; if(val<0) tempwidth++; for(int i=newset[WDEC].getWidth();i0) newset[W50].setUnits("[" + head.getSpectralUnits() + "]"); tempwidth = newset[W50].getUnits().size() + 1; for(int i=newset[W50].getWidth();i0.)){ minval = pow(10, -1. * (newset[W50].getPrecision()+1)); if(val < minval) newset[W50].upPrec(); } tempwidth = int( log10(fabs(val)) + 1) + newset[W50].getPrecision() + 2; if(val<0) tempwidth++; for(int i=newset[W50].getWidth();i0) newset[W20].setUnits("[" + head.getSpectralUnits() + "]"); tempwidth = newset[W20].getUnits().size() + 1; for(int i=newset[W20].getWidth();i0.)){ minval = pow(10, -1. * (newset[W20].getPrecision()+1)); if(val < minval) newset[W20].upPrec(); } tempwidth = int( log10(fabs(val)) + 1) + newset[W20].getPrecision() + 2; if(val<0) tempwidth++; for(int i=newset[W20].getWidth();i0) newset[WVEL].setUnits("[" + head.getSpectralUnits() + "]"); tempwidth = newset[WVEL].getUnits().size() + 1; for(int i=newset[WVEL].getWidth();i0.)){ minval = pow(10, -1. * (newset[WVEL].getPrecision()+1)); if(val < minval) newset[WVEL].upPrec(); } tempwidth = int( log10(fabs(val)) + 1) + newset[WVEL].getPrecision() + 2; if(val<0) tempwidth++; for(int i=newset[WVEL].getWidth();i0) newset[FINT].setUnits("[" + head.getIntFluxUnits() + "]"); tempwidth = newset[FINT].getUnits().size() + 1; for(int i=newset[FINT].getWidth();i0.) ){ int minprec = int(fabs(log10(fabs(val))))+2; for(int i=newset[FINT].getPrecision();i0.) ){ int minprec = int(fabs(log10(fabs(val))))+2; for(int i=newset[FTOT].getPrecision();i0.) ){ int minprec = int(fabs(log10(fabs(val))))+2; for(int i=newset[FPEAK].getPrecision();i0.)){ minval = pow(10, -1. * (newset[SNRPEAK].getPrecision()+1)); if(val < minval) newset[SNRPEAK].upPrec(); } tempwidth = int( log10(fabs(val)) + 1) + newset[SNRPEAK].getPrecision() +2; if(val<0) tempwidth++; for(int i=newset[SNRPEAK].getWidth();i0.)){ minval = pow(10, -1. * (newset[XAV].getPrecision()+1)); if(val < minval) newset[XAV].upPrec(); } tempwidth = int( log10(val) + 1) + newset[XAV].getPrecision() + 2; for(int i=newset[XAV].getWidth();i0.)){ minval = pow(10, -1. * (newset[YAV].getPrecision()+1)); if(val < minval) newset[YAV].upPrec(); } tempwidth = int( log10(val) + 1) + newset[YAV].getPrecision() + 2; for(int i=newset[YAV].getWidth();i0.)){ minval = pow(10, -1. * (newset[ZAV].getPrecision()+1)); if((val>0.)&&(val < minval)) newset[ZAV].upPrec(); } tempwidth = int( log10(val) + 1) + newset[ZAV].getPrecision() + 2; for(int i=newset[ZAV].getWidth();i0.)){ minval = pow(10, -1. * (newset[XCENT].getPrecision()+1)); if(val < minval) newset[XCENT].upPrec(); } tempwidth = int( log10(val) + 1) + newset[XCENT].getPrecision() + 2; for(int i=newset[XCENT].getWidth();i0.)){ minval = pow(10, -1. * (newset[YCENT].getPrecision()+1)); if(val < minval) newset[YCENT].upPrec(); } tempwidth = int( log10(val) + 1) + newset[YCENT].getPrecision() + 2; for(int i=newset[YCENT].getWidth();i0.)){ minval = pow(10, -1. * (newset[ZCENT].getPrecision()+1)); if((val>0.)&&(val < minval)) newset[ZCENT].upPrec(); } tempwidth = int( log10(val) + 1) + newset[ZCENT].getPrecision() + 2; for(int i=newset[ZCENT].getWidth();i0.)){ minval = pow(10, -1. * (newset[XPEAK].getPrecision()+1)); if(val < minval) newset[XPEAK].upPrec(); } tempwidth = int( log10(val) + 1) + newset[XPEAK].getPrecision() + 2; for(int i=newset[XPEAK].getWidth();i0.)){ minval = pow(10, -1. * (newset[YPEAK].getPrecision()+1)); if(val < minval) newset[YPEAK].upPrec(); } tempwidth = int( log10(val) + 1) + newset[YPEAK].getPrecision() + 2; for(int i=newset[YPEAK].getWidth();i0.)){ minval = pow(10, -1. * (newset[ZPEAK].getPrecision()+1)); if((val>0.)&&(val < minval)) newset[ZPEAK].upPrec(); } tempwidth = int( log10(val) + 1) + newset[ZPEAK].getPrecision() + 2; for(int i=newset[ZPEAK].getWidth();i getLogColSet(std::vector &objectList, FitsHeader &head) { /// @details A function that returns a std::vector of Col /// objects containing information on the columns necessary /// for logfile output: /// Obj#,X,Y,Z,F_tot,F_peak,X1,X2,Y1,Y2,Z1,Z2,Npix /// /// Each object in the provided objectList is checked to see if /// it requires any column to be widened, or for that column to /// have its precision increased. /// /// \param objectList A std::vector list of Detection objects that the columns need to fit. /// \param head The FitsHeader object defining the World Coordinate System. /// \return A std::vector list of Col definitions. std::vector newset,tempset; // set up the default columns: // get from FullColSet, and select only the ones we want. tempset = getFullColSet(objectList,head); newset.push_back( tempset[NUM] ); newset.push_back( tempset[X] ); newset.push_back( tempset[Y] ); newset.push_back( tempset[Z] ); newset.push_back( tempset[FTOT] ); newset.push_back( tempset[FPEAK] ); newset.push_back( tempset[SNRPEAK] ); newset.push_back( tempset[X1] ); newset.push_back( tempset[X2] ); newset.push_back( tempset[Y1] ); newset.push_back( tempset[Y2] ); newset.push_back( tempset[Z1] ); newset.push_back( tempset[Z2] ); newset.push_back( tempset[NPIX] ); return newset; } } }