Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "OdfIO.h"
namespace sammy{
OdfIO::OdfIO() {}
double OdfIO::readFloat(std::istream &fs, bool unix){
unsigned char tmp1,tmp2,tmp3,tmp4;
int i=0;
float 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 );
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;
}
// grab int pointer, cast to float, dereference
value = *reinterpret_cast<float *>( &i );
return (double)value;
}
int OdfIO::readInteger(std::istream &fs){
size_t intsize = sizeof(int);
int val;
fs.read( (char*)&val, intsize );
return val;
}
std::vector<double> OdfIO::getSection(int start, int readSize, int section,
std::istream &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 = head["ifb"] + block * head["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( head["mode"] == 3 ) dataSec[read] = readFloat(in,head["unix"]);
else if( head["mode"] == 1 ) dataSec[read] = readInteger(in);
read++;
}
in.ignore(intsize*2); // skip over two ints in the block which contain no data
while( read<readSize ){
skipped=(head["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( head["mode"] == 3) dataSec[read] = readFloat(in,head["unix"]);
else if(head["mode"] == 1) dataSec[read] = readInteger(in);
read++;
}
in.ignore(intsize*2); // skip over two ints in the block which contain no data
}
return dataSec;
}
std::vector<std::vector<double>> OdfIO::getAllSections(std::istream &in){
// --- go to start of file ---
in.seekg(0, std::ios::beg);
std::vector<std::vector<double>> data;
data.resize(head["numSection"]);
// --- grab each section ---
for( int section=1; section<=head["numSection"]; ++section ){
data[section-1].resize(head["numChan"]);
data[section-1] = getSection(0,head["numChan"],section,in);
}
return data;
}
void OdfIO::readHeader(std::istream &in, int unix){
size_t intsize = sizeof(int);
int bytes_per_block = 512;
int bytes_per_word = 4;
head["unix"] = unix;
// comments based on OPRODF manual: Jack Craven, report no. ORNL/CSD/TM-45, 1978
// ** keep in mind that changes may have happened between that report and
// ** the writing of the files!!! For example it seems that 36 bit ints are no
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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
/* TODO: the following doesn't work properly yet, we ignore for now */
// ------------------------------------
// --- Read crunch table
// ------------------------------------
// energy index table. each word contains the largest energy for each n blocks in the data set. N=(NDWRDS/125)+1
ndtbl.resize(100);
for( int i=0;i<100;++i ) in.read( (char*)&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);
in.ignore(bytes_per_word);
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(){
for( auto member : head ){
std::cout << member.first << " = " << head[member.first] << std::endl;
}
}
}