Line data Source code
1 : //# FlagAgentShadow.cc: This file contains the implementation of the FlagAgentShadow class.
2 : //#
3 : //# CASA - Common Astronomy Software Applications (http://casa.nrao.edu/)
4 : //# Copyright (C) Associated Universities, Inc. Washington DC, USA 2011, All rights reserved.
5 : //# Copyright (C) European Southern Observatory, 2011, All rights reserved.
6 : //#
7 : //# This library is free software; you can redistribute it and/or
8 : //# modify it under the terms of the GNU Lesser General Public
9 : //# License as published by the Free software Foundation; either
10 : //# version 2.1 of the License, or (at your option) any later version.
11 : //#
12 : //# This library is distributed in the hope that it will be useful,
13 : //# but WITHOUT ANY WARRANTY, without even the implied warranty of
14 : //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : //# Lesser General Public License for more details.
16 : //#
17 : //# You should have received a copy of the GNU Lesser General Public
18 : //# License along with this library; if not, write to the Free Software
19 : //# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 : //# MA 02111-1307 USA
21 : //# $Id: $
22 :
23 : #include <flagging/Flagging/FlagAgentShadow.h>
24 :
25 : #include <casacore/measures/Measures/MBaseline.h>
26 : #include <casacore/measures/Measures/MCBaseline.h>
27 : #include <casacore/measures/Measures/MCDirection.h>
28 : #include <casacore/measures/Measures/MCuvw.h>
29 : #include <casacore/measures/Measures/MDirection.h>
30 : #include <casacore/measures/Measures/MEpoch.h>
31 : #include <casacore/measures/Measures/Muvw.h>
32 : #include <casacore/measures/TableMeasures/ScalarMeasColumn.h>
33 :
34 : using namespace casacore;
35 : namespace casa { //# NAMESPACE CASA - BEGIN
36 :
37 : // Definition of static members for common pre-processing
38 : vector<Int> FlagAgentShadow::shadowedAntennas_p;
39 : casa::async::Mutex FlagAgentShadow::staticMembersMutex_p;
40 : vector<bool> FlagAgentShadow::startedProcessing_p;
41 : bool FlagAgentShadow::preProcessingDone_p = false;
42 : uShort FlagAgentShadow::nAgents_p = 0;
43 :
44 0 : FlagAgentShadow::FlagAgentShadow(FlagDataHandler *dh, Record config, Bool writePrivateFlagCube, Bool flag):
45 0 : FlagAgentBase(dh,config,ROWS_PREPROCESS_BUFFER,writePrivateFlagCube,flag)
46 : {
47 0 : setAgentParameters(config);
48 :
49 : // Set preProcessingDone_p static member to false
50 0 : preProcessingDone_p = false;
51 :
52 : // Request loading antenna1,antenna2 and uvw
53 0 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna1);
54 0 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna2);
55 0 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Uvw);
56 : /////flagDataHandler_p->preLoadColumn(VisBufferComponent2::Time);
57 0 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::TimeCentroid);
58 0 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::PhaseCenter);
59 : /////flagDataHandler_p->preLoadColumn(vi::Direction1);
60 :
61 : // FlagAgentShadow counters and ids to handle static variables
62 0 : staticMembersMutex_p.acquirelock();
63 0 : agentNumber_p = nAgents_p;
64 0 : nAgents_p += 1;
65 0 : staticMembersMutex_p.unlock();
66 :
67 : // Set timekeeper to zero - this will later detect when the timestep changes.
68 0 : currTime_p=0.0;
69 :
70 : // Append the supplied additional antennas to COPIES of existing base-class lists.
71 :
72 : // Append to existing lists of antenna info.
73 0 : Int nAntsInMS = flagDataHandler_p->antennaNames_p->nelements();
74 0 : Int nNewAnts=0;
75 :
76 :
77 : // antennaNames_p
78 : // antennaDiameters_p
79 : // antennaPositions_p
80 0 : if( additionalAntennas_p.nfields() )
81 : {
82 :
83 : // For debugging...
84 : //ostringstream recprint;
85 : //additionalAntennas_p.print(recprint);
86 : //cout << " Additional Antennas : " << recprint.str() << endl;
87 :
88 : // TODO : Verify input Record. If invalid, print warning and proceed with no extra antennas.
89 0 : Bool validants=true;
90 0 : String errorReason;
91 0 : for(Int anew=0; anew<(Int) additionalAntennas_p.nfields(); anew++)
92 : {
93 : // Extract the record.
94 0 : Record arec = additionalAntennas_p.subRecord(RecordFieldId(String::toString(anew)));
95 :
96 0 : if( ! arec.isDefined("diameter") ||
97 0 : ( arec.type(arec.fieldNumber("diameter")) != casacore::TpFloat &&
98 0 : arec.type(arec.fieldNumber("diameter")) != casacore::TpInt &&
99 0 : arec.type(arec.fieldNumber("diameter")) != casacore::TpDouble ) )
100 : {
101 0 : validants=false;
102 0 : errorReason += String("Input Record [") + String::toString(anew) + ("] needs a field 'diameter' of type <double> \n");
103 : }
104 :
105 0 : if( ! arec.isDefined("position") ||
106 0 : ( arec.type(arec.fieldNumber("position")) != casacore::TpArrayFloat &&
107 0 : arec.type(arec.fieldNumber("position")) != casacore::TpInt &&
108 0 : arec.type(arec.fieldNumber("position")) != casacore::TpArrayDouble ) )
109 : {
110 0 : validants=false;
111 0 : errorReason += String("Input Record [") + String::toString(anew) + ("] needs a field 'position' of type Array<double>\n");
112 : }
113 : else
114 : {
115 0 : Array<Double> tpos;
116 0 : arec.get( RecordFieldId(String("position")) , tpos );
117 0 : if(tpos.shape() != IPosition(1,3))
118 : {
119 0 : validants=false;
120 0 : errorReason += String("'position' for Record [") + String::toString(anew)+ ("] must be a vector of 3 floats or doubles\n");
121 : }
122 0 : }
123 :
124 0 : }// end of valid-ants loop
125 :
126 : // If antenna list is valid, set the number of new antennas to add.
127 0 : if(validants)
128 : {
129 0 : nNewAnts = additionalAntennas_p.nfields();
130 : }
131 : else // warn and continue.
132 : {
133 0 : *logger_p << LogIO::WARN << "NOT using additional antennas for shadow calculations, for the following reason(s) : " << errorReason << LogIO::POST;
134 : }
135 0 : }// if additionalAnts exist.
136 :
137 :
138 : // Make holders for cumulative information
139 0 : shadowAntennaPositions_p.resize(nAntsInMS+nNewAnts);
140 : /// shadowAntennaNames_p.resize(nAntsInMS+nNewAnts);
141 0 : shadowAntennaDiameters_p.resize(nAntsInMS+nNewAnts);
142 :
143 : // Copy existing antennas into these arrays
144 0 : for(Int antid=0;antid<nAntsInMS;antid++)
145 : {
146 0 : shadowAntennaPositions_p[antid] = flagDataHandler_p->antennaPositions_p->operator()(antid);
147 : ///shadowAntennaNames_p[antid] = flagDataHandler_p->antennaNames_p->operator()(antid);
148 0 : shadowAntennaDiameters_p[antid] = flagDataHandler_p->antennaDiameters_p->operator()(antid);
149 : }
150 :
151 : // If any additional antennas are given, and are valid, add them to the lists
152 0 : for(Int antid=0;antid<nNewAnts;antid++)
153 : {
154 : // Extract the record.
155 0 : Record arec = additionalAntennas_p.subRecord(RecordFieldId(String::toString(antid)));
156 :
157 : // Extract and add new positions
158 0 : Array<Double> aposarr;
159 0 : arec.get( RecordFieldId(String("position")) , aposarr );
160 0 : Vector<Double> aposvec(aposarr);
161 0 : MVPosition apos(aposvec(0),aposvec(1),aposvec(2));
162 0 : shadowAntennaPositions_p[nAntsInMS+antid] = MPosition(apos,MPosition::Types(MPosition::ITRF));
163 :
164 : // Extract and add new diameters
165 : Double adia;
166 0 : arec.get( RecordFieldId(String("diameter")) , adia );
167 0 : shadowAntennaDiameters_p[nAntsInMS+antid] = adia;
168 :
169 : // Extract and add new names
170 : ///String aname aname;
171 : ///arec.get( RecordFieldId(String("name")) , aname );
172 : ///shadowAntennaNames_p[nAntsInMS+antid] = aname;
173 :
174 0 : }
175 :
176 :
177 0 : firststep_p=false; // Set to true, to print a debug message (antenna uvw coordinates for the first row in the first visbuffer seen by this code...
178 :
179 0 : }// end of constructor
180 :
181 0 : FlagAgentShadow::~FlagAgentShadow()
182 : {
183 : // Compiler automagically calls FlagAgentBase::~FlagAgentBase()
184 :
185 : // NOTE: The following is necessary because the static variables
186 : // persist even if all the instances of the class were deleted!
187 0 : staticMembersMutex_p.acquirelock();
188 0 : agentNumber_p = nAgents_p;
189 0 : nAgents_p -= 1;
190 0 : staticMembersMutex_p.unlock();
191 0 : }
192 :
193 : void
194 0 : FlagAgentShadow::setAgentParameters(Record config)
195 : {
196 0 : logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
197 : int exists;
198 :
199 : // Amount of shadowing to allow. Float or Double, in units of Meters.
200 0 : exists = config.fieldNumber ("tolerance");
201 0 : if (exists >= 0)
202 : {
203 0 : if( config.type(exists) != casacore::TpDouble && config.type(exists) != casacore::TpFloat && config.type(exists) != casacore::TpInt )
204 : {
205 0 : throw( AipsError ( "Parameter 'tolerance' must be of type 'double'" ) );
206 : }
207 :
208 0 : shadowTolerance_p = config.asDouble("tolerance");
209 : }
210 : else
211 : {
212 0 : shadowTolerance_p = 0.0;
213 : }
214 :
215 0 : *logger_p << logLevel_p << " tolerance is " << shadowTolerance_p << " meters "<< LogIO::POST;
216 :
217 : // A list of antenna parameters, to add to those in the antenna subtable, to calculate shadows.
218 0 : exists = config.fieldNumber ("addantenna");
219 0 : if (exists >= 0)
220 : {
221 0 : if( config.type(exists) != casacore::TpRecord )
222 : {
223 0 : throw( AipsError ( "Parameter 'addantenna' must be of type 'record/dict'" ) );
224 : }
225 :
226 0 : additionalAntennas_p = config.subRecord( RecordFieldId("addantenna") );
227 : }
228 : else
229 : {
230 0 : additionalAntennas_p = Record();
231 : }
232 :
233 0 : ostringstream recprint;
234 0 : additionalAntennas_p.print(recprint);
235 0 : *logger_p << logLevel_p << " addantenna is " << recprint.str() << LogIO::POST;
236 :
237 0 : return;
238 0 : }
239 :
240 : void
241 0 : FlagAgentShadow::preProcessBuffer(const vi::VisBuffer2 &visBuffer)
242 : {
243 0 : if (nAgents_p > 1)
244 : {
245 0 : staticMembersMutex_p.acquirelock();
246 :
247 0 : if (!preProcessingDone_p)
248 : {
249 : // Reset processing state variables
250 0 : if (startedProcessing_p.size() != nAgents_p) startedProcessing_p.resize(nAgents_p,false);
251 0 : for (vector<bool>::iterator iter = startedProcessing_p.begin();iter != startedProcessing_p.end();iter++)
252 : {
253 0 : *iter = false;
254 : }
255 :
256 : // Do actual pre-processing
257 0 : preProcessBufferCore(visBuffer);
258 :
259 : // Mark pre-processing as done so that other agents don't redo it
260 0 : preProcessingDone_p = true;
261 : }
262 :
263 0 : staticMembersMutex_p.unlock();
264 : }
265 : else
266 : {
267 0 : preProcessBufferCore(visBuffer);
268 : }
269 :
270 0 : return;
271 : }
272 :
273 : void
274 0 : FlagAgentShadow::preProcessBufferCore(const vi::VisBuffer2 &/*visBuffer*/)
275 : {
276 : // This function is empty, because shadowedAntennas_p needs to be re-calculated for
277 : // every new timestep, and it is done inside computeRowFlags(), whenever the
278 : // timestep changes.
279 0 : }
280 :
281 : // (1) Go through all listed baselines for the current timestep, use existing uvw values to
282 : // check for shadowing.
283 : // (2) If not ALL baselines exist in the current timestep, or if additional antennas have been
284 : // supplied, calculate u,v,w, for all antennas, and from there, uvw for all remaining baselines
285 : // and check for shadows between them too.
286 : // Note : The calculation of UVW happens per antenna, not baselines. This is an optimization.
287 : // Note : The direction used for UVW re-calculation is the phasecenter, and not the pointing
288 : // direction of each antenna. This was done to prevent a performance hit due to
289 : // accessing vb.direction1() which accesses MS derived columns, which is also thread-unsafe.
290 : // The only situation where phasecenter is inaccurate, is on-the-fly mosaicing, but
291 : // unless one is doing an on-the-fly mosaic of the whole sky, using a single phase-center (!!!)
292 : // this will not adversely affect shadow flags.
293 0 : void FlagAgentShadow::calculateShadowedAntennas(const vi::VisBuffer2 &visBuffer, Int rownr)
294 : {
295 : // Init the list of antennas.
296 0 : shadowedAntennas_p.clear();
297 : Double u,v,w, uvDistance;
298 0 : Int nAnt = shadowAntennaDiameters_p.nelements();
299 :
300 : // Init the list of baselines, to later decide which to read and which to recalculate.
301 0 : Vector<Bool> listBaselines(nAnt*(nAnt-1)/2);
302 0 : listBaselines = false;
303 :
304 : // We know the starting row for this timestep. Find the ending row.
305 : // This assumes that all baselines are grouped together.
306 : // This is guaranteed by the sort-order defined for the visIterator.
307 0 : Int endrownr = rownr;
308 0 : Double timeval = visBuffer.timeCentroid()(rownr) ;
309 0 : for (Int row_i=rownr;row_i<visBuffer.nRows();row_i++)
310 : {
311 0 : if(timeval < visBuffer.timeCentroid()(row_i)) // we have touched the next timestep
312 : {
313 0 : endrownr = row_i-1;
314 0 : break;
315 : }
316 : else
317 : {
318 0 : endrownr = row_i;
319 : }
320 : }
321 :
322 : // See CAS-12555 for why this loop which was commented out for long time was
323 : // brought back.
324 : // (1) Now, for all rows between 'rownr' and 'endrownr', calculate shadowed Ants.
325 : // This row range represents all listed baselines in the "current" timestep.
326 : // For those, we take the u,v,w from the UVW column of the MS
327 0 : for (Int row_i=rownr;row_i<=endrownr;row_i++)
328 : {
329 : // Retrieve antenna ids
330 0 : auto antenna1 = visBuffer.antenna1()(row_i);
331 0 : auto antenna2 = visBuffer.antenna2()(row_i);
332 :
333 : // Check if this row corresponds to autocorrelation, or radiometer, sqld, etc.
334 : // (Antennas don't shadow themselves)
335 0 : if (antenna1 == antenna2) continue;
336 : // Record the baseline being processed
337 0 : listBaselines[baselineIndex(nAnt,antenna1,antenna2)] = true;
338 :
339 : // Compute uv distance
340 0 : u = visBuffer.uvw()(0,row_i);
341 0 : v = visBuffer.uvw()(1,row_i);
342 0 : w = visBuffer.uvw()(2,row_i);
343 0 : uvDistance = sqrt(u*u + v*v);
344 :
345 0 : decideBaselineShadow(uvDistance, w, antenna1, antenna2);
346 :
347 : }// end of for 'row'
348 :
349 :
350 : // (2) Now, if there are any untouched baselines, calculate 'uvw' for all antennas,
351 : // using 'computeAntUVW(), and fill in missing baselines.
352 : // This is the part that picks up invisible antennas, whether they come from the antenna_subtable or
353 : // are externally supplied.
354 0 : if(product(listBaselines)==false) // could use anyEQ(listBaselines, false)
355 : {
356 : // For the current timestep, compute UVWs for all antennas.
357 : // uvwAnt_p will be filled these values.
358 0 : computeAntUVW(visBuffer, rownr);
359 :
360 : // For all untouched baselines, calculate uvw and check for shadows.
361 0 : for (Int antenna1=0; antenna1<nAnt; antenna1++)
362 : {
363 0 : Double u1=uvwAnt_p(0,antenna1), v1=uvwAnt_p(1,antenna1), w1=uvwAnt_p(2,antenna1);
364 0 : for (Int antenna2=antenna1; antenna2<nAnt; antenna2++)
365 : {
366 : // Check if this row corresponds to autocorrelation (Antennas don't shadow themselves)
367 0 : if (antenna1 == antenna2) continue;
368 :
369 : // Proceed only if we don't already have this.
370 0 : if(listBaselines[baselineIndex(nAnt,antenna1,antenna2)] == false)
371 : {
372 0 : Double u2=uvwAnt_p(0,antenna2), v2=uvwAnt_p(1,antenna2), w2=uvwAnt_p(2,antenna2);
373 :
374 0 : u = u2-u1;
375 0 : v = v2-v1;
376 0 : w = w2-w1;
377 0 : uvDistance = sqrt(u*u + v*v);
378 :
379 0 : if(firststep_p==true) // this is only a debug message here....
380 : {
381 0 : cout << "Ant1 : " << antenna1 << " : " << u1 << "," << v1 << "," << w1 << " Ant2 : " << antenna2 << " : " << u2 << "," << v2<< "," << w2 << " UVW : " << u << "," << v << "," << w << endl;
382 : }
383 :
384 0 : decideBaselineShadow(uvDistance, w, antenna1, antenna2);
385 : }
386 : }
387 : }
388 : }
389 :
390 0 : firststep_p=false;// debug message should happen only once (at most).
391 :
392 0 : }// end of calculateShadowedAntennas
393 :
394 0 : uInt FlagAgentShadow::baselineIndex(uInt nAnt, uInt a1, uInt a2)
395 : {
396 0 : uInt bindex = (nAnt-1)*nAnt/2 - ((nAnt-1)-a1)*((nAnt-1)-a1+1)/2 + a2-a1-1 ;
397 0 : AlwaysAssert( bindex < nAnt*(nAnt-1)/2 ,AipsError);
398 0 : return bindex;
399 : }
400 :
401 :
402 0 : void FlagAgentShadow::decideBaselineShadow(Double uvDistance, Double w, Int antenna1, Int antenna2)
403 : {
404 : Double antennaDiameter1,antennaDiameter2, antennaDistance;
405 :
406 : // Get antenna diameter
407 0 : antennaDiameter1 = shadowAntennaDiameters_p[antenna1];
408 0 : antennaDiameter2 = shadowAntennaDiameters_p[antenna2];
409 :
410 : // Compute effective distance for shadowing
411 0 : antennaDistance = (antennaDiameter1+antennaDiameter2)/2.0;
412 :
413 : // Check if one of the antennas can be shadowed
414 0 : if (uvDistance < antennaDistance - shadowTolerance_p)
415 : {
416 : ///////////////////////////////////////////////////////
417 : // Conventions.
418 : // (A) For a Right Handed coordinate system, with 'w' pointing towards the source....
419 : // ( as defined here : http://casa.nrao.edu/Memos/229.html#SECTION00041000000000000000 )
420 : // if(w>0) antenna1 is shadowed by antenna2
421 : // if(w<0) antenna2 is shadowed by antenna1
422 : //
423 : // This is implemented in casapy 3.4 and 4.0
424 : //
425 : // (B) For a Left Handed Coordinate system, with 'w' pointing away from the source...
426 : // ( You get B by flipping the sign on all three axes (u,v,w) of A ).
427 : // This is what is present in the data (i.e. filler, simulator, (our use of Measures?)).
428 : // if(w<0) antenna1 is shadowed by antenna2
429 : // if(w>0) antenna2 is shadowed by antenna1
430 : //
431 : // This is implemented in casapy 4.1 ( from 1 Feb 2013 onwards ).
432 : //
433 : ///////////////////////////////////////////////////////
434 :
435 : // if (w>0) ////// as in casapy 3.4 and casapy 4.0
436 0 : if (w<0) ////// casapy 4.1 onwards.
437 : {
438 0 : if (std::find (shadowedAntennas_p.begin(), shadowedAntennas_p.end(), antenna1) == shadowedAntennas_p.end())
439 : {
440 0 : shadowedAntennas_p.push_back(antenna1);
441 : }
442 : }
443 : else
444 : {
445 0 : if (std::find (shadowedAntennas_p.begin(), shadowedAntennas_p.end(), antenna2) == shadowedAntennas_p.end())
446 : {
447 0 : shadowedAntennas_p.push_back(antenna2);
448 : }
449 : }
450 : }
451 0 : }
452 :
453 : /// NOTE : This function is almost a copy of
454 : /// ms/MeasurementSets/NewMSSimulator::calcAntUVW
455 : /// -- TODO : try to re-use that code by moving out all private-member accesses in the simulator.
456 : /// -- TOCHECK : Should we use vb.timeCentroid() ?? This gives closest results so far, for real and simulated data.
457 : /// NOTE : We are using vb.phasecenter() instead of vb.direction() because of a performance hit
458 : /// and thread-safety problems with vb.direction1().
459 0 : Bool FlagAgentShadow::computeAntUVW(const vi::VisBuffer2 &vb, Int rownr)
460 : {
461 : // Get time and timeinterval from the visbuffer.
462 : Double Time;
463 :
464 : // Centroid gives the closest values to uvws in the MS. For simulated data, gives exact values.
465 0 : Time = vb.timeCentroid()(rownr);
466 :
467 : // Make the Time epoch.
468 0 : MEpoch epoch(Quantity((Time), "s"), MEpoch::UT1);
469 :
470 : // Get the MDirection of the feed of antenna 1. Assume all ants point in the same direction.
471 : //MDirection refdir(vb.direction1()(rownr));
472 0 : MDirection refdir(vb.phaseCenter()); // Each visbuf sees only one fieldId
473 :
474 : // read position of first antenna as reference. Does not matter, since uvws are only differences.
475 0 : MPosition obsPos( shadowAntennaPositions_p[0] );
476 :
477 : // Input measure ref. frame
478 0 : MVPosition basePos=obsPos.getValue();
479 0 : MeasFrame measFrame(obsPos);
480 0 : measFrame.set(epoch);
481 0 : measFrame.set(refdir);
482 :
483 : // Convert direction to J2000
484 0 : MDirection::Convert covertionEngine(refdir,MDirection::Ref(MDirection::J2000,measFrame)); // Each visbuf sees only one fieldId
485 0 : MDirection refdirJ2000 = covertionEngine(refdir);
486 :
487 : // Baseline measure
488 0 : MVBaseline mvbl;
489 0 : MBaseline basMeas;
490 0 : MBaseline::Ref basref(MBaseline::ITRF, measFrame);
491 0 : basMeas.set(mvbl, basref);
492 0 : basMeas.getRefPtr()->set(measFrame);
493 :
494 : // going to convert from ITRF vector to J2000 baseline vector I guess !
495 0 : if(refdirJ2000.getRef().getType() != MDirection::J2000)
496 0 : throw(AipsError("Internal FlagAgentShadow restriction : Conversion to J2000 did not work"));
497 :
498 0 : Int nAnt = shadowAntennaDiameters_p.nelements();
499 0 : if(uvwAnt_p.shape() != IPosition(2,3,nAnt))
500 : {
501 0 : uvwAnt_p.resize(3,nAnt);
502 : }
503 :
504 0 : MBaseline::Convert elconv(basMeas, MBaseline::Ref(MBaseline::J2000));
505 0 : Muvw::Convert uvwconv(Muvw(), Muvw::Ref(Muvw::J2000, measFrame));
506 0 : for(Int k=0; k< nAnt; ++k)
507 : {
508 0 : MPosition antpos=shadowAntennaPositions_p(k); // msc.antenna().positionMeas()(k);
509 :
510 0 : MVBaseline mvblA(obsPos.getValue(), antpos.getValue());
511 0 : basMeas.set(mvblA, basref);
512 0 : MBaseline bas2000 = elconv(basMeas);
513 0 : MVuvw uvw2000 (bas2000.getValue(), refdirJ2000.getValue());
514 0 : const Vector<double>& xyz = uvw2000.getValue();
515 0 : uvwAnt_p.column(k)=xyz;
516 0 : }
517 :
518 0 : return true;
519 0 : }
520 :
521 :
522 : bool
523 0 : FlagAgentShadow::computeRowFlags(const vi::VisBuffer2 &visBuffer, FlagMapper &/*flags*/, uInt row)
524 : {
525 : // If we have advanced to a new timestep, calculate new antenna UVW values and shadowed antennas
526 : // This function resets and fills 'shadowedAntennas_p'.
527 0 : if( currTime_p != visBuffer.timeCentroid()(row) )
528 : {
529 0 : currTime_p = visBuffer.timeCentroid()(row) ;
530 0 : calculateShadowedAntennas(visBuffer, row);
531 : }
532 :
533 0 : bool flagRow = false;
534 : // Flag row if either antenna1 or antenna2 are in the list of shadowed antennas
535 0 : Int antenna1 = visBuffer.antenna1()[row];
536 0 : Int antenna2 = visBuffer.antenna2()[row];
537 0 : if ( (std::find (shadowedAntennas_p.begin(), shadowedAntennas_p.end(), antenna1) != shadowedAntennas_p.end()) or
538 0 : (std::find (shadowedAntennas_p.begin(), shadowedAntennas_p.end(), antenna2) != shadowedAntennas_p.end()) )
539 : {
540 0 : flagRow = true;
541 : }
542 :
543 0 : if ((nAgents_p > 1) and preProcessingDone_p)
544 : {
545 0 : startedProcessing_p[agentNumber_p] = true;
546 0 : if (std::find (startedProcessing_p.begin(), startedProcessing_p.end(), false) == startedProcessing_p.end())
547 : {
548 0 : preProcessingDone_p = false;
549 : }
550 : }
551 :
552 0 : return flagRow;
553 : }
554 :
555 :
556 : #if 0
557 :
558 : // // Copy of the old version of this function. It has code for "always recalculate UVW, never recalc UVW
559 : // // and 'decide when to calc UVW'. Above, only the 'decide when to calc UVW' part is used.
560 : // void FlagAgentShadow::calculateShadowedAntennas(const VisBuffer &visBuffer, Int rownr)
561 : // {
562 : // // Init the list of antennas.
563 : // shadowedAntennas_p.clear();
564 : // Double u,v,w, uvDistance;
565 : // Int nAnt = shadowAntennaDiameters_p.nelements();
566 :
567 : // // Init the list of baselines, to later decide which to read and which to recalculate.
568 : // Vector<Bool> listBaselines(nAnt*(nAnt-1)/2);
569 : // listBaselines = false;
570 :
571 : // //uInt countread=0;
572 : // //uInt countcalc=0;
573 : // //Double reftime = 4.794e+09;
574 :
575 : // if (decideUVW_p==true)
576 : // {
577 : // // We know the starting row for this timestep. Find the ending row.
578 : // // This assumes that all baselines are grouped together.
579 : // // This is guaranteed by the sort-order defined for the visIterator.
580 : // Int endrownr = rownr;
581 : // Double timeval = visBuffer.timeCentroid()(rownr) ;
582 : // for (Int row_i=rownr;row_i<visBuffer.nRow();row_i++)
583 : // {
584 : // if(timeval < visBuffer.timeCentroid()(row_i)) // we have touched the next timestep
585 : // {
586 : // endrownr = row_i-1;
587 : // break;
588 : // }
589 : // else
590 : // {
591 : // endrownr = row_i;
592 : // }
593 : // }
594 :
595 : // //cout << "For time : " << timeval-4.73423e+09 << " start : " << rownr << " end : " << endrownr << endl;
596 :
597 : // // Now, for all rows between 'rownr' and 'endrownr', calculate shadowed Ants.
598 : // // This row range represents all listed baselines in the "current" timestep.
599 : // Int antenna1, antenna2;
600 : // for (Int row_i=rownr;row_i<=endrownr;row_i++)
601 : // {
602 : // // Retrieve antenna ids
603 : // antenna1 = visBuffer.antenna1()(row_i);
604 : // antenna2 = visBuffer.antenna2()(row_i);
605 :
606 : // // Check if this row corresponds to autocorrelation (Antennas don't shadow themselves)
607 : // if (antenna1 == antenna2) continue;
608 :
609 : // // Record the baseline being processed
610 : // listBaselines[baselineIndex(nAnt,antenna1,antenna2)] = true;
611 :
612 : // // Compute uv distance
613 : // u = visBuffer.uvw()(row_i)(0);
614 : // v = visBuffer.uvw()(row_i)(1);
615 : // w = visBuffer.uvw()(row_i)(2);
616 : // uvDistance = sqrt(u*u + v*v);
617 :
618 : // //if(row_i==0 && rownr==0) cout << " Row : " << row_i << " uvdist : " << uvDistance << " w : " << w << " time-x : " << visBuffer.timeCentroid()(row_i)-reftime << endl;
619 :
620 : // decideBaselineShadow(uvDistance, w, antenna1, antenna2);
621 : // //countread++;
622 :
623 : // }// end of for 'row'
624 :
625 : // // Now, if there are any untouched baselines, calculate 'uvw' for all antennas, and fill in missing baselines.
626 : // if(product(listBaselines)==false)
627 : // {
628 : // // For the current timestep, compute UVWs for all antennas.
629 : // // uvwAnt_p will be filled these values.
630 : // computeAntUVW(visBuffer, rownr);
631 :
632 : // for (Int antenna1=0; antenna1<nAnt; antenna1++)
633 : // {
634 : // Double u1=uvwAnt_p(0,antenna1), v1=uvwAnt_p(1,antenna1), w1=uvwAnt_p(2,antenna1);
635 : // for (Int antenna2=antenna1; antenna2<nAnt; antenna2++)
636 : // {
637 : // // Check if this row corresponds to autocorrelation (Antennas don't shadow themselves)
638 : // if (antenna1 == antenna2) continue;
639 :
640 : // if(listBaselines[baselineIndex(nAnt,antenna1,antenna2)] == false)
641 : // {
642 : // Double u2=uvwAnt_p(0,antenna2), v2=uvwAnt_p(1,antenna2), w2=uvwAnt_p(2,antenna2);
643 :
644 : // u = u2-u1;
645 : // v = v2-v1;
646 : // w = w2-w1;
647 : // uvDistance = sqrt(u*u + v*v);
648 : // //countcalc++;
649 :
650 : // //if(rownr==0 && antenna1==tant1 && antenna2==tant2) cout << " (r)Row : " << rownr << " uvdist : " << uvDistance << " w : " << w << " time-x : " << visBuffer.timeCentroid()(rownr)-reftime << endl;
651 :
652 : // decideBaselineShadow(uvDistance, w, antenna1, antenna2);
653 :
654 : // listBaselines[baselineIndex(nAnt,antenna1,antenna2)] = true;
655 : // }
656 : // }
657 : // }
658 : // }
659 :
660 : // }
661 : // else if(recalculateUVW_p)
662 : // {
663 : // // (1) For the current timestep, compute UVWs for all antennas.
664 : // // uvwAnt_p will be filled these values.
665 : // computeAntUVW(visBuffer, rownr);
666 :
667 : // // debug code.
668 : // // Int tant1 = visBuffer.antenna1()(rownr);
669 : // // Int tant2 = visBuffer.antenna2()(rownr);
670 :
671 : // // (2) For all antenna pairs, calculate UVW of the baselines, and check for shadowing.
672 : // for (Int antenna1=0; antenna1<nAnt; antenna1++)
673 : // {
674 : // Double u1=uvwAnt_p(0,antenna1), v1=uvwAnt_p(1,antenna1), w1=uvwAnt_p(2,antenna1);
675 : // for (Int antenna2=antenna1; antenna2<nAnt; antenna2++)
676 : // {
677 : // // Check if this row corresponds to autocorrelation (Antennas don't shadow themselves)
678 : // if (antenna1 == antenna2) continue;
679 :
680 : // Double u2=uvwAnt_p(0,antenna2), v2=uvwAnt_p(1,antenna2), w2=uvwAnt_p(2,antenna2);
681 :
682 : // u = u2-u1;
683 : // v = v2-v1;
684 : // w = w2-w1;
685 : // uvDistance = sqrt(u*u + v*v);
686 : // //countcalc++;
687 :
688 : // //if(rownr==0 && antenna1==tant1 && antenna2==tant2) cout << " (r)Row : " << rownr << " uvdist : " << uvDistance << " w : " << w << " time-x : " << visBuffer.timeCentroid()(rownr)-reftime << endl;
689 :
690 : // decideBaselineShadow(uvDistance, w, antenna1, antenna2);
691 :
692 : // }// end for antenna2
693 : // }// end for antenna1
694 :
695 : // }// end of recalculateUVW_p==true
696 : // else // recalculateUVW_p = false
697 : // {
698 :
699 : // // We know the starting row for this timestep. Find the ending row.
700 : // // This assumes that all baselines are grouped together.
701 : // // This is guaranteed by the sort-order defined for the visIterator.
702 : // Int endrownr = rownr;
703 : // Double timeval = visBuffer.timeCentroid()(rownr) ;
704 : // for (Int row_i=rownr;row_i<visBuffer.nRow();row_i++)
705 : // {
706 : // if(timeval < visBuffer.timeCentroid()(row_i)) // we have touched the next timestep
707 : // {
708 : // endrownr = row_i-1;
709 : // break;
710 : // }
711 : // else
712 : // {
713 : // endrownr = row_i;
714 : // }
715 : // }
716 :
717 : // //cout << "For time : " << timeval-4.73423e+09 << " start : " << rownr << " end : " << endrownr << endl;
718 :
719 : // // Now, for all rows between 'rownr' and 'endrownr', calculate shadowed Ants.
720 : // // This row range represents all baselines in the "current" timestep.
721 : // Int antenna1, antenna2;
722 : // for (Int row_i=rownr;row_i<=endrownr;row_i++)
723 : // {
724 : // // Retrieve antenna ids
725 : // antenna1 = visBuffer.antenna1()(row_i);
726 : // antenna2 = visBuffer.antenna2()(row_i);
727 :
728 : // // Check if this row corresponds to autocorrelation (Antennas don't shadow themselves)
729 : // if (antenna1 == antenna2) continue;
730 :
731 : // // Compute uv distance
732 : // u = visBuffer.uvw()(row_i)(0);
733 : // v = visBuffer.uvw()(row_i)(1);
734 : // w = visBuffer.uvw()(row_i)(2);
735 : // uvDistance = sqrt(u*u + v*v);
736 : // //countread++;
737 :
738 : // //if(row_i==0 && rownr==0) cout << " Row : " << row_i << " uvdist : " << uvDistance << " w : " << w << " time-x : " << visBuffer.timeCentroid()(row_i)-reftime << endl;
739 :
740 : // decideBaselineShadow(uvDistance, w, antenna1, antenna2);
741 :
742 : // }// end of for 'row'
743 : // }
744 :
745 : // //cout << "Row : " << rownr << " read : " << countread << " calc : " << countcalc << endl;
746 :
747 : // }// end of calculateShadowedAntennas
748 :
749 :
750 : #endif
751 :
752 :
753 : } //# NAMESPACE CASA - END
754 :
755 :
|