void CompositeCoordinateSystem::setAxis( int axis, const BasicCoordinateSystemInfo & bcs, int subAxis ) { CARTA_ASSERT( axis >= 0 && axis < ndim() ); CARTA_ASSERT( subAxis >= 0 && subAxis < bcs.ndim() ); m_cs[axis] = bcs; m_subAxis[axis] = subAxis; }
LineCombiner::Cell & LineCombiner::cell( int row, int col ) { CARTA_ASSERT( row >= 0 ); CARTA_ASSERT( col >= 0 ); CARTA_ASSERT( row < m_nRows ); CARTA_ASSERT( col < m_nCols ); CARTA_ASSERT( m_grid.size() > 0 ); return m_grid[row][col]; }
virtual Me & setAxisPrecision( int precision, int axis ) override { CARTA_ASSERT( axis >= 0 && axis < nAxes() ); m_precisions[axis] = precision; return * this; }
CCCoordinateFormatter::Me & CCCoordinateFormatter::setAxisPrecision( int precision, int axis ) { CARTA_ASSERT( axis >= 0 && axis < nAxes() ); m_precisions[axis] = precision; return * this; }
bool ImageSaveService::saveFullImage(){ bool dataPrepared = _prepareData( ); if ( dataPrepared ){ CARTA_ASSERT( m_renderService); m_renderService->render( 0 ); } return dataPrepared; }
virtual QStringList formatFromPixelCoordinate( const VD & pix ) override { CARTA_ASSERT( pix.size() >= 2 ); QStringList res; res.append( QString::number( pix[0] ) ); res.append( QString::number( pix[1] ) ); return res; }
void LayeredRemoteVGView::setRasterLayer( int layer, const QImage & img ) { CARTA_ASSERT( layer >= 0 && layer < 1000 ); if ( int ( m_rasterLayers.size() ) <= layer ) { m_rasterLayers.resize( layer + 1 ); } m_rasterLayers[layer].qimg = img; }
void LayeredRemoteVGView::setRasterLayerCombiner( int layer, IQImageCombiner::SharedPtr combiner ) { CARTA_ASSERT( layer >= 0 && layer < 1000 ); if ( int ( m_rasterLayers.size() ) <= layer ) { m_rasterLayers.resize( layer + 1 ); } m_rasterLayers[layer].combiner = combiner; }
void LayeredRemoteVGView::setVGLayer( int layer, const VectorGraphics::VGList & vglist ) { CARTA_ASSERT( layer >= 0 && layer < 1000 ); if ( int ( m_vgLayers.size() ) <= layer ) { m_vgLayers.resize( layer + 1 ); } m_vgLayers[layer].vglist = vglist; }
void DesktopConnector::jsViewRefreshedSlot(const QString & viewName, qint64 id) { //qDebug() << "jsViewRefreshedSlot()" << viewName << id; ViewInfo * viewInfo = findViewInfo( viewName); if( ! viewInfo) { qCritical() << "Received refresh view signal for unknown view" << viewName; return; } CARTA_ASSERT( viewInfo-> view); viewInfo-> view-> viewRefreshed( id); }
JsonMessage JsonMessage::fromTagMessage( const TagMessage & message ) { CARTA_ASSERT( message.tag() == TAG || message.tag() == "async" ); QJsonParseError jsonError; QJsonDocument doc = QJsonDocument::fromJson( message.data(), & jsonError ); if ( doc.isEmpty() || jsonError.error != QJsonParseError::NoError ) { qWarning() << "error in parsing received JSON"; qWarning() << jsonError.errorString(); qWarning() << "...in..."; qWarning() << message.data(); return JsonMessage( QJsonDocument() ); } return JsonMessage( doc ); }
bool ImageSaveService::_prepareData( ){ bool dataPrepared = false; if ( m_inputView ){ CARTA_ASSERT( m_renderService); m_renderService-> setPixelPipeline( m_pixelPipelineCopy, m_pixelPipelineCopy-> cacheId()); m_renderService-> setInputView( m_inputView, m_inputViewId ); double zoom = m_renderService->zoom(); QSize outputSize = QSize( zoom * m_inputXFrames, zoom * m_inputYFrames ); qDebug() << "IMS outputSize=" << outputSize; qDebug() << "IMS inputframes" << m_inputXFrames << m_inputYFrames; qDebug() << "IMS zoom" << zoom; m_renderService->setOutputSize( outputSize); // m_renderService->setOutputSize( QSize( zoom * m_inputXFrames, zoom * m_inputYFrames ) ); m_renderService->setPan( { m_inputXFrames / 2.0 - 0.5, m_inputYFrames / 2.0 - 0.5 }); dataPrepared = true; } return dataPrepared; }
const BasicCoordinateSystemInfo & CompositeCoordinateSystem::cs( int axis ) const { CARTA_ASSERT( axis >= 0 && axis < ndim() ); return m_cs[axis]; }
virtual const Carta::Lib::AxisInfo & axisInfo( int ind ) const override { CARTA_ASSERT( ind >= 0 && ind < nAxes() ); return m_axisInfos[ind]; }
/* Derivation from the fortran version of CONREC by Paul Bourke view ! view of the data ilb,iub ! bounds for first coordinate (column), inclusive jlb,jub ! bounds for second coordinate (row), inclusive xCoords ! column coordinates (first index) yCoords ! row coordinates (second index) nc ! number of contour levels z ! contour levels in increasing order */ static Carta::Lib::Algorithms::ContourConrec::Result conrecFaster( Carta::Lib::NdArray::RawViewInterface * view, int ilb, int iub, int jlb, int jub, const VD & xCoords, const VD & yCoords, int nc, double * z ) { // we will only need two rows in memory at any given time // int nRows = jub - jlb + 1; int nCols = iub - ilb + 1; double * rows[2] { nullptr, nullptr }; std::vector < double > row1( nCols ), row2( nCols ); rows[0] = & row1[0]; rows[1] = & row2[0]; int nextRowToReadIn = 0; auto updateRows = [&] () -> void { CARTA_ASSERT( nextRowToReadIn < view-> dims()[1] ); // make a row view into the view SliceND rowSlice; rowSlice.next().start( nextRowToReadIn ).end( nextRowToReadIn + 1 ); auto rawRowView = view-> getView( rowSlice ); nextRowToReadIn++; // make a double view of this raw row view Carta::Lib::NdArray::Double dview( rawRowView, true ); // shift the row up // note: we could avoid this memory copy if we swapped row[] pointers instead, // and alternately read in the data into row1,row2..., for a miniscule performance // gain and lot more complicated algorithm row1 = row2; // read in the data into row2 int i = 0; dview.forEach([&] ( const double & val ) { row2[i++] = val; } ); CARTA_ASSERT( i == nCols ); }; updateRows(); // NdArray::Double doubleView( view, false ); // auto acc = [& doubleView] ( int col, int row ) { // return doubleView.get( { col, row } // ); // }; // to keep the data accessor easy, we use this lambda, and hope the compiler // optimizes it into an inline expression... :) auto acc = [&] ( int col, int row ) { row -= nextRowToReadIn - 2; return rows[row][col]; }; Carta::Lib::Algorithms::ContourConrec::Result result; if ( nc < 1 ) { return result; } result.resize( nc ); #define xsect( p1, p2 ) ( h[p2] * xh[p1] - h[p1] * xh[p2] ) / ( h[p2] - h[p1] ) #define ysect( p1, p2 ) ( h[p2] * yh[p1] - h[p1] * yh[p2] ) / ( h[p2] - h[p1] ) int m1, m2, m3, case_value; double dmin, dmax, x1 = 0, x2 = 0, y1 = 0, y2 = 0; int i, j, k, m; double h[5]; int sh[5]; double xh[5], yh[5]; int im[4] = { 0, 1, 1, 0 }, jm[4] = { 0, 0, 1, 1 }; int castab[3][3][3] = { { { 0, 0, 8 }, { 0, 2, 5 }, { 7, 6, 9 } }, { { 0, 3, 4 }, { 1, 3, 1 }, { 4, 3, 0 } }, { { 9, 6, 7 }, { 5, 2, 0 }, { 8, 0, 0 } } }; double temp1, temp2; // original code went from bottom to top, not sure why // for ( j = ( jub - 1 ) ; j >= jlb ; j-- ) { for ( j = jlb ; j < jub ; j++ ) { updateRows(); for ( i = ilb ; i < iub ; i++ ) { temp1 = std::min( acc( i, j ), acc( i, j + 1 ) ); temp2 = std::min( acc( i + 1, j ), acc( i + 1, j + 1 ) ); dmin = std::min( temp1, temp2 ); // early abort if one of the values is not finite if ( ! std::isfinite( dmin ) ) { continue; } temp1 = std::max( acc( i, j ), acc( i, j + 1 ) ); temp2 = std::max( acc( i + 1, j ), acc( i + 1, j + 1 ) ); dmax = std::max( temp1, temp2 ); if ( dmax < z[0] || dmin > z[nc - 1] ) { continue; } for ( k = 0 ; k < nc ; k++ ) { if ( z[k] < dmin || z[k] > dmax ) { continue; } for ( m = 4 ; m >= 0 ; m-- ) { if ( m > 0 ) { h[m] = acc( i + im[m - 1], j + jm[m - 1] ) - z[k]; xh[m] = xCoords[i + im[m - 1]]; yh[m] = yCoords[j + jm[m - 1]]; } else { h[0] = 0.25 * ( h[1] + h[2] + h[3] + h[4] ); xh[0] = 0.50 * ( xCoords[i] + xCoords[i + 1] ); yh[0] = 0.50 * ( yCoords[j] + yCoords[j + 1] ); } if ( h[m] > 0.0 ) { sh[m] = 1; } else if ( h[m] < 0.0 ) { sh[m] = - 1; } else { sh[m] = 0; } } /* Note: at this stage the relative heights of the corners and the centre are in the h array, and the corresponding coordinates are in the xh and yh arrays. The centre of the box is indexed by 0 and the 4 corners by 1 to 4 as shown below. Each triangle is then indexed by the parameter m, and the 3 vertices of each triangle are indexed by parameters m1,m2,and m3. It is assumed that the centre of the box is always vertex 2 though this isimportant only when all 3 vertices lie exactly on the same contour level, in which case only the side of the box is drawn. vertex 4 +-------------------+ vertex 3 | \ / | | \ m-3 / | | \ / | | \ / | | m=2 X m=2 | the centre is vertex 0 | / \ | | / \ | | / m=1 \ | | / \ | vertex 1 +-------------------+ vertex 2 */ /* Scan each triangle in the box */ for ( m = 1 ; m <= 4 ; m++ ) { m1 = m; m2 = 0; if ( m != 4 ) { m3 = m + 1; } else { m3 = 1; } if ( ( case_value = castab[sh[m1] + 1][sh[m2] + 1][sh[m3] + 1] ) == 0 ) { continue; } switch ( case_value ) { case 1 : /* Line between vertices 1 and 2 */ x1 = xh[m1]; y1 = yh[m1]; x2 = xh[m2]; y2 = yh[m2]; break; case 2 : /* Line between vertices 2 and 3 */ x1 = xh[m2]; y1 = yh[m2]; x2 = xh[m3]; y2 = yh[m3]; break; case 3 : /* Line between vertices 3 and 1 */ x1 = xh[m3]; y1 = yh[m3]; x2 = xh[m1]; y2 = yh[m1]; break; case 4 : /* Line between vertex 1 and side 2-3 */ x1 = xh[m1]; y1 = yh[m1]; x2 = xsect( m2, m3 ); y2 = ysect( m2, m3 ); break; case 5 : /* Line between vertex 2 and side 3-1 */ x1 = xh[m2]; y1 = yh[m2]; x2 = xsect( m3, m1 ); y2 = ysect( m3, m1 ); break; case 6 : /* Line between vertex 3 and side 1-2 */ x1 = xh[m3]; y1 = yh[m3]; x2 = xsect( m1, m2 ); y2 = ysect( m1, m2 ); break; case 7 : /* Line between sides 1-2 and 2-3 */ x1 = xsect( m1, m2 ); y1 = ysect( m1, m2 ); x2 = xsect( m2, m3 ); y2 = ysect( m2, m3 ); break; case 8 : /* Line between sides 2-3 and 3-1 */ x1 = xsect( m2, m3 ); y1 = ysect( m2, m3 ); x2 = xsect( m3, m1 ); y2 = ysect( m3, m1 ); break; case 9 : /* Line between sides 3-1 and 1-2 */ x1 = xsect( m3, m1 ); y1 = ysect( m3, m1 ); x2 = xsect( m1, m2 ); y2 = ysect( m1, m2 ); break; default : break; } // switch // add the line segment to the result // ConrecLine( x1, y1, x2, y2, k ); if ( std::isfinite( x1 ) && std::isfinite( y1 ) && std::isfinite( x2 ) && std::isfinite( y2 ) ) { QPolygonF poly; poly.append( QPointF( x1, y1 ) ); poly.append( QPointF( x2, y2 ) ); result[k].push_back( poly ); } } /* m */ } /* k - contour */ } /* i */ } /* j */ return result; #undef xsect #undef ysect } // conrecFaster
virtual int axisPrecision( int axis ) override { CARTA_ASSERT( axis >= 0 && axis < nAxes() ); return m_precisions[axis]; }
void LineCombiner::add( QPointF p1, QPointF p2 ) { bool ok; qDebug() << "add" << p1 << p2; // find closest points within the threshold distance of p1 and p2 IndexPt * ip1 = _findClosestPt( p1 ); IndexPt * ip2 = _findClosestPt( p2 ); // normalize the cases if ( ! ip1 ) { std::swap( ip1, ip2 ); std::swap( p1, p2 ); } if ( ip1 ) { CARTA_ASSERT( ip1-> poly ); } if ( ip2 ) { CARTA_ASSERT( ip2-> poly ); } // case1: this line segment is not near anything else if ( ip1 == nullptr && ip2 == nullptr ) { qDebug() << "case null null"; // we insert a new polyline and update spacial index // make a new polyline from p1 and p2 Poly * poly = new Poly; poly->append( p1 ); poly->append( p2 ); // insert beginning of this polyline into grid findCell( p1 )-> pts.append( IndexPt( poly, false ) ); // insert end of this polyine into grid findCell( p2 )-> pts.append( IndexPt( poly, true ) ); IndexPt ipt1( poly, true ); CARTA_ASSERT( findCell( ipt1.pt() )->pts.contains( ipt1 ) ); return; } // catch a super-special case.... both points point to the same polyline, same end... // we'll treat this as if only one of the points pointed to a polyline) if( ip2 && ip1->poly == ip2->poly && ip1->flipped == ip2->flipped) { qDebug() << "super special"; ip2 = nullptr; } // only one point has a match (ip1, ip2 is null) if ( ip1 != nullptr && ip2 == nullptr ) { qDebug() << "case poly null"; // make a copy of what ip1 points to, because it'll be destroyed IndexPt ip1copy = * ip1; // remove ip1 from it's corresponding cell (after this ip1 will point to // a destroyed memory!) ok = findCell( ip1-> pt() )-> pts.removeOne( * ip1 ); CARTA_ASSERT( ok ); // re-point ip1 to the copy ip1 = & ip1copy; // we extend the polyline that ip1 points to with p2 if ( ip1-> flipped ) { ip1-> poly-> append( p2 ); } else { ip1-> poly-> prepend( p2 ); } // and add a new index point (for p2) to the respective cell findCell( p2 )-> pts.append( * ip1 ); return; } // both points have a match, and it's the same polyline, but different ends... if ( ip1-> poly == ip2-> poly ) { qDebug() << "case poly poly same"; CARTA_ASSERT( ip1->flipped == ! ip2->flipped ); // we need to remove both points from their cells Poly * poly = ip1->poly; ok = findCell( ip1->pt() )->pts.removeOne( * ip1 ); CARTA_ASSERT( ok ); ok = findCell( ip2->pt() )->pts.removeOne( * ip2 ); CARTA_ASSERT( ok ); // make it a closed polyline poly->append( poly->first() ); QPolygonF polygon = poly2polygon( poly ); m_polygons.push_back( polygon ); delete poly; return; } // last case is: both points have a match to 2 different polylines qDebug() << "case poly poly diff"; // we need to merge these two polylines together IndexPt ip1c = * ip1; IndexPt ip2c = * ip2; // remove first polyline from the spatial index ok = findCell( ip1c.poly->front() )-> pts.removeAll( { ip1c.poly, false } ); CARTA_ASSERT( ok ); ok = findCell( ip1c.poly->back() )-> pts.removeAll( { ip1c.poly, true } ); CARTA_ASSERT( ok ); // remove second polyline from the spatial index ok = findCell( ip2c.poly->front() )-> pts.removeAll( { ip2c.poly, false } ); CARTA_ASSERT( ok ); ok = findCell( ip2c.poly->back() )-> pts.removeAll( { ip2c.poly, true } ); CARTA_ASSERT( ok ); Q_UNUSED(ok); // we need to handle 4 cases for merging... in any case, we'll be re-using poly1 and // appending/prepending to it all elements from poly2 // case1: append poly2 to the end of poly1, in forward order if ( ip1c.flipped && ! ip2c.flipped ) { qDebug() << "subcase1 - append forward"; for ( auto & pt : * ip2c.poly ) { ip1c.poly->append( pt ); } } else if ( ip1c.flipped && ip2c.flipped ) { qDebug() << "subcase2 - append reverse"; QLinkedListIterator < QPointF > i( * ip2c.poly ); i.toBack(); while ( i.hasPrevious() ) { ip1c.poly-> append( i.previous() ); } } else if ( ! ip1c.flipped && ! ip2c.flipped ) { qDebug() << "subase3 - prepend forward"; for ( auto & pt : * ip2c.poly ) { ip1c.poly->prepend( pt ); } } else { qDebug() << "subase4 - prepend reverse"; QLinkedListIterator < QPointF > i( * ip2c.poly ); i.toBack(); while ( i.hasPrevious() ) { ip1c.poly-> prepend( i.previous() ); } } // get rid of poly2 delete ip2c.poly; // re-insert the endpoints of poly1 into spatial index ip1c = IndexPt( ip1c.poly, false ); ip2c = IndexPt( ip1c.poly, true ); findCell( ip1c.poly->first() )->pts.append( ip1c ); findCell( ip1c.poly->last() )->pts.append( ip2c ); } // add
void CCCoordinateFormatter::parseCasaCSi( int pixelAxis ) { CARTA_ASSERT( 0 <= pixelAxis && pixelAxis < nAxes() ); // find the pixel axes in casacore's coordinate system // coord will be the index of the 'coordinate' // and coord2 will be an index within that index... // warning: casa's coordinates and axes are two completely different things! // e.g. a standard 4D fits file with frequency and stokes has 3 coordinates, but // 4 axes... int coord; // this is the world coordinate int coord2; // this is the index within world coordinate (0 for all but latitude) m_casaCS->findPixelAxis( coord, coord2, pixelAxis ); //qDebug() << pixelAxis << "-->" << coord << "," << coord2; //qDebug() << " " // << casa::Coordinate::typeToString( m_casaCS->coordinate( coord ).type() ).c_str(); AxisInfo & aInfo = m_axisInfos[pixelAxis]; // default will be unknown axis aInfo.setKnownType( AxisInfo::KnownType::OTHER ) .setLongLabel( HtmlString::fromPlain( "Unknown" ) ) .setShortLabel( HtmlString::fromPlain( "Unknown" ) ) .setUnit( "unknown" ); // did we find the world coordinate for this axis in casa core's coordinatesystem? if ( coord >= 0 ) { const auto & cc = m_casaCS->coordinate( coord ); auto skycs = skyCS(); // we handle sky coordinate if ( cc.type() == casa::Coordinate::DIRECTION ) { // is it longitude? if ( coord2 == 0 ) { aInfo.setKnownType( AxisInfo::KnownType::DIRECTION_LON ); // B1950,J200 and ICRS share labels if ( skycs == KnownSkyCS::B1950 || skycs == KnownSkyCS::J2000 || skycs == KnownSkyCS::ICRS ) { aInfo.setLongLabel( HtmlString::fromPlain( "Right ascension" ) ) .setShortLabel( HtmlString( "RA", "α" ) ); } else if ( skycs == KnownSkyCS::Ecliptic ) { aInfo.setLongLabel( HtmlString::fromPlain( "Ecliptic longitude" ) ) //.setShortLabel( HtmlString( "ELon", "l" ) ); .setShortLabel( HtmlString( "ELon", "λ")); } else if ( skycs == KnownSkyCS::Galactic ) { aInfo.setLongLabel( HtmlString::fromPlain( "Galactic longitude" ) ) //.setShortLabel( HtmlString( "GLon", "λ" ) ); .setShortLabel( HtmlString( "GLon", "l")); } else { CARTA_ASSERT( false ); } } // it's latitude then else { aInfo.setKnownType( AxisInfo::KnownType::DIRECTION_LAT ); // B1950,J200 and ICRS share labels if ( skycs == KnownSkyCS::B1950 || skycs == KnownSkyCS::J2000 || skycs == KnownSkyCS::ICRS ) { aInfo.setLongLabel( HtmlString::fromPlain( "Declination" ) ) .setShortLabel( HtmlString( "Dec", "δ" ) ); } else if ( skycs == KnownSkyCS::Ecliptic ) { aInfo.setLongLabel( HtmlString::fromPlain( "Ecliptic latitude" ) ) //.setShortLabel( HtmlString( "ELat", "b" ) ); .setShortLabel( HtmlString( "Elat", "β")); } else if ( skycs == KnownSkyCS::Galactic ) { aInfo.setLongLabel( HtmlString::fromPlain( "Galactic latitude" ) ) //.setShortLabel( HtmlString( "GLat", "β" ) ); .setShortLabel( HtmlString( "GLat", "b")); } else { CARTA_ASSERT( false ); } } m_precisions[pixelAxis] = 3; } else if ( cc.type() == casa::Coordinate::SPECTRAL ) { aInfo.setKnownType( AxisInfo::KnownType::SPECTRAL ) .setLongLabel( HtmlString::fromPlain( "Frequency" ) ) .setShortLabel( HtmlString( "Freq", "Freq" ) ); m_precisions[pixelAxis] = 6; } else if ( cc.type() == casa::Coordinate::STOKES ) { aInfo.setKnownType( AxisInfo::KnownType::STOKES ) .setLongLabel( HtmlString::fromPlain( "Stokes" ) ) .setShortLabel( HtmlString::fromPlain( "Stokes" ) ); } else if ( cc.type() == casa::Coordinate::TABULAR ) { aInfo.setKnownType( AxisInfo::KnownType::TABULAR ); // else if ( cc.type() == casa::Coordinate::QUALITY ) { // aInfo.setKnownType( aInfo.KnownType::QUALITY); // } } else if ( cc.type() == casa::Coordinate::LINEAR ){ aInfo.setKnownType( AxisInfo::KnownType::LINEAR ) .setLongLabel( HtmlString::fromPlain( "Linear")) .setShortLabel( HtmlString::fromPlain( "Linear")); } else { // other types... we copy whatever casacore dishes out aInfo.setKnownType( AxisInfo::KnownType::OTHER ); QString rawAxisLabel = cc.worldAxisNames() ( coord2 ).c_str(); QString shortLabel = rawAxisLabel; aInfo.setLongLabel( HtmlString::fromPlain( rawAxisLabel ) ); aInfo.setShortLabel( HtmlString::fromPlain( shortLabel ) ); } CARTA_ASSERT( cc.worldAxisNames().size() > 0 ); // we always take the unit from casa aInfo.setUnit( cc.worldAxisUnits() ( coord2 ).c_str() ); } else { // this should never happen that casacore didn't find world coordinates for // the given axis... but let's not panic and just leave it a default value } } // parseCasaCSi
QString CCCoordinateFormatter::formatWorldValue( int whichAxis, double worldValue ) { // get info for this axis const AxisInfo & ai = axisInfo( whichAxis ); // // decide what to do based on the type of the axis // // for longigute / latitude we do the same thing, except for a different factor // when doing sexagesimal if ( ai.knownType() == AxisInfo::KnownType::DIRECTION_LON || ai.knownType() == AxisInfo::KnownType::DIRECTION_LAT ) { double sexFactor = ( ai.knownType() == AxisInfo::KnownType::DIRECTION_LON ) ? 24 * 60 * 60 / ( 2 * M_PI ) : 180 * 60 * 60 / M_PI; // for longitude values, wrap around negative values if ( ai.knownType() == AxisInfo::KnownType::DIRECTION_LON && worldValue < 0 ) { worldValue += 2 * M_PI; } if ( skyFormatting() == SkyFormatting::Radians ) { return DoubleFormatter() .showPlus( false ) .sexagesimal( false ) .precision( axisPrecision( whichAxis ) ) .go( worldValue ); } if ( skyFormatting() == SkyFormatting::Degrees ) { return DoubleFormatter() .showPlus( true ) .sexagesimal( false ) .precision( axisPrecision( whichAxis ) ) .go( worldValue * 180 / M_PI ) + ( m_textOutputFormat == TextFormat::Html ? "°" : "deg" ); } CARTA_ASSERT( skyFormatting() == SkyFormatting::Sexagesimal ); return DoubleFormatter() .showPlus( true ) .sexagesimal( true, ":" ) .precision( axisPrecision( whichAxis ) ) .go( worldValue * sexFactor ) // + QString("(%1)").arg(worldValue*180/M_PI,0,'f',10) ; } // for stokes we convert to a string using casacore's Stokes class else if ( ai.knownType() == AxisInfo::KnownType::STOKES ) { return casa::Stokes::name( static_cast < casa::Stokes::StokesTypes > ( round( worldValue ) ) ) .c_str(); } else if ( ai.knownType() == AxisInfo::KnownType::SPECTRAL ){ int exp = 1; QStringList availUnits={"Hz","KHz","MHz","GHz"}; int unitCount = availUnits.size(); for ( ; exp < unitCount; exp++ ){ if ( worldValue < pow(10, 3*exp) ){ break; } } exp = exp - 1; QString oldUnit = ai.unit(); int diff = 0; QString unit = oldUnit; if ( exp >= 1 ){ for ( int i = 0; i < availUnits.size(); i++ ){ if ( availUnits[i] == oldUnit ){ if ( i < exp ){ diff = exp - i; break; } } } } unit = availUnits[exp]; worldValue = worldValue / pow(10,3*diff); int precision = axisPrecision( whichAxis); return QString::number(worldValue, 'g', precision) +" "+ unit; } // for other types we do verbatim formatting QString unit = ai.unit(); if ( m_textOutputFormat == TextFormat::Html ) { unit = unit.toHtmlEscaped(); } return DoubleFormatter() .showPlus( false ) .sexagesimal( false ) .precision( axisPrecision( whichAxis ) ) .go( worldValue ) + unit; } // formatWorldValue
const Carta::Lib::AxisInfo & CCCoordinateFormatter::axisInfo( int ind ) const { CARTA_ASSERT( ind >= 0 && ind < nAxes() ); return m_axisInfos[ind]; }
CCCoordinateFormatter::Me & CCCoordinateFormatter::setSkyCS( const KnownSkyCS & scs ) { //qDebug() << "setSkyCS" << static_cast < int > ( scs ); // don't even try to set this to unknown if ( scs == KnownSkyCS::Unknown ) { return * this; } // find out where the direction world coordinate lives int which = m_casaCS->directionCoordinateNumber(); if ( which < 0 ) { // this system does not have sky cs, so we are done return * this; // find out which axes correspond to the world coordinate array(longitude/latitude) } auto pixelAxes = m_casaCS->directionAxesNumbers(); CARTA_ASSERT( pixelAxes.size() == 2 ); CARTA_ASSERT( 0 <= pixelAxes[0] && pixelAxes[0] < nAxes() ); CARTA_ASSERT( 0 <= pixelAxes[1] && pixelAxes[1] < nAxes() ); // make a copy of it casa::DirectionCoordinate dirCoordCopy = casa::DirectionCoordinate( m_casaCS->directionCoordinate( which ) ); // change the system in the copy casa::MDirection::Types mdir; switch ( scs ) { case KnownSkyCS::B1950 : mdir = casa::MDirection::B1950; break; case KnownSkyCS::J2000 : mdir = casa::MDirection::J2000; break; case KnownSkyCS::ICRS : mdir = casa::MDirection::ICRS; break; case KnownSkyCS::Ecliptic : mdir = casa::MDirection::ECLIPTIC; break; case KnownSkyCS::Galactic : mdir = casa::MDirection::GALACTIC; break; default : CARTA_ASSERT_ALWAYS_X( false, "Internal error" ); break; } // switch dirCoordCopy.setReferenceConversion( mdir ); if ( ! m_casaCS->replaceCoordinate( dirCoordCopy, which ) ) { qWarning() << "Could not set wcs because replaceCoordinate() failed"; return * this; } // now we need to adjust axisinfos, formatting and precision setSkyFormatting( SkyFormatting::Default ); parseCasaCSi( pixelAxes[0] ); parseCasaCSi( pixelAxes[1] ); // chaning support return * this; } // setSkyCS
void ImageSaveService::setZoom( double zoom ){ CARTA_ASSERT( m_renderService); m_renderService->setZoom( zoom ); }
int CCCoordinateFormatter::axisPrecision( int axis ) { CARTA_ASSERT( axis >= 0 && axis < nAxes() ); return m_precisions[axis]; }
int CCCoordinateFormatter::nAxes() const { CARTA_ASSERT( m_casaCS ); return m_casaCS->nPixelAxes(); }
int CompositeCoordinateSystem::subAxis( int axis ) const { CARTA_ASSERT( axis >= 0 && axis < ndim() ); return m_subAxis[axis]; }
void viewRefreshed( qint64 id) { CARTA_ASSERT( m_iview); m_iview-> viewRefreshed( id); }
void Region::_setUserId( const QString& file, int index ){ CARTA_ASSERT( index >= 0 ); QString id = file + QString::number( index ); m_state.setValue<QString>( Util::ID, id ); }
void ImageSaveService::setDisplayShape( int dimAxis1, int dimAxis2 ){ CARTA_ASSERT( dimAxis1 >= 0 && dimAxis2 >= 0 ); m_inputXFrames = dimAxis1; m_inputYFrames = dimAxis2; }