diff --git a/sammy/src/io/CMakeLists.txt b/sammy/src/io/CMakeLists.txt index 43ab2c968fb2177fe4ae41c02e6004c9305a8346..10a4c64a62e4391c5e12462b7ea0d045be93b911 100644 --- a/sammy/src/io/CMakeLists.txt +++ b/sammy/src/io/CMakeLists.txt @@ -10,12 +10,14 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) # Set headers SET(HEADERS ExperimentalParametersIO.h + odfIO.h interface/cpp/ExperimentalParametersIOInterface.h ) APPEND_SET(IO_SOURCES ExperimentalParametersIO.cpp + odfIO.cpp interface/cpp/ExperimentalParametersIOInterface.cpp interface/fortran/ExperimentalParametersIO_M.f90 interface/fortran/ExperimentalParametersIO_I.f90 diff --git a/sammy/src/io/odfIO.cpp b/sammy/src/io/odfIO.cpp new file mode 100644 index 0000000000000000000000000000000000000000..885d94e04b15559e47fc02b5bf6e17f522453dc4 --- /dev/null +++ b/sammy/src/io/odfIO.cpp @@ -0,0 +1,179 @@ +#include "odfIO.h" + +namespace sammy{ + + odfIO::odfIO() {} + + double odfIO::readFloat(std::ifstream &fs, bool unix){ + + unsigned char tmp1,tmp2,tmp3,tmp4; + int i=0; + float value; + float * dummy_value; + + if(!unix){ // wacky VMS + fs.read( (char*)&tmp1, 1 ); // 1 byte each + fs.read( (char*)&tmp2, 1 ); + fs.read( (char*)&tmp3, 1 ); + fs.read( (char*)&tmp4, 1 ); + // std::cout << "1,2,3,4 = " << (int)tmp1<<","<< (int)tmp2<<","<< (int)tmp3<<","<< (int)tmp4<<","<<std::endl; + if((tmp2 & 0x7f) == 0){ + if(tmp1+tmp3+tmp4 != 0) { + tmp1=tmp2=tmp3=0; + } + tmp2=0; + } + else tmp2--; + + i=(tmp2 << 24) + (tmp1 << 16) + (tmp4 << 8) + tmp3; + } + else{ + fs.read( (char*)&tmp1, 1 ); + fs.read( (char*)&tmp2, 1 ); + fs.read( (char*)&tmp3, 1 ); + fs.read( (char*)&tmp4, 1 ); + i=(tmp4 << 24) + (tmp3 << 16) + (tmp2 << 8 ) +tmp1; + } + dummy_value=(float*) &i; + value = *dummy_value; + return value; + } + + std::vector<double> odfIO::getSection(int start, int readSize, int section, + header &hd, std::ifstream &in){ + in.seekg(0,std::ios::beg); + std::vector<double> dataSec; + int block,skipped,channel,max; + size_t intsize = sizeof(int); + + dataSec.resize(readSize); + + block = start/125; + channel = start - block * 125; + block = hd.ifb + block * hd.numSection; + block--; + skipped=( block + (section-1) )*512; // skip 512 bytes per block + skipped += 4; // account for control word + skipped += channel*4; // and add channels not to read + in.ignore(skipped); // jump skipped-many bytes, alt: in.seekg(skipped,std::ios::cur); + + max = std::min(readSize,125-channel); + + int read = 0; + for(int i=0;i<max;i++){ + if( hd.mode == 3 ) dataSec[read] = readFloat(in,hd.unix); + else if( hd.mode == 1 ) dataSec[read] = readFloat(in,hd.unix); // needs to read integer not float + read++; + } + in.ignore(intsize*2); // skip over two ints in the block which contain no data + + while( read<readSize ){ + skipped=(hd.numSection-1)*512; // skip over other sections + in.ignore(skipped); + in.ignore(intsize); // discard control word + + for( int i=0; i<125 && read<readSize; i++ ) { + if( hd.mode == 3) dataSec[read] = readFloat(in,hd.unix); + else if(hd.mode == 1) dataSec[read] = readFloat(in,hd.unix); // needs to read integer not float + read++; + } + in.ignore(intsize*2); // skip over two ints in the block which contain no data + } + + return dataSec; + } + + void odfIO::readHeader(std::ifstream &in, header &head){ + size_t intsize = sizeof(int); + int bytes_per_block = 512; + int bytes_per_word = 4; + // comments based on OPRODF manual: Jack Craven, report no. ORNL/CSD/TM-45, 1978 + in.read( (char*)&head.mode, intsize ); // 0,1,3 for 18-bit ints, 36-bit ints, floating-point vals + in.read( (char*)&head.source, intsize ); // 0,1,2 for SEL, CSISRS, or ENDF/B data + in.read( (char*)&head.irun, intsize ); // run number + in.read( (char*)&head.ncblks, intsize ); // starting block no. for the comment section + in.read( (char*)&head.ncwrds, intsize ); // number of words in comment section + in.read( (char*)&head.nsblks, intsize ); // starting block for scalar section + in.read( (char*)&head.nswrds, intsize ); // number of words in scalar section + in.read( (char*)&head.ncstrt, intsize ); // starting word number of DAQ scalar and counter section in scalar section + in.read( (char*)&head.ncntrs, intsize ); // number of words in DAQ scalar and counter section + in.read( (char*)&head.nxstrt, intsize ); // starting word number of DAQ variable section in scalar section + in.read( (char*)&head.nxwrds, intsize ); // number of words in DAQ variable section + in.read( (char*)&head.npblks, intsize ); // starting block number of parameter section + in.read( (char*)&head.npwrds, intsize ); // number of words in parameter section + in.read( (char*)&head.ndtype, intsize ); // 0,1 for data section described by table in parameter section, data section is dependent on dataset 1 (i.e. datasets 2-x correspond to energy in dataset 1) + in.read( (char*)&head.numSection, intsize ); // number of sections in each dataset + in.read( (char*)&head.ifb, intsize ); // + in.read( (char*)&head.numChan, intsize ); // number of channels in each section + in.read( (char*)&head.zan, intsize ); // ENDF/B charge/mass id + in.read( (char*)&head.awr, intsize ); // ENDF/B ratio of nuclear mass (iso,ele,molec,mix) to neutron + in.read( (char*)&head.mat, intsize ); // ENDF/B MAT number + in.read( (char*)&head.mf, intsize ); // ENDF/B file number + in.read( (char*)&head.mt, intsize ); // ENDF/B reaction type + in.read( (char*)&head.varswt, intsize ); // 0,1 for dataset 1 decreasing, and increasing in value (ignored if ndtype is 0) + in.read( (char*)&head.dctswt, intsize ); // 0,1 for not dead-time corrected, and dead-time corrected + in.read( (char*)&head.strt, intsize ); // starting word number of each dataset in data section (mode 0 only) + in.read( (char*)&head.ndwend, intsize ); // ending word number of last word written in block NDBEND + + + /* the following doesn't work properly yet */ + // ------------------------------------ + // --- Read crunch table + // ------------------------------------ + // energy index table. each word contains the largest energy for each n blocks in the data set. N=(NDWRDS/125)+1 + head.ndtbl.resize(100); + for( int i=0;i<100;++i ) in.read( (char*)&head.ndtbl[i], intsize ); + // ------------------------------------ + // --- comments section --- + // ------------------------------------ + int bytes_to_comments = (head.ncblks) * bytes_per_block; + std::vector<unsigned char> comments; + int bytes_in_comments = head.ncwrds*bytes_per_word; + comments.resize( bytes_in_comments ); + + in.seekg(bytes_to_comments,std::ios::beg); + for( int i=0;i<bytes_in_comments;++i ){ + in.read( (char*)&comments[i], 1 ); + comments[i] = comments[i]; + } + // ------------------------------------ + // --- scalars section --- + // ------------------------------------ + int bytes_to_scalars = (head.nsblks) * bytes_per_block; + } + + void odfIO::printHeader(header &head){ + std::cout << "mode = " << head.mode << std::endl + << "source = " << head.source << std::endl + << "irun = " << head.irun << std::endl + << "ncblks = " << head.ncblks << std::endl + << "ncwrds = " << head.ncwrds << std::endl + << "nsblks = " << head.nsblks << std::endl + << "nswrds = " << head.nswrds << std::endl + << "ncstrt = " << head.ncstrt << std::endl + << "ncntrs = " << head.ncntrs << std::endl + << "nxstrt = " << head.nxstrt << std::endl + << "nxwrds = " << head.nxwrds << std::endl + << "npblks = " << head.npblks << std::endl + << "npwrds = " << head.npwrds << std::endl + << "ndtype = " << head.ndtype << std::endl + << "numSection = " << head.numSection << std::endl + << "ifb = " << head.ifb << std::endl + << "numChan = " << head.numChan << std::endl + << "zan = " << head.zan << std::endl + << "awr = " << head.awr << std::endl + << "mat = " << head.mat << std::endl + << "mf = " << head.mf << std::endl + << "mt = " << head.mt << std::endl + << "varswt = " << head.varswt << std::endl + << "dctswt = " << head.dctswt << std::endl + << "strt = " << head.strt << std::endl + << "ndwend = " << head.ndwend << std::endl; + + // for( int i=0;i<ndtbl.size();++i ){ + // std::cout << ndtbl[i] << " "; + // if( (i+1)%10==0 ) std::cout << std::endl; + // } + } + +} \ No newline at end of file diff --git a/sammy/src/io/odfIO.h b/sammy/src/io/odfIO.h new file mode 100644 index 0000000000000000000000000000000000000000..34f24b874ad98f036153d9fbc86fb37cb9b834b3 --- /dev/null +++ b/sammy/src/io/odfIO.h @@ -0,0 +1,68 @@ +#ifndef SAMMY_ODFIO_H +#define SAMMY_ODFIO_H + +#include <vector> +#include <fstream> // ifstream +#include <iostream> + +namespace sammy{ + + class odfIO { + + public: + odfIO(); + virtual ~odfIO() {} + + /**************************************** + * Object for ODF header info + ***************************************/ + struct header { + // variables explained in readHeader() + int mode, source, irun; + int ncblks, ncwrds, nsblks, nswrds, ncstrt, ncntrs, nxstrt, nxwrds; + int npblks, npwrds, ndtype, numSection, ifb, numChan; + int zan, awr, mat, mf, mt; // ENDF identifiers + int varswt,dctswt,strt,ndwend; + bool unix; + std::vector<int> ndtbl; + }; + + /**************************************** + * Read a single floating point value, based on whether it is in + * VAX-VMS format (?) or unix, from an ODF file + * + * @param fs a reference to the ODF file stream + * @param unix whether or not the format is unix-style + ***************************************/ + double readFloat(std::ifstream &fs, bool unix); + + /**************************************** + * Read one section of data. Sections are typcially energy, transmission, + * cross section, etc. + * + * @param start what channel to start in + * @param readSize how many channels to read + * @param section which section to read from + ***************************************/ + std::vector<double> getSection(int start, int readSize, int section, + header &hd, std::ifstream &in); + + /**************************************** + * Read the ODF header + * + * @param fs a reference to the ODF file stream + * @param head an ODF-header struct + ***************************************/ + void readHeader(std::ifstream &in, header &head); + + /**************************************** + * Print the ODF header + * + * @param head an ODF-header struct + ***************************************/ + void printHeader(header &head); + + }; +} + +#endif /* SAMMY_ODFIO_H */ \ No newline at end of file