/** * Updates from a more generic ascii file * @param filename :: The input filename */ void UpdateInstrumentFromFile::updateFromAscii(const std::string & filename) { AsciiFileHeader header; const bool isSpectrum = parseAsciiHeader(header); Geometry::Instrument_const_sptr inst = m_workspace->getInstrument(); // Throws for multiple detectors const spec2index_map specToIndex(m_workspace->getSpectrumToWorkspaceIndexMap()); std::ifstream datfile(filename.c_str(), std::ios_base::in); const int skipNLines = getProperty("SkipFirstNLines"); std::string line; int lineCount(0); while(lineCount < skipNLines) { std::getline(datfile,line); ++lineCount; } std::vector<double> colValues(header.colCount - 1, 0.0); while(std::getline(datfile,line)) { boost::trim(line); std::istringstream is(line); // Column 0 should be ID/spectrum number int32_t detOrSpec(-1000); is >> detOrSpec; // If first thing read is not a number then skip the line if(is.fail()) { g_log.debug() << "Skipping \"" << line << "\". Cannot interpret as list of numbers.\n"; continue; } Geometry::IDetector_const_sptr det; try { if(isSpectrum) { auto it = specToIndex.find(detOrSpec); if(it != specToIndex.end()) { const size_t wsIndex = it->second; det = m_workspace->getDetector(wsIndex); } else { g_log.debug() << "Skipping \"" << line << "\". Spectrum is not in workspace.\n"; continue; } } else { det = inst->getDetector(detOrSpec); } } catch(Kernel::Exception::NotFoundError&) { g_log.debug() << "Skipping \"" << line << "\". Spectrum in workspace but cannot find associated detector.\n"; continue; } // Special cases for detector r,t,p. Everything else is // attached as an detector parameter double R(0.0),theta(0.0), phi(0.0); for(size_t i = 1; i < header.colCount; ++i) { double value(0.0); is >> value; if(i < header.colCount - 1 && is.eof()) { //If stringstream is at EOF & we are not at the last column then // there aren't enought columns in the file throw std::runtime_error("UpdateInstrumentFromFile::updateFromAscii - " "File contains fewer than expected number of columns, check AsciiHeader property."); } if(i == header.rColIdx) R = value; else if(i == header.thetaColIdx) theta = value; else if(i == header.phiColIdx) phi = value; else if(header.detParCols.count(i) == 1) { Geometry::ParameterMap & pmap = m_workspace->instrumentParameters(); pmap.addDouble(det->getComponentID(), header.colToName[i],value); } } // Check stream state. stringstream::EOF should have been reached, if not then there is still more to // read and the file has more columns than the header indicated if(!is.eof()) { throw std::runtime_error("UpdateInstrumentFromFile::updateFromAscii - " "File contains more than expected number of columns, check AsciiHeader property."); } // If not supplied use current values double r,t,p; det->getPos().getSpherical(r,t,p); if(header.rColIdx == 0) R = r; if(header.thetaColIdx == 0) theta = t; if(header.phiColIdx == 0) phi = p; setDetectorPosition(det, static_cast<float>(R), static_cast<float>(theta), static_cast<float>(phi)); } }
// rebuild a single subblock Epetra_CrsMatrix void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector<std::pair<int,RCP<Epetra_Map> > > & subMaps,Epetra_CrsMatrix & mat) { // get the number of variables families int numVarFamily = subMaps.size(); TEUCHOS_ASSERT(i>=0 && i<numVarFamily); TEUCHOS_ASSERT(j>=0 && j<numVarFamily); TEUCHOS_ASSERT(mat.Filled()); const Epetra_Map & gRowMap = *subMaps[i].second; const Epetra_Map & rowMap = *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[i].second,"contigMap"); int colFamilyCnt = subMaps[j].first; // compute the number of global variables // and the row and column block offset int numGlobalVars = 0; int rowBlockOffset = 0; int colBlockOffset = 0; for(int k=0;k<numVarFamily;k++) { numGlobalVars += subMaps[k].first; // compute block offsets if(k<i) rowBlockOffset += subMaps[k].first; if(k<j) colBlockOffset += subMaps[k].first; } // copy all global rows to here Epetra_Import import(gRowMap,A.RowMap()); Epetra_CrsMatrix localA(Copy,gRowMap,0); localA.Import(A,import,Insert); // clear out the old matrix mat.PutScalar(0.0); // get entry information int numMyRows = rowMap.NumMyElements(); int maxNumEntries = A.GlobalMaxNumEntries(); // for extraction std::vector<int> indices(maxNumEntries); std::vector<double> values(maxNumEntries); // for insertion std::vector<int> colIndices(maxNumEntries); std::vector<double> colValues(maxNumEntries); // insert each row into subblock // let FillComplete handle column distribution for(int localRow=0;localRow<numMyRows;localRow++) { int numEntries = -1; int globalRow = gRowMap.GID(localRow); int contigRow = rowMap.GID(localRow); TEUCHOS_ASSERT(globalRow>=0); TEUCHOS_ASSERT(contigRow>=0); // extract a global row copy int err = localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]); TEUCHOS_ASSERT(err==0); int numOwnedCols = 0; for(int localCol=0;localCol<numEntries;localCol++) { int globalCol = indices[localCol]; // determinate which block this column ID is in int block = globalCol / numGlobalVars; bool inFamily = true; // test the beginning of the block inFamily &= (block*numGlobalVars+colBlockOffset <= globalCol); inFamily &= ((block*numGlobalVars+colBlockOffset+colFamilyCnt) > globalCol); // is this column in the variable family if(inFamily) { int familyOffset = globalCol-(block*numGlobalVars+colBlockOffset); colIndices[numOwnedCols] = block*colFamilyCnt + familyOffset; colValues[numOwnedCols] = values[localCol]; numOwnedCols++; } } // insert it into the new matrix mat.SumIntoGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]); } }
/** * Updates from a more generic ascii file * @param filename :: The input filename */ void UpdateInstrumentFromFile::updateFromAscii(const std::string &filename) { AsciiFileHeader header; const bool isSpectrum = parseAsciiHeader(header); // Throws for multiple detectors const spec2index_map specToIndex( m_workspace->getSpectrumToWorkspaceIndexMap()); std::ifstream datfile(filename.c_str(), std::ios_base::in); const int skipNLines = getProperty("SkipFirstNLines"); std::string line; int lineCount(0); while (lineCount < skipNLines) { std::getline(datfile, line); ++lineCount; } Geometry::ParameterMap &pmap = m_workspace->instrumentParameters(); auto &detectorInfo = m_workspace->mutableDetectorInfo(); const auto &spectrumInfo = m_workspace->spectrumInfo(); std::vector<double> colValues(header.colCount - 1, 0.0); while (std::getline(datfile, line)) { boost::trim(line); std::istringstream is(line); // Column 0 should be ID/spectrum number int32_t detOrSpec(-1000); is >> detOrSpec; // If first thing read is not a number then skip the line if (is.fail()) { g_log.debug() << "Skipping \"" << line << "\". Cannot interpret as list of numbers.\n"; continue; } bool skip{false}; size_t index = static_cast<size_t>(-1); const Geometry::IDetector *det{nullptr}; if (isSpectrum) { auto it = specToIndex.find(detOrSpec); if (it != specToIndex.end()) { index = it->second; if (spectrumInfo.hasDetectors(index)) { det = &spectrumInfo.detector(index); } else { skip = true; } } else { g_log.debug() << "Skipping \"" << line << "\". Spectrum is not in workspace.\n"; continue; } } else { try { index = detectorInfo.indexOf(detOrSpec); det = &detectorInfo.detector(index); } catch (std::out_of_range &) { skip = true; } } if (skip || index == static_cast<size_t>(-1)) { g_log.debug() << "Skipping \"" << line << "\". Spectrum in workspace but cannot find associated detector.\n"; continue; } std::vector<size_t> indices; if (isSpectrum) { if (auto group = dynamic_cast<const Geometry::DetectorGroup *>(det)) { for (const auto detID : group->getDetectorIDs()) indices.push_back(detectorInfo.indexOf(detID)); } else { indices.push_back(detectorInfo.indexOf(det->getID())); } } else { indices.push_back(index); } // Special cases for detector r,t,p. Everything else is // attached as an detector parameter double R(0.0), theta(0.0), phi(0.0); for (size_t i = 1; i < header.colCount; ++i) { double value(0.0); is >> value; if (i < header.colCount - 1 && is.eof()) { // If stringstream is at EOF & we are not at the last column then // there aren't enought columns in the file throw std::runtime_error("UpdateInstrumentFromFile::updateFromAscii - " "File contains fewer than expected number of " "columns, check AsciiHeader property."); } if (i == header.rColIdx) R = value; else if (i == header.thetaColIdx) theta = value; else if (i == header.phiColIdx) phi = value; else if (header.detParCols.count(i) == 1) { for (const auto index : indices) { auto id = detectorInfo.detector(index).getComponentID(); pmap.addDouble(id, header.colToName[i], value); } } } // Check stream state. stringstream::EOF should have been reached, if not // then there is still more to // read and the file has more columns than the header indicated if (!is.eof()) { throw std::runtime_error("UpdateInstrumentFromFile::updateFromAscii - " "File contains more than expected number of " "columns, check AsciiHeader property."); } // If not supplied use current values double r, t, p; if (isSpectrum) spectrumInfo.position(index).getSpherical(r, t, p); else detectorInfo.position(index).getSpherical(r, t, p); if (header.rColIdx == 0) R = r; if (header.thetaColIdx == 0) theta = t; if (header.phiColIdx == 0 || m_ignorePhi) phi = p; for (const auto index : indices) setDetectorPosition(detectorInfo, index, static_cast<float>(R), static_cast<float>(theta), static_cast<float>(phi)); } }