def clear_ogp(self): ''' Clears the OGP registers on the ADC. ''' for core in range(1, 5): adc.set_spi_gain(self._roach, 0, core, 0) adc.set_spi_offset(self._roach, 0, core, 0) adc.set_spi_phase(self._roach, 0, core, 0)
def clear_ogp(): """ Clear all of the Offset, Gain and Phase corrections registers on the adc. """ for core in range(1,5): adc5g.set_spi_gain(roach2,zdok, core, 0) adc5g.set_spi_offset(roach2,zdok, core, 0) adc5g.set_spi_phase(roach2,zdok, core, 0)
def clear_ogp(): """ Clear all of the Offset, Gain and Phase corrections registers on the adc. """ for core in range(1, 5): adc5g.set_spi_gain(roach2, zdok, core, 0) adc5g.set_spi_offset(roach2, zdok, core, 0) adc5g.set_spi_phase(roach2, zdok, core, 0)
def set_ogp(self, ogp): ''' Sets the OGP registers on the ADC. Input shape must be (4, 3). ''' offs = ogp[:, 0] gains = ogp[:, 1] phase = ogp[:, 2] for i in range(len(offs)): adc.set_spi_offset(self._roach, 0, i+1, offs[i]) adc.set_spi_gain(self._roach, 0, i+1, gains[i]) adc.set_spi_phase(self._roach, 0, i+1, phase[i])
def clear_ogp(self, chans=[0, 1, 2, 3]): """ Sets OGP to 0 for channels in 'chans' """ for chan in chans: zdok, cores = self.get_channel_core_spi(chan) for core in cores: adc5g.set_spi_offset(self.roach, zdok, core, 0) adc5g.set_spi_gain(self.roach, zdok, core, 0) adc5g.set_spi_phase(self.roach, zdok, core, 0)
def clear_ogp(self, chans = [0,1,2,3]): """ Sets OGP to 0 for channels in 'chans' """ for chan in chans: zdok, cores = self.get_channel_core_spi(chan) for core in cores: adc5g.set_spi_offset(self.roach, zdok, core, 0) adc5g.set_spi_gain(self.roach, zdok, core, 0) adc5g.set_spi_phase(self.roach, zdok, core, 0)
def set_offs(o1, o2, o3, o4): """ Set the offsets for each core in the order a, b, c, d. """ t = float(o1) print math.floor(.5+t*255/100.)+0x80, adc5g.set_spi_offset(roach2,zdok, 1, t) t = float(o2) print math.floor(.5+t*255/100.)+0x80, adc5g.set_spi_offset(roach2,zdok, 2, t) t = float(o3) print math.floor(.5+t*255/100.)+0x80, adc5g.set_spi_offset(roach2,zdok, 3, t) t = float(o4) print math.floor(.5+t*255/100.)+0x80 adc5g.set_spi_offset(roach2,zdok, 4, t)
def set_offs(o1, o2, o3, o4): """ Set the offsets for each core in the order a, b, c, d. """ t = float(o1) print math.floor(.5 + t * 255 / 100.) + 0x80, adc5g.set_spi_offset(roach2, zdok, 1, t) t = float(o2) print math.floor(.5 + t * 255 / 100.) + 0x80, adc5g.set_spi_offset(roach2, zdok, 2, t) t = float(o3) print math.floor(.5 + t * 255 / 100.) + 0x80, adc5g.set_spi_offset(roach2, zdok, 3, t) t = float(o4) print math.floor(.5 + t * 255 / 100.) + 0x80 adc5g.set_spi_offset(roach2, zdok, 4, t)
def set_ogp(self, ogp_chan, chan): """ Sets ogp for two cores of channel 'chan' multi_ogp is format (ogp1, ogp2) """ zdok, cores = self.get_channel_core_spi(chan) i = 0 for core in cores: off, gain, phase = ogp_chan[i] off_spi = math.floor(.5 + off * 255 / 100.) + 0x80 adc5g.set_spi_offset(self.roach, zdok, core, float(off)) gain_spi = math.floor(.5 + gain * 255 / 36.) + 0x80 adc5g.set_spi_gain(self.roach, zdok, core, float(gain)) phase_spi = math.floor(.5 + phase * 255 / 28.) + 0x80 adc5g.set_spi_phase(self.roach, zdok, core, float(phase) * 0.65) i += 1
def set_ogp(self, ogp_chan, chan): """ Sets ogp for two cores of channel 'chan' multi_ogp is format (ogp1, ogp2) """ zdok, cores = self.get_channel_core_spi(chan) i = 0 for core in cores: off, gain, phase = ogp_chan[i] off_spi = math.floor(.5 + off*255/100.) + 0x80 adc5g.set_spi_offset(self.roach, zdok, core, float(off)) gain_spi = math.floor(.5 + gain*255/36.) + 0x80 adc5g.set_spi_gain(self.roach, zdok, core, float(gain)) phase_spi = math.floor(.5 + phase*255/28.) + 0x80 adc5g.set_spi_phase(self.roach, zdok, core, float(phase)*0.65) i += 1
def calibrate_adc_offset(self, zdok=0, oiter=10, otol=0.005, verbose=10): """ Attempt to match the core offsets within the ADC. See ArtooDaq.calibrate_adc_ogp for more details. """ # offset controlled by float varying over [-50,50] mV with 0.4 mV resolution res_offset = 0.4 lim_offset = [-50.0, 50.0] groups = 8 test_step = 10 * res_offset if verbose > 3: print " Offset calibration ZDOK{0}:".format(zdok) for ic in xrange(1, 5): adc5g.set_spi_offset(self.roach2, zdok, ic, 0) x1 = self._snap_per_core(zdok=zdok, groups=groups) sx1 = x1.std(axis=0) mx1 = x1.mean(axis=0) / sx1 if verbose > 5: print " ...offset: with zero-offsets, means are [{0}]".format( ", ".join(["{0:+7.4f}".format(imx) for imx in mx1])) for ic in xrange(1, 5): adc5g.set_spi_offset(self.roach2, zdok, ic, test_step) x2 = self._snap_per_core(zdok=zdok, groups=groups) sx2 = x2.std(axis=0) mx2 = x2.mean(axis=0) / sx2 if verbose > 5: print " ...offset: with {0:+4.1f} mV offset, means are [{1}]".format( test_step, ", ".join(["{0:+7.4f}".format(imx) for imx in mx2])) d_mx = (mx2 - mx1) / test_step core_offsets = -mx1 / d_mx for ic in xrange(1, 5): adc5g.set_spi_offset(self.roach2, zdok, ic, core_offsets[ic - 1]) core_offsets[ic - 1] = adc5g.get_spi_offset(self.roach2, zdok, ic) x = self._snap_per_core(zdok=zdok, groups=groups) sx = x.std(axis=0) mx = x.mean(axis=0) / sx if verbose > 5: print " ...offset: solution offsets are [{0}] mV, means are [{1}]".format( ", ".join(["{0:+6.2f}".format(ico) for ico in core_offsets]), ", ".join(["{0:+7.4f}".format(imx) for imx in mx])) if any(abs(mx) >= otol): if verbose > 5: print " ...offset: solution not good enough, iterating (tol={0:4.4f},iter={1:d})".format( otol, oiter) for ii in xrange(0, oiter): for ic in xrange(1, 5): if mx[ic - 1] > otol: adc5g.set_spi_offset(self.roach2, zdok, ic, core_offsets[ic - 1] - res_offset) elif mx[ic - 1] < -otol: adc5g.set_spi_offset(self.roach2, zdok, ic, core_offsets[ic - 1] + res_offset) core_offsets[ic - 1] = adc5g.get_spi_offset( self.roach2, zdok, ic) x = self._snap_per_core(zdok=zdok, groups=groups) sx = x.std(axis=0) mx = x.mean(axis=0) / sx if verbose > 7: print " ...offset: solution offsets are [{0}] mV, means are [{1}]".format( ", ".join( ["{0:+6.2f}".format(ico) for ico in core_offsets]), ", ".join(["{0:+7.4f}".format(imx) for imx in mx])) if all(abs(mx) < otol): if verbose > 5: print " ...offset: solution good enough" break if ii == oiter - 1: if verbose > 5: print " ...offset: maximum number of iterations reached, aborting" else: if verbose > 5: print " ...offset: solution good enough" return core_offsets
def calibrate_adc_offset(self,zdok=0,oiter=10,otol=0.005,verbose=10): """ Attempt to match the core offsets within the ADC. See ArtooDaq.calibrate_adc_ogp for more details. """ # offset controlled by float varying over [-50,50] mV with 0.4 mV resolution res_offset = 0.4 lim_offset = [-50.0,50.0] groups = 8 test_step = 10*res_offset if verbose > 3: print " Offset calibration ZDOK{0}:".format(zdok) for ic in xrange(1,5): adc5g.set_spi_offset(self.roach2,zdok,ic,0) x1 = self._snap_per_core(zdok=zdok,groups=groups) sx1 = x1.std(axis=0) mx1 = x1.mean(axis=0)/sx1 if verbose > 5: print " ...offset: with zero-offsets, means are [{0}]".format( ", ".join(["{0:+7.4f}".format(imx) for imx in mx1]) ) for ic in xrange(1,5): adc5g.set_spi_offset(self.roach2,zdok,ic,test_step) x2 = self._snap_per_core(zdok=zdok,groups=groups) sx2 = x2.std(axis=0) mx2 = x2.mean(axis=0)/sx2 if verbose > 5: print " ...offset: with {0:+4.1f} mV offset, means are [{1}]".format( test_step, ", ".join(["{0:+7.4f}".format(imx) for imx in mx2]) ) d_mx = (mx2 - mx1)/test_step core_offsets = -mx1/d_mx for ic in xrange(1,5): adc5g.set_spi_offset(self.roach2,zdok,ic,core_offsets[ic-1]) core_offsets[ic-1] = adc5g.get_spi_offset(self.roach2,zdok,ic) x = self._snap_per_core(zdok=zdok,groups=groups) sx = x.std(axis=0) mx = x.mean(axis=0)/sx if verbose > 5: print " ...offset: solution offsets are [{0}] mV, means are [{1}]".format( ", ".join(["{0:+6.2f}".format(ico) for ico in core_offsets]), ", ".join(["{0:+7.4f}".format(imx) for imx in mx]) ) if any(abs(mx) >= otol): if verbose > 5: print " ...offset: solution not good enough, iterating (tol={0:4.4f},iter={1:d})".format(otol,oiter) for ii in xrange(0,oiter): for ic in xrange(1,5): if mx[ic-1] > otol: adc5g.set_spi_offset(self.roach2,zdok,ic,core_offsets[ic-1]-res_offset) elif mx[ic-1] < -otol: adc5g.set_spi_offset(self.roach2,zdok,ic,core_offsets[ic-1]+res_offset) core_offsets[ic-1] = adc5g.get_spi_offset(self.roach2,zdok,ic) x = self._snap_per_core(zdok=zdok,groups=groups) sx = x.std(axis=0) mx = x.mean(axis=0)/sx if verbose > 7: print " ...offset: solution offsets are [{0}] mV, means are [{1}]".format( ", ".join(["{0:+6.2f}".format(ico) for ico in core_offsets]), ", ".join(["{0:+7.4f}".format(imx) for imx in mx]) ) if all(abs(mx) < otol): if verbose > 5: print " ...offset: solution good enough" break if ii==oiter-1: if verbose > 5: print " ...offset: maximum number of iterations reached, aborting" else: if verbose > 5: print " ...offset: solution good enough" return core_offsets
def ogapply(sol): for i in [0, 1]: for j in [0, 1, 2, 3]: adc5g.set_spi_offset(r2, i, corder[j], sol[i,j,0]) adc5g.set_spi_gain(r2, i, corder[j], sol[i,j,1])
plt.text(0.95, 0.95, statslabel, ha='right', va='top', transform=plt.gca().transAxes) plt.xlim(-128, 128) plt.ylim(0, 1.05 * np.max(counts)) plt.yticks([]) plt.xticks([]) means[j] = ret[1] stds[j] = ret[2] print "IF%d Core %d: mean %5.2f std %5.2f" % (i, j, ret[1], ret[2]) avg_std = np.mean(stds) # target std for j in [0,1,2,3]: orig_off = adc5g.get_spi_offset(r2, i, corder[j]) orig_gain = adc5g.get_spi_gain(r2, i, corder[j]) new_off = orig_off - means[j] * 500./256. new_gain = (100. + orig_gain) * (avg_std / stds[j]) - 100. if setog: adc5g.set_spi_offset(r2, i, corder[j], new_off) adc5g.set_spi_gain(r2, i, corder[j], new_gain) sol[i,j,0] = new_off sol[i,j,1] = new_gain if doplot: plt.suptitle('%s ADC 8bit population\n%s' % (open('/etc/hostname').read().strip(), tag)) plt.subplots_adjust(hspace=0, wspace=0) plt.setp(plt.gcf(), figwidth=8, figheight=12) figfile = 'ogplot-%s.png' % tag print "saving figure to: %s" % figfile plt.savefig(figfile) solfile = 'ogsol-%s.npy' % tag print "saving solution to: %s" % solfile np.save(solfile, sol)