enum STSTestReturnValues { StsOK = 0, StsError, StsGlitch }; void hdipart(const char* name, ChipEnv *env=cEnvP) { int len=32; env->pname=new char[len+1]; strcpy(env->pname,name); sscanf(env -> pname,"h%d-%d",&env->ptype,&env->pnum); if(env->ptype<1 || env->ptype>3) { cout<<"error unrecognized part name "<ptype=-1; return; } env->nSideN=nChips[env->ptype-1][0]; env->pSideN=nChips[env->ptype-1][1]; ExpandChipArray(env,env->nSideN+env->pSideN); env->pinit=1; } void DumpThresh(UInt_t run, UInt_t charge) { char buf[256]; Int_t i; TH2S *hnew; sprintf(buf,"r%05d-q%d.root",run,charge); hfile = new TFile(buf,"NEW",buf); for (i = 0 ; i < 2 * nChips[cEnvP->ptype-1][0] ; i ++) { sprintf(buf,"chip%02d-tscan",i); hnew = (TH2S*) cEnvP->cArrayP[i]->sHstP -> Clone(); hnew -> SetName(buf); } hfile -> Write(); } Bool_t CheckState() { //this function verifies the most basic function of the hdi //test stand. if we can write a control register and read it //back out, we assume the stand is set up properly and working //fine. do this 10x for redundancy. //returns kFALSE on failure, kTRUE on success. UInt_t cr; inject(0x1e,0); //reset inject(0x1 ,0); //clear readout inject(0x2 ,0); //sync for (Int_t i = 0 ; i < 10 ; i ++) { wrcntrl(defControl,0); cr = readcr(0); if (cr != (defControl | 0x80000000)) return kFALSE; inject(0x1e,0); } return kTRUE; } void DoDigital(UInt_t chipLow, UInt_t chipHigh, UInt_t run, UInt_t chipsPerSide) { UInt_t curChip; char filename[256]; Int_t ret; sprintf(filename,"r%05d_digital.log",run); ofstream outfile(filename); for (UInt_t curChip = chipLow ; curChip <= chipHigh ; curChip++) { outfile << "Testing chip " << curChip << endl; outfile << " Testing Clk/Cmd A, readout to the left" << endl; if (ret = DoChipDigital(curChip, outfile, clockA, rLeft, chipsPerSide)) { outfile << "Received error " << ret << endl; } outfile << " Testing Clk/Cmd A, readout to the right" << endl; if (ret = DoChipDigital(curChip, outfile, clockA, rRight, chipsPerSide)) { outfile << "Received error " << ret << endl; } /* outfile << " Testing Clk/Cmd B, readout to the left" << endl; if (ret = DoChipDigital(curChip, outfile, clockB, rLeft, chipsPerSide)) { outfile << "Received error " << ret << endl; } */ /* outfile << " Testing Clk/Cmd B, readout to the right" << endl; if (ret = DoChipDigital(curChip, outfile, clockB, rRight, chipsPerSide)) { outfile << "Received error " << ret << endl; } */ outfile << endl; } outfile.close(); setclk(clockAB); } Int_t DoChipDigital(UInt_t chip, ofstream &file, int clock, int rdir, UInt_t chipsPerSide) { Bool_t error = kFALSE; UInt_t reg, mask; UInt_t writeCR, readCR; StsAtomMask writeCalMask, writeChaMask; StsAtomMask readCalMask, readChaMask; char str[256]; Int_t temp, master; mask = 0x80000000 | //clock sel status 0x40000000 | //clock select 0x00800000 | // readout dir 0x01000000 | //resp to read 0x02000000 ; // clock through inject(0x1e,chip); if (clock == clockA) { setclk(clock0); gSystem -> Sleep(1); setclk(clockA); } else { setclk(clockB); } writeCR = 0x0; if (clock == clockB) writeCR |= 0x40000000; if (rdir == rRight) writeCR |= 0x00800000; if (rdir == rLeft) { if (chip < chipsPerSide) master = 0; else master = chipsPerSide; for (temp = chip - 1 ; temp > master ; temp --) { cout << "attempting to align rLeft " << temp << endl; inject(0x1e,temp); wrcntrl(writeCR, temp); file << "aligning rLeft chip " << temp << endl; } } else { if (chip < chipsPerSide) master = chipsPerSide - 1; else master = 2 * chipsPerSide - 1; for (temp = chip + 1 ; temp < master ; temp ++) { inject(0x1e,temp); wrcntrl(writeCR, temp); file << "aligning rRight chip " << temp << endl; } } if (chip != master) { writeCR |= 0x01000000; inject(0x1e,master); wrcntrl(writeCR, master); file << "aligning master chip " << master << endl; } cout << "beginning CR walking 1's test" << endl; file << " beginning CR walking 1's test" << endl; reg = 0x1; while (reg) { if ((reg & mask) == 0x0) { writeCR = reg; if (rdir == rRight) writeCR |= 0x00800000; if (clock == clockB) writeCR |= 0x40000000; else writeCR |= 0x80000000; if (chip == master) writeCR |= 0x01000000; cout << (void*)writeCR << endl; wrcntrl(writeCR, chip); readCR = readcr(chip, rdir); if (readCR == 0x80000000) { return StsGlitch; } if (readCR != writeCR) { cout << (void*)readCR << " was read. should be " << (void*)writeCR << endl; sprintf(str,"0x%x 0x%x\n",readCR, writeCR); file << str; error = kTRUE; } } reg <<= 1; } cout << "beginning CR walking 0's test" << endl; file << " beginning CR walking 0's test" << endl; reg = 0x1; while (reg) { if ((reg & mask) == 0) { writeCR = ~reg; writeCR &= ~(0x02000000); if (rdir == rLeft) writeCR &= ~(0x00800000); if (clock == clockB) writeCR &= ~(0x80000000); else writeCR &= ~(0x40000000); wrcntrl(writeCR, chip); readCR = readcr(chip, rdir); if (readCR == 0x80000000) { return StsGlitch; } if (readCR != writeCR) { cout << (void*)readCR << " was read. should be " << (void*)writeCR << endl; sprintf(str,"0x%x 0x%x\n",readCR, writeCR); file << str; error = kTRUE; } } reg <<= 1; } /* inject(0x1e,chip); writeCR = 0; if (rdir == rRight) writeCR |= 0x00800000; if (clock == clockA) writeCR |= 0x80000000; else writeCR |= 0x40000000; wrcntrl(writeCR, chip); cout << "beginning cal mask walking 1's test" << endl; file << " beginning cal mask walking 1's test" << endl; writeCalMask.SetAllBits(0); for (reg = 0 ; reg < 128 ; reg ++) { writeCalMask.SetMaskBit(reg); cout << writeCalMask; wrmasks(chip,fee,writeCalMask,writeChaMask); readmr(chip,rdir,&readCalMask,&readChaMask); cout << "mr returned okay" << endl; if (!(readCalMask == writeCalMask)) { file << readCalMask << " " << writeCalMask << endl; readCR = readcr(chip,rdir); if (readCR == 0x80000000) return StsGlitch; error = kTRUE; } writeCalMask.ClearMaskBit(reg); } cout << "beginning cal mask walking 0's test" << endl; file << " beginning cal mask walking 0's test" << endl; writeCalMask.SetAllBits(0xffffffff); for (reg = 0 ; reg < 128 ; reg ++) { writeCalMask.ClearMaskBit(reg); cout << writeCalMask; wrmasks(chip,fee,writeCalMask,writeChaMask); readmr(chip,rdir,&readCalMask,&readChaMask); cout << "mr returned okay" << endl; if (!(readCalMask == writeCalMask)) { file << readCalMask << " " << writeCalMask << endl; readCR = readcr(chip,rdir); if (readCR == 0x80000000) return StsGlitch; error = kTRUE; } writeCalMask.SetMaskBit(reg); } cout << "beginning cha mask walking 1's test" << endl; file << " beginning cha mask walking 1's test" << endl; writeChaMask.SetAllBits(0); for (reg = 0 ; reg < 128 ; reg ++) { writeChaMask.SetMaskBit(reg); cout << writeChaMask; wrmasks(chip,fee,writeCalMask,writeChaMask); readmr(chip,rdir,&readCalMask,&readChaMask); cout << "mr returned okay" << endl; if (!(readChaMask == writeChaMask)) { file << readChaMask << " " << writeChaMask << endl; readCR = readcr(chip,rdir); if (readCR == 0x80000000) return StsGlitch; error = kTRUE; } writeChaMask.ClearMaskBit(reg); } cout << "beginning cha mask walking 0's test" << endl; file << " beginning cha mask walking 0's test" << endl; writeChaMask.SetAllBits(0xffffffff); for (reg = 0 ; reg < 128 ; reg ++) { writeChaMask.ClearMaskBit(reg); cout << writeChaMask; wrmasks(chip,fee,writeCalMask,writeChaMask); readmr(chip,rdir,&readCalMask,&readChaMask); cout << "mr returned okay" << endl; if (!(readChaMask == writeChaMask)) { file << readChaMask << " " << writeChaMask << endl; readCR = readcr(chip,rdir); if (readCR == 0x80000000) return StsGlitch; error = kTRUE; } writeChaMask.SetMaskBit(reg); } */ if (error) return StsError; return StsOK; } void DoThreshTests(UInt_t chipLow, UInt_t chipHigh, UInt_t run, Int_t *qArray, UInt_t events, UInt_t maskN, char *partName, Bool_t bonded = kFALSE) { UInt_t curCharge, chargeAccum; Bool_t scanbad; chargeAccum = 0; for (curCharge = 0 ; curCharge < 64 ; curCharge ++) { if (!qArray[curCharge]) continue; scanbad = (curCharge == 3); chargeAccum ++; cout << "beginning tscan, charge=" << curCharge << endl; DoThresh(chipLow, chipHigh, run, curCharge, events, maskN, partName, scanbad,bonded); DumpThresh(run, curCharge); } if (chargeAccum < 3) return; //do gain extraction now... char buf[256]; FILE *inFile; ofstream outFile, badfile; Int_t chan, x, y, numChips; Float_t thresh, threshE, noise, noiseE; Double_t intercept, gain, interceptE, gainE; numChips = 1 + chipHigh - chipLow; sprintf(buf,"r%05d_threshold.fits",run); outFile.open(buf); sprintf(buf,"r%05d_threshold_badgains.list",run); badfile.open(buf); TH1F *channels[128*20]; Bool_t badChannels[128*20]; for (x = 0 ; x < numChips * 128 ; x ++) { sprintf(buf,"chan%04d",x); channels[x] = new TH1F(buf,"",64,0,64); } for (curCharge = 0 ; curCharge < 64 ; curCharge ++) { if (!qArray[curCharge]) continue; sprintf(buf,"r%05d_threshold_q%02d.data",run,curCharge); cout << "opening threshold scan file " << buf << endl; inFile = fopen(buf,"rt"); for (x = 0 ; x < numChips ; x ++) { fgets(buf,256,inFile); cout << buf; for (y = 0 ; y < 128 ; y ++) { fscanf(inFile,"%d %f %f %f %f\n",&chan,&thresh,&threshE, &noise, &noiseE); badChannels[x*128+y] = (thresh < 0); channels[x*128+y] -> SetBinContent(curCharge + 1,thresh); channels[x*128+y] -> SetBinError (curCharge + 1,threshE); } } fclose(inFile); } TH1F *hInt = new TH1F("hint" ,"",128*numChips,-0.5,128*numChips-0.5); TH1F *hGain = new TH1F("hgain","",128*numChips,-0.5,128*numChips-0.5); TF1 *func = new TF1("func","[0]*x+[1]",0,64); for (x = 0 ; x < numChips ; x ++) { outFile << "--- Chip " << x + chipLow << " ---" << endl; for (y = 0 ; y < 128 ; y ++) { channels[x*128+y] -> Fit("func","NOR"); gain = func -> GetParameter(0); intercept = func -> GetParameter(1); gainE = func -> GetParError (0); interceptE = func -> GetParError (1); intercept -= gain * 0.5; if (badChannels[x*128+y]) { gain = -100; intercept = -1; gainE = 0; interceptE = 0; } hInt -> SetBinContent(x*128+y+1,intercept ); hInt -> SetBinError (x*128+y+1,interceptE); hGain -> SetBinContent(x*128+y+1,gain ); hGain -> SetBinError (x*128+y+1,gainE ); sprintf(buf,"%3d\t%f\t%f\t%f\t%f\n",y,intercept,interceptE, gain, gainE); outFile << buf; if ((gain < -15) || (gain > -5)) { sprintf(buf,"Chip %2d Chan %3d Gain %f\n",x+chipLow,y,gain); badfile << buf; } } } c1 = new TCanvas("gain_canvas","gain extraction results",900,600); c1 -> SetFillColor(kWhite); pad1 = new TPad("pad1","int pad" ,0.01,0.49,0.99,0.96,kWhite,0,0); pad2 = new TPad("pad2","gain pad",0.01,0.01,0.99,0.48,kWhite,0,0); pad1 -> Draw(); pad2 -> Draw(); gStyle -> SetOptStat(0); hInt -> GetXaxis() -> SetLabelOffset(2); hInt -> GetXaxis() -> SetTickLength(0); hInt -> GetYaxis() -> SetTitle("Intercept (DAC counts)"); hInt -> GetYaxis() -> CenterTitle(); hInt -> GetYaxis() -> SetTickLength(0); hInt -> GetYaxis() -> SetTitleOffset(0.7); hInt -> SetMinimum(40); hInt -> SetMaximum(80); hGain -> GetXaxis() -> SetLabelOffset(2); hGain -> GetXaxis() -> SetTickLength(0); hGain -> GetYaxis() -> SetTitle("Gain (DAC counts)"); hGain -> GetYaxis() -> CenterTitle(); hGain -> GetYaxis() -> SetTickLength(0); hGain -> GetYaxis() -> SetTitleOffset(0.7); hGain -> SetMinimum(-20); hGain -> SetMaximum(-2); TGaxis *axisArray[20][2]; for (x = 0 ; x < numChips ; x ++) { axisArray[x][0] = new TGaxis(128*x-0.5,40,128*x-0.5,80,0,80,510,"U-S"); axisArray[x][0] -> SetTickSize(0.01); axisArray[x][1] = new TGaxis(128*x-0.5,-20,128*x-0.5,-2,-20,-2,510,"U-S"); axisArray[x][1] -> SetTickSize(0.01); } TText *t = new TText(); t -> SetTextSize(0.055); t -> SetTextAlign(20); pad1 -> cd(); hInt -> Draw(); for (x = 0 ; x < numChips ; x ++) { axisArray[x][0] -> Draw(); sprintf(buf,"%d",x + chipLow); t -> DrawText(128*x+60,36,buf); } pad2 -> cd(); hGain -> Draw(); for (x = 0 ; x < numChips ; x ++) { axisArray[x][1] -> Draw(); sprintf(buf,"%d",x + chipLow); t -> DrawText(128*x+60,-22,buf); } c1 -> cd(); t -> SetTextSize(0.03); t -> SetTextAlign(22); sprintf(buf,"Threshold Scan Part %s Run #%d Gain Fits",partName,run); t -> DrawText(0.5,0.98,buf); sprintf(buf,"tscan-fits.ps"); c1 -> SaveAs(buf); } void DoThresh(UInt_t chipLow, UInt_t chipHigh, UInt_t run, UInt_t charge, UInt_t events, UInt_t maskN, char *partName, Bool_t scanbad, Bool_t bonded) { char buf[256]; sprintf(buf,"r%05d_threshold_q%02d.data",run,charge); ofstream datafile(buf); if (scanbad) { sprintf(buf,"r%05d_threshold_scanbad.list",run); cout << buf; ofstream badfile(buf); Float_t noiseMin = -1; if (bonded) noiseMin = 1.6; Float_t noiseMax = 6; Float_t threshMin = 1; Float_t threshMax = 63; Float_t threshMaxE = 2; Float_t noiseMaxE = 2; } sprintf(buf,"canvas%d",charge); c1 = new TCanvas(buf,"threshold scan results",900,600); c1 -> SetFillColor(kWhite); pad1 = new TPad("pad1","thresh pad",0.01,0.49,0.99,0.96,kWhite,0,0); pad2 = new TPad("pad2","noise pad", 0.01,0.01,0.99,0.48,kWhite,0,0); pad1 -> Draw(); pad2 -> Draw(); UInt_t nChans = 128 * (chipHigh + 1 - chipLow); sprintf(buf,"hthresh%d",charge); TH1F *hThresh = new TH1F(buf,"",nChans,-0.5,nChans+0.5); sprintf(buf,"hnoise%d",charge); TH1F *hNoise = new TH1F(buf,"",nChans,-0.5,nChans+0.5); hdipart(partName); cEnvP -> nCharge = charge; cEnvP -> pCharge = defChargeOffset - charge; if (cEnvP -> pCharge > 63) cEnvP -> pCharge = 63; UInt_t nchips = nChips[cEnvP -> ptype - 1][0]; UInt_t cOffset = cEnvP -> pCharge + cEnvP -> nCharge; calInit(charge, -1 , cEnvP -> ptype, -1, -1, bSide, ((cEnvP -> pconf == 0) ? 1 : 0), defControl, cOffset); cEnvP -> pconf = 1; tscan(events, -1, 63, 0, 1, maskN, gHdi, cEnvP); UInt_t curChip, i, curChan; for (curChip = chipLow ; curChip <= chipHigh ; curChip ++) { datafile << "--- Chip " << curChip << " ---" << endl; ffit(curChip); ChipScan *scanP = cEnvP -> cArrayP[curChip]; float *threshA = scanP -> tFitP -> GetArray() + 1; float *noiseA = scanP -> nFitP -> GetArray() + 1; float *threshE = scanP -> ttsFitP -> GetArray() + 1; float *noiseE = scanP -> nnsFitP -> GetArray() + 1; for (i = 0 ; i < 128 ; i ++) { curChan = 128 * (curChip - chipLow) + i; sprintf(buf, "%3d\t%f\t%f\t%f\t%f\n",i,threshA[i],threshE[i], noiseA[i],noiseE[i]); datafile << buf; hThresh -> SetBinContent(curChan+1,threshA[i]); hThresh -> SetBinError (curChan+1,threshE[i]); hNoise -> SetBinContent(curChan+1,noiseA[i]); hNoise -> SetBinError (curChan+1,noiseE[i]); if (scanbad) { if ((threshA[i] < threshMin) || (threshA[i] > threshMax) || (threshE[i] > threshMaxE) || (noiseA[i] < noiseMin) || (noiseA[i] > noiseMax) || (noiseE[i] > noiseMaxE)) { sprintf(buf,"Chip %2d Chan %3d %f\t%f\t%f\t%f\n", curChip, i, threshA[i], threshE[i], noiseA[i], noiseE[i]); //badfile << buf; } } } } gStyle -> SetOptStat(0); hThresh -> GetXaxis() -> SetLabelOffset(2); hThresh -> GetXaxis() -> SetTickLength(0); hThresh -> GetYaxis() -> SetTitle("Thresh (DAC Counts)"); hThresh -> GetYaxis() -> CenterTitle(); hThresh -> GetYaxis() -> SetTickLength(0); hThresh -> GetYaxis() -> SetTitleOffset(0.7); hThresh -> SetMaximum(60.0); hThresh -> SetMinimum(0.0); hNoise -> GetXaxis() -> SetLabelOffset(2); hNoise -> GetXaxis() -> SetTickLength(0); hNoise -> GetYaxis() -> SetTitle("Noise (DAC Counts)"); hNoise -> GetYaxis() -> CenterTitle(); hNoise -> GetYaxis() -> SetTickLength(0); hNoise -> GetYaxis() -> SetTitleOffset(0.7); hNoise -> SetMaximum(6.0); hNoise -> SetMinimum(0.0); UInt_t j; TGaxis *axisArray[20][2]; for (j = 0 ; j <= chipHigh - chipLow ; j ++) { axisArray[j][0] = new TGaxis(128*j-0.5,0,128*j-0.5,60,0,60,510,"U-S"); axisArray[j][0] -> SetTickSize(0.01); axisArray[j][1] = new TGaxis(128*j-0.5,0,128*j-0.5,6 ,0,6 ,510,"U-S"); axisArray[j][1] -> SetTickSize(0.01); } TText *t = new TText(); t -> SetTextSize(0.055); t -> SetTextAlign(20); pad1 -> cd(); hThresh -> Draw(); for (j = 0 ; j <= chipHigh - chipLow ; j ++) { axisArray[j][0] -> Draw(); sprintf(buf,"%d",j+chipLow); t -> DrawText(128*j+60,-4,buf); } pad2 -> cd(); hNoise -> Draw(); for (j = 0 ; j <= chipHigh - chipLow ; j ++) { axisArray[j][1] -> Draw(); sprintf(buf,"%d",j+chipLow); t -> DrawText(128*j+60,-0.5,buf); } c1 -> cd(); t -> SetTextSize(0.03); t -> SetTextAlign(22); sprintf(buf,"Threshold Scan Part %s Run #%d Charge %d",partName,run,charge); t -> DrawText(0.5,0.98,buf); sprintf(buf,"tscan-q%d.ps",charge); c1 -> SaveAs(buf); }