示例#1
0
    def applyCTICorrection(self):
        """
        Applies a CTI correction in electrons using CDM03 CTI model.
        Converts the data to electrons using the gain value given in self.values.
        The number of forward reads is defined by self.values['order'] parameter.

        Bristow & Alexov (2003) algorithm further developed for HST data
        processing by Massey, Rhodes et al.

        There is probably an excess of .copy() calls here, but I had some problems
        when calling the Fortran code so I added them for now.
        """
        self.instrument['trapfile'] = self.instrument['ctifile']

        if self.instrument['order'] < 1:
            self.log.warning(
                'Order < 1, no CTI correction (forward modeling) applied!')
            return

        #multiply with the gain
        self.log.info(
            'Multiplying the data with the gain factor = %.3f to convert electrons'
            % self.instrument['gain'])
        self.data *= self.instrument['gain']

        #make a copy, not necessary...?
        out = self.data.copy()

        if out.shape[0] < 2500:
            #this must be quadrant
            self.log.info(
                'Applying %i forward reads to a quadrant to perform a CTI correction'
                % self.instrument['order'])
            for x in range(self.instrument['order']):
                rd = CTI.CDM03(self.instrument, [], self.log)
                damaged = rd.applyRadiationDamage(
                    out.copy(), iquadrant=self.hdu['QUADRANT'])
                out += self.data.copy() - damaged
                self.log.info('Forward read %i performed' % (x + 1))
                del (rd)
        else:
            self.log.info(
                'Applying %i forward reads to the full CCD to perform a CTI correction'
                % self.instrument['order'])
            for x in range(self.instrument['order']):
                rd = CTI.CDM03(self.instrument, out.copy(), self.log)
                damaged = rd.radiateFullCCD2()
                out += self.data.copy() - damaged
                self.log.info('Forward read %i performed' % (x + 1))
                del (rd)

        #divide with the gain
        self.log.info(
            'Dividing the data with the gain factor = %.3f to convert ADUs' %
            self.instrument['gain'])
        self.data = out / self.instrument['gain']
def currentValues(parallel='cdm_euclid_parallel.dat',
                  serial='cdm_euclid_serial.dat',
                  chargeInjection=43500.):
    #set up the charge injection chargeInjection positions
    lines = dict(xstart1=577,
                 xstop1=588,
                 ystart1=1064,
                 ystop1=1075,
                 xstart2=4096 - 588,
                 xstop2=4096 - 577,
                 ystart2=4132 - 1075,
                 ystop2=4132 - 1064)

    #create two CCD files
    CCDhor = np.zeros((4132, 4096), dtype=np.float32)
    CCDver = np.zeros((4132, 4096), dtype=np.float32)

    #add horizontal charge injection lines
    CCDhor[lines['ystart1']:lines['ystop1'], :] = chargeInjection
    CCDhor[lines['ystart2']:lines['ystop2'], :] = chargeInjection

    #add vertical charge injection lines
    CCDver[:, lines['xstart1']:lines['xstop1']] = chargeInjection
    CCDver[:, lines['xstart2']:lines['xstop2']] = chargeInjection

    #write output files
    writeFITSfile(CCDhor,
                  'ChargeInjectionsHorizontal.fits',
                  unsigned16bit=False)
    writeFITSfile(CCDver, 'ChargeInjectionsVertical.fits', unsigned16bit=False)

    #radiate the CCDs
    params = MSSLCDM03params()
    params.update(
        dict(parallelTrapfile=parallel, serialTrapfile=serial, rdose=1.6e10))
    CCDCTIhor = CTI.CDM03bidir(params, CCDhor).radiateFullCCD()
    CCDCTIver = CTI.CDM03bidir(params, CCDver).radiateFullCCD()

    #write output files
    writeFITSfile(CCDCTIhor,
                  'ChargeInjectionsHorizontalCTI.fits',
                  unsigned16bit=False)
    writeFITSfile(CCDCTIver,
                  'ChargeInjectionsVerticalCTI.fits',
                  unsigned16bit=False)

    #plot profiles
    plotProfiles(CCDCTIver, CCDCTIhor, lines)
def generateSimpleTestData(lines, level=(100, 1000, 10000)):
    """

    """
    params = MSSLCDM03params()
    params.update(
        dict(
            parallelTrapfile=
            '/Users/sammy/EUCLID/CTItesting/Reconciliation/singletrap/cdm_test_parallel.dat',
            serialTrapfile=
            '/Users/sammy/EUCLID/CTItesting/Reconciliation/singletrap/cdm_test_serial.dat',
            rdose=1.6e10,
            serial=0,
            parallel=1,
            quadrant=0))

    for i, l in enumerate(level):
        print i, l
        #create a quadrant
        CCD = np.zeros((2066, 2048), dtype=np.float64)

        #add horizontal charge injection lines
        CCD[lines['ystart1']:lines['ystop1'], :] = l
        writeFITSfile(CCD.copy(),
                      'ChargeInjectionParallelSingle%i.fits' % i,
                      unsigned16bit=False)

        #radiate CTI to plot initial set trails
        c = CTI.CDM03bidir(params, [])
        CCDCTIhor = c.applyRadiationDamage(CCD.copy().transpose()).transpose()
        writeFITSfile(CCDCTIhor, 'CTISingle%i.fits' % i, unsigned16bit=False)
def addCTI(file, loc=1900, bcgr=72.2, thibautCDM03=False, beta=True, serial=1, parallel=1):
    """
    Add CTI trails to a FITS file or input data.
    """
    #trap parameters: parallel
    if thibautCDM03:
        f1 = '/Users/sammy/EUCLID/vissim-python/data/cdm_thibaut_parallel.dat'
        f2 = '/Users/sammy/EUCLID/vissim-python/data/cdm_thibaut_serial.dat'
        params = ThibautsCDM03params()
        params.update(dict(parallelTrapfile=f1, serialTrapfile=f2, rdose=8.0e9, serial=serial, parallel=parallel))
    else:
        f1 = '/Users/sammy/EUCLID/vissim-python/data/cdm_euclid_parallel.dat'
        f2 = '/Users/sammy/EUCLID/vissim-python/data/cdm_euclid_serial.dat'
        params = MSSLCDM03params()
        params.update(dict(parallelTrapfile=f1, serialTrapfile=f2, rdose=8.0e9, serial=serial, parallel=parallel))
        if beta:
            params.update(dict(beta_p=0.6, beta_s=0.6))

    print f1, f2

    #load data
    if type(file) is str:
        nocti = pf.getdata(file)
    else:
        nocti = file.copy()

    #place it on canvas
    tmp = np.zeros((2066, 2048))
    ysize, xsize = nocti.shape
    ysize /= 2
    xsize /= 2
    tmp[loc-ysize:loc+ysize, loc-xsize:loc+xsize] = nocti.copy()

    #add background
    tmp += bcgr

    #run CDM03
    c = CTI.CDM03bidir(params, [])
    tmp = c.applyRadiationDamage(tmp)

    #remove background and make a cutout
    CTIdata = tmp[loc-ysize:loc+ysize, loc-xsize:loc+xsize]
    CTIdata -= bcgr
    CTIdata[CTIdata < 0.] = 0.

    return CTIdata
