/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*
*/
#include "MDpartEventV1724.h"
MDpartEventV1724::MDpartEventV1724(void *d):MDdataContainer(d){
UnValidate();
for (unsigned int ch=0; ch < V1724_NCHANNELS ; ch++) {
_sequence[ch]=NULL;
}
Init();
}
void MDpartEventV1724::Init(){
UnValidate();
unsigned int * header = Get32bWordPtr(0);
int index;
unsigned int length;
if (header) {
if ( (header[DWV1724_Header_Sync_Word] & DWV1724_Header_Sync_Mask) == DWV1724_Header_Sync ) {
Validate();
SetSize( GetWordCount() * V1724_WORD_SIZE );
//cout << "Size : " << dec << 4*GetWordCount() << " ( "
// << hex << showbase << 4*GetWordCount() << " ) " << dec << endl;
// find the number of non null bit in the channel mask:
_nChannels = 0;
for (unsigned int ch=0; ch < V1724_NCHANNELS ; ch++) {
_nChannels += (GetChannelMask()>>ch) & 0x00000001;
}
switch( GetZS() ) {
case 0:
{ // No zero length encoding. Life is easy.
length = (GetWordCount() - V1724_HEADER_WORDS)/_nChannels;
for (unsigned int ch=0; ch < V1724_NCHANNELS ; ch++) {
_length[ch] = ((GetChannelMask()>>ch) & 0x00000001)*length;
if ( _length[ch] ){
_sequence[ch] = Get32bWordPtr(V1724_HEADER_WORDS + ch*length);
if( _testCallBack )
_testCallBack( _sequence[ch][10] );
}
else _sequence[ch] = NULL;
// cout << " Init ch " << ch << " : " << _length[ch] << " ; " << _sequence[ch] << endl;
}
break;
}
case 1:
{ // Zero length encoding. That's a pain
index = V1724_HEADER_WORDS;
for (unsigned int ch=0; ch < V1724_NCHANNELS ; ch++) {
// Not tested !
// what if some channels are disabled ?
_sequence[ch] = Get32bWordPtr(index);
_length[ch] += _sequence[ch][0];
index +=_length[ch];
}
break;
}
case 7 :
{
index = V1724_HEADER_WORDS;
for (unsigned int ch=0; ch < V1724_NCHANNELS ; ch++) {
unsigned int * ch_ptr = Get32bWordPtr(index);
unsigned int ch_code = (*ch_ptr & DWV1724_Header_ZS_Channel_Mask) >> DWV1724_Header_ZS_Channel_Shift;
int l = *ch_ptr & DWV1724_Header_ZS_Length_Mask;
if(ch!=ch_code)
throw MDexception("ERROR in MDpartEventV1724::Init: Channel number mismatch in ZS mode.");
if(l)_sequence[ch] = Get32bWordPtr(index+1);
_length[ch] = l;
index += l+1;
}
break;
}
default:
{ // Invalid data structure
throw MDexception("ERROR in MDpartEventV1724::Init: Unexpected ZS code.");
}
}
} else {
//cout << "Data Word : " << hex << showbase << Get32bWordPtr(0) << dec << noshowbase << endl;
throw MDexception("ERROR in MDpartEventV1724::Init: INVALID particle Event");
}
}
}
void MDpartEventV1724::SetDataPtr( void *d ) {
MDdataContainer::SetDataPtr(d);
Init();
}
unsigned int MDpartEventV1724::GetWordCount(){
if (IsValid()) {
unsigned int * header = Get32bWordPtr(0);
return ( header[DWV1724_Header_WordCount_Word] & DWV1724_Header_WordCount_Mask ) >> DWV1724_Header_WordCount_Shift;
} else {
return 0;
}
}
unsigned int MDpartEventV1724::GetGeo(){
if (IsValid()) {
unsigned int * header = Get32bWordPtr(0);
return ( header[DWV1724_Header_Geo_Word] & DWV1724_Header_Geo_Mask ) >> DWV1724_Header_Geo_Shift;
} else {
return 0;
}
}
int MDpartEventV1724::GetZS(){
if (IsValid()) {
unsigned int * header = Get32bWordPtr(0);
return ( header[DWV1724_Header_ZS_Word] & DWV1724_Header_ZS_Mask ) >> DWV1724_Header_ZS_Shift;
} else {
return -1;
}
}
unsigned int MDpartEventV1724::GetPattern(){
if (IsValid()) {
unsigned int * header = Get32bWordPtr(0);
return ( header[DWV1724_Header_Pattern_Word] & DWV1724_Header_Pattern_Mask ) >> DWV1724_Header_Pattern_Shift;
} else {
return 0;
}
}
unsigned int MDpartEventV1724::GetChannelMask(){
if (IsValid()) {
unsigned int * header = Get32bWordPtr(0);
return ( header[DWV1724_Header_ChannelMask_Word] & DWV1724_Header_ChannelMask_Mask ) >> DWV1724_Header_ChannelMask_Shift;
} else {
return 0;
}
}
unsigned int MDpartEventV1724::GetEventCounter(){
if (IsValid()) {
unsigned int * header = Get32bWordPtr(0);
return ( header[DWV1724_Header_EventCounter_Word] & DWV1724_Header_EventCounter_Mask ) >> DWV1724_Header_EventCounter_Shift;
} else {
return 0;
}
}
unsigned int MDpartEventV1724::GetTriggerTimeTag(){
if (IsValid()) {
unsigned int * header = Get32bWordPtr(0);
return ( header[DWV1724_Header_TriggerTimeTag_Word] & DWV1724_Header_TriggerTimeTag_Mask ) >> DWV1724_Header_TriggerTimeTag_Shift;
} else {
return 0;
}
}
int16_t MDpartEventV1724::GetSampleData( unsigned short aChannel , unsigned long aSample ) {
if ( aChannel >= V1724_NCHANNELS ) return 0;
if ( aSample >= GetLength(aChannel)*2 ) return 0;
if ( _length[aChannel] == 0 ) return 0;
MDdataWordV1724 dw1724;
if ( _sequence[aChannel] ) {
dw1724.SetDataPtr( &_sequence[aChannel][aSample/2] );
if ( dw1724.IsValid() ) return dw1724.GetSample(aSample%2);
}
return 0;
}
void MDpartEventV1724::Dump(int atTheTime){
cout << *this;
return;
}
////////////////////////////////////////////////////////////////////////
ostream &operator<<(ostream &s,MDpartEventV1724 &dw){
MDdataWordV1724 dw1724;
s << showbase << hex;
s << " ------------ CAEN V1724 Header ------------ " << endl ;
s << " Word Count : " << dec << dw.GetWordCount() << endl;
s << " Geo : " << dw.GetGeo() ;
int zs = dw.GetZS();
if ( zs ) s << " ; ZS enabled (" << zs << ")";
else s << " ; ZS disabled" ;
s << " ; Channel Mask : " << showbase << hex << dw.GetChannelMask() << endl;
s << " Event Counter : " << dec << dw.GetEventCounter() << endl;
s << " Trigger Time Tag : " << dw.GetTriggerTimeTag() << endl;
s << " ------------ End of CAEN V1724 Header ----------- " << endl ;
// unsigned int nSamplePerChannel = 512;
// unsigned int nWordPerChannel = nSamplePerChannel/2 ; // two samples per word
if ( dw.GetZS() == 0 ) {
unsigned int expectWordCount( dw.GetNChannels()* dw.GetLength(0) + V1724_HEADER_WORDS );
if ( expectWordCount != dw.GetWordCount() ) {
s << " *** ERROR in CAEN V1724 data format: Word count is not consistent *** " << endl ;
}
for (unsigned int ch=0; ch < V1724_NCHANNELS ; ch++) {
s << " ---------- Channel " << dec << ch << " ( Length = " << dw.GetLength(ch) << " ) ---------- " << endl ;
for ( unsigned int iw=0; iw