Line data Source code
1 : #if !defined(_BASELINESSET_H)
2 :
3 : #include <alma/ASDM/ASDMEntities.h>
4 : #include <alma/ASDMBinaries/Error.h>
5 : #include <alma/ASDMBinaries/BaselineMetadata.h>
6 : #include <alma/ASDMBinaries/SwitchCyclesList.h>
7 : #include <alma/ASDMBinaries/DataDescriptionsSet.h>
8 :
9 : #include <alma/Enumtcl/AxisName.h>
10 : #include <alma/Enumtcl/DataContent.h>
11 :
12 :
13 : namespace sdmbin {
14 :
15 : /** Definition of the second level (the top level) in the tree hierarchy: include the antenna baseline
16 : * configuration */
17 : class BaselinesSet : public DataDescriptionsSet
18 : {
19 : public:
20 : BaselinesSet();
21 :
22 : /** Definition of the second level of the tree hierarchy
23 : * @pre the lower levels of the tree hierarchy are already known
24 : * @param v_antennaIdArray Array of antenna identifiers
25 : * @param v_feedIdArray Array of feed identifiers
26 : * \note Because with ALMA there is only one feed used at any time this vector has
27 : * the same size as v_antennaIdArray. With Focal Plane Array this size is
28 : * multiplied by the number of feeds in the FPA
29 : * @param v_phasedArrayList Place-holder, not yet implemented
30 : * @param v_antennaUsedArray Array to tell in the antennaIdArray which antenna have been actually used
31 : * for the data being stored. v_antennaUsedArray and v_antennaIdArray must have
32 : * the same size.
33 : * @param dataDescriptionsSet a dataDescriptionsSet object (<i>i.e.</i> the lower levels of the hierarchy
34 : * @post the whole tree hierarchy is now known, transfer identifier available for read and write methods
35 : * @note v_feedIdArray may be typed vector<vector<int> > in the future to better describe the case of
36 : * of focal plane arrays when used with interferometers
37 : */
38 : BaselinesSet( std::vector<asdm::Tag> v_antennaIdArray,
39 : std::vector<int> v_feedIdArray,
40 : std::vector<int> v_phasedArrayList,
41 : std::vector<bool> v_antennaUsedArray,
42 : DataDescriptionsSet& dataDescriptionsSet
43 : );
44 :
45 : /** Copy constructor */
46 : BaselinesSet(const BaselinesSet &);
47 :
48 : /** Destructor (use the default implementation) */
49 : ~BaselinesSet();
50 :
51 : /** Transfer identifier for a given node in the tree hierarchy for auto-correlation data
52 : * Transfer identifier for a given node in the tree hierarchy for auto-correlation data
53 : * @pre WARNING: if the use-case is CROSS_AND_AUTO and the current index ndd corresponds
54 : * to the case when crossDataDescriptionId is not associated to an autoDataDescriptionId,
55 : * i.e. when v_pairDataDescriptionId[ndd]==false, it is an error to invoke this method.
56 : * This situation is met with DSB front-ends, the sideband separation being possible only
57 : * for the cross data.
58 : * @param na Index of the antenna
59 : * @param ndd Index of the dataDescription
60 : * @param nbin Index for the step in a switchCycle (nbin=0 if no switchCycle mode used)
61 : * @return A position (counted in number of PDT values) in the container of auto-correlation
62 : * data where the data starts for the selection
63 : * @note Note that the APC axis has a size of 1 for the auto-correlations, even when, in the
64 : * CROSS_AND_AUTO mode, the cross data are stored with an APC axis size of 2. Would TelCal
65 : * not like this feature will have to be modified in the method size() of the base class
66 : * DataDescriptionsSet and this will have an additional napc input parameter.
67 : */
68 : unsigned int transferId(unsigned int na, unsigned int ndd, unsigned int nbin);
69 :
70 : /** Transfer identifier for a given node in the tree hierarchy for auto-correlation data
71 : * @pre WARNING: if the use-case is CROSS_AND_AUTO and the current index ndd corresponds
72 : * to the case when crossDataDescriptionId is not associated to a autoDataDescriptionId,
73 : * i.e. when v_pairDataDescriptionId[ndd]==false, it is an error to invoke this method.
74 : * This situation is met with DSB front-ends, the sideband separation being possible only
75 : * for the cross data.
76 : * @param na Index of the antenna
77 : * @param nfe Index of the feed (required when using FPAs)
78 : * @param ndd Index of the dataDescription
79 : * @param nbin Index for the step in a switchCycle (nbin=0 if no switchCycle mode used)
80 : * @return A position (counted in number of PDT values) in the container of auto-correlation
81 : * data where the data starts for the selection
82 : * @note Note that the APC axis has a size of 1 for the auto-correlations, even when, in the
83 : * CROSS_AND_AUTO mode, the cross data are stored with an APC axis size of 2. Would TelCal
84 : * not like this feature will have to be modified in the method size() of the base class
85 : * DataDescriptionsSet and this will have an additional napc input parameter.
86 : */
87 : unsigned int transferId(unsigned int na, unsigned int nfe, unsigned int ndd, unsigned int nbin);
88 :
89 : /** Transfer identifier for a given node in the tree hierarchy for cross-correlation data
90 : * @param na1 Index of the antenna 1
91 : * @param na2 Index of the antenna 2
92 : * @param ndd Index of the dataDescription
93 : * @param nbin index for the step in a switchCycle (nbin=0 if no switchCycle mode used)
94 : * @return A position (counted in number of PDT values) in the container of cross-correlation
95 : * data where the data starts for the selection
96 : * @note A baseline corresponds to a pair of indices. The convention is that the first index is
97 : * smaller than the second one (i.e. na1<na2). In case na2<na1, this method will consider
98 : * na2 as the first index and na1 as the second one.
99 : */
100 : unsigned int transferId(unsigned int na1, unsigned int na2, unsigned int ndd, unsigned int nbin, unsigned int napc);
101 :
102 : /** Transfer identifier for a given node in the tree hierarchy for cross-correlation data
103 : * @param na1 Index of the antenna 1
104 : * @param na2 Index of the antenna 2
105 : * @param nfe Index of the feed (required when using FPAs)
106 : * @param ndd Index of the dataDescription
107 : * @param nbin Index for the step in a switchCycle (0nbin=0 if no switchCycle mode used)
108 : * @return A position (counted in number of PDT values) in the container of cross-correlation
109 : * data where the data starts for the selection
110 : * @note A baseline corresponds to a pair of indices. The convention is that the first index is
111 : * smaller than the second one (i.e. na1<na2). In case na2<na1, this method will consider
112 : * na2 as the first index and na1 as the second one.
113 : */
114 : unsigned int transferId(unsigned int na1, unsigned int na2, unsigned int nfe, unsigned int ndd, unsigned int nbin, unsigned int napc);
115 :
116 : /** Baseline number for a given antenna identifier. This number is equal to i+1 where i is the antenna index in the
117 : * list of antennas effectively producing data. In this context this is the 'zero-baseline' number. This number
118 : * never exceed the number of effectively used antennas (given by the method getNumEffAntennas()).
119 : * @param antennaId Antenna identifier
120 : * @exception antennaId does not correspond to any of the antenna effectively producing data.
121 : * @return The baseline number (one-based)
122 : * @exception Error if there is no antenna effectively
123 : * producing data with this antennaId.
124 : */
125 : unsigned int baselineIndex( asdm::Tag antennaId) ;
126 :
127 : /** Baseline number for a given pair of antenna identifiers
128 : * @param antennaId1 Antenna identifier of one of the antenna in a pair of a non-zero baseline
129 : * @exception antennaId1 does not correspond to any of the antenna effectively producing data.
130 : * @param antennaId2 Antenna identifier of the other antenna in a pair to define the non-zero baseline
131 : * @exception antennaId2 does not correspond to any of the antenna effectively producing data.
132 : * @return The baseline number (one-based)
133 : * @exception Error if antennaId1 or (and) antennaId2 is (are) not associated to an antenna producing
134 : * effectively data.
135 : * \note Order of the baselines:\n
136 : * Example 1: Consider an antenna array with the list of identifiers (1,2,3,5) the pairs of identifier
137 : * defining the baselines are in the order (1,2 1,3 2,3 1,5 2,5 3,5).
138 : * Hence, if antennaId1=2 and antennaId2=3 the returned value is 3. \n
139 : * Example 2: Consider an antenna array with the list of identifiers (5,2,3,1) the pairs of identifier
140 : * defining the baselines are in the order (5,2 5,3 2,3 5,1 2,1 3,1).
141 : * If antennaId1=2 and antennaId2=3 the returned value is 3. If antennaId1=5 and antennaId2=1 the returned
142 : * value is 4. Note that if antennaId1=1 and antennaId2=5 the returned value will be again 4 due to the
143 : * convention that baselines are defined on the basis of a pair onf indices (see the note in the documentation
144 : * for the transferId(int, int, int, int, int) method.
145 : */
146 : unsigned int baselineIndex( asdm::Tag antennaId1, asdm::Tag antennaId2) ;
147 :
148 : /** Baseline number for a given pair of antenna indices in the list of antennas effectively producing data
149 : * @param na1 index (zero-based) of antenna 1
150 : * @exception na1 exceeds the maximum limit imposed by the number of antennas effectively producing data
151 : * @param na2 index (zero-based) of antenna 2
152 : * @exception na2 exceeds the maximum limit imposed by the number of antennas effectively producing data
153 : * @return the corresponding baseline number (one-based)
154 : * @exception Error this methods returns 0 in lax mode if na1 or na2 exceeds this maximum limit
155 : * @note
156 : * -# Order of the baselines:\n
157 : * Example for an antenna array consisting of 4 antennas the indices describing this array range
158 : * from 0 to 3. The pairs of indices for the baselines are in the order (0,1 0,2 1,2 0,3 1,3 2,3). Hence, if
159 : * na1=1 and na2=3 the returned value is 5.
160 : * -# By definition the first index in any pair being always smaller than the second index, would in the input na1>na2,
161 : * the method swaps these indices.
162 : */
163 : unsigned int baselineIndex( unsigned int na1, unsigned int na2) ;
164 :
165 : /** Antenna index of the first antenna of a pair defining a baseline number
166 : * @param baselineIndex A baseline number (zero-based)
167 : * @exception baselineIndex not zero-based
168 : * @return the index for the first antenna of the pair in the list of antennas effectively producing data
169 : * @exception Error if there is no such baselineIndex in the configuration.
170 : * @note See the note in the documentation of the baselineIndex() method to know
171 : * how baselines are ordered and how baselines correspond to pairs of
172 : * antenna indices.
173 : */
174 : unsigned int antenna1(unsigned int baselineIndex) ;
175 :
176 : /** Antenna index of the second antenna of a pair defining a baseline number
177 : * @param baselineIndex A baseline number (one-based)
178 : * @exception baselineIndex not one-based
179 : * @return the index for the second antenna of the pair
180 : * @exception Error if there is no such baselineIndex in the configuration.
181 : * @note See the note in the documentation of the baselineIndex() method to know
182 : * how baselines are ordered and how baselines correspond to pairs of
183 : * antenna indices.
184 : */
185 : unsigned int antenna2(unsigned int baselineIndex) ;
186 :
187 : /** Accessor to the feed index of a feed identifier given an antenna identifier
188 : * @param antennaId Antenna identifier of an antenna
189 : * @param feedId Feed identifier
190 : * @return The feed index (zero-based)
191 : * @exception Error
192 : * - No antenna with this antenna identifier. In this case, in lax mode, this method return -1.
193 : * - No feed with this feed identifier given the antenna identifier. In this case, in lax mode, this method return -2.
194 : */
195 : unsigned int feedIndex(asdm::Tag antennaId, int feedId) ;
196 :
197 : /** Antenna identifier from its index in the sequence of antenna restricted to those effectively producing data
198 : * @param na The antenna index in the list of \f$ N'_{ant}\f$ antennas effectively producing data
199 : * @exception na exceeds \f$ N'_{ant}-1\f$
200 : * @return The antenna identifier
201 : */
202 : asdm::Tag getEffAntennaId(unsigned int na) ;
203 :
204 : /** Number of antenna involved in the data if none would have been dropped
205 : * @return this number \f$ N_{ant} \f$ which is also the number of antenna scheduled for the observations
206 : */
207 : unsigned int getNumAntennas();
208 :
209 :
210 : /** Accessor to the feed identifier given a feed index and an antenna index
211 : * @param na The antenna index in the list of \f$ N'_{ant}\f$ antennas effectively producing data
212 : * @exception na exceeds \f$ N'_{ant}-1\f$
213 : * @param nfe The feed index
214 : * @exception nfe exceeds the upper limit considering the number of feeds used in the configuration.
215 : * @return a feed identifier
216 : * @note In general for telescopes with no focal plane arrays (FPA), this identifier should have always
217 : * the value 0. Although ALMA does not have FPAs, a feed identifier may also have the value 1. That
218 : * would happen in datasets with spectral windows located in the overlap region of two receiver bands,
219 : * e.g. the ALMA bands 2 and 3, some of the data obtained with band 2 and the other
220 : * data with band 3 for identical spectral windows.
221 : */
222 : int getFeedId(unsigned int na, unsigned int nfe) ;
223 :
224 : /** Number of antenna actualy involved in the data
225 : * @return the actual number \f$ N'_{ant} \f$ producing data
226 : * @note The constraint is that this number can not exceed the number of antenna scheduled
227 : * for the observations: \f$ N'_{ant} \le N_{ant} \f$. \n
228 : * This number \f$ N'_{ant}\f$ is equal to the number of items in the vector antennaUsedArray
229 : * which have the value "true", this vector being a parameter required by the constructors.
230 : *
231 : * See the BaselineFlagsMetadata class for details to define or find when a given antenna produce
232 : * or not data.
233 : */
234 : unsigned int getNumEffAntennas();
235 :
236 : /** Get the number of antenna pairs if all the antennas in v_AntennaIdArray_ were used
237 : * @return The number of baselines actually scheduled for the observations.
238 : * @note This is simply given by \f$ N_{bl}=N_{ant}(N_{ant}-1)/2 \f$
239 : */
240 : unsigned int getNumBaselines();
241 :
242 : /** Get the effective number of antenna pairs producing data
243 : * @return The number of antenna actually producing data
244 : * @note This is simply given by \f$ N'_{bl}=N'_{ant}(N'_{ant}-1)/2 \f$\n
245 : * where N'_{ant} is the value returned by the method getNumEffAntennas().
246 : */
247 : unsigned int getNumEffBaselines();
248 :
249 : /** Get the number of primitive data values (i.e. when a complex number counts for
250 : * two values) for a block of data.
251 : * @param e_dc the nature of the data content
252 : * @param es_an the sequence of axes associated to the structure for this block of data
253 : * @param effective a boolean to tell if one consider only the antennas which actualy
254 : * produce data or all those scheduled to do the observations.
255 : * @note Note that ALMA has dropped this concept of restricting to the antennas that
256 : * have effectively produced data. Hence in that context "effective" must be set
257 : * to false and the data involving the antennas with problem will be considered
258 : * as blanked on the basis of the FLAGS information.
259 : */
260 : unsigned int getNumPDTvalue(Enum<DataContentMod::DataContent> e_dc, EnumSet<AxisNameMod::AxisName> es_an, bool effective);
261 :
262 : private:
263 : std::vector<asdm::Tag> v_AntennaIdArray_; //!< Input array set of antenna identifiers (size numAntennas_)
264 : std::vector<int> v_FeedIdArray_; //!< Input array list of feed identifiers (size numFeed*numAntennas_)
265 : std::vector<int> v_PhasedArrayList_; //!< Input phasedArray list (not yet implemented)
266 : unsigned int numFeeds_; //!< Input number of feeds
267 : unsigned int numAntennas_; //!< Input number of antennas
268 : unsigned int numEffAntennas_; //!< Effective number of antennas with data
269 : unsigned int numBaselines_; //!< number of antenna pairs
270 : unsigned int numEffBaselines_; //!< Effective number of antenna pairs
271 : std::vector<asdm::Tag> v_effAntennaIdArray_;//!< Effective array of antenna identifiers
272 :
273 : };
274 :
275 :
276 6563556 : inline unsigned int BaselinesSet::transferId(unsigned int na1,unsigned int na2,unsigned int nfe, unsigned int ndd,unsigned int nbin,unsigned int napc){
277 :
278 6563556 : unsigned int baselineidx = baselineIndex(na1,na2); //cout << "baselineidx=" << baselineidx << endl;
279 :
280 6563556 : unsigned int v_cumulCrossSize_ndd=0; if(v_cumulCrossSize_.size()!=0)v_cumulCrossSize_ndd = v_cumulCrossSize_[ndd];
281 6563556 : unsigned int v_crossSize_ndd=0; if(v_crossSize_.size()!=0) v_crossSize_ndd = v_crossSize_[ndd];
282 :
283 : unsigned int n =
284 13127112 : baselineidx*numFeeds_*sumCrossSize_ + // /baseline
285 13127112 : nfe*sumCrossSize_ + // /baseline/feed
286 : v_cumulCrossSize_ndd + // /baseline/feed/datadesc
287 13127112 : nbin*(v_crossSize_ndd/numBin(ndd)) + // /baseline/feed/datadesc/bin
288 6563556 : napc*(v_crossSize_ndd/(numBin(ndd)*numApc_)); // /baseline/feed/datadesc/bin/napc
289 :
290 6563556 : return n;
291 : }
292 :
293 6563556 : inline unsigned int BaselinesSet::baselineIndex( unsigned int na1, unsigned int na2) {
294 6563556 : unsigned int iIdx = std::min (na1, na2);
295 6563556 : unsigned int jIdx = std::max (na1, na2);
296 6563556 : return jIdx * (jIdx - 1) / 2 + iIdx;
297 : }
298 : }
299 : #define _BASELINESSET_H
300 : #endif
|