Line data Source code
1 : //# AMueller.cc: Implementation of AMueller
2 : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: casa-feedback@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 :
27 : #include <synthesis/CalTables/CalDescColumns.h>
28 : #include <synthesis/CalTables/CTColumns.h>
29 : #include <synthesis/CalTables/CTMainColumns.h>
30 : //#include <ms/MeasurementSets/MSColumns.h>
31 : #include <msvis/MSVis/VisBuffer.h>
32 : #include <msvis/MSVis/VisBuffGroupAcc.h>
33 : #include <msvis/MSVis/VBContinuumSubtractor.h>
34 : #include <synthesis/MeasurementComponents/CalCorruptor.h>
35 : #include <synthesis/MeasurementComponents/AMueller.h>
36 : #include <synthesis/MeasurementEquations/VisEquation.h>
37 :
38 : #include <msvis/MSVis/VisBuffer2.h>
39 :
40 :
41 : using namespace casacore;
42 : namespace casa { //# NAMESPACE CASA - BEGIN
43 :
44 :
45 : // **********************************************************
46 : // AMueller
47 : //
48 :
49 :
50 0 : AMueller::AMueller(VisSet& vs) :
51 : VisCal(vs), // virtual base
52 : VisMueller(vs), // virtual base
53 : MMueller(vs), // immediate parent
54 0 : fitorder_p(0),
55 0 : doSub_p(true),
56 0 : nCorr_p(-1)
57 : {
58 0 : if (prtlev()>2) cout << "A::A(vs)" << endl;
59 :
60 0 : init();
61 0 : }
62 :
63 0 : AMueller::AMueller(String msname,Int MSnAnt,Int MSnSpw) :
64 : VisCal(msname,MSnAnt,MSnSpw), // virtual base
65 : VisMueller(msname,MSnAnt,MSnSpw), // virtual base
66 : MMueller(msname,MSnAnt,MSnSpw), // immediate parent
67 0 : fitorder_p(0),
68 0 : doSub_p(true),
69 0 : nCorr_p(-1)
70 : {
71 0 : if (prtlev()>2) cout << "A::A(msname,MSnAnt,MSnSpw)" << endl;
72 :
73 0 : init();
74 0 : }
75 :
76 :
77 0 : AMueller::AMueller(const MSMetaInfoForCal& msmc) :
78 : VisCal(msmc), // virtual base
79 : VisMueller(msmc), // virtual base
80 : MMueller(msmc), // immediate parent
81 0 : fitorder_p(0),
82 0 : doSub_p(true),
83 0 : nCorr_p(-1)
84 : {
85 0 : if (prtlev()>2) cout << "A::A(msmc)" << endl;
86 :
87 0 : init();
88 0 : }
89 :
90 :
91 0 : AMueller::AMueller(const Int& nAnt) :
92 : VisCal(nAnt),
93 : VisMueller(nAnt),
94 : MMueller(nAnt), // immediate parent
95 0 : fitorder_p(0),
96 0 : doSub_p(true),
97 0 : nCorr_p(-1)
98 : {
99 0 : if (prtlev()>2) cout << "A::A(nAnt)" << endl;
100 :
101 0 : init();
102 0 : }
103 :
104 0 : AMueller::~AMueller() {
105 0 : if (prtlev()>2) cout << "A::~A()" << endl;
106 0 : }
107 :
108 0 : void AMueller::init()
109 : {
110 0 : lofreq_p.resize(nSpw());
111 0 : hifreq_p.resize(nSpw());
112 0 : totnumchan_p.resize(nSpw());
113 0 : spwApplied_p.resize(nSpw());
114 :
115 0 : lofreq_p = -1.0;
116 0 : hifreq_p = -1.0;
117 0 : totnumchan_p = 0;
118 0 : spwApplied_p = false;
119 0 : }
120 :
121 0 : void AMueller::setSolve(const Record& solvepar) {
122 :
123 : // Call parent
124 0 : MMueller::setSolve(solvepar);
125 :
126 : // Extract the AMueller-specific solve parameters
127 0 : if(solvepar.isDefined("fitorder"))
128 0 : fitorder_p = solvepar.asInt("fitorder");
129 :
130 0 : nChanParList() = fitorder_p + 1; // Orders masquerade as output chans.
131 :
132 : // Override preavg
133 : // (solver will fail if we don't average completely in each solint)
134 0 : preavg()=DBL_MAX;
135 0 : }
136 :
137 0 : void AMueller::setSolveChannelization(VisSet& vs)
138 : {
139 0 : Vector<Int> startDatChan(vs.startChan());
140 :
141 : // If fitorder_p != 0, this is frequency dependent.
142 0 : if(fitorder_p){
143 : // AMueller keeps its polynomial orders where channels would normally go,
144 : // and typically (advisedly) the number of orders is << the number of data
145 : // channels. *Otherwise* the overall par shape follows the data shape.
146 0 : nChanParList() = fitorder_p + 1; // Deja vu from setSolve().
147 0 : startChanList() = startDatChan;
148 :
149 : // However, for solving, we will only consider one channel at a time:
150 0 : nChanMatList() = 1;
151 : }
152 : else {
153 : // Pars are not themselves channel-dependent
154 0 : nChanParList() = 1;
155 :
156 : // Check if matrices may still be freq-dep:
157 0 : if (freqDepMat()) {
158 : // cal is an explicit f(freq) (e.g., like delay)
159 0 : nChanMatList() = vs.numberChan();
160 0 : startChanList() = startDatChan;
161 : } else {
162 : // cal has no freq dep at all
163 0 : nChanMatList() = Vector<Int>(nSpw(),1);
164 0 : startChanList() = Vector<Int>(nSpw(),0);
165 : }
166 : }
167 :
168 : // At this point:
169 : // 1. nChanParList() represents the number of coefficients per polynomial,
170 : // appropriate for shaping the CalSet.
171 : // 2. nChanMatList() represents the per-Spw matrix channel axis length to
172 : // be used during the solve, independent of the parameter channel
173 : // axis length. In the solve context, nChanMat()>1 when there is
174 : // more than one channel of data upon which the (single channel)
175 : // solve parameters depend (e.g. polynomial order != 1)
176 0 : }
177 :
178 0 : Int AMueller::sizeUpSolve(VisSet& vs, Vector<Int>& nChunkPerSol)
179 : {
180 0 : sortVisSet(vs);
181 0 : VisIter& vi(vs.iter());
182 :
183 0 : nCorr_p = fitorder_p ? vi.nCorr() : 2;
184 :
185 : // Would SolvableVisCal be better here? After all the need for this
186 : // specialization started with MMueller::nPar()...
187 0 : return MMueller::sizeUpSolve(vs, nChunkPerSol);
188 : }
189 :
190 0 : void AMueller::selfSolveOne(VisBuffGroupAcc& vbga)
191 : {
192 : // Solver for the polynomial continuum fit. It is overkill for fitorder_p ==
193 : // 0, and not used in that case.
194 :
195 0 : LogIO os(LogOrigin("AMueller", "selfSolveOne()", WHERE));
196 0 : VBContinuumSubtractor vbcs;
197 :
198 : // Initialize
199 0 : if(lofreq_p[currSpw()] < 0.0){ // 1st time for this spw, so let vbga
200 0 : vbcs.initFromVBGA(vbga); // provide the info.
201 0 : lofreq_p[currSpw()] = vbcs.getLowFreq();
202 0 : hifreq_p[currSpw()] = vbcs.getHighFreq();
203 0 : totnumchan_p[currSpw()] = vbcs.getTotNumChan();
204 : }
205 : else // Reuse the prev vals for consistency.
206 0 : vbcs.init(solveParOK().shape(), nAnt() - 1, totnumchan_p[currSpw()],
207 0 : lofreq_p[currSpw()], hifreq_p[currSpw()]);
208 :
209 0 : vbcs.fit(vbga, fitorder_p, MS::DATA, solveCPar(), solveParOK(),
210 0 : false, false, !append());
211 0 : }
212 :
213 0 : void AMueller::storeNCT() {
214 :
215 : // Update the freq info
216 0 : if(fitorder_p != 0){ // Store lofreq_p[currSpw()] and hifreq_p[currSpw()]
217 :
218 : // Access SPW subtable
219 0 : CTColumns ncc(*ct_);
220 :
221 : // We are expecting nSpw rows...
222 0 : AlwaysAssert( Int(ncc.spectralWindow().chanFreq().nrow())==nSpw(), AipsError);
223 :
224 : // We store the freq domain as a pair of values in chanFreq(),
225 : // and reset numChan()=fitorder_p
226 :
227 0 : Vector<Double> freqrange(2);
228 0 : for (Int ispw=0;ispw<nSpw();++ispw) {
229 : // Only if values are ok...
230 0 : if (lofreq_p[ispw]>0.0 &&
231 0 : hifreq_p[ispw]>0.0) {
232 0 : freqrange(0)=lofreq_p[ispw];
233 0 : freqrange(1)=hifreq_p[ispw];
234 0 : ncc.spectralWindow().chanFreq().setShape(ispw,IPosition(1,2));
235 0 : ncc.spectralWindow().chanFreq().put(ispw,freqrange);
236 0 : ncc.spectralWindow().numChan().put(ispw,fitorder_p+1);
237 0 : ncc.spectralWindow().flagRow().put(ispw,false);
238 : }
239 : else
240 : // Mark this spw flagged (no solutions in main
241 0 : ncc.spectralWindow().flagRow().put(ispw,true);
242 : }
243 0 : }
244 :
245 : // Now call conventional store
246 0 : MMueller::storeNCT();
247 :
248 0 : }
249 :
250 0 : void AMueller::hurl(const String& origin, const String& msg)
251 : {
252 0 : LogIO os(LogOrigin("AMueller", origin, WHERE));
253 :
254 0 : os << msg << LogIO::EXCEPTION;
255 0 : }
256 :
257 0 : void AMueller::setApply(const Record& applypar)
258 : {
259 0 : LogIO os(LogOrigin("AMueller", "setApply()", WHERE));
260 :
261 0 : if(applypar.isDefined("table")){
262 0 : calTableName() = applypar.asString("table");
263 0 : verifyCalTable(calTableName());
264 :
265 : {
266 : // TBD: Improve this kluge!
267 : // e.g., fitorder from a keyword, etc.
268 0 : NewCalTable ct0(calTableName(),Table::Old,Table::Plain);
269 0 : ROCTMainColumns ncmc(ct0);
270 0 : IPosition sh=ncmc.cparam().shape(0);
271 0 : nCorr_p = sh(0);
272 0 : fitorder_p= sh(1)-1;
273 0 : nChanParList().set(sh(1));
274 0 : }
275 : }
276 : else
277 : os << "AMueller::setApply(Record&) needs the record to have a table"
278 0 : << LogIO::EXCEPTION;
279 :
280 :
281 : // Call parent to get the general stuff
282 0 : MMueller::setApply(applypar);
283 :
284 : // Now get some uvcontsub-specific stuff
285 :
286 : // Extract freq domain for non-trivial fits
287 0 : if(fitorder_p != 0){
288 :
289 : // Access to SPW subtable..
290 0 : ROCTColumns ncc(*ct_);
291 0 : Vector<Bool> spwflrow;
292 0 : ncc.spectralWindow().flagRow().getColumn(spwflrow);
293 0 : Int nspw=spwflrow.nelements();
294 :
295 : // TBD: What if caltable contains more or less than nSpw() (from MS) spws?
296 :
297 0 : lofreq_p.resize(nspw);
298 0 : hifreq_p.resize(nspw);
299 :
300 0 : Vector<Double> freqrange(2);
301 0 : if (spwMap()(0)==-999) { // auto-fan-out
302 0 : Int ispw=0;
303 0 : while (spwflrow(ispw)) ++ispw; // find first good spw
304 0 : ncc.spectralWindow().chanFreq().get(ispw,freqrange);
305 0 : lofreq_p.set(freqrange(0));
306 0 : hifreq_p.set(freqrange(1));
307 : }
308 : else { // fill lo/hifreq per spw (only good ones)
309 0 : for (Int ispw=0;ispw<nspw;++ispw) {
310 0 : if (!spwflrow(ispw)) {
311 0 : ncc.spectralWindow().chanFreq().get(ispw,freqrange);
312 0 : lofreq_p[ispw]=freqrange(0);
313 0 : hifreq_p[ispw]=freqrange(1);
314 : }
315 : }
316 : }
317 :
318 0 : }
319 :
320 0 : }
321 :
322 : // Apply this calibration to VisBuffer visibilities
323 0 : void AMueller::applyCal(VisBuffer& vb, Cube<Complex>& Vout,Bool trial)
324 : {
325 0 : LogIO os(LogOrigin("AMueller", "applyCal()", WHERE));
326 :
327 0 : if(fitorder_p == 0){
328 0 : VisMueller::applyCal(vb, Vout, trial);
329 : }
330 : else{
331 0 : if(prtlev() > 3)
332 0 : os << " AMueller::applyCal()" << LogIO::POST;
333 :
334 0 : if (trial)
335 0 : throw(AipsError("trial apply not supported by AMueller with fitorder_p>0"));
336 :
337 0 : Int cspw = currSpw();
338 0 : VBContinuumSubtractor vbcs;
339 :
340 0 : if (lofreq_p[cspw]>0.0 &&
341 0 : hifreq_p[cspw]>0.0)
342 0 : vbcs.init(currCPar().shape(), nAnt() - 1, totnumchan_p[cspw],
343 0 : lofreq_p[cspw], hifreq_p[cspw]);
344 : else
345 0 : throw(AipsError("AMueller::applyCal: Bad freq domain info."));
346 :
347 : // Correct DATA (will write out to CORRECTED_DATA later)
348 0 : MS::PredefinedColumns whichcol = MS::DATA;
349 0 : if(!vbcs.apply(vb, whichcol, currCPar(), currParOK(), doSub_p,
350 0 : !spwApplied_p[cspw]))
351 0 : throw(AipsError("Could not place the continuum-subtracted data in "
352 0 : + MS::columnName(whichcol)));
353 0 : spwApplied_p[cspw] = true;
354 0 : }
355 0 : }
356 :
357 :
358 : // Apply this calibration to VisBuffer visibilities
359 0 : void AMueller::applyCal2(vi::VisBuffer2& vb,
360 : casacore::Cube<casacore::Complex>& Vout,casacore::Cube<casacore::Float>& Wout,
361 : casacore::Bool trial)
362 :
363 : {
364 0 : LogIO os(LogOrigin("AMueller", "applyCal2()", WHERE));
365 :
366 0 : if(fitorder_p == 0){
367 0 : VisMueller::applyCal2(vb, Vout, Wout, trial);
368 : }
369 : else{
370 0 : if(prtlev() > 3)
371 0 : os << " AMueller::applyCal2()" << LogIO::POST;
372 :
373 0 : if (trial)
374 0 : throw(AipsError("trial apply not supported by AMueller with fitorder_p>0"));
375 :
376 0 : Int cspw = currSpw();
377 0 : VBContinuumSubtractor vbcs;
378 :
379 0 : if (lofreq_p[cspw]>0.0 &&
380 0 : hifreq_p[cspw]>0.0)
381 0 : vbcs.init(currCPar().shape(), nAnt() - 1, totnumchan_p[cspw],
382 0 : lofreq_p[cspw], hifreq_p[cspw]);
383 : else
384 0 : throw(AipsError("AMueller::applyCal2: Bad freq domain info."));
385 :
386 : // Correct Vout
387 0 : if(!vbcs.apply2(vb, Vout, currCPar(), currParOK(), doSub_p,
388 0 : !spwApplied_p[cspw]))
389 0 : throw(AipsError("Error applying continuum-subtraction"));
390 :
391 0 : spwApplied_p[cspw] = true;
392 0 : }
393 0 : }
394 :
395 0 : void AMueller::corrupt(VisBuffer& vb)
396 : {
397 0 : LogIO os(LogOrigin("AMueller", "corrupt()", WHERE));
398 :
399 0 : if(prtlev() > 3)
400 0 : os << LogIO::NORMAL << " A::corrupt()" << LogIO::POST;
401 :
402 : // Initialize model data to zero, so corruption contains
403 : // only the AMueller solution
404 : // TBD: may wish to make this user togglable.
405 0 : vb.setModelVisCube(Complex(0.0));
406 :
407 0 : if(fitorder_p == 0){
408 : // Call general version:
409 0 : VisMueller::corrupt(vb);
410 : }
411 : else{
412 : // Ensure weight calibration off internally for corrupt
413 : // (corruption doesn't re-scale the data!)
414 0 : Bool userCalWt=calWt();
415 0 : calWt()=false;
416 :
417 : // Bring calibration up-to-date with the vb, with inversion turned OFF
418 0 : syncCal(vb,false);
419 :
420 0 : Int cspw = currSpw();
421 0 : VBContinuumSubtractor vbcs;
422 0 : if (lofreq_p[cspw]>0.0 &&
423 0 : hifreq_p[cspw]>0.0)
424 0 : vbcs.init(currCPar().shape(), nAnt() - 1, totnumchan_p[cspw],
425 0 : lofreq_p[cspw], hifreq_p[cspw]);
426 : else
427 0 : throw(AipsError("AMueller::applyCal: Bad freq domain info."));
428 :
429 0 : MS::PredefinedColumns whichcol = MS::MODEL_DATA;
430 0 : if(!vbcs.apply(vb, whichcol, currCPar(), currParOK(), false,
431 0 : !spwApplied_p[cspw]))
432 0 : throw(AipsError("Could not place the continuum estimate in "
433 0 : + MS::columnName(whichcol)));
434 0 : spwApplied_p[cspw] = true;
435 : // Restore user's calWt()
436 0 : calWt()=userCalWt;
437 0 : }
438 0 : }
439 :
440 0 : void ANoise::createCorruptor(const VisIter& vi, const Record& simpar, const Int nSim)
441 : {
442 0 : if (prtlev()>2) cout << " AN::createCorruptor()" << endl;
443 0 : AlwaysAssert((isSimulated()),AipsError);
444 :
445 0 : acorruptor_p = new ANoiseCorruptor();
446 0 : corruptor_p = acorruptor_p;
447 :
448 : // call generic parent to set corr,spw,etc info
449 0 : SolvableVisCal::createCorruptor(vi,simpar,nSim);
450 :
451 0 : Int Seed(1234);
452 0 : if (simpar.isDefined("seed")) {
453 0 : Seed=simpar.asInt("seed");
454 : }
455 :
456 0 : Float Amp(1.0);
457 0 : if (simpar.isDefined("amplitude")) {
458 0 : Amp=simpar.asFloat("amplitude");
459 : }
460 :
461 0 : acorruptor_p->initialize(Seed,Amp);
462 :
463 0 : String Mode("calc"); // calc means multiply by 1/sqrt(dnu dt)
464 0 : if (simpar.isDefined("mode")) {
465 0 : Mode=simpar.asString("mode");
466 : }
467 :
468 0 : acorruptor_p->mode()=Mode;
469 :
470 0 : if (prtlev()>2) cout << " ~AN::createCorruptor()" << endl;
471 :
472 0 : }
473 :
474 :
475 0 : ANoise::ANoise(VisSet& vs) :
476 : VisCal(vs), // virtual base
477 : VisMueller(vs), // virtual base
478 0 : SolvableVisMueller(vs) // immediate parent
479 : {
480 0 : if (prtlev()>2) cout << "ANoise::ANoise(vs)" << endl;
481 0 : }
482 :
483 0 : ANoise::ANoise(String msname,Int MSnAnt,Int MSnSpw) :
484 : VisCal(msname,MSnAnt,MSnSpw), // virtual base
485 : VisMueller(msname,MSnAnt,MSnSpw), // virtual base
486 0 : SolvableVisMueller(msname,MSnAnt,MSnSpw) // immediate parent
487 : {
488 0 : if (prtlev()>2) cout << "ANoise::ANoise(msname,MSnAnt,MSnSpw)" << endl;
489 0 : }
490 :
491 0 : ANoise::ANoise(const MSMetaInfoForCal& msmc) :
492 : VisCal(msmc), // virtual base
493 : VisMueller(msmc), // virtual base
494 0 : SolvableVisMueller(msmc) // immediate parent
495 : {
496 0 : if (prtlev()>2) cout << "ANoise::ANoise(msmc)" << endl;
497 0 : }
498 :
499 0 : ANoise::ANoise(const Int& nAnt) :
500 : VisCal(nAnt),
501 : VisMueller(nAnt),
502 0 : SolvableVisMueller(nAnt)
503 : {
504 0 : if (prtlev()>2) cout << "ANoise::ANoise(nAnt)" << endl;
505 0 : }
506 :
507 0 : ANoise::~ANoise() {
508 0 : if (prtlev()>2) cout << "ANoise::~ANoise()" << endl;
509 0 : }
510 :
511 :
512 : // Calculate Mueller matrices for all baselines
513 0 : void ANoise::calcAllMueller() {
514 :
515 0 : if (prtlev()>6) cout << " AN::calcAllMueller" << endl;
516 :
517 : // Should handle OK flags in this method, and only
518 : // do Mueller calc if OK
519 :
520 0 : Vector<Complex> oneMueller;
521 0 : Vector<Bool> oneMOK;
522 0 : Vector<Complex> onePar;
523 0 : Vector<Bool> onePOK;
524 :
525 0 : ArrayIterator<Complex> Miter(currMElem(),1);
526 0 : ArrayIterator<Bool> MOKiter(currMElemOK(),1);
527 0 : ArrayIterator<Complex> Piter(currCPar(),1);
528 0 : ArrayIterator<Bool> POKiter(currParOK(),1);
529 :
530 : // All required baselines
531 0 : Int iant1(0), iant2(-1);
532 0 : for (Int ibln=0; ibln<nCalMat(); ibln++) {
533 : // update antenna numbers of the current baseline (assumes iant1 <= iant2)
534 0 : iant2++;
535 0 : if (iant2 == nAnt()) {
536 0 : iant1++;
537 0 : iant2 = iant1;
538 : }
539 0 : corruptor_p->currAnt()=iant1;
540 0 : corruptor_p->currAnt2()=iant2;
541 :
542 : // The following assumes that nChanPar()=1 or nChanMat()
543 :
544 0 : for (Int ich=0; ich<nChanMat(); ich++) {
545 :
546 0 : oneMueller.reference(Miter.array());
547 0 : oneMOK.reference(MOKiter.array());
548 0 : onePar.reference(Piter.array());
549 0 : onePOK.reference(POKiter.array());
550 :
551 : // TBD What if calcOneMueller needs freq value info?
552 :
553 0 : calcOneMueller(oneMueller,oneMOK,onePar,onePOK);
554 :
555 : // Advance iterators, as required
556 0 : Miter.next();
557 0 : MOKiter.next();
558 0 : if (freqDepPar()) {
559 0 : Piter.next();
560 0 : POKiter.next();
561 : }
562 :
563 : }
564 :
565 : // Step to next baseline's pars if we didn't in channel loop
566 0 : if (!freqDepPar()) {
567 0 : Piter.next();
568 0 : POKiter.next();
569 : }
570 : }
571 :
572 0 : }
573 :
574 :
575 :
576 :
577 0 : void ANoise::calcOneMueller(Vector<Complex>& mat, Vector<Bool>& mOk,
578 : const Vector<Complex>& par, const Vector<Bool>& pOk) {
579 :
580 0 : if(prtlev() > 10)
581 : cout << " AN::calcOneMueller()\n"
582 0 : << "par: " << par // These are more to remove a compiler
583 0 : << "\npOk: " << pOk // warning (par & pOK unused)
584 0 : << endl; // than anything.
585 :
586 : // If Mueller matrix is trivial, shouldn't get here
587 0 : if (trivialMuellerElem())
588 0 : throw(AipsError("Trivial Mueller Matrix logic error."));
589 : else {
590 0 : Int len=0;
591 0 : mat.shape(len);
592 0 : for (Int i=0; i<len; i++) {
593 0 : mat[i]=acorruptor_p->simPar(); // single complex #
594 0 : mOk[i]=true;
595 : }
596 : }
597 0 : }
598 :
599 :
600 :
601 : } //# NAMESPACE CASA - END
|