def useThibautsData(log, output, bcgr=72.2, sigma=0.75, iterations=4, loc=1900, galaxies=1000,
                    datadir='/Users/smn2/EUCLID/CTItesting/uniform/',
                    thibautCDM03=False, beta=False, serial=1, parallel=1):
    """
    Test the impact of CTI in case of no noise and no correction.

    :param log: logger instance
    :param bcgr: background in electrons for the CTI modelling
    :param sigma: size of the weighting function for the quadrupole moment
    :param iterations: number of iterations in the quadrupole moments estimation
    :param loc: location to which the galaxy will be placed [default=1900]
    :param galaxies: number of galaxies to use (< 10000)
    :param datadir: directory pointing to the galaxy images

    :return:
    """
    files = g.glob(datadir + '*.fits')
    #pick randomly
    files = np.random.choice(files, galaxies, replace=False)

    #trap parameters: parallel
    if thibautCDM03:
        f1 = '/Users/smn2/EUCLID/vissim-python/data/cdm_thibaut_parallel.dat'
        f2 = '/Users/smn2/EUCLID/vissim-python/data/cdm_thibaut_serial.dat'
        params = ThibautsCDM03params()
        params.update(dict(parallelTrapfile=f1, serialTrapfile=f2, rdose=8.0e9, serial=serial, parallel=parallel))
    else:
        f1 = '/Users/smn2/EUCLID/vissim-python/data/cdm_euclid_parallel.dat'
        f2 = '/Users/smn2/EUCLID/vissim-python/data/cdm_euclid_serial.dat'
        params = MSSLCDM03params()
        params.update(dict(parallelTrapfile=f1, serialTrapfile=f2, rdose=8.0e9, serial=serial, parallel=parallel))
        if beta:
            params.update(dict(beta_p=0.6, beta_s=0.6))

    print f1, f2

    #store shapes
    eclean = []
    e1clean = []
    e2clean = []
    R2clean = []
    xclean = []
    yclean = []
    eCTI = []
    e1CTI = []
    e2CTI = []
    R2CTI = []
    xCTI = []
    yCTI = []
    eCTIfixed = []
    e1CTIfixed = []
    e2CTIfixed = []
    R2CTIfixed = []
    xCTIfixed = []
    yCTIfixed = []

    fh = open(output.replace('.pk', '.csv'), 'w')
    fh.write('#files: %s and %s\n' % (f1, f2))
    for key in params:
        print key, params[key]
        fh.write('# %s = %s\n' % (key, str(params[key])))
    fh.write('#file, delta_e, delta_e1, delta_e2, delta_R2, delta_x, delta_y\n')
    for f in files:
        print 'Processing: ', f

        #load data
        nocti = pf.getdata(f)

        #scale to SNR about 10 (average galaxy, a single exposure)
        nocti /= np.sum(nocti)
        nocti *= 1500.

        #place it on canvas
        tmp = np.zeros((2066, 2048))
        ysize, xsize = nocti.shape
        ysize /= 2
        xsize /= 2
        tmp[loc-ysize:loc+ysize, loc-xsize:loc+xsize] = nocti.copy()

        #add background
        tmp += bcgr

        #run CDM03
        c = CTI.CDM03bidir(params, [])
        tmp = c.applyRadiationDamage(tmp.copy().transpose()).transpose()

        #remove background and make a cutout
        CTIdata = tmp[loc-ysize:loc+ysize, loc-xsize:loc+xsize]
        CTIdata -= bcgr
        CTIdata[CTIdata < 0.] = 0.

        #write files
        #fileIO.writeFITS(nocti, f.replace('.fits', 'noCTI.fits'), int=False)
        #fileIO.writeFITS(CTI, f.replace('.fits', 'CTI.fits'), int=False)

        #reset settings
        settings = dict(sigma=sigma, iterations=iterations)

        #calculate shapes
        sh = shape.shapeMeasurement(nocti.copy(), log, **settings)
        results = sh.measureRefinedEllipticity()

        eclean.append(results['ellipticity'])
        e1clean.append(results['e1'])
        e2clean.append(results['e2'])
        R2clean.append(results['R2'])
        xclean.append(results['centreX'])
        yclean.append(results['centreY'])

        #CTI, fitted centroid
        sh = shape.shapeMeasurement(CTIdata.copy(), log, **settings)
        results2 = sh.measureRefinedEllipticity()

        eCTI.append(results2['ellipticity'])
        e1CTI.append(results2['e1'])
        e2CTI.append(results2['e2'])
        R2CTI.append(results2['R2'])
        xCTI.append(results2['centreX'])
        yCTI.append(results2['centreY'])

        #fixed centroid
        settings['fixedPosition'] = True
        settings['fixedX'] = results['centreX']
        settings['fixedY'] = results['centreY']
        settings['iterations'] = 1
        sh = shape.shapeMeasurement(CTIdata.copy(), log, **settings)
        results3 = sh.measureRefinedEllipticity()

        eCTIfixed.append(results3['ellipticity'])
        e1CTIfixed.append(results3['e1'])
        e2CTIfixed.append(results3['e2'])
        R2CTIfixed.append(results3['R2'])
        xCTIfixed.append(results3['centreX'])
        yCTIfixed.append(results3['centreY'])

        text = '%s,%e,%e,%e,%e,%e,%e\n' % (f, results['ellipticity'] - results2['ellipticity'],
                                           results['e1'] - results2['e1'], results['e2'] - results2['e2'],
                                           results['R2'] - results2['R2'],
                                           results['centreX'] - results2['centreX'],
                                           results['centreY'] - results2['centreY'])
        fh.write(text)
        print text

    fh.close()

    results = {'eclean': np.asarray(eclean),
               'e1clean': np.asarray(e1clean),
               'e2clean': np.asarray(e2clean),
               'R2clean': np.asarray(R2clean),
               'xclean': np.asarray(xclean),
               'yclean': np.asarray(yclean),
               'eCTI': np.asarray(eCTI),
               'e1CTI': np.asarray(e1CTI),
               'e2CTI': np.asarray(e2CTI),
               'R2CTI': np.asarray(R2CTI),
               'xCTI': np.asarray(xCTI),
               'yCTI': np.asarray(yCTI),
               'eCTIfixed': np.asarray(eCTIfixed),
               'e1CTIfixed': np.asarray(e1CTIfixed),
               'e2CTIfixed': np.asarray(e2CTIfixed),
               'R2CTIfixed': np.asarray(R2CTIfixed),
               'xCTIfixed': np.asarray(xCTIfixed),
               'yCTIfixed': np.asarray(yCTIfixed)}

    #save to a file
    fileIO.cPickleDumpDictionary(results, output)

    return results
def testCTIcorrectionNonoise(log, files, output, sigma=0.75, iterations=4):
    """
    Calculates PSF properties such as ellipticity and size from data w/ and w/o CTI.

    :param log: python logger instance
    :type log: instance
    :param files: a list of files to be processed
    :type files: list
    :param sigma: size of the Gaussian weighting function
    :type sigma: float
    :param iterations: the number of iterations for the moment based shape estimator
    :type iterations: int

    :return: ellipticity and size
    :rtype: dict
    """
    eclean = []
    e1clean = []
    e2clean = []
    R2clean = []
    xclean = []
    yclean = []
    eCTI = []
    e1CTI = []
    e2CTI = []
    R2CTI = []
    xCTI = []
    yCTI = []
    eCTIfixed = []
    e1CTIfixed = []
    e2CTIfixed = []
    R2CTIfixed = []
    xCTIfixed = []
    yCTIfixed = []

    fh = open(output.replace('pk', 'csv'), 'w')
    fh.write('#file, delta_e, delta_e1, delta_e2, delta_R2, delta_x, delta_y\n')
    for f in files:
        print 'Processing: ', f

        #reset settings
        settings = dict(sigma=sigma, iterations=iterations)

        #load no cti data
        nocti = pf.getdata(f.replace('CUT', 'CUTnoctinonoise'))

        #load CTI data
        CTI = pf.getdata(f)

        sh = shape.shapeMeasurement(nocti, log, **settings)
        results = sh.measureRefinedEllipticity()

        eclean.append(results['ellipticity'])
        e1clean.append(results['e1'])
        e2clean.append(results['e2'])
        R2clean.append(results['R2'])
        xclean.append(results['centreX'])
        yclean.append(results['centreY'])

        #CTI, fitted centroid
        sh = shape.shapeMeasurement(CTI.copy(), log, **settings)
        results2 = sh.measureRefinedEllipticity()

        eCTI.append(results2['ellipticity'])
        e1CTI.append(results2['e1'])
        e2CTI.append(results2['e2'])
        R2CTI.append(results2['R2'])
        xCTI.append(results2['centreX'])
        yCTI.append(results2['centreY'])

        #fixed centroid
        settings['fixedPosition'] = True
        settings['fixedX'] = results['centreX']
        settings['fixedY'] = results['centreY']
        settings['iterations'] = 1
        sh = shape.shapeMeasurement(CTI.copy(), log, **settings)
        results3 = sh.measureRefinedEllipticity()

        eCTIfixed.append(results3['ellipticity'])
        e1CTIfixed.append(results3['e1'])
        e2CTIfixed.append(results3['e2'])
        R2CTIfixed.append(results3['R2'])
        xCTIfixed.append(results3['centreX'])
        yCTIfixed.append(results3['centreY'])

        text = '%s,%e,%e,%e,%e,%e,%e\n' % (f, results['ellipticity'] - results2['ellipticity'],
              results['e1'] - results2['e1'], results['e2'] - results2['e2'], results['R2'] - results2['R2'],
              results['centreX'] - results2['centreX'], results['centreY'] - results2['centreY'])
        fh.write(text)
        print text

    fh.close()

    results = {'eclean' : np.asarray(eclean),
               'e1clean' : np.asarray(e1clean),
               'e2clean' : np.asarray(e2clean),
               'R2clean' : np.asarray(R2clean),
               'xclean' : np.asarray(xclean),
               'yclean' : np.asarray(yclean),
               'eCTI' : np.asarray(eCTI),
               'e1CTI' : np.asarray(e1CTI),
               'e2CTI' : np.asarray(e2CTI),
               'R2CTI' : np.asarray(R2CTI),
               'xCTI' : np.asarray(xCTI),
               'yCTI' : np.asarray(yCTI),
               'eCTIfixed': np.asarray(eCTIfixed),
               'e1CTIfixed': np.asarray(e1CTIfixed),
               'e2CTIfixed': np.asarray(e2CTIfixed),
               'R2CTIfixed': np.asarray(R2CTIfixed),
               'xCTIfixed': np.asarray(xCTIfixed),
               'yCTIfixed': np.asarray(yCTIfixed)}

    #save to a file
    fileIO.cPickleDumpDictionary(results, output)

    return results
def deriveTrails(parallel,
                 serial,
                 chargeInjection=44500.,
                 lines=dict(ystart1=1064, ystop1=1075, xstart1=577,
                            xstop1=588),
                 thibaut=False,
                 beta=False):
    """
    Derive CTI trails in both parallel and serial direction separately given the input data files

    :param parallel: name of the parallel CTI file
    :param serial:  name of the serial CTI file
    :param chargeInjection: number of electrons to inject
    :param lines: positions of the charge injectino lines
    :param thibaut: whether or not to scale the capture cross sections from m**2 to cm**2

    :return:
    """
    #create a quadrant
    CCD = np.zeros((2066, 2048), dtype=np.float64)

    #add horizontal charge injection lines
    CCD[lines['ystart1']:lines['ystop1'], :] = chargeInjection
    if thibaut:
        writeFITSfile(CCD.copy(), 'ChargeHT.fits', unsigned16bit=False)
    else:
        writeFITSfile(CCD.copy(), 'ChargeH.fits', unsigned16bit=False)

    #radiate CTI to plot initial set trails
    if thibaut:
        params = ThibautsCDM03params()
        params.update(
            dict(parallelTrapfile=parallel,
                 serialTrapfile=serial,
                 rdose=8.0e9,
                 serial=0,
                 parallel=1,
                 quadrant=0))
        c = CTI.CDM03bidir(params, [])
        CCDCTIhor = c.applyRadiationDamage(CCD.copy().transpose()).transpose()
        writeFITSfile(CCDCTIhor, 'CTIHT.fits', unsigned16bit=False)
    else:
        if beta:
            params = MSSLCDM03params()
            params.update(
                dict(parallelTrapfile=parallel,
                     serialTrapfile=serial,
                     rdose=1.6e10,
                     beta_s=0.6,
                     beta_p=0.6,
                     serial=0,
                     parallel=1,
                     quadrant=0))
            c = CTI.CDM03bidir(params, [])
            CCDCTIhor = c.applyRadiationDamage(
                CCD.copy().transpose()).transpose()
            writeFITSfile(CCDCTIhor, 'CTIH2.fits', unsigned16bit=False)
        else:
            params = MSSLCDM03params()
            params.update(
                dict(parallelTrapfile=parallel,
                     serialTrapfile=serial,
                     rdose=1.6e10,
                     serial=0,
                     parallel=1,
                     quadrant=0))
            c = CTI.CDM03bidir(params, [])
            CCDCTIhor = c.applyRadiationDamage(
                CCD.copy().transpose()).transpose()
            writeFITSfile(CCDCTIhor, 'CTIH.fits', unsigned16bit=False)

    profileParallel = np.average(CCDCTIhor, axis=1)

    #now serial
    CCD = np.zeros((2066, 2048), dtype=np.float64)

    #add horizontal charge injection lines
    CCD[:, lines['xstart1']:lines['xstop1']] = chargeInjection
    if thibaut:
        writeFITSfile(CCD, 'ChargeVT.fits', unsigned16bit=False)
    else:
        writeFITSfile(CCD, 'ChargeV.fits', unsigned16bit=False)

    #radiate CTI to plot initial set trails
    if thibaut:
        params = ThibautsCDM03params()
        params.update(
            dict(parallelTrapfile=parallel,
                 serialTrapfile=serial,
                 rdose=8.0e9,
                 parallel=0,
                 serial=1,
                 quadrant=0))
        c = CTI.CDM03bidir(params, [])
        CCDCTI = c.applyRadiationDamage(CCD.copy().transpose()).transpose()
        writeFITSfile(CCDCTI, 'CTIVT.fits', unsigned16bit=False)
    else:
        if beta:
            params = MSSLCDM03params()
            params.update(
                dict(parallelTrapfile=parallel,
                     serialTrapfile=serial,
                     rdose=1.6e10,
                     beta_p=0.6,
                     beta_s=0.6,
                     parallel=0,
                     serial=1,
                     quadrant=0))
            c = CTI.CDM03bidir(params, [])
            CCDCTI = c.applyRadiationDamage(CCD.copy().transpose()).transpose()
            writeFITSfile(CCDCTI, 'CTIV2.fits', unsigned16bit=False)
        else:
            params = MSSLCDM03params()
            params.update(
                dict(parallelTrapfile=parallel,
                     serialTrapfile=serial,
                     rdose=1.6e10,
                     parallel=0,
                     serial=1,
                     quadrant=0))
            c = CTI.CDM03bidir(params, [])
            CCDCTI = c.applyRadiationDamage(CCD.copy().transpose()).transpose()
            writeFITSfile(CCDCTI, 'CTIV.fits', unsigned16bit=False)

    #plot trails
    profileSerial = np.average(CCDCTI, axis=0)

    return profileParallel, profileSerial
def testPythonCDM03(parallel='cdm_euclid_parallel.dat',
                    serial='cdm_euclid_serial.dat',
                    chargeInjection=44500.,
                    lines=dict(ystart1=1064,
                               ystop1=1075,
                               xstart1=577,
                               xstop1=588)):
    from CTI import CTI

    trapdata = np.loadtxt(parallel)
    nt_p = trapdata[:, 0]
    sigma_p = trapdata[:, 1]
    taur_p = trapdata[:, 2]

    trapdata = np.loadtxt(serial)
    nt_s = trapdata[:, 0]
    sigma_s = trapdata[:, 1]
    taur_s = trapdata[:, 2]

    #create a quadrant
    CCD = np.zeros((2066, 2048), dtype=np.float32)

    #add horizontal charge injection lines
    CCD[lines['ystart1']:lines['ystop1'], :] = chargeInjection
    writeFITSfile(CCD.copy(), 'ChargeHtest.fits', unsigned16bit=False)

    #radiate CTI to plot initial set trails
    c = CTI.CDM03Python({}, [])
    CCDCTIhor = c.applyRadiationDamage(CCD.copy(),
                                       nt_p,
                                       sigma_p,
                                       taur_p,
                                       nt_s,
                                       sigma_s,
                                       taur_s,
                                       rdose=1.6e10)
    writeFITSfile(CCDCTIhor, 'CTIHtest.fits', unsigned16bit=False)

    parallel = np.average(CCDCTIhor, axis=1)

    #now serial
    CCD = np.zeros((2066, 2048), dtype=np.float32)

    #add horizontal charge injection lines
    CCD[:, lines['xstart1']:lines['xstop1']] = chargeInjection
    writeFITSfile(CCD, 'ChargeVtest.fits', unsigned16bit=False)

    #radiate CTI to plot initial set trails
    c = CTI.CDM03Python({}, [])
    CCDCTI = c.applyRadiationDamage(CCD.copy(),
                                    nt_p,
                                    sigma_p,
                                    taur_p,
                                    nt_s,
                                    sigma_s,
                                    taur_s,
                                    rdose=1.6e10)
    writeFITSfile(CCDCTI, 'CTIVtest.fits', unsigned16bit=False)

    #plot trails
    serial = np.average(CCDCTI, axis=0)

    #get parallel measurements
    indp, parallelValues = parallelMeasurements(returnScale=True)
    inds, serialValues = serialMeasurements(returnScale=True)

    #mask out irrelevant values
    mskp = indp > -5
    msks = inds > -5
    indp = indp[mskp][:100]
    inds = inds[msks][:250]
    parallelValues = parallelValues[mskp][:100]
    serialValues = serialValues[msks][:250]

    #rescale
    indp += 185
    inds += 10

    #cutout right region
    shift = 5
    profileParallelM = parallel[lines['ystop1'] - shift:lines['ystop1'] -
                                shift + len(indp)]
    profileSerialM = serial[lines['xstop1'] - shift:lines['xstop1'] - shift +
                            len(inds)]

    #set up the charge injection chargeInjection positions
    fig = plt.figure()
    fig.suptitle(
        'CCD204 05325-03-02 Hopkinson EPER at 200kHz, with 20.48ms, 8e9 at 10MeV'
    )
    fig.subplots_adjust(bottom=0.1, right=0.8, top=0.9)
    ax1 = fig.add_subplot(211)
    ax2 = fig.add_subplot(212)

    ax1.set_title('Parallel CTI')
    ax2.set_title('Serial CTI')

    ax1.semilogy(indp, parallelValues, 'bo', ms=3, label='152.55K')
    ax1.semilogy(indp, profileParallelM, 'y-', label='MSSL')

    ax2.semilogy(inds, serialValues, 'bs', ms=3, label='152.5K')
    ax2.semilogy(inds, profileSerialM, 'y-', label='MSSL')

    ax1.set_ylim(1., 60000)
    ax2.set_ylim(1., 60000)

    ax1.set_xlim(180, 250)
    ax2.set_xlim(0, 220)

    ax2.set_xlabel('Pixels')
    ax1.set_ylabel('Photoelectrons')
    ax2.set_ylabel('Photoelectrons')
    ax1.legend(fancybox=True, shadow=True, numpoints=1)
    ax2.legend(fancybox=True, shadow=True, numpoints=1)
    plt.savefig('PythonCDM03.pdf')
    plt.close()
def addCTI(file,
           locx=200,
           locy=200,
           bcgr=72.2,
           thibautCDM03=False,
           test=False,
           beta=True,
           serial=1,
           parallel=0,
           quadrant=0,
           single=True):
    """
    Add CTI trails to a FITS file or input data.
    """
    #trap parameters: parallel2
    if thibautCDM03:
        f1 = '/Users/sammy/EUCLID/vissim-python/data/cdm_thibaut_parallel.dat'
        f2 = '/Users/sammy/EUCLID/vissim-python/data/cdm_thibaut_serial.dat'
        params = ThibautsCDM03params()
        params.update(
            dict(parallelTrapfile=f1,
                 serialTrapfile=f2,
                 rdose=8.e9,
                 serial=serial,
                 parallel=parallel))
    elif test:
        if single:
            f1 = '/Users/sammy/EUCLID/CTItesting/Reconciliation/singletrap/cdm_test_parallel.dat'
            f2 = '/Users/sammy/EUCLID/CTItesting/Reconciliation/singletrap/cdm_test_serial.dat'
        else:
            f1 = '/Users/sammy/EUCLID/CTItesting/Reconciliation/multitrap/cdm_test_parallel.dat'
            f2 = '/Users/sammy/EUCLID/CTItesting/Reconciliation/multitrap/cdm_test_serial.dat'
        params = TestCDM03params()
        params.update(
            dict(parallelTrapfile=f1,
                 serialTrapfile=f2,
                 rdose=8e9,
                 serial=serial,
                 parallel=parallel))
    else:
        f1 = '/Users/sammy/EUCLID/vissim-python/data/cdm_euclid_parallel.dat'
        f2 = '/Users/sammy/EUCLID/vissim-python/data/cdm_euclid_serial.dat'
        params = MSSLCDM03params()
        params.update(
            dict(parallelTrapfile=f1,
                 serialTrapfile=f2,
                 rdose=8.e9,
                 serial=serial,
                 parallel=parallel))
        if beta:
            params.update(dict(beta_p=0.6, beta_s=0.6))

    #load data
    if type(file) is str:
        nocti = pf.getdata(file)
    else:
        nocti = file.copy()

    #place it on canvas
    if locx is not None:
        tmp = np.zeros((2066, 2048))
        ysize, xsize = nocti.shape
        ysize /= 2
        xsize /= 2
        tmp[locy - ysize:locy + ysize,
            locx - xsize:locx + xsize] = nocti.copy()
    else:
        tmp = nocti

    #add background
    if bcgr is not None:
        tmp += bcgr

    #run CDM03
    c = CTI.CDM03bidir(params, [])
    tmp = c.applyRadiationDamage(tmp.T, iquadrant=quadrant).T

    #make a cutout
    if locx is not None:
        CTIdata = tmp[locy - ysize:locy + ysize, locx - xsize:locx + xsize]
    else:
        CTIdata = tmp

    #remove background
    if bcgr is not None:
        CTIdata -= bcgr
        CTIdata[CTIdata < 0.] = 0.

    return CTIdata