Commit 05c4fd45 authored by dauncey's avatar dauncey

Missed a new file for OOT PU handling

parent 00a99df5
// The architecture setting defines how the charge is digitised
//
// The method setting defines how the digitised values are combined
// for the trigger
#ifndef AdcReadingMultiple_HH
#define AdcReadingMultiple_HH
#include <iostream>
#include <cstdint>
#include <cassert>
#include <cmath>
#include "Backtrace.hh"
#include "Random.hh"
class AdcReadingMultiple {
public:
enum {
kNumberOfBx=4
};
AdcReadingMultiple() {
initialise();
for(unsigned bx(0);bx<AdcReadingMultiple::kNumberOfBx;bx++) {
fLoData[bx]=0;
fHiData[bx]=0;
}
}
~AdcReadingMultiple() {
}
void initialise() {
assert(fLoGain==0.0 && fHiGain==0.0);
fLoPedestal=Random::random().Uniform()-0.5;
fHiPedestal=Random::random().Uniform()-0.5;
fLoGain=Random::random().Gaus();
fHiGain=Random::random().Uniform()-0.5;
}
double loPedestal() const {
return fLoPedestal;
}
double hiPedestal() const {
return fHiPedestal;
}
double loGain() const {
return fLoGain;
}
double hiGain() const {
return fHiGain;
}
uint16_t loData() const {
return fLoData[currentBx()];
}
uint16_t hiData() const {
return fHiData[currentBx()];
}
uint32_t convertLsb(uint32_t a, double lsb) const {
double d(lsb*(a+0.5));
return uint32_t(d/fAdcLsb);
}
void reading(double q) {
double loAdcLsb(fLoAdcLsb*(1.0+fLoGainWidth*fLoGain));
double loAdc(fLoPedestal+(q/loAdcLsb));
// Allow for non-linear TOT
if(fArchitecture==0) {
if(q>150.0) q-=150.0*(150.0-140.0)/(q-140.0);
else q=0.0;
}
double hiAdcLsb(fHiAdcLsb*(1.0+fHiGainWidth*fHiGain));
double hiAdc(fHiPedestal+(q/hiAdcLsb));
// Baseline and ~ideal baseline
if(fArchitecture==0 ||fArchitecture==1) {
// Low range
if(loAdc<0.0) {
fLoData[currentBx()]=0;
} else {
if(loAdc<fLoSaturation) fLoData[currentBx()]=uint16_t(loAdc+0.5);
else fLoData[currentBx()]=fLoSaturation;
}
// High range
if(hiAdc<0.0) {
fHiData[currentBx()]=0;
} else {
if(hiAdc<fHiSaturation) fHiData[currentBx()]=uint16_t(hiAdc+0.5);
else fHiData[currentBx()]=fHiSaturation;
}
}
// Bi-gain with TOT which is never used in the trigger
if(fArchitecture==2) {
// Low range
if(loAdc<0.0) {
fLoData[currentBx()]=0;
} else {
if(loAdc<fLoSaturation) fLoData[currentBx()]=uint16_t(loAdc+0.5);
else fLoData[currentBx()]=fLoSaturation;
}
// High range
if(hiAdc<0.0) {
fHiData[currentBx()]=0;
} else {
if(hiAdc<16383.0) fHiData[currentBx()]=uint16_t(hiAdc+0.5);
else fHiData[currentBx()]=16383;
}
}
// Bi-gain with no TOT
if(fArchitecture==3) {
// Low range
if(loAdc<0.0) {
fLoData[currentBx()]=0;
} else {
if(loAdc<255.0) fLoData[currentBx()]=uint16_t(loAdc+0.5);
else fLoData[currentBx()]=255;
}
// High range
if(hiAdc<0.0) {
fHiData[currentBx()]=0;
} else {
if(hiAdc<fHiSaturation) fHiData[currentBx()]=uint16_t(hiAdc+0.5);
else fHiData[currentBx()]=fHiSaturation;
}
}
// Single gain ~ideal
if(fArchitecture==4) {
// Low and high ranges combined to store more than 16 bits
uint32_t total;
if(loAdc<0.0) {
total=0;
} else {
if(loAdc<524287.0) total=uint32_t(loAdc+0.5);
else total=524287;
}
fLoData[currentBx()]=(total&0xffff);
fHiData[currentBx()]=(total>>16);
if(fHiData[currentBx()]>7) {
std::cout << "AdcReadingMultiple::reading() Arch 3, q = " << q
<< ", loAdcLsb = " << loAdcLsb
<< ", fLoData[currentBx()] = " << fLoData[currentBx()]
<< ", fHiData[currentBx()] = " << fHiData[currentBx()]
<< ", total = " << total << std::endl;
}
}
}
// Assume this is used for merging the two ranges for
// the TPG path only, not for the DAQ and TPG selection
uint32_t result() const {
return trgResult();
}
uint32_t trgResult() const {
assert(fMethod<numberOfMethods());
if(fArchitecture==0) {
if(fMethod!=4) {
if(fLoData[currentBx()]<1023 || fMethod==0) return fLoData[currentBx()];
//if(fMethod==3 && fHiData[currentBx()]<41) return 1023;
unsigned loSat(1220);
if(fMethod==3 && fHiData[currentBx()]<(loSat/fRatio)) return loSat;
}
//uint32_t hi(fHiData[currentBx()]);
// Only do manipulation for non-linear region (below 400 fC)
// Actually restrict to 8 bits = 640 fC
if(fHiData[currentBx()]>0 && fHiData[currentBx()]<256) {
if(fMethod==2 || fMethod==4) { // Linearise
// double linearHi(0.5*(36.0+fHiData[currentBx()]+sqrt((36.0-fHiData[currentBx()])*(36.0-fHiData[currentBx()])+640.0)));
//hi=uint32_t(linearHi);
double r(fHiAdcLsb*(fHiData[currentBx()]+0.5));
double q(0.5*(90.0+r+sqrt((90.0-r)*(90.0-r)+400*(100-90.0))));
return uint32_t(q/fAdcLsb);
}
}
//return fRatio*hi+fRatio/2;
return convertLsb(fHiData[currentBx()],fHiAdcLsb);
}
if(fArchitecture==1) {
uint16_t hi(fHiData[currentBx()]);
// Bit 2 of fMethod controls bit round-off
//if((fMethod&(1<<2))!=0) {
// hi=(hi+2)/4;
// hi*=4;
//}
// Bit 1 of fMethod controls using only high range or not
if((fMethod&(1<<1))==0 && hi<(1023/fRatio)) {
// Bit 2 of fMethod controls bit round-off
if((fMethod&(1<<2))!=0) return convertLsb(fLoData[currentBx()]/4,4.0*fLoAdcLsb);
return fLoData[currentBx()];
}
// Bit 0 of fMethod controls using 12-bit or perfect high range
if((fMethod&(1<<2))!=0) {
hi/=4;
if((fMethod&(1<<0))==0 && hi>255) hi=255;
return convertLsb(hi,4.0*fHiAdcLsb);
}
if((fMethod&(1<<0))==0 && hi>1023) hi=1023;
return convertLsb(hi,fHiAdcLsb);
}
if(fArchitecture==2) {
if(fMethod==1) return convertLsb(fHiData[currentBx()]/2 , 2.0*fHiAdcLsb);
if(fMethod==2) return convertLsb(fHiData[currentBx()]/4 , 4.0*fHiAdcLsb);
if(fMethod==3) return convertLsb(fHiData[currentBx()]/8 , 8.0*fHiAdcLsb);
if(fMethod==4) return convertLsb(fHiData[currentBx()]/16,16.0*fHiAdcLsb);
return convertLsb(fHiData[currentBx()],fHiAdcLsb);
}
if(fArchitecture==3) {
uint32_t total(fHiData[currentBx()]);
total<<=16;
/*
std::cout << "AdcReadingMultiple::result() Arch 3, fLoData[currentBx()] = " << fLoData[currentBx()]
<< ", fHiData[currentBx()] = " << fHiData[currentBx()]
<< ", result = " << total+fLoData[currentBx()] << std::endl;
*/
return total+fLoData[currentBx()];
}
if(fArchitecture==4) {
if(fLoData[currentBx()]<1023) return fLoData[currentBx()];
return 25*fHiData[currentBx()]+12;
}
// IMPLEMENT THIS SOMEWHERE HERE!!!
/*
unsigned r(result());
if(fTruncateBits>0) {
r>>=fTruncateBits;
r<<=fTruncateBits;
}
*/
assert(false);
return 0xffffffff;
}
// Assume this is only used for DAQ and TPG path selection
// in DigHit, not for TPG merging of two ranges
double chargeResult(unsigned dBx) const {
return daqResult(dBx);
}
double daqResult(unsigned dBx) const {
/*
if(fArchitecture==0) return fAdcLsb*(result()+0.5);
if(fArchitecture==1) return fAdcLsb*(result()+0.5);
if(fArchitecture==2) {
if(fMethod==0) return fHiAdcLsb*(result()+0.5);
if(fMethod==1) return 4*fHiAdcLsb*(result()+0.5);
if(fMethod==2) return 16*fHiAdcLsb*(result()+0.5);
}
assert(false);
return 999999.0;
*/
/*
unsigned r(result());
if(fTruncateBits>0) {
r>>=fTruncateBits;
r<<=fTruncateBits;
}
*/
//return fAdcLsb*(r+0.5);
if(fLoData[previousBx(dBx)]<fLoSaturation) {
double loAdcLsb(fLoAdcLsb*(1.0+fLoGainWidth*fLoGain));
return loAdcLsb*(fLoData[previousBx(dBx)]-fLoPedestal);
}
double hiAdcLsb(fHiAdcLsb*(1.0+fHiGainWidth*fHiGain));
double q(hiAdcLsb*(fHiData[previousBx(dBx)]-fHiPedestal));
if(fArchitecture==0) {
if(q>0.0) q=0.5*(140.0+q+sqrt((140.0-q)*(140.0-q)+600*(150.0-140.0)));
else q=0.0;
}
return q;
}
bool read(std::istream &fin) {
fin >> fLoData[currentBx()] >> fHiData[currentBx()];
if(!fin) return false;
return true;
}
bool write(std::ostream &fout) const {
fout << fLoData[currentBx()] << " " << fHiData[currentBx()];
if(!fout) return false;
return true;
}
void print() const {
std::cout << "AdcReadingMultiple ADC values " << fLoData[currentBx()] << ", " << fHiData[currentBx()];
}
void printConstants() const {
std::cout << "AdcReadingMultiple Low pedestal, gain " << fLoPedestal << ", " << fLoGain
<< ", High pedestal, gain " << fHiPedestal << ", " << fHiGain << std::endl
<< std::endl;
}
static void printStatics() {
std::cout << "AdcReadingMultiple parameters: architecture " << fArchitecture
<< ", method " << fMethod << std::endl
<< " ADC: LSB " << fLoAdcLsb
<< ", saturation " << fLoSaturation << ", gain width " << fLoGainWidth << std::endl
<< " TDC: LSB " << fHiAdcLsb
<< ", saturation " << fHiSaturation << ", gain width " << fHiGainWidth << std::endl
<< " Range ratio " << fRatio << std::endl
<< " Truncation bits " << fTruncateBits << std::endl
<< std::endl;
}
static double loAdcLsb() {
return fLoAdcLsb;
}
static double hiAdcLsb() {
return fLoAdcLsb;
}
static double hiAdcToFc(double a) {
return a*fLoAdcLsb;
}
static double fcToLoAdc(double q) {
return q/fLoAdcLsb;
}
static void setArchitecture(unsigned a) {
assert(a<fNumberOfArchitectures);
fArchitecture=a;
if(fArchitecture==0 || fArchitecture==1) {
fLoAdcLsb=fAdcLsb;
fRatio=30.0;
fHiAdcLsb=fRatio*fAdcLsb;
//fLoSaturation=(1<<11)-1;
fLoSaturation=1600; // Force earlier saturation than 11 bits = 2047
fHiSaturation=(1<<13)-1;
}
if(fArchitecture==2) {
fLoAdcLsb=fAdcLsb;
fRatio=10.0;
fHiAdcLsb=fRatio*fAdcLsb;
fLoSaturation=(1<<11)-1;
fHiSaturation=(1<<14)-1;
}
if(fArchitecture==3) {
fHiAdcLsb=3.0;
fRatio=60;
fLoAdcLsb=fHiAdcLsb/fRatio;
fLoSaturation=(1<<8)-1;
fHiSaturation=(1<<13)-1;
}
if(fArchitecture==4) {
fLoAdcLsb=fAdcLsb;
fRatio=0.0;
fHiAdcLsb=0.0;
}
resetMethod();
}
static void resetArchitecture() {
setArchitecture(0);
}
static unsigned numberOfMethods() {
if(fArchitecture==0) return 5;
if(fArchitecture==1) return 1;
if(fArchitecture==2) return 8;
if(fArchitecture==3) return 5;
if(fArchitecture==4) return 1;
return 0;
}
static void setMethod(unsigned m) {
assert(m<numberOfMethods());
fMethod=m;
}
static void resetMethod() {
if(fArchitecture==0) setMethod(2);
if(fArchitecture==1) setMethod(0);
if(fArchitecture==2) setMethod(0);
if(fArchitecture==3) setMethod(0);
if(fArchitecture==4) setMethod(0);
}
static unsigned currentBx() {
return fBxNumber%kNumberOfBx;
}
static unsigned previousBx(unsigned dBx) {
BACKTRACE_AND_ASSERT(dBx<kNumberOfBx);
return (fBxNumber+kNumberOfBx-dBx)%kNumberOfBx;
}
static const unsigned fNumberOfArchitectures;
static const unsigned fMaximumNumberOfMethods;
const static double fAdcLsb;
static double fRatio;
static double fLoAdcLsb;
static double fHiAdcLsb;
static double fLoGainWidth;
static double fHiGainWidth;
static unsigned fLoSaturation;
static unsigned fHiSaturation;
static unsigned fTruncateBits;
static unsigned fBxNumber;
protected:
static unsigned fArchitecture;
static unsigned fMethod;
uint16_t fLoData[kNumberOfBx];
uint16_t fHiData[kNumberOfBx];
float fLoPedestal;
float fHiPedestal;
float fLoGain;
float fHiGain;
};
unsigned AdcReadingMultiple::fBxNumber=0;
const unsigned AdcReadingMultiple::fNumberOfArchitectures=5;
unsigned AdcReadingMultiple::fArchitecture=0;
const unsigned AdcReadingMultiple::fMaximumNumberOfMethods=8;
unsigned AdcReadingMultiple::fMethod=2;
const double AdcReadingMultiple::fAdcLsb=0.1;
double AdcReadingMultiple::fLoAdcLsb=AdcReadingMultiple::fAdcLsb;
double AdcReadingMultiple::fRatio=30.0;
double AdcReadingMultiple::fHiAdcLsb=AdcReadingMultiple::fRatio*AdcReadingMultiple::fAdcLsb;
double AdcReadingMultiple::fLoGainWidth=0.01;
double AdcReadingMultiple::fHiGainWidth=1/25.0;
unsigned AdcReadingMultiple::fLoSaturation=(1<<11)-1;
unsigned AdcReadingMultiple::fHiSaturation=(1<<13)-1;
unsigned AdcReadingMultiple::fTruncateBits=0;
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment