void TimeFrequencyImager::image(size_t antenna1Select, size_t antenna2Select, size_t spectralWindowSelect, size_t startIndex, size_t endIndex) { size_t timeCount = _observationTimes.size(); int frequencyCount = _measurementSet->FrequencyCount(); initializePolarizations(); checkPolarizations(); if(_sortedTable == 0) { casa::Table *rawTable = _measurementSet->OpenTable(); casa::Block<casa::String> names(4); names[0] = "DATA_DESC_ID"; names[1] = "ANTENNA1"; names[2] = "ANTENNA2"; names[3] = "TIME"; _sortedTable = new casa::Table(rawTable->sort(names)); delete rawTable; } casa::Block<casa::String> selectionNames(3); selectionNames[0] = "DATA_DESC_ID"; selectionNames[1] = "ANTENNA1"; selectionNames[2] = "ANTENNA2"; casa::TableIterator iter(*_sortedTable, selectionNames, casa::TableIterator::Ascending, casa::TableIterator::NoSort); while(!iter.pastEnd()) { casa::Table table = iter.table(); casa::ScalarColumn<int> antenna1(table, "ANTENNA1"); casa::ScalarColumn<int> antenna2(table, "ANTENNA2"); casa::ScalarColumn<int> windowColumn(table, "DATA_DESC_ID"); if(table.nrow() > 0 && windowColumn(0) == (int) spectralWindowSelect && antenna1(0) == (int) antenna1Select && antenna2(0) == (int) antenna2Select) { break; } else { iter.next(); } } if(iter.pastEnd()) { throw std::runtime_error("Baseline not found"); } casa::Table table = iter.table(); if(startIndex > timeCount) { std::cerr << "Warning: startIndex > timeCount" << std::endl; } if(endIndex > timeCount) { endIndex = timeCount; std::cerr << "Warning: endIndex > timeCount" << std::endl; } size_t width = endIndex-startIndex; if(width == 0 || frequencyCount == 0) return; ClearImages(); if(_readData) { if(_realXX==0 && _readXX) { _realXX = Image2D::CreateZeroImagePtr(width, frequencyCount); _imaginaryXX = Image2D::CreateZeroImagePtr(width, frequencyCount); } if(_realXY == 0 && _readXY) { _realXY = Image2D::CreateZeroImagePtr(width, frequencyCount); _imaginaryXY = Image2D::CreateZeroImagePtr(width, frequencyCount); } if(_realYX == 0 && _readYX) { _realYX = Image2D::CreateZeroImagePtr(width, frequencyCount); _imaginaryYX = Image2D::CreateZeroImagePtr(width, frequencyCount); } if(_realYY == 0 && _readYY) { _realYY = Image2D::CreateZeroImagePtr(width, frequencyCount); _imaginaryYY = Image2D::CreateZeroImagePtr(width, frequencyCount); } if(_realStokesI == 0 && _readStokesI) { _realStokesI = Image2D::CreateZeroImagePtr(width, frequencyCount); _imaginaryStokesI = Image2D::CreateZeroImagePtr(width, frequencyCount); } } if(_readFlags) { // The flags should be initialized to true, as this baseline might // miss some time scans that other baselines do have, and these // should be flagged. if(_flagXX==0 && _readXX) _flagXX = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount); if(_flagXY==0 && _readXY) _flagXY = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount); if(_flagYX==0 && _readYX) _flagYX = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount); if(_flagYY==0 && _readYY) _flagYY = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount); if(_flagCombined==0 && _readStokesI) _flagCombined = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount); } _uvw.resize(width); casa::ScalarColumn<int> antenna1(table, "ANTENNA1"); casa::ScalarColumn<int> antenna2(table, "ANTENNA2"); casa::ScalarColumn<int> windowColumn(table, "DATA_DESC_ID"); casa::ScalarColumn<double> timeColumn(table, "TIME"); casa::ArrayColumn<float> weightColumn(table, "WEIGHT"); casa::ArrayColumn<double> uvwColumn(table, "UVW"); casa::ArrayColumn<casa::Complex> *dataColumn = 0; if(_readData) dataColumn = CreateDataColumn(_dataKind, table); ArrayColumnIterator<casa::Complex> *modelIter; if(_dataKind == ResidualData) { casa::ArrayColumn<casa::Complex> *modelColumn; modelColumn = new casa::ArrayColumn<casa::Complex>(table, "MODEL_DATA"); modelIter = new ArrayColumnIterator<casa::Complex>(ArrayColumnIterator<casa::Complex>::First(*modelColumn)); } else { modelIter = 0; } casa::ArrayColumn<bool> flagColumn(table, "FLAG"); ScalarColumnIterator<int> antenna1Iter = ScalarColumnIterator<int>::First(antenna1); ScalarColumnIterator<int> antenna2Iter = ScalarColumnIterator<int>::First(antenna2); ScalarColumnIterator<int> windowIter = ScalarColumnIterator<int>::First(windowColumn); ScalarColumnIterator<double> timeIter = ScalarColumnIterator<double>::First(timeColumn); ArrayColumnIterator<double> uvwIter = ArrayColumnIterator<double>::First(uvwColumn); ArrayColumnIterator<float> weightIter = ArrayColumnIterator<float>::First(weightColumn); ArrayColumnIterator<casa::Complex> dataIter = ArrayColumnIterator<casa::Complex>::First(*dataColumn); ArrayColumnIterator<bool> flagIter = ArrayColumnIterator<bool>::First(flagColumn); for(size_t i=0;i<table.nrow();++i) { double time = *timeIter; size_t timeIndex = _observationTimes.find(time)->second; bool timeIsSelected = timeIndex>=startIndex && timeIndex<endIndex; if(_readData && timeIsSelected) { if(_dataKind == WeightData) ReadWeights(timeIndex-startIndex, frequencyCount, *weightIter); else if(modelIter == 0) ReadTimeData(timeIndex-startIndex, frequencyCount, *dataIter, 0); else { const casa::Array<casa::Complex> model = **modelIter; ReadTimeData(timeIndex-startIndex, frequencyCount, *dataIter, &model); } } if(_readFlags && timeIsSelected) { const casa::Array<bool> flag = *flagIter; ReadTimeFlags(timeIndex-startIndex, frequencyCount, flag); } if(timeIsSelected) { casa::Array<double> arr = *uvwIter; casa::Array<double>::const_iterator i = arr.begin(); _uvw[timeIndex-startIndex].u = *i; ++i; _uvw[timeIndex-startIndex].v = *i; ++i; _uvw[timeIndex-startIndex].w = *i; } if(_readData) { ++dataIter; if(modelIter != 0) ++(*modelIter); } if(_readFlags) { ++flagIter; } ++weightIter; ++antenna1Iter; ++antenna2Iter; ++timeIter; ++uvwIter; ++windowIter; } if(dataColumn != 0) delete dataColumn; }
// simplify for wind data - no map needed, no mask OSErr NetCDFWindMoverCurv_c::ReorderPoints(TMap **newMap, char* errmsg) { long i, j, n, ntri, numVerdatPts=0; long fNumRows_ext = fNumRows+1, fNumCols_ext = fNumCols+1; long nv = fNumRows * fNumCols, nv_ext = fNumRows_ext*fNumCols_ext; long iIndex, jIndex, index; long triIndex1, triIndex2, waterCellNum=0; long ptIndex = 0, cellNum = 0; long indexOfStart = 0; OSErr err = 0; LONGH landWaterInfo = (LONGH)_NewHandleClear(fNumRows * fNumCols * sizeof(long)); LONGH maskH2 = (LONGH)_NewHandleClear(nv_ext * sizeof(long)); LONGH ptIndexHdl = (LONGH)_NewHandleClear(nv_ext * sizeof(**ptIndexHdl)); LONGH verdatPtsH = (LONGH)_NewHandleClear(nv_ext * sizeof(**verdatPtsH)); GridCellInfoHdl gridCellInfo = (GridCellInfoHdl)_NewHandleClear(nv * sizeof(**gridCellInfo)); TopologyHdl topo=0; LongPointHdl pts=0; VelocityFH velH = 0; DAGTreeStruct tree; WorldRect triBounds; TTriGridVel *triGrid = nil; tree.treeHdl = 0; TDagTree *dagTree = 0; VelocityFH velocityH = 0; if (!landWaterInfo || !ptIndexHdl || !gridCellInfo || !verdatPtsH || !maskH2) {err = memFullErr; goto done;} err = ReadTimeData(indexOfStart,&velocityH,errmsg); // try to use velocities to set grid for (i=0;i<fNumRows;i++) { for (j=0;j<fNumCols;j++) { // eventually will need to have a land mask, for now assume fillValue represents land //if (INDEXH(velocityH,i*fNumCols+j).u==0 && INDEXH(velocityH,i*fNumCols+j).v==0) // land point if (INDEXH(velocityH,i*fNumCols+j).u==fFillValue && INDEXH(velocityH,i*fNumCols+j).v==fFillValue) // land point { INDEXH(landWaterInfo,i*fNumCols+j) = -1; // may want to mark each separate island with a unique number } else { INDEXH(landWaterInfo,i*fNumCols+j) = 1; INDEXH(ptIndexHdl,i*fNumCols_ext+j) = -2; // water box INDEXH(ptIndexHdl,i*fNumCols_ext+j+1) = -2; INDEXH(ptIndexHdl,(i+1)*fNumCols_ext+j) = -2; INDEXH(ptIndexHdl,(i+1)*fNumCols_ext+j+1) = -2; } } } for (i=0;i<fNumRows_ext;i++) { for (j=0;j<fNumCols_ext;j++) { if (INDEXH(ptIndexHdl,i*fNumCols_ext+j) == -2) { INDEXH(ptIndexHdl,i*fNumCols_ext+j) = ptIndex; // count up grid points ptIndex++; } else INDEXH(ptIndexHdl,i*fNumCols_ext+j) = -1; } } for (i=0;i<fNumRows;i++) { for (j=0;j<fNumCols;j++) { if (INDEXH(landWaterInfo,i*fNumCols+j)>0) { INDEXH(gridCellInfo,i*fNumCols+j).cellNum = cellNum; cellNum++; INDEXH(gridCellInfo,i*fNumCols+j).topLeft = INDEXH(ptIndexHdl,i*fNumCols_ext+j); INDEXH(gridCellInfo,i*fNumCols+j).topRight = INDEXH(ptIndexHdl,i*fNumCols_ext+j+1); INDEXH(gridCellInfo,i*fNumCols+j).bottomLeft = INDEXH(ptIndexHdl,(i+1)*fNumCols_ext+j); INDEXH(gridCellInfo,i*fNumCols+j).bottomRight = INDEXH(ptIndexHdl,(i+1)*fNumCols_ext+j+1); } else INDEXH(gridCellInfo,i*fNumCols+j).cellNum = -1; } } ntri = cellNum*2; // each water cell is split into two triangles if(!(topo = (TopologyHdl)_NewHandleClear(ntri * sizeof(Topology)))){err = memFullErr; goto done;} for (i=0;i<nv_ext;i++) { if (INDEXH(ptIndexHdl,i) != -1) { INDEXH(verdatPtsH,numVerdatPts) = i; //INDEXH(verdatPtsH,INDEXH(ptIndexHdl,i)) = i; numVerdatPts++; } } _SetHandleSize((Handle)verdatPtsH,numVerdatPts*sizeof(**verdatPtsH)); pts = (LongPointHdl)_NewHandle(sizeof(LongPoint)*(numVerdatPts)); if(pts == nil) { strcpy(errmsg,"Not enough memory to triangulate data."); return -1; } for (i=0; i<=numVerdatPts; i++) // make a list of grid points that will be used for triangles { float fLong, fLat, fDepth, dLon, dLat, dLon1, dLon2, dLat1, dLat2; //double val, u=0., v=0.; LongPoint vertex; if(i < numVerdatPts) { // since velocities are defined at the lower left corner of each grid cell // need to add an extra row/col at the top/right of the grid // set lat/lon based on distance between previous two points // these are just for boundary/drawing purposes, velocities are set to zero index = i+1; n = INDEXH(verdatPtsH,i); iIndex = n/fNumCols_ext; jIndex = n%fNumCols_ext; if (iIndex==0) { if (jIndex<fNumCols) { dLat = INDEXH(fVertexPtsH,fNumCols+jIndex).pLat - INDEXH(fVertexPtsH,jIndex).pLat; fLat = INDEXH(fVertexPtsH,jIndex).pLat - dLat; dLon = INDEXH(fVertexPtsH,fNumCols+jIndex).pLong - INDEXH(fVertexPtsH,jIndex).pLong; fLong = INDEXH(fVertexPtsH,jIndex).pLong - dLon; } else { dLat1 = (INDEXH(fVertexPtsH,jIndex-1).pLat - INDEXH(fVertexPtsH,jIndex-2).pLat); dLat2 = INDEXH(fVertexPtsH,fNumCols+jIndex-1).pLat - INDEXH(fVertexPtsH,fNumCols+jIndex-2).pLat; fLat = 2*(INDEXH(fVertexPtsH,jIndex-1).pLat + dLat1)-(INDEXH(fVertexPtsH,fNumCols+jIndex-1).pLat+dLat2); dLon1 = INDEXH(fVertexPtsH,fNumCols+jIndex-1).pLong - INDEXH(fVertexPtsH,jIndex-1).pLong; dLon2 = (INDEXH(fVertexPtsH,fNumCols+jIndex-2).pLong - INDEXH(fVertexPtsH,jIndex-2).pLong); fLong = 2*(INDEXH(fVertexPtsH,jIndex-1).pLong-dLon1)-(INDEXH(fVertexPtsH,jIndex-2).pLong-dLon2); } } else { if (jIndex<fNumCols) { fLat = INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex).pLat; fLong = INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex).pLong; //u = INDEXH(velocityH,(iIndex-1)*fNumCols+jIndex).u; //v = INDEXH(velocityH,(iIndex-1)*fNumCols+jIndex).v; } else { dLat = INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex-1).pLat - INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex-2).pLat; fLat = INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex-1).pLat + dLat; dLon = INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex-1).pLong - INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex-2).pLong; fLong = INDEXH(fVertexPtsH,(iIndex-1)*fNumCols+jIndex-1).pLong + dLon; } } vertex.v = (long)(fLat*1e6); vertex.h = (long)(fLong*1e6); fDepth = 1.; INDEXH(pts,i) = vertex; } else { // for outputting a verdat the last line should be all zeros index = 0; fLong = fLat = fDepth = 0.0; } ///////////////////////////////////////////////// } // figure out the bounds triBounds = voidWorldRect; if(pts) { LongPoint thisLPoint; if(numVerdatPts > 0) { WorldPoint wp; for(i=0;i<numVerdatPts;i++) { thisLPoint = INDEXH(pts,i); wp.pLat = thisLPoint.v; wp.pLong = thisLPoint.h; AddWPointToWRect(wp.pLat, wp.pLong, &triBounds); } } } DisplayMessage("NEXTMESSAGETEMP"); DisplayMessage("Making Triangles"); ///////////////////////////////////////////////// for (i=0;i<fNumRows;i++) { for (j=0;j<fNumCols;j++) { if (INDEXH(landWaterInfo,i*fNumCols+j)==-1) continue; waterCellNum = INDEXH(gridCellInfo,i*fNumCols+j).cellNum; // split each cell into 2 triangles triIndex1 = 2*waterCellNum; triIndex2 = 2*waterCellNum+1; // top/left tri in rect (*topo)[triIndex1].vertex1 = INDEXH(gridCellInfo,i*fNumCols+j).topRight; (*topo)[triIndex1].vertex2 = INDEXH(gridCellInfo,i*fNumCols+j).topLeft; (*topo)[triIndex1].vertex3 = INDEXH(gridCellInfo,i*fNumCols+j).bottomLeft; if (j==0 || INDEXH(gridCellInfo,i*fNumCols+j-1).cellNum == -1) (*topo)[triIndex1].adjTri1 = -1; else { (*topo)[triIndex1].adjTri1 = INDEXH(gridCellInfo,i*fNumCols+j-1).cellNum * 2 + 1; } (*topo)[triIndex1].adjTri2 = triIndex2; if (i==0 || INDEXH(gridCellInfo,(i-1)*fNumCols+j).cellNum==-1) (*topo)[triIndex1].adjTri3 = -1; else { (*topo)[triIndex1].adjTri3 = INDEXH(gridCellInfo,(i-1)*fNumCols+j).cellNum * 2 + 1; } // bottom/right tri in rect (*topo)[triIndex2].vertex1 = INDEXH(gridCellInfo,i*fNumCols+j).bottomLeft; (*topo)[triIndex2].vertex2 = INDEXH(gridCellInfo,i*fNumCols+j).bottomRight; (*topo)[triIndex2].vertex3 = INDEXH(gridCellInfo,i*fNumCols+j).topRight; if (j==fNumCols-1 || INDEXH(gridCellInfo,i*fNumCols+j+1).cellNum == -1) (*topo)[triIndex2].adjTri1 = -1; else { (*topo)[triIndex2].adjTri1 = INDEXH(gridCellInfo,i*fNumCols+j+1).cellNum * 2; } (*topo)[triIndex2].adjTri2 = triIndex1; if (i==fNumRows-1 || INDEXH(gridCellInfo,(i+1)*fNumCols+j).cellNum == -1) (*topo)[triIndex2].adjTri3 = -1; else { (*topo)[triIndex2].adjTri3 = INDEXH(gridCellInfo,(i+1)*fNumCols+j).cellNum * 2; } } } DisplayMessage("NEXTMESSAGETEMP"); DisplayMessage("Making Dag Tree"); MySpinCursor(); // JLM 8/4/99 tree = MakeDagTree(topo, (LongPoint**)pts, errmsg); MySpinCursor(); // JLM 8/4/99 if (errmsg[0]) {err = -1; goto done;} // sethandle size of the fTreeH to be tree.fNumBranches, the rest are zeros _SetHandleSize((Handle)tree.treeHdl,tree.numBranches*sizeof(DAG)); ///////////////////////////////////////////////// fVerdatToNetCDFH = verdatPtsH; ///////////////////////////////////////////////// triGrid = new TTriGridVel; if (!triGrid) { err = true; TechError("Error in NetCDFWindMoverCurv::ReorderPoints()","new TTriGridVel",err); goto done; } fGrid = (TTriGridVel*)triGrid; triGrid -> SetBounds(triBounds); dagTree = new TDagTree(pts,topo,tree.treeHdl,velH,tree.numBranches); if(!dagTree) { err = -1; printError("Unable to create dag tree."); goto done; } triGrid -> SetDagTree(dagTree); //triGrid -> SetDepths(totalDepthH); // used by PtCurMap to check vertical movement pts = 0; // because fGrid is now responsible for it topo = 0; // because fGrid is now responsible for it velH = 0; // because fGrid is now responsible for it tree.treeHdl = 0; // because fGrid is now responsible for it velH = 0; // because fGrid is now responsible for it ///////////////////////////////////////////////// done: if (landWaterInfo) {DisposeHandle((Handle)landWaterInfo); landWaterInfo=0;} if (ptIndexHdl) {DisposeHandle((Handle)ptIndexHdl); ptIndexHdl = 0;} if (gridCellInfo) {DisposeHandle((Handle)gridCellInfo); gridCellInfo = 0;} if(err) { if(!errmsg[0]) strcpy(errmsg,"An error occurred in NetCDFWindMoverCurv::ReorderPoints"); printError(errmsg); if(pts) {DisposeHandle((Handle)pts); pts=0;} if(topo) {DisposeHandle((Handle)topo); topo=0;} if(velH) {DisposeHandle((Handle)velH); velH=0;} if(tree.treeHdl) {DisposeHandle((Handle)tree.treeHdl); tree.treeHdl=0;} if(fGrid) { fGrid ->Dispose(); delete fGrid; fGrid = 0; } if (verdatPtsH) {DisposeHandle((Handle)verdatPtsH); verdatPtsH = 0;} if (maskH2) {DisposeHandle((Handle)maskH2); maskH2 = 0;} } if (velocityH) {DisposeHandle((Handle)velocityH); velocityH = 0;} return err; }