Line data Source code
1 : //# FlagAgentSummary.cc: This file contains the implementation of the FlagAgentSummary 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/FlagAgentSummary.h>
24 :
25 : #include <casacore/measures/TableMeasures/ScalarMeasColumn.h>
26 :
27 : using namespace casacore;
28 : namespace casa { //# NAMESPACE CASA - BEGIN
29 :
30 400 : FlagAgentSummary::FlagAgentSummary(FlagDataHandler *dh, Record config):
31 400 : FlagAgentBase(dh,config,ROWS_PREPROCESS_BUFFER,false)
32 : {
33 400 : arrayId = 0;
34 400 : fieldId = 0;
35 400 : spw = 0;
36 400 : scan = 0;
37 400 : observationId = 0;
38 :
39 400 : arrayId_str = String("");
40 400 : fieldId_str = String("");
41 400 : spw_str = String("");
42 400 : observationId_str = String("");
43 :
44 400 : spwChannelCounts = false;
45 400 : spwPolarizationCounts = false;
46 400 : baselineCounts = false;
47 400 : fieldCounts = false;
48 400 : display_p = String("none");
49 :
50 400 : setAgentParameters(config);
51 :
52 400 : currentSummary = NULL;
53 400 : fieldSummaryMap.clear();
54 400 : if (fieldCounts)
55 : {
56 1 : currentSummary = NULL;
57 : }
58 : else
59 : {
60 399 : currentSummary = new summary();
61 : }
62 :
63 : // Request loading polarization map to FlagDataHandler
64 400 : flagDataHandler_p->setMapPolarizations(true);
65 :
66 : // Request pre-loading array,field,spw, scan, observation, antenna1, antenna2
67 400 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::ArrayId);
68 400 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::FieldId);
69 400 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Scan);
70 400 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::ObservationId);
71 400 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::SpectralWindows);
72 400 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna1);
73 400 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna2);
74 : //flagDataHandler_p->preLoadColumn(vi::Freq);
75 400 : }
76 :
77 800 : FlagAgentSummary::~FlagAgentSummary()
78 : {
79 400 : if (fieldCounts)
80 : {
81 5 : for(const auto &iter : fieldSummaryMap)
82 : {
83 4 : delete iter.second;
84 : }
85 1 : fieldSummaryMap.clear();
86 : }
87 : else
88 : {
89 399 : delete currentSummary;
90 : }
91 :
92 : // Compiler automagically calls FlagAgentBase::~FlagAgentBase()
93 800 : }
94 :
95 : void
96 400 : FlagAgentSummary::setAgentParameters(Record config)
97 : {
98 400 : logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
99 :
100 : int exists;
101 :
102 400 : exists = config.fieldNumber ("spwchan");
103 400 : if (exists >= 0)
104 : {
105 388 : if( config.type(exists) != TpBool )
106 : {
107 0 : throw( AipsError ( "Parameter 'spwchan' must be of type 'bool'" ) );
108 : }
109 :
110 388 : spwChannelCounts = config.asBool("spwchan");
111 : }
112 : else
113 : {
114 12 : spwChannelCounts = false;
115 : }
116 :
117 400 : if (spwChannelCounts)
118 : {
119 33 : *logger_p << LogIO::NORMAL << " Spw-Channel count activated " << LogIO::POST;
120 : }
121 : /*
122 : else
123 : {
124 : *logger_p << LogIO::NORMAL << " Spw-Channel count deactivated " << LogIO::POST;
125 : }
126 : */
127 :
128 400 : exists = config.fieldNumber ("spwcorr");
129 400 : if (exists >= 0)
130 : {
131 388 : if( config.type(exists) != TpBool )
132 : {
133 0 : throw( AipsError ( "Parameter 'spwcorr' must be of type 'bool'" ) );
134 : }
135 :
136 388 : spwPolarizationCounts = config.asBool("spwcorr");
137 : }
138 : else
139 : {
140 12 : spwPolarizationCounts = false;
141 : }
142 :
143 400 : if (spwPolarizationCounts)
144 : {
145 0 : *logger_p << LogIO::NORMAL << " Spw-Correlation count activated " << LogIO::POST;
146 : }
147 : /*
148 : else
149 : {
150 : *logger_p << LogIO::NORMAL << " Spw-Correlation count deactivated " << LogIO::POST;
151 : }
152 : */
153 :
154 400 : exists = config.fieldNumber ("basecnt");
155 400 : if (exists >= 0)
156 : {
157 388 : if( config.type(exists) != TpBool )
158 : {
159 0 : throw( AipsError ( "Parameter 'basecnt' must be of type 'bool'" ) );
160 : }
161 :
162 388 : baselineCounts = config.asBool("basecnt");
163 : }
164 : else
165 : {
166 12 : baselineCounts = false;
167 : }
168 :
169 400 : if (baselineCounts)
170 : {
171 22 : *logger_p << LogIO::NORMAL << " Baseline count activated " << LogIO::POST;
172 : }
173 : /*
174 : else
175 : {
176 : *logger_p << LogIO::NORMAL << " Baseline count deactivated " << LogIO::POST;
177 : }
178 : */
179 :
180 400 : exists = config.fieldNumber ("fieldcnt");
181 400 : if (exists >= 0)
182 : {
183 388 : if( config.type(exists) != TpBool )
184 : {
185 0 : throw( AipsError ( "Parameter 'fieldcnt' must be of type 'bool'" ) );
186 : }
187 :
188 388 : fieldCounts = config.asBool("fieldcnt");
189 : }
190 : else
191 : {
192 12 : fieldCounts = false;
193 : }
194 :
195 400 : if (fieldCounts)
196 : {
197 1 : *logger_p << LogIO::NORMAL << " Field breakdown activated " << LogIO::POST;
198 : }
199 : /*
200 : else
201 : {
202 : *logger_p << LogIO::NORMAL << " Field breakdown deactivated " << LogIO::POST;
203 : }
204 : */
205 :
206 400 : exists = config.fieldNumber ("display");
207 400 : if (exists >= 0)
208 : {
209 388 : if( config.type(exists) != TpString )
210 : {
211 0 : throw( AipsError ( "Parameter 'display' must be of type 'string'" ) );
212 : }
213 :
214 388 : display_p = config.asString("display");
215 388 : *logger_p << LogIO::NORMAL << " display is: " << display_p << LogIO::POST;
216 : }
217 :
218 :
219 400 : return;
220 : }
221 :
222 : void
223 106609 : FlagAgentSummary::preProcessBuffer(const vi::VisBuffer2 &visBuffer)
224 : {
225 106609 : arrayId = visBuffer.arrayId()(0);
226 106609 : arrayId_str = std::to_string(arrayId);
227 :
228 106609 : fieldId = visBuffer.fieldId()(0);
229 : // Transform fieldId into field name using the corresponding subtable
230 106609 : fieldId_str = flagDataHandler_p->fieldNames_p->operator()(fieldId);
231 :
232 106609 : spw = visBuffer.spectralWindows()(0);
233 106609 : spw_str = std::to_string(spw);
234 :
235 106609 : observationId = visBuffer.observationId()[0];
236 106609 : observationId_str = std::to_string(observationId);
237 :
238 : // Read in channel-frequencies.
239 : // RVU : I'm not sure if this should go here, or in the FlagDataHandler so that all agents get it.
240 106609 : if (spwChannelCounts) {
241 5946 : Vector<Double> flist(visBuffer.getFrequencies(0,MFrequency::TOPO));
242 195427 : for(Int i=0;i<(Int) flist.nelements();i++)
243 192454 : frequencyList[spw].push_back(flist[i]);
244 : }
245 :
246 106609 : if (fieldCounts)
247 : {
248 136 : if (fieldSummaryMap.find(fieldId_str) != fieldSummaryMap.end())
249 : {
250 132 : currentSummary = fieldSummaryMap[fieldId_str];
251 : }
252 : else
253 : {
254 4 : summary *newsummary = new summary();
255 4 : fieldSummaryMap.insert(std::pair<std::string, summary*>(fieldId_str,newsummary) );
256 4 : currentSummary = fieldSummaryMap[fieldId_str];
257 : }
258 : }
259 :
260 106609 : bufferTotal = 0;
261 106609 : bufferFlags = 0;
262 106609 : }
263 :
264 : bool
265 4608292 : FlagAgentSummary::computeRowFlags(const vi::VisBuffer2 &visBuffer, FlagMapper &flags,
266 : uInt row)
267 : {
268 4608292 : const Int antenna1 = visBuffer.antenna1()[row];
269 4608292 : const Int antenna2 = visBuffer.antenna2()[row];
270 9216584 : const auto antenna1Name = flagDataHandler_p->antennaNames_p->operator()(antenna1);
271 9216584 : const auto antenna2Name = flagDataHandler_p->antennaNames_p->operator()(antenna2);
272 :
273 : // Get scan for each particular row to cover for the "combine scans" case
274 4608292 : const auto scan = visBuffer.scan()[row];
275 9216584 : const auto scan_str = std::to_string(scan);
276 :
277 : // Compute totals
278 : Int nChannels, nRows;
279 4608292 : flags.shape(nChannels,nRows);
280 9216584 : const vector< vector<uInt> > polarizations = flags.getSelectedCorrelations();
281 4608292 : const Int nPolarizations = polarizations.size();
282 4608292 : const uInt64 rowTotal = nChannels*nPolarizations;
283 :
284 : // Initialize polarization counts
285 4608292 : Int pol_i = 0;;
286 4608292 : vector<uInt64> polarizationsBreakdownFlags(nPolarizations, 0);
287 :
288 : // Iterate through channels
289 : Bool flag;
290 4608292 : Int channel_i = 0;
291 4608292 : uInt64 rowFlags = 0;
292 4608292 : uInt64 channelFlags = 0;
293 245081194 : for (channel_i=0; channel_i<nChannels; ++channel_i)
294 : {
295 240472902 : channelFlags = 0;
296 879263438 : for (pol_i=0; pol_i < nPolarizations; ++pol_i)
297 : {
298 638790536 : flag = flags.getModifiedFlags(pol_i,channel_i,row);
299 638790536 : channelFlags += flag;
300 638790536 : polarizationsBreakdownFlags[pol_i] += flag;
301 : }
302 240472902 : rowFlags += channelFlags;
303 :
304 240472902 : if (spwChannelCounts)
305 : {
306 5149955 : currentSummary->accumChanneltotal[spw][channel_i] += nPolarizations;
307 5149955 : currentSummary->accumChannelflags[spw][channel_i] += channelFlags;
308 : }
309 : }
310 :
311 : // Update polarization counts
312 : const polarizationIndexMap *toPolarizationIndexMap =
313 4608292 : flagDataHandler_p->getPolarizationIndexMap();
314 16202941 : for (pol_i=0; pol_i < nPolarizations; ++pol_i)
315 : {
316 11594649 : const auto &polarization_str = (*toPolarizationIndexMap).at(polarizations[pol_i][0]);
317 11594649 : currentSummary->accumtotal["correlation"][polarization_str] += nChannels;
318 11594649 : currentSummary->accumflags["correlation"][polarization_str] += polarizationsBreakdownFlags[pol_i];
319 :
320 11594649 : if (spwPolarizationCounts)
321 : {
322 0 : currentSummary->accumPolarizationtotal[spw][polarization_str] += nChannels;
323 0 : currentSummary->accumPolarizationflags[spw][polarization_str] += polarizationsBreakdownFlags[pol_i];
324 : }
325 : }
326 :
327 : // Update row counts in fields that require row specific info (like scan, antenna and,
328 : // optionally, baseline)
329 4608292 : currentSummary->accumtotal["scan"][scan_str] += rowTotal;
330 4608292 : currentSummary->accumflags["scan"][scan_str] += rowFlags;
331 :
332 4608292 : currentSummary->accumtotal["antenna"][antenna1Name] += rowTotal;
333 4608292 : currentSummary->accumflags["antenna"][antenna1Name] += rowFlags;
334 :
335 4608292 : if (antenna1 != antenna2)
336 : {
337 4095833 : currentSummary->accumtotal["antenna"][antenna2Name] += rowTotal;
338 4095833 : currentSummary->accumflags["antenna"][antenna2Name] += rowFlags;
339 : }
340 :
341 4608292 : if ( baselineCounts )
342 : {
343 658038 : const auto baseline = antenna1Name + "&&" + antenna2Name;
344 329019 : currentSummary->accumtotal["baseline"][baseline] += rowTotal;
345 329019 : currentSummary->accumflags["baseline"][baseline] += rowFlags;
346 329019 : currentSummary->accumAntScantotal[antenna1][scan] += rowTotal;
347 329019 : currentSummary->accumAntScanflags[antenna1][scan] += rowFlags;
348 329019 : if (antenna1 != antenna2)
349 : {
350 303075 : currentSummary->accumAntScantotal[antenna2][scan] += rowTotal;
351 303075 : currentSummary->accumAntScanflags[antenna2][scan] += rowFlags;
352 : }
353 : }
354 :
355 : // keep updating buffer totals for postProcessBuffer()
356 4608292 : bufferTotal += rowTotal;
357 4608292 : bufferFlags += rowFlags;
358 :
359 9216584 : return false;
360 : }
361 :
362 : void
363 106609 : FlagAgentSummary::postProcessBuffer() {
364 : // Update here the summary fields that do not need to be updated on a row per row basis
365 : // (in computeRowFlags which would otherwise repeat all this many more times than needed)
366 : // The main reason to put these here is that this is much faster (CAS-12714)
367 106609 : currentSummary->accumtotal["array"][arrayId_str] += bufferTotal;
368 106609 : currentSummary->accumflags["array"][arrayId_str] += bufferFlags;
369 :
370 106609 : currentSummary->accumtotal["field"][fieldId_str] += bufferTotal;
371 106609 : currentSummary->accumflags["field"][fieldId_str] += bufferFlags;
372 :
373 106609 : currentSummary->accumtotal["spw"][spw_str] += bufferTotal;
374 106609 : currentSummary->accumflags["spw"][spw_str] += bufferFlags;
375 :
376 106609 : currentSummary->accumtotal["observation"][observationId_str] += bufferTotal;
377 106609 : currentSummary->accumflags["observation"][observationId_str] += bufferFlags;
378 :
379 106609 : currentSummary->accumTotalCount += bufferTotal;
380 106609 : currentSummary->accumTotalFlags += bufferFlags;
381 106609 : }
382 :
383 : FlagReport
384 400 : FlagAgentSummary::getReport()
385 : {
386 : // Make the flagreport list
387 800 : FlagReport summarylist("list");
388 :
389 : // Add the standard summary dictionary as a report of type 'summary'
390 : // summarylist.addReport( FlagReport("summary", agentName_p, getResult()) );
391 400 : summarylist.addReport( FlagReport("summary", summaryName_p, getResult()) );
392 :
393 : //////// Note : Calculate extra views only if the user has asked for it.
394 : /////// If returning only summary report, do the following.
395 : //////// return FlagReport("summary", agentName_p, getResult());
396 :
397 : // Add a list of reports from the flag-count dictionary
398 400 : if ( (display_p == String("report")) or (display_p == String("both")) )
399 : {
400 0 : summarylist.addReport ( buildFlagCountPlots() );
401 : }
402 :
403 : // // Make a report (or a list of them )for a view, and add it to the list
404 : // FlagReport viewrep("plotline",agentName_p,"title","xaxis","yaxis")
405 : // viewrep.addData(xdata,ydata,"label");
406 : // summarylist.addReport( viewRep );
407 : //
408 400 : return summarylist;
409 : }
410 :
411 : FlagReport
412 0 : FlagAgentSummary::buildFlagCountPlots()
413 : {
414 0 : logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
415 0 : *logger_p << LogIO::NORMAL << "Generating flag count reports for display" << LogIO::POST;
416 :
417 0 : FlagReport countRepList("list");
418 :
419 : // (1) Plot of fraction flagged vs frequency (only if spwchan==true)
420 0 : if( spwChannelCounts )
421 : {
422 0 : std::pair<string, double> freqUnit("GHz",1e+9);
423 :
424 0 : FlagReport subRep1 = FlagReport("plotpoints",summaryName_p,"Percentage Flagged",
425 0 : "Frequency ("+freqUnit.first+")", "% Flagged");
426 :
427 0 : for (const auto &key1 : currentSummary->accumChanneltotal)
428 : {
429 0 : Int nCh=currentSummary->accumChanneltotal[key1.first].size();
430 :
431 0 : Vector<Float> freqVals(nCh), flagPercent(nCh);
432 0 : uInt chCount=0;
433 0 : for (const auto &key2 : key1.second)
434 : {
435 : // read the frequency value for this channel.
436 0 : freqVals[chCount] = frequencyList[key1.first][key2.first] / freqUnit.second;
437 :
438 : // calculate the percentage flagged for this channel
439 0 : if( key2.second > 0 )
440 : {
441 0 : flagPercent[chCount] = 100.0 *
442 0 : (Double) currentSummary->accumChannelflags[key1.first][key2.first] /
443 0 : (Double) key2.second;
444 : }
445 : else
446 : {
447 0 : flagPercent[chCount] = 0.0;
448 : }
449 :
450 : // Increment channel counter
451 0 : chCount++;
452 : }
453 :
454 0 : subRep1.addData("line", freqVals,flagPercent,"",Vector<Float>(),
455 0 : "spw"+String::toString(key1.first));
456 :
457 : }
458 :
459 0 : countRepList.addReport( subRep1 );
460 : }
461 :
462 : // (2) Plot of fraction flagged vs antenna-position
463 0 : Int nAnt=currentSummary->accumtotal["antenna"].size();
464 0 : if(nAnt>0) // Perhaps put a parameter to control this ?
465 : {
466 0 : Vector<Float> antPosX(nAnt), antPosY(nAnt), radius(nAnt);
467 0 : Int antCount=0;
468 0 : const Vector<double> xyzOrigin = (flagDataHandler_p->antennaPositions_p->operator()(0))
469 0 : .getValue().getValue();
470 :
471 0 : FlagReport subRep2 = FlagReport("plotpoints",summaryName_p,"Percentage Flagged",
472 0 : "X meters (ITRF)", "Y meters (ITRF)");
473 :
474 0 : for (const auto antkey : currentSummary->accumtotal["antenna"])
475 : {
476 0 : Int antId = 0; //antCount; // this needs to find the antenna-id for the antenna name.... aaaaah.
477 0 : for(antId=0; antId<(Int) flagDataHandler_p->antennaNames_p->nelements(); antId++)
478 : {
479 0 : if( flagDataHandler_p->antennaNames_p->operator()(antId)
480 0 : == String(antkey.first) ) break;
481 : }
482 :
483 0 : const Vector<double> xyz = (flagDataHandler_p->antennaPositions_p->operator()(antId))
484 0 : .getValue().getValue();
485 0 : antPosX[antCount] = xyz[0]-xyzOrigin[0];
486 0 : antPosY[antCount] = xyz[1]-xyzOrigin[1];
487 0 : radius[antCount] = 200.0 *
488 0 : (Double) currentSummary->accumflags["antenna"][antkey.first]/
489 0 : (Double) antkey.second;
490 0 : antCount++;
491 : }
492 0 : subRep2.addData("scatter", antPosX,antPosY,"circle",radius,"");
493 0 : countRepList.addReport( subRep2 );
494 : }
495 :
496 0 : Int nBase= baselineCounts? 0:currentSummary->accumtotal["baseline"].size();
497 :
498 : // (3) Plot of fraction flagged vs baseline-length
499 0 : if(nBase>0) // Perhaps put a parameter to control this ?
500 : {
501 0 : Vector<Float> baselineLength(nBase), flagFraction(nBase);
502 0 : Int baseCount=0;
503 0 : FlagReport subRep3 = FlagReport("plotpoints",summaryName_p,"Percentage Flagged per baseline",
504 0 : "Baseline Length (m)", "% Flagged");
505 :
506 0 : for (const auto &basekey : currentSummary->accumtotal["baseline"])
507 : {
508 0 : Int antId1 = 0, antId2=0;
509 0 : String antName1,antName2;
510 0 : antName1 = antName2 = String(basekey.first);
511 0 : antName1 = antName1.before("&&");
512 0 : antName2 = antName2.after("&&");
513 0 : for(Int antId=0; antId<(Int) flagDataHandler_p->antennaNames_p->nelements(); antId++)
514 : {
515 0 : if( flagDataHandler_p->antennaNames_p->operator()(antId) == antName1 ) antId1 = antId;
516 0 : if( flagDataHandler_p->antennaNames_p->operator()(antId) == antName2 ) antId2 = antId;
517 : }
518 :
519 0 : const Vector<double> xyz1 = (flagDataHandler_p->antennaPositions_p->operator()(antId1))
520 0 : .getValue().getValue();
521 0 : const Vector<double> xyz2 = (flagDataHandler_p->antennaPositions_p->operator()(antId2))
522 0 : .getValue().getValue();
523 0 : baselineLength[baseCount] = sqrt( fabs( (xyz1[0]-xyz2[0])*(xyz1[0]-xyz2[0]) +
524 0 : (xyz1[1]-xyz2[1])*(xyz1[1]-xyz2[1]) +
525 0 : (xyz1[2]-xyz2[2])*(xyz1[2]-xyz2[2]) ) );
526 0 : flagFraction[baseCount] = 100.0 *
527 0 : (Double) currentSummary->accumflags["baseline"][basekey.first]/
528 0 : (Double) basekey.second;
529 0 : baseCount++;
530 : }
531 0 : subRep3.addData("scatter", baselineLength,flagFraction,"",Vector<Float>(),"");
532 0 : countRepList.addReport( subRep3 );
533 : }
534 :
535 : // jagonzal: CAS-3450
536 0 : if(nBase>0)
537 : {
538 0 : Int totalNAnt = flagDataHandler_p->antennaNames_p->size();
539 : // Add ant1xant2 summary views
540 0 : FlagReport subRep4 = FlagReport("plotraster",summaryName_p,"% Flagged per baseline", "Antenna 1", "Antenna 2");
541 0 : Array<Float> ant1ant2View( IPosition(2, totalNAnt, totalNAnt) , (Float)0);
542 0 : std::pair<Int,Int> ant1ant2;
543 : Float percentageFlagged;
544 0 : for (const auto &basekey : currentSummary->accumtotal["baseline"])
545 : {
546 0 : ant1ant2 = flagDataHandler_p->baselineToAnt1Ant2_p[basekey.first];
547 0 : percentageFlagged = (Float)100*((Double)currentSummary->accumflags["baseline"][basekey.first] /
548 0 : (Double)currentSummary->accumtotal["baseline"][basekey.first]);
549 0 : ant1ant2View(IPosition(2, ant1ant2.first, ant1ant2.second)) = percentageFlagged;
550 0 : ant1ant2View(IPosition(2, ant1ant2.second, ant1ant2.first)) = percentageFlagged;
551 :
552 : }
553 :
554 0 : subRep4.addData(ant1ant2View);
555 0 : countRepList.addReport( subRep4 );
556 :
557 : // Add ant1xscan summary views
558 0 : FlagReport subRep5 = FlagReport("plotraster",summaryName_p,"% Flagged per antenna and scan", "Scan relative index", "% Flagged per antenna");
559 :
560 : // NOTE: We need to handle directly the storage array, because it seems that the dimension steps are switched
561 0 : Array<Float> antScanView( IPosition(2, currentSummary->accumflags["scan"].size(),totalNAnt) , (Float)0);
562 0 : Bool deleteIt = false;
563 0 : Float* antScanViewPtr = antScanView.getStorage(deleteIt);
564 :
565 :
566 0 : uInt scanIdx,antennaIdx = 0;
567 0 : for (const auto &antkey : currentSummary->accumAntScantotal)
568 : {
569 0 : scanIdx = 0;
570 0 : for (const auto scankey : antkey.second)
571 : {
572 0 : percentageFlagged = (Float)100*((Double)currentSummary->accumAntScanflags[antkey.first][scankey.first] /
573 0 : (Double)currentSummary->accumAntScantotal[antkey.first][scankey.first]);
574 0 : antScanViewPtr[totalNAnt*scanIdx + antkey.first] = percentageFlagged;
575 0 : scanIdx += 1;
576 : }
577 0 : antennaIdx += 1;
578 : }
579 :
580 0 : subRep5.addData(antScanView);
581 0 : countRepList.addReport( subRep5 );
582 : }
583 :
584 :
585 0 : return countRepList;
586 : }
587 :
588 :
589 : Record
590 400 : FlagAgentSummary::getResult()
591 : {
592 400 : logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
593 :
594 400 : Record result;
595 :
596 400 : if (fieldCounts)
597 : {
598 5 : for(const auto &iter : fieldSummaryMap)
599 : {
600 4 : Record subresult;
601 4 : currentSummary = iter.second;
602 4 : getResultCore(subresult);
603 4 : result.defineRecord(iter.first, subresult);
604 : }
605 : }
606 : else
607 : {
608 399 : getResultCore(result);
609 : }
610 :
611 400 : return result;
612 : }
613 :
614 : void
615 403 : FlagAgentSummary::getResultCore(Record &result)
616 : {
617 403 : if (fieldCounts)
618 : {
619 8 : string field = currentSummary->accumtotal["field"].begin()->first;
620 4 : string spaces(field.size(),'=');
621 4 : *logger_p << LogIO::NORMAL << "======" << spaces << "==========" << LogIO::POST;
622 4 : *logger_p << LogIO::NORMAL << "Field " << field << " breakdown" << LogIO::POST;
623 4 : *logger_p << LogIO::NORMAL << "======" << spaces << "==========" << LogIO::POST;
624 : }
625 :
626 403 : if (spwChannelCounts)
627 : {
628 33 : Record stats_key1;
629 :
630 81 : for (const auto &key1 : currentSummary->accumChanneltotal)
631 : {
632 : // Transform spw id into string
633 96 : stringstream spw_stringStream;
634 48 : spw_stringStream << key1.first;
635 :
636 2855 : for (const auto &key2 : key1.second)
637 : {
638 5614 : Record stats_key2;
639 :
640 2807 : stats_key2.define("flagged", (Double) currentSummary->accumChannelflags[key1.first][key2.first]);
641 2807 : stats_key2.define("total", (Double) key2.second);
642 :
643 : // Transform channel id into string
644 5614 : stringstream channel_stringStream;
645 2807 : channel_stringStream << key2.first;
646 :
647 : // Construct spw:channel string as first key
648 2807 : stats_key1.defineRecord(spw_stringStream.str() + ":" + channel_stringStream.str(), stats_key2);
649 : // Calculate percentage flagged
650 2807 : stringstream percentage;
651 2807 : percentage.precision(3);
652 : // percentage.fixed;
653 2807 : if( key2.second > 0 )
654 : {
655 2807 : percentage << " (" << 100.0 *
656 2807 : (Double) currentSummary->accumChannelflags[key1.first][key2.first]/
657 2807 : (Double) key2.second << "%)";
658 : }
659 :
660 2807 : *logger_p << LogIO::NORMAL
661 5614 : << " Spw:" << key1.first << " Channel:" << key2.first
662 2807 : << " flagged: " << (Double) currentSummary->accumChannelflags[key1.first][key2.first]
663 2807 : << " total: " << (Double) key2.second
664 2807 : << percentage.str()
665 5614 : << LogIO::POST;
666 : }
667 :
668 : }
669 :
670 33 : result.defineRecord("spw:channel", stats_key1);
671 : }
672 :
673 403 : if (spwPolarizationCounts)
674 : {
675 0 : Record stats_key1;
676 :
677 0 : for (const auto &key1 : currentSummary->accumPolarizationtotal)
678 : {
679 : // Transform spw id into string
680 0 : stringstream spw_stringStream;
681 0 : spw_stringStream << key1.first;
682 :
683 0 : for (const auto &key2 : key1.second)
684 : {
685 0 : Record stats_key2;
686 :
687 0 : stats_key2.define("flagged", (Double) currentSummary->accumPolarizationflags[key1.first][key2.first]);
688 0 : stats_key2.define("total", (Double) key2.second);
689 :
690 : // Construct spw:correlation string as first key (Polarization already comes as a string)
691 0 : stats_key1.defineRecord(spw_stringStream.str() + ":" + key2.first, stats_key2);
692 :
693 : // Calculate percentage flagged
694 0 : stringstream percentage;
695 0 : percentage.precision(3);
696 : // percentage.fixed;
697 0 : if( key2.second > 0 )
698 : {
699 0 : percentage << " (" << 100.0 *
700 0 : (Double) currentSummary->accumPolarizationflags[key1.first][key2.first]/
701 0 : (Double) key2.second << "%)";
702 : }
703 :
704 0 : *logger_p << LogIO::NORMAL
705 0 : << " Spw:" << key1.first << " Correlation:" << key2.first
706 0 : << " flagged: " << (Double) currentSummary->accumPolarizationflags[key1.first][key2.first]
707 0 : << " total: " << (Double) key2.second
708 0 : << percentage.str()
709 0 : << LogIO::POST;
710 : }
711 : }
712 :
713 0 : result.defineRecord("spw:correlation", stats_key1);
714 : }
715 :
716 403 : if (baselineCounts)
717 : {
718 22 : Record stats_key1;
719 :
720 398 : for (const auto &key1 : currentSummary->accumAntScantotal)
721 : {
722 : // Construct antenna name
723 752 : stringstream antenna_stringStream;
724 376 : antenna_stringStream << flagDataHandler_p->antennaNames_p->operator()(key1.first);
725 :
726 1948 : for (const auto &key2 : key1.second)
727 : {
728 : // Construct scan name
729 3144 : stringstream scan_stringStream;
730 1572 : scan_stringStream << key2.first;
731 :
732 3144 : Record stats_key2;
733 :
734 1572 : stats_key2.define("flagged", (Double) currentSummary->accumAntScanflags[key1.first][key2.first]);
735 1572 : stats_key2.define("total", (Double) key2.second);
736 :
737 : // Construct spw:correlation string as first key (Polarization already comes as a string)
738 1572 : stats_key1.defineRecord(antenna_stringStream.str() + ":" + scan_stringStream.str(), stats_key2);
739 :
740 : // Calculate percentage flagged
741 1572 : stringstream percentage;
742 1572 : percentage.precision(3);
743 : // percentage.fixed;
744 1572 : if( key2.second > 0 )
745 : {
746 1572 : percentage << " (" << 100.0 *
747 1572 : (Double) currentSummary->accumAntScanflags[key1.first][key2.first]/
748 1572 : (Double) key2.second << "%)";
749 : }
750 :
751 1572 : *logger_p << LogIO::NORMAL
752 3144 : << " Spw:" << key1.first << " Correlation:" << key2.first
753 1572 : << " flagged: " << (Double) currentSummary->accumAntScanflags[key1.first][key2.first]
754 1572 : << " total: " << (Double) key2.second
755 1572 : << percentage.str()
756 3144 : << LogIO::POST;
757 : }
758 : }
759 :
760 22 : result.defineRecord("antenna:scan", stats_key1);
761 : }
762 :
763 3239 : for (const auto &key1 : currentSummary->accumtotal)
764 : {
765 2836 : Record stats_key1;
766 19716 : for (const auto &key2 : key1.second)
767 : {
768 33760 : Record stats_key2;
769 :
770 16880 : stats_key2.define("flagged", (Double) currentSummary->accumflags[key1.first][key2.first]);
771 16880 : stats_key2.define("total", (Double) key2.second);
772 16880 : stats_key1.defineRecord(key2.first, stats_key2);
773 :
774 : // Calculate percentage flagged
775 16880 : stringstream percentage;
776 16880 : percentage.precision(3);
777 : // percentage.fixed;
778 16880 : if( key2.second > 0 )
779 : {
780 16880 : percentage << " (" << 100.0 *
781 16880 : (Double) currentSummary->accumflags[key1.first][key2.first] /
782 16880 : (Double) key2.second << "%)";
783 : }
784 :
785 16880 : *logger_p << LogIO::NORMAL
786 33760 : << " " << key1.first << " " << key2.first
787 16880 : << " flagged: " << (Double) currentSummary->accumflags[key1.first][key2.first]
788 16880 : << " total: " << (Double) key2.second
789 0 : << percentage.str()
790 33760 : << LogIO::POST;
791 : }
792 :
793 2836 : result.defineRecord(key1.first, stats_key1);
794 : }
795 :
796 403 : result.define("flagged", (Double) currentSummary->accumTotalFlags);
797 403 : result.define("total" , (Double) currentSummary->accumTotalCount);
798 :
799 : // Calculate percentage flagged
800 806 : stringstream percentage;
801 403 : percentage.precision(3);
802 : // percentage.fixed;
803 403 : if( currentSummary->accumTotalCount > 0 )
804 : {
805 402 : percentage << " (" << 100.0 *
806 402 : (Double) currentSummary->accumTotalFlags /
807 402 : (Double) currentSummary->accumTotalCount << "%)";
808 : }
809 403 : *logger_p << LogIO::NORMAL
810 403 : << " Total Flagged: " << (Double) currentSummary->accumTotalFlags
811 403 : << " Total Counts: " << (Double) currentSummary->accumTotalCount
812 0 : << percentage.str()
813 403 : << LogIO::POST;
814 :
815 806 : return;
816 : }
817 :
818 : } //# NAMESPACE CASA - END
819 :
820 :
|