ConvertData.cc
00001 #include "ConvertData.hh"
00002 #include "V172X_Event.hh"
00003 #include "V172X_Params.hh"
00004 #include "RootWriter.hh"
00005 #include "EventHandler.hh"
00006 #include "runinfo.hh"
00007 #include "ConfigHandler.hh"
00008 #include <vector>
00009
00010
00011 ConvertData::ConvertData():
00012 BaseModule(GetDefaultName(),
00013 "Convert the binary data to useable vectors and timestamps")
00014 {
00015 RegisterParameter("offset_channels", _offsets,
00016 "map of channelid:offset time to apply for analysis");
00017 _v172X_params = 0;
00018 _headers_only = false;
00019 }
00020
00021 ConvertData::~ConvertData()
00022 {
00023
00024 }
00025
00026 int ConvertData::Initialize()
00027 {
00028 start_time = 0;
00029 previous_event_time = 0;
00030 _id_mismatches = 0;
00031 ConfigHandler* config = ConfigHandler::GetInstance();
00032
00033
00034 if(!_v172X_params)
00035 _v172X_params = dynamic_cast<V172X_Params*>
00036 (config->GetParameter(V172X_Params().GetDefaultKey()));
00037
00038 bool err = 0;
00039 if(config->GetSavedCfgFile() != "")
00040 err = config->LoadCreateParameterList(_v172X_params);
00041 if(_v172X_params){
00042 Message(DEBUG)<<"Number of V172X boards in this run: "
00043 <<_v172X_params->GetEnabledBoards()<<"\n";
00044
00045 for(int i=0; i<_v172X_params->GetEnabledBoards(); i++){
00046 V172X_BoardParams& board = _v172X_params->board[i];
00047 board.UpdateBoardSpecificVariables();
00048 }
00049
00050 _v172X_params->GetEventSize();
00051 }
00052
00053
00054 if(!_v172X_params){
00055 Message(ERROR)<<"Unable to load saved configuration information!\n";
00056 return 1;
00057 }
00058
00059 _info = EventHandler::GetInstance()->GetRunInfo();
00060
00061 return 0;
00062 }
00063
00064 int ConvertData::Finalize()
00065 {
00066
00067 _v172X_params = 0;
00068 if(_id_mismatches){
00069 Message(WARNING)<<_id_mismatches<<" events had mismatched IDs!\n";
00070 }
00071 return 0;
00072 }
00073
00074 const uint64_t ns_per_s = 1000000000;
00075 int ConvertData::Process(EventPtr event)
00076 {
00077 RawEventPtr raw = event->GetRawEvent();
00078 EventDataPtr data = event->GetEventData();
00079
00080
00081 data->event_id = raw->GetID();
00082 data->timestamp = raw->GetTimestamp();
00083 if(start_time == 0){
00084
00085 start_time = data->timestamp;
00086 }
00087
00088 data->event_time = 1000000000*(data->timestamp-start_time);
00089
00090 data->channels.clear();
00091 for(size_t blocknum=0; blocknum<raw->GetNumDataBlocks(); blocknum++){
00092 switch(raw->GetDataBlockType(blocknum)){
00093 case RawEvent::CAEN_V172X :
00094 DecodeV172XData(raw->GetRawDataBlock(blocknum),
00095 raw->GetDataBlockSize(blocknum),
00096 data);
00097 break;
00098 case RawEvent::MONTECARLO :
00099 default :
00100 Message(ERROR)<<"Decoding has not yet been implemented for block type "
00101 <<raw->GetDataBlockType(blocknum)<<"\n";
00102 continue;
00103 }
00104 }
00105
00106 if(!_headers_only){
00107 data->nchans = data->channels.size();
00108
00109 for(int ch=0; ch<data->nchans; ch++)
00110 {
00111 ChannelData& chdata = data->channels[ch];
00112 double* wave = chdata.GetWaveform();
00113 double* max_samp = std::max_element(wave, wave+chdata.nsamps);
00114 double* min_samp = std::min_element(wave, wave+chdata.nsamps);
00115
00116 chdata.saturated = (*min_samp == 0 ||
00117 *max_samp == chdata.GetVerticalRange());
00118 if(chdata.saturated) data->saturated = true;
00119 chdata.maximum = *max_samp;
00120 chdata.minimum = *min_samp;
00121 chdata.max_time = chdata.SampleToTime(max_samp - wave);
00122 chdata.min_time = chdata.SampleToTime(min_samp - wave);
00123
00124
00125 int chinfo=0;
00126
00127
00128 if(chinfo)
00129 chdata.spe_mean = 1;
00130 else
00131 {
00132 chdata.spe_mean = 1;
00133 bool fail = EventHandler::GetInstance()->GetFailOnBadCal();
00134 if(fail){
00135 Message(ERROR)<<"No calibration info for channel "
00136 <<chdata.channel_id<<" in event "
00137 <<data->event_id<<" in run "<<data->run_id<<"\n";
00138 return -1;
00139 }
00140 }
00141
00142
00143
00144 }
00145 data->nchans = data->channels.size();
00146 }
00147
00148 data->dt = ( previous_event_time > 0 ?
00149 data->event_time - previous_event_time : 0 );
00150 previous_event_time = data->event_time;
00151
00152
00153 _info->starttime = start_time;
00154 _info->endtime = data->timestamp;
00155 _info->events = data->event_id+1;
00156 _info->triggers = data->trigger_count+1;
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 return 0;
00168 }
00169
00170 int ConvertData::DecodeV172XData(const unsigned char* rawdata,
00171 uint32_t datasize,
00172 EventDataPtr data)
00173 {
00174 V172XEventPtr v172X(new V172X_Event(rawdata,
00175 datasize,
00176 _v172X_params) );
00177 const V172X_Params* params = v172X->GetParameters();
00178 int n_boards = v172X->GetNBoards();
00179
00180 int reserve_size = (params->enabled_channels > 0 ? params->enabled_channels :
00181 n_boards * 10 );
00182 data->channels.reserve( reserve_size + 5);
00183 bool id_mismatch=false;
00184 for(int i=0; i<n_boards; i++){
00185 const V172X_BoardData& board_data = v172X->GetBoard(i);
00186 const V172X_BoardParams& board_params =
00187 params->board[board_data.board_id];
00188
00189 if(i==0)
00190 data->trigger_count = board_data.event_counter;
00191 else if(board_data.event_counter != (uint32_t)data->trigger_count){
00192 id_mismatch = true;
00193 }
00194
00195 uint64_t s_since_start = data->timestamp - start_time;
00196
00197 if(board_data.timestamp * board_params.ns_per_clocktick <
00198 board_params.GetTimestampRange()/2)
00199 s_since_start+=board_params.GetTimestampRange()/ns_per_s/4;
00200 else
00201 s_since_start-=board_params.GetTimestampRange()/ns_per_s/4;
00202 uint64_t n_resets = (s_since_start * ns_per_s)/
00203 ( board_params.GetTimestampRange());
00204
00205
00206
00207
00208
00209
00210 data->event_time = board_params.GetTimestampRange() * n_resets +
00211 board_params.ns_per_clocktick * board_data.timestamp;
00212 for(int j=0; j<board_data.nchans; j++){
00213 if(board_data.channel_start[j] == NULL)
00214 continue;
00215 int channel_id = board_data.nchans * board_data.board_id + j;
00216 if( _skip_channels.find(channel_id) != _skip_channels.end())
00217 continue;
00218 const V172X_ChannelParams& ch_params = board_params.channel[j];
00219 data->channels.push_back(ChannelData());
00220 ChannelData& chdata = data->channels.back();
00221 chdata.board_id = board_data.board_id;
00222 chdata.board_num = i;
00223 chdata.channel_num = j;
00224 chdata.channel_id = channel_id;
00225 chdata.label = ch_params.label;
00226 chdata.timestamp = board_data.timestamp * 10;
00227 chdata.sample_bits = board_params.sample_bits;
00228 chdata.sample_rate = board_params.GetSampleRate();
00229 chdata.trigger_index = board_params.GetTriggerIndex() -
00230 (int)(GetChOffset(channel_id) * chdata.sample_rate);
00231
00232
00233 if(_headers_only) continue;
00234 chdata.channel_start = (char*)(board_data.channel_start[j]);
00235 chdata.channel_end = (char*)(board_data.channel_end[j]);
00236 if(board_params.zs_type != ZLE){
00237
00238 if(chdata.sample_bits < 9)
00239 chdata.waveform.assign((uint8_t*)chdata.channel_start,
00240 (uint8_t*)chdata.channel_end);
00241 else if (chdata.sample_bits == 10) {
00242 chdata.waveform.clear ();
00243 for (uint32_t* ptr = (uint32_t*)chdata.channel_start;
00244 ptr < (uint32_t*)chdata.channel_end; ptr ++) {
00245 uint32_t raw_v = *ptr;
00246 const int ns = (raw_v>>30)&3;
00247 for (int i = 0; i < ns; i++) {
00248 uint16_t sample = raw_v & 0x3ff;
00249 raw_v = raw_v >> 10;
00250 chdata.waveform.push_back (sample);
00251 }
00252 }
00253 }
00254 else if(chdata.sample_bits < 17)
00255 chdata.waveform.assign((uint16_t*)chdata.channel_start,
00256 (uint16_t*)chdata.channel_end);
00257 else
00258 chdata.waveform.assign((uint32_t*)chdata.channel_start,
00259 (uint32_t*)chdata.channel_end);
00260 }
00261 else{
00262
00263
00264 uint32_t nwords = *((uint32_t*)(chdata.channel_start));
00265 chdata.nsamps = 0;
00266 uint32_t offset = 1;
00267 std::vector<const char*> data_blocks;
00268 while(offset < nwords){
00269
00270 uint32_t control = *( ((uint32_t*)(chdata.channel_start)) + offset);
00271 uint32_t subwords = control & 0x1FFFFF;
00272 uint32_t subsamps = subwords * board_params.bytes_per_sample;
00273 bool good = control & 0x80000000;
00274
00275 if(good){
00276 data_blocks.push_back( chdata.channel_start + 4*(offset+1) );
00277 std::pair<int,int> region(chdata.nsamps,
00278 chdata.nsamps + subsamps);
00279 chdata.unsuppressed_regions.push_back(region);
00280 offset += subwords;
00281 }
00282
00283 chdata.nsamps += subsamps;
00284 offset += 1;
00285 }
00286
00287 chdata.waveform.assign(chdata.nsamps, 1);
00288 std::vector<double>& wave = chdata.waveform;
00289
00290 for(size_t block=0; block < data_blocks.size(); block++){
00291 int subsamps = chdata.unsuppressed_regions[block].second -
00292 chdata.unsuppressed_regions[block].first;
00293 if(chdata.sample_bits < 9){
00294 std::copy( (uint8_t*)data_blocks[block],
00295 ((uint8_t*)data_blocks[block]) + subsamps,
00296 &(wave[chdata.unsuppressed_regions[block].first]) );
00297 }
00298 else if (chdata.sample_bits < 17){
00299 std::copy( (uint16_t*)data_blocks[block],
00300 ((uint16_t*)data_blocks[block]) + subsamps,
00301 &(wave[chdata.unsuppressed_regions[block].first]) );
00302 }
00303 else {
00304 std::copy( (uint32_t*)data_blocks[block],
00305 ((uint32_t*)data_blocks[block]) + subsamps,
00306 &(wave[chdata.unsuppressed_regions[block].first]) );
00307 }
00308 }
00309
00310 for(size_t block=0; block < data_blocks.size(); block++){
00311 std::pair<int,int> region = chdata.unsuppressed_regions[block];
00312 int fill_start = (block > 0 ?
00313 chdata.unsuppressed_regions[block-1].second : 0 );
00314 int fill_end = region.first;
00315 if(fill_end > fill_start)
00316 std::fill( &(wave[fill_start]), &(wave[fill_end]), wave[fill_end]);
00317 }
00318
00319 if( !chdata.unsuppressed_regions.empty() &&
00320 chdata.unsuppressed_regions.back().second < chdata.nsamps){
00321 std::fill( &(wave[chdata.unsuppressed_regions.back().second]),
00322 &(wave[chdata.nsamps]),
00323 wave[chdata.unsuppressed_regions.back().second-1] );
00324 }
00325 }
00326 chdata.nsamps = chdata.waveform.size();
00327 }
00328 }
00329 if(id_mismatch){
00330 if(_id_mismatches==0){
00331 Message(WARNING)<<"Event ID mismatch found on event "
00332 <<data->event_id<<"!\n";
00333 Message(WARNING)<<"Further mismatches will be silent.\n";
00334 }
00335
00336 data->status |= EventData::ID_MISMATCH;
00337 _id_mismatches++;
00338 }
00339
00340 return 0;
00341 }
00342