00001 #include "RawBeamSwicData.h" 00002 00003 #include <iostream> 00004 using namespace std; 00005 00006 ClassImp(RawBeamSwicData) 00007 00008 RawBeamSwicData::RawBeamSwicData() 00009 { 00010 fData.SetData(0); 00011 } 00012 00013 RawBeamSwicData::RawBeamSwicData(const RawBeamData& data) 00014 { 00015 this->SetData(data); 00016 } 00017 00018 RawBeamSwicData::~RawBeamSwicData() 00019 { 00020 fData.SetData(0); 00021 } 00022 00023 RawBeamData& RawBeamSwicData::GetData() 00024 { 00025 return fData; 00026 } 00027 const RawBeamData& RawBeamSwicData::GetData() const 00028 { 00029 return fData; 00030 } 00031 bool RawBeamSwicData::SetData(const RawBeamData& data) 00032 { 00033 fData = data; 00034 00035 if (!fData.GetData()) return false; 00036 00037 // Sanity checks 00038 const size_t swic_data_size = 216; 00039 const size_t siz = fData.GetDataLength(); 00040 if (siz != swic_data_size) { 00041 cerr << "Not right size: 216 != " << siz << endl; 00042 fData.SetData(0); 00043 return false; 00044 } 00045 00046 return true; 00047 } 00048 00049 bool RawBeamSwicData::IsValid() const 00050 { 00051 return fData.GetData() != 0; 00052 } 00053 00054 00055 // This stuff is from SwicScaled from Jim Patrick @ FNAL 00056 00057 /* 00058 Example of reading and displaying SWIC display buffer. 00059 The data comes from the front-end as an array of 00060 216 (16 bit) shorts. The control system converts ("scales") 00061 this into an array of 216 doubles by the transformation: 00062 readings[i] = (double) ((10. * (double)raw[i]) / 32767.) 00063 (This transformation is specified in the definition 00064 of the device in the device database). 00065 In order to interpret the data properly, it 00066 is necessary to invert this transformation. 00067 Furthermore, the data is not simply an array of 00068 shorts, but a structure that contains some floats 00069 and (32 bit) longs as well. Hence it is necessary 00070 to combine some of the short elements to get 00071 the correct data. See the "readings" method below. 00072 */ 00073 00074 /* Note all RawBeamData comes over the wire as 32 bit ints. In the 00075 * case of things that are scaled doubles in XML-RPC, they are 00076 * downcasted to floats, memcpy'ed to ints, then packed in to raw 00077 * blocks and sent to rotorooter. 00078 */ 00079 00080 // Offsets defining elements of the structure 00081 00082 // First part of the structure is a set of 8 blocks 00083 // of calculation results. 00084 static const int CALCULATION_OFFSET = 0; 00085 static const int CALCULATION_BLOCK_COUNT = 8; 00086 // Offsets within one of the 8 calculation blocks 00087 // Flags for what was calculated; each a "short" 00088 static const int MEAN_FLAG_OFFSET = 0; 00089 static const int SIGMA_FLAG_OFFSET = 1; 00090 static const int INTENSITY_FLAG_OFFSET = 2; 00091 static const int FOM_FLAG_OFFSET = 3; // "Figure of merit" 00092 static const int STATUS_FLAG_OFFSET = 4; 00093 // Actual calculation results 00094 // These are 32 bit "floats" and have to be constructed 00095 // from 2 of the returned array elements 00096 static const int MEAN_OFFSET = 5; 00097 static const int SIGMA_OFFSET = 7; 00098 static const int INTENSITY_OFFSET = 9; 00099 static const int FOM_OFFSET = 11; 00100 00101 static const int CALCULATION_BLOCK_LENGTH = 13; 00102 00103 // The raw data 00104 static const int RAW_OFFSET = CALCULATION_BLOCK_LENGTH * CALCULATION_BLOCK_COUNT + CALCULATION_OFFSET; 00105 static const int RAW_LENGTH = 96; 00106 00107 // Flag indicating position of chamber (in/out/unknown/etc.) 00108 static const int POSITION_OFFSET = 200; 00109 // Timestamp block 00110 // Only the GPS timestamp is relevant for non-miniBoone SWICs 00111 static const int EVENT8FTIMESTAMP_OFFSET = 201; 00112 // The first 2 words are combined to form a 32 bit seconds since 1/1/70 00113 // The second 2 words are combined to form a ns offset to the above 00114 static const int GPSTIMESTAMP_OFFSET = EVENT8FTIMESTAMP_OFFSET + 4; 00115 // Below not generally filled in except for miniBoone 00116 static const int SAMPLEEVENT_OFFSET = GPSTIMESTAMP_OFFSET + 4; 00117 static const int RESETEVENT_OFFSET = SAMPLEEVENT_OFFSET + 1; 00118 static const int N0CEVENT_OFFSET = RESETEVENT_OFFSET + 1; 00119 static const int MILLISLASTMI_OFFSET = N0CEVENT_OFFSET + 1; 00120 static const int N1DEVENTMIRESET_OFFSET = MILLISLASTMI_OFFSET + 1; 00121 static const int N1DEVENT00_OFFSET = N1DEVENTMIRESET_OFFSET + 1; 00122 00123 /* 00124 block 0 = horizontal chamber results 00125 block 1 = vertical chamber results 00126 block 2 = unused 00127 block 3 = unused 00128 block 4 = unused 00129 block 5 = unused 00130 block 6 = unused 00131 block 7 = unused 00132 */ 00133 static const int HORIZONTAL_BLOCK_NUMBER = 0; 00134 static const int VERTICAL_BLOCK_NUMBER = 1; 00135 00136 00137 00138 int unscale(const double& d) 00139 { 00140 // double temp_needed_to_avoid_gcc_bug = d*32767./10.; 00141 // return (int)temp_needed_to_avoid_gcc_bug; 00142 return (int)(d*32767.001/10.); 00143 } 00144 00145 // upper-lower to integer 00146 int ul2int(const double& d1, const double& d2) 00147 { 00148 int id1 = unscale(d1); 00149 int id2 = unscale(d2); 00150 return (id1<<16)+(id2&0xffff); 00151 } 00152 00153 00154 00155 int RawBeamSwicData::VmeSeconds() const 00156 { 00157 const double* data = fData.GetData(); 00158 return ul2int(data[GPSTIMESTAMP_OFFSET], 00159 data[GPSTIMESTAMP_OFFSET+1]); 00160 } 00161 00162 int RawBeamSwicData::VmeNanoseconds() const 00163 { 00164 const double* data = fData.GetData(); 00165 return ul2int(data[GPSTIMESTAMP_OFFSET+2], 00166 data[GPSTIMESTAMP_OFFSET+3]); 00167 } 00168 00169 void RawBeamSwicData::UnscaledWireData(vector<int>& wd) const 00170 { 00171 const double* data = fData.GetData(); 00172 for (int ind=0; ind < RAW_LENGTH; ++ind) { 00173 wd.push_back(unscale(data[RAW_OFFSET+ind])); 00174 } 00175 } 00176 void RawBeamSwicData::ScaledWireData(vector<double>& wd) const 00177 { 00178 const double* data = fData.GetData(); 00179 for (int ind=0; ind < RAW_LENGTH; ++ind) { 00180 wd.push_back(data[RAW_OFFSET+ind]); 00181 } 00182 }
1.3.9.1