MuTr Calibration Response

This page shows a summary of how the MuTr electronics response can be, and has been parametrized, how it is being stored in Objy and how it can be accessed/used in offline or elsewhere. For the plots, I'm using calibration runs taken in the end of April'02. I use the same channels for the comparison between different versions.

Linear version: used in Run-2

The first version of the calibrations used a linear parametrization between DAC and ADC values:
ADC = pedestal + gain*DAC
Throughout this page I use the 'convenient ADC notation' which is 1800 minus the real recorded ADC value. This has the property of giving a pedestal around 0 and a 'signal' which grows with input/DAC. As you can see in the image below to the left, the linear parametrization is a rather good approximation, but not quite perfect as seen in the image below to the right:



Linear response [Left] ADC vs DAC for a typical channel [Right] Residuals for ~128 channels (One Station 2 FEM). (profile histogram)

Non-linear version: for the future

By simply adding more free parameters we should be able to reproduce the response better.. To amplify the deviations, and perhaps better understand the response, I looked at the difference between neighboring bins, shown below to the left. I then parametrized this difference behaviour with a square (2nd degree) term for the distance to the center (also a free parameter) of the distribution. I used different terms for values below and above the center.


[Left] Neighboring bin difference (ADC counts) vs DAC for the same typical channel [Right] For all channels in the same fem (box plot).

If we move on to higher DAC values, or look at Station 3, which has a higher gain, we will approach the region where the preamp saturates, giving rise to a linear trend in the difference between neighboring bins. The saturation appears to kick in at about 1600 ADC counts. (You see a hint of it in the plots above at the high DAC end also) The corresponding DAC value is stored as a parameter named Saturation. The slope of the difference between bins at these rather high DAC values is stored as LinSat, which is also a free parameter during the fitting. The relation between DAC and ADC values, and the difference between neighboring bins for a station 3 FEM is shown below (as before: the markers indicate the mean and error of the mean):

Note that the step size was four times larger than for the plot above. This (16, 0x10) is the normal step size for calibrations. In total, we thus have four new free parameters, in addition to the two we had previously. The new calibration software is thus significantly slower than the old version; now roughly ten minutes for the south arm. Since the calibrations are done once per day during the run we should however be able to keep up.. I have started looking into using LUTs instead of the slow step method now used, which should be able to speed things up. The threshold files can be (are) generated before the fitting starts and should thus be available shortly after the calibration runs were taken. The online monitoring software has been upgraded to use a similar style (reusing is always nice). Check out the software on cvsweb if you want. The resulting residuals are plotted below, for all channels in the station 3 FEM. The left one is the old linear and the one on the right is with the extra parameters. On the average we thus keep within a few counts now. A significant improvement was made and we should be able to go further out into the saturation but at the cost of adding more parameters.

Objy/PdbCal: PdbMutCalibStrip

Most variables in PdbMutCalibStrip are hopefully selfexplanatory to muon folks.

The different extra parameters I described in the previous section are named: Center, SqrLow, SqrHigh and LinSat respectively.
The variable Status is used to describe how the fitting worked (-999 = not fitted, 0 = good, 1000 = refit needed with a fixed center, 1000 + XYZ = failure, XYZ is a bit code of which parameters that hit the limits). Step tells us which size of steps are supposed to be used in the getAdc(dac) and getDac(adc) methods. Having these methods accept and return floats would perhaps have been convenient but I just couldn't bring myself to do that. I/O is handled via standard iostreams.

Offline/Mut: MutCalibStrip

MutCalibStrip. Just holds an 'dynamic' STL set of strips. Routines for reading to/from ASCII and Objy.

Examples of usage


void test(const char *infile = "in.txt", 
	  const char *outfile = "out.txt")
{
  
  cout << "starting...." << endl;
  // load the shared libraries
  gSystem->Load("libvtx.so");
  gSystem->Load("libmut.so");
  cout << "libraries loaded..." << endl;

  MutCalibStrip *cobj = new MutCalibStrip();

  // ASCII I/O
  cobj->txtGetAll(infile); // infile must match what PdbMutCalibStrip expects to read
  cobj->txtPutAll(outfile);

  cout << "trying to get hold of a real strip" << endl;
  PdbMutCalibStrip *p2 = cobj->getPdbMutCalibStrip(0,0,0,0,0,0,1);

  cout << "did we get it?" << endl;
  if (p2) 
    {
      p2.print();
      cout << "changing pedestal value" << endl;
      p2.set_pedestal(999.999);
      p2.print();
    }
  //  cobj->putPdbMutCalibStrip(p2); // needed to change value in set

  cout << "Id and name: " << endl;
  int uniqid = p3.getUniqueId(); // bit packed, used for automatic sorting in set
  cout << hex << uniqid << dec << endl;

  char *name = "muTr_ArmX_StaY_OctZ_HOctW_GapI_PlaneJ_StripK";
  bool nameok = p3.getName(name);
  cout << name << endl;

  int nstrips = cobj->getNumberOfStrips();
  cout << "nstrips = " << nstrips << endl;
 
  delete cobj;
}

The following macros can be used for putting stuff into the database or retrieving it, respectively. You probably want to change the timestamps and the descriptive string for your use, though.

void dbputall(const char *infile = "in.txt") { cout << "starting...." << endl; // load the shared libraries gSystem->Load("libvtx.so"); gSystem->Load("libPdbCal.so"); gSystem->Load("libmut.so"); cout << "libraries loaded..." << endl; MutCalibStrip *cobj = new MutCalibStrip(); cobj->txtGetAll(infile); PHTimeStamp start(2002,04,28,15,0,0); PHTimeStamp stop(2002,04,29,16,0,0); PHString descriptor("DS - test calibration"); cout << "start: " << start << endl; cout << "stop: " << stop << endl; cout << "descriptor: " << descriptor << endl;; cobj->dbPutAll(start, stop, descriptor); delete cobj; } void dbgetall(const char *outfile = "outdb.txt") { cout << "starting...." << endl; // load the shared library gBenchmark->Start("test"); gSystem->Load("libvtx.so"); gSystem->Load("libPdbCal.so"); gSystem->Load("libmut.so"); cout << "libraries loaded..." << endl; MutCalibStrip *cobj = new MutCalibStrip(); PHTimeStamp tsearch(2002,04,29,0,0,0); cout << "tsearch: " << tsearch << endl; cobj->dbGetAll(tsearch); cobj->txtPutAll(outfile); delete cobj; gBenchmark->Show("test"); }



silvermy@lanl.gov 2002