def onEvent(evt):

    # ------------------- #
    # INITIAL DIAGNOSTICS #
    # ------------------- #

    # Time measurement
    analysis.event.printProcessingRate()

    # ------- #
    # RECORDS #
    # ------- #
    
    # -------------------- #
    # DETECTOR CORRECTIONS #
    # -------------------- #

    if do_cmc:
        analysis.pixel_detector.cmc_pnccd(evt, back_type, back_key)
        analysis.pixel_detector.cmc_pnccd(evt, front_type, front_key)

    # -------- #
    # ANALYSIS #
    # -------- #

    # Simple hitfinding (Count Nr. of lit pixels)
    analysis.hitfinding.countLitPixels(
        evt, back_type, back_key, 
        aduThreshold=adu_threshold, 
        hitscoreThreshold=min_lit_pixels, 
        hitscoreMax=max_lit_pixels, 
        mask=mask_back)
    hit = evt["analysis"]["isHit - " + back_key].data

    # ------------------------ #
    # Send RESULT TO INTERFACE #
    # ------------------------ #

    # -------------------- #
    # RECORD data for hits #
    # -------------------- #


    if hit:
        recorder.append(evt)
Example #2
0
def onEvent(evt):

    # ------------------- #
    # INITIAL DIAGNOSTICS #
    # ------------------- #

    # Time measurement
    analysis.event.printProcessingRate()

    #analysis.event.printID(evt["eventID"])
    #print evt["photonPixelDetectors"].keys()
    #from IPython.core.debugger import Tracer
    #Tracer()()
    #for k in evt["parameters"].keys(): print k
    #print evt["parameters"].keys()
    #print evt["parameters"][injector_x_key]
    #print evt["parameters"][pnccd_x_key]
    #print evt["parameters"][injector_y_key]
    #print evt["parameters"][injector_z_key]
    #print evt.native_keys()
    #evt["psana.PNCCD.FramesV1"]["DetInfo(Camp.0:pnCCD.0)"]

    # ------- #
    # RECORDS #
    # ------- #
    
    # Injector motor positions
    inj_x = evt["parameters"][injector_x_key]
    inj_y = evt["parameters"][injector_y_key]
    inj_z = evt["parameters"][injector_z_key]
    # Injector pressures
    #p1 = evt["parameters"]["CXI:SDS:REG:01:PRESS"]
    #p2 = evt["parameters"]["CXI:SDS:REG:02:PRESS"]

    # -------------------- #
    # DETECTOR CORRECTIONS #
    # -------------------- #

    if do_cmc:
        # CMC
        analysis.pixel_detector.cmc_pnccd(evt, back_type, back_key)
        analysis.pixel_detector.cmc_pnccd(evt, front_type, front_key)
        back_type_s = "analysis"
        back_key_s = "cmc_pnccd - " + back_key
        front_type_s = "analysis"
        front_key_s = "cmc_pnccd - " + front_key
    if not do_cmc:
        back_type_s = back_type
        back_key_s = back_key
        front_type_s = front_type
        front_key_s = front_key

    # COLLECTING BACKGROUND
    if do_stacks:
        # Update
        bg_front.add(evt[front_type_s][front_key_s].data)
        bg_back.add(evt[back_type_s][back_key_s].data)
        # Reduce
        bg_front.reduce()
        bg_back.reduce()
        # Write to file
        #bg_front.write(evt,directory=bg_dir)
        #bg_back.write(evt,directory=bg_dir)


        #print data
        #data = bg_front.mean()
        #bg_front_mean = add_record(evt["analysis"], "analysis", "pnCCD front (mean)", data, unit='')
        #plotting.image.plotImage(evt["analysis"]["pnCCD front (mean)"], 
        #                         msg='', name="pnCCD front (mean)", vmin=0, vmax=10000)     
        #data = bg_front.max()
        #bg_front_max = add_record(evt["analysis"], "analysis", "pnCCD front (max)", data, unit='')
        #plotting.image.plotImage(evt["analysis"]["pnCCD front (max)"], 
        #                         msg='', name="pnCCD front (max)", vmin=0, vmax=10000)     

        #data = bg_back.mean()
        #bg_back_mean = add_record(evt["analysis"], "analysis", "pnCCD back (mean)", data, unit='')
        #plotting.image.plotImage(evt["analysis"]["pnCCD back (mean)"], 
        #                         msg='', name="pnCCD back (mean)", vmin=0, vmax=10000)     
        data = bg_back.max()
        bg_back_max = add_record(evt["analysis"], "analysis", "pnCCD back (max)", data, unit='')
        plotting.image.plotImage(evt["analysis"]["pnCCD back (max)"], 
                                 msg='', name="pnCCD back (max)")#, vmin=0, vmax=10000)     

        data = bg_back.sum()
        bg_back_sum = add_record(evt["analysis"], "analysis", "pnCCD back (sum)", data, unit='')
        plotting.image.plotImage(evt["analysis"]["pnCCD back (sum)"], 
                                 msg='', name="pnCCD back (sum)")#, vmin=0, vmax=10000)     

    # -------- #
    # ANALYSIS #
    # -------- #

    # Simple hitfinding (Count Nr. of lit pixels)
    analysis.hitfinding.countLitPixels(evt, back_type, back_key, aduThreshold=1600, hitscoreThreshold=3600, hitscoreMax=500000, mask=mask_back)

    # Compute the hitrate
    analysis.hitfinding.hitrate(evt, evt["analysis"]["isHit - " + back_key], history=10000)
    hit = evt["analysis"]["isHit - " + back_key].data
    
    # ------------------------ #
    # Send RESULT TO INTERFACE #
    # ------------------------ #

    # Plot the hitscore
    #plotting.line.plotHistory(evt["analysis"]["hitscore - " + back_key], label='Nr. of lit pixels')
    plotting.line.plotHistory(evt["analysis"]["hitscore - " + back_key], runningHistogram=True, hmin=0, hmax=5000, bins=100, window=100, history=1000)

    # Plot the hitrate
    plotting.line.plotHistory(evt["analysis"]["hitrate"], label='Hit rate [%]')

    # Plot the hitrate
    add_record(evt["analysis"], "analysis", "sum", evt[back_type][back_key].data.sum(), unit="")
    plotting.line.plotHistory(evt["analysis"]["sum"], label='Sum [ADU]')


    # Plot MeanMap of hitrate(y,z)
    if False:
        # TESTING
        x = x_min + numpy.random.rand() * (x_max-x_min)
        add_record(evt["analysis"], "analysis", "x", x, unit='')
        x = evt["analysis"]["x"]
        z = z_min + numpy.random.rand() * (z_max-z_min)
        add_record(evt["analysis"], "analysis", "z", z, unit='')
        z = evt["analysis"]["z"]
        h =  float(numpy.random.randint(2))
        plotting.correlation.plotMeanMap(x, z, h, plotid='hitrateMeanMap', **hitrateMeanMapParams)

    # Pulse Energy
    #plotting.line.plotHistory(evt["analysis"]["averagePulseEnergy"])
    
    # Perform sizing on hits
    if do_showall:
        plotting.image.plotImage(evt[front_type_s][front_key_s], 
                                 msg='', name="pnCCD front", mask=mask_front)     
        plotting.image.plotImage(evt[back_type_s][back_key_s], 
                                 msg='', name="pnCCD back", mask=mask_back) 



    # Perform sizing on hits
    if hit:
        plotting.image.plotImage(evt[front_type_s][front_key_s], 
                                 msg='', name="pnCCD front (hit)", vmin=0, vmax=10000, mask=mask_front)     
        plotting.image.plotImage(evt[back_type_s][back_key_s], 
                                 msg='', name="pnCCD back (hit)", vmin=0, vmax=10000, mask=mask_back) 
        # Record time stamps and other metadata for hits
        recorder.append(evt)
Example #3
0
def onEvent(evt):

    # ------------------- #
    # INITIAL DIAGNOSTICS #
    # ------------------- #

    # Time measurement
    analysis.event.printProcessingRate()
    #analysis.event.printID(evt["eventID"])
    #print evt.native_keys()

    # Send Fiducials and Timestamp
    plotting.line.plotTimestamp(evt["eventID"]["Timestamp"])
    
    # Spit out a lot for debugging
    if do_diagnostics: diagnostics.initial_diagnostics(evt)
    
    # -------- #
    # ANALYSIS #
    # -------- #
    #print evt.native_keys()

    # AVERAGE PULSE ENERGY
    analysis.beamline.averagePulseEnergy(evt, "pulseEnergies")

    # HIT FINDING
    #analysis.hitfinding.countTof(evt, "ionTOFs", "Acqiris 0 Channel 0")

    # Simple hit finding by counting lit pixels
    analysis.hitfinding.countLitPixels(evt, c2x2_type, c2x2_key, aduThreshold=aduThreshold, hitscoreThreshold=hitscoreThreshold, hitscoreDark=hitscoreDark, mask=mask_c2x2)
    hit  = evt["analysis"]["isHit - " + c2x2_key].data
    miss = evt["analysis"]["isMiss - " + c2x2_key].data

    # CAMERA
    doing_camera = False
    if do_camera and "Sc2Questar[camimage]" in evt["camimage"]:        
        analysis.injection_camera.getMaskedParticles(evt, "camimage", "Sc2Questar[camimage]", "maskedcamera", minX = 200, maxX = 1300, thresh = 30)
        analysis.injection_camera.countContours(evt, "image", "Sc2Questar[camimage]", "maskedcamera", "coloredmask", "particlestream")
        doing_camera = True

    # COUNT PHOTONS
    # Count photons in different detector regions
    analysis.pixel_detector.totalNrPhotons(evt, c2x2_type, c2x2_key, aduPhoton=20, aduThreshold=10)
    if do_front:
        analysis.pixel_detector.getCentral4Asics(evt, clarge_type, clarge_key)
        if do_assemble_front:
            analysis.pixel_detector.assemble(evt, clarge_type, clarge_key, x=x_front, y=y_front, nx=400, ny=400, subset=map(lambda i : (i * 8 + 1) * 2, xrange(4)))
        analysis.pixel_detector.totalNrPhotons(evt, clarge_type, clarge_key, aduPhoton=1, aduThreshold=0.5)
        analysis.pixel_detector.totalNrPhotons(evt, "analysis", "central4Asics", aduPhoton=1, aduThreshold=0.5)

        
    if miss or bgall:
        #print "MISS (hit score %i < %i)" % (evt["analysis"]["hitscore - " + c2x2_key].data, hitscoreThreshold)
        # COLLECTING BACKGROUND
        # Update
        bg.add(evt[c2x2_type][c2x2_key].data)
        # Reduce
        bg.reduce()
        # Write to file
        bg.write(evt,directory=bg_dir)
        
    if hit:
        print "HIT (hit score %i > %i)" % (evt["analysis"]["hitscore - " + c2x2_key].data, hitscoreThreshold)
        good_hit = False
        if do_sizing:
            if do_cmc:
                # CMC
                analysis.pixel_detector.cmc(evt, c2x2_type, c2x2_key, mask=beamstops_c2x2)
                c2x2_type_s = "analysis"
                c2x2_key_s = "cmc - " + c2x2_key            
            if do_bgsub:
                # Running background subtraction
                analysis.pixel_detector.bgsub(evt, c2x2_type_s, c2x2_key_s, bg=bg.last_mean)
                c2x2_type_s = "analysis"
                c2x2_key_s = "bgsub - " + c2x2_key_s            
            if not do_cmc and not do_bgsub:
                c2x2_type_s = c2x2_type
                c2x2_key_s = c2x2_key
            # RADIAL SPHERE FIT
            # Find the center of diffraction
            analysis.sizing.findCenter(evt, c2x2_type_s, c2x2_key_s, mask=mask_c2x2, **centerParams)
            # Calculate radial average
            analysis.pixel_detector.radial(evt, c2x2_type_s, c2x2_key_s, mask=mask_c2x2, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data)          
            # Fitting sphere model to get size and intensity
            analysis.sizing.fitSphereRadial(evt, "analysis", "radial distance - " + c2x2_key_s, "radial average - " + c2x2_key_s, **dict(modelParams, **sizingParams))
            # Calculate diffraction pattern from fit result 
            analysis.sizing.sphereModel(evt, "analysis", "offCenterX", "offCenterY", "diameter", "intensity", (ny_c2x2,nx_c2x2), poisson=False, **modelParams)
            # Calculate radial average of diffraction pattern from fit result
            analysis.pixel_detector.radial(evt, "analysis", "fit", mask=mask_c2x2, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data)
            # Decide whether or not the fit was successful
            fit_succeeded = evt["analysis"]["fit error"].data < fit_error_threshold
            if fit_succeeded:
                # Decide whether or not this was a good hit, i.e. a hit in the expected size range
                good_hit = abs(evt["analysis"]["diameter"].data - diameter_expected) <= diameter_error_max
            backend.add_record(evt["analysis"], "analysis", "Good hit rate", float(good_hit))

        # Record hits together with sizing results
		recorder.setup_file_if_needed(evt)
        recorder.append(evt)
Example #4
0
def onEvent(evt):

    # ------------------- #
    # INITIAL DIAGNOSTICS #
    # ------------------- #

    # Time measurement
    analysis.event.printProcessingRate()
    #analysis.event.printID(evt["eventID"])
    #print evt.native_keys()

    # Send Fiducials and Timestamp
    plotting.line.plotTimestamp(evt["eventID"]["Timestamp"])
    
    # Spit out a lot for debugging
    if do_diagnostics: diagnostics.initial_diagnostics(evt)
    
    # -------- #
    # ANALYSIS #
    # -------- #
    #print evt.native_keys()

    # AVERAGE PULSE ENERGY
    analysis.beamline.averagePulseEnergy(evt, "pulseEnergies")

    # HIT FINDING
    #analysis.hitfinding.countTof(evt, "ionTOFs", "Acqiris 0 Channel 0")

    # Simple hit finding by counting lit pixels
    analysis.hitfinding.countLitPixels(evt, c2x2_type, c2x2_key, aduThreshold=aduThreshold, hitscoreThreshold=hitscoreThreshold, hitscoreDark=hitscoreDark, mask=mask_c2x2)
    hit  = evt["analysis"]["isHit - " + c2x2_key].data
    miss = evt["analysis"]["isMiss - " + c2x2_key].data

    # CAMERA
    doing_camera = False
    if do_camera and "Sc2Questar[camimage]" in evt["camimage"]:        
        analysis.injection_camera.getMaskedParticles(evt, "camimage", "Sc2Questar[camimage]", "maskedcamera", minX = 200, maxX = 1300, thresh = 30)
        analysis.injection_camera.countContours(evt, "image", "Sc2Questar[camimage]", "maskedcamera", "coloredmask", "particlestream")
        doing_camera = True

    # COUNT PHOTONS
    # Count photons in different detector regions
    analysis.pixel_detector.totalNrPhotons(evt, c2x2_type, c2x2_key, aduPhoton=20, aduThreshold=10)
    if do_front:
        analysis.pixel_detector.getCentral4Asics(evt, clarge_type, clarge_key)
        if do_assemble_front:
            analysis.pixel_detector.assemble(evt, clarge_type, clarge_key, x=x_front, y=y_front, nx=400, ny=400, subset=map(lambda i : (i * 8 + 1) * 2, xrange(4)))
        analysis.pixel_detector.totalNrPhotons(evt, clarge_type, clarge_key, aduPhoton=1, aduThreshold=0.5)
        analysis.pixel_detector.totalNrPhotons(evt, "analysis", "central4Asics", aduPhoton=1, aduThreshold=0.5)

        
    if miss or bgall:
        #print "MISS (hit score %i < %i)" % (evt["analysis"]["hitscore - " + c2x2_key].data, hitscoreThreshold)
        # COLLECTING BACKGROUND
        # Update
        bg.add(evt[c2x2_type][c2x2_key].data)
        # Reduce
        bg.reduce()
        # Write to file
        bg.write(evt,directory=bg_dir)
        
    if hit:
        print "HIT (hit score %i > %i)" % (evt["analysis"]["hitscore - " + c2x2_key].data, hitscoreThreshold)
        good_hit = False
        if do_sizing:
            if do_cmc:
                # CMC
                analysis.pixel_detector.cmc(evt, c2x2_type, c2x2_key, mask=beamstops_c2x2)
                c2x2_type_s = "analysis"
                c2x2_key_s = "cmc - " + c2x2_key            
            if do_bgsub:
                # Running background subtraction
                analysis.pixel_detector.bgsub(evt, c2x2_type_s, c2x2_key_s, bg=bg.last_mean)
                c2x2_type_s = "analysis"
                c2x2_key_s = "bgsub - " + c2x2_key_s            
            if not do_cmc and not do_bgsub:
                c2x2_type_s = c2x2_type
                c2x2_key_s = c2x2_key
            # RADIAL SPHERE FIT
            # Find the center of diffraction
            analysis.sizing.findCenter(evt, c2x2_type_s, c2x2_key_s, mask=mask_c2x2, **centerParams)
            # Calculate radial average
            analysis.pixel_detector.radial(evt, c2x2_type_s, c2x2_key_s, mask=mask_c2x2, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data)          
            # Fitting sphere model to get size and intensity
            analysis.sizing.fitSphereRadial(evt, "analysis", "radial distance - " + c2x2_key_s, "radial average - " + c2x2_key_s, **dict(modelParams, **sizingParams))
            # Calculate diffraction pattern from fit result 
            analysis.sizing.sphereModel(evt, "analysis", "offCenterX", "offCenterY", "diameter", "intensity", (ny_c2x2,nx_c2x2), poisson=False, **modelParams)
            # Calculate radial average of diffraction pattern from fit result
            analysis.pixel_detector.radial(evt, "analysis", "fit", mask=mask_c2x2, cx=evt["analysis"]["cx"].data, cy=evt["analysis"]["cy"].data)
            # Decide whether or not the fit was successful
            fit_succeeded = evt["analysis"]["fit error"].data < fit_error_threshold
            if fit_succeeded:
                # Decide whether or not this was a good hit, i.e. a hit in the expected size range
                good_hit = abs(evt["analysis"]["diameter"].data - diameter_expected) <= diameter_error_max
            backend.add_record(evt["analysis"], "analysis", "Good hit rate", float(good_hit))

        # Record hits together with sizing results
        recorder.append(evt)
                
    # ------------------------ #
    # Send RESULT TO INTERFACE #
    # ------------------------ #

    # Send stuf from particle stream
    if doing_camera:
        plotting.line.plotHistogram(evt["analysis"]["particlestream"], log10=True, hmin=1, hmax=8, bins=1000)
        plotting.image.plotImage(evt["camimage"]["Sc2Questar[camimage]"], msg="")
        plotting.image.plotImage(evt["analysis"]["maskedcamera"], msg="", name="Masked Opal image")                                                                

    # If not miss or hit, probably dark run -> do not send anything
    #if not (miss or hit):
    #    return 
    
    # Pulse Energy
    plotting.line.plotHistory(evt["analysis"]["averagePulseEnergy"])

    # Injector position (z is along the beam, x is across the beam)
    x = evt["parameters"][injector_x_key]
    #y = evt["parameters"][injector_y_key]
    z = evt["parameters"][injector_z_key]
    plotting.line.plotHistory(x)
    #plotting.line.plotHistory(y)
    plotting.line.plotHistory(z)

    # Injector pressures
    p1 = evt["parameters"]["CXI:SDS:REG:01:PRESS"]
    p2 = evt["parameters"]["CXI:SDS:REG:02:PRESS"]
    
    # HITFINDING
    # Keep hit history for hitrate plots
    plotting.line.plotHistory(evt["analysis"]["isHit - " + c2x2_key])
    # Plot MeanMap of hitrate(y,z)
    #plotting.correlation.plotMeanMap(x, z, evt["analysis"]["hitscore - " + ]], plotid='hitrateMeanMap', **hitrateMeanMapParams)
    # Keep hitscore history
    plotting.line.plotHistory(evt["analysis"]["hitscore - " + c2x2_key], runningHistogram=True, hmin=hitscoreThreshold-100, hmax=hitscoreThreshold+100, bins=100, window=100, history=1000)

    # PHOTON COUNTING
    # Keep history of number of photons on the back
    plotting.line.plotHistory(evt["analysis"]["nrPhotons - " + c2x2_key], runningHistogram=True, hmin=hitscoreThreshold-100, hmax=hitscoreThreshold+100, bins=100, window=100, history=1000)

    # Nr. of photons 
    plotting.line.plotHistory(evt["analysis"]["nrPhotons - " + c2x2_key])
    plotting.line.plotHistory(evt["analysis"]["nrPhotons - " + c2x2_key], runningHistogram=True, hmin=0, hmax=100000, bins=100, window=100, history=1000)
    if do_front:
        plotting.line.plotHistory(evt["analysis"]["nrPhotons - central4Asics"])

    # Plot ScatterPlot with colored hitscore
    #plotting.correlation.plotScatterColor(x,z, evt["analysis"]["hitscore - " + c2x2_key], plotid='hitscoreScatter', vmin=0, vmax=2000, xlabel='Injector X', ylabel='Injectory Z', zlabel='Hitscore')

    if do_showall:        
        # Image of back detector for all events
        plotting.image.plotImage(evt[c2x2_type][c2x2_key], msg="", name="Cspad 2x2: All", mask=mask_c2x2, vmin=vmin_c2x2, vmax=vmax_c2x2)
        # Histogram of detector for all events
        plotting.line.plotHistogram(evt[c2x2_type][c2x2_key], mask=mask_c2x2, hmin=-100, hmax=100, bins=200, label='Cspad 2x2 pixel value [ADU]')
   
    # THIS HERE CAUSED A CRASH
    #plotting.correlation.plotMeanMap(evt["analysis"]["averagePulseEnergy"], evt["analysis"]["nrPhotons - central4Asics"], hit)
    #plotting.line.plotHistory(evt["analysis"]["averagePulseEnergy"])
    
    if hit:

        # Scatter plot of hitscore vs. injector in Z
        plotting.correlation.plotScatter(x, evt["analysis"]["hitscore - " + c2x2_key], plotid='tuneInjectionX', history=10000, xlabel='Injector in X', ylabel='Hitscore')  
        plotting.correlation.plotScatter(z, evt["analysis"]["hitscore - " + c2x2_key], plotid='tuneInjectionZ', history=10000, xlabel='Injector in Z', ylabel='Hitscore')  
        
        # Scatter plot for hitscore vs. injector pressure
        plotting.correlation.plotScatter(p1, evt["analysis"]["hitscore - " + c2x2_key], plotid='tuneInjectionP1', history=10000, xlabel='Injector in X', ylabel='Hitscore')  
        plotting.correlation.plotScatter(p2, evt["analysis"]["hitscore - " + c2x2_key], plotid='tuneInjectionP2', history=10000, xlabel='Injector in Z', ylabel='Hitscore')  
        
        # ToF
        plotting.line.plotTrace(evt["ionTOFs"]["Acqiris 0 Channel 1"]) 
        
        # Image of hit
        plotting.image.plotImage(evt[c2x2_type][c2x2_key], msg='', name="Cspad 2x2: Hit", vmin=vmin_c2x2, vmax=vmax_c2x2 )      

        if do_sizing:
            if do_cmc or do_bgsub:
                # Image of hit (cmc corrected)
                plotting.image.plotImage(evt[c2x2_type_s][c2x2_key_s], msg="", mask=mask_c2x2, name="Cspad 2x2: Hit (corrected)", vmin=vmin_c2x2, vmax=vmax_c2x2)
        
        if do_front:
            # Front detector image (central 4 asics) of hit
            #plotting.image.plotImage(evt[clarge_type][clarge_key])
            plotting.image.plotImage(evt["analysis"]["central4Asics"], vmin=vmin_clarge, vmax=vmax_clarge)
            if do_assemble_front:
                plotting.image.plotImage(evt["analysis"]["assembled - " + clarge_key], msg="", name="Cspad large (central 4 asics): Hit", vmin=vmin_clarge, vmax=vmin_clarge)

        if do_sizing:

            # Image of fit
            msg = "diameter: %.2f nm \nIntensity: %.2f mJ/um2" %(evt["analysis"]["diameter"].data, evt["analysis"]["intensity"].data)
            plotting.image.plotImage(evt["analysis"]["fit"], log=True, mask=mask_c2x2, name="Cspad 2x2: Fit result (radial sphere fit)", vmin=vmin_c2x2, vmax=vmax_c2x2, msg=msg)
            
            # Plot measurement radial average
            plotting.line.plotTrace(evt["analysis"]["radial average - "+c2x2_key_s], evt["analysis"]["radial distance - "+c2x2_key_s],tracelen=radial_tracelen)
            # Plot fit radial average
            plotting.line.plotTrace(evt["analysis"]["radial average - fit"], evt["analysis"]["radial distance - fit"], tracelen=radial_tracelen)         
            # Fit error history
            plotting.line.plotHistory(evt["analysis"]["fit error"])

            if fit_succeeded:

                # Plot parameter histories
                plotting.line.plotHistory(evt["analysis"]["offCenterX"])
                plotting.line.plotHistory(evt["analysis"]["offCenterY"])
                plotting.line.plotHistory(evt["analysis"]["diameter"], runningHistogram=True)
                plotting.line.plotHistory(evt["analysis"]["intensity"], runningHistogram=True)
                plotting.correlation.plotMeanMap(x,z,evt["analysis"]["diameter"].data, plotid='DiameterMeanMap', **diameterMeanMapParams)
                plotting.correlation.plotMeanMap(x,z,evt["analysis"]["intensity"].data, plotid='IntensityMeanMap', **intensityMeanMapParams)

                # Diameter vs. intensity scatter plot
                plotting.correlation.plotScatter(evt["analysis"]["diameter"], evt["analysis"]["intensity"], plotid='Diameter vs. intensity', history=100)

                if good_hit:

                    # Image of good hit
                    plotting.image.plotImage(evt[c2x2_type][c2x2_key], msg="", log=True, mask=mask_c2x2, name="Cspad 2x2: Hit and correct particle size", vmin=vmin_c2x2, vmax=vmax_c2x2)
                    
                    if do_front:
                        # Front detector image of good hit
                        plotting.image.plotImage(evt[clarge_type][clarge_key], msg="", name="Cspad large (full): Correct particle size", vmin=vmin_clarge, vmax=vmax_clarge)       
        
    # ----------------- #
    # FINAL DIAGNOSTICS #
    # ----------------- #
    
    # Spit out a lot for debugging
    if do_diagnostics: diagnostics.final_diagnostics(evt)