// Author: Andrew M. Rogers, NSCL 07/01/2006
// Original Design: Daniel Bazin, NSCL
//* Copyright (C) 2006-2008 Andrew M. Rogers

#include "TS800Tppac.h"


#include <TBranch.h>
#include <iostream>
#include <math.h>

#include <TNamed.h>
#include <TList.h>

ClassImp(TS800Tppac);

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TS800Tppac                                                           //
//                                                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

static const UShort_t tppacmapx[64]={30,31,28,29,26,27,24,25,22,23,20,21,18,19,16,17,14,15,12,13,10,11,8,9,6,7,4,5,2,3,0,1,33,32,35,34,37,36,39,38,41,40,43,42,45,44,47,46,49,48,51,50,53,52,55,54,57,56,59,58,61,60,63,62};
static const UShort_t tppacmapy[64]={0,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,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32};


//______________________________________________________________________________
TS800Tppac::TS800Tppac(const TS800Tppac & p) : TObject(p)
{
  // -- Copy Constructor.


}

//______________________________________________________________________________
Int_t TS800Tppac::Calculate(Long64_t entry)
{
  // --
  //

  Double_t maxpad = 0, mom = 0;
  Int_t i, padmax=-1, lowpad, highpad, bad = 0;

  Clear();

  // x plane
  for (i=0; i<64; i++) {
    if (xstrip[i] > maxpad) {
      maxpad = xstrip[i];
      padmax = i;
    }
  }
  lowpad  = padmax - (Int_t)width/2;
  highpad = lowpad + (Int_t)width - 1;
  if (lowpad < 0) {
    lowpad  = 0;
    highpad = padmax + (Int_t)width/2;
  }
  else if (highpad >= 64) {
    highpad = 63;
    lowpad  = padmax - (Int_t)width/2;
  }
  xsum = 0;
  mom  = 0;
  
  // Reject bad pads stored in the badpad array
  for (Int_t i=lowpad; i<= highpad; i++) {
    bad = 0;
    for (Int_t j=0; j<badxstrips; j++) {
      if (i == badxstrip[j]) bad = 1;
    }
    if (bad == 0) {
      xsum += xstrip[i];
      mom  += i*xstrip[i];
    }
  }
  x = (mom / xsum)*1.27 - xcenter; // The pitch of the strips is 1/20"
  
  // y plane
  for (Int_t i=0; i<64; i++) {
    if 	(ystrip[i] > maxpad) {
      maxpad = ystrip[i];
      padmax = i;
    }
  }
  lowpad  = padmax - (Int_t)width/2;
  highpad = lowpad + (Int_t)width - 1;
  if (lowpad < 0) {
    lowpad  = 0;
    highpad = padmax + (Int_t)width/2;
  }
  else if (highpad >= 64) {
    highpad = 63;
    lowpad  = padmax - (Int_t)width/2;
  }
  ysum = 0;
  mom  = 0;
  
  // Reject bad pads stored in the badpad array
  for (Int_t i=lowpad; i<= highpad; i++) {
    bad = 0;
    for (Int_t j=0; j<badystrips; j++) {
      if (i == badystrip[j]) bad = 1;
    }
    if (bad == 0) {
      ysum += ystrip[i];
      mom  += i*ystrip[i];
    }
  }
  y = (mom / ysum)*1.27 - ycenter; // The pitch of the strips is 1/20"
  
  //  printf("%s is now calculated.",name);
  return 1;
}


//______________________________________________________________________________
//void TS800Tppac::Calculate()
// {
//   // --
//   //

//   Double_t maxpad = 0, mom = 0;
//   Int_t i, padmax=-1, lowpad, highpad, bad = 0;

//   b_x->Reset();
//   b_y->Reset();
//   b_xsum->Reset();
//   b_ysum->Reset();

//   for(Long64_t k=0; k<fChain->GetEntriesFast(); k++){
//     Clear();

//     b_xstrip->GetEntry(k);
//     b_ystrip->GetEntry(k);

//     // x plane
//     for (i=0; i<64; i++) {
//       if (xstrip[i] > maxpad) {
// 	maxpad = xstrip[i];
// 	padmax = i;
//       }
//     }
//     lowpad  = padmax - (Int_t)width/2;
//     highpad = lowpad + (Int_t)width - 1;
//     if (lowpad < 0) {
//       lowpad  = 0;
//       highpad = padmax + (Int_t)width/2;
//     }
//     else if (highpad >= 64) {
//       highpad = 63;
//       lowpad  = padmax - (Int_t)width/2;
//     }
//     xsum = 0;
//     mom  = 0;

//     // Reject bad pads stored in the badpad array
//     for (Int_t i=lowpad; i<= highpad; i++) {
//       bad = 0;
//       for (Int_t j=0; j<badxstrips; j++) {
// 	if (i == badxstrip[j]) bad = 1;
//       }
//       if (bad == 0) {
// 	xsum += xstrip[i];
// 	mom  += i*xstrip[i];
//       }
//     }
//     x = (mom / xsum)*1.27 - xcenter; // The pitch of the strips is 1/20"

//     // y plane
//     for (Int_t i=0; i<64; i++) {
//       if 	(ystrip[i] > maxpad) {
// 	maxpad = ystrip[i];
// 	padmax = i;
//       }
//     }
//     lowpad  = padmax - (Int_t)width/2;
//     highpad = lowpad + (Int_t)width - 1;
//     if (lowpad < 0) {
//       lowpad  = 0;
//       highpad = padmax + (Int_t)width/2;
//     }
//     else if (highpad >= 64) {
//       highpad = 63;
//       lowpad  = padmax - (Int_t)width/2;
//     }
//     ysum = 0;
//     mom  = 0;
  
//     // Reject bad pads stored in the badpad array
//     for (Int_t i=lowpad; i<= highpad; i++) {
//       bad = 0;
//       for (Int_t j=0; j<badystrips; j++) {
// 	if (i == badystrip[j]) bad = 1;
//       }
//       if (bad == 0) {
// 	ysum += ystrip[i];
// 	mom  += i*ystrip[i];
//       }
//     }
//     y = (mom / ysum)*1.27 - ycenter; // The pitch of the strips is 1/20"

//     b_x->Fill();
//     b_y->Fill();
//     b_xsum->Fill();
//     b_ysum->Fill();
//   }

//   //  printf("%s is now calculated.",name);
// }


//______________________________________________________________________________
Int_t TS800Tppac::Calibrate(Long64_t entry)
{
  // --
  //

  Int_t    index;
  Float_t  sum[256];
  Int_t    samples[256];

  Clear();

  fCon->b_filled->GetEntry(entry);
  fCon->b_channel->GetEntry(entry);
  fCon->b_data->GetEntry(entry);
  
  bzero(samples, sizeof(samples));
  memset(sum, 0, sizeof(sum));
  
  // Integrate samples into strips
  xmult = 0;
  ymult = 0;
  //    if( filled>0)cout << "filled: " << filled << endl;
  for (Int_t f=0; f<fCon->filled; f++) {
    index = fCon->channel[f];
    if(index<64){
      xstrip[index] += fCon->data[f];
      samples[index]++;
    }
    if(index>=64 && index<128){
      ystrip[index - 64] += fCon->data[f];
      //	cout << ystrip[index-64] << " " << data[f] << endl;
      samples[index]++;
    }
  }
  
  for(Int_t i=0; i<64; i++){
    if (xstrip[i] > 0) xmult++;
    if (ystrip[i] > 0) ymult++;
  }
  //cout << name << " is now calibrated.\n";
  return 1;
}


//______________________________________________________________________________
//void TS800Tppac::Calibrate()
// {
//   // --
//   //

//   Int_t    index;
//   Float_t  sum[256];
//   Int_t    samples[256];
  
//   b_xstrip->Reset();
//   b_ystrip->Reset();
//   b_xmult->Reset();
//   b_ymult->Reset();

//   for(Long64_t i=0; i<fChain->GetEntries(); i++){
//     Clear();

//     b_filled->GetEntry(i);
//     b_channel->GetEntry(i);
//     b_data->GetEntry(i);

//     bzero(samples, sizeof(samples));
//     memset(sum, 0, sizeof(sum));

//     // Integrate samples into strips
//     xmult = 0;
//     ymult = 0;
//     //    if( filled>0)cout << "filled: " << filled << endl;
//     for (Int_t f=0; f<filled; f++) {
//       index = channel[f];
//       if(index<64){
// 	xstrip[index] += data[f];
// 	samples[index]++;
//       }
//       if(index>=64 && index<128){
//  	ystrip[index - 64] += data[f];
// 	//	cout << ystrip[index-64] << " " << data[f] << endl;
//  	samples[index]++;
//       }
//     }

//     for(Int_t i=0; i<64; i++){
//       if (xstrip[i] > 0) xmult++;
//       if (ystrip[i] > 0) ymult++;
//     }

//     b_xstrip->Fill();
//     b_ystrip->Fill();
//     b_xmult->Fill();
//     b_ymult->Fill();
//   }

//   cout << name << " is now calibrated.\n";
// }


//______________________________________________________________________________
void TS800Tppac::Copy(TObject &tppac) const
{
  // -- Copy this method.
  TObject::Copy((TObject&)tppac);
  ((TS800Tppac&)tppac).fRandom.SetSeed(0);
  ((TS800Tppac&)tppac).fInterpolate = fInterpolate;
  ((TS800Tppac&)tppac).fSatFlat     = fSatFlat;
  ((TS800Tppac&)tppac).channels     = channels;
  ((TS800Tppac&)tppac).tag          = tag;
  ((TS800Tppac&)tppac).maxwidth     = maxwidth;
  ((TS800Tppac&)tppac).threshold    = threshold;
  ((TS800Tppac&)tppac).sampleBegin  = sampleBegin;
  ((TS800Tppac&)tppac).sampleWidth  = sampleWidth;
  ((TS800Tppac&)tppac).debug        = debug;
  ((TS800Tppac&)tppac).badxstrips   = badxstrips;
  for(Int_t i=0; i<20; i++) ((TS800Tppac&)tppac).badxstrip[i] = badxstrip[i];
  ((TS800Tppac&)tppac).badystrips   = badystrips;
  for(Int_t i=0; i<20; i++) ((TS800Tppac&)tppac).badystrip[i] = badystrip[i];
  ((TS800Tppac&)tppac).width        = width;
  ((TS800Tppac&)tppac).xcenter      = xcenter;
  ((TS800Tppac&)tppac).ycenter      = ycenter;
  ((TS800Tppac&)tppac).name         = name;

  // Clear();

}


//______________________________________________________________________________
void TS800Tppac::InitClass(TString iname) 
{
  // --
  //

  name = iname;

  debug    = false; 
  maxwidth = 32;
  filled   = 0;
  sampleWidth = 8;
  width = 32;
  xcenter = 40.64;
  ycenter = 40.64;
  
  channel     = new Short_t[4096];
  sample      = new Short_t[4096];
  data        = new Short_t[4096];
}

