#include "TS800Crdc.h"
#include "TS800.h"
#include "nrutil.h"
#include <fstream>
#include <iostream>
#include <math.h>
#include <TDirectory.h>
#include <TFile.h>
#include <TNamed.h>
#include <TList.h>
ClassImp(TS800Crdc);
extern short gNumrecError, gNumrecMessage;
TS800Crdc::TS800Crdc(const TS800Crdc &crdc) : TNamed(crdc)
{
((TS800Crdc&)crdc).Copy(*this);
}
void TS800Crdc::InitFix()
{
pad.parent = this;
calc.parent = this;
calc.pad = &pad;
channel = new Short_t[4096];
sample = new Short_t[4096];
data = new Short_t[4096];
}
Int_t TS800Crdc::Calculate(Long64_t entry)
{
if(!fChain){printf("TTree or TChain has not been initialized!!!\n"); return -1;}
Long64_t ibad = 0;
Double_t yInt = sqrt(-1.0);
short restore = gNumrecMessage;
gNumrecMessage = 0;
if(entry==0){
if(calc.fInterpPoly==kTRUE) { printf("Using POLYNOMIAL INTERPOLATION for bad pads.\n");}
else if(calc.fInterpSpline3==kTRUE){ printf("Using CUBIC SPLINE INTERPOLATION for bad pads.\n");}
else if(calc.fSatFlat==kTRUE) { printf("Using FLATTENING for saturated pads.\n");}
else if(fYSplineCorr==kTRUE) { printf("Using Y Correcting Cubic Spline.\n");
if(!strcmp(fYSplineMatchPnt,"begin") || !strcmp(fYSplineMatchPnt,"end")){
printf("* Invalid CRDC Y Spline Matching Point.\n");
}
}
else{ printf("NO CRDC PAD CORRECTIONS APPLIED.\n");}
}
Clear();
fCon->b_filled->GetEntry(entry);
if (fCon->filled > 0) {
if (calc.method == 1) {
calc.CalculateGravity();
x = x_offset[1]
+ x_slope[1]*x_offset[0]
+ x_slope[0]*x_slope[1]*calc.x_gravity;
if (isnan(calc.x_gravity)) ibad++;
}
if (calc.method == 2) {
calc.CalculateFit();
x = x_offset[1]
+ x_slope[1]*x_offset[0]
+ x_slope[0]*x_slope[1]*calc.x_fit;
if (isnan(calc.x_fit)) ibad++;
}
}
fCon->b_tac->GetEntry(entry);
if(parent->fAddRndm && !fTACSplineCorr && !fAnodeSplineCorr){
if(entry==0) printf("* Using uncorrected y calibration with radomization.\n");
y = y_offset[1] + y_slope[1]*y_offset[0] + y_slope[0]*y_slope[1]*(fCon->tac+fRandom.Rndm());
yInt = y_offset[1] + y_slope[1]*y_offset[0];
}else if(!parent->fAddRndm && fTACSplineCorr) {
if(entry==0) printf("* Using TAC corrected y calibration without radomization.\n");
if(x>fTACSpline->GetXmin() && x<fTACSpline->GetXmax() && !isnan(x)){
fCon->tac -= (UShort_t)(fTACSpline->Eval(x)-fTACSplineLevel);
}
tac = fCon->tac;
y = y_offset[1] + y_slope[1]*y_offset[0] + y_slope[0]*y_slope[1]*(Double_t)(fCon->tac);
yInt = y_offset[1] + y_slope[1]*y_offset[0];
if(fYSplineCorr){
Double_t xkb,ykb,xke,yke;
fYSpline->GetKnot(0,xkb,ykb);
fYSpline->GetKnot(fYSpline->GetNp()-1,xke,yke);
if (strcmp(fYSplineMatchPnt,"begin")==0){
if(y>xkb && y<=xke) y = fYSpline->Eval(y);
if(y>xke) y = fYSpline->Derivative(xke)*(y-xke)+yke;
}
else if(strcmp(fYSplineMatchPnt,"end")==0){
if(y<xke && y>=xkb) y = fYSpline->Eval(y);
if(y<xkb) y = fYSpline->Derivative(xkb)*(y-xkb)+ykb;
}
}
}else if(parent->fAddRndm && fTACSplineCorr) {
if(entry==0) printf("* Using TAC corrected y calibration with radomization.\n");
if(x>fTACSpline->GetXmin() && x<fTACSpline->GetXmax() && !isnan(x)){
fCon->tac -= (UShort_t)(fTACSpline->Eval(x)-fTACSplineLevel);
}
tac = fCon->tac;
y = y_offset[1] + y_slope[1]*y_offset[0] + y_slope[0]*y_slope[1]*(fCon->tac+fRandom.Rndm());
yInt = y_offset[1] + y_slope[1]*y_offset[0];
if(fYSplineCorr){
Double_t xkb,ykb,xke,yke;
fYSpline->GetKnot(0,xkb,ykb);
fYSpline->GetKnot(fYSpline->GetNp()-1,xke,yke);
if (strcmp(fYSplineMatchPnt,"begin")==0){
if(y>xkb && y<=xke) y = fYSpline->Eval(y);
if(y>xke) y = fYSpline->Derivative(xke)*(y-xke)+yke;
}
else if(strcmp(fYSplineMatchPnt,"end")==0){
if(y<xke && y>=xkb) y = fYSpline->Eval(y);
if(y<xkb) y = fYSpline->Derivative(xkb)*(y-xkb)+ykb;
}
}
}else if(parent->fAddRndm && fAnodeSplineCorr) {
if(entry==0) printf("* Using Anode corrected y calibration with radomization.\n");
fCon->b_anode->GetEntry(entry);
if(calc.x_gravity>fAnodeSpline->GetXmin() && calc.x_gravity<fAnodeSpline->GetXmax() && !isnan(calc.x_gravity)){
anode = (UShort_t)(fCon->anode - (UShort_t)(fAnodeSpline->Eval(calc.x_gravity)-fAnodeSplineLevel));
}
tac = (UShort_t)(fCon->tac + (Double_t)(anode)*fAnodeCorrSlope + fAnodeCorrOffset);
y = y_offset[1] + y_slope[1]*y_offset[0] + y_slope[0]*y_slope[1]*(tac+fRandom.Rndm());
yInt = y_offset[1] + y_slope[1]*y_offset[0];
}else{
if(entry==0) printf("* Using uncorrected y calibration without radomization.\n");
y = y_offset[1] + y_slope[1]*y_offset[0] + y_slope[0]*y_slope[1]*(Double_t)fCon->tac;
yInt = y_offset[1] + y_slope[1]*y_offset[0];
}
y += fYShift;
x += fXShift;
gNumrecMessage = restore;
return 1;
}
void TS800Crdc::InitClass(TString iname,TS800 *theParent)
{
parent = theParent;
fName = iname;
fTACSplineCorr = kFALSE;
fTACSplineLevel = 0;
fAnodeSplineCorr = kFALSE;
fAnodeSplineLevel = 0;
fYSplineCorr = kFALSE;
debug = false;
maxwidth = 32;
filled = 0;
fAnodeCorrSlope = 1;
fAnodeCorrOffset = 0;
x_offset[0] = -288;
x_slope[0] = 2.54;
y_offset[0] = 0;
y_slope[0] = 1;
x_offset[1] = 0;
x_slope[1] = 1;
y_offset[1] = 0;
y_slope[1] = 1;
fXShift = 0;
fYShift = 0;
fYGainShift = 0;
pad.parent = this;
calc.parent = this;
calc.pad = &pad;
channel = new Short_t[4096];
sample = new Short_t[4096];
data = new Short_t[4096];
pad.InitClass(fName+".pad");
calc.InitClass(fName+".calc");
Char_t name[1000],title[1000];
sprintf(name,"fHYShifts_%s",GetName());
sprintf(title,"%s Y Shifts",GetName());
fHYShifts.SetNameTitle(name,title);
fHYShifts.SetBins(2000,1,2001);
sprintf(name,"fHYGainShifts_%s",GetName());
sprintf(title,"%s Y Gain Shifts",GetName());
fHYGainShifts.SetNameTitle(name,title);
fHYGainShifts.SetBins(2000,1,2001);
for(Int_t i=0; i<fHYGainShifts.GetNbinsX(); i++) fHYGainShifts.SetBinContent(i,1.0);
}
void TS800Crdc::InitTree(TTree *tree)
{
fChain = tree;
fCurrent = -1;
b_data = fChain->GetBranch(fName+".data");
b_sample = fChain->GetBranch(fName+".sample");
b_channel = fChain->GetBranch(fName+".channel");
b_filled = fChain->GetBranch(fName+".filled");
b_x = fChain->GetBranch(fName+".x");
b_y = fChain->GetBranch(fName+".y");
b_anode = fChain->GetBranch(fName+".anode");
b_tac = fChain->GetBranch(fName+".tac");
pad.InitTree(tree);
calc.InitTree(tree);
}
void TS800Crdc::Clear(Option_t*)
{
x = sqrt(-1.0);
y = sqrt(-1.0);
anode = 0;
tac = 0;
calc.Clear();
}
void TS800Crdc::Copy(TObject &crdc) const
{
TObject::Copy((TObject&)crdc);
((TS800Crdc&)crdc).channels = channels;
((TS800Crdc&)crdc).tag = tag;
((TS800Crdc&)crdc).maxwidth = maxwidth;
((TS800Crdc&)crdc).threshold = threshold;
((TS800Crdc&)crdc).sampleBegin = sampleBegin;
((TS800Crdc&)crdc).sampleWidth = sampleWidth;
((TS800Crdc&)crdc).debug = debug;
((TS800Crdc&)crdc).fAnodeSplineCorr = fAnodeSplineCorr;
((TS800Crdc&)crdc).fAnodeSpline = fAnodeSpline;
((TS800Crdc&)crdc).fAnodeSplineLevel = fAnodeSplineLevel;
((TS800Crdc&)crdc).fTACSplineCorr = fTACSplineCorr;
((TS800Crdc&)crdc).fTACSpline = fTACSpline;
((TS800Crdc&)crdc).fTACSplineLevel = fTACSplineLevel;
((TS800Crdc&)crdc).fYSplineCorr = fYSplineCorr;
((TS800Crdc&)crdc).fYSpline = fYSpline;
((TS800Crdc&)crdc).fYSplineMatchPnt = fYSplineMatchPnt;
pad.Copy(((TS800Crdc&)crdc).pad);
calc.Copy(((TS800Crdc&)crdc).calc);
((TS800Crdc&)crdc).pad.parent = &((TS800Crdc&)crdc);
((TS800Crdc&)crdc).calc.parent = &((TS800Crdc&)crdc);
((TS800Crdc&)crdc).fAnodeCorrOffset = fAnodeCorrOffset;
((TS800Crdc&)crdc).fAnodeCorrSlope = fAnodeCorrSlope;
((TS800Crdc&)crdc).x_offset[0] = x_offset[0];
((TS800Crdc&)crdc).x_slope[0] = x_slope[0];
((TS800Crdc&)crdc).y_offset[0] = y_offset[0];
((TS800Crdc&)crdc).y_slope[0] = y_slope[0];
((TS800Crdc&)crdc).x_offset[1] = x_offset[1];
((TS800Crdc&)crdc).x_slope[1] = x_slope[1];
((TS800Crdc&)crdc).y_offset[1] = y_offset[1];
((TS800Crdc&)crdc).y_slope[1] = y_slope[1];
((TS800Crdc&)crdc).fXShift = fXShift;
((TS800Crdc&)crdc).fYShift = fYShift;
((TS800Crdc&)crdc).fYGainShift = fYGainShift;
fHYShifts.Copy(((TS800Crdc&)crdc).fHYShifts);
fHYGainShifts.Copy(((TS800Crdc&)crdc).fHYGainShifts);
((TS800Crdc&)crdc).fName = fName;
}
void TS800Crdc::GetEntry(int i)
{
calc.GetEntry(i);
b_x->GetEntry(i);
b_y->GetEntry(i);
b_anode->GetEntry(i);
b_tac->GetEntry(i);
}
Bool_t TS800Crdc::LoadYShifts(Char_t *yShiftFile)
{
ifstream iFile(yShiftFile,ios::in);
Char_t line[1000];
Int_t runNum;
Double_t shift;
if(!iFile.is_open()) {printf("* File could not be opened!\n"); return kFALSE;}
iFile.getline(line,1000);
while(line[0]=='#' || line[0]==' ') iFile.getline(line,1000);
Bool_t firstLine = kTRUE;
while (!iFile.eof()){
if(!firstLine) iFile.getline(line,1000);
firstLine = kFALSE;
sscanf(line,"%i %*f %lf %*e",&runNum,&shift);
fHYShifts.SetBinContent(runNum,shift);
}
iFile.close();
printf("* Loading %s Y shifts . . . \t\t\t\t [OK]\n",GetName());
return kTRUE;
}
Bool_t TS800Crdc::LoadSpline(Char_t *splineFile,Int_t crdcID, Int_t type)
{
TDirectory *cDir = gDirectory;
TFile spFile(splineFile,"READ");
Char_t spName[100];
TSpline3 *tmpSp;
if(type==0){
sprintf(spName,"crdc%iAnodeSpline",crdcID);
tmpSp = (TSpline3*)spFile.FindObjectAny(spName);
fAnodeSpline = (TSpline3*)tmpSp->Clone(spName);
}else if(type==1){
sprintf(spName,"crdc%iTACSpline",crdcID);
fTACSpline = (TSpline3*)spFile.FindObjectAny(spName);
}else if(type==2){
sprintf(spName,"crdc%iYSpline",crdcID);
fYSpline = (TSpline3*)spFile.FindObjectAny(spName);
}else{
printf("* ERROR: Invalid type.\n");
}
spFile.Close();
cDir->cd();
if(type==0 && !fAnodeSpline) {printf("Error: %s function not found.\n",spName); return kFALSE;}
if(type==1 && !fTACSpline ) {printf("Error: %s function not found.\n",spName); return kFALSE;}
if(type==2 && !fYSpline) {printf("Error: %s function not found.\n",spName); return kFALSE;}
else{printf("Loaded %s correcting function (Spline will be used during CRDC%i calculations).\n",spName,crdcID);}
if(type==0) fAnodeSplineCorr = kTRUE;
if(type==1) fTACSplineCorr = kTRUE;
if(type==2) fYSplineCorr = kTRUE;
return kTRUE;
}
void TS800Crdc::SetYShift(Int_t runNum)
{
Double_t shift = fHYShifts.GetBinContent(runNum);
fYShift = shift;
}
void TS800Crdc::SetYGainShift(Int_t runNum)
{
Double_t shift = fHYGainShifts.GetBinContent(runNum);
fYGainShift = shift;
}
UShort_t* TS800Crdc::Unpack(UShort_t *p)
{
if(*(p+1) == tag+1){
p = Unpackrawdata(p);
}
if(*(p+1) == tag+5){
anode = (UShort_t)*(p+2);
tac = (UShort_t)*(p+3);
p += 4;
}
return p;
}
UShort_t* TS800Crdc::Unpackrawdata(UShort_t *p)
{
static ULong_t total=0, failed=0;
Short_t isample, ichannel, cdata[4], connector, previous_sample=0, ch;
memset(data, 0, sizeof(data));
memset(channel, 0, sizeof(channel));
memset(sample, 0, sizeof(sample));
filled = 0;
UShort_t *pStore = p;
bool mes1=true, mes2=true, mes3=true, mes4=true;
UShort_t length = *p++;
Short_t i = length-3;
p++;
threshold = *p++;
while(i>0) {
if((*p)>>15 != 1) {
cout << "CRDC data is corrupted!" << endl;
p++; i--;
continue;
}else{
isample = (Short_t)((*p)&0x7FC0)>>6;
ichannel = (Short_t)(*p)&0x3F;
if (i == length-3) {sampleBegin = isample; previous_sample = isample;}
}
p++; i--;
memset(cdata, 0, sizeof(cdata));
while((*p)>>15 == 0) {
connector = (Short_t)((*p)&0x0C00)>>10;
cdata[connector] = (Short_t)(*p)&0x3FF;
p++; i--;
if(i==0) break;
}
if(isample < sampleBegin || isample > sampleBegin+maxwidth) {
if(debug)
printf("Warning in Crdc Unpack: inconsistent sample number: %d (first: %d)\n",
isample, sampleBegin);
mes1 = false;
continue;
}
if(isample < previous_sample) {
if (debug)
printf("Warning in Crdc 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 && ch<channels) {
if(cdata[j]<threshold) {
if(debug)
printf ("Warning in Crdc Unpack: data lower than threshold: %d (threshold: %d)\n",
cdata[j], threshold);
mes3 = false;
}else{
data[filled] = cdata[j];
channel[filled] = ch;
sample[filled] = isample;
filled++;
}
}else if(cdata[j]!=0 && ch>=channels) {
if(debug)
printf ("Warning in Crdc Unpack: channel greater than limit: %d (limit: %d)\n",
ch, channels);
mes4 = false;
}
}
sampleWidth = isample - sampleBegin + 1;
}
if(!mes1 || !mes2 || !mes3 || !mes4) failed++;
total++;
if(failed==1000) {
if (debug)
printf ("Errors in Crdc Unpackings: %g%%\n", 1.0*failed/total*100);
total = 0;
failed = 0;
}
return (pStore+length);
}
void TS800Crdc::Snapshot1D(TH1F *histogram, Int_t entry)
{
histogram->Reset();
pad.b_cal->GetEntry(entry);
for (Int_t i=0; i<channels; i++) {
if (!isnan(pad.cal[i])) histogram->Fill(i, pad.cal[i]);
}
histogram->Draw();
}
void TS800Crdc::Snapshot2D(TH2F *histogram, Int_t entry)
{
histogram->Reset();
b_sample->GetEntry(entry);
b_channel->GetEntry(entry);
b_data->GetEntry(entry);
b_filled->GetEntry(entry);
for (int i=0; i<filled; i++) {
histogram->Fill(channel[i], sample[i], data[i]);
}
histogram->Draw("COLZ");
}
Last change: Sun Dec 21 12:38:54 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.