diff --git a/LCS/ApplCommon/include/ApplCommon/AntField.h b/LCS/ApplCommon/include/ApplCommon/AntField.h index 4abf9ce2b35c186c67e3a544bc283d1bf81b76e6..53012ed12e4baf220caa2939a3350b66d83ab4af 100644 --- a/LCS/ApplCommon/include/ApplCommon/AntField.h +++ b/LCS/ApplCommon/include/ApplCommon/AntField.h @@ -56,7 +56,10 @@ namespace LOFAR { typedef pair<vector<size_t>, vector<double> > AFArray; // Read the AntennaField file. - explicit AntField (const string& filename); + // If <src>mustExist=true</src> an exception is thrown if the file does + // not exist. Otherwise an error message is logged and zero data is filled + // in for the various arrays. + explicit AntField (const string& filename, bool mustExist=true); ~AntField(); @@ -116,6 +119,17 @@ namespace LOFAR { // Get max nr of fields int maxFields() const; + // Read the arrays from the file. + void readFile (istream& inputStream, const string& fullFilename); + + // Initialize all arrays to zero. + void setZeroes(); + + // Initialize an array to the given shape and fill with zeroes. + void initArray (AntField::AFArray& array, size_t n1); + void initArray (AntField::AFArray& array, size_t n1, size_t n2); + void initArray (AntField::AFArray& array, size_t n1, size_t n2, size_t n3); + // Helper function to read an array in Blitz format. template<int NDIM> static void readBlitzArray(AntField::AFArray& array, istream& is) diff --git a/LCS/ApplCommon/src/AntField.cc b/LCS/ApplCommon/src/AntField.cc index b138cea9e031d6a0c192981c02999edcccb19b20..a34f80f2147e7eec191cf938ac15ea353e4dafb5 100644 --- a/LCS/ApplCommon/src/AntField.cc +++ b/LCS/ApplCommon/src/AntField.cc @@ -64,15 +64,17 @@ namespace LOFAR { // itsxxxRCUPos[rcu,xyz] because some programs are antenna based, // while others are rcu based. // - AntField::AntField(const string& filename) + AntField::AntField(const string& filename, bool mustExist) { // Locate the file (only done if no absolute path given). ConfigLocator cl; string fullFilename(cl.locate(filename)); ifstream inputStream (fullFilename.c_str()); - ASSERTSTR(inputStream.good(), "File :" << fullFilename - << " (extracted from: " << filename - << ") cannot be opened succesfully."); + if (mustExist) { + ASSERTSTR(inputStream.good(), "File :" << fullFilename + << " (extracted from: " << filename + << ") cannot be opened succesfully."); + } // Reserve space for expected info. itsAntPos.resize (MAX_FIELDS); @@ -81,6 +83,34 @@ namespace LOFAR { itsRotationMatrix.resize (MAX_FIELDS); itsRCULengths.resize (MAX_FIELDS); + // Fill in zeroes if the file does not exist. + if (inputStream.good()) { + readFile (inputStream, fullFilename); + inputStream.close(); + LOG_INFO_STR("Antenna position file " << fullFilename + << " read in succesfully"); + + } else { + LOG_ERROR_STR("Antenna position file " << fullFilename + << " not found; using zeroes instead"); + setZeroes(); + } + + // Finally construct the HBA0 and HBA1 info if their centre positions + // are given. + if (! getShape(itsFieldCentres[HBA0_IDX]).empty()) { + LOG_DEBUG("Constructing HBA0 and HBA1 from HBA information"); + makeSubField (HBA0_IDX); + makeSubField (HBA1_IDX); + } + + } + + AntField::~AntField() + {} + + void AntField::readFile (istream& inputStream, const string& fullFilename) + { string fieldName; string inputLine; int fieldIndex; @@ -160,8 +190,6 @@ namespace LOFAR { // Calculate length of RCU vectors. makeRCULen (fieldIndex); } // while not EOF - inputStream.close(); - ASSERTSTR(!getShape(itsAntPos[LBA_IDX]).empty() && !getShape(itsAntPos[HBA_IDX]).empty(), "File " << fullFilename << @@ -170,22 +198,51 @@ namespace LOFAR { getShape(itsFieldCentres[HBA1_IDX]).empty(), "File " << fullFilename << "should contain definitions for both HBA0 and HBA1 or none"); + } - // Finally construct the HBA0 and HBA1 info if their centre positions - // are given. - if (! getShape(itsFieldCentres[HBA0_IDX]).empty()) { - LOG_DEBUG("Constructing HBA0 and HBA1 from HBA information"); - makeSubField (HBA0_IDX); - makeSubField (HBA1_IDX); + void AntField::setZeroes() + { + for (int i=0; i<MAX_FIELDS; ++i) { + initArray (itsAntPos[i], 48, 2, 3); + initArray (itsFieldCentres[i], 3); + initArray (itsNormVectors[i], 3); + initArray (itsRotationMatrix[i], 3, 3); + initArray (itsRCULengths[i], 48*2); } + } - LOG_INFO_STR("Antenna positionfile " << fullFilename - << " read in succesfully"); - + void AntField::initArray (AntField::AFArray& array, size_t n1) + { + vector<size_t>& shape = AntField::getShape(array); + vector<double>& data = AntField::getData(array); + shape.resize (1); + shape[0] = n1; + data.resize (n1); + std::fill (data.begin(), data.end(), 0.); } - AntField::~AntField() + void AntField::initArray (AntField::AFArray& array, size_t n1, size_t n2) + { + vector<size_t>& shape = AntField::getShape(array); + vector<double>& data = AntField::getData(array); + shape.resize (2); + shape[0] = n1; + shape[1] = n2; + data.resize (n1*n2); + std::fill (data.begin(), data.end(), 0.); + } + + void AntField::initArray (AntField::AFArray& array, + size_t n1, size_t n2, size_t n3) { + vector<size_t>& shape = AntField::getShape(array); + vector<double>& data = AntField::getData(array); + shape.resize (3); + shape[0] = n1; + shape[1] = n2; + shape[2] = n3; + data.resize (n1*n2*n3); + std::fill (data.begin(), data.end(), 0.); } int AntField::name2Index(const string& fieldName) const diff --git a/LCS/ApplCommon/test/tAntField.cc b/LCS/ApplCommon/test/tAntField.cc index b3dbda094919b0a0c06c2d164747fd67741d76ac..9bd9bb1347f17b5d3900e2308ac573c521e0f946 100644 --- a/LCS/ApplCommon/test/tAntField.cc +++ b/LCS/ApplCommon/test/tAntField.cc @@ -40,12 +40,10 @@ namespace LOFAR { using namespace LOFAR; - -int main() +void show (const AntField& theAP) { - AntField theAP("tAntField.in"); - // Show the names of the sets. + cout << endl; cout << "The tAntField.in file containes the following definitions:" << endl; cout << "LBA count : " << theAP.nrAnts("LBA") << endl; cout << "LBA centre : " << theAP.Centre("LBA") << endl; @@ -74,6 +72,24 @@ int main() cout << "HBA1 rot.Matrix : " << theAP.rotationMatrix("HBA1") << endl; cout << "HBA1 Ant positions: " << theAP.AntPos("HBA1") << endl; cout << "HBA1 RCU lengths : " << theAP.RCULengths("HBA1") << endl; +} + +int main() +{ + // Read an existing file. + AntField theAP1("tAntField.in", true); + show (theAP1); + AntField theAP2("tAntField.in", false); + // Accept a non-existing file. + AntField theAP3("tAntFielx.in", false); + show (theAP3); + bool failed = false; + try { + AntField theAP4("tAntFielx.in", true); + } catch (LOFAR::Exception&) { + failed = true; + } + ASSERT (failed); return (0); } diff --git a/LCS/ApplCommon/test/tAntField.stdout b/LCS/ApplCommon/test/tAntField.stdout index b0b1171995e47d00c1a362c6ee08a1f29fccf58c..34c0ba145506b5bde60098015f69a2ce44b71b08 100644 --- a/LCS/ApplCommon/test/tAntField.stdout +++ b/LCS/ApplCommon/test/tAntField.stdout @@ -1,3 +1,4 @@ + The tAntField.in file containes the following definitions: LBA count : 96 LBA centre : [3] [3.82658e+06,461023,5.06489e+06] @@ -23,3 +24,29 @@ HBA1 normVector : [3] [0.598753,0.072099,0.797682] HBA1 rot.Matrix : [3,3] [-0.119595,-0.791954,0.598753,0.992823,-0.095419,0.072099,3.3e-05,0.603078,0.797682] HBA1 Ant positions: [24,2,3] [-9.888,-3.785,7.765,-9.888,-3.785,7.765,-10.504,1.328,7.765,-10.504,1.328,7.765,-5.194,-8.407,4.659,-5.194,-8.407,4.659,-5.81,-3.294,4.659,-5.81,-3.294,4.659,-6.426,1.819,4.659,-6.426,1.819,4.659,-7.042,6.932,4.659,-7.042,6.932,4.659,-0.499,-13.028,1.553,-0.499,-13.028,1.553,-1.115,-7.915,1.553,-1.115,-7.915,1.553,-1.731,-2.802,1.553,-1.731,-2.802,1.553,-2.347,2.311,1.553,-2.347,2.311,1.553,-2.963,7.424,1.553,-2.963,7.424,1.553,-3.579,12.537,1.553,-3.579,12.537,1.553,3.579,-12.537,-1.553,3.579,-12.537,-1.553,2.963,-7.424,-1.553,2.963,-7.424,-1.553,2.347,-2.311,-1.553,2.347,-2.311,-1.553,1.731,2.802,-1.553,1.731,2.802,-1.553,1.115,7.915,-1.553,1.115,7.915,-1.553,0.499,13.028,-1.553,0.499,13.028,-1.553,7.042,-6.932,-4.659,7.042,-6.932,-4.659,6.426,-1.819,-4.659,6.426,-1.819,-4.659,5.81,3.294,-4.659,5.81,3.294,-4.659,5.194,8.407,-4.659,5.194,8.407,-4.659,10.504,-1.328,-7.765,10.504,-1.328,-7.765,9.888,3.785,-7.765,9.888,3.785,-7.765] HBA1 RCU lengths : [48] [13.1299,13.1299,13.1298,13.1298,10.9253,10.9253,8.14327,8.14327,8.143,8.143,10.9247,10.9247,13.1297,13.1297,8.14262,8.14262,3.64134,3.64134,3.64156,3.64156,8.14291,8.14291,13.13,13.13,13.13,13.13,8.14291,8.14291,3.64156,3.64156,3.64134,3.64134,8.14262,8.14262,13.1297,13.1297,10.9247,10.9247,8.143,8.143,8.14327,8.14327,10.9253,10.9253,13.1298,13.1298,13.1299,13.1299] + +The tAntField.in file containes the following definitions: +LBA count : 48 +LBA centre : [3] [0,0,0] +LBA normVector : [3] [0,0,0] +LBA rot.Matrix : [3,3] [0,0,0,0,0,0,0,0,0] +LBA Ant positions: [48,2,3] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +LBA RCU lengths : [96] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +HBA count : 48 +HBA centre : [3] [0,0,0] +HBA normVector : [3] [0,0,0] +HBA rot.Matrix : [3,3] [0,0,0,0,0,0,0,0,0] +HBA Ant positions: [48,2,3] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +HBA RCU lengths : [96] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +HBA0 count : 24 +HBA0 centre : [3] [0,0,0] +HBA0 normVector : [3] [0,0,0] +HBA0 rot.Matrix : [3,3] [0,0,0,0,0,0,0,0,0] +HBA0 Ant positions: [24,2,3] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +HBA0 RCU lengths : [48] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +HBA1 count : 24 +HBA1 centre : [3] [0,0,0] +HBA1 normVector : [3] [0,0,0] +HBA1 rot.Matrix : [3,3] [0,0,0,0,0,0,0,0,0] +HBA1 Ant positions: [24,2,3] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] +HBA1 RCU lengths : [48] [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] diff --git a/LCS/MSLofar/include/MSLofar/BeamTables.h b/LCS/MSLofar/include/MSLofar/BeamTables.h index 2dccb2bc4dc30f0645c4f3c130272c966f8bf4c3..d59ea97ca2c6cbf1390303af083dfd06b9090310 100644 --- a/LCS/MSLofar/include/MSLofar/BeamTables.h +++ b/LCS/MSLofar/include/MSLofar/BeamTables.h @@ -59,11 +59,14 @@ namespace LOFAR { bool overwrite = false); // Fill the subtables. They should be empty. + // <src>mustExist</src> tells if the AntennaField and iHBADelta file on + // an antenna must exist. static void fill (casa::Table& ms, const string& antennaSet, const string& antennaSetFileName, const string& antennaFieldDir, - const string& iHBADeltaDir); + const string& iHBADeltaDir, + bool mustExist=false); // Write an AntennaField entry in the given row. static void writeAntField (MSAntennaFieldColumns& columns, int rownr, @@ -105,7 +108,8 @@ namespace LOFAR { static casa::Array<double> array2Casa (const AntField::AFArray& barray); // Read the HBA dipole offsets. - static void getHBADeltas (const string& filename, AntField::AFArray&); + static void getHBADeltas (const string& filename, AntField::AFArray&, + bool mustExist); }; } //# end namespace diff --git a/LCS/MSLofar/src/BeamTables.cc b/LCS/MSLofar/src/BeamTables.cc index a11c84ffefc45d894f4444141442bb284ebd757b..d03a1d1c6a6f912c689637885b262429a90c407a 100644 --- a/LCS/MSLofar/src/BeamTables.cc +++ b/LCS/MSLofar/src/BeamTables.cc @@ -72,7 +72,8 @@ void BeamTables::fill (Table& ms, const string& antennaSetName, const string& antennaSetFileName, const string& antennaFieldDir, - const string& iHBADeltaDir) + const string& iHBADeltaDir, + bool mustExist) { // Open the AntennaSets file. AntennaSets antennaSet(antennaSetFileName); @@ -123,7 +124,8 @@ void BeamTables::fill (Table& ms, int stationId = stationIdMap.size(); stationIdMap[stationName] = stationId; } - AntField antField(antFieldPath + stationName + "-AntennaField.conf"); + AntField antField(antFieldPath + stationName + "-AntennaField.conf", + mustExist); // Get the station type from the station name (using StationInfo.h). // Use it to get the bitset telling which elements are present for // the given antennaSet. @@ -135,7 +137,7 @@ void BeamTables::fill (Table& ms, if (antFieldType == "HBA") { // Get the offsets of HBA dipoles w.r.t. tile center. getHBADeltas (hbaDeltaPath + stationName + "-iHBADeltas.conf", - hbaOffsets); + hbaOffsets, mustExist); } if (antFieldName == "HBA") { // HBA can be split into HBA0 and HBA1. @@ -336,19 +338,33 @@ void BeamTables::writeAntenna (Table& antTable, } void BeamTables::getHBADeltas (const string& fileName, - AntField::AFArray& deltas) + AntField::AFArray& deltas, + bool mustExist) { ifstream file(fileName.c_str()); - ASSERTSTR(file.good(), "Can not open file " << fileName); - // The file may have comment lines at the top, starting with '#' - // These must be skipped - string line; - getline (file, line); - while (line[0] == '#') { + if (mustExist) { + ASSERTSTR(file.good(), "Cannot open file " << fileName); + } + if (file.good()) { + // The file may have comment lines at the top, starting with '#' + // These must be skipped + string line; getline (file, line); + while (line[0] == '#') { + getline (file, line); + } + // The array is stored after the name line which has just been read. + AntField::readBlitzArray<2> (deltas, file); + } else { + // File not found is acceptable; fill with zeroes. + vector<size_t>& shape = AntField::getShape(deltas); + vector<double>& data = AntField::getData(deltas); + shape.resize (2); + shape[0] = 16; + shape[1] = 3; + data.resize (16*3); + std::fill (data.begin(), data.end(), 0.); } - // The array is stored after the name line which has just been read. - AntField::readBlitzArray<2> (deltas, file); ASSERTSTR (AntField::getShape(deltas)[1] == 3 && (AntField::getShape(deltas)[0] == 16 || AntField::getShape(deltas)[0] == 32), diff --git a/LCS/MSLofar/src/makebeamtables.cc b/LCS/MSLofar/src/makebeamtables.cc index 5d10701df40736ebbe23e65772eed89833a073f9..8d03ae2232add1c8830c3569943834960307c759 100644 --- a/LCS/MSLofar/src/makebeamtables.cc +++ b/LCS/MSLofar/src/makebeamtables.cc @@ -63,7 +63,7 @@ int main (int argc, char* argv[]) Bool overwrite = inputs.getBool ("overwrite"); MeasurementSet ms(msName, Table::Update); BeamTables::create (ms, overwrite); - BeamTables::fill (ms, antSet, antSetFile, antFieldDir, hbaDeltaDir); + BeamTables::fill (ms, antSet, antSetFile, antFieldDir, hbaDeltaDir, true); } catch (std::exception& x) { cout << "Unexpected exception: " << x.what() << endl; return 1;