//______________________________________________________________________________
void TS800Tppac::InitTree(TTree *tree) 
{
  // --
  //

  fChain = tree;
  fCurrent = -1;
  //  TNamed *aState = (TNamed*)fChain->GetUserInfo()->FindObject("Analysis State");
  #ifdef TESTING
  fChain->SetMakeClass(1);
  #endif

//   fChain->SetBranchAddress(name+".data",data,&b_data);
//   fChain->SetBranchAddress(name+".sample",sample,&b_sample);
//   fChain->SetBranchAddress(name+".channel",channel,&b_channel);
//   fChain->SetBranchAddress(name+".filled",&filled,&b_filled);
//   fChain->SetBranchAddress(name+".x",&x,&b_x);
//   fChain->SetBranchAddress(name+".y",&y,&b_y);
//   fChain->SetBranchAddress(name+".xstrip[64]",&xstrip,&b_xstrip);
//   fChain->SetBranchAddress(name+".ystrip[64]",&ystrip,&b_ystrip);
//   fChain->SetBranchAddress(name+".xmult",&xmult,&b_xmult);
//   fChain->SetBranchAddress(name+".ymult",&ymult,&b_ymult);
//   fChain->SetBranchAddress(name+".xsum",&xsum,&b_xsum);
//   fChain->SetBranchAddress(name+".ysum",&ysum,&b_ysum);
//  if(      strcmp(aState->GetName(),"0")){
    b_data    = fChain->GetBranch(name+".data");
    b_sample  = fChain->GetBranch(name+".sample");
    b_channel = fChain->GetBranch(name+".channel");
    b_filled  = fChain->GetBranch(name+".filled");
    b_x       = fChain->GetBranch(name+".x");
    b_y       = fChain->GetBranch(name+".y");
    b_xstrip  = fChain->GetBranch(name+".xstrip");
    b_ystrip  = fChain->GetBranch(name+".ystrip");
    b_xmult   = fChain->GetBranch(name+".xmult");
    b_ymult   = fChain->GetBranch(name+".ymult");
    b_xsum    = fChain->GetBranch(name+".xsum");
    b_ysum    = fChain->GetBranch(name+".ysum");
//   }else if(strcmp(aState->GetName(),"1")){
//     fChain->SetBranchAddress("E02023."+name+".data",data,&b_data);
//     fChain->SetBranchAddress("E02023."+name+".sample",sample,&b_sample);
//     fChain->SetBranchAddress("E02023."+name+".channel",channel,&b_channel);
//     fChain->SetBranchAddress("E02023."+name+".filled",&filled,&b_filled);
//     b_x       = fChain->GetBranch(name+".x");
//     b_y       = fChain->GetBranch(name+".y");
//     b_xstrip  = fChain->GetBranch(name+".xstrip");
//     b_ystrip  = fChain->GetBranch(name+".ystrip");
//     b_xmult   = fChain->GetBranch(name+".xmult");
//     b_ymult   = fChain->GetBranch(name+".ymult");
//     b_xsum    = fChain->GetBranch(name+".xsum");
//     b_ysum    = fChain->GetBranch(name+".ysum");
//   }else if(strcmp(aState->GetName(),"2")){
//     fChain->SetBranchAddress("E02023."+name+".data",data,&b_data);
//     fChain->SetBranchAddress("E02023."+name+".sample",sample,&b_sample);
//     fChain->SetBranchAddress("E02023."+name+".channel",channel,&b_channel);
//     fChain->SetBranchAddress("E02023."+name+".filled",&filled,&b_filled);
//     fChain->SetBranchAddress("E02023Cal."+name+".x",&x,&b_x);
//     fChain->SetBranchAddress("E02023Cal."+name+".y",&y,&b_y);
//     fChain->SetBranchAddress("E02023Cal."+name+".xstrip[64]",&xstrip,&b_xstrip);
//     fChain->SetBranchAddress("E02023Cal."+name+".ystrip[64]",&ystrip,&b_ystrip);
//     fChain->SetBranchAddress("E02023Cal."+name+".xmult",&xmult,&b_xmult);
//     fChain->SetBranchAddress("E02023Cal."+name+".ymult",&ymult,&b_ymult);
//     fChain->SetBranchAddress("E02023Cal."+name+".xsum",&xsum,&b_xsum);
//     fChain->SetBranchAddress("E02023Cal."+name+".ysum",&ysum,&b_ysum);
//   }
}

//______________________________________________________________________________
void TS800Tppac::Clear(Option_t*) 
{
  // --
  //

  for(Int_t i=0; i<64; i++){
    //    xstrip[i] = sqrt(-1.0);
    //    ystrip[i] = sqrt(-1.0);
    xstrip[i] = 0;
    ystrip[i] = 0;
  }
  x     = sqrt(-1.0);
  y     = sqrt(-1.0);
  xmult = 0;
  ymult = 0;
  xsum  = sqrt(-1.0);
  ysum  = sqrt(-1.0);
}

//______________________________________________________________________________
void TS800Tppac::GetEntry(Int_t i) 
{
  // --
  //

  b_xstrip->GetEntry(i);
  b_ystrip->GetEntry(i);
}

//______________________________________________________________________________
UShort_t* TS800Tppac::Unpack(UShort_t *p, Int_t ID)
{
  // -- 
  //

  //  cout << "Unpack Tppac. . ." << tag << " " << *(p+1) << endl;
  if (*(p+1) == tag+1) {	// we are reading raw data
    p = Unpackrawdata(p,ID);
  }
  else {
    printf("Error: could not recognize TRACK sub-packet type: %x\n", *(p+1));
  }

  return p;
}

//______________________________________________________________________________
UShort_t* TS800Tppac::Unpackrawdata(UShort_t *p, Int_t ID)
{
  // --
  //

  static ULong_t total=0, failed=0;
  Short_t isample, ichannel, cdata[4], connector, previous_sample=0, ch=0;
  UShort_t index;
  //  Int_t count = 0;
  
  memset(data,    0, sizeof(data));
  memset(channel, 0, sizeof(channel));
  memset(sample,  0, sizeof(sample));
  filled = 0;

  //  cout << endl << "Unpack Raw Data. " << endl;
  UShort_t *pStore = p;
  Bool_t mes1=true, mes2=true, mes3=true, mes4=true;
  UShort_t length = *p++;
  Short_t i = length-3;
  p++;	// skip packet id
  //  cout << p << endl;
  threshold = *p++;
  while (i > 0) {
    if ((*p)>>15 != 1) {
      cout << "TPPAC data is corrupted!" << endl;
      p++; i--;
      continue;
    } else {
      isample = ((*p)&0x7FC0)>>6;
      ichannel = (*p)&0x3F;
      if (i == length-3) {sampleBegin = isample; previous_sample = isample;}
      //      cout << "isample: " << isample << " ichannel: " << ichannel << " sampleBegin: " << sampleBegin << endl;
    }
    p++; i--;
    memset(cdata, 0, sizeof(cdata));
    while ((*p)>>15 == 0) {
      connector = ((*p)&0x0C00)>>10;
      cdata[connector] = (*p)&0x3FF;
      p++; i--;
      if (i == 0) break;
    }
    if (isample < sampleBegin || isample > sampleBegin+maxwidth) {
      if (debug)
	printf("Warning in TPPAC Unpack: inconsistent sample number: %d (first: %d)\n",
	       isample, sampleBegin);
      mes1 = false;
      continue;
    }
    if (isample < previous_sample) {
      if (debug)
	printf("Warning in TPPAC Unpack: sample number lower than previous: %d (previous: %d)\n",
	       isample, previous_sample);
      mes2 = false;
      continue;
    }
    previous_sample = isample;
    for (Int_t j=0; j<4; j++) {
      //    ch = ichannel+j*64;
      if (cdata[j] != 0 && ichannel < (TS800_II_TRACK_CHANNELS / 4)) {
	if (j == 0 || j == 2) index = tppacmapx[ichannel];
	if (j == 1 || j == 3) index = tppacmapy[ichannel];

	//	ch = ichannel + j*64;
	ch = index + j*64;

	if (cdata[j] < threshold) {
	  if (debug)
	    printf ("Warning in TTPAC Unpack: data lower than threshold: %d (threshold: %d)\n",
		    cdata[j], threshold);
	  mes3 = false;
	} else {
	  if(j==0 || j==1 && ID==1){
	    //	    m_data[index+j*64][sample-m_sampleBegin] = cdata[j];
	    data[filled]    = cdata[j];
	    channel[filled] = ch;
	    sample[filled]  = isample;
	    filled++;
	  //	  cout << "Filled:  " << filled << endl;
	  }
	  if(j==2 || j==3 && ID==2){
	    //	    m_data[index+j*64][sample-m_sampleBegin] = cdata[j];
	    data[filled]    = cdata[j];
	    channel[filled] = ch - 128;
	    sample[filled]  = isample;
	    filled++;
	  }
	    //	  }else{
	    //	    printf("Warning in TPPAC Unpack: ppac ID not valid: %i\n",ID);
	    //	  }
	  //	  data[filled]    = cdata[j];
	  //	  channel[filled] = ch;
	  //	  sample[filled]  = isample;
	  //	  filled++;
	  //	  cout << "Filled:  " << filled << endl;
	}
      } else if (cdata[j] != 0 && ch >= channels) {
	if (debug)
	  printf ("Warning in TPPAC Unpack: channel greater than limit: %d (limit: %d)\n",
		  ch, channels);
	mes4 = false;
      }
    }
    sampleWidth = isample - sampleBegin;
  }


  // integrate samples into pads
  //	if (filled > 0) pad.Integrate();
  if (!mes1 || !mes2 || !mes3 || !mes4) failed++;
  total++;
  if (failed == 1000) {
    if (debug)
      printf ("Errors in TPPAC Unpackings: %g%%\n", 1.0*failed/total*100);
    total = 0;
    failed = 0;
  }

  if(ID==1) return pStore;
  if(ID==2) return (pStore+length);

  return p;

}

Last change: Sun Dec 21 12:38:58 2008
Last generated: 2008-12-21 12:38

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.