QuarkNet students' results

Data processing

Trimming strips

After the data for an HV point has been collected by the data harvesting script, the noise for each APV is run over and trimmed; the categories of strips considered are "noisy", "dead", and "normal". Those strips ruled as normal will continue to the output portion of the data harvester. This is achieved by comparing each $i$ strip's (mean) noise value to a running mean and rms, which are updated with each following strip's (mean) noise value. In this way we can cut strips which locally diverge but keep strips that may appear to the eye to be outliers, but are within the APV's noise behavior in previous strips. We perform this isntead of the individual comparison to the total APV's strips' mean noise and rms noise to speed up the data harvesting --- we can perform this as the values from each APV are read in.

For some strip's noise value $\sigma_i$, that strip is marked as noisy if and a strip is marked dead if

In addition to dead or noisy strips, there are also those which register a cosmic event which passes the (random) trigger; such an occurrence looks like the following example:

Sep2012 Analyzing Noise Bias Scan data for partition TECM 30 V| Dead strips: 185 | Noisy strips: 12 | Total strips: 1916416 | 45 V| Dead strips: 167 | Noisy strips: 19 | Total strips: 1916416 | 60 V| Dead strips: 169 | Noisy strips: 23 | Total strips: 1916416 | 75 V| Dead strips: 169 | Noisy strips: 26 | Total strips: 1916416 | 90 V| Dead strips: 171 | Noisy strips: 34 | Total strips: 1916416 | 105 V| Dead strips: 172 | Noisy strips: 51 | Total strips: 1916416 | 120 V| Dead strips: 162 | Noisy strips: 61 | Total strips: 1916416 | 135 V| Dead strips: 161 | Noisy strips: 76 | Total strips: 1916416 | 150 V| Dead strips: 169 | Noisy strips: 83 | Total strips: 1916416 | 165 V| Dead strips: 168 | Noisy strips: 103 | Total strips: 1916416 | 180 V| Dead strips: 159 | Noisy strips: 122 | Total strips: 1916416 | 195 V| Dead strips: 160 | Noisy strips: 123 | Total strips: 1916416 | 210 V| Dead strips: 155 | Noisy strips: 145 | Total strips: 1916416 | 225 V| Dead strips: 157 | Noisy strips: 154 | Total strips: 1916416 | 240 V| Dead strips: 153 | Noisy strips: 169 | Total strips: 1916416 | 250 V| Dead strips: 156 | Noisy strips: 179 | Total strips: 1916416 | 260 V| Dead strips: 157 | Noisy strips: 190 | Total strips: 1916416 | 275 V| Dead strips: 157 | Noisy strips: 214 | Total strips: 1916416 | 290 V| Dead strips: 156 | Noisy strips: 245 | Total strips: 1916416 | 300 V| Dead strips: 153 | Noisy strips: 265 | Total strips: 1916416 | 325 V| Dead strips: 154 | Noisy strips: 352 | Total strips: 1916416 | 350 V| Dead strips: 151 | Noisy strips: 485 | Total strips: 1916416 |

Trimmed APV post-mortem report for Sep2012 TECM :

Point-by-point: HV # empty APVs # dead APVs # noisy APVs # APVs with large error bars # APVs with large first value: # surviving APVs total # APVs
30.0 V: 0 0 0 0 0 0 0
45.0 V: 0 0 0 0 0 0 0
60.0 V: 0 0 0 0 0 0 0
75.0 V: 0 0 0 0 0 14948 14948
90.0 V: 0 0 0 0 0 14956 14956
105.0 V: 0 0 0 0 0 14956 14956
120.0 V: 0 0 0 1 0 14956 14956
135.0 V: 0 0 0 4 0 14956 14956
150.0 V: 0 0 0 1 0 14956 14956
165.0 V: 0 0 0 5 0 14956 14956
180.0 V: 0 0 0 2 0 14956 14956
195.0 V: 0 0 0 2 0 14956 14956
210.0 V: 0 0 0 1 0 14956 14956
225.0 V: 0 0 0 3 0 14957 14957
240.0 V: 0 0 0 5 0 14956 14956
250.0 V: 0 0 0 5 0 14956 14956
260.0 V: 0 0 0 8 0 14955 14955
275.0 V: 0 0 0 7 0 14956 14956
290.0 V: 0 0 0 18 0 14956 14956
300.0 V: 0 0 2 13 0 14954 14956
325.0 V: 0 0 0 32 0 14954 14954
350.0 V: 16 0 2 39 8 0 2
| APV profiles: | Dead APVs: 14952 | noisy APVs: 20 | survivors: 0

