Changeset 1603 for branches/alma/src
- Timestamp:
- 07/18/09 06:35:47 (15 years ago)
- Location:
- branches/alma/src
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/alma/src/LineCatalog.cpp
r1259 r1603 62 62 void LineCatalog::setPattern(const std::string& name, const std::string& stype) 63 63 { 64 //std::string mode = stype+"('"+name+"')"; 65 std::string taql = "SELECT FROM $1 WHERE Column1 == pattern('"+name+"')"; 66 cerr << taql << endl; 64 std::string mode = stype+"('"+name+"')"; 65 std::string taql = "SELECT FROM $1 WHERE Column1 == " + mode; 67 66 Table tmp = tableCommand(taql, table_); 68 67 if (tmp.nrow() > 0) table_ = tmp.sort("Column2"); … … 110 109 } 111 110 } 112 /// @todo implement me113 111 return String(oss); 114 112 } 115 113 116 /*! 117 \fn asap::LineCatalog::getName(int row) 118 */ 114 119 115 std::string LineCatalog::getName(uint row) const 120 116 { … … 123 119 } 124 120 125 double asap::LineCatalog::getFrequency(uint row) const121 double LineCatalog::getFrequency(uint row) const 126 122 { 127 ROScalarColumn<Double> col(table_, "Column2"); 128 return col(row); 123 return getDouble("Column2", row); 129 124 } 130 125 131 double asap::LineCatalog::getStrength(uint row) const126 double LineCatalog::getStrength(uint row) const 132 127 { 133 ROScalarColumn<Double> col(table_, "Column3"); 134 return col(row); 128 return getDouble("Column4", row); 135 129 } 136 130 131 double LineCatalog::getDouble(const std::string& colname, uint row) const { 132 DataType dtype = table_.tableDesc().columnDesc(colname).dataType(); 133 if (dtype == TpDouble) { 134 ROScalarColumn<Double> col(table_, colname); 135 return col(row); 136 } else if (dtype == TpInt) { 137 ROScalarColumn<Int> col(table_, colname); 138 return Double(col(row)); 139 } else { 140 throw AipsError("Column " + colname + "doesn't contain numerical values." ); 141 } 142 } 137 143 138 144 } // namespace -
branches/alma/src/LineCatalog.h
r1353 r1603 111 111 casa::Table setLimits(double lmin, double lmax, const std::string& colname); 112 112 113 double getDouble(const std::string& colname, uint row) const; 114 113 115 // the table with seelection 114 116 casa::Table table_; -
branches/alma/src/Makefile
r1520 r1603 43 43 RPFITSLIB := -lrpfits 44 44 45 #wcs 46 WCSLIB := -lwcs 47 45 48 G2CROOT := /usr 46 G2CARCH := $(G2CROOT)/lib/gcc/i386-apple-darwin8.7.1/4.2.0/libgcc.a47 G2CARCH := $(G2CROOT)/lib/gcc/powerpc-apple-darwin8.7.0/4.2.0/libgcc.a48 G2CARCH := $(G2CROOT)/lib/gcc/i386-redhat-linux/4.1. 0/libgcc.a49 #G2CARCH := $(G2CROOT)/lib/gcc/i386-apple-darwin8.7.1/4.2.0/libgcc.a 50 #G2CARCH := $(G2CROOT)/lib/gcc/powerpc-apple-darwin8.7.0/4.2.0/libgcc.a 51 G2CARCH := $(G2CROOT)/lib/gcc/i386-redhat-linux/4.1.2/libgcc.a 49 52 #G2CLIB := $(G2CROOT)/lib/libgfortran.a 50 G2CLIB := -lg2c 53 G2CLIB := $(G2CARCH) 54 #G2CLIB := -lg2c 51 55 52 56 # This assumes all casa libs are static only (*.a) … … 56 60 -lcasa_lattices -lcasa_fits -lcasa_measures -lcasa_measures_f \ 57 61 -lcasa_tables -lcasa_scimath -lcasa_scimath_f -lcasa_casa \ 58 $( CASALIB)/libwcs.a\62 $(WCSLIB) \ 59 63 $(RPFITSLIB) $(CFITSIOLIB) $(G2CLIB) -lstdc++ 60 64 … … 127 131 STWriter.o \ 128 132 STAsciiWriter.o \ 133 STFITSImageWriter.o \ 129 134 Scantable.o \ 130 135 Templates.o … … 172 177 STPolLinear.h \ 173 178 STWriter.h \ 174 STAsciiWriter.h 179 STAsciiWriter.h \ 180 STFITSImageWriter.h 175 181 176 182 STATICCCLIB := libasap.a -
branches/alma/src/MathUtils.cpp
r1530 r1603 35 35 #include <casa/Arrays/MaskedArray.h> 36 36 #include <casa/Arrays/MaskArrMath.h> 37 #include <casa/Arrays/VectorSTLIterator.h> 37 38 #include <casa/BasicSL/String.h> 38 39 #include <scimath/Mathematics/MedianSlider.h> … … 106 107 { 107 108 std::vector<std::string> out; 108 Vector<String>::const_iterator it = in.begin();109 for ( uInt i=0; it != in.end(); ++it,++i) {109 out.reserve(in.nelements()); 110 for (Array<String>::const_iterator it = in.begin(); it != in.end(); ++it) { 110 111 out.push_back(*it); 111 112 } … … 116 117 { 117 118 Vector<String> out(in.size()); 118 uInt i=0;119 std::vector<std::string>::const_iterator it;120 for (it=in.begin();it != in.end();++it,++i) {121 out[i] = casa::String(*it);119 Array<String>::iterator oit = out.begin(); 120 for (std::vector<std::string>::const_iterator it=in.begin() ; 121 it != in.end(); ++it,++oit) { 122 *oit = *it; 122 123 } 123 124 return out; -
branches/alma/src/MathUtils.h
r1514 r1603 87 87 88 88 /** 89 * Convert a std::vector of std::string 90 * to a casa::Vector casa::String 91 * @param in 92 * @return 89 * Convert casa implementations to stl 90 * @param in casa string 91 * @return a std vector of std strings 93 92 */ 94 93 std::vector<std::string> tovectorstring(const casa::Vector<casa::String>& in); 95 94 96 95 /** 97 * Convert a casa::Vector of casa::String 98 * to a stl std::vector of stl std::string 96 * convert stl implementations to casa versions 99 97 * @param in 100 98 * @return -
branches/alma/src/RowAccumulator.cpp
r1446 r1603 44 44 Vector<Bool> dummymsk(m.nelements(), True); 45 45 spectrum_.setData(dummy, dummymsk); 46 n_.setData(Vector< Float>(v.nelements(), 0.0), dummymsk);46 n_.setData(Vector<uInt>(v.nelements(), 0), dummymsk); 47 47 weightSum_.setData(Vector<Float>(v.nelements(), 0.0), dummymsk); 48 48 tsysSum_.resize(tsys.nelements()); tsysSum_=0.0; … … 50 50 // add spectrum related weights, so far it is variance only. 51 51 Float totalweight = 1.0; 52 totalweight *= addTsys(tsys); 52 53 53 // only add these if not everything masked 54 54 if ( !allEQ(m, False) ) { 55 totalweight *= addTsys(tsys); 55 56 totalweight *= addInterval(interval); 56 57 addTime(time); … … 79 80 weightSum_ += wadd; 80 81 spectrum_ += data; 81 const MaskedArray< Float> inc(Vector<Float>(m.nelements(),1.0), m);82 const MaskedArray<uInt> inc(Vector<uInt>(m.nelements(),1), m); 82 83 n_ += inc; 83 84 } … … 125 126 casa::Double asap::RowAccumulator::getTime( ) const 126 127 { 127 Float n = max(n_); 128 if (n < 1.0) n = 1.0; 129 return timeSum_/n; 128 uInt n = max(n_); 129 return timeSum_/Float(n); 130 130 } 131 131 … … 138 138 { 139 139 // Return the "total" mask - False where no points have been accumulated. 140 return (n_.getArray() > Float(0.0));140 return (n_.getArray() > uInt(0)); 141 141 } 142 142 … … 144 144 { 145 145 // @fixme this assumes tsys.nelements() == 1 146 return tsysSum_/ max(n_);146 return tsysSum_/Float(max(n_)); 147 147 } 148 148 … … 158 158 return initialized_; 159 159 } 160 -
branches/alma/src/RowAccumulator.h
r1446 r1603 103 103 //these are Vectors 104 104 casa::MaskedArray<casa::Float> spectrum_; 105 casa::MaskedArray<casa::Float> n_, weightSum_; 105 casa::MaskedArray<casa::Float> weightSum_; 106 casa::MaskedArray<casa::uInt> n_; 106 107 107 108 casa::Vector<casa::Bool> userMask_; -
branches/alma/src/STFiller.cpp
r1533 r1603 5 5 // 6 6 // 7 // Author: Malte Marquarding <asap@atnf.csiro.au>, (C) 2006 7 // Author: Malte Marquarding <asap@atnf.csiro.au>, (C) 2006-2007 8 8 // 9 9 // Copyright: See COPYING file that comes with this distribution … … 28 28 #include <measures/Measures/MeasConvert.h> 29 29 30 #include <atnf/PKSIO/PKSrecord.h> 30 31 #include <atnf/PKSIO/PKSreader.h> 32 #ifdef HAS_ALMA 33 #include <casa/System/ProgressMeter.h> 34 #endif 31 35 #include <casa/System/ProgressMeter.h> 32 36 #include <atnf/PKSIO/NROReader.h> 33 37 34 38 #include <time.h> 39 35 40 36 41 #include "STDefs.h" … … 48 53 header_(0), 49 54 table_(0), 55 refRx_(".*(e|w|_R)$"), 50 56 nreader_(0) 51 57 { … … 56 62 header_(0), 57 63 table_(stbl), 64 refRx_(".*(e|w|_R)$"), 58 65 nreader_(0) 59 66 { … … 64 71 header_(0), 65 72 table_(0), 73 refRx_(".*(e|w|_R)$"), 66 74 nreader_(0) 67 75 { … … 141 149 Int status = reader_->getHeader(header_->observer, header_->project, 142 150 header_->antennaname, header_->antennaposition, 143 header_->obstype,header_->equinox, 151 header_->obstype, 152 header_->fluxunit, 153 header_->equinox, 144 154 header_->freqref, 145 155 header_->utc, header_->reffreq, 146 header_->bandwidth, 147 header_->fluxunit); 156 header_->bandwidth); 148 157 149 158 if (status) { … … 166 175 Bool throwIt = False; 167 176 Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt); 168 //header_->fluxunit = "Jy"; 177 169 178 if (inst==ATMOPRA || inst==TIDBINBILLA) { 170 header_->fluxunit = "K"; 179 header_->fluxunit = "K"; 180 } else { 181 // downcase for use with Quanta 182 if (header_->fluxunit == "JY") { 183 header_->fluxunit = "Jy"; 184 } 171 185 } 172 186 STAttr stattr; … … 275 289 // 276 290 291 /** 277 292 Int beamNo, IFno, refBeam, scanNo, cycleNo; 278 293 Float azimuth, elevation, focusAxi, focusRot, focusTan, … … 287 302 Complex xCalFctr; 288 303 Vector<Complex> xPol; 304 **/ 305 289 306 Double min = 0.0; 290 307 Double max = nInDataRow; 308 #ifdef HAS_ALMA 291 309 ProgressMeter fillpm(min, max, "Data importing progress"); 310 #endif 311 PKSrecord pksrec; 292 312 int n = 0; 293 313 while ( status == 0 ) { 294 status = reader_->read(scanNo, cycleNo, mjd, interval, fieldName, 295 srcName, srcDir, srcPM, srcVel, obsType, IFno, 296 refFreq, bandwidth, freqInc, restFreq, tcal, tcalTime, 297 azimuth, elevation, parAngle, focusAxi, 298 focusTan, focusRot, temperature, pressure, 299 humidity, windSpeed, windAz, refBeam, 300 beamNo, direction, scanRate, 301 tsys, sigma, calFctr, baseLin, baseSub, 302 spectra, flagtra, xCalFctr, xPol); 314 status = reader_->read(pksrec); 303 315 if ( status != 0 ) break; 304 316 n += 1; 305 317 306 318 Regex filterrx(".*[SL|PA]$"); 307 319 Regex obsrx("^AT.+"); 308 if ( header_->antennaname.matches(obsrx) && obsType.matches(filterrx)) { 320 if ( header_->antennaname.matches(obsrx) && 321 pksrec.obsType.matches(filterrx)) { 309 322 //cerr << "ignoring paddle scan" << endl; 310 323 continue; … … 314 327 // fields that don't get used and are just passed through asap 315 328 RecordFieldPtr<Array<Double> > srateCol(rec, "SCANRATE"); 316 *srateCol = scanRate; 329 // MRC changed type from double to float 330 Vector<Double> sratedbl(pksrec.scanRate.nelements()); 331 convertArray(sratedbl, pksrec.scanRate); 332 *srateCol = sratedbl; 317 333 RecordFieldPtr<Array<Double> > spmCol(rec, "SRCPROPERMOTION"); 318 *spmCol = srcPM;334 *spmCol = pksrec.srcPM; 319 335 RecordFieldPtr<Array<Double> > sdirCol(rec, "SRCDIRECTION"); 320 *sdirCol = srcDir;336 *sdirCol = pksrec.srcDir; 321 337 RecordFieldPtr<Double> svelCol(rec, "SRCVELOCITY"); 322 *svelCol = srcVel;338 *svelCol = pksrec.srcVel; 323 339 // the real stuff 324 340 RecordFieldPtr<Int> fitCol(rec, "FIT_ID"); 325 341 *fitCol = -1; 326 342 RecordFieldPtr<uInt> scanoCol(rec, "SCANNO"); 327 *scanoCol = scanNo-1;343 *scanoCol = pksrec.scanNo-1; 328 344 RecordFieldPtr<uInt> cyclenoCol(rec, "CYCLENO"); 329 *cyclenoCol = cycleNo-1;345 *cyclenoCol = pksrec.cycleNo-1; 330 346 RecordFieldPtr<Double> mjdCol(rec, "TIME"); 331 *mjdCol = mjd;347 *mjdCol = pksrec.mjd; 332 348 RecordFieldPtr<Double> intCol(rec, "INTERVAL"); 333 *intCol = interval;349 *intCol = pksrec.interval; 334 350 RecordFieldPtr<String> srcnCol(rec, "SRCNAME"); 335 351 RecordFieldPtr<Int> srctCol(rec, "SRCTYPE"); 336 352 RecordFieldPtr<String> fieldnCol(rec, "FIELDNAME"); 337 *fieldnCol = fieldName;353 *fieldnCol = pksrec.fieldName; 338 354 // try to auto-identify if it is on or off. 339 Regex rx( ".*[e|w|_R]$");355 Regex rx(refRx_); 340 356 Regex rx2("_S$"); 341 Int match = srcName.matches(rx);357 Int match = pksrec.srcName.matches(rx); 342 358 if (match) { 343 *srcnCol = srcName;359 *srcnCol = pksrec.srcName; 344 360 } else { 345 *srcnCol = srcName.before(rx2);346 } 347 //*srcnCol = srcName;//.before(rx2);361 *srcnCol = pksrec.srcName.before(rx2); 362 } 363 //*srcnCol = pksrec.srcName;//.before(rx2); 348 364 *srctCol = match; 349 365 RecordFieldPtr<uInt> beamCol(rec, "BEAMNO"); 350 *beamCol = beamNo-beamOffset_-1;366 *beamCol = pksrec.beamNo-beamOffset_-1; 351 367 RecordFieldPtr<Int> rbCol(rec, "REFBEAMNO"); 352 368 Int rb = -1; 353 if (nBeam_ > 1 ) rb = refBeam-1;369 if (nBeam_ > 1 ) rb = pksrec.refBeam-1; 354 370 *rbCol = rb; 355 371 RecordFieldPtr<uInt> ifCol(rec, "IFNO"); 356 *ifCol = IFno-ifOffset_- 1;372 *ifCol = pksrec.IFno-ifOffset_- 1; 357 373 uInt id; 358 374 /// @todo this has to change when nchan isn't global anymore 359 375 id = table_->frequencies().addEntry(Double(header_->nchan/2), 360 refFreq,freqInc);376 pksrec.refFreq, pksrec.freqInc); 361 377 RecordFieldPtr<uInt> mfreqidCol(rec, "FREQ_ID"); 362 378 *mfreqidCol = id; 363 379 364 id = table_->molecules().addEntry( restFreq);380 id = table_->molecules().addEntry(pksrec.restFreq); 365 381 RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID"); 366 382 *molidCol = id; 367 383 368 id = table_->tcal().addEntry( tcalTime,tcal);384 id = table_->tcal().addEntry(pksrec.tcalTime, pksrec.tcal); 369 385 RecordFieldPtr<uInt> mcalidCol(rec, "TCAL_ID"); 370 386 *mcalidCol = id; 371 id = table_->weather().addEntry(temperature, pressure, humidity, 372 windSpeed, windAz); 387 id = table_->weather().addEntry(pksrec.temperature, pksrec.pressure, 388 pksrec.humidity, pksrec.windSpeed, 389 pksrec.windAz); 373 390 RecordFieldPtr<uInt> mweatheridCol(rec, "WEATHER_ID"); 374 391 *mweatheridCol = id; 375 392 RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID"); 376 id = table_->focus().addEntry(focusAxi, focusTan, focusRot); 393 id = table_->focus().addEntry(pksrec.focusAxi, pksrec.focusTan, 394 pksrec.focusRot); 377 395 *mfocusidCol = id; 378 396 RecordFieldPtr<Array<Double> > dirCol(rec, "DIRECTION"); 379 *dirCol = direction;397 *dirCol = pksrec.direction; 380 398 RecordFieldPtr<Float> azCol(rec, "AZIMUTH"); 381 *azCol = azimuth;399 *azCol = pksrec.azimuth; 382 400 RecordFieldPtr<Float> elCol(rec, "ELEVATION"); 383 *elCol = elevation;401 *elCol = pksrec.elevation; 384 402 385 403 RecordFieldPtr<Float> parCol(rec, "PARANGLE"); 386 *parCol = p arAngle;404 *parCol = pksrec.parAngle; 387 405 388 406 RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA"); … … 395 413 Vector<Float> tsysvec(1); 396 414 // Why is spectra.ncolumn() == 3 for haveXPol_ == True 397 uInt npol = ( spectra.ncolumn()==1 ? 1: 2);415 uInt npol = (pksrec.spectra.ncolumn()==1 ? 1: 2); 398 416 for ( uInt i=0; i< npol; ++i ) { 399 tsysvec = tsys(i);417 tsysvec = pksrec.tsys(i); 400 418 *tsysCol = tsysvec; 401 419 *polnoCol = i; 402 420 403 *specCol = spectra.column(i);404 *flagCol = flagtra.column(i);421 *specCol = pksrec.spectra.column(i); 422 *flagCol = pksrec.flagged.column(i); 405 423 table_->table().addRow(); 406 424 row.put(table_->table().nrow()-1, rec); … … 408 426 if ( haveXPol_[0] ) { 409 427 // no tsys given for xpol, so emulate it 410 tsysvec = sqrt( tsys[0]*tsys[1]);428 tsysvec = sqrt(pksrec.tsys[0]*pksrec.tsys[1]); 411 429 *tsysCol = tsysvec; 412 430 // add real part of cross pol 413 431 *polnoCol = 2; 414 Vector<Float> r(real( xPol));432 Vector<Float> r(real(pksrec.xPol)); 415 433 *specCol = r; 416 434 // make up flags from linears 417 435 /// @fixme this has to be a bitwise or of both pols 418 *flagCol = flagtra.column(0);// | flagtra.column(1);436 *flagCol = pksrec.flagged.column(0);// | pksrec.flagged.column(1); 419 437 table_->table().addRow(); 420 438 row.put(table_->table().nrow()-1, rec); 421 439 // ad imaginary part of cross pol 422 440 *polnoCol = 3; 423 Vector<Float> im(imag( xPol));441 Vector<Float> im(imag(pksrec.xPol)); 424 442 *specCol = im; 425 443 table_->table().addRow(); 426 444 row.put(table_->table().nrow()-1, rec); 427 445 } 446 #ifdef HAS_ALMA 428 447 fillpm._update(n); 448 #endif 429 449 } 430 450 if (status > 0) { … … 432 452 throw(AipsError("Reading error occured, data possibly corrupted.")); 433 453 } 454 #ifdef HAS_ALMA 434 455 fillpm.done(); 456 #endif 435 457 return status; 436 458 } -
branches/alma/src/STFiller.h
r1495 r1603 111 111 casa::Bool fileCheck() ; 112 112 113 void setReferenceExpr(const std::string& rx) { refRx_ = rx; } 114 113 115 private: 114 116 … … 120 122 casa::uInt ifOffset_, beamOffset_; 121 123 casa::Vector<casa::Bool> haveXPol_; 124 casa::String refRx_; 122 125 NROReader *nreader_ ; 123 126 casa::Bool isNRO_ ; -
branches/alma/src/STFrequencies.cpp
r1446 r1603 157 157 // get first row - there should only be one matching id 158 158 const TableRecord& rec = row.get(0); 159 160 159 return SpectralCoordinate( getFrame(true), rec.asDouble("REFVAL"), 161 160 rec.asDouble("INCREMENT"), … … 165 164 /** 166 165 SpectralCoordinate 167 asap::STFrequencies::getSpectralCoordinate( const MDirection& md,168 169 170 166 STFrequencies::getSpectralCoordinate( const MDirection& md, 167 const MPosition& mp, 168 const MEpoch& me, 169 Double restfreq, uInt id ) const 171 170 **/ 172 171 SpectralCoordinate -
branches/alma/src/STHeader.cpp
r901 r1603 53 53 conforms = (this->antennaname == other.antennaname 54 54 && this->equinox == other.equinox 55 && this->obstype == other.obstype56 55 && this->fluxunit == other.fluxunit 57 56 ); 58 57 return conforms; 58 } 59 60 String STHeader::diff( const STHeader& other ) 61 { 62 ostringstream thediff; 63 if ( this->equinox != other.equinox ) { 64 thediff << "Equinox: " << this->equinox << " <-> " 65 << other.equinox << endl; 66 } 67 if ( this->obstype != other.obstype ) { 68 thediff << "Obs. Type: " << this->obstype << " <-> " 69 << other.obstype << endl; 70 } 71 if ( this->fluxunit != other.fluxunit ) { 72 thediff << "Flux unit: " << this->fluxunit << " <-> " 73 << other.fluxunit << endl; 74 } 75 return String(thediff); 59 76 } 60 77 -
branches/alma/src/STHeader.h
r1386 r1603 50 50 51 51 bool conformant(const STHeader& other); 52 casa::String diff( const STHeader& other ); 53 52 54 53 55 casa::Int nchan; -
branches/alma/src/STLineFinder.cpp
r1315 r1603 870 870 // iterator through lines 871 871 std::list<std::pair<int,int> >::const_iterator cli=lines.begin(); 872 for (int ch=0;ch<int(res_mask.size());++ch) 872 for (int ch=0;ch<int(res_mask.size());++ch) { 873 873 if (ch<edge.first || ch>=edge.second) res_mask[ch]=false; 874 874 else if (!mask[ch]) res_mask[ch]=false; 875 875 else { 876 876 res_mask[ch]=!invert; // no line by default 877 if (cli==lines.end()) continue; 878 if (ch>=cli->first && ch<cli->second) 879 res_mask[ch]=invert; // this is a line 880 if (ch>=cli->second) 881 ++cli; // next line in the list 882 } 883 877 if (cli!=lines.end()) 878 if (ch>=cli->first && ch<cli->second) 879 res_mask[ch]=invert; // this is a line 880 } 881 if (cli!=lines.end()) 882 if (ch>=cli->second) { 883 ++cli; // next line in the list 884 } 885 } 884 886 return res_mask; 885 887 } -
branches/alma/src/STMath.cpp
r1516 r1603 297 297 bool droprows) 298 298 { 299 if (insitu_) return in; 299 if (insitu_) { 300 return in; 301 } 300 302 else { 301 303 // clone 302 Scantable* tabp = new Scantable(*in, Bool(droprows)); 303 return CountedPtr<Scantable>(tabp); 304 return CountedPtr<Scantable>(new Scantable(*in, Bool(droprows))); 304 305 } 305 306 } … … 1513 1514 ArrayColumn<Float> specCol(tab, "SPECTRA"); 1514 1515 ArrayColumn<uChar> flagCol(tab, "FLAGTRA"); 1516 ArrayColumn<Float> tsysCol(tab, "TSYS"); 1515 1517 for ( uInt i=0; i<tab.nrow(); ++i) { 1516 1518 Float zdist = Float(C::pi_2) - elev(i); … … 1520 1522 specCol.put(i, ma.getArray()); 1521 1523 flagCol.put(i, flagsFromMA(ma)); 1524 Vector<Float> tsys; 1525 tsysCol.get(i, tsys); 1526 tsys *= factor; 1527 tsysCol.put(i, tsys); 1522 1528 } 1523 1529 return out; … … 1614 1620 while ( it != in.end() ){ 1615 1621 if ( ! (*it)->conformant(*out) ) { 1616 // log message: "ignoring scantable i, as it isn't 1617 // conformant with the other(s)" 1618 cerr << "oh oh" << endl; 1619 ++it; 1620 continue; 1622 // non conformant. 1623 pushLog(String("Warning: Can't merge scantables as header info differs.")); 1621 1624 } 1622 1625 out->appendToHistoryTable((*it)->history()); … … 1628 1631 Table thetab = freqit.table(); 1629 1632 uInt nrow = tout.nrow(); 1630 //tout.addRow(thetab.nrow());1633 tout.addRow(thetab.nrow()); 1631 1634 TableCopy::copyRows(tout, thetab, nrow, 0, thetab.nrow()); 1632 1635 ROTableRow row(thetab); … … 1826 1829 1827 1830 InterpolateArray1D<Double,Float>::InterpolationMethod interp = stringToIMethod(method); 1831 /* 1832 // Comment from MV. 1833 // the following code has been commented out because different FREQ_IDs have to be aligned together even 1834 // if the frame doesn't change. So far, lack of this check didn't cause any problems. 1828 1835 // test if user frame is different to base frame 1829 1836 if ( in->frequencies().getFrameString(true) … … 1832 1839 " (use set_freqframe) or it is aligned already.")); 1833 1840 } 1841 */ 1834 1842 MFrequency::Types system = in->frequencies().getFrame(); 1835 1843 MVTime mvt(refEpoch.getValue()); … … 1857 1865 1858 1866 ROArrayColumn<Float> sCol(t, "SPECTRA"); 1859 MDirection direction = dirCol(0); 1860 uInt nchan = sCol(0).nelements(); 1867 const MDirection direction = dirCol(0); 1868 const uInt nchan = sCol(0).nelements(); 1869 1870 // skip operations if there is nothing to align 1871 if (fiter.pastEnd()) { 1872 continue; 1873 } 1874 1875 Table ftab = fiter.table(); 1876 // align all frequency ids with respect to the first encountered id 1877 ScalarColumn<uInt> freqidCol(ftab, "FREQ_ID"); 1878 // get the SpectralCoordinate for the freqid, which we are iterating over 1879 SpectralCoordinate sC = in->frequencies().getSpectralCoordinate(freqidCol(0)); 1880 FrequencyAligner<Float> fa( sC, nchan, refEpoch, 1881 direction, refPos, system ); 1882 // realign the SpectralCoordinate and put into the output Scantable 1883 Vector<String> units(1); 1884 units = String("Hz"); 1885 Bool linear=True; 1886 SpectralCoordinate sc2 = fa.alignedSpectralCoordinate(linear); 1887 sc2.setWorldAxisUnits(units); 1888 const uInt id = out->frequencies().addEntry(sc2.referencePixel()[0], 1889 sc2.referenceValue()[0], 1890 sc2.increment()[0]); 1861 1891 while ( !fiter.pastEnd() ) { 1862 Table ftab = fiter.table(); 1863 ScalarColumn<uInt> freqidCol(ftab, "FREQ_ID"); 1864 // get the SpectralCoordinate for the freqid, which we are iterating over 1865 SpectralCoordinate sC = in->frequencies().getSpectralCoordinate(freqidCol(0)); 1866 FrequencyAligner<Float> fa( sC, nchan, refEpoch, 1867 direction, refPos, system ); 1868 // realign the SpectralCoordinate and put into the output Scantable 1869 Vector<String> units(1); 1870 units = String("Hz"); 1871 Bool linear=True; 1872 SpectralCoordinate sc2 = fa.alignedSpectralCoordinate(linear); 1873 sc2.setWorldAxisUnits(units); 1874 uInt id = out->frequencies().addEntry(sc2.referencePixel()[0], 1875 sc2.referenceValue()[0], 1876 sc2.increment()[0]); 1877 TableVector<uInt> tvec(ftab, "FREQ_ID"); 1878 tvec = id; 1892 ftab = fiter.table(); 1893 // spectral coordinate for the current FREQ_ID 1894 ScalarColumn<uInt> freqidCol2(ftab, "FREQ_ID"); 1895 sC = in->frequencies().getSpectralCoordinate(freqidCol2(0)); 1879 1896 // create the "global" abcissa for alignment with same FREQ_ID 1880 1897 Vector<Double> abc(nchan); 1881 Double w;1882 1898 for (uInt i=0; i<nchan; i++) { 1883 sC.toWorld(w,Double(i)); 1884 abc[i] = w; 1885 } 1899 Double w; 1900 sC.toWorld(w,Double(i)); 1901 abc[i] = w; 1902 } 1903 TableVector<uInt> tvec(ftab, "FREQ_ID"); 1904 // assign new frequency id to all rows 1905 tvec = id; 1886 1906 // cache abcissa for same time stamps, so iterate over those 1887 1907 TableIterator timeiter(ftab, "TIME"); … … 1892 1912 MEpoch::ROScalarColumn timeCol(tab, "TIME"); 1893 1913 // use align abcissa cache after the first row 1914 // these rows should be just be POLNO 1894 1915 bool first = true; 1895 // these rows should be just be POLNO1896 1916 for (int i=0; i<int(tab.nrow()); ++i) { 1897 1917 // input values -
branches/alma/src/STMath.h
r1516 r1603 65 65 * average a vector of Scantables 66 66 * @param in the vector of Scantables to average 67 * @param an optional mask to apply on specific weights67 * @param mask an optional mask to apply on specific weights 68 68 * @param weight weighting scheme 69 69 * @param avmode the mode ov averaging. Per "SCAN" or "ALL". -
branches/alma/src/STSelector.cpp
r1387 r1603 143 143 if ( taql_.size() > 0 ) { 144 144 Table tmpt = tab; 145 std::string pytaql = "USING STYLE PYTHON " + taql_; 145 146 146 147 if ( !query.isNull() ) { // taql and selection 147 tmpt = tableCommand( taql_, tab(query));148 tmpt = tableCommand(pytaql, tab(query)); 148 149 } else { // taql only 149 tmpt = tableCommand( taql_, tab);150 tmpt = tableCommand(pytaql, tab); 150 151 } 151 152 return sort(tmpt); -
branches/alma/src/STWeather.cpp
r856 r1603 108 108 void STWeather::getEntry( Float& temperature, Float& pressure, 109 109 Float& humidity, Float& windspeed, Float& windaz, 110 uInt id ) 110 uInt id ) const 111 111 { 112 112 Table t = table_(table_.col("ID") == Int(id) ); -
branches/alma/src/STWeather.h
r1353 r1603 44 44 casa::Float& humidity, 45 45 casa::Float& windspeed, casa::Float& windaz, 46 casa::uInt id) ;46 casa::uInt id) const; 47 47 48 48 const casa::String& name() const { return name_; } -
branches/alma/src/STWriter.cpp
r1446 r1603 39 39 #include <casa/Utilities/Assert.h> 40 40 41 #include <atnf/PKSIO/PKSrecord.h> 41 42 #include <atnf/PKSIO/PKSMS2writer.h> 42 43 #include <atnf/PKSIO/PKSSDwriter.h> … … 47 48 #include <tables/Tables/ArrayColumn.h> 48 49 49 //#include "SDFITSImageWriter.h"50 #include "STFITSImageWriter.h" 50 51 #include "STAsciiWriter.h" 51 52 #include "STHeader.h" … … 58 59 STWriter::STWriter(const std::string &format) 59 60 { 61 format_ = format; 62 String t(format_); 63 t.upcase(); 64 if (t == "MS2") { 65 writer_ = new PKSMS2writer(); 66 } else if (t == "SDFITS") { 67 writer_ = new PKSSDwriter(); 68 } else if (t == "ASCII" || t == "FITS" || t == "CLASS") { 69 writer_ = 0; 70 } else { 71 throw (AipsError("Unrecognized export format")); 72 } 73 } 74 75 STWriter::~STWriter() 76 { 77 if (writer_) { 78 delete writer_; 79 } 80 } 81 82 Int STWriter::setFormat(const std::string &format) 83 { 84 if (format != format_) { 85 if (writer_) delete writer_; 86 } 87 60 88 format_ = format; 61 89 String t(format_); … … 65 93 } else if (t== "SDFITS") { 66 94 writer_ = new PKSSDwriter(); 67 } else if (t== "ASCII") { 68 writer_ = 0; 69 } else { 70 throw (AipsError("Unrecognized export format")); 71 } 72 } 73 74 STWriter::~STWriter() 75 { 76 if (writer_) { 77 delete writer_; 78 } 79 } 80 81 Int STWriter::setFormat(const std::string &format) 82 { 83 if (format != format_) { 84 if (writer_) delete writer_; 85 } 86 87 format_ = format; 88 String t(format_); 89 t.upcase(); 90 if (t== "MS2") { 91 writer_ = new PKSMS2writer(); 92 } else if (t== "SDFITS") { 93 writer_ = new PKSSDwriter(); 94 } else if (t== "ASCII") { 95 } else if (t == "ASCII" || t == "FITS" || t == "CLASS") { 95 96 writer_ = 0; 96 97 } else { … … 110 111 } else { 111 112 return 1; 113 } 114 } else if ( format_ == "FITS" || format_ == "CLASS") { 115 STFITSImageWriter iw; 116 if (format_ == "CLASS") { 117 iw.setClass(True); 118 } 119 if (iw.write(*in, filename)) { 120 return 0; 112 121 } 113 122 } … … 139 148 Int status; 140 149 status = writer_->create(String(filename), hdr.observer, hdr.project, 141 hdr.antennaname, hdr.antennaposition, 142 hdr.obstype, hdr.equinox, hdr.freqref, 143 nChan, nPol, havexpol, False, fluxUnit); 150 hdr.antennaname, hdr.antennaposition, 151 hdr.obstype, hdr.fluxunit, 152 hdr.equinox, hdr.freqref, 153 nChan, nPol, havexpol, False); 144 154 if ( status ) { 145 155 throw(AipsError("Failed to create output file")); 146 156 } 147 157 148 Double srcVel; 149 150 String fieldName, srcName, tcalTime; 151 Vector<Float> calFctr, sigma, tcal, tsys; 152 Vector<Double> direction(2), scanRate(2), srcDir(2), srcPM(2); 153 Matrix<Float> spectra; 154 Matrix<uChar> flagtra; 155 Complex xCalFctr; 158 156 159 Int count = 0; 157 Int scanno = 1; 160 PKSrecord pksrec; 161 pksrec.scanNo = 1; 158 162 // use spearate iterators to ensure renumbering of all numbers 159 163 TableIterator scanit(table, "SCANNO"); … … 161 165 Table stable = scanit.table(); 162 166 TableIterator beamit(stable, "BEAMNO"); 163 Int beamno = 1;167 pksrec.beamNo = 1; 164 168 while (!beamit.pastEnd() ) { 165 169 Table btable = beamit.table(); 166 // position only varies by beam167 // No, we want to pointing data which varies by cycle!168 170 MDirection::ScalarColumn dirCol(btable, "DIRECTION"); 169 Vector<Double>direction = dirCol(0).getAngle("rad").getValue();171 pksrec.direction = dirCol(0).getAngle("rad").getValue(); 170 172 TableIterator cycit(btable, "CYCLENO"); 171 173 ROArrayColumn<Double> srateCol(btable, "SCANRATE"); 172 srateCol.get(0, scanRate); 174 Vector<Double> sratedbl; 175 srateCol.get(0, sratedbl); 176 Vector<Float> srateflt(sratedbl.nelements()); 177 convertArray(srateflt, sratedbl); 178 //pksrec.scanRate = srateflt; 179 pksrec.scanRate = sratedbl; 173 180 ROArrayColumn<Double> spmCol(btable, "SRCPROPERMOTION"); 174 spmCol.get(0, srcPM);181 spmCol.get(0, pksrec.srcPM); 175 182 ROArrayColumn <Double> sdirCol(btable, "SRCDIRECTION"); 176 sdirCol.get(0, srcDir);183 sdirCol.get(0, pksrec.srcDir); 177 184 ROScalarColumn<Double> svelCol(btable, "SRCVELOCITY"); 178 svelCol.get(0, srcVel);185 svelCol.get(0, pksrec.srcVel); 179 186 ROScalarColumn<uInt> bCol(btable, "BEAMNO"); 180 beamno = bCol(0)+1;181 Int cycno = 1;187 pksrec.beamNo = bCol(0)+1; 188 pksrec.cycleNo = 1; 182 189 while (!cycit.pastEnd() ) { 183 190 Table ctable = cycit.table(); 191 TableIterator ifit(ctable, "IFNO"); 184 192 //MDirection::ScalarColumn dirCol(ctable, "DIRECTION"); 185 //Vector<Double> direction = dirCol(0).getAngle("rad").getValue(); 186 TableIterator ifit(ctable, "IFNO"); 187 Int ifno = 1; 193 //pksrec.direction = dirCol(0).getAngle("rad").getValue(); 194 pksrec.IFno = 1; 188 195 while (!ifit.pastEnd() ) { 189 196 Table itable = ifit.table(); … … 192 199 const TableRecord& rec = row.get(0); 193 200 ROArrayColumn<Float> specCol(itable, "SPECTRA"); 194 ifno = rec.asuInt("IFNO")+1;201 pksrec.IFno = rec.asuInt("IFNO")+1; 195 202 uInt nchan = specCol(0).nelements(); 196 //Double cdelt,crval,crpix, restfreq; 197 Double cdelt,crval,crpix; 198 Vector<Double> restfreq; 199 Float focusAxi, focusTan, focusRot, 200 temperature, pressure, humidity, windSpeed, windAz; 203 Double crval,crpix; 204 //Vector<Double> restfreq; 201 205 Float tmp0,tmp1,tmp2,tmp3,tmp4; 202 Vector<Float> tcalval;203 //String stmp0,stmp1, tcalt;204 206 String tcalt; 205 207 Vector<String> stmp0, stmp1; 206 in->frequencies().getEntry(crpix,crval,cdelt, rec.asuInt("FREQ_ID")); 207 in->focus().getEntry(focusAxi, focusTan, focusRot, 208 tmp0,tmp1,tmp2,tmp3,tmp4, 208 in->frequencies().getEntry(crpix,crval, pksrec.freqInc, 209 rec.asuInt("FREQ_ID")); 210 in->focus().getEntry(pksrec.focusAxi, pksrec.focusTan, 211 pksrec.focusRot, tmp0,tmp1,tmp2,tmp3,tmp4, 209 212 rec.asuInt("FOCUS_ID")); 210 in->molecules().getEntry(restfreq,stmp0,stmp1,rec.asuInt("MOLECULE_ID")); 211 in->tcal().getEntry(tcalt,tcalval,rec.asuInt("TCAL_ID")); 212 in->weather().getEntry(temperature, pressure, humidity, 213 windSpeed, windAz, 214 rec.asuInt("WEATHER_ID")); 213 in->molecules().getEntry(pksrec.restFreq,stmp0,stmp1, 214 rec.asuInt("MOLECULE_ID")); 215 in->tcal().getEntry(pksrec.tcalTime, pksrec.tcal, 216 rec.asuInt("TCAL_ID")); 217 in->weather().getEntry(pksrec.temperature, pksrec.pressure, 218 pksrec.humidity, pksrec.windSpeed, 219 pksrec.windAz, rec.asuInt("WEATHER_ID")); 215 220 Double pixel = Double(nchan/2); 216 Double refFreqNew = (pixel-crpix)*cdelt+ crval;221 pksrec.refFreq = (pixel-crpix)*pksrec.freqInc + crval; 217 222 // ok, now we have nrows for the n polarizations in this table 218 Matrix<Float> specs; 219 Matrix<uChar> flags; 220 Vector<Complex> xpol; 221 polConversion(specs, flags, xpol, itable); 222 Vector<Float> tsys = tsysFromTable(itable); 223 polConversion(pksrec.spectra, pksrec.flagged, pksrec.xPol, itable); 224 pksrec.tsys = tsysFromTable(itable); 223 225 // dummy data 224 //uInt npol; 225 //if ( hdr.antennaname == "GBT" ) { 226 // npol = nPolUsed; 227 //} 228 //else { 229 // npol = specs.ncolumn(); 230 //} 231 uInt npol = specs.ncolumn(); 232 233 Matrix<Float> baseLin(npol,2, 0.0f); 234 Matrix<Float> baseSub(npol,9, 0.0f); 235 Complex xCalFctr; 236 Vector<Double> scanRate(2, 0.0); 237 Vector<Float> sigma(npol, 0.0f); 238 Vector<Float> calFctr(npol, 0.0f); 239 status = writer_->write(scanno, cycno, rec.asDouble("TIME"), 240 rec.asDouble("INTERVAL"), 241 rec.asString("FIELDNAME"), 242 rec.asString("SRCNAME"), 243 srcDir, srcPM, srcVel,hdr.obstype, 244 ifno, 245 refFreqNew, nchan*abs(cdelt), cdelt, 246 restfreq, 247 tcalval, 248 tcalt, 249 rec.asFloat("AZIMUTH"), 250 rec.asFloat("ELEVATION"), 251 rec.asFloat("PARANGLE"), 252 focusAxi, focusTan, focusRot, 253 temperature, 254 pressure, humidity, windSpeed, windAz, 255 rec.asInt("REFBEAMNO")+1, beamno, 256 direction, 257 scanRate, 258 tsys, 259 sigma, calFctr,// not in scantable 260 baseLin, baseSub,// not in scantable 261 specs, flags, 262 xCalFctr,// 263 xpol); 226 uInt npol = pksrec.spectra.ncolumn(); 227 228 pksrec.mjd = rec.asDouble("TIME"); 229 pksrec.interval = rec.asDouble("INTERVAL"); 230 pksrec.fieldName = rec.asString("FIELDNAME"); 231 pksrec.srcName = rec.asString("SRCNAME"); 232 pksrec.obsType = hdr.obstype; 233 pksrec.bandwidth = nchan * abs(pksrec.freqInc); 234 pksrec.azimuth = rec.asFloat("AZIMUTH"); 235 pksrec.elevation = rec.asFloat("ELEVATION"); 236 pksrec.parAngle = rec.asFloat("PARANGLE"); 237 pksrec.refBeam = rec.asInt("REFBEAMNO") + 1; 238 pksrec.sigma.resize(npol); 239 pksrec.sigma = 0.0f; 240 pksrec.calFctr.resize(npol); 241 pksrec.calFctr = 0.0f; 242 pksrec.baseLin.resize(npol,2); 243 pksrec.baseLin = 0.0f; 244 pksrec.baseSub.resize(npol,9); 245 pksrec.baseSub = 0.0f; 246 pksrec.xCalFctr = 0.0; 247 248 status = writer_->write(pksrec); 264 249 if ( status ) { 265 250 writer_->close(); … … 267 252 } 268 253 ++count; 269 ++ifno;254 //++pksrec.IFno; 270 255 ++ifit; 271 256 } 272 ++ cycno;257 ++pksrec.cycleNo; 273 258 ++cycit; 274 259 } 275 ++beamno;260 //++pksrec.beamNo; 276 261 ++beamit; 277 262 } 278 ++ scanno;263 ++pksrec.scanNo; 279 264 ++scanit; 280 265 } … … 286 271 if ( format_ == "MS2" ) { 287 272 replacePtTab(table, filename); 288 } 273 } 289 274 return 0; 290 275 } -
branches/alma/src/Scantable.cpp
r1451 r1603 213 213 td.addColumn(ScalarColumnDesc<String>("SRCNAME")); 214 214 // Type of source (on=0, off=1, other=-1) 215 td.addColumn(ScalarColumnDesc<Int>("SRCTYPE", Int(-1))); 215 ScalarColumnDesc<Int> stypeColumn("SRCTYPE"); 216 stypeColumn.setDefault(Int(-1)); 217 td.addColumn(stypeColumn); 216 218 td.addColumn(ScalarColumnDesc<String>("FIELDNAME")); 217 219 … … 535 537 return int(n); 536 538 } else { 537 // take the first SCANNO,POLNO,BEAMNO,CYCLENO as nbeam shouldn't vary with these 539 // take the first SCANNO,POLNO,BEAMNO,CYCLENO as nbeam shouldn't 540 // vary with these 538 541 Table t = table_(table_.col("IFNO") == ifno); 539 542 if ( t.nrow() == 0 ) return 0; … … 885 888 } 886 889 890 MEpoch Scantable::getEpoch(int whichrow) const 891 { 892 if (whichrow > -1) { 893 return timeCol_(uInt(whichrow)); 894 } else { 895 Double tm; 896 table_.keywordSet().get("UTC",tm); 897 return MEpoch(MVEpoch(tm)); 898 } 899 } 900 887 901 std::string Scantable::getDirectionString(int whichrow) const 888 902 { … … 892 906 std::vector< double > Scantable::getAbcissa( int whichrow ) const 893 907 { 894 if ( whichrow > int(table_.nrow()) ) throw(AipsError("Illegal ro number"));908 if ( whichrow > int(table_.nrow()) ) throw(AipsError("Illegal row number")); 895 909 std::vector<double> stlout; 896 910 int nchan = specCol_(whichrow).nelements(); -
branches/alma/src/Scantable.h
r1446 r1603 158 158 casa::MEpoch::Types getTimeReference() const; 159 159 160 161 casa::MEpoch getEpoch(int whichrow) const; 162 160 163 /** 161 164 * Get global antenna position … … 164 167 casa::MPosition getAntennaPosition() const; 165 168 166 167 168 169 170 169 /** 170 * the @ref casa::MDirection for a specific row 171 * @param[in] whichrow the row number 172 * return casa::MDirection 173 */ 171 174 casa::MDirection getDirection( int whichrow ) const; 172 173 174 * get the direction as a string 175 176 177 175 176 /** 177 * get the direction type as a string, e.g. "J2000" 178 * @param[in] whichrow the row number 179 * return the direction string 180 */ 178 181 std::string getDirectionString( int whichrow ) const; 179 182 180 181 182 183 183 /** 184 * set the direction type as a string, e.g. "J2000" 185 * @param[in] refstr the direction type 186 */ 184 187 void setDirectionRefString(const std::string& refstr=""); 188 185 189 /** 186 190 * get the direction reference string 187 191 * @return a string describing the direction reference 188 192 */ 189 std::string getDirectionRefString() const; /** 190 * get the direction type as a string, e.g. "J2000" 191 * param[in] whichrow the row number 192 * return the direction string 193 */ 194 193 std::string getDirectionRefString() const; 195 194 196 195 /** -
branches/alma/src/python_STFiller.cpp
r1386 r1603 47 47 .def("_close", &STFillerWrapper::close) 48 48 .def("_getdata", &STFillerWrapper::getScantable) 49 .def("_setreferenceexpr", &STFillerWrapper::setReferenceExpr) 49 50 ; 50 51 }; -
branches/alma/src/python_asap.cpp
r1126 r1603 39 39 #include "ScantableWrapper.h" 40 40 41 #ifndef HAVE_LIBPYRAP 42 #include "pyconversions.h" 43 #else 44 #include <pyrap/Converters/PycExcp.h> 45 #include <pyrap/Converters/PycBasicData.h> 46 #endif 41 47 42 #include "pyconversions.h"43 48 #include "python_asap.h" 44 49 50 #ifndef HAVE_LIBPYRAP 45 51 namespace asap { 46 52 namespace python { 53 47 54 void translate_ex(const casa::AipsError& e) 48 55 { … … 53 60 } 54 61 } 62 #endif 63 55 64 using namespace boost::python; 56 65 … … 65 74 asap::python::python_STWriter(); 66 75 asap::python::python_LineCatalog(); 76 asap::python::python_Logger(); 67 77 68 asap::python::python_Logger(); 78 #ifndef HAVE_LIBPYRAP 79 // Use built-in pyconversions.h 69 80 register_exception_translator<casa::AipsError>(&asap::python::translate_ex); 70 71 //std_vector_to_tuple < > ();72 81 from_python_sequence < std::vector< asap::ScantableWrapper >, 73 82 variable_capacity_policy > (); 74 75 83 std_vector_to_tuple < int > (); 76 84 from_python_sequence < std::vector < int >, … … 91 99 from_python_sequence < std::vector < bool >, 92 100 variable_capacity_policy > (); 101 #else 102 casa::pyrap::register_convert_excp(); 103 casa::pyrap::register_convert_basicdata(); 104 casa::pyrap::register_convert_std_vector<asap::ScantableWrapper>(); 105 #endif 93 106 }
Note:
See TracChangeset
for help on using the changeset viewer.