Line data Source code
1 : /**
2 : Bojan Nikolic <b.nikolic@mrao.cam.ac.uk>, <bojan@bnikolic.co.uk>
3 : Initial version January 2010.
4 : Maintained by ESO since 2013.
5 :
6 : This file is part of LibAIR and is licensed under GNU Public
7 : License Version 2
8 :
9 : \file mswvrdata.cpp
10 : Renamed mswvrdata.cc 2023
11 :
12 : */
13 :
14 : #include <set>
15 : #include <memory>
16 : #include <iostream>
17 : #include <iomanip>
18 :
19 : #include "mswvrdata.h"
20 : #include "msspec.h"
21 : #include "msutils.h"
22 : #include "casawvr_errs.h"
23 :
24 : #include <casacore/ms/MeasurementSets/MeasurementSet.h>
25 : #include <casacore/ms/MeasurementSets/MSProcessor.h>
26 : #include <casacore/ms/MeasurementSets/MSColumns.h>
27 : #include <casacore/ms/MSOper/MSDerivedValues.h>
28 : #include <casacore/casa/Utilities/GenSort.h>
29 : #include <casacore/casa/Arrays/Vector.h>
30 : #include <casacore/casa/Quanta/MVTime.h>
31 :
32 : #include "../src/apps/arraydata.h"
33 :
34 :
35 : namespace LibAIR2 {
36 :
37 : SPWSet
38 0 : WVRSPWIDs(const casacore::MeasurementSet &ms)
39 : {
40 0 : const casacore::MSSpectralWindow & specTable(ms.spectralWindow());
41 : // Not using these in present algorithm
42 : //const casacore::MSProcessor & proc(ms.processor());
43 :
44 : casacore::ScalarColumn<casacore::Int> nc(specTable,
45 0 : casacore::MSSpectralWindow::columnName(casacore::MSSpectralWindow::NUM_CHAN));
46 :
47 0 : SPWSet res;
48 0 : for(size_t i=0; i<specTable.nrow(); ++i)
49 : {
50 0 : if (nc(i)==4)
51 0 : res.insert(i);
52 : }
53 0 : return res;
54 0 : }
55 :
56 : std::set<size_t>
57 0 : WVRDataDescIDs(const casacore::MeasurementSet &ms,
58 : const std::vector<int> &wvrspws)
59 : {
60 0 : SPWSet ssfull=WVRSPWIDs(ms);
61 0 : std::map<size_t, size_t> ddmap=SPWDataDescMap(ms);
62 0 : std::set<size_t> res;
63 :
64 0 : SPWSet ss;
65 0 : if(wvrspws.size()==0){
66 0 : ss = ssfull;
67 : }
68 : else{
69 0 : for(size_t i=0; i<wvrspws.size(); i++){
70 0 : if(ssfull.count(wvrspws[i])){
71 0 : ss.insert(wvrspws[i]);
72 : }
73 : }
74 : }
75 :
76 0 : for(SPWSet::const_iterator si=ss.begin();
77 0 : si!=ss.end();
78 0 : ++si)
79 : {
80 0 : if (ddmap.count(*si))
81 : {
82 0 : res.insert(ddmap[*si]);
83 : }
84 : }
85 0 : return res;
86 0 : }
87 :
88 0 : size_t nWVRSPWIDs(const casacore::MeasurementSet &ms)
89 : {
90 0 : SPWSet s=WVRSPWIDs(ms);
91 0 : return s.size();
92 0 : }
93 :
94 : AntSet
95 0 : WVRAntennas(const casacore::MeasurementSet &ms,
96 : const std::vector<int> &wvrspws)
97 : {
98 0 : AntSet res=WVRAntennasFeedTab(ms, wvrspws);
99 0 : if (res.size() == 0)
100 : {
101 0 : res=WVRAntennasMainTab(ms, wvrspws);
102 : }
103 0 : return res;
104 0 : }
105 :
106 : AntSet
107 0 : WVRAntennasFeedTab(const casacore::MeasurementSet &ms,
108 : const std::vector<int> &wvrspws)
109 : {
110 0 : const casacore::MSFeed &feedtable=ms.feed();
111 :
112 : casacore::ScalarColumn<casacore::Int> ant(feedtable,
113 0 : casacore::MSFeed::columnName(casacore::MSFeed::ANTENNA_ID));
114 :
115 : casacore::ScalarColumn<casacore::Int> fspw(feedtable,
116 0 : casacore::MSFeed::columnName(casacore::MSFeed::SPECTRAL_WINDOW_ID));
117 :
118 0 : const size_t nfeeds=feedtable.nrow();
119 0 : AntSet res;
120 0 : for (size_t i=0; i<nfeeds; ++i){
121 0 : for (size_t j=0; j<wvrspws.size(); j++){
122 0 : if(fspw(i)==wvrspws[j]){
123 0 : res.insert(ant(i));
124 : }
125 : }
126 : }
127 :
128 0 : return res;
129 :
130 0 : }
131 :
132 : AntSet
133 0 : WVRAntennasMainTab(const casacore::MeasurementSet &ms,
134 : const std::vector<int> &wvrspws)
135 : {
136 0 : std::set<size_t> dsc_ids=WVRDataDescIDs(ms, wvrspws);
137 :
138 : casacore::ScalarColumn<casacore::Int> c_desc_id(ms,
139 0 : casacore::MS::columnName(casacore::MS::DATA_DESC_ID));
140 : casacore::ScalarColumn<casacore::Int> a1(ms,
141 0 : casacore::MS::columnName(casacore::MS::ANTENNA1));
142 :
143 0 : AntSet res;
144 0 : const size_t nrows=c_desc_id.nrow();
145 0 : for(size_t i=0; i<nrows; ++i)
146 : {
147 0 : if (dsc_ids.count(c_desc_id(i))>0)
148 : {
149 0 : res.insert(a1(i));
150 : }
151 : }
152 0 : return res;
153 0 : }
154 :
155 0 : void WVRAddFlaggedAnts(const casacore::MeasurementSet &ms,
156 : LibAIR2::AntSet &flaggedAnts)
157 : {
158 : // add the antennas flagged in the ANTENNA table to the set
159 0 : casacore::ScalarColumn<casacore::Bool> antflagrow(ms.antenna(),
160 0 : casacore::MSAntenna::columnName(casacore::MSAntenna::FLAG_ROW));
161 0 : const size_t nants=ms.antenna().nrow();
162 0 : for(size_t i=0; i<nants; i++)
163 : {
164 0 : if(antflagrow(i)==casacore::True) // i.e. flagged
165 : {
166 0 : flaggedAnts.insert(i);
167 : }
168 : }
169 0 : }
170 :
171 :
172 0 : void WVRTimeStatePoints(const casacore::MeasurementSet &ms,
173 : std::vector<double> ×,
174 : std::vector<size_t> &states,
175 : std::vector<size_t> &field,
176 : std::vector<size_t> &source,
177 : const std::vector<int> &wvrspws,
178 : const std::vector<size_t> &sortedI)
179 : {
180 0 : std::set<size_t> dsc_ids=WVRDataDescIDs(ms, wvrspws);
181 0 : size_t dsc_id = *dsc_ids.begin();
182 :
183 : casacore::ScalarColumn<casacore::Double> c_times(ms,
184 0 : casacore::MS::columnName(casacore::MS::TIME));
185 : casacore::ScalarColumn<casacore::Int> c_states(ms,
186 0 : casacore::MS::columnName(casacore::MS::STATE_ID));
187 : casacore::ScalarColumn<casacore::Int> c_field(ms,
188 0 : casacore::MS::columnName(casacore::MS::FIELD_ID));
189 :
190 : casacore::ScalarColumn<casacore::Int> c_desc_id(ms,
191 0 : casacore::MS::columnName(casacore::MS::DATA_DESC_ID));
192 : casacore::ScalarColumn<casacore::Int> a1(ms,
193 0 : casacore::MS::columnName(casacore::MS::ANTENNA1));
194 :
195 : casacore::ArrayColumn<casacore::Bool> c_flags(ms,
196 0 : casacore::MS::columnName(casacore::MS::FLAG));
197 :
198 0 : std::map<size_t, size_t> srcmap=getFieldSrcMap(ms);
199 :
200 0 : times.resize(0);
201 0 : states.resize(0);
202 :
203 0 : double prev_time=0.;
204 :
205 0 : const size_t nrows=c_desc_id.nrow();
206 0 : for(size_t ii=0; ii<nrows; ++ii)
207 : {
208 :
209 0 : size_t i = sortedI[ii];
210 :
211 0 : if (c_times(i)>prev_time and // only one entry per time stamp
212 0 : c_desc_id(i)==(int)dsc_id
213 : )
214 : {
215 0 : prev_time = c_times(i);
216 :
217 0 : bool haveUnflaggedWvrData=false;
218 0 : size_t iii=ii;
219 0 : while(iii<nrows && c_times(sortedI[iii])==prev_time)
220 : {
221 : // while in this timestamp, check if there is unflagged WVR data
222 0 : if(c_desc_id(sortedI[iii])==(int)dsc_id and
223 0 : casacore::allEQ(casacore::False, c_flags(sortedI[iii]))) // i.e. not flagged
224 : {
225 0 : haveUnflaggedWvrData=true;
226 0 : break;
227 : }
228 0 : iii++;
229 : }
230 0 : if(haveUnflaggedWvrData)
231 : {
232 0 : times.push_back(c_times(i));
233 0 : states.push_back(c_states(i));
234 0 : field.push_back(c_field(i));
235 : #if __GNUC__ <= 4 and __GNUC_MINOR__ < 1
236 : source.push_back(srcmap[(c_field(i))]);
237 : #else
238 0 : source.push_back(srcmap.at(c_field(i)));
239 : #endif
240 : }
241 : }
242 : }
243 0 : }
244 :
245 0 : void loadPointing(const casacore::MeasurementSet &ms,
246 : std::vector<double> &time,
247 : std::vector<double> &az,
248 : std::vector<double> &el)
249 : {
250 0 : const casacore::MSPointing &ptable=ms.pointing();
251 0 : const casacore::MSPointingColumns ptablecols(ptable);
252 0 : const casacore::ArrayColumn<casacore::Double> &dir=ptablecols.direction();
253 0 : const casacore::ScalarColumn<casacore::Double> &ptime=ptablecols.time();
254 :
255 0 : const size_t n=ptime.nrow();
256 0 : if(n==0){
257 0 : throw LibAIR2::MSInputDataError("Didn't find any POINTING data points");
258 : }
259 :
260 0 : time.resize(n);
261 0 : az.resize(n);
262 0 : el.resize(n);
263 0 : for(size_t i=0; i<n; ++i)
264 : {
265 0 : time[i]=ptime(i);
266 0 : casacore::Array<casacore::Double> a;
267 0 : dir.get(i, a,
268 : casacore::True);
269 0 : az[i]=a(casacore::IPosition(2,0,0));
270 0 : el[i]=a(casacore::IPosition(2,1,0));
271 0 : }
272 0 : }
273 :
274 : /** Get the nearest pointing record to each WVR observation
275 : */
276 0 : bool WVRNearestPointing(const casacore::MeasurementSet &ms,
277 : const std::vector<double> &time,
278 : std::vector<double> &az,
279 : std::vector<double> &el)
280 : {
281 :
282 0 : std::vector<double> ptime, paz, pel;
283 0 : bool rval = true;
284 : try{
285 0 : loadPointing(ms,
286 : ptime,
287 : paz,
288 : pel);
289 : }
290 0 : catch(const std::runtime_error rE){
291 0 : std::cerr << std::endl << "WARNING: problem while accessing POINTING table:"
292 0 : << std::endl << " LibAIR2::WVRNearestPointing: " << rE.what() << std::endl;
293 0 : std::cout << std::endl << "WARNING: problem while accessing POINTING table:"
294 0 : << std::endl << " LibAIR2::WVRNearestPointing: " << rE.what() << std::endl;
295 0 : rval = false;
296 0 : }
297 :
298 0 : size_t wrows=time.size();
299 0 : size_t prows=ptime.size();
300 :
301 0 : az.resize(wrows);
302 0 : el.resize(wrows);
303 :
304 0 : size_t pi=0;
305 :
306 0 : for (size_t wi=0; wi<wrows; ++wi)
307 : {
308 0 : while(pi<(prows-1) and ptime[pi]<time[wi])
309 0 : ++pi;
310 0 : az[wi]=paz[pi];
311 0 : el[wi]=pel[pi];
312 : }
313 :
314 0 : return rval;
315 :
316 0 : }
317 :
318 : /** Calculate the AZ and EL for each WVR observation based on the field table
319 : */
320 0 : void WVRFieldAZEl(const casacore::MeasurementSet &ms,
321 : const std::vector<double> &time,
322 : const std::vector<size_t> &fields,
323 : std::vector<double> &az,
324 : std::vector<double> &el)
325 : {
326 :
327 0 : casacore::MSDerivedValues msd;
328 0 : casacore::MEpoch etime;
329 0 : casacore::MDirection azel;
330 :
331 :
332 0 : msd.setMeasurementSet(ms);
333 0 : msd.setAntenna(0); // use antenna 0 as reference position
334 :
335 0 : size_t wrows=time.size();
336 :
337 0 : az.resize(wrows);
338 0 : el.resize(wrows);
339 :
340 0 : for (size_t wi=0; wi<wrows; ++wi)
341 : {
342 0 : etime.set(casacore::MVEpoch(casacore::Quantity(time[wi], "s")));
343 0 : msd.setEpoch(etime);
344 0 : msd.setFieldCenter(fields[wi]);
345 0 : azel = msd.azel();
346 0 : az[wi]=azel.getAngle().getValue()[0];
347 0 : el[wi]=azel.getAngle().getValue()[1];
348 : }
349 :
350 0 : return;
351 :
352 0 : }
353 :
354 :
355 0 : InterpArrayData *loadWVRData(const casacore::MeasurementSet &ms, const std::vector<int>& wvrspws,
356 : std::vector<size_t>& sortedI,
357 : std::set<int>& flaggedantsInMain,
358 : double requiredUnflaggedFraction,
359 : bool usepointing,
360 : std::string offsetstable)
361 : {
362 0 : bool haveOffsets=false;
363 0 : casacore::Vector<casacore::Double> offsetTime;
364 0 : casacore::Vector<casacore::Int> offsetAnts;
365 0 : casacore::Matrix<casacore::Double> offsets;
366 0 : if(offsetstable!=""){
367 : try{
368 0 : casacore::Table offsettab(offsetstable);
369 0 : casacore::ScalarColumn<casacore::Double> timecol(offsettab, "TIME");
370 0 : casacore::ScalarColumn<casacore::Int> antcol(offsettab, "ANTENNA");
371 0 : casacore::ArrayColumn<casacore::Double> offsetcol(offsettab, "OFFSETS");
372 0 : if(offsettab.nrow()>0){
373 0 : timecol.getColumn(offsetTime, casacore::True);
374 0 : antcol.getColumn(offsetAnts, casacore::True);
375 0 : offsetcol.getColumn(offsets, casacore::True);
376 0 : haveOffsets=true;
377 : //for(size_t i=0; i<offsetAnts.size(); i++){
378 : // std::cout << std::setprecision(15) << offsetTime[i] << " " << offsetAnts[i] << " " << offsets.column(i) << std::endl;
379 : //}
380 : }
381 : else{
382 0 : throw LibAIR2::MSInputDataError("Provided Offsets Table is empty");
383 : }
384 0 : }
385 0 : catch(std::exception rE){
386 0 : std::cerr << "ERROR reading offsets table " << offsetstable << std::endl;
387 0 : throw rE;
388 0 : }
389 : }
390 :
391 0 : std::set<size_t> dsc_ids=WVRDataDescIDs(ms, wvrspws);
392 0 : AntSet wvrants=WVRAntennas(ms, wvrspws);
393 0 : const size_t nAnts=ms.antenna().nrow();
394 :
395 0 : if(requiredUnflaggedFraction<0.){
396 0 : std::cout << "WARNING: Negative required fraction of unflagged data points. Will assume 0." << std::endl;
397 0 : requiredUnflaggedFraction=0.;
398 : }
399 0 : if(requiredUnflaggedFraction>1.){
400 0 : std::cout << "WARNING: Required fraction of unflagged data points > 1. Will assume 1." << std::endl;
401 0 : requiredUnflaggedFraction=1.;
402 : }
403 :
404 : casacore::ScalarColumn<casacore::Double> maintime(ms,
405 0 : casacore::MS::columnName(casacore::MS::TIME));
406 :
407 0 : const size_t nrows=maintime.nrow();
408 :
409 0 : sortedI.resize(nrows);
410 0 : flaggedantsInMain.clear();
411 :
412 : {
413 0 : casacore::Vector<casacore::uInt> sortedIV(nrows);
414 0 : casacore::Vector<casacore::Double> mainTimesV = maintime.getColumn();
415 0 : casacore::GenSortIndirect<casacore::Double>::sort(sortedIV,mainTimesV);
416 0 : for(casacore::uInt i=0; i<nrows; i++){ // necessary for type conversion
417 0 : sortedI[i] = (size_t) sortedIV(i);
418 : }
419 0 : }
420 :
421 0 : std::vector<double> times, az, el;
422 0 : std::vector<size_t> states, fields, source;
423 0 : WVRTimeStatePoints(ms,
424 : times,
425 : states,
426 : fields,
427 : source,
428 : wvrspws,
429 : sortedI);
430 :
431 0 : if (times.size() == 0){
432 0 : throw LibAIR2::MSInputDataError("Didn't find any WVR data points");
433 : }
434 :
435 0 : if(usepointing && !WVRNearestPointing(ms, times, az, el)){
436 0 : std::cout << "Could not get antenna pointing information from POINTING table." << std::endl;
437 0 : std::cerr << "Could not get antenna pointing information from POINTING table." << std::endl;
438 0 : usepointing=false;
439 : }
440 0 : if(!usepointing){
441 0 : std::cout << "Deriving antenna pointing information from FIELD table ..." << std::endl;
442 0 : std::cerr << "Deriving antenna pointing information from FIELD table ..." << std::endl;
443 0 : WVRFieldAZEl(ms, times, fields, az, el);
444 : }
445 :
446 : std::unique_ptr<InterpArrayData>
447 : res(new InterpArrayData(times,
448 : el,
449 : az,
450 : states,
451 : fields,
452 : source,
453 0 : nAnts));
454 :
455 : // This holds how far we've filled in for each of the antennas
456 :
457 0 : int counter = -1;
458 :
459 0 : std::vector<size_t> nunflagged(nAnts, 0);
460 0 : std::vector<size_t> ntotal(nAnts, 0);
461 :
462 0 : casacore::ArrayColumn<casacore::Complex> indata(ms, casacore::MS::columnName(casacore::MS::DATA));
463 0 : casacore::ScalarColumn<casacore::Int> indsc_id(ms, casacore::MS::columnName(casacore::MS::DATA_DESC_ID));
464 0 : casacore::ScalarColumn<casacore::Int> a1(ms, casacore::MS::columnName(casacore::MS::ANTENNA1));
465 0 : casacore::ScalarColumn<casacore::Int> a2(ms, casacore::MS::columnName(casacore::MS::ANTENNA2));
466 :
467 0 : casacore::ArrayColumn<casacore::Bool> inflags(ms, casacore::MS::columnName(casacore::MS::FLAG));
468 :
469 0 : casacore::ScalarColumn<casacore::Double> c_times(ms, casacore::MS::columnName(casacore::MS::TIME));
470 :
471 0 : std::vector<size_t> offsetSortedI;
472 0 : size_t nOffRows=0;
473 :
474 0 : if(haveOffsets){ // prepare offset application
475 0 : for(casacore::uInt i=0; i<nrows; i++){
476 0 : if (a1(i) == a2(i) and
477 0 : dsc_ids.count(indsc_id(i)) > 0)
478 : {
479 0 : ++nOffRows;
480 : }
481 : }
482 :
483 0 : if(offsetTime.size() != nOffRows){
484 0 : std::cout << "offsetTime.size() nOffRows nrows " << offsetTime.size() << " "
485 0 : << nOffRows << " " << nrows << std::endl;
486 0 : throw LibAIR2::MSInputDataError("Provided Offsets Table number of rows does not match the number of WVR data rows in MS.");
487 : }
488 0 : offsetSortedI.resize(nOffRows);
489 :
490 0 : casacore::Vector<casacore::uInt> offsetSortedIV(nOffRows);
491 0 : casacore::GenSortIndirect<casacore::Double>::sort(offsetSortedIV,offsetTime);
492 0 : for(casacore::uInt i=0; i<nOffRows; i++){ // necessary for type conversion
493 0 : offsetSortedI[i] = (size_t) offsetSortedIV(i);
494 : }
495 0 : }
496 :
497 : //size_t offsetIndex=0;
498 0 : size_t offI=0;
499 0 : size_t offRow=0;
500 0 : double prevtime=0;
501 :
502 0 : for(size_t ii=0; ii<nrows; ++ii)
503 : {
504 0 : size_t i = sortedI[ii];
505 :
506 0 : if (a1(i) == a2(i) and
507 0 : dsc_ids.count(indsc_id(i)) > 0)
508 : {
509 :
510 0 : if(haveOffsets){
511 0 : offI = offsetSortedI[offRow];
512 0 : ++offRow;
513 : }
514 :
515 0 : int newtimestamp = 0;
516 0 : if(c_times(i)>prevtime)
517 : {
518 0 : prevtime = c_times(i);
519 0 : newtimestamp = 1;
520 : }
521 :
522 0 : if(c_times(i)==times[counter+newtimestamp]) // there is data for this timestamp
523 : {
524 :
525 0 : if(newtimestamp==1)
526 : {
527 0 : ++counter;
528 : }
529 :
530 0 : ++(ntotal[a1(i)]);
531 :
532 0 : casacore::Array<casacore::Bool> fl;
533 0 : inflags.get(i, fl, ::casacore::True);
534 :
535 0 : if(casacore::allEQ(casacore::False, inflags(i))) // i.e. not flagged
536 : {
537 0 : casacore::Array<std::complex<float> > a;
538 0 : indata.get(i,a, casacore::True);
539 0 : bool tobsbad=false;
540 0 : bool matchingOffset=true;
541 :
542 0 : if(haveOffsets){
543 0 : if(offsetTime(offI) != c_times(i)){
544 0 : std::cerr << "WARNING: time disagreement: j i (offsetTime(j) - c_times(i)) "
545 0 : << offI << " " << i << " " << offsetTime(offI) - c_times(i)
546 0 : << std::endl;
547 0 : matchingOffset=false;
548 : }
549 0 : if(offsetAnts(offI) != a1(i)){
550 0 : std::cerr << "WARNING: antenna mismatch: j i offsetAnts(j) a1(i) "
551 0 : << offI << " " << i << " " << offsetAnts(offI) << " " << a1(i)
552 0 : << std::endl;
553 0 : matchingOffset=false;
554 : }
555 : }
556 :
557 0 : for(size_t k=0; k<4; ++k)
558 : {
559 0 : casacore::Double rdata = a(casacore::IPosition(2,k,0)).real();
560 :
561 0 : if(haveOffsets && matchingOffset){
562 0 : rdata -= offsets(k, offI);
563 : }
564 :
565 0 : if(2.7<rdata and rdata<300.){
566 0 : res->set(counter,
567 0 : a1(i),
568 : k,
569 : rdata);
570 : }
571 : else{
572 0 : tobsbad=true;
573 : }
574 : }
575 0 : if(tobsbad){ // TObs outside permitted range
576 0 : for(size_t k=0; k<4; ++k){
577 0 : res->set(counter, a1(i), k, 0.);
578 : }
579 : }
580 : else{
581 0 : nunflagged[a1(i)]++;
582 : }
583 0 : }
584 : else{ // flagged
585 0 : for(size_t k=0; k<4; ++k){
586 0 : res->set(counter, a1(i), k, 0.);
587 : }
588 : }
589 0 : } // end if c_times ...
590 : }
591 : } // end for ii
592 :
593 0 : bool allFlagged=true;
594 0 : for(AntSet::iterator it=wvrants.begin(); it != wvrants.end(); it++)
595 : {
596 0 : if(nunflagged[*it]>0)
597 : {
598 0 : allFlagged=false;
599 0 : break;
600 : }
601 : }
602 0 : if(!allFlagged)
603 : {
604 0 : allFlagged = true;
605 0 : for(AntSet::iterator it=wvrants.begin(); it != wvrants.end(); it++)
606 : {
607 0 : if(nunflagged[*it]==0)
608 : {
609 0 : std::cout << "All WVR data points for antenna " << *it << " are flagged." << std::endl;
610 0 : flaggedantsInMain.insert(*it);
611 : }
612 0 : else if(nunflagged[*it]<requiredUnflaggedFraction * ntotal[*it])
613 : {
614 0 : std::cout << "The fraction of good (unflagged) WVR data points for antenna " << *it
615 0 : << " is " << nunflagged[*it] << " out of " << ntotal[*it]
616 0 : << ". This is below the required " << requiredUnflaggedFraction*100.
617 0 : << "%. Antenna will be flagged." << std::endl;
618 0 : flaggedantsInMain.insert(*it);
619 : }
620 : else{
621 0 : allFlagged=false;
622 : }
623 : }
624 0 : if(allFlagged)
625 : {
626 0 : throw LibAIR2::MSInputDataError("All antennas needed to be flagged.");
627 : }
628 : }
629 : else
630 : {
631 0 : throw LibAIR2::MSInputDataError("All WVR data points are flagged.");
632 : }
633 :
634 0 : return res.release();
635 :
636 0 : }
637 :
638 :
639 :
640 : }
641 :
642 :
|