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 408 : FlagAgentSummary::FlagAgentSummary(FlagDataHandler *dh, Record config):
31 408 : FlagAgentBase(dh,config,ROWS_PREPROCESS_BUFFER,false)
32 : {
33 408 : arrayId = 0;
34 408 : fieldId = 0;
35 408 : spw = 0;
36 408 : scan = 0;
37 408 : observationId = 0;
38 :
39 408 : arrayId_str = String("");
40 408 : fieldId_str = String("");
41 408 : spw_str = String("");
42 408 : observationId_str = String("");
43 :
44 408 : spwChannelCounts = false;
45 408 : spwPolarizationCounts = false;
46 408 : baselineCounts = false;
47 408 : fieldCounts = false;
48 408 : display_p = String("none");
49 :
50 408 : setAgentParameters(config);
51 :
52 408 : currentSummary = NULL;
53 408 : fieldSummaryMap.clear();
54 408 : if (fieldCounts)
55 : {
56 1 : currentSummary = NULL;
57 : }
58 : else
59 : {
60 407 : currentSummary = new summary();
61 : }
62 :
63 : // Request loading polarization map to FlagDataHandler
64 408 : flagDataHandler_p->setMapPolarizations(true);
65 :
66 : // Request pre-loading array,field,spw, scan, observation, antenna1, antenna2
67 408 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::ArrayId);
68 408 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::FieldId);
69 408 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Scan);
70 408 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::ObservationId);
71 408 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::SpectralWindows);
72 408 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna1);
73 408 : flagDataHandler_p->preLoadColumn(VisBufferComponent2::Antenna2);
74 : //flagDataHandler_p->preLoadColumn(vi::Freq);
75 408 : }
76 :
77 816 : FlagAgentSummary::~FlagAgentSummary()
78 : {
79 408 : 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 407 : delete currentSummary;
90 : }
91 :
92 : // Compiler automagically calls FlagAgentBase::~FlagAgentBase()
93 816 : }
94 :
95 : void
96 408 : FlagAgentSummary::setAgentParameters(Record config)
97 : {
98 408 : logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
99 :
100 : int exists;
101 :
102 408 : exists = config.fieldNumber ("spwchan");
103 408 : if (exists >= 0)
104 : {
105 396 : if( config.type(exists) != TpBool )
106 : {
107 0 : throw( AipsError ( "Parameter 'spwchan' must be of type 'bool'" ) );
108 : }
109 :
110 396 : spwChannelCounts = config.asBool("spwchan");
111 : }
112 : else
113 : {
114 12 : spwChannelCounts = false;
115 : }
116 :
117 408 : 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 408 : exists = config.fieldNumber ("spwcorr");
129 408 : if (exists >= 0)
130 : {
131 396 : if( config.type(exists) != TpBool )
132 : {
133 0 : throw( AipsError ( "Parameter 'spwcorr' must be of type 'bool'" ) );
134 : }
135 :
136 396 : spwPolarizationCounts = config.asBool("spwcorr");
137 : }
138 : else
139 : {
140 12 : spwPolarizationCounts = false;
141 : }
142 :
143 408 : if (spwPolarizationCounts)
144 : {
145 2 : *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 408 : exists = config.fieldNumber ("basecnt");
155 408 : if (exists >= 0)
156 : {
157 396 : if( config.type(exists) != TpBool )
158 : {
159 0 : throw( AipsError ( "Parameter 'basecnt' must be of type 'bool'" ) );
160 : }
161 :
162 396 : baselineCounts = config.asBool("basecnt");
163 : }
164 : else
165 : {
166 12 : baselineCounts = false;
167 : }
168 :
169 408 : if (baselineCounts)
170 : {
171 23 : *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 408 : exists = config.fieldNumber ("fieldcnt");
181 408 : if (exists >= 0)
182 : {
183 396 : if( config.type(exists) != TpBool )
184 : {
185 0 : throw( AipsError ( "Parameter 'fieldcnt' must be of type 'bool'" ) );
186 : }
187 :
188 396 : fieldCounts = config.asBool("fieldcnt");
189 : }
190 : else
191 : {
192 12 : fieldCounts = false;
193 : }
194 :
195 408 : 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 408 : exists = config.fieldNumber ("display");
207 408 : if (exists >= 0)
208 : {
209 396 : if( config.type(exists) != TpString )
210 : {
211 0 : throw( AipsError ( "Parameter 'display' must be of type 'string'" ) );
212 : }
213 :
214 396 : display_p = config.asString("display");
215 396 : *logger_p << LogIO::NORMAL << " display is: " << display_p << LogIO::POST;
216 : }
217 :
218 :
219 408 : return;
220 : }
221 :
222 : void
223 107178 : FlagAgentSummary::preProcessBuffer(const vi::VisBuffer2 &visBuffer)
224 : {
225 107178 : arrayId = visBuffer.arrayId()(0);
226 107178 : arrayId_str = std::to_string(arrayId);
227 :
228 107178 : fieldId = visBuffer.fieldId()(0);
229 : // Transform fieldId into field name using the corresponding subtable
230 107178 : fieldId_str = flagDataHandler_p->fieldNames_p->operator()(fieldId);
231 :
232 107178 : spw = visBuffer.spectralWindows()(0);
233 107178 : spw_str = std::to_string(spw);
234 :
235 107178 : observationId = visBuffer.observationId()[0];
236 107178 : 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 107178 : if (spwChannelCounts) {
241 2973 : 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 2973 : }
245 :
246 107178 : 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 107178 : bufferTotal = 0;
261 107178 : bufferFlags = 0;
262 107178 : }
263 :
264 : bool
265 4661962 : FlagAgentSummary::computeRowFlags(const vi::VisBuffer2 &visBuffer, FlagMapper &flags,
266 : uInt row)
267 : {
268 4661962 : const Int antenna1 = visBuffer.antenna1()[row];
269 4661962 : const Int antenna2 = visBuffer.antenna2()[row];
270 4661962 : const auto antenna1Name = flagDataHandler_p->antennaNames_p->operator()(antenna1);
271 4661962 : 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 4661962 : const auto scan = visBuffer.scan()[row];
275 4661962 : const auto scan_str = std::to_string(scan);
276 :
277 : // Compute totals
278 : Int nChannels, nRows;
279 4661962 : flags.shape(nChannels,nRows);
280 4661962 : const vector< vector<uInt> > polarizations = flags.getSelectedCorrelations();
281 4661962 : const Int nPolarizations = polarizations.size();
282 4661962 : const uInt64 rowTotal = nChannels*nPolarizations;
283 :
284 : // Initialize polarization counts
285 4661962 : Int pol_i = 0;;
286 4661962 : vector<uInt64> polarizationsBreakdownFlags(nPolarizations, 0);
287 :
288 : // Iterate through channels
289 : Bool flag;
290 4661962 : Int channel_i = 0;
291 4661962 : uInt64 rowFlags = 0;
292 4661962 : uInt64 channelFlags = 0;
293 248065168 : for (channel_i=0; channel_i<nChannels; ++channel_i)
294 : {
295 243403206 : channelFlags = 0;
296 888191822 : for (pol_i=0; pol_i < nPolarizations; ++pol_i)
297 : {
298 644788616 : flag = flags.getModifiedFlags(pol_i,channel_i,row);
299 644788616 : channelFlags += flag;
300 644788616 : polarizationsBreakdownFlags[pol_i] += flag;
301 : }
302 243403206 : rowFlags += channelFlags;
303 :
304 243403206 : 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 4661962 : flagDataHandler_p->getPolarizationIndexMap();
314 16366099 : for (pol_i=0; pol_i < nPolarizations; ++pol_i)
315 : {
316 11704137 : const auto &polarization_str = (*toPolarizationIndexMap).at(polarizations[pol_i][0]);
317 11704137 : currentSummary->accumtotal["correlation"][polarization_str] += nChannels;
318 11704137 : currentSummary->accumflags["correlation"][polarization_str] += polarizationsBreakdownFlags[pol_i];
319 :
320 11704137 : if (spwPolarizationCounts)
321 : {
322 49602 : currentSummary->accumPolarizationtotal[spw][polarization_str] += nChannels;
323 49602 : 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 4661962 : currentSummary->accumtotal["scan"][scan_str] += rowTotal;
330 4661962 : currentSummary->accumflags["scan"][scan_str] += rowFlags;
331 :
332 4661962 : currentSummary->accumtotal["antenna"][antenna1Name] += rowTotal;
333 4661962 : currentSummary->accumflags["antenna"][antenna1Name] += rowFlags;
334 :
335 4661962 : if (antenna1 != antenna2)
336 : {
337 4145995 : currentSummary->accumtotal["antenna"][antenna2Name] += rowTotal;
338 4145995 : currentSummary->accumflags["antenna"][antenna2Name] += rowFlags;
339 : }
340 :
341 4661962 : if ( baselineCounts )
342 : {
343 351672 : const auto baseline = antenna1Name + "&&" + antenna2Name;
344 351672 : currentSummary->accumtotal["baseline"][baseline] += rowTotal;
345 351672 : currentSummary->accumflags["baseline"][baseline] += rowFlags;
346 351672 : currentSummary->accumAntScantotal[antenna1][scan] += rowTotal;
347 351672 : currentSummary->accumAntScanflags[antenna1][scan] += rowFlags;
348 351672 : if (antenna1 != antenna2)
349 : {
350 324109 : currentSummary->accumAntScantotal[antenna2][scan] += rowTotal;
351 324109 : currentSummary->accumAntScanflags[antenna2][scan] += rowFlags;
352 : }
353 351672 : }
354 :
355 : // keep updating buffer totals for postProcessBuffer()
356 4661962 : bufferTotal += rowTotal;
357 4661962 : bufferFlags += rowFlags;
358 :
359 4661962 : return false;
360 4661962 : }
361 :
362 : void
363 107178 : 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 107178 : currentSummary->accumtotal["array"][arrayId_str] += bufferTotal;
368 107178 : currentSummary->accumflags["array"][arrayId_str] += bufferFlags;
369 :
370 107178 : currentSummary->accumtotal["field"][fieldId_str] += bufferTotal;
371 107178 : currentSummary->accumflags["field"][fieldId_str] += bufferFlags;
372 :
373 107178 : currentSummary->accumtotal["spw"][spw_str] += bufferTotal;
374 107178 : currentSummary->accumflags["spw"][spw_str] += bufferFlags;
375 :
376 107178 : currentSummary->accumtotal["observation"][observationId_str] += bufferTotal;
377 107178 : currentSummary->accumflags["observation"][observationId_str] += bufferFlags;
378 :
379 107178 : currentSummary->accumTotalCount += bufferTotal;
380 107178 : currentSummary->accumTotalFlags += bufferFlags;
381 107178 : }
382 :
383 : FlagReport
384 408 : FlagAgentSummary::getReport()
385 : {
386 : // Make the flagreport list
387 816 : 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 408 : 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 408 : 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 408 : return summarylist;
409 0 : }
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 0 : }
458 :
459 0 : countRepList.addReport( subRep1 );
460 0 : }
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 0 : }
492 0 : subRep2.addData("scatter", antPosX,antPosY,"circle",radius,"");
493 0 : countRepList.addReport( subRep2 );
494 0 : }
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 0 : }
531 0 : subRep3.addData("scatter", baselineLength,flagFraction,"",Vector<Float>(),"");
532 0 : countRepList.addReport( subRep3 );
533 0 : }
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 0 : }
583 :
584 :
585 0 : return countRepList;
586 0 : }
587 :
588 :
589 : Record
590 408 : FlagAgentSummary::getResult()
591 : {
592 408 : logger_p->origin(LogOrigin(agentName_p,__FUNCTION__,WHERE));
593 :
594 408 : Record result;
595 :
596 408 : 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 4 : }
605 : }
606 : else
607 : {
608 407 : getResultCore(result);
609 : }
610 :
611 408 : return result;
612 0 : }
613 :
614 : void
615 411 : FlagAgentSummary::getResultCore(Record &result)
616 : {
617 411 : if (fieldCounts)
618 : {
619 4 : 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 4 : }
625 :
626 411 : 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 48 : stringstream spw_stringStream;
634 48 : spw_stringStream << key1.first;
635 :
636 2855 : for (const auto &key2 : key1.second)
637 : {
638 2807 : 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 2807 : 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 0 : << percentage.str()
665 5614 : << LogIO::POST;
666 2807 : }
667 :
668 48 : }
669 :
670 33 : result.defineRecord("spw:channel", stats_key1);
671 33 : }
672 :
673 411 : if (spwPolarizationCounts)
674 : {
675 2 : Record stats_key1;
676 :
677 4 : for (const auto &key1 : currentSummary->accumPolarizationtotal)
678 : {
679 : // Transform spw id into string
680 2 : stringstream spw_stringStream;
681 2 : spw_stringStream << key1.first;
682 :
683 8 : for (const auto &key2 : key1.second)
684 : {
685 6 : Record stats_key2;
686 :
687 6 : stats_key2.define("flagged", (Double) currentSummary->accumPolarizationflags[key1.first][key2.first]);
688 6 : stats_key2.define("total", (Double) key2.second);
689 :
690 : // Construct spw:correlation string as first key (Polarization already comes as a string)
691 6 : stats_key1.defineRecord(spw_stringStream.str() + ":" + key2.first, stats_key2);
692 :
693 : // Calculate percentage flagged
694 6 : stringstream percentage;
695 6 : percentage.precision(3);
696 : // percentage.fixed;
697 6 : if( key2.second > 0 )
698 : {
699 6 : percentage << " (" << 100.0 *
700 6 : (Double) currentSummary->accumPolarizationflags[key1.first][key2.first]/
701 6 : (Double) key2.second << "%)";
702 : }
703 :
704 6 : *logger_p << LogIO::NORMAL
705 12 : << " Spw:" << key1.first << " Correlation:" << key2.first
706 6 : << " flagged: " << (Double) currentSummary->accumPolarizationflags[key1.first][key2.first]
707 6 : << " total: " << (Double) key2.second
708 0 : << percentage.str()
709 12 : << LogIO::POST;
710 6 : }
711 2 : }
712 :
713 2 : result.defineRecord("spw:correlation", stats_key1);
714 2 : }
715 :
716 411 : if (baselineCounts)
717 : {
718 23 : Record stats_key1;
719 :
720 426 : for (const auto &key1 : currentSummary->accumAntScantotal)
721 : {
722 : // Construct antenna name
723 403 : stringstream antenna_stringStream;
724 403 : const auto antennaName = flagDataHandler_p->antennaNames_p->operator()(key1.first);
725 403 : antenna_stringStream << antennaName;
726 :
727 2164 : for (const auto &key2 : key1.second)
728 : {
729 : // Construct scan name
730 1761 : stringstream scan_stringStream;
731 1761 : scan_stringStream << key2.first;
732 :
733 1761 : Record stats_key2;
734 :
735 1761 : stats_key2.define("flagged", (Double) currentSummary->accumAntScanflags[key1.first][key2.first]);
736 1761 : stats_key2.define("total", (Double) key2.second);
737 :
738 : // Construct spw:correlation string as first key (Polarization already comes as a string)
739 1761 : stats_key1.defineRecord(antenna_stringStream.str() + ":" + scan_stringStream.str(), stats_key2);
740 :
741 : // Calculate percentage flagged
742 1761 : stringstream percentage;
743 1761 : percentage.precision(3);
744 : // percentage.fixed;
745 1761 : if( key2.second > 0 )
746 : {
747 1761 : percentage << " (" << 100.0 *
748 1761 : (Double) currentSummary->accumAntScanflags[key1.first][key2.first]/
749 1761 : (Double) key2.second << "%)";
750 : }
751 :
752 1761 : *logger_p << LogIO::NORMAL
753 1761 : << " Antenna:" << antennaName << " Scan:" << key2.first
754 1761 : << " flagged: " << (Double) currentSummary->accumAntScanflags[key1.first][key2.first]
755 1761 : << " total: " << (Double) key2.second
756 0 : << percentage.str()
757 3522 : << LogIO::POST;
758 1761 : }
759 403 : }
760 :
761 23 : result.defineRecord("antenna:scan", stats_key1);
762 23 : }
763 :
764 3304 : for (const auto &key1 : currentSummary->accumtotal)
765 : {
766 2893 : Record stats_key1;
767 20569 : for (const auto &key2 : key1.second)
768 : {
769 17676 : Record stats_key2;
770 :
771 17676 : stats_key2.define("flagged", (Double) currentSummary->accumflags[key1.first][key2.first]);
772 17676 : stats_key2.define("total", (Double) key2.second);
773 17676 : stats_key1.defineRecord(key2.first, stats_key2);
774 :
775 : // Calculate percentage flagged
776 17676 : stringstream percentage;
777 17676 : percentage.precision(3);
778 : // percentage.fixed;
779 17676 : if( key2.second > 0 )
780 : {
781 17676 : percentage << " (" << 100.0 *
782 17676 : (Double) currentSummary->accumflags[key1.first][key2.first] /
783 17676 : (Double) key2.second << "%)";
784 : }
785 :
786 17676 : *logger_p << LogIO::NORMAL
787 35352 : << " " << key1.first << " " << key2.first
788 17676 : << " flagged: " << (Double) currentSummary->accumflags[key1.first][key2.first]
789 17676 : << " total: " << (Double) key2.second
790 0 : << percentage.str()
791 35352 : << LogIO::POST;
792 17676 : }
793 :
794 2893 : result.defineRecord(key1.first, stats_key1);
795 2893 : }
796 :
797 411 : result.define("flagged", (Double) currentSummary->accumTotalFlags);
798 411 : result.define("total" , (Double) currentSummary->accumTotalCount);
799 :
800 : // Calculate percentage flagged
801 411 : stringstream percentage;
802 411 : percentage.precision(3);
803 : // percentage.fixed;
804 411 : if( currentSummary->accumTotalCount > 0 )
805 : {
806 410 : percentage << " (" << 100.0 *
807 410 : (Double) currentSummary->accumTotalFlags /
808 410 : (Double) currentSummary->accumTotalCount << "%)";
809 : }
810 411 : *logger_p << LogIO::NORMAL
811 411 : << " Total Flagged: " << (Double) currentSummary->accumTotalFlags
812 411 : << " Total Counts: " << (Double) currentSummary->accumTotalCount
813 0 : << percentage.str()
814 411 : << LogIO::POST;
815 :
816 822 : return;
817 411 : }
818 :
819 : } //# NAMESPACE CASA - END
820 :
821 :
|