|
| 1 | +// THcBPM: BPM class for Hall C |
| 2 | +// Based on THaBPM but using Hall C style hit list in decoding |
| 3 | + |
| 4 | +#include "THcBPM.h" |
| 5 | +#include "THaEvData.h" |
| 6 | +#include "THaApparatus.h" |
| 7 | +#include "THaCutList.h" |
| 8 | + |
| 9 | +#include "THcDetectorMap.h" |
| 10 | +#include "THcRawAdcHit.h" |
| 11 | +#include "THcRasterRawHit.h" |
| 12 | +#include "THcSignalHit.h" |
| 13 | + |
| 14 | +#include "THcParmList.h" |
| 15 | +#include "THcGlobals.h" |
| 16 | + |
| 17 | +static const Int_t NCHAN = 4; // number of channels |
| 18 | + |
| 19 | +using namespace std; |
| 20 | + |
| 21 | +//______________________________________________________________ |
| 22 | +THcBPM::THcBPM( const char* name, const char* description, THaApparatus* a) |
| 23 | + : THaBeamDet(name, description, a), |
| 24 | + fRawSignal(NCHAN), fPedestals(NCHAN), fCorSignal(NCHAN), fRotPos(NCHAN/2), |
| 25 | + fRot2HCSPos(NCHAN/2,NCHAN/2), fCalibRot(0) |
| 26 | +{ |
| 27 | + fNhits = 0; |
| 28 | + fAnalyzePedestals = 0; |
| 29 | + fNPedestalEvents = 0; |
| 30 | + fADCMode = 0; // default: kDBPed |
| 31 | + frAdcPulseIntRaw = new TClonesArray("THcSignalHit", NCHAN); |
| 32 | + frAdcPulseInt = new TClonesArray("THcSignalHit", NCHAN); |
| 33 | + |
| 34 | +} |
| 35 | + |
| 36 | +//______________________________________________________________ |
| 37 | +THcBPM::~THcBPM() |
| 38 | +{ |
| 39 | + delete frAdcPulseIntRaw; frAdcPulseIntRaw = nullptr; |
| 40 | + delete frAdcPulseInt; frAdcPulseInt = nullptr; |
| 41 | + |
| 42 | + delete [] fPed; fPed = nullptr; |
| 43 | + delete [] fPedSum; fPedSum = nullptr; |
| 44 | + delete [] fPedLimit; fPedLimit = nullptr; |
| 45 | + delete [] fPedCount; fPedCount = nullptr; |
| 46 | +} |
| 47 | + |
| 48 | +//______________________________________________________________ |
| 49 | +THaAnalysisObject::EStatus THcBPM::Init( const TDatime& date ) |
| 50 | +{ |
| 51 | + // cout << "THcBPM::Init" << endl; |
| 52 | + |
| 53 | + char EngineDID[] = "xBPM"; |
| 54 | + EngineDID[0] = toupper(GetApparatus()->GetName()[0]); |
| 55 | + |
| 56 | + if( gHcDetectorMap->FillMap(fDetMap, EngineDID) < 0 ) { |
| 57 | + static const char* const here = "Init()"; |
| 58 | + Error( Here(here), "Error filling detectormap for %s.", EngineDID); |
| 59 | + |
| 60 | + return kInitError; |
| 61 | + } |
| 62 | + |
| 63 | + InitHitList(fDetMap,"THcRasterRawHit",fDetMap->GetTotNumChan()+1); |
| 64 | + |
| 65 | + EStatus status; |
| 66 | + if( (status = THaBeamDet::Init( date )) ) |
| 67 | + return fStatus=status; |
| 68 | + |
| 69 | + return fStatus = kOK; |
| 70 | + |
| 71 | +} |
| 72 | + |
| 73 | +//______________________________________________________________ |
| 74 | +Int_t THcBPM::ReadDatabase( const TDatime& date ) |
| 75 | +{ |
| 76 | + |
| 77 | + // cout << "THcBPM::ReadDatabase" << endl; |
| 78 | + |
| 79 | + // Hall C style LoadDB |
| 80 | + char prefix[2]; |
| 81 | + prefix[0] = 'g'; |
| 82 | + prefix[1] = '\0'; |
| 83 | + |
| 84 | + // default values |
| 85 | + fMinPed = 0; |
| 86 | + |
| 87 | + fOrigin.SetXYZ(0.0, 0.0, 0.0); |
| 88 | + |
| 89 | + InitializePedestals(); |
| 90 | + |
| 91 | + Double_t pedestals[NCHAN], rotations[NCHAN]; |
| 92 | + Double_t offsets[2]; // offset x, y |
| 93 | + |
| 94 | + memset( pedestals, 0, sizeof(pedestals) ); |
| 95 | + memset( rotations, 0, sizeof(rotations) ); |
| 96 | + memset( offsets , 0, sizeof( offsets ) ); |
| 97 | + DBRequest list[] = { |
| 98 | + {Form("%s_calib_rot",GetName()), &fCalibRot}, |
| 99 | + {Form("%s_pedestals",GetName()), pedestals, kDouble, NCHAN, 1}, // optional |
| 100 | + {Form("%s_rotmatrix",GetName()), rotations, kDouble, NCHAN, 1}, |
| 101 | + {Form("%s_offsets",GetName()), offsets, kDouble, 2, 1}, |
| 102 | + {Form("%s_mode",GetName()), &fADCMode, kInt, 0, 1}, |
| 103 | + {Form("%s_ped_limit",GetName()), fPedLimit, kInt, NCHAN, 1}, |
| 104 | + {Form("%s_min_ped",GetName()), &fMinPed, kInt, 0, 1}, |
| 105 | + {nullptr} |
| 106 | + }; |
| 107 | + |
| 108 | + gHcParms->LoadParmValues((DBRequest*)&list, prefix); |
| 109 | + |
| 110 | + fOffset.SetXYZ(offsets[0], offsets[1], 0); |
| 111 | + fPedestals.SetElements( pedestals ); |
| 112 | + |
| 113 | + fRot2HCSPos(0,0) = rotations[0]; |
| 114 | + fRot2HCSPos(0,1) = rotations[1]; |
| 115 | + fRot2HCSPos(1,0) = rotations[2]; |
| 116 | + fRot2HCSPos(1,1) = rotations[3]; |
| 117 | + |
| 118 | + return kOK; |
| 119 | +} |
| 120 | + |
| 121 | +//______________________________________________________________ |
| 122 | +Int_t THcBPM::DefineVariables( EMode mode ) |
| 123 | +{ |
| 124 | + |
| 125 | + RVarDef vars[] = { |
| 126 | + {"rawcur.1", "Current in antenna 1", "GetRawSignal0()"}, |
| 127 | + {"rawcur.2", "Current in antenna 2", "GetRawSignal1()"}, |
| 128 | + {"rawcur.3", "Current in antenna 3", "GetRawSignal2()"}, |
| 129 | + {"rawcur.4", "Current in antenna 4", "GetRawSignal3()"}, |
| 130 | + {"x", "reconstructed x position", "fPosition.fX"}, |
| 131 | + {"y", "reconstructed y position", "fPosition.fY"}, |
| 132 | + {"z", "reconstructed z position", "fPosition.fZ"}, |
| 133 | + {"xl", "local x position in bpm system", "GetRotPosX()"}, |
| 134 | + {"yl", "local y position in bpm system", "GetRotPosY()"}, |
| 135 | + { nullptr } |
| 136 | + }; |
| 137 | + |
| 138 | + return DefineVarsFromList( vars, mode ); |
| 139 | +} |
| 140 | + |
| 141 | +//______________________________________________________________ |
| 142 | +void THcBPM::Clear( Option_t* opt ) |
| 143 | +{ |
| 144 | + |
| 145 | + THaBeamDet::Clear(opt); |
| 146 | + fPosition.SetXYZ(0.,0.,-10000.); |
| 147 | + fDirection.SetXYZ(0.,0.,1.); |
| 148 | + for( UInt_t k=0; k<NCHAN; ++k ) { |
| 149 | + fRawSignal(k)=-1; |
| 150 | + fCorSignal(k)=-1; |
| 151 | + } |
| 152 | + |
| 153 | + fRotPos(0) = fRotPos(1) = 0.0; |
| 154 | + |
| 155 | + fNhits = 0; |
| 156 | + frAdcPulseIntRaw->Clear(); |
| 157 | + frAdcPulseInt->Clear(); |
| 158 | + |
| 159 | +} |
| 160 | + |
| 161 | +//______________________________________________________________ |
| 162 | +Int_t THcBPM::Decode( const THaEvData& evdata ) |
| 163 | +{ |
| 164 | + // cout << "THcBPM::Decode" << endl; |
| 165 | + |
| 166 | + fNhits = DecodeToHitList(evdata); |
| 167 | + |
| 168 | + if(gHaCuts->Result("Pedestal_event")) { |
| 169 | + AccumulatePedestals(fRawHitList); |
| 170 | + fAnalyzePedestals = 1; // Analyze pedestals first normal events |
| 171 | + fNPedestalEvents++; |
| 172 | + return(0); |
| 173 | + } |
| 174 | + |
| 175 | + if(fAnalyzePedestals) { |
| 176 | + CalculatePedestals(); |
| 177 | + fAnalyzePedestals = 0; // Don't analyze pedestals next event |
| 178 | + } |
| 179 | + |
| 180 | + Int_t ihit = 0; |
| 181 | + UInt_t nrAdcHits = 0; |
| 182 | + while(ihit < fNhits) { |
| 183 | + THcRasterRawHit* hit = (THcRasterRawHit*)fRawHitList->At(ihit); |
| 184 | + THcRawAdcHit& rawAdcHit = hit->GetRawAdcHitPos(); |
| 185 | + Int_t nsig = hit->fCounter; |
| 186 | + |
| 187 | + Double_t adcTopC = rawAdcHit.GetAdcTopC(); |
| 188 | + |
| 189 | + // pulse data |
| 190 | + for(UInt_t thit = 0; thit < rawAdcHit.GetNPulses(); thit++) { |
| 191 | + ((THcSignalHit*) frAdcPulseIntRaw->ConstructedAt(nrAdcHits))->Set(nsig, rawAdcHit.GetPulseIntRaw(thit)); |
| 192 | + ((THcSignalHit*) frAdcPulseInt->ConstructedAt(nrAdcHits))->Set(nsig, rawAdcHit.GetPulseInt(thit)/adcTopC); // convert back from pC to ADC |
| 193 | + ++nrAdcHits; |
| 194 | + } |
| 195 | + |
| 196 | + // or using simple integral of sample data |
| 197 | + if (rawAdcHit.GetNPulses()==0 && rawAdcHit.GetNSamples()>0 ) { |
| 198 | + Int_t NSA = rawAdcHit.GetF250_NSA(); |
| 199 | + UInt_t LS = 0; |
| 200 | + UInt_t HS = NSA; |
| 201 | + Int_t rawdata = rawAdcHit.GetIntegral(LS,HS); |
| 202 | + |
| 203 | + UInt_t SampPed = rawAdcHit.GetSampPedRaw(); |
| 204 | + // NSA+1: because we call GetIntegral for [0, NSA]; NSA+1 samples |
| 205 | + Double_t PeakPedestalRatio = 1.0 * (NSA+1)/rawAdcHit.GetF250_NPedestalSamples(); |
| 206 | + Double_t data = (rawdata - SampPed * PeakPedestalRatio); |
| 207 | + |
| 208 | + ((THcSignalHit*) frAdcPulseIntRaw->ConstructedAt(nrAdcHits))->Set(nsig, rawdata); |
| 209 | + ((THcSignalHit*) frAdcPulseInt->ConstructedAt(nrAdcHits))->Set(nsig, data); |
| 210 | + ++nrAdcHits; |
| 211 | + } |
| 212 | + ihit++; |
| 213 | + }// loop over hits |
| 214 | + |
| 215 | + // subtract pedestal and fill vectors |
| 216 | + for(Int_t ielem = 0; ielem < frAdcPulseIntRaw->GetEntries(); ielem++) { |
| 217 | + Int_t pad_num = ((THcSignalHit*) frAdcPulseIntRaw->ConstructedAt(ielem))->GetPaddleNumber() - 1; |
| 218 | + Double_t pulseIntRaw = ((THcSignalHit*) frAdcPulseIntRaw->ConstructedAt(ielem))->GetData(); |
| 219 | + Double_t pulseInt = ((THcSignalHit*) frAdcPulseInt->ConstructedAt(ielem))->GetData(); |
| 220 | + |
| 221 | + // We expect N paddle = NCHAN = 4 |
| 222 | + if( pad_num > NCHAN-1 ) { |
| 223 | + Warning(Here("Decode"), "Number of fired channels out of range. Should be <= 4. Ignore the channel."); |
| 224 | + continue; |
| 225 | + } |
| 226 | + |
| 227 | + fRawSignal(pad_num) = pulseIntRaw; |
| 228 | + |
| 229 | + // Subtract pedestals |
| 230 | + if(fADCMode == kDynamicPed){ |
| 231 | + // Use event by event ped subtraction |
| 232 | + fCorSignal(pad_num) = pulseInt; |
| 233 | + } else if (fADCMode == kDBPed ) { |
| 234 | + // Use ped values from DB file (default) |
| 235 | + fCorSignal(pad_num) = fRawSignal(pad_num) - fPedestals(pad_num); |
| 236 | + } else { |
| 237 | + // kCalculatePed |
| 238 | + fCorSignal(pad_num) = fRawSignal(pad_num) - fPed[pad_num]; |
| 239 | + } |
| 240 | + } |
| 241 | + |
| 242 | + return fNhits; |
| 243 | +} |
| 244 | + |
| 245 | +//______________________________________________________________ |
| 246 | +Int_t THcBPM::Process( ) |
| 247 | +{ |
| 248 | + // Calculate position and directions |
| 249 | + // (x, y)_lab = Cij * (x, y)_bpm + (offset_x, offset_y) |
| 250 | + |
| 251 | + // First calculate position in bpm coord system |
| 252 | + // assume 0:x+ 1:x- 2:y+ 3:y- |
| 253 | + for(Int_t k = 0; k < NCHAN; k += 2) { |
| 254 | + Double_t ap = fCorSignal(k); |
| 255 | + Double_t am = fCorSignal(k+1); |
| 256 | + |
| 257 | + fRotPos(k / 2) = 0.0; |
| 258 | + if( ap + am != 0.0 ) |
| 259 | + fRotPos(k / 2) = fCalibRot * (ap - am) / (ap + am); |
| 260 | + } |
| 261 | + |
| 262 | + // transform it into the HCS |
| 263 | + TVectorD temp(fRotPos); |
| 264 | + temp *= fRot2HCSPos; |
| 265 | + fPosition.SetXYZ( temp(0) + fOrigin(0) + fOffset(0), |
| 266 | + temp(1) + fOrigin(1) + fOffset(1), |
| 267 | + fOrigin(2) ); |
| 268 | + |
| 269 | + return 0; |
| 270 | +} |
| 271 | + |
| 272 | +//______________________________________________________________ |
| 273 | +void THcBPM::InitializePedestals() |
| 274 | +{ |
| 275 | + |
| 276 | + fNPedestalEvents = 0; |
| 277 | + fPed = new Int_t [NCHAN]; |
| 278 | + fPedSum = new Int_t [NCHAN]; |
| 279 | + fPedCount = new Int_t [NCHAN]; |
| 280 | + fPedLimit = new Int_t [NCHAN]; |
| 281 | + for(Int_t i = 0; i < NCHAN; i++) { |
| 282 | + fPed[i] = 0; |
| 283 | + fPedSum[i] = 0; |
| 284 | + fPedCount[i] = 0; |
| 285 | + fPedLimit[i] = 1000; |
| 286 | + } |
| 287 | + |
| 288 | +} |
| 289 | + |
| 290 | +//______________________________________________________________ |
| 291 | +void THcBPM::AccumulatePedestals( TClonesArray* rawhits ) |
| 292 | +{ |
| 293 | + |
| 294 | + UInt_t nhits = rawhits->GetLast() + 1; |
| 295 | + |
| 296 | + for(UInt_t ihit = 0; ihit < nhits; ihit++) { |
| 297 | + THcRasterRawHit* hit = (THcRasterRawHit*)fRawHitList->At(ihit); |
| 298 | + |
| 299 | + Int_t ielem = hit->fCounter -1; |
| 300 | + Int_t rawadc = hit->GetRawAdcHitPos().GetPulseIntRaw(); |
| 301 | + |
| 302 | + if(rawadc <= fPedLimit[ielem]) { |
| 303 | + fPedSum[ielem] += rawadc; |
| 304 | + fPedCount[ielem]++; |
| 305 | + |
| 306 | + //fMinPed is hard-coded value, 500 |
| 307 | + if(fPedCount[ielem] == fMinPed/5) { |
| 308 | + fPedLimit[ielem] = 100 + fPedSum[ielem]/fPedCount[ielem]; |
| 309 | + } |
| 310 | + } |
| 311 | + }//loop over hits |
| 312 | + |
| 313 | +} |
| 314 | + |
| 315 | +//______________________________________________________________ |
| 316 | +void THcBPM::CalculatePedestals() |
| 317 | +{ |
| 318 | + // Calculate pedestal mean |
| 319 | + for(Int_t i = 0; i < NCHAN; i++) { |
| 320 | + fPed[i] = (Double_t)fPedSum[i]/TMath::Max(1, fPedCount[i]); |
| 321 | + } |
| 322 | + |
| 323 | +} |
| 324 | + |
| 325 | +ClassImp(THcBPM) |
0 commit comments