Analyzing Noise Bias Scan data for partition TECP 30 V| Dead strips: 186 | Noisy strips: 6 | Total strips: 1911040 | 45 V| Dead strips: 178 | Noisy strips: 15 | Total strips: 1911040 | 60 V| Dead strips: 183 | Noisy strips: 19 | Total strips: 1911040 | 75 V| Dead strips: 181 | Noisy strips: 30 | Total strips: 1911040 | 90 V| Dead strips: 179 | Noisy strips: 35 | Total strips: 1911040 | 105 V| Dead strips: 180 | Noisy strips: 44 | Total strips: 1911040 | 120 V| Dead strips: 179 | Noisy strips: 53 | Total strips: 1911040 | 135 V| Dead strips: 172 | Noisy strips: 67 | Total strips: 1911040 | 150 V| Dead strips: 174 | Noisy strips: 83 | Total strips: 1911040 | 165 V| Dead strips: 172 | Noisy strips: 97 | Total strips: 1911040 | 180 V| Dead strips: 173 | Noisy strips: 111 | Total strips: 1911040 | 195 V| Dead strips: 171 | Noisy strips: 121 | Total strips: 1911040 | 210 V| Dead strips: 170 | Noisy strips: 127 | Total strips: 1911040 | 225 V| Dead strips: 171 | Noisy strips: 140 | Total strips: 1911040 | 240 V | Dead strips: 169 | Noisy strips: 151 | Total strips: 1911040 | 250 V| Dead strips: 176 | Noisy strips: 168 | Total strips: 1911040 | 260 V| Dead strips: 178 | Noisy strips: 175 | Total strips: 1911040 | 275 V| Dead strips: 172 | Noisy strips: 191 | Total strips: 1911040 | 290 V| Dead strips: 169 | Noisy strips: 215 | Total strips: 1911040 | 300 V| Dead strips: 172 | Noisy strips: 238 | Total strips: 1911040 | 325 V| Dead strips: 173 | Noisy strips: 320 | Total strips: 1911040 | 350 V| Dead strips: 176 | Noisy strips: 452 | Total strips: 1911040 |

Trimmed APV post-mortem report for Sep2012 TECP :

Point-by-point: HV # empty APVs # dead APVs # noisy APVs # APVs with large error bars # APVs with large first value: # surviving APVs total # APVs
30.0 V: 0 0 0 0 0 0 0
45.0 V: 0 0 0 0 0 0 0
60.0 V: 0 0 0 0 0 0 0
75.0 V: 0 0 0 1 0 14927 14927
90.0 V: 0 0 0 1 0 14930 14930
105.0 V: 0 0 0 1 0 14930 14930
| 120.0 V: | 0 | 0 | 0 | 3 | 0 | 14930 | 14930
135.0 V: 0 0 0 3 0 14930 14930
150.0 V: 0 0 0 4 0 14930 14930
165.0 V: 0 0 0 1 0 14930 14930
180.0 V: 0 0 0 6 0 14930 14930
195.0 V: 0 0 0 4 0 14930 14930
210.0 V: 0 0 0 6 0 14930 14930
225.0 V: 0 0 0 5 0 14930 14930
240.0 V: 0 0 0 5 0 14930 14930
250.0 V: 0 0 0 7 0 14930 14930
260.0 V: 0 0 0 4 0 14930 14930
275.0 V: 0 0 0 15 0 14930 14930
290.0 V: 0 0 0 9 0 14930 14930
300.0 V: 0 0 1 20 0 14929 14930
325.0 V: 0 0 0 23 0 14929 14929
350.0 V: 0 0 0 26 3 1 1

| APV profiles: | Dead APVs: 14920 | noisy APVs: 10 | survivors: 0

Analyzing Noise Bias Scan data for partition TIB

30 V Dead strips: 45 Noisy strips: 67 Total strips: 2234880
45 V Dead strips: 39 Noisy strips: 80 Total strips: 2234880
60 V Dead strips: 41 Noisy strips: 74 Total strips: 2234880
75 V Dead strips: 39 Noisy strips: 78 Total strips: 2234880
90 V Dead strips: 39 Noisy strips: 83 Total strips: 2234880
105 V Dead strips: 38 Noisy strips: 94 Total strips: 2234880
120 V Dead strips: 42 Noisy strips: 102 Total strips: 2234880
135 V Dead strips: 39 Noisy strips: 115 Total strips: 2234880
150 V Dead strips: 38 Noisy strips: 125 Total strips: 2234880
165 V Dead strips: 37 Noisy strips: 136 Total strips: 2234880
180 V Dead strips: 37 Noisy strips: 152 Total strips: 2234880
195 V Dead strips: 35 Noisy strips: 165 Total strips: 2234880
210 V Dead strips: 37 Noisy strips: 176 Total strips: 2234880
225 V Dead strips: 36 Noisy strips: 205 Total strips: 2234880
240 V Dead strips: 32 Noisy strips: 226 Total strips: 2234880
250 V Dead strips: 32 Noisy strips: 241 Total strips: 2234880
260 V Dead strips: 34 Noisy strips: 266 Total strips: 2234880
275 V Dead strips: 33 Noisy strips: 288 Total strips: 2234880
290 V Dead strips: 34 Noisy strips: 325 Total strips: 2234880
300 V Dead strips: 33 Noisy strips: 351 Total strips: 2234880
325 V Dead strips: 34 Noisy strips: 486 Total strips: 2234880
350 V Dead strips: 36 Noisy strips: 700 Total strips: 2234880

Cleaning noisy / dead APVs for TIB ... Trimmed APV post-mortem report for Sep2012 TIB :

