Line data Source code
1 : #include <vector>
2 : #include <iostream>
3 :
4 : #include <alma/ASDMBinaries/Error.h>
5 : #include <alma/ASDMBinaries/BaselinesSet.h>
6 :
7 : using namespace asdm;
8 : using namespace sdmbin;
9 : using namespace std;
10 :
11 : using namespace AxisNameMod;
12 : using namespace BasebandNameMod;
13 : using namespace CorrelationModeMod;
14 : using namespace DataContentMod;
15 :
16 : // constructors
17 0 : BaselinesSet::BaselinesSet(){
18 0 : bool coutest=false;
19 0 : if(coutest)cout<<"Constructor vide BaselinesSet" <<endl;
20 0 : }
21 :
22 0 : BaselinesSet::BaselinesSet( vector<Tag> v_antennaIdArray,
23 : vector<int> v_feedIdArray,
24 : vector<int> v_phasedArrayList,
25 : vector<bool> v_antennaUsedArray,
26 : DataDescriptionsSet &dataDescriptionsSet
27 0 : ):
28 : DataDescriptionsSet(dataDescriptionsSet),
29 0 : v_AntennaIdArray_(v_antennaIdArray),
30 0 : v_FeedIdArray_(v_feedIdArray),
31 0 : v_PhasedArrayList_(v_phasedArrayList)
32 : {
33 0 : bool coutest=false;
34 0 : if(coutest)cout << "Constructor BaselinesSet" << endl;
35 0 : if(coutest)cout << "v_AntennaIdArray_.size=" << v_AntennaIdArray_.size() << endl;
36 0 : numAntennas_ = v_antennaIdArray.size(); if(coutest)cout << "numAntennas_=" << numAntennas_ << endl;
37 0 : numFeeds_ = v_feedIdArray.size()/numAntennas_; if(coutest)cout << "numFeeds_= " << numFeeds_ << endl;
38 :
39 :
40 0 : for(unsigned int na=0; na<numAntennas_; na++)
41 0 : if(v_antennaUsedArray[na])
42 0 : v_effAntennaIdArray_.push_back(v_antennaIdArray[na]);
43 0 : numEffAntennas_ = v_effAntennaIdArray_.size();
44 :
45 0 : if(coutest)cout << "numEffAntennas_=" << numEffAntennas_ << endl;
46 0 : numBaselines_ = (numAntennas_*(numAntennas_-1))/2; // number of cross-correlation baselines
47 0 : if(coutest)cout << "numBaselines_=" << numBaselines_ << endl;
48 0 : numEffBaselines_ = (numEffAntennas_*(numEffAntennas_-1))/2; // number of effective cross-correlation baselines
49 0 : if(coutest)cout << "numEffBaselines_=" << numEffBaselines_ << endl;
50 0 : }
51 :
52 0 : BaselinesSet::BaselinesSet(const BaselinesSet & a) : DataDescriptionsSet(a) {
53 0 : cout << "Copy constructor BaselinesSet" << endl;
54 :
55 : // attributes inherited from the class SwitchCyclesList:
56 0 : m_bn_v_scId_ = a.m_bn_v_scId_;
57 0 : m_bn_v_numBin_ = a.m_bn_v_numBin_;
58 0 : vv_numBin_ = a.vv_numBin_;
59 0 : v_numBin_ = a.v_numBin_;
60 0 : datasetPtr_ = a.datasetPtr_;
61 0 : vv_switchCycleId_ = a.vv_switchCycleId_;
62 0 : v_switchCycleId_ = a.v_switchCycleId_;
63 :
64 : // attributes inherited from the class DataDescriptionsSet:
65 0 : v_numPol_ = a.v_numPol_;
66 0 : v_spwId_ = a.v_spwId_;
67 0 : v_numChan_ = a.v_numChan_;
68 0 : v_basebandName_ = a.v_basebandName_;
69 0 : vv_nsp_ = a.vv_nsp_;
70 :
71 0 : m_bn_v_ddp_ = a.m_bn_v_ddp_;
72 0 : m_ddid_bbn_ = a.m_ddid_bbn_;
73 : //cout << "1" << endl;
74 0 : numApc_ = a.numApc_;
75 0 : numDataDescription_ = a.numDataDescription_;
76 0 : e_cm_ = a.e_cm_;
77 0 : correlationMode_ = a.correlationMode_;
78 0 : es_apc_ = a.es_apc_;
79 0 : v_atmPhaseCorrection_ = a.v_atmPhaseCorrection_;
80 : //cout << "2" << endl;
81 0 : sumMetaDataIndex_ = a.sumMetaDataIndex_;
82 0 : sumAutoSize_ = a.sumAutoSize_;
83 0 : sumCrossSize_ = a.sumCrossSize_;
84 : //cout << "3" << endl;
85 0 : v_metaDataIndex_ = a.v_metaDataIndex_;
86 0 : v_cumulAutoSize_ = a.v_cumulAutoSize_;
87 0 : v_cumulCrossSize_ = a.v_cumulCrossSize_;
88 0 : v_numAutoData_ = a.v_numAutoData_;
89 0 : v_numCrossData_ = a.v_numCrossData_;
90 0 : v_autoSize_ = a.v_autoSize_;
91 0 : v_crossSize_ = a.v_crossSize_;
92 : //cout << "4" << endl;
93 0 : v_dataDescriptionIdArray_ = a.v_dataDescriptionIdArray_;
94 0 : v_crossDataDescriptionId_ = a.v_crossDataDescriptionId_;
95 0 : v_autoDataDescriptionId_ = a.v_autoDataDescriptionId_;
96 0 : v_basebandSet_ = a.v_basebandSet_;
97 0 : v_numSpwPerBb_ = a.v_numSpwPerBb_;
98 :
99 : // attribute in the present BaselinesSet class:
100 0 : v_AntennaIdArray_ = a.v_AntennaIdArray_;
101 0 : v_FeedIdArray_ = a.v_FeedIdArray_;
102 0 : v_PhasedArrayList_ = a.v_PhasedArrayList_;
103 0 : numAntennas_ = a.numAntennas_;
104 0 : numFeeds_ = a.numFeeds_;
105 0 : numEffAntennas_ = a.numEffAntennas_;
106 0 : numBaselines_ = a.numBaselines_;
107 0 : numEffBaselines_ = a.numEffBaselines_;
108 0 : v_effAntennaIdArray_ = a.v_effAntennaIdArray_;
109 0 : }
110 :
111 0 : BaselinesSet::~BaselinesSet(){}
112 :
113 0 : unsigned int BaselinesSet::getNumAntennas(){ return numAntennas_; }
114 :
115 0 : unsigned int BaselinesSet::getNumEffAntennas(){ return numEffAntennas_; }
116 :
117 0 : Tag BaselinesSet::getEffAntennaId(unsigned int na) {
118 0 : if(na>=v_effAntennaIdArray_.size())
119 0 : Error(SERIOUS,
120 : (char *) "The antenna index, %d, exceeds the maximum limit of %d",
121 0 : na,v_effAntennaIdArray_.size()-1);
122 0 : return v_effAntennaIdArray_[na];
123 : }
124 :
125 0 : int BaselinesSet::getFeedId(unsigned int na, unsigned int nfe) {
126 0 : if(na>=v_effAntennaIdArray_.size())
127 0 : Error(SERIOUS,
128 : (char *) "The antenna index, %d, exceeds the maximum limit of %d",
129 0 : na,v_effAntennaIdArray_.size()-1);
130 0 : if(nfe>=numFeeds_)
131 0 : Error(SERIOUS,
132 : (char *) "The feed index, %d, exceeds the maximum limit of %d deriving from the number of feeds in the configuration",
133 0 : nfe,numFeeds_-1);
134 0 : return v_FeedIdArray_[na*numFeeds_+nfe];
135 : }
136 :
137 0 : unsigned int BaselinesSet::getNumBaselines(){ return numBaselines_; }
138 :
139 0 : unsigned int BaselinesSet::getNumEffBaselines(){ return numEffBaselines_; }
140 :
141 0 : unsigned int BaselinesSet::baselineIndex( Tag antennaId1, Tag antennaId2) {
142 : // int iNum = 0; // iNum will be the (1 based) antennaNum in the list for antennaId1
143 : // int jNum = 0; // jNum will be the (1 based) antennaNum in the list for antennaId2
144 : // for(int n=0; n<numEffAntennas_; n++)if(v_effAntennaIdArray_[n]==antennaId1)iNum=n+1; if(iNum==0)return 0;
145 : // for(int n=0; n<numEffAntennas_; n++)if(v_effAntennaIdArray_[n]==antennaId2)jNum=n+1; if(jNum==0)return 0;
146 :
147 0 : unsigned int m = 0;
148 0 : unsigned int iIdx=baselineIndex(antennaId1);
149 0 : unsigned int jIdx=baselineIndex(antennaId2);
150 0 : if(iIdx>jIdx){
151 0 : m=jIdx; jIdx=iIdx; iIdx=m;
152 : }
153 0 : m = 0;
154 0 : for(unsigned int n=0; n<jIdx; n++)m=m+n;
155 0 : return m+iIdx;
156 : }
157 :
158 0 : unsigned int BaselinesSet::baselineIndex( Tag antennaId ) {
159 0 : for(unsigned int n=0; n<numEffAntennas_; n++)
160 0 : if(v_effAntennaIdArray_[n]==antennaId)return n;
161 0 : Error(FATAL,(char *) "No baseline index for antennaId=%s",antennaId.toString().c_str());
162 0 : return 0;
163 : }
164 :
165 :
166 : // unsigned int BaselinesSet::baselineIndex( unsigned int na1, unsigned int na2) {
167 :
168 : // // if(na1>=v_effAntennaIdArray_.size()){
169 : // // Error(FATAL,"The antenna index, %d, exceeds the limit of %d",
170 : // // na1,v_effAntennaIdArray_.size()-1);
171 : // // return 0;
172 : // // }
173 : // // if(na2>=v_effAntennaIdArray_.size()){
174 : // // Error(FATAL,"The antenna index, %d, exceeds the limit of %d",
175 : // // na2,v_effAntennaIdArray_.size()-1);
176 : // // return 0;
177 : // // }
178 :
179 : // unsigned int iIdx = min (na1, na2);
180 : // unsigned int jIdx = max (na1, na2);
181 : // /*
182 : // if(na1<na2){
183 : // iIdx = na1;
184 : // jIdx = na2;
185 : // }else{
186 : // iIdx = na2;
187 : // jIdx = na1;
188 : // }
189 : // unsigned int m = 0;
190 : // for(unsigned int n=0; n<jIdx; n++)m=m+n;
191 : // */
192 : // return jIdx * (jIdx - 1) / 2 + iIdx;
193 : // }
194 :
195 :
196 0 : unsigned int BaselinesSet::antenna1( unsigned int baselineIdx) {
197 : unsigned int iIdx;
198 : unsigned int jIdx;
199 : unsigned int m;
200 0 : for(unsigned int na1=0; na1<numEffAntennas_; na1++){
201 0 : for(unsigned int na2=na1; na2<numEffAntennas_; na2++){
202 0 : iIdx = na1;
203 0 : jIdx = na2;
204 0 : m = 0;
205 0 : for(unsigned int n=0; n<jIdx; n++)m += n;
206 0 : if((m+iIdx)==baselineIdx)return na1;
207 : }
208 : }
209 0 : Error(FATAL,(char *) "No antenna1 index for the requested baseline index %d",baselineIdx);
210 0 : return 0;
211 : }
212 :
213 0 : unsigned int BaselinesSet::antenna2( unsigned int baselineIdx) {
214 : unsigned int iIdx;
215 : unsigned int jIdx;
216 : unsigned int m;
217 0 : if(baselineIdx==0)return 0;
218 0 : for(unsigned int na1=0; na1<numEffAntennas_; na1++){
219 0 : for(unsigned int na2=na1; na2<numEffAntennas_; na2++){
220 0 : iIdx = na1;
221 0 : jIdx = na2;
222 0 : m = 0;
223 0 : for(unsigned int n=0; n<jIdx; n++)m += n;
224 0 : if((m+iIdx)==baselineIdx)return na2;
225 : }
226 : }
227 0 : Error(FATAL,(char *) "No antenna2 index for the requested baseline index %d",baselineIdx);
228 0 : return 0;
229 : }
230 :
231 0 : unsigned int BaselinesSet::feedIndex(Tag antId, int feedId) {
232 0 : int na = -1;
233 0 : for(unsigned int n=0; n<numAntennas_; n++)if(antId==v_AntennaIdArray_[n])na=n;
234 0 : if(na<0){
235 0 : Error(FATAL,
236 : (char *) "Antenna with identifier %s not in the configuration",
237 0 : antId.toString().c_str());
238 0 : return 0;
239 : }
240 0 : int nfe = -2;
241 0 : for(unsigned int n=0; n<numFeeds_; n++)if(feedId==v_FeedIdArray_[na*numFeeds_+n])nfe=n;
242 0 : if(nfe<0){
243 0 : Error(FATAL,
244 : (char *) "Feed identifier %d for antenna with the identifier %s not in the configuration",
245 0 : feedId,antId.toString().c_str());
246 0 : return nfe;
247 : }
248 0 : return (unsigned int) nfe;
249 : }
250 :
251 0 : unsigned int BaselinesSet::getNumPDTvalue(Enum<DataContent> e_dc, EnumSet<AxisName> es_an, bool effective){
252 :
253 0 : unsigned int nAntennas =1; if(es_an[ANT])nAntennas = numAntennas_; if(e_dc[CROSS_DATA])nAntennas =0;
254 0 : unsigned int nBaselines=1; if(es_an[BAL])nBaselines= numBaselines_; if(e_dc[AUTO_DATA]) nBaselines=0;
255 : // nBaseband is not currently used
256 : // unsigned int nBaseband =1; if(es_an[BAB])nBaseband = numBaseband();
257 0 : unsigned int nBin =1;
258 0 : unsigned int nApc =1; if(es_an[APC])nApc = es_apc_.count();
259 0 : unsigned int nSpp =1;
260 0 : unsigned int nPol =1;
261 : unsigned int npv;
262 0 : unsigned int nv1=0, nv2=0;
263 :
264 : // The concept of having in the binary the data only for those actualy producing data has been dropped
265 : // Hence, in practice effective should be alway set to false with the consequence that nAntennas and
266 : // nBaselines in general will reflect what has been actually scheduled in antenna resource to do the
267 : // observations.
268 0 : if(effective && e_dc[FLAGS]==false){
269 0 : if(es_an[ANT])nAntennas = numEffAntennas_;; if(e_dc[CROSS_DATA])nAntennas =0;
270 0 : if(es_an[BAL])nBaselines= numEffBaselines_; if(e_dc[AUTO_DATA]) nBaselines=0;
271 : }
272 :
273 : map<BasebandName,vector<DataDescParams> >::iterator
274 0 : itbnddp,
275 0 : itbnddpb=m_bn_v_ddp_.begin(),
276 0 : itbnddpe=m_bn_v_ddp_.end();
277 0 : for(itbnddp=itbnddpb;itbnddp!=itbnddpe; ++itbnddp){
278 0 : for(unsigned int nspw=0; nspw<itbnddp->second.size(); nspw++){
279 0 : if(es_an[POL]){
280 0 : nPol = itbnddp->second[nspw].numCorr;
281 0 : if(e_dc[FLAGS]||e_dc[ZERO_LAGS])if(nPol>2)nPol=2;
282 : }
283 0 : npv = nPol;
284 0 : if(e_dc[AUTO_DATA]){
285 0 : if(nPol==3)npv=4; // XX XY YY ==> 4 primitive values, 3 real values and 1 imaginary value
286 0 : if(nPol==4)npv=6; // XX XY YX YY ==> 6 primitive values (use-case not expected for ALMA)
287 : }
288 0 : if(e_dc[CROSS_DATA]){
289 0 : npv *=2; // 2 primitive values, all the data being complex numbers
290 : }
291 0 : if(es_an[SPP])nSpp=itbnddp->second[nspw].numChan;
292 0 : if(es_an[BIN])nBin=itbnddp->second[nspw].numBin;
293 0 : nv1 += npv*nBin*nSpp;
294 : }
295 : }
296 0 : if(e_cm_[AUTO_ONLY]){ // (multi) single-dish use-case
297 0 : nv1 = nv1*nAntennas*nApc;
298 0 : return nv1;
299 : }
300 0 : if(e_cm_[CROSS_ONLY]){ // non-standard use-case for ALMA, standard use-case for EVLA
301 0 : nv1 = nv1*nBaselines*nApc;
302 0 : return nv1;
303 : }
304 0 : if(e_dc[ZERO_LAGS]){ // these auxiliary data can be only antenna-based
305 0 : nv1 = nv1*nAntennas*nApc;
306 0 : return nv1;
307 : }
308 :
309 : // From here we are now only in the use-case CROSS_AND_AUTO (standard and almost always used for ALMA)
310 0 : unsigned int nv=0;
311 :
312 : // Comments about structural constraints:
313 : // FLAGS:
314 : // For the FLAGS meta-data the POL axis, if any, corresponds effectively to a PolarizationType
315 : // axis; the size of this POL axis must be the same for both the non-zero and zero baselines.
316 : // APC axis:
317 : // The following implementation assumes that the APC axis has a size which is the same for
318 : // the baseline-based and the antenna-based parts of the metadata (i.e. of ACTUAL_TIMES or
319 : // ACTUAL_DURATION or WEIGHTS or FLAGS). In practice we do not expect an APC axis for these
320 : // metadata. Would one WVRadiometer have a problem for one antenna, this will be known by looking
321 : // at the nature of the flags set in FLAGS; In such situations, for all the baselines which involve
322 : // the antenna(s) with WVR problems, the filler will retrieve ONLY the uncorrected data.
323 : // The implication is that actualTimes, actualDurations, weights and flags ARE NOT EXPECTED TO
324 : // HAVE "APC" IN THEIR SEQUENCE OF AXES in order to concisely describe the data.
325 0 : if(e_dc[FLAGS]){
326 0 : if(es_an[BAL])nv = nv1*nBaselines*nApc;
327 0 : if(es_an[ANT])nv += nv1*nAntennas*nApc;
328 0 : return nv;
329 : }
330 :
331 0 : if(e_dc[CROSS_DATA]){ // the query is for the size of crossData
332 0 : return nv1*nBaselines*nApc;
333 : }
334 :
335 : // From here we must also account for the implicit numPol of the zero-baselines because, when in the
336 : // case of CROSS_AND_AUTO, only the numPol for the non-zero baselines are explicit.
337 0 : nSpp=1;
338 0 : nBin=1;
339 0 : nPol=1;
340 0 : for(itbnddp=itbnddpb;itbnddp!=itbnddpe; ++itbnddp){
341 0 : for(unsigned int nspw=0; nspw<itbnddp->second.size(); nspw++){
342 0 : if(es_an[SPP])nSpp=itbnddp->second[nspw].numChan;
343 0 : if(es_an[BIN])nBin=itbnddp->second[nspw].numBin;
344 0 : if(es_an[POL])nPol=numPol(itbnddp->second[nspw].ddIdx);
345 0 : npv = nPol;
346 0 : if(es_an[POL] && e_dc[AUTO_DATA]){
347 0 : if(nPol==3)npv=4; // XX XY YY ==> 4 primitive values, 3 real values and 1 imaginary value
348 0 : if(nPol==4)npv=6; // XX XY YX YY ==> 6 primitive values (use-case not expected for ALMA)
349 : }
350 0 : nv2 += npv*nBin*nSpp;
351 : }
352 : }
353 0 : nv2 *= nAntennas*nApc;
354 0 : if(e_dc[AUTO_DATA]) // the query is for the size of autoData
355 0 : return nv2;
356 :
357 0 : if(es_an[BAL])nv += nv1;
358 0 : if(es_an[ANT])nv += nv2;
359 0 : return nv; // the query is for the size of actualTimes or actualDurations
360 :
361 : }
362 :
363 :
364 :
365 :
366 0 : unsigned int BaselinesSet::transferId(unsigned int na, unsigned int ndd, unsigned int nbin){
367 0 : unsigned int nfe=0;
368 0 : return transferId(na,nfe,ndd,nbin);
369 : }
370 :
371 0 : unsigned int BaselinesSet::transferId(unsigned int na, unsigned int nfe, unsigned int ndd, unsigned int nbin){
372 0 : unsigned int v_cumulAutoSize_ndd=0;
373 0 : if(v_cumulAutoSize_.size()!=0)v_cumulAutoSize_ndd=v_cumulAutoSize_[ndd];
374 0 : unsigned int v_autoSize_ndd=0;
375 0 : if(v_autoSize_.size()!=0)v_autoSize_ndd=v_autoSize_[ndd];
376 : return
377 0 : na*numFeeds_*sumAutoSize_ + // /antenna
378 0 : nfe*sumAutoSize_ + // /antenna/feed
379 : v_cumulAutoSize_ndd + // /antenna/feed/datadesc
380 0 : nbin*(v_autoSize_ndd/numBin(ndd)); // /antenna/feed/datadesc/bin
381 : }
382 :
383 :
384 :
385 0 : unsigned int BaselinesSet::transferId(unsigned int na1, unsigned int na2, unsigned int ndd, unsigned int nbin, unsigned int napc){
386 0 : unsigned int nfe=0;
387 0 : return transferId(na1,na2, nfe, ndd, nbin, napc);
388 : }
|