MS2ASDM::MS2ASDM(MeasurementSet& ms) :
baseUid_p("uid://X0/X0/X"),
currentUid_p("uid://X0/X0/X0"),
asdmSpectralWindowId_p(Tag()),
asdmPolarizationId_p(Tag()),
asdmProcessorId_p(Tag()),
asdmEphemerisId_p(Tag()),
asdmDataDescriptionId_p(Tag()),
asdmConfigDescriptionId_p(Tag()),
asdmSBSummaryId_p(Tag()),
asdmExecBlockId_p(Tag()),
asdmPointingModelId_p(-1)
asdmVersion_p = String((ASDM_p->getEntity()).getEntityVersion());
setSBDuration(); // set to default values
for(uInt j=0;j<ant.size();j++){
if(antenna1()(i) == ant[j]){
ant.push_back(antenna1()(i));
stateIdV.push_back( asdmStateId_p(stateId()(i)) );
stateIdV.push_back( asdmStateId_p.at(stateId()(i)) );
for(uInt j=0;j<ant.size();j++){
if(antenna2()(i) == ant[j]){
ant.push_back(antenna2()(i));
stateIdV.push_back( asdmStateId_p(stateId()(i)) );
stateIdV.push_back( asdmStateId_p.at(stateId()(i)) );
numAntennas = ant.size();
CorrelationModeMod::CorrelationMode correlationMode;
correlationMode = CorrelationModeMod::CROSS_ONLY;
vector< SDMDataObject::Baseband > basebands; // ???
// construct spectral window and basedband vectors
vector<SDMDataObject::SpectralWindow> spectralWindows;
// for creating a Spectral Window
uInt PolId = dataDescription().polarizationId()(theDDId);
uInt numStokesMS = polarization().numCorr()(PolId);
asdm::PolarizationRow* PR = (ASDM_p->getPolarization()).getRowByKey(asdmPolarizationId_p(PolId));
asdm::PolarizationRow* PR = (ASDM_p->getPolarization()).getRowByKey(asdmPolarizationId_p.at(PolId));
uInt numStokes = PR->getNumCorr();
Array<Int> corrT = polarization().corrType()(PolId);
vector<StokesParameterMod::StokesParameter> crossPolProducts = PR->getCorrType();
vector<StokesParameterMod::StokesParameter> sdPolProduct;
uInt spwId = dataDescription().spectralWindowId()(theDDId);
unsigned int numSpectralPoint = spectralWindow().numChan()(spwId);
OptionalSpectralResolutionType spectralResolution = SpectralResolutionTypeMod::FULL_RESOLUTION;
String sId = antenna().station()(irow);
tR = tT.newRow(name, position, type);
asdm::StationRow* tR2 = 0;
if(tR2 == tR){ // adding this row caused a new tag to be defined
// enter tag into the map
asdmStationId_p.define(String(name), tR->getStationId());
asdmStationId_p.insert(std::pair<casacore::String, asdm::Tag>(String(name), tR->getStationId()));
os << LogIO::SEVERE << "Duplicate station in MS Antenna table: " << irow << LogIO::POST;
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
Vector<Double > v; // aux. vector
v.reference(antenna().offset()(irow));
for(uInt i=0; i<v.size(); i++){
offset.push_back(Length(v[i]));
ArrayTime atime = ASDMArrayTime(time()(0)); // use start time of MS
String sId = antenna().station()(irow); // the station name
if(asdmStationId_p.isDefined(sId)){
stationId = asdmStationId_p(sId);
if(asdmStationId_p.find(sId) != asdmStationId_p.end( )){
stationId = asdmStationId_p[sId];
os << LogIO::SEVERE << "Internal error: No station ID defined for station name " << sId << LogIO::POST;
tR = tT.newRow(name, antennaMake, antennaType, dishDiameter, position, offset, atime, stationId);
asdm::AntennaRow* tR2 = 0;
if(tR2 == tR){ // adding this row caused a new tag to be defined
// enter tag into the map
asdmAntennaId_p.define(irow, tR->getAntennaId());
asdmAntennaId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR->getAntennaId()));
os << LogIO::WARN << "Duplicate row in MS Antenna table :" << irow << LogIO::POST;
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
if(!spectralWindow().dopplerId().isNull()){ // DOPPLER_ID is an optional MS column
tR->setDopplerId( spectralWindow().dopplerId()(irow) );
// add the row to the table
asdm::SpectralWindowRow* tR2 = 0;
if(tR2 == tR){ // adding this row caused a new tag to be defined
// enter tag into the map
asdmSpectralWindowId_p.define(irow, tR->getSpectralWindowId());
asdmSpectralWindowId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR->getSpectralWindowId()));
os << LogIO::WARN << "Duplicate row in MS Spectral Window table :" << irow << LogIO::POST;
} // end loop over MS SPW table
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
Int sId = source().sourceId()(irow);
// parameters of the new row
ArrayTimeInterval timeInterval( ASDMTimeInterval(source().timeQuant()(irow), source().intervalQuant()(irow)) );
//cout << "in writeSource: timeInterval " << source().time()(irow) << ", " << source().interval()(irow) << endl;
//cout << " timeInterval " << timeInterval.getStartInNanoSeconds() << ", " << timeInterval.getDurationInNanoSeconds() << endl;
Int spwId = source().spectralWindowId()(irow);
if(!asdmSpectralWindowId_p.isDefined(spwId)){
if( asdmSpectralWindowId_p.find(spwId) == asdmSpectralWindowId_p.end( ) ){
os << LogIO::SEVERE << "Undefined SPW id " << spwId << " in MS Source table row "<< irow << LogIO::POST;
spectralWindowId = asdmSpectralWindowId_p(spwId);
spectralWindowId = asdmSpectralWindowId_p[spwId];
string code = source().code()(irow).c_str();
if(code=="" || code==" "){
vector< Angle > direction;
MDirection theSourceDir = source().directionMeas()(irow);
direction.push_back( Angle( theSourceDir.getAngle( unitASDMAngle() ).getValue()(0) ) ); // RA
direction.push_back( Angle( theSourceDir.getAngle( unitASDMAngle() ).getValue()(1) ) ); // DEC
catch(asdm::UniquenessViolationException x){
os << LogIO::WARN << "While creating ASDM: UID \"" << getCurrentUid()
<< "\" Source table: " << x.getMessage() << endl
<< "Will try to continue."
if(tR2 != tR){ // did not lead to the creation of a new tag
os << LogIO::WARN << "Duplicate MS Source table row " << irow << ", source id " << sId << LogIO::POST;
if(!asdmSourceId_p.isDefined(sId)){
if( asdmSourceId_p.find(sId) == asdmSourceId_p.end( ) ){
int souId = tR2->getSourceId();
asdmSourceId_p.define(sId, souId);
asdmSourceId_p.insert(std::pair<casacore::Int, int>(sId, souId));
} // end loop over source table
} // id if source table exists
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
os << LogIO::NORMAL << "Filled Source table " << getCurrentUid() << " with " << tT.size() << " rows ..." << LogIO::POST;
////bool flagRow = polarization().flagRow()(irow);
////tR->setFlagRow(flagRow);
// add the row to the table
asdm::PolarizationRow* tR2 = 0;
if(tR2 == tR){ // adding this row caused a new tag to be defined
// enter tag into the map
asdmPolarizationId_p.define(irow, tR->getPolarizationId());
asdmPolarizationId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR->getPolarizationId()));
os << LogIO::WARN << "Duplicate row in MS Polarization table :" << irow << LogIO::POST;
} // end loop over MS Pol table
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
tR = tT.newRow(modeId, processorType, processorSubType);
// add the row to the table
asdm::ProcessorRow* tR2 = 0;
if(tR2 == tR){ // adding this row caused a new tag to be defined
// enter tag into the map
asdmProcessorId_p.define(irow, tR->getProcessorId());
asdmProcessorId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR->getProcessorId()));
os << LogIO::WARN << "Duplicate row in MS Processor table :" << irow << LogIO::POST;
} // end loop over MS processor table
else{ // MS processor table is empty
os << LogIO::WARN << "MS Processor table is empty. Will try to proceed assuming a standard ALMA Correlator." << LogIO::POST;
ProcessorTypeMod::ProcessorType processorType = ProcessorTypeMod::CORRELATOR;
ProcessorSubTypeMod::ProcessorSubType processorSubType = ProcessorSubTypeMod::ALMA_CORRELATOR_MODE;
vector< asdm::CorrelatorModeRow* > corrModeRows = ASDM_p->getCorrelatorMode().get();
if(corrModeRows.size()==0){
os << LogIO::SEVERE << "Internal error: ASDM CorrelatorMode table is empty." << LogIO::POST;
Tag modeId = corrModeRows[0]->getCorrelatorModeId(); // get tag from first row of CorrelatorMode table (there is only one) ???
tR = tT.newRow(modeId, processorType, processorSubType);
// enter tag into the map connecting it to "-1"
asdmProcessorId_p.define(-1, tR->getProcessorId());
asdmProcessorId_p.insert(std::pair<casacore::Int, asdm::Tag>(-1, tR->getProcessorId()));
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
os << LogIO::NORMAL << "Filled Processor table " << getCurrentUid() << " with " << tT.size() << " rows ..." << LogIO::POST;
////tR = tT.newRow(fieldName, code, numPoly, delayDirV, phaseDirV, referenceDirV);
tR = tT.newRow(fieldName, numPoly, delayDirV, phaseDirV, referenceDirV);
tR->setDirectionCode(directionCode);
tR->setTime(ASDMArrayTime(field().timeQuant()(irow).getValue("s")));
Int sId = field().sourceId()(irow);
if(asdmSourceId_p.isDefined(sId)){
tR->setSourceId(asdmSourceId_p(sId));
if ( asdmSourceId_p.find(sId) != asdmSourceId_p.end( ) ) {
tR->setSourceId(asdmSourceId_p[sId]);
else if(sId!=-1){ // -1 means "no source"
os << LogIO::WARN << "Undefined source id " << sId << " in MS field table row " << irow << LogIO::POST;
if(!field().ephemerisId().isNull()){
Int eid = field().ephemerisId()(irow);
if(asdmEphemerisId_p.isDefined(eid)){
tR->setEphemerisId(asdmEphemerisId_p(eid));
os << LogIO::WARN << "Undefined ephemeris id " << eid << " in MS field table row " << irow << LogIO::POST;
// add the row to the table
if(tR2 == tR){ // adding this row caused a new tag to be defined
// enter tag into the map
asdmFieldId_p.define(irow, tR->getFieldId());
asdmFieldId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR->getFieldId()));
if(sId == tR2->getSourceId()){ // if also the Source ID agrees, we really have a duplication
os << LogIO::SEVERE << "Duplicate row in MS Field table :" << irow << LogIO::POST;
fieldName = fieldName+"_B";
tR->setFieldName(fieldName);
if(tR2 == tR){ // adding this row caused a new tag to be defined
os << LogIO::WARN << "Duplicate row in MS Field table :" << irow << endl
<< " appended \"_B\" to field name for second occurrence. New field name: " << fieldName << LogIO::POST;
asdmFieldId_p.define(irow, tR->getFieldId());
asdmFieldId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR->getFieldId()));
os << LogIO::SEVERE << "Duplicate row in MS Field table :" << irow << LogIO::POST;
} // end loop over MS field table
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
for(uInt irow=0; irow<feed().nrow(); irow++){
// parameters of the new feed row
Int aid = feed().antennaId()(irow);
if(asdmAntennaId_p.isDefined(aid)){
antennaId = asdmAntennaId_p(aid);
if( asdmAntennaId_p.find(aid) != asdmAntennaId_p.end( ) ){
antennaId = asdmAntennaId_p[aid];
os << LogIO::SEVERE << "Undefined antenna id " << aid << " in MS feed table row "<< irow << LogIO::POST;
ArrayTimeInterval timeInterval( ASDMTimeInterval(feed().timeQuant()(irow), feed().intervalQuant()(irow)) );
int numReceptor = feed().numReceptors()(irow);
vector< vector< double > > beamOffsetV;
} // end loop over receptors
// look at SPW Id parameter last!
vector< Tag > spwIdV; // the spw ids fow which to insert rows for this feed
Int spwid = feed().spectralWindowId()(irow);
if(spwid == -1){ // this means the MS Feed row is valid for all SPWs => need to insert same row for each SPW!
for(Int ispw=0; ispw<(Int)spectralWindow().nrow(); ispw++){
if(asdmSpectralWindowId_p.isDefined(ispw)){
spectralWindowId = asdmSpectralWindowId_p(ispw);
if( asdmSpectralWindowId_p.find(ispw) != asdmSpectralWindowId_p.end( ) ){
spectralWindowId = asdmSpectralWindowId_p[ispw];
spwIdV.push_back(spectralWindowId);
else if(asdmSpectralWindowId_p.isDefined(spwid)){
spectralWindowId = asdmSpectralWindowId_p(spwid);
spwIdV.push_back(spectralWindowId); // just one entry
else if( asdmSpectralWindowId_p.find(spwid) != asdmSpectralWindowId_p.end( ) ){
spectralWindowId = asdmSpectralWindowId_p[spwid];
spwIdV.push_back(spectralWindowId); // just one entry
os << LogIO::SEVERE << "Undefined SPW id " << spwid << " in MS feed table row "<< irow << LogIO::POST;
// create the row for the first of the SPW Ids
tR = tT.newRow(antennaId, spwIdV[0], timeInterval, numReceptor, beamOffsetV, focusReferenceV,
polarizationTypesV, polResponseV, receptorAngleV, receiverIdV);
if(feed().beamId()(irow)!=-1 && !warned3){ // there should be a beam table in the MS, but presently it is not implemented!!!
os << LogIO::WARN << "MS Feed table contains reference to a Beam table row " << feed().beamId()(irow)
<< " but a Beam table is not implemented in CASA. Ignoring." << LogIO::POST;
// add the row to the table
int asdmFId = tR->getFeedId(); // the determination of the feed id is done internally by the add() method
Int fId = feed().feedId()(irow);
if(asdmFeedId_p.isDefined(fId)){ // there is already a mapping
if(asdmFId!=asdmFeedId_p(fId)){ // but it doesn't agree with the newly defined id
if( asdmFeedId_p.find(fId) != asdmFeedId_p.end( ) ){ // there is already a mapping
if(asdmFId!=asdmFeedId_p[fId]){ // but it doesn't agree with the newly defined id
os << LogIO::WARN << "Internal problem: field id map inconsistent for MS feed table row:" << irow
<< ". MS FId " << fId << " is already mapped to ASDM FId" << asdmFeedId_p(fId)
<< ". MS FId " << fId << " is already mapped to ASDM FId" << asdmFeedId_p[fId]
<< " but should also be mapped to ASDM FId " << asdmFId << LogIO::POST;
asdmFeedId_p.define(fId, asdmFId);
asdmFeedId_p.insert(std::pair<int,int>(fId, asdmFId));
// add the same row for the remaining SPW Ids in the vector accumulated above
for(uint i=1; i<spwIdV.size(); i++){
tR = tT.newRow(antennaId, spwIdV[i], timeInterval, numReceptor, beamOffsetV, focusReferenceV,
polarizationTypesV, polResponseV, receptorAngleV, receiverIdV);
} // end loop over MS feed table
asdm::DataDescriptionRow* tR = 0;
// loop over MS data description table
for(uInt irow=0; irow<dataDescription().nrow(); irow++){
// parameters for the new row
Int polId = dataDescription().polarizationId()(irow);
Int spwId = dataDescription().spectralWindowId()(irow);
if(asdmPolarizationId_p.isDefined(polId)){
polOrHoloId = asdmPolarizationId_p(polId);
if( asdmPolarizationId_p.find(polId) != asdmPolarizationId_p.end( ) ){
polOrHoloId = asdmPolarizationId_p[polId];
os << LogIO::SEVERE << "Inconsistent MS: undefined polarization id " << polId
<< " in row " << irow << " of the DataDesc table." << LogIO::POST;
if(asdmSpectralWindowId_p.isDefined(spwId)){
spectralWindowId = asdmSpectralWindowId_p(spwId);
if( asdmSpectralWindowId_p.find(spwId) != asdmSpectralWindowId_p.end( ) ){
spectralWindowId = asdmSpectralWindowId_p[spwId];
os << LogIO::SEVERE << "Inconsistent MS: undefined SPW id " << spwId
<< " in row " << irow << " of the DataDesc table." << LogIO::POST;
tR = tT.newRow(polOrHoloId, spectralWindowId);
asdm::DataDescriptionRow* tR2 = 0;
if(tR2 == tR){ // adding this row caused a new tag to be defined
// enter tag into the map
asdmDataDescriptionId_p.define(irow, tR->getDataDescriptionId());
asdmDataDescriptionId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR->getDataDescriptionId()));
os << LogIO::WARN << "Duplicate row in MS DataDesc table :" << irow << LogIO::POST;
} // end loop over MS DD table
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
CalibrationDeviceMod::CalibrationDevice calDeviceName = CalibrationDeviceMod::NONE;
tR = tT.newRow(calDeviceName, bSig, bRef, bOnSky);
tR->setWeight(1.); // optional column
// add the new row to the table
// enter tag into the map
asdmStateId_p.define(-1, tR->getStateId());
asdmStateId_p.insert(std::pair<casacore::Int, asdm::Tag>(-1, tR->getStateId()));
else{ // MS State table exists
for(uInt irow=0; irow<state().nrow(); irow++){
// parameters of the new row
bool bSig = state().sig()(irow);
bool bRef = state().ref()(irow);
Double loadT = state().load()(irow);
Double noiseT = state().cal()(irow);
bool bOnSky = bSig || bRef;
CalibrationDeviceMod::CalibrationDevice calDeviceName;
tR = tT.newRow(calDeviceName, bSig, bRef, bOnSky);
tR->setWeight(1.); // optional column
// add the new row to the table
// enter tag into the map
asdmStateId_p.define(irow, tR2->getStateId());
asdmStateId_p.insert(std::pair<casacore::Int, asdm::Tag>(irow, tR2->getStateId()));
if(tR2 != tR){ // adding this row did not cause a new tag to be defined
os << LogIO::WARN << "Duplicate row in MS State table :" << irow << LogIO::POST;
} // end loop over MS state table
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
Int f2Id = feed2()(mainTabRow);
Int DDId = dataDescId()(mainTabRow);
Double startTime = timestampStartSecs(mainTabRow);
// create vectors of info for each antenna
SimpleOrderedMap <Int, Int> antennaDone(-1);
std::map<Int, Int> antennaDone;
// while ddid and feed id remain the same
while(irow<nMainTabRows &&
dataDescId()(irow) == DDId &&
Int aId = antenna1()(irow);
// if info for given antenna not yet filled
if(!antennaDone.isDefined(aId)){
if( antennaDone.find(aId) == antennaDone.end( ) ){
// get info for antenna and fill vectors
Int spwId = dataDescription().spectralWindowId()(DDId);
nRecV.push_back(feed().numReceptors()(f1Id));
nChanV.push_back(spectralWindow().numChan()(spwId));
antennaDone.define(aId, f1Id);
antennaDone.insert(std::pair<Int, Int>(aId, f1Id));
// if info for given antenna not yet filled
if(!antennaDone.isDefined(aId)){
if( antennaDone.find(aId) == antennaDone.end( ) ){
// get info for antenna and fill vectors
Int spwId = dataDescription().spectralWindowId()(DDId);
nRecV.push_back(feed().numReceptors()(f2Id));
nChanV.push_back(spectralWindow().numChan()(spwId));
antennaDone.define(aId, f2Id);
antennaDone.insert(std::pair<Int, Int>(aId, f2Id));
Double endTime = timestampEndSecs(irow-1);
// create ArrayTimeInterval
asdm::ArrayTimeInterval timeInterval( ASDMArrayTime(startTime),
ASDMInterval(endTime-startTime) );
// create new rows in syscal table based on the vectors
for(uInt i=0; i<aIdV.size(); i++){
// parameters of the new SysCal row
Tag antennaId = asdmAntennaId_p(aIdV[i]);
Tag spectralWindowId = asdmSpectralWindowId_p(SPWIdV[i]);
int feedId = asdmFeedId_p(feedIdV[i]);
Tag antennaId = asdmAntennaId_p.at(aIdV[i]);
Tag spectralWindowId = asdmSpectralWindowId_p.at(SPWIdV[i]);
int feedId = asdmFeedId_p.at(feedIdV[i]);
int numReceptor = nRecV[i];
tR = tT.newRow(antennaId, spectralWindowId, timeInterval, feedId, numReceptor, numChan);
// add the new row to the table
} // end loop over main table
else{ // MS SysCal table exists
for(uInt irow=0; irow<nSysCalRows; irow++){
// parameters of the new row
Tag antennaId = asdmAntennaId_p( sysCal().antennaId()(irow) );
Tag antennaId = asdmAntennaId_p.at( sysCal().antennaId()(irow) );
Int spwId = sysCal().spectralWindowId()(irow);
Tag spectralWindowId = asdmSpectralWindowId_p( spwId );
Tag spectralWindowId = asdmSpectralWindowId_p.at( spwId );
int feedId = sysCal().feedId()(irow);
ArrayTimeInterval timeInterval( ASDMTimeInterval(sysCal().timeQuant()(irow), sysCal().intervalQuant()(irow)) );
uInt numReceptor = feed().numReceptors()(feedId);
uInt nChan = spectralWindow().numChan()(spwId);
tR = tT.newRow(antennaId, spectralWindowId, timeInterval, feedId, (int)numReceptor, (int)nChan);
// now set the optional columns if they exist in the MS
os << LogIO::NORMAL << "Processor Id: " << procId << LogIO::POST;
asdm::ConfigDescriptionRow* tR = 0;
if(asdmProcessorId_p.isDefined(procId)){
procIdTag = asdmProcessorId_p(procId);
if(asdmProcessorId_p.find(procId) != asdmProcessorId_p.end()){
procIdTag = asdmProcessorId_p[procId];
if(procId == dummyProcId && asdmProcessorId_p.isDefined(-1)){ // there is no MS Proc table and the main table is
procIdTag = asdmProcessorId_p(-1); // using wrong proc ids
if(procId == dummyProcId && asdmProcessorId_p.find(-1) != asdmProcessorId_p.end( )){ // there is no MS Proc table and the main table is
procIdTag = asdmProcessorId_p[-1]; // using wrong proc ids
os << LogIO::SEVERE << "Internal error: undefined mapping for processor id " << procId << LogIO::POST;
// get processor type from already existing ASDM processor table
ProcessorTypeMod::ProcessorType processorType = procT.getRowByKey(procIdTag)->getProcessorType();
// temprorary solution until other processro types are supported
if(processorType!=ProcessorTypeMod::CORRELATOR){
badSpwV.push_back(dataDescription().spectralWindowId()(iDDId));
goodSpwV.push_back(dataDescription().spectralWindowId()(iDDId));
if(!asdmDataDescriptionId_p.isDefined(iDDId)){
if(asdmDataDescriptionId_p.find(iDDId) != asdmDataDescriptionId_p.end( )){
os << LogIO::SEVERE << "Internal error: undefined mapping for data desc. id " << iDDId
<< " in main table row " << jrow << LogIO::POST;
uInt spwId = dataDescription().spectralWindowId()(iDDId);
if(spectralWindow().numChan()(spwId)<5){
// spectralType = SpectralResolutionTypeMod::CHANNEL_AVERAGE;
// os << LogIO::NORMAL << " Less than 5 channels. Assuming data is of spectral resolution type \"CHANNEL_AVERAGE\"."
Int aId = antenna1()(irow);
for(uInt j=0; j<msAntennaIdV.size(); j++){
if(aId == msAntennaIdV[j]){
msAntennaIdV.push_back(aId);
if(!asdmAntennaId_p.isDefined(aId)){
if(asdmAntennaId_p.find(aId) == asdmAntennaId_p.end( )){
os << LogIO::SEVERE << "Internal error: undefined mapping for antenna1 id " << aId
<< " in main table row " << irow << LogIO::POST;
for(uInt j=0; j<msAntennaIdV.size(); j++){
if(aId == msAntennaIdV[j]){
msAntennaIdV.push_back(aId);
if(!asdmAntennaId_p.isDefined(aId)){
if(asdmAntennaId_p.find(aId) == asdmAntennaId_p.end( )){
os << LogIO::SEVERE << "Internal error: undefined mapping for antenna2 id " << aId
<< " in main table row " << irow << LogIO::POST;
Int fIdi = feed1()(irow);
Int fKeyi = fIdi + 10000*antenna1()(irow);
for(uInt j=0;j<msFeedKeyV.size();j++){
if(fKeyi == msFeedKeyV[j]){
msFeedKeyV.push_back(fKeyi);
msFeedIdV.push_back(fIdi);
if(!asdmFeedId_p.isDefined(fIdi)){
if(asdmFeedId_p.find(fIdi) == asdmFeedId_p.end( )){
os << LogIO::SEVERE << "Internal error: undefined mapping for feed1 id " << fIdi
<< " in main table row " << irow << LogIO::POST;
fKeyi = fIdi + 10000*antenna2()(irow);
for(uInt j=0;j<msFeedKeyV.size();j++){
if(fKeyi == msFeedKeyV[j]){
msFeedKeyV.push_back(fKeyi);
msFeedIdV.push_back(fIdi);
if(!asdmFeedId_p.isDefined(fIdi)){
if(asdmFeedId_p.find(fIdi) == asdmFeedId_p.end( )){
os << LogIO::SEVERE << "Internal error: undefined mapping for feed2 id " << fIdi
<< " in main table row " << irow << LogIO::POST;
// sort the antenna ids before entering them into the ConfigDescription table
std::sort(msAntennaIdV.begin(), msAntennaIdV.end());
for(uInt i=0; i<msAntennaIdV.size(); i++){
antennaId.push_back(asdmAntennaId_p(msAntennaIdV[i]));
antennaId.push_back(asdmAntennaId_p.at(msAntennaIdV[i]));
numAntenna = antennaId.size();
// (there is just one DDId per config description in this scheme)
dataDId.push_back(asdmDataDescriptionId_p(msDDIdV[0]));
dataDId.push_back(asdmDataDescriptionId_p.at(msDDIdV[0]));
// sort the feed ids before entering them into the ConfigDescription table
std::sort(msFeedIdV.begin(), msFeedIdV.end());
for(uInt i=0; i<msFeedIdV.size(); i++){
feedId.push_back(asdmFeedId_p(msFeedIdV[i]));
feedId.push_back(asdmFeedId_p.at(msFeedIdV[i]));
numFeed = numFeed/numAntenna;
correlationMode = CorrelationModeMod::CROSS_ONLY;
//tR->setPhasedArrayList(phasedArrayList);
//tR->setFlagAnt(flagAnt);
//tR->setAssocNature(assocNature);
// add this row to to the config description table.
// note that this will check for uniqueness
asdm::ConfigDescriptionRow* tR2 = 0;
Tag newTag = tR2->getConfigDescriptionId();
asdmConfigDescriptionId_p.define(mainTabRow, newTag);
asdmConfigDescriptionId_p.insert(std::pair<casacore::uInt, asdm::Tag>(mainTabRow, newTag));
cout << "Defined conf desc id for main table row " << mainTabRow << endl;
} // end loop over remainder of timestamp in MS main table
} // end loop over MS DD table
asdm::SBSummaryTable& tT = ASDM_p->getSBSummary();
asdm::SBSummaryRow* tR = 0;
asdm::ExecBlockTable& tET = ASDM_p->getExecBlock();
asdm::ExecBlockRow* tER = 0;
SimpleOrderedMap <asdm::Tag, Double> execBlockStartTime(-1.); // map from SBSummaryID to current execblock start time
SimpleOrderedMap <asdm::Tag, Double> execBlockEndTime(-1.); // map from SBSummaryID to current execblock end time
SimpleOrderedMap <asdm::Tag, asdm::ConfigDescriptionRow*> correspConfigDescRow(0); // map from SBSummaryID to the
std::map <asdm::Tag, Double> execBlockStartTime; // map from SBSummaryID to current execblock start time
std::map <asdm::Tag, Double> execBlockEndTime; // map from SBSummaryID to current execblock end time
std::map <asdm::Tag, asdm::ConfigDescriptionRow*> correspConfigDescRow; // map from SBSummaryID to the
// ConfigDescription row of current exec block
SimpleOrderedMap <asdm::Tag, Int> execBlockNumber(0); // map from SBSummaryID to current execblock number
SimpleOrderedMap <asdm::Tag, Int> obsIdFromSBSum(-1); // map from SBSummaryID to current obs ID
SimpleOrderedMap <asdm::Tag, Double> minBaseline(0.); // map from SBSummaryID to minimum baseline of current exec block
SimpleOrderedMap <asdm::Tag, Double> maxBaseline(0.); // map from SBSummaryID to maximum baseline of current exec block
std::map <asdm::Tag, Int> execBlockNumber; // map from SBSummaryID to current execblock number
std::map <asdm::Tag, Int> obsIdFromSBSum; // map from SBSummaryID to current obs ID
std::map <asdm::Tag, Double> minBaseline; // map from SBSummaryID to minimum baseline of current exec block
std::map <asdm::Tag, Double> maxBaseline; // map from SBSummaryID to maximum baseline of current exec block
SimpleOrderedMap <Int, Int> firstFieldIdFromObsId(-1); // map from obsId to first field id (for the representative direction)
std::map <Int, Int> firstFieldIdFromObsId; // map from obsId to first field id (for the representative direction)
// unfortunately, we have to loop over the main table to get the information
// but beforehand we calculate the position of the array center for later reference
if (observation().nrow() > 0) {
// limit the scheduling block duration (not the same as the observation duration)
if(durationSecs > schedBlockDuration_p){
sbDuration = ASDMInterval(schedBlockDuration_p);
numberRepeats = (int) ceil(durationSecs/schedBlockDuration_p);
durationSecs = schedBlockDuration_p;
vector< Angle > centerDirection;
Int fId = fieldId()(mainTabRow);
// an observation (and an SB) can have many fields. use the first one as representative direction
if(firstFieldIdFromObsId.isDefined(obsId)){
fId = firstFieldIdFromObsId(obsId);
if(firstFieldIdFromObsId.find(obsId) != firstFieldIdFromObsId.end( )){
fId = firstFieldIdFromObsId[obsId];
firstFieldIdFromObsId.define(obsId,fId);
firstFieldIdFromObsId.insert(std::pair<Int, Int>(obsId,fId));
////MDirection theFieldDir = field().phaseDirMeas(fId,0);
////centerDirection.push_back( theFieldDir.getAngle( unitASDMAngle() ).getValue()(0) ); // RA
////centerDirection.push_back( theFieldDir.getAngle( unitASDMAngle() ).getValue()(1) ); // DEC
int numObservingMode = 1;
vector< string > observingMode;
observingMode.push_back("observing mode t.b.d.");
vector< string > scienceGoal;
numObservingMode, observingMode, numberRepeats, numScienceGoal,
scienceGoal, numWeatherConstraint, weatherConstraint);
asdm::SBSummaryRow* tR2 = 0;
Tag sBSummaryTag = tR2->getSBSummaryId();
if(tR2 == tR){ // adding the row led to the creation of a new tag
cout << "New SBSummary tag created: " << tR2 << endl;
if(asdmSBSummaryId_p.isDefined(sbKey)){
if( asdmSBSummaryId_p.find(sbKey) != asdmSBSummaryId_p.end( ) ){
os << LogIO::WARN << "There is more than one scheduling block necessary for the obsid - freqBand pair ("
<< obsId << ", " << bandNum << ").\n This can presently not yet be handled properly.\n"
<< "(MS Main table row " << mainTabRow << ")" << LogIO::POST;
asdmSBSummaryId_p.define(sbKey, sBSummaryTag);
asdmSBSummaryId_p.insert(std::pair<casacore::Int, asdm::Tag>(sbKey, sBSummaryTag));
// now have a valid SBSummaryID for the execblock
// Step 2: write exec block table
// has the exec block been started already?
if(execBlockStartTime.isDefined(sBSummaryTag)){ // yes
if(execBlockStartTime.find(sBSummaryTag) != execBlockStartTime.end( )){ // yes
// continue accumulation of min and max baseline
Double baseLine = MVBaseline( (antenna().positionMeas()(antenna1()(mainTabRow))).getValue(),
(antenna().positionMeas()(antenna2()(mainTabRow))).getValue()
).getLength().getValue(unitASDMLength());
if(baseLine>maxBaseline(sBSummaryTag)){
maxBaseline.remove(sBSummaryTag);
maxBaseline.define(sBSummaryTag, baseLine);
if(baseLine>maxBaseline.at(sBSummaryTag)){
auto ptr = maxBaseline.find(sBSummaryTag);
maxBaseline.insert(std::pair<asdm::Tag, Double>(sBSummaryTag, baseLine));
else if(baseLine<minBaseline(sBSummaryTag)){
minBaseline.remove(sBSummaryTag);
minBaseline.define(sBSummaryTag, baseLine);
else if(baseLine<minBaseline.at(sBSummaryTag)){
auto ptr = minBaseline.find(sBSummaryTag);
minBaseline.insert(std::pair<asdm::Tag, Double>(sBSummaryTag, baseLine));
// is the exec block complete?
Double endT = timestampEndSecs(mainTabRow);
if(endT > execBlockEndTime(sBSummaryTag)){ // integration intervals may be different for different DD Ids, take max endT
execBlockEndTime.remove(sBSummaryTag);
execBlockEndTime.define(sBSummaryTag, endT);
if(endT > execBlockEndTime.at(sBSummaryTag)){ // integration intervals may be different for different DD Ids, take max endT
auto ptr = execBlockEndTime.find(sBSummaryTag);
execBlockEndTime.erase(ptr);
execBlockEndTime.insert(std::pair<asdm::Tag, Double>(sBSummaryTag, endT));
cout << "interval = " << endT - execBlockStartTime(sBSummaryTag) << ", duration == " << durationSecs << endl;
cout << "interval = " << endT - execBlockStartTime.at(sBSummaryTag) << ", duration == " << durationSecs << endl;
if(endT - execBlockStartTime(sBSummaryTag) >= durationSecs){ // yes, it is complete
if(endT - execBlockStartTime.at(sBSummaryTag) >= durationSecs){ // yes, it is complete
// parameters for a new row
ArrayTime startTime = ASDMArrayTime(execBlockStartTime(sBSummaryTag));
ArrayTime startTime = ASDMArrayTime(execBlockStartTime.at(sBSummaryTag));
ArrayTime endTime = ASDMArrayTime(endT);
int execBlockNum = execBlockNumber(sBSummaryTag);
int execBlockNum = execBlockNumber.at(sBSummaryTag);
EntityRef execBlockUID; // to be filled with the EntityRef of the containing ASDM
execBlockUID = EntityRef(asdmUID_p, "", "ASDM", asdmVersion_p);
catch(asdm::InvalidArgumentException x){
os << LogIO::SEVERE << "Error creating ASDM: UID \"" << getCurrentUid()
<< "\" (intended for the ASDM) is not a valid Entity reference: " << x.getMessage()
observingLog.resize(sV.size());
numObservingLog = observingLog.size();
for(uInt i=0; i<sV.size(); i++){
observingLog[i] = string(sV[i].c_str());
////string sessionReference = "sessionReference t.b.d."; // ???
////EntityRef sbSummary = sbSummaryUID;
EntityRef sessionReference = sbSummaryUID;
////string schedulerMode = "CASA exportasdm"; //???
Length baseRangeMin = Length( minBaseline(sBSummaryTag) );
Length baseRangeMax = Length( maxBaseline(sBSummaryTag) );
Length baseRangeMin = Length( minBaseline.at(sBSummaryTag) );
Length baseRangeMax = Length( maxBaseline.at(sBSummaryTag) );
Length baseRmsMinor = Length(0); // ???
Length baseRmsMajor = Length(0); // ???
Angle basePa = Angle(0); // ???
asdm::ConfigDescriptionRow* cDR = correspConfigDescRow(sBSummaryTag);
asdm::ConfigDescriptionRow* cDR = correspConfigDescRow.at(sBSummaryTag);
int numAntenna = cDR->getNumAntenna();
vector< Tag > antennaId = cDR->getAntennaId();
tER = tET.newRow(startTime, endTime, execBlockNum, execBlockUID, projectId, configName, telescopeName, observerName,
numObservingLog, observingLog, //// now vector< string>
sessionReference, //// now of type EntityRef
////sbSummary, schedulerMode,
baseRangeMin, baseRangeMax, baseRmsMinor, baseRmsMajor, basePa,
////siteAltitude, siteLongitude, siteLatitude,
aborted, numAntenna, antennaId, sBSummaryTag);
asdm::ExecBlockRow* tER2;
os << LogIO::SEVERE << "Internal error: attempt to store duplicate exec block row." << LogIO::POST;
asdmExecBlockId_p.define(execBlockStartTime(sBSummaryTag), tER->getExecBlockId());
asdmExecBlockId_p.insert(std::pair<casacore::Double, asdm::Tag>(execBlockStartTime.at(sBSummaryTag), tER->getExecBlockId()));
cout << "eblock id defined in loop 1 for start time " << setprecision(13) << execBlockStartTime(sBSummaryTag) << endl;
cout << " end time " << setprecision(13) << execBlockEndTime(sBSummaryTag) << endl;
cout << "eblock id defined in loop 1 for start time " << setprecision(13) << execBlockStartTime.at(sBSummaryTag) << endl;
cout << " end time " << setprecision(13) << execBlockEndTime.at(sBSummaryTag) << endl;
// undefine the mapping for this Tag since the ExecBlock was completed
execBlockStartTime.remove(sBSummaryTag);
execBlockEndTime.remove(sBSummaryTag);
correspConfigDescRow.remove(sBSummaryTag);
obsIdFromSBSum.remove(sBSummaryTag);
minBaseline.remove(sBSummaryTag);
maxBaseline.remove(sBSummaryTag);
auto startptr = execBlockStartTime.find(sBSummaryTag);
if ( startptr != execBlockStartTime.end( ) ) execBlockStartTime.erase(startptr);
auto endptr = execBlockEndTime.find(sBSummaryTag);
if ( endptr != execBlockEndTime.end( ) ) execBlockEndTime.erase(endptr);
auto corptr = correspConfigDescRow.find(sBSummaryTag);
if ( corptr != correspConfigDescRow.end( ) ) correspConfigDescRow.erase(corptr);
auto sumptr = obsIdFromSBSum.find(sBSummaryTag);
if ( sumptr != obsIdFromSBSum.end( ) ) obsIdFromSBSum.erase(sumptr);
auto minptr = minBaseline.find(sBSummaryTag);
if ( minptr != minBaseline.end( ) ) minBaseline.erase(minptr);
auto maxptr = maxBaseline.find(sBSummaryTag);
if ( maxptr != maxBaseline.end( ) ) maxBaseline.erase(maxptr);
// else{ // no, it is not complete
else{// no, it has not been started, yet
// check if there is another exec block which started at the same time
for(uInt i=0; i<execBlockStartTime.ndefined(); i++){
if(execBlockStartTime.getVal(i) == timestampStartSecs(mainTabRow)){
os << LogIO::SEVERE << "Observation of different frequency bands at the same time and under the same observation ID is not supported by the ASDM."
<< "\n Please split out the different spectral bands into individual MSs and process separately." << LogIO::POST;
for ( auto iter = execBlockStartTime.begin( ); iter != execBlockStartTime.end( ); ++iter ) {
if ( iter->second == timestampStartSecs(mainTabRow) ){
os << LogIO::SEVERE << "Observation of different frequency bands at the same time and under the same observation ID is not supported by the ASDM."
<< "\n Please split out the different spectral bands into individual MSs and process separately." << LogIO::POST;
execBlockStartTime.define(sBSummaryTag, timestampStartSecs(mainTabRow));
execBlockStartTime.insert(std::pair<asdm::Tag, Double>(sBSummaryTag, timestampStartSecs(mainTabRow)));
execBlockEndTime.insert(std::pair<asdm::Tag, Double>(sBSummaryTag, timestampEndSecs(mainTabRow))); // will be updated
execBlockEndTime.define(sBSummaryTag, timestampEndSecs(mainTabRow)); // will be updated
if(execBlockNumber.isDefined(sBSummaryTag)){
auto numptr = execBlockNumber.find(sBSummaryTag);
if( numptr != execBlockNumber.end( ) ){
// increment exec block number
oldNum = execBlockNumber(sBSummaryTag);
execBlockNumber.remove(sBSummaryTag);
execBlockNumber.erase(numptr);
execBlockNumber.define(sBSummaryTag, oldNum + 1); // sequential numbering starting at 1
execBlockNumber.insert(std::pair<asdm::Tag, Int>(sBSummaryTag, oldNum + 1)); // sequential numbering starting at 1
cout << "eblock number " << oldNum + 1 << " defined for start time " << setprecision (9) << timestampStartSecs(mainTabRow) << endl;
obsIdFromSBSum.define(sBSummaryTag, obsId); // remember the obsId for this exec block
obsIdFromSBSum.insert(std::pair<asdm::Tag, Int>(sBSummaryTag, obsId)); // remember the obsId for this exec block
if(!asdmConfigDescriptionId_p.isDefined(mainTabRow)){
if( asdmConfigDescriptionId_p.find(mainTabRow) == asdmConfigDescriptionId_p.end( ) ){
os << LogIO::SEVERE << "Internal error: undefined config description id for MS main table row "
<< mainTabRow << LogIO::POST;
asdm::ConfigDescriptionRow* cDR = (ASDM_p->getConfigDescription()).getRowByKey(asdmConfigDescriptionId_p(mainTabRow));
asdm::ConfigDescriptionRow* cDR = (ASDM_p->getConfigDescription()).getRowByKey(asdmConfigDescriptionId_p[mainTabRow]);
os << LogIO::SEVERE << "Internal error: no row in ASDM ConfigDesc Table for ConfigDescriptionId stored for main table row "
<< mainTabRow << LogIO::POST;
correspConfigDescRow.define(sBSummaryTag, cDR); // remember the config description row for this exec block
correspConfigDescRow.insert(std::pair<asdm::Tag, asdm::ConfigDescriptionRow*>(sBSummaryTag, cDR)); // remember the config description row for this exec block
// start accumulation of min and max baseline
Double bLine = MVBaseline( (antenna().positionMeas()(antenna1()(mainTabRow))).getValue(),
(antenna().positionMeas()(antenna2()(mainTabRow))).getValue()
).getLength().getValue(unitASDMLength());
minBaseline.define(sBSummaryTag, bLine);
maxBaseline.define(sBSummaryTag, bLine);
minBaseline.insert(std::pair<asdm::Tag, Double>(sBSummaryTag, bLine));
maxBaseline.insert(std::pair<asdm::Tag, Double>(sBSummaryTag, bLine));
// skip rest of this timestamp
Double tStamp = time()(mainTabRow);
while(mainTabRow<nMainTabRows
&& time()(mainTabRow)==tStamp
&& dataDescId()(mainTabRow)==ddId){
mainTabRow--;// we are inside a for loop which will perform the last mainTabRow++
} // end loop over main table
// are there pending exec blocks?
while(execBlockStartTime.ndefined()>0){ // yes
Tag sBSummaryTag = execBlockStartTime.getKey(0);
while(execBlockStartTime.size()>0){ // yes
Tag sBSummaryTag = execBlockStartTime.begin( )->first;
tR = tT.getRowByKey(sBSummaryTag);
Int obsId = obsIdFromSBSum(sBSummaryTag);
Int obsId = obsIdFromSBSum.at(sBSummaryTag);
// parameters for a new row
ArrayTime startTime = ASDMArrayTime(execBlockStartTime(sBSummaryTag));
ArrayTime endTime = ASDMArrayTime(execBlockEndTime(sBSummaryTag));
int execBlockNum = execBlockNumber(sBSummaryTag);
ArrayTime startTime = ASDMArrayTime(execBlockStartTime.at(sBSummaryTag));
ArrayTime endTime = ASDMArrayTime(execBlockEndTime.at(sBSummaryTag));
int execBlockNum = execBlockNumber.at(sBSummaryTag);
EntityRef execBlockUID; // to be filled with the EntityRef of the containing ASDM
execBlockUID = EntityRef(asdmUID_p, "", "ASDM", asdmVersion_p);
catch(asdm::InvalidArgumentException x){
os << LogIO::SEVERE << "Error creating ASDM: UID \"" << getCurrentUid()
<< "\" (intended for an exec block) not a valid Entity reference: " << x.getMessage()
numObservingLog = observingLog.size();
for(uInt i=0; i<sV.size(); i++){
observingLog[i] = string(sV[i].c_str());
//// string sessionReference = "sessionReference t.b.d."; // ???
////EntityRef sbSummary = tR->getSbSummaryUID();
EntityRef sessionReference = tR->getSbSummaryUID();
////string schedulerMode = "CASA exportasdm"; //???
Length baseRangeMin = Length( minBaseline(sBSummaryTag) );
Length baseRangeMax = Length( maxBaseline(sBSummaryTag) );
Length baseRangeMin = Length( minBaseline.at(sBSummaryTag) );
Length baseRangeMax = Length( maxBaseline.at(sBSummaryTag) );
Length baseRmsMinor = Length(0); // ???
Length baseRmsMajor = Length(0); // ???
Angle basePa = Angle(0); // ???
asdm::ConfigDescriptionRow* cDR = correspConfigDescRow(sBSummaryTag);
asdm::ConfigDescriptionRow* cDR = correspConfigDescRow.at(sBSummaryTag);
int numAntenna = cDR->getNumAntenna();
vector< Tag > antennaId = cDR->getAntennaId();
tER = tET.newRow(startTime, endTime, execBlockNum, execBlockUID, projectId, configName, telescopeName, observerName,
numObservingLog, observingLog,
////sbSummary, schedulerMode,
baseRangeMin, baseRangeMax, baseRmsMinor, baseRmsMajor, basePa,
////siteAltitude, siteLongitude, siteLatitude,
aborted, numAntenna, antennaId, sBSummaryTag);
asdm::ExecBlockRow* tER2;
os << LogIO::SEVERE << "Internal error: attempt to store duplicate exec block row." << LogIO::POST;
asdmExecBlockId_p.define(execBlockStartTime(sBSummaryTag), tER->getExecBlockId());
asdmExecBlockId_p.insert(std::pair<casacore::Double, asdm::Tag>(execBlockStartTime.at(sBSummaryTag), tER->getExecBlockId()));
cout << "eblock id defined in loop 2 for start time " << setprecision(13) << execBlockStartTime(sBSummaryTag) << endl;
cout << " end time " << setprecision(13) << execBlockEndTime(sBSummaryTag) << endl;
cout << "eblock id defined in loop 2 for start time " << setprecision(13) << execBlockStartTime.at(sBSummaryTag) << endl;
cout << " end time " << setprecision(13) << execBlockEndTime.at(sBSummaryTag) << endl;
// undefine the mapping for this Tag since the ExecBlock was completed
execBlockStartTime.remove(sBSummaryTag); // need only remove from the map what is tested
execBlockEndTime.remove(sBSummaryTag);
auto startptr = execBlockStartTime.find(sBSummaryTag); // need only remove from the map what is tested
if ( startptr != execBlockStartTime.end( ) ) execBlockStartTime.erase(startptr);
auto endptr = execBlockEndTime.find(sBSummaryTag);
if ( endptr != execBlockEndTime.end( ) ) execBlockEndTime.erase(endptr);
// finish the SBSummary table
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
os << LogIO::NORMAL << "Filled SBSummary table " << getCurrentUid() << " with " << tT.size() << " rows ..." << LogIO::POST;
vector< CalDataOriginMod::CalDataOrigin > scanCalDataType;
vector< bool > scanCalibrationOnLine;
////bool scanFlagRow = false; // always false ???
uInt nMainTabRows = ms_p.nrow();
for(uInt mainTabRow=0; mainTabRow<nMainTabRows; mainTabRow++){
Double rowTime = timestampStartSecs(mainTabRow);
// asdmExecBlockId_p defined for this timestamp?
if(asdmExecBlockId_p.isDefined(rowTime)){ // a new exec block has started
if(asdmExecBlockId_p.find(rowTime) != asdmExecBlockId_p.end( )){ // a new exec block has started
// is there a previous exec block?
if(execBlockId != Tag()){
// finish the old exec block
// parameters for the first scan
execBlockId = asdmExecBlockId_p(rowTime);
execBlockId = asdmExecBlockId_p.at(rowTime);
asdm::ExecBlockRow* EBR = (ASDM_p->getExecBlock()).getRowByKey(execBlockId);
scanNumber = 1; // ASDM scan numbering starts at 1
subscanNumber = 1; // dito for subscans
scanStartTime = ASDMArrayTime( scanStart );
scanEndTime = EBR->getEndTime(); // preset to the end of the execblock
scanCalDataType.resize(0);
<< endl << "Will try to continue ..." << LogIO::POST;
// search back to see if the execblock start can be found
Double searchIntervalSecs = 60.;
uInt mainTabRowB = mainTabRow;
Bool foundEBStart = false;
Double rowTimeB = rowTime;
while(rowTime - rowTimeB < searchIntervalSecs && mainTabRowB>0){
rowTimeB = timestampStartSecs(--mainTabRowB);
if(asdmExecBlockId_p.isDefined(rowTimeB)){
if(asdmExecBlockId_p.find(rowTimeB) != asdmExecBlockId_p.end( )){
execBlockId = asdmExecBlockId_p(rowTimeB);
execBlockId = asdmExecBlockId_p.at(rowTimeB);
asdm::ExecBlockRow* EBR = (ASDM_p->getExecBlock()).getRowByKey(execBlockId);
scanNumber = 1; // ASDM scan numbering starts at 1
subscanNumber = 1; // dito for subscans
scanStartTime = ASDMArrayTime( scanStart );
scanEndTime = EBR->getEndTime(); // preset to the end of the execblock
scanCalDataType.resize(0);
MSTimeSecs(scanEndTime) - (rowTime = timestampStartSecs(mainTabRow)) > 1E-3 ){ // presently one scan per exec block ???
// parameters for the new SubScan table row
Double subScanEnd = rowTime + subscanDuration_p;
if(subScanEnd > MSTimeSecs(scanEndTime)){
subScanEnd = MSTimeSecs(scanEndTime);
// find all DDIds in the time between now and end of subscan
SimpleOrderedMap< Int, uInt > subScanDDIdStartRows(0);
std::map< Int, uInt > subScanDDIdStartRows;
while(irow<nMainTabRows &&
timestampStartSecs(irow) < subScanEnd){
Int ddId = dataDescId()(irow);
if(!subScanDDIdStartRows.isDefined(ddId)){
subScanDDIdStartRows.define(ddId, irow); // memorize their start rows
if(subScanDDIdStartRows.find(ddId) == subScanDDIdStartRows.end( )){
subScanDDIdStartRows.insert(std::pair< Int, uInt >(ddId, irow)); // memorize their start rows
for(uInt ddIndex=0; ddIndex < subScanDDIdStartRows.ndefined(); ddIndex++){
Int theDDId = subScanDDIdStartRows.getKey(ddIndex);
for( auto iter = subScanDDIdStartRows.begin( ); iter != subScanDDIdStartRows.end( ); ++iter ){
Int theDDId = iter->first;
// find all FieldIds in the time between now and now+subscanduration or until Scan ends
SimpleOrderedMap< Int, uInt > subScanStartRows(0);
SimpleOrderedMap< Int, uInt > subScanEndRows(0);
std::map< Int, uInt > subScanStartRows;
std::map< Int, uInt > subScanEndRows;
while(irow2<nMainTabRows &&
timestampStartSecs(irow2) < subScanEnd){
Int ddId = dataDescId()(irow2);
Int fId = fieldId()(irow2);
if(subScanEndRows.isDefined(fId)){
subScanEndRows.remove(fId);
subScanEndRows.define(fId, irow2); // update end row
if(!subScanStartRows.isDefined(fId)){
subScanStartRows.define(fId, irow2); // memorize their start rows
subScanEndRows.define(fId, irow2); // and end rows
auto erptr = subScanEndRows.find(fId);
if( erptr != subScanEndRows.end( ) ){
subScanEndRows.erase(erptr);
subScanEndRows.insert(std::pair< Int, uInt >(fId, irow2)); // update end row
auto srptr = subScanStartRows.find(fId);
if( srptr == subScanStartRows.end( ) ){
subScanStartRows.insert(std::pair< Int, uInt >(fId, irow2)); // memorize their start rows
subScanEndRows.insert(std::pair< Int, uInt >(fId, irow2)); // and end rows
for(uInt fIndex=0; fIndex < subScanStartRows.ndefined(); fIndex++){
Int theFId = subScanStartRows.getKey(fIndex);
uInt startRow = subScanStartRows(theFId);
uInt endRow = subScanEndRows(theFId);
for( auto iter = subScanStartRows.begin( ); iter != subScanStartRows.end( ); ++iter ) {
Int theFId = iter->first;
uInt startRow = subScanStartRows.at(theFId);
uInt endRow = subScanEndRows.at(theFId);
// parameters for the new SubScan table row
ArrayTime subScanStartArrayTime = ASDMArrayTime(timestampStartSecs(startRow));
ArrayTime subScanEndArrayTime = ASDMArrayTime(timestampEndSecs(endRow));
string fieldName = field().name()(fieldId()(startRow)).c_str();
SubscanIntentMod::SubscanIntent subscanIntent = SubscanIntentMod::ON_SOURCE;
vector< int > numberSubintegration;
////bool flagRow = false;
// parameters for the corresponding new Main table row
ArrayTime mainTime = ASDMArrayTime((timestampStartSecs(startRow) + timestampEndSecs(endRow))/2.); // midpoint!
if(!asdmConfigDescriptionId_p.isDefined(startRow)){
if(asdmConfigDescriptionId_p.find(startRow) == asdmConfigDescriptionId_p.end( )){
os << LogIO::SEVERE << "Internal error: undefined config description id for MS main table row "
<< startRow << LogIO::POST;
Tag configDescriptionId = asdmConfigDescriptionId_p(startRow);
Tag configDescriptionId = asdmConfigDescriptionId_p.at(startRow);
asdm::ConfigDescriptionRow* CDR = (ASDM_p->getConfigDescription()).getRowByKey(configDescriptionId);
os << LogIO::SEVERE << "Internal error: no row in ASDM ConfigDesc Table for ConfigDescriptionId stored for main table row "
<< startRow << LogIO::POST;
Tag fieldIdTag = asdmFieldId_p(theFId);
Tag fieldIdTag = asdmFieldId_p.at(theFId);
int numAntenna = CDR->getNumAntenna();
TimeSamplingMod::TimeSampling timeSampling = TimeSamplingMod::INTEGRATION;
Interval interval = ASDMInterval(intervalQuant()(startRow).getValue("s")); // data sampling interval
int numIntegration; // to be set by the following method call
int dataSize; // to be set by the following method call
EntityRef dataOid; // to be set by the following method call
vector< Tag > stateIdV; // "
// Note: for WVR data, a special case would have to be made here or inside
// writeMainBinSubScanForOneDDIdFIdPair() which does not call corrDataHeader
ReceiverBandMod::ReceiverBand receiverBand = recRowV[0]->getFrequencyBand(); // take from the first receiver
string assocNature = "NOT_SET";
int assocPointingModelId = -1;
tR = tT.newRow(antennaId, numCoeff, coeffName, coeffVal, polarizationType,
receiverBand, assocNature, assocPointingModelId);
asdm::PointingModelRow* tR2 = 0;
if(!asdmPointingModelId_p.isDefined(antennaId)){
asdmPointingModelId_p.define(antennaId, tR2->getPointingModelId() );
if(asdmPointingModelId_p.find(antennaId) == asdmPointingModelId_p.end( )){
asdmPointingModelId_p.insert(std::pair<asdm::Tag, int>(antennaId, tR2->getPointingModelId() ));
} // end loop over receptors
} // end loop over ASDM Feed table
EntityId theUid(getCurrentUid());
Entity ent = tT.getEntity();
os << LogIO::WARN << "MS Pointing table doesn't exist or is empty." << LogIO::POST;
return true; // not an error
Bool warned = false; // aux. var. to avoid repetition of warnings
// loop over MS antenna table
for(Int aId=0; aId<(Int)antenna().nrow(); aId++){
if(!asdmAntennaId_p.isDefined(aId)){
if(asdmAntennaId_p.find(aId) == asdmAntennaId_p.end( )){
os << LogIO::SEVERE << "Internal error: no tag defined for antenna id "
uInt totNumRows=0; // total of MS Pointing table rows for this antenna
while(irow<nPointingRows){
if(firstRow==-1){ // no further data for this antenna
uInt numRows=1; // number of rows with contiguous timestamps for this antenna
// parameters for the next pointing table row
Tag antennaId = asdmAntennaId_p(aId);
Tag antennaId = asdmAntennaId_p.at(aId);
ArrayTimeInterval timeInterval( ASDMTimeInterval( pointing().timeQuant()(firstRow), pointing().intervalQuant()(firstRow)) );
bool pointingTracking = pointing().tracking()(firstRow);
bool usePolynomials = false;
int numTerm = 0; // to be updated later
if(pointing().numPoly()(firstRow)>0){
numTerm = pointing().numPoly()(irow)+1;
os << LogIO::SEVERE << "Inconsistent MS: in pointing table row " << firstRow
<< ": numpoly + 1 should be == dimension of array SOURCE_OFFSET." << LogIO::POST;
for(uInt i=0; i<(uInt)numTerm; i++){
sourceOffset.push_back(ASDMAngleV(dirV[i]));
int pointingModelId = asdmPointingModelId_p(antennaId);
int pointingModelId = asdmPointingModelId_p.at(antennaId);
double endTimeMJD = timeInterval.getStartInMJD() + timeInterval.getDurationInDays();
// check if there are more rows for this antenna with adjacent time intervals
while(irow<nPointingRows && numTerm==0){ // while we find more adjacent rows and don't use polynomials
if(pointing().antennaId()(irow) != aId){