Point-by-point: HV # empty APVs # dead APVs # noisy APVs # APVs with large error bars # APVs with large first value: # surviving APVs total # APVs
195.0 V: 0 0 0 7 0 17456 17456
260.0 V: 0 0 0 19 0 17456 17456
325.0 V: 0 0 2 67 0 17454 17456
135.0 V: 0 0 0 2 0 17456 17456
75.0 V: 0 0 0 1 0 17456 17456
210.0 V: 0 0 0 9 0 17456 17456
275.0 V: 0 0 0 22 0 17456 17456
150.0 V: 0 0 0 6 0 17456 17456
90.0 V: 0 0 0 2 0 17456 17456
30.0 V: 0 0 0 0 0 0 0
225.0 V: 0 0 0 9 0 17456 17456
290.0 V: 0 0 0 31 0 17456 17456
165.0 V: 0 0 0 2 0 17456 17456
105.0 V: 0 0 0 3 0 17456 17456
300.0 V: 0 0 0 40 0 17456 17456
45.0 V: 0 0 0 0 0 0 0
240.0 V: 0 0 0 14 0 17456 17456
180.0 V: 0 0 0 6 0 17456 17456
350.0 V: 4 0 0 87 0 0 0
120.0 V: 0 0 0 4 0 17456 17456
250.0 V: 0 0 0 11 0 17456 17456
60.0 V: 0 0 0 0 0 0 0
| APV profiles: | Dead APVs: 17454 | noisy APVs: 6 | survivors: 0

Analyzing Noise Bias Scan data for partition TOB

30 V Dead strips: 82 Noisy strips: 26 Total strips: 3047424
45 V Dead strips: 81 Noisy strips: 17 Total strips: 3047424
60 V Dead strips: 83 Noisy strips: 20 Total strips: 3047424
75 V Dead strips: 80 Noisy strips: 24 Total strips: 3047424
90 V Dead strips: 73 Noisy strips: 30 Total strips: 3047424
105 V Dead strips: 76 Noisy strips: 37 Total strips: 3047424
120 V Dead strips: 75 Noisy strips: 47 Total strips: 3047424
135 V Dead strips: 76 Noisy strips: 50 Total strips: 3047424
150 V Dead strips: 80 Noisy strips: 57 Total strips: 3047424
165 V Dead strips: 77 Noisy strips: 61 Total strips: 3047424
180 V Dead strips: 78 Noisy strips: 65 Total strips: 3047424
195 V Dead strips: 83 Noisy strips: 78 Total strips: 3047424
210 V Dead strips: 80 Noisy strips: 97 Total strips: 3047424
225 V Dead strips: 85 Noisy strips: 110 Total strips: 3047424
240 V Dead strips: 83 Noisy strips: 120 Total strips: 3047424
250 V Dead strips: 83 Noisy strips: 133 Total strips: 3047424
260 V Dead strips: 81 Noisy strips: 149 Total strips: 3047424
275 V Dead strips: 82 Noisy strips: 171 Total strips: 3047424
290 V Dead strips: 73 Noisy strips: 181 Total strips: 3047424
300 V Dead strips: 78 Noisy strips: 206 Total strips: 3047424
325 V Dead strips: 80 Noisy strips: 240 Total strips: 3047424
350 V Dead strips: 77 Noisy strips: 280 Total strips: 3047424

Trimmed APV post-mortem report for Sep2012 TOB :

Point-by-point: HV # empty APVs # dead APVs # noisy APVs # APVs with large error bars # APVs with large first value: # surviving APVs total # APVs
30.0 V: 0 0 0 46 0 0 0
45.0 V: 0 0 0 0 0 0 0
60.0 V: 0 0 0 5 0 0 0
75.0 V: 0 0 0 0 0 23806 23806
90.0 V: 0 0 0 0 0 23808 23808
105.0 V: 0 0 0 0 0 23808 23808
120.0 V: 0 0 0 0 0 23808 23808
135.0 V: 0 0 0 0 0 23808 23808
150.0 V: 0 0 0 1 0 23808 23808
165.0 V: 0 0 0 1 0 23808 23808
180.0 V: 0 0 0 0 0 23808 23808
195.0 V: 0 0 0 1 0 23808 23808
210.0 V: 0 0 0 1 0 23808 23808
225.0 V: 0 0 0 2 0 23808 23808
240.0 V: 0 0 0 2 0 23808 23808
250.0 V: 0 0 0 1 0 23808 23808
260.0 V: 0 0 0 4 0 23808 23808
275.0 V: 0 0 0 4 0 23808 23808
290.0 V: 0 0 0 10 0 23808 23808
300.0 V: 0 0 0 12 0 23808 23808
325.0 V: 0 0 0 18 0 23808 23808
350.0 V: 0 0 0 32 2 0 0
| APV profiles: | Dead APVs: 23761 | noisy APVs: 47 | survivors: 0

Trimming APVs

The APVs' noise profiles (versus scanned HV points) exhibit some pathological behaviors; categorizing them and removing them (either completely or just singular noise values if, say, there exists a large rms on the noise at some HV value) will decrease the error bars on those APVs that only have a few errant points, and will clean up the tails of the fitted distribution.

We can categorize the various pathologies of APVs as follows:

1. dead APVs 2. noisy APVs and also 3. non-constantly noisy / dead (that is, high or low noise values at a few HV points (high values at one point may point to a cosmic event which passes the random trigger)).

Noise fitting model

To detect those charge carriers disturbed by minimum-ionizing traversing radiation (as well as transient, internal currents, etc.) we need to have a charge-carrier-depleted (neutral) zone in the bulk of the detector -- this is achieved by applying a reverse-biased potential across a p-n junction, and so on. < this can be fleshed out, I think.> This is intuitively model-able as a capacitance, which, as in Prokhorets [2], is modeled in the piecewise, inverse-square-root-in-HV, just like the above equation. For a more macroscopic view of the treatment of readout noise in pedestal bias runs, see chapter 3 of Richard Bremer's dissertation [1].

The relevant code:

def fitting_function(x, par):

    import math
    import ROOT

    if x[0] <= par[2]:
        return  par[0] + par[1] *  math.sqrt(par[2]) * 1. / math.sqrt(x[0])
    else:
        return par[0] + par[1]

There are, however, some difficulties encountered in fitting this function to the pesestal-noise data retrieved during noise (pedestal) bias runs. In short, the fits' reduced chi-squared values are either large (~50) or very small (~0.001), which indicates the fitting routine is "missing" the data points and their respective error bars, or our system is somehow overdetermined (i.e., tiny reduced chi-squared means the fit is very nearly intersecting the data points, which means that either we're really good at guessing the functional form, or that something's awry).
[1] R. Bremer, Ph.D. thesis, RWTH Aachen University, 2008 bremer_ch3.pdf: Bremer's dissertation, chapter 3
[2] I.M. Prokhorets, et. al. Nucl. Exp. Techn. 46 24 (2003)2003_Prokhorets.pdf

Obtaining fit parameter spaces

Before we get to the parameter spaces and what they can tell us, first, how does one get these contours? Using the contour tutorial as a basis, the general recipe is a) make a TFitResults object with the usual .Fit() routine, and b) call gMinuit explicitly. Note that in the below code snippet, gMinuit is altered in its fitting strategy to its most "careful" setting; see http://wwwasdoc.web.cern.ch/wwwasdoc/minuit/node18.html for details.
# Set up the function with 3 fitting parameters, using the "fitting_function" function, in the range 
# [func_min, func_max], with initial guesses for the fit parameters:

                fit_for_plot = ROOT.TF1("fit", fitting_function, func_min, func_max, 3)
                fit_for_plot.SetParameters(par0_guess, par1_guess, par2_guess)
                fit_for_plot.SetParLimits(2, par2_min, par2_max)
                fit_for_plot.SetParLimits(1, par1_min, par1_max)
                fit_for_plot.SetParNames('a', 'b', 'vdepl') #Make the var names understandable.

                output_canvas = ROOT.TCanvas(date+'_contours_'+profile.GetName(), 'Testing n-sigma contours', 10, 10, 1200, 800)            
                results = profile.Fit(fit_for_plot, 'RSQ') #Fitting the current profile with the TF1 defined above
                output_canvas.Update()
                outputted_a_par = fit_for_plot.GetParameter(0)
                outputted_delta_a_par = fit_for_plot.GetParError(0)
                outputted_b_par = fit_for_plot.GetParameter(1)
                outputted_delta_b_par = fit_for_plot.GetParError(1)
                outputted_vdepl = fit_for_plot.GetParameter(2)
                outputted_delta_vdepl = fit_for_plot.GetParError(2)
                outputted_chi2 = fit_for_plot.GetChisquare()

                ## Setting up the first plot: b(Vdepl) contour at 2 sigma.            
                output_canvas.cd(1)

                ROOT.gMinuit.SetErrorDef(4) # TMinuit goes by n_{sigma}^2; 2^2 (sigma^2) = 4.
                # The below two commands are somewhat arcane. Here's a try at an explanation.
                # Because the fits are so tricky, I want TMinuit to really work at finding
                # as best it can local minima and not get stuck (hopefully...). So I need to
                # explicitly access TMinuit's options through gMinuit. Then things like fitting
                # strategy 
                p0vp2 = ROOT.gMinuit; p0vp2.Command('SET STR 2')

                # With gMinuit set up, let's make the contour now, for param. b against Vdepl:
                p0_v_p2 = p0vp2.Contour(80,2,1)
                leg_1 = ROOT.TLegend(0.55, 0.55, 0.8, 0.8)
                if p0_v_p2 != None: 
                    #This set of loops catches any failed fitting.
                    # If the fit "fails" or gMinuit decides it's gone too far, no TGraph is returned.

                    if p0_v_p2.ClassName() != 'TObject':
                        p0_v_p2.SetFillColor(42) 
                        p0_v_p2.Draw('alf')
                        p0_v_p2.SetTitle('2 #sigma')
                        leg_1.AddEntry(p0_v_p2)
                        p0_v_p2.SetTitle('Parameter b vs V_{depl};V_{depl} [V]; parameter b [V]') 

Parameter space nave fit

The contour plot script is derived from the tutorial ROOT macro found on most computers under
$ROOTSYS/tutorials/fit/fitcont.C

The contour plot script used to generate the parameter-space contour seen on this page can be found on AFS under:

/afs/cern.ch/work/e/eorcutt/public/noise/test_parameter_contours.py

As the fits are finicky, our chi-squared hypersurface is, instead of the tractable smooth as with polynomial functions, very irregular, with many local chi-squared minima, and enormous global minima -- hence the large number of fits converging to nearly 10.0 and 350.0 V. Below is a composite graphic of contour plots of the fit parameters against each other, with a comparison plot of the fitted data (replete with fitting function).

This is a "well-behaved" APV; note, however, the small reduced chi-squared value, and the absence of a two- contour in the contour of a(b). This hints already that the fit isn't working so well; also look to the very small reduced value -- we do not know the model nearly so precisely, as can be verified by looking at the fit function -- it doesn't pass through every data point.

An example of a not-as-good fit is given below:

Notice that the double knee phenomenon occurs here and noticeably throws off the fitter. This also hints at the notion that perhaps the double knee is not an optical noise phenomenon: the two above contour plots are for consecutive APVs (that is, they're on the same opto-pair).

Linearised fittings:


    • with this parameterization, we get the piecewise-defined function

With this linearization it is hoped we can avoid the difficulty TMinuit is experiencing with an inverse-root-defined, region-defining parameter (i.e., ) by refactoring it so that it is not weighted as much in defining the quadratic and linear regions. This linearization preserves one of the inequalities and keeps the inverse square root.

The related Python code is:

def fitting_function(x, par):
    import math
    import ROOT

    if x[0] <= par[2]:
        return par[0] + par[1] / math.sqrt(x[0])
    else:
        return par[0] + par[1] / math.sqrt(par[2])

This has shown fit convergence rates and fitted values and their corresponding uncertainties similar to those of the "old" fitting method (i.e., the nave fitting using the "standard" function.

Parameter space for

    • with this other parameterization, we get the piecewise-defined function

The code for this is

def fitting_function(x, par):

    import math
    import ROOT

    if x[0] >= 1./math.sqrt(par[2]):
        return par[0] + par[1] * math.sqrt(par[2]) * x[0]
    else:
        return par[0] + par[1]

Here, it is hoped we can avoid the quadratic behavior of altogether, and work with a function linear in ; note, however, that the quadratic behavior is shifted to the region bounds and the itself (as in the "original" noise function).

Parameter space for

As for the quadratic behavior being offset, let's see what the fit-parameter spaces tell us:

A more adjustable (and accurate) fitting scheme

Another approach which seems (need to check on whether this is T/F, and remove the subjunctive) to work well is making the a parameter over which we loop. From these we can find which gives the best fit; some examples of this behavior are shown below.

The code which effects this is quite simple:

vd_list = [x for x in range(10,460,20)]
# The Fitted() class is simply allowing one-line access to a fit, its results, and so its chi-squared value.
min_list = [ Fitted(new_profile, x, 25).getChiSquared() for x in vd_list ]
# Now, just take the built-in STL .min() method Python provides to get the smallest chi-squared.
minchi = min(min_list)

# Next, find the Vdepl that gave us this chi-squared, using the list
# of chi-squareds as our guide.
for x,y in zip(min_list, vd_list):
    if x == minchi:
        best_vdepl = y
        best_index = min_list.index(x)
        best_results = Fitted(new_profile, x_list[best_index]-1, 25).getResults()

         a_param = best_results.Value(0)
         delta_a = best_results.ParError(0)
         b_param = best_results.Value(1)
         delta_b = best_results.ParError(1)
         chi2 = minchi  ##Just relabelling...
         delta_vdepl = 0.
         fit_success = int(best_results)

Just below is the first in the loop (for the December dataset, anyway...) notice the overall is not so great:

This second plot shows another point: notice the improvement in visual fit, and in :

This third plot corresponds to the optimal (ie, the is the least out of the set of values). Note that since we're working with the overall , the nonlinear portion begins to extend into a region that it may not well describe -- so we see that visually the goodness of fit decreases as the cutoff increases:

Note, though, that the best for this APV corresponds to a goodness-of-fit of ~4. My current hypothesis (this will be tested soon) is that this optimization is over the overall so we can likely squeeze some more goodness-of-fit from the data if I optimize to the for the exponential piece and the linear piece.

APV behaviors

Using September as a "standard candle" for kinds of misbehaving / damaged APVs' behavior, we can both develop tools to clean up the Vdepl signal in the July and December datasets, and have a better understanding of the most-irradiated (up to this point) silicon detectors (as of September, the SSD has suffered the most luminosity -- this will change when the January 2013 bias scan is made available).

A simple starting point is trying to understand the APVs and modules in the right-hand-side tail of the APV-distribution of fitted Vdepl, >= 325 V:

Another simple starting point is the fit parameter "A", or the noise value (in ADC counts) corresponding to a fully-depleted module. Looking at all three of the datasets, we see an interesting structure to the full-depleted noise distributions: There are several significant features: 1. The double-Gaussian appearance for all the datasets, and 2. The peaks' central values for December 2010 and September 2012 are at higher ADC count values than the July 2011 dataset is -- because December and September's readout modes were set to deconvolution mode, the noise read out tends to be higher in comparison to peak mode (which is the readout mode the SSD tracker was set to for the July noise bias scan).

A partition-by-partition look at this fit parameter examine above for the standard candle September 2012 dataset shows more interesting structure: Namely, that the double-Gaussian behavior is limited to the endcap partitions -- the barrels and tracker inner disks (TID) are singly-peaked. This suggests many possible reasons for the tendendcy for the endcap APVs to have a fully-depleted noise value of ~4.5 or ~6 ADCc -- for example, geometry (radial values correlate in some way to A), bulk volume, EC disk #, ring/wheel # are parameters that should be investigated; these coordinates can be translated to Python (nearly done with that), transliterating the methods and classes found at http://cmslxr.fnal.gov/lxr/source/DataFormats/SiStripDetId/src/SiStripSubStructure.cc.

For a satisfying checkover, we'll look at July 2011 and December 2010's "A" parameter plots, partition-by-partition, as well. Note again, the same encap/double-Gaussian occurrence.

"Old" to "new"

From the older, more-bug-ridden analysis / data-harvesting code, we saw some odd features, such as comparatively large error bars on the mean noise measurements, irregularly masked tracker-map regions, and problematic noise fitting. Examples of these are below .

The newer data-harvesting and analysis has (hopefully) repaired the error bars, and has regularized the tracker map-making code (and made it so that the problematic dictionaries occasionally handed to the mapping function are no longer problematic, and so that "capping" (arbitrarily-chosen by the user) high fitted full depletion voltages or other quantities is possible [this allows us a better 'resolution' for the mapped values as there's a more-visible color variance among differing values when there's no large value at "red"]). The fitting, however, remains another matter.

In the plot below, notice 1) that the mean noise between the two "datasets" is the same (not surprising, but reassuring), and that 2) the error bars for the "new" are on the whole smaller (this is not a guarantee for those noisier APVs):

So, what in the fit behaviors has changed? Below is a plot of the distributions for "old" and "new", with another plot which shows a zoomed-in view of the first plot from 0 to 50 V HV:


Finding the TID modules

One glaring problem in the "old" outputted tracker maps was the absence of the tracker inner disk (TID) modules. In the end, they were easy to add back in. The problem lies in the bundling of TID module data in the tracker inner barrel (TIB) pedestal bias run output files. Because the data harvester separated data based on the partitions which were derived from the input filenames, and because the input file names included only tracker end caps (TECM, TECP), and the barrel (TIB, TOB), TID was excluded. The code fragment used to generate a list of detIDs for a given partition is:
detid_list = [detid for detid in detidPathDict.keys() if list(strip_detid_alias_dict[int(detid)])[0].upper().startswith(partition)]

That is, from the files (these are examples only)

(for December 2010 and July 2011 data):
tecm185.root 
tecp185.root
tib185.root
tob185.root

(for September 2012 data):
TECM_203270_180.root
TECP_203244_180.root
TIB_203243_180.root
TOB_203245_180.root
we will get (voltage points 185 and 180 V) the same partitions: TEC(M,P) and T(I,O)B. So how is TID added back in? With the following simple addendum:
for detid in detidPathDict.keys():
   if list(strip_detid_alias_dict[int(detid)])[0].split('_')[0].startswith('TID'):
      tidDict.update({detid:detidPathDict[detid]})
   tid_list = [ x for x in tidDict.keys() ]

if partition == 'TIB':
   detid_list = detid_list.append(tid_list)

Workflow

Check-out the noise-bias-scan data-harvesting and analysis scripts:
cd CMSSW_X_Y_Z/src
cvs co UserCode/eorcutt/NoiseBiasScan

Current noise bias scan data

Noise bias scan run date Partition NBS data location Run #s APV 25 readout mode Elogs
December 2010 TEC- eos/cms/store/user/gbenelli/NoiseBiasScan/Dec2010/TECM   deco  
  TEC+ eos/cms/store/user/gbenelli/NoiseBiasScan/Dec2010/TECP    
  TIB eos/cms/store/user/gbenelli/NoiseBiasScan/Dec2010/TIB    
  TOB eos/cms/store/user/gbenelli/NoiseBiasScan/Dec2010/TOB    
July 2011 TEC- eos/cms/store/user/gbenelli/NoiseBiasScan/Jul2011/TECM   peak http://cmsonline.cern.ch/cms-elog/598844
  TEC+ eos/cms/store/user/gbenelli/NoiseBiasScan/Jul2011/TECP      
  TIB eos/cms/store/user/gbenelli/NoiseBiasScan/Jul2011/TIB    
  TOB eos/cms/store/user/gbenelli/NoiseBiasScan/Jul2011/TOB    
September 2012 TEC- eos/cms/store/user/gbenelli/NoiseBiasScan/Sep2012/TECM   deco http://cmsonline.cern.ch/cms-elog/785673
  TEC+ eos/cms/store/user/gbenelli/NoiseBiasScan/Sep2012/TECP    
  TIB eos/cms/store/user/gbenelli/NoiseBiasScan/Sep2012/TIB    
  TOB eos/cms/store/user/gbenelli/NoiseBiasScan/Sep2012/TOB    

External condition timeline

Time Condition (September 2012) Link
0000    
0100    
0200    
0300    
0400    
0500    
0600    
0700    
0800 begin noise scan  
0900    
1000    
1100    
1200    
1300    
1400    
1500 end noise scan  
1600    
1700    
1800    
1900      
2000      

Purpose

The purpose of this project is to be able to extract from noise bias scan data the (full) depletion voltage for each module in the cms silicon strip detectors (the inner and outer barrels, and the +z and -z end cap detectors); from multiple bias scans, we can determine the modules' depletion voltage time evolution. We should be able to determine the modules' responses to radiation damage; from this we can answer questions such as where the detectors are on the type-inversion plot.

Analysis

The pedestal bias noise for a given strip is the rms of the pedestal value for that strip; this is taken during pedestal bias runs, in which the silicon strip detectors are not forward biased (or indeed, biased at all), but rather the readout is "listening" to the machine noise (phrasing? correctness?).

The results of the pedestal bias run are shown below:

And the RMS of the pedestals extracted for each strip, over 2 APVs is:

This figure shows the pedestal values for 256 strips; since there are 128 strips / APV, there are 2 APVs in this profile. It is worthwhile to note that there are two APVs per optical link (aka laser channel). There are designed an "upper" and a "lower" APV per opto-link (APV pair).

As of mid to late December, it was noticed that the error bars on the fitted depletion voltage were overlarge: ~ 1 V. This gives the fit more "room" to find a "good" fit (from the viewpoint of chi-squared only; other parameters and their sigmas can give a better picture); there was a noticeable propensity for modules (and APVs) to skew towards the 350 V end of the fitted depletion voltage (i.e., get pushed to the best possible "minimum" value for the noise function):

[plots go here showing the "old" method's skewed outcomes]

Depletion voltage

First are the distributions of (mean untrimmed) V_{depl} for December and July, for all APVs [NB: shift around to keep Dec with Dec and July with July?]:

Notice the 'spike' at ~450 V, especially in December (!!). What does the chi2 distribution of these fitted V_{depl} look like?

Once the data have been fitted with the above fitting function [need to add the details on fitting function and motivations (if there exist) for the given damage model], we need to decide what constitutes a 'good' versus a 'bad' fit.

Given 31 degrees of freedom for the December 2010 dataset (34 HV points - 3 fit parameters), a (non-reduced) chi-squared value of 50 will give us a set of fitted V_{depl} with a ~98% confidence level; for 18 degrees of freedom for the December 2010 dataset (21 HV points - 3 fit parameters), a (non-reduced) chi-squared value of 33 will give us a set of fitted V_{depl} with a ~98% confidence level.

December 2010, fitted V_{depl}, averaged across n APVs for each module (where n is between 4 and 6)

July 2011, fitted V_{depl}, averaged across n APVs for each module (where n is between 4 and 6)

What are the effects of the cuts on the number of APV1's in each module?

For December:

December 2010 # APVS passed chi2 cut # APVs passed V_{depl} cut #APVs passed both Vd and chi2 Total # APVs
TOB 5120 4636 4628 5130
TECM 3180 2198 2198 3181
TECP 3166 2082 2082 3166
TIB 2549 2408 2408 2553

For July:

July 2011 # APVS passed chi2 cut # APVs passed V_{depl} cut #APVs passed both Vd and chi2 Total # APVs
TOB 5112 3486 3209 5114
TECM 3181 2306 2211 3181
TECP 3166 2321 2203 3166
TIB 2555 2159 2146 2555

Spread in depletion voltage

currently using the standard deviation from the mean fitted V_{depl} across all APVs in a given module, for all modules. This may change.

December 2010, spread in fitted V_{depl}

December 2010, spread in fitted V_{depl}, distribution

Jul 2011, spread in fitted V_{depl}

Jul 2011, spread in fitted V_{depl}, distribution

Golden modules

One potentially useful handle on determining the goings-on in a dataset is finding a set of "golden" modules: those which have "good" fit values and Vdepl fitted values for 4 / 4 or 6 / 6 APVs in the modules. From there we may get a better picture of the fitted Vdepl distribution, see which modules remain as constants across the cumulative datasets, which change, etc.

%------+++ Mean noise versus median noise

Double knees

Instead of the "expected" inverse root, asymptotic behavior expected from the capacitance noise model, we see a "double" of the decrease; an example is seen below:

So, how many modules (and how many APVs in a given module) are affected by this? Does this cause some of our fits to converge to the local minimum (which is the endpoint on the high voltage bias axis, hence the proportionately large number of fitted 450-V modules)? Below are tables for the December 2010 and the July 2011 bias runs, on how many modules report 1, 2, 3, ..., 6 APVs with a double knee. Note that the numbers of modules with /n/ double knees is exclusive -- that is, if a module reports 4 APVs with a double knee, then it will not be counted as one with 3, 2, or 1 double-kneed modules (this is also checked by matching the sums).

Number of modules in each detector with [0,6] APVs reporting a DK:

[NB: the following tables were computed by hand. As is plain to see, the results are tedious and horrendous. Add in a LaTeX-table-generating portion to the analysis script.]

December 2010:

# Modules with n DK 0 1 2 3 4 5 6 Total #
TECM 2842 251 78 6 4 0 0 3184
Percentage of total 89.3% 7.9% 1.9% 0% 0% --
TECP 2856 222 70 11 7 0 0 3166
Percentage of total 90.2% 7.00% 2.2% 0% 0% --
TIB 1668 483 229 102 63 8 0 2555
Percentage of total 66.1% 18.9% 4.0% 2.5% 0% --
TOB 4081 637 328 64 17 3 0 5130
Percentage of total 79.6% 6.4% 1.2% 0.1% 0% --

July 2011:

# Modules with n DK 0 1 2 3 4 5 6 Total #
TECM 2558 393 174 42 14 0 0 3184
TECP 2567 383 153 51 11 1 0 3166
TIB 1369 662 387 112 23 2 0 2555
TOB 4646 335 96 28 8 0 0 5130

From the above numbers, it (naively at least) seems that the double knee issue is a non-issue. It wouldn't hurt to check correlations further down the line, when cuts and such have been applied. Also, need to investigate whether plots which fail the fit (and also those which "pass" the fit) exhibit double knee behavior.

December 2010: modules with a double knee (using "old" test currently) NB: for map above (Dec 2010 double knee TM), keep in mind this is a map for APV #6 in each module; I'll be fixing this oversight soon.

July 2011: modules with a double knee (using "old" test currently) NB: for map above (Jul 2010 double knee TM), keep in mind this is a map for APV #6 in each module; I'll be fixing this oversight soon.

Construction database

NB: There are some discrepancies in the provided construction database total depletion voltage values (i.e., those modules that are white) and the December, July, or August datasets. Any "missing" modules w.r.t.t. pedestal bias runs are not considered with anything construction DB-related.

Notice in the below tracker map and distribution, the approximate mean of Vdepl ~ 200 V.

Tracker map of full depletion voltage values from construction DB

Distribution of full depletion voltage values from construction DB

Software

The repository for the data harvester and analysis code is here. It can be checked out on an lxplus machine via 'cvs co /UserCode/eorcutt/NoiseScan'.

1. The DataHarvester_rc.py script takes the noise bias run data from EOS and extracts and calculates the quantities we want, and stores this in ROOT files, divided by detector (this is due to memory concerns when generating each detector's dictionary). It can be found at http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/eorcutt/NoiseScan/ModifiedDataHarvester_rc.py?view=log and on AFS at the directory /afs/cern.ch/work/e/eorcutt/public/noise/ModifiedDataHarvester_rc.py

2. The analyze_again.py script fits the V_{depl} found in the ROOT files output by the data harvester (linked above), if the script is run with the command-line argument "--fit". If it is instead "--nofit", then the analysis script portion is run instead, and analysis histograms and correlation plots and a bash script to generate tracker maps is created. The output file is analysisOutput.root. It can be found at http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/eorcutt/NoiseScan/ModifiedDataHarvester_rc.py?view=log and on AFS at the location /afs/cern.ch/work/e/eorcutt/public/noise/analyze_again.py

Data flow [rough section]

Pedestal bias run data -> (1) DataHarvester -> (2) analyze.py (dk flagging, vdepl fitting -- fitting flag set to "True") -> (3) analyze.py (analysis script mode -- fitting flag set to "False")

The pedestal bias scan data is our starting point (link to example file on AFS/EOS here); the bias voltage for each strip is monitored over 2000 events; the rms of this is our noise. So we grab this noise from each strip using TProfile's GetBinError() method.

-- JamesOrcutt - 24-Oct-2012

Error during latex2img:
ERROR: problems during latex
INPUT:
\documentclass[fleqn,12pt]{article}
\usepackage{amsmath}
\usepackage[normal]{xcolor}
\setlength{\mathindent}{0cm}
\definecolor{teal}{rgb}{0,0.5,0.5}
\definecolor{navy}{rgb}{0,0,0.5}
\definecolor{aqua}{rgb}{0,1,1}
\definecolor{lime}{rgb}{0,1,0}
\definecolor{maroon}{rgb}{0.5,0,0}
\definecolor{silver}{gray}{0.75}
\usepackage{latexsym}
\begin{document}
\pagestyle{empty}
\pagecolor{white}
{
\color{black}
\begin{math}\displaystyle B'\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle \sigma\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle \chi^{2}\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle x \rightarrow x' = x^{-\frac{1}{2}}\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle \chi^2\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle B \rightarrow B' = B\sqrt{C}\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle x'\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle n(V)\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle sigma_i \gt \bar{\sigma}_{APV} + 5 * \text{rms}(\sigma_{APV}),\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle \sigma_i \lt \bar{\sigma}_{APV} - 5 * \text{rms}(\sigma_{APV})\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle V_{depl}\end{math}
}
\clearpage
{
\color{black}
\begin{math}\displaystyle x\end{math}
}
\clearpage
\end{document}
STDERR:
This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013)
 restricted \write18 enabled.
entering extended mode
(/tmp/_2CepvyWoX/tyXS8q0TYD
LaTeX2e <2011/06/27>
Babel  and hyphenation patterns for english, dumylang, nohyphenation, lo
aded.
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/fleqn.clo)
(/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo))
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty
For additional information on amsmath, use the `?' option.
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty))
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty)
(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty))
(/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty
(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg)
(/usr/share/texlive/texmf-dist/tex/latex/graphics/dvips.def))
(/usr/share/texlive/texmf-dist/tex/latex/base/latexsym.sty)
No file tyXS8q0TYD.aux.
(/usr/share/texlive/texmf-dist/tex/latex/base/ulasy.fd) [1] [2] [3] [4]
[5] [6] [7] [8]
! Undefined control sequence.
l.57 \begin{math}\displaystyle sigma_i \gt
                                           \bar{\sigma}_{APV} + 5 * \text{rm...

[9]
! Undefined control sequence.
l.62 \begin{math}\displaystyle \sigma_i \lt
                                            \bar{\sigma}_{APV} - 5 * \text{r...

[10] [11] [12] (./tyXS8q0TYD.aux) )
(see the transcript file for additional information)
Output written on tyXS8q0TYD.dvi (12 pages, 3308 bytes).
Transcript written on tyXS8q0TYD.log.
Edit | Attach | Watch | Print version | History: r16 < r15 < r14 < r13 < r12 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r16 - 2013-07-04 - JamesOrcutt
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Main All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback