def generatePulses(frame): # this dom is the one which should launch while its only LC partner (dom 2) is # dead from previous launches dom1 = OMKey(47, 1) # this dom will be hit at all three times, first to ensure that both digitizers # are busy and then to supply the LC high to dom1 dom2 = OMKey(47, 2) # this dom will be pulse twice (time1 and time 2) to ensure that dom2 has LC and # makes HLC readouts (to maximize deadtime) dom3 = OMKey(47, 3) #This is a IT DOM to test IT SLC dom4 = OMKey(47, 62) pulseWeight = 1000 time1 = 0 time2 = time1 + 6600 time3 = time2 + 8000 pulses = simclasses.I3MCPulseSeriesMap() series1 = simclasses.I3MCPulseSeries() series2 = simclasses.I3MCPulseSeries() series3 = simclasses.I3MCPulseSeries() pulse = simclasses.I3MCPulse() pulse.charge = pulseWeight pulse.time = time1 series3.append(pulse) series2.append(pulse) pulse.time = time2 series3.append(pulse) series2.append(pulse) pulse.time = time3 series2.append(pulse) series1.append(pulse) pulses[dom1] = series1 pulses[dom2] = series2 pulses[dom3] = series3 pulse.charge = 5000 pulse.time = 500000 series2.append(pulse) pulses[dom4] = series2 frame.Put("TestPulses", pulses)
def _GetDroppedDoms(self): """ Returns a list of dropped doms. Only experimental data supported (run id required) Returns: list: A list of `OMKeys`. """ # Simulation is not supported if self.simulation: icetray.logging.log_fatal("Dropped dom information is not supported for simulation.") self._GetDomInfoFromI3Live() droppedDoms = [] # Dropped doms are categorized by souce, e.g. `user_alert` and `moni_file` for key, src in self.runInfo['dropped_doms'].items(): for om in src: # Only use this dropped dom if it dropped before the good stop time # string compare works since both date times are in the correct format for it if om['drop_time'] < self.snapshot['runs'][0]['good_tstop']: droppedDoms.append(OMKey(om['dom_string'], om['dom_position'])) return droppedDoms
def _GetUnconfiguredDoms(self): """ Returns the list of unconfigured doms. If the simulation flag is set to `True`, it checks the dom status in the frame. If a dom is not in the status or has no HV, it is considered as unconfigured dom. If you provided a run id and the simulation flag is `False`, it gets the information from I3Live. Returns: list: A list if `OMKeys`. """ unconfDoms = [] icetray.logging.log_info("Getting unconfigured OMs") # If simulation is True, we need to get the information from the GCD file if self.simulation: for dom in self.frame['I3Geometry'].omgeo.keys(): if self.ignoreNewDOMs and \ self.frame['I3Geometry'].omgeo[dom].omtype in self.newDOMTypes : continue if dom not in self.frame['I3DetectorStatus'].dom_status.keys() or \ self.frame['I3DetectorStatus'].dom_status[dom].pmt_hv == 0: unconfDoms.append(dom) else: self._GetDomInfoFromI3Live() for key, om in self.runInfo['unconfigured_doms'].items(): unconfDoms.append(OMKey(om['string'], om['position'])) icetray.logging.log_info("Finished getting unconfigured OMs") return unconfDoms
def _GetNoHVDoms(self): """ Returns the list of doms with no HV. If the simulation flag is set to `True`, it checks the dom status in the frame. If you provided a run id and the simulation flag is `False`, it gets the information from I3Live. Returns: list: A list if `OMKeys`. """ noHVDoms = [] # If simulation is True, we need to get the information from the GCD file if self.simulation: for dom in self.frame['I3Geometry'].omgeo.keys(): if self.ignoreNewDOMs and \ self.frame['I3Geometry'].omgeo[dom].omtype in self.newDOMTypes : continue if self.frame['I3DetectorStatus'].dom_status[dom].pmt_hv == 0: noHVDoms.append(dom) else: self._GetDomInfoFromI3Live() if 'No HV' in self.runInfo['problem_doms'].keys(): for key, om in self.runInfo['problem_doms']['No HV'].items(): noHVDoms.append(OMKey(om['string'], om['position'])) return noHVDoms
def generateOMString(stringNumber, startPos, numDoms, spacing, direction): orientation = dataclasses.I3Orientation( 0, 0, -1, 1, 0, 0) # same orientation as icecube DOMs (dir=down) area = 0.5857538 * I3Units.meter2 # same area as KM3NET MDOMs geomap = dataclasses.I3OMGeoMap() x = startPos.x y = startPos.y z = startPos.z dx = [spacingVal * direction.x for spacingVal in spacing] dy = [spacingVal * direction.y for spacingVal in spacing] dz = [spacingVal * direction.z for spacingVal in spacing] # create OMKeys and I3OMGeo for DOMs on string and add them to the map for i in xrange(0, numDoms): omkey = OMKey(stringNumber, i, 0) omGeometry = dataclasses.I3OMGeo() omGeometry.omtype = dataclasses.I3OMGeo.OMType.IceCube omGeometry.orientation = orientation omGeometry.area = area omGeometry.position = dataclasses.I3Position(x + dx[i] * i, y + dy[i] * i, z + dz[i] * i) geomap[omkey] = omGeometry return geomap
def convertToOmkeyList(stringList, layers): omkeyList = [] for string in stringList: for dom in layers: omkeyList.append(OMKey(string, dom, 0)) return omkeyList
def generatePulses(frame): global n dom1 = OMKey(47,1) dom2 = OMKey(47,2) dom3 = OMKey(47,15) dom4 = OMKey(47,25) dom5 = OMKey(47,26) pulseWeight = 10 pulses = simclasses.I3MCPulseSeriesMap() series = simclasses.I3MCPulseSeries() pulse = simclasses.I3MCPulse() pulse.charge = pulseWeight if(n==1): time1 = 0 time2 = 29*icetray.I3Units.microsecond else: time1 = 2*29*icetray.I3Units.microsecond time2 = 3*29*icetray.I3Units.microsecond series2 = simclasses.I3MCPulseSeries() series3 = simclasses.I3MCPulseSeries() pulse.time = time1 series.append(pulse) pulse.time = time2 series.append(pulse) pulses[dom1]=series pulses[dom2]=series pulses[dom3]=series if(n == 1): pulses[dom4]=series else: pulse.time = 29*icetray.I3Units.microsecond+200 series = simclasses.I3MCPulseSeries() series.append(pulse) pulses[dom5]=series frame.Put("TestPulses",pulses)
def fillDT(frame, Streams2=[icetray.I3Frame.DAQ]): if 'ATWDPortiaPulse' not in frame: print 'no pulse' return False # Get ATWD info calib_atwd = frame['CalibratedATWD'] cleanData = frame['CleanInIceRawData'] #print cleanData # Loop over OM Keys and get calibrated ATWD # Set SC pulses SC_DOMs = [OMKey(55, d) for d in SCDoms] for key, domlaunchs in cleanData: for i in range(len(SCDoms)): if key == SC_DOMs[i]: domTime = 9999999 passLC = False for launch in domlaunchs: if launch.time < domTime: domTime = launch.time passLC = launch.lc_bit # Do not look at events where LCBit fail if not passLC: continue if domTime < 0: continue # Now we have start time, loop over calibrated # waveforms and keep the waveform that has shortest # time waveForms = calib_atwd.get(key) dT = -999 maxV = -999 for waveform in waveForms: if waveform.time <= domTime: # This is it, record info voltages = waveform.waveform binSize = waveform.binWidth for j in range(len(voltages)): Voltage = voltages[j] / I3Units.V if maxV < Voltage: maxV = Voltage dT = ( (len(voltages) - j) * binSize) / I3Units.ns break # Now save the wavetime, if non-negative if dT < 0: continue # Fill h_dT_perDom[i].Fill(dT) # end if have right DOM # end for loop over SC DOMS # end loop over clean data return True
def generateMCPEList(photons, modkey): omkey = OMKey(modkey.string, modkey.om, 0) mcpeList = simclasses.I3MCPESeries() photonList = [] for photon in photons: if survived(photon,omkey): mcpe = simclasses.I3MCPE() #mcpe.id = dataclasses.I3ParticleID(photon.particleMajorID, photon.particleMinorID) mcpe.npe = 1 mcpe.time = photon.time #TODO: change to corrected time mcpeList.append(mcpe) photonList.append(photon) return mcpeList, photonList
def getPhotonDataFromFrames(frameList): photonAngle = [] photonWavelength = [] for frame in frameList: photonMap = frame["I3Photons"] for modkey, photons in photonMap: for photon in photons: photonAngle.append( getrelativeAngle(photon, OMKey(modkey.string, modkey.om, 0))) photonWavelength.append(photon.wavelength) return photonAngle, photonWavelength
def test_I3FlasherInfo_equality(self): fi1 = dataclasses.I3FlasherInfo() fi2 = dataclasses.I3FlasherInfo() fi1.flashing_om = OMKey(2, 1, 0) fi2.flashing_om = OMKey(2, 1, 0) fi1.flash_time = 1.0 fi2.flash_time = 1.0 fi1.atwd_bin_size = 1.0 fi2.atwd_bin_size = 1.0 fi1.led_brightness = 1 fi2.led_brightness = 1 fi1.mask = 1 fi2.mask = 1 fi1.width = 1 fi2.width = 1 fi1.rate = 1 fi2.rate = 1 fi1.raw_atwd3 = [1, 2, 3] fi2.raw_atwd3 = [1, 2, 3] self.assertTrue(fi1 == fi2, "this should be true.")
def Physics(self, frame): fit, mask, fit_status = get_fit(frame, 0.5) mask1 = dataclasses.I3RecoPulseSeriesMapMask(frame, 'All_pulses') count = 0 for omkey in frame['WaveformInfo'].keys(): dom = int(omkey.split(',')[1]) string = int(omkey.split(',')[0].split('(')[1]) key = OMKey(string, dom) mask1.set(key, bool(mask[count])) count += 1 frame['NewMask'] = mask1 self.PushFrame(frame)
def _GetTemporarilyBadDoms(self): """ Returns a list of temporarily bad doms. Only experimental data supported (run id required) Returns: list: A list of `OMKeys`. """ # Simulation is not supported if self.simulation: icetray.logging.log_fatal("Temporarily bad dom information is not supported for simulation.") self._GetDomInfoFromI3Live() tmpBadDoms = [] if 'Temporarily bad' in self.runInfo['problem_doms'].keys(): for key, om in self.runInfo['problem_doms']['Temporarily bad'].items(): tmpBadDoms.append(OMKey(om['string'], om['position'])) return tmpBadDoms
def _GetDarkNoiseModeDoms(self): """ Returns a list of good dark noise doms. That means, doms that have HV, are configured, and are in dark noise mode. If the simulation flag is set to `True`, it checks the dom status in the frame. If you provided a run id and the simulation flag is `False`, it gets the information from I3Live. Note: Currently is the only source the frame. Will be updated as soon I3Live provides this information. Returns: list: A list of `OMKeys`. """ goodDarkNoiseDoms = [] # If simulation is True, we need to get the information from the GCD file if self.simulation: for dom in self.frame['I3Geometry'].omgeo.keys(): if self.ignoreNewDOMs and \ self.frame['I3Geometry'].omgeo[dom].omtype in self.newDOMTypes : continue if dom in self.frame['I3DetectorStatus'].dom_status.keys() and \ self.frame['I3DetectorStatus'].dom_status[dom].lc_mode == self.frame['I3DetectorStatus'].dom_status[dom].LCMode.SoftLC and \ self.frame['I3DetectorStatus'].dom_status[dom].pmt_hv > 0: goodDarkNoiseDoms.append(dom) else: self._GetDomInfoFromI3Live() if 'No LC' in self.runInfo['problem_doms'].keys(): for key, om in self.runInfo['problem_doms']['No LC'].items(): position = "%s-%s" % (om['string'], om['position']) if position in self.runInfo['configured_doms'].keys() and \ position not in self.runInfo['problem_doms']['No HV'].keys(): goodDarkNoiseDoms.append(OMKey(om['string'], om['position'])) return goodDarkNoiseDoms
def harvest_calibrated_waveforms(inputfile, outputfile, digitizer, targets=None, debug=False): ''' Inputs -------- inputfile: str (name of an i3 file) outputfile: str (name of a vzp file) digitizer: str (type of digitization to use: ATWD or FADC) targets: str (name of a .py file containing a list of Tuples called target) debug: bool (debug flag) ''' print("harvesting ", inputfile, "...") import numpy as np from icecube.icetray import OMKey, I3Units from icecube import dataclasses, simclasses from icecube import dataio import pickle if debug: import matplotlib.pyplot as plt exec("from utils.%s import targets" % (args.targets.split('.')[-2].split('/')[-1])) #convert tuples into OMKey objects targets_key = [] for e in targets: a = OMKey(e[0], e[1]) targets_key.append(a) targets = targets_key F = dataio.I3File(inputfile) n_hits_total = 0. n_hits_hlc = 0. previous_atwd_1_hit = {} previous_hit = {} waveforms = {} for om in targets: waveforms[om] = {} waveforms[om]['traces'] = [] waveforms[om]['times'] = [] waveforms[om]['type'] = digitizer waveforms[om]['n_HLC'] = 0.0 waveforms[om]['n_tot'] = 0.0 waveforms[om]['deadtime'] = [] previous_atwd_1_hit[om] = 0.0 previous_hit[om] = None n_frames = 0 while F.more(): frame = F.pop_frame() for hits in frame['CalibratedWaveforms']: pmt = hits[0] if pmt in targets: for h in hits[1]: if h.hlc: waveforms[pmt]['n_HLC'] += 1. if str(h.source) == digitizer: # # Store the waveform information # Note: waveforms at this stage give positive pulses # waveforms[pmt]['traces'].append(h.waveform) waveforms[pmt]['times'].append(h.time) if debug: plt.plot(np.array(h.waveform) / I3Units.mV) plt.xlabel('sample #') plt.ylabel('Waveform signal (mV)') plt.show() # Deadtime calculations #----------------------------------------------------------------------- # Deal with the deadtime between ATWD recordings # And overflow to higher amplification channels # # No matter the type of digitizer data wanted, both channels # (ATWD and FADC) need to distinguish which ATWD fired on a hit # before computing the associated deadtime if digitizer == 'ATWD': if str( h.source ) == 'ATWD' and h.channel == 0: # Deal with the deadtime between ATWD recordings # And overflow to higher amplification channels # ATWD A if h.source_index == 0: previous_atwd_1_hit[pmt] = h.time waveforms[pmt]['deadtime'].append(6023.) elif h.source_index == 1: if previous_atwd_1_hit[pmt] is None: print "at file ", inputfile, " frame # ", n_frames sys.exit( "ERROR: something is fishy: you found an atwd_b hit with no previous atwd_a hit." ) tprevious = previous_atwd_1_hit[ pmt] + 32500 # time for ATWD A to finish digitizing dead_b = h.time + 427 # start of the ATWD B deadtime waveforms[pmt]['deadtime'].append( tprevious - dead_b) previous_atwd_1_hit[pmt] = None elif digitizer == 'FADC' and str(h.source) == 'FADC': if previous_hit[pmt] is None: print "at file ", inputfile, " frame # ", n_frames sys.exit( "ERROR: something is fishy: First hit found was an FADC hit..." ) elif str(previous_hit[pmt].source ) == 'ATWD' and previous_hit[ pmt].source_index == 0: #if ATWD A: previous_atwd_1_hit[pmt] = h.time waveforms[pmt]['deadtime'].append( 50 ) # only a 50ns delay before ATWD-b can kick in elif str(previous_hit[pmt].source ) == 'ATWD' and previous_hit[ pmt].source_index == 1: #if ATWD B tprevious = previous_atwd_1_hit[pmt] + 32500 waveforms[pmt]['deadtime'].append(tprevious - (h.time + 6400)) previous_hit[pmt] = h else: print "HEY! found an SLC hit!!!" waveforms[pmt]['n_tot'] += 1. n_frames += 1 pickle.dump([n_frames, waveforms], open(outputfile, "wb")) return
def Physics(self, frame): print(self.run_id, self.evt_id) wfs = frame[self.key] if self.string is None and self.dom is None: prev_string = 1 wf_cnt = 0 fig, ax = plt.subplots() for omkey in wfs.keys(): if omkey.string != prev_string: prev_string = omkey.string if wf_cnt > 0: ax.legend(loc='best') ax.set_xlabel(r'Time / ns') ax.set_ylabel(r'ATWD Voltage / mV') filename = os.path.join(self.outputfolder, self.out_name + '_evt_{}.pdf') exists = True i = 0 while exists: fname = filename.format(i) if os.path.isfile(fname): i += 1 else: exists = False print(fname) fig.savefig(fname) wf_cnt = 0 fig, ax = plt.subplots() waveform_series = wfs[omkey] for waveform in waveform_series: wf_vect = np.array(waveform.waveform) / I3Units.mV if np.sum(wf_vect) > WAVEFORM_THRESH: start_time = waveform.time bin_width = waveform.bin_width time = np.linspace(start_time, start_time + bin_width * 128, 128) ax.plot(time, wf_vect, label=omkey) wf_cnt += 1 elif self.string is not None and self.dom is not None: fig, ax = plt.subplots() key = OMKey(self.string, self.dom) ax.legend(loc='best') ax.set_xlabel(r'Time / ns') try: waveform_series = wfs[key] except KeyError: print('No waveforms found for this dom. Skipping this event!') return else: min_time = 0 for waveform in waveform_series: wf_vect = np.array(waveform.waveform) / I3Units.mV start_time = waveform.time bin_width = waveform.bin_width if min_time == 0: min_time = start_time # Skip possible second launches if len(wf_vect) == 128: if start_time > min_time + 5000: continue elif len(wf_vect) == 256: if start_time > min_time + 20000: continue time = np.linspace(start_time, start_time + bin_width * len(wf_vect), len(wf_vect)) ax.plot(time, wf_vect, label=key) if len(wf_vect) == 128: ax.set_ylabel(r'ATWD Voltage / mV') elif len(wf_vect) == 256: ax.set_ylabel('FADC Voltage / mV') filename = os.path.join( self.outputfolder, self.out_name + f'evt{self.evt_id}_str{self.string}_dom{self.dom}.png') if len(wf_vect) == 256: filename = filename.replace('.png', '_fadc.png') print(filename) fig.savefig(filename) else: raise NotImplementedError()
#!/usr/bin/env python import unittest from I3Tray import I3Tray, I3Units from icecube import icetray, dataclasses, DomTools from icecube.icetray import OMKey doms = [OMKey(1, 1), OMKey(1, 2), OMKey(1, 3), OMKey(1, 4), OMKey(2, 4)] def make_geometry(): geo = dataclasses.I3Geometry() for omkey in doms: geo.omgeo[omkey] = dataclasses.I3OMGeo() geo.omgeo[icetray.OMKey(1, 1)].position = dataclasses.I3Position(0, 0, 0) geo.omgeo[icetray.OMKey(1, 2)].position = dataclasses.I3Position(0, 0, 50) geo.omgeo[icetray.OMKey(1, 3)].position = dataclasses.I3Position(0, 0, 100) geo.omgeo[icetray.OMKey(1, 4)].position = dataclasses.I3Position(0, 0, 500) geo.omgeo[icetray.OMKey(2, 4)].position = dataclasses.I3Position(0, 50, 500) return geo def make_rpsmap(): rpsmap = dataclasses.I3RecoPulseSeriesMap() for omkey in doms: rpsmap[omkey] = dataclasses.I3RecoPulseSeries() # time, width, and charge rp_properties = [(1650, 100, 0), (1850, 100, 1), (0, 100, 2), (550, 0, 3), (800, 0, 4), (3500, 100, 5), (3500, 100, 6),
# generated by create_forced_lc.py from icecube.icetray import OMKey doms_to_plot = [] dom_targets = [] doms_to_plot.append({ 'name': "S09-D39", 'T': -19.450003, 'inice': "09-39", 'scale': 150, 'spe': 75000, 'qpair': 5 }) dom_targets.append(OMKey(9, 37)) dom_targets.append(OMKey(9, 38)) dom_targets.append(OMKey(9, 39)) dom_targets.append(OMKey(9, 40)) dom_targets.append(OMKey(9, 41)) doms_to_plot.append({ 'name': "S41-D37", 'T': -20.049994, 'inice': "41-37", 'scale': 150, 'spe': 75000, 'qpair': 5 }) dom_targets.append(OMKey(41, 35)) dom_targets.append(OMKey(41, 36))
mcpe.npe = 1 mcpe.time = photon.time #TODO: change to corrected time mcpeList.append(mcpe) photonList.append(photon) return mcpeList, photonList # TODO: def getCorrectedTime(photon, omkey): while( infile.more() ): frame = infile.pop_daq() photonDOMMap = frame["I3Photons"] mcpeMap = simclasses.I3MCPESeriesMap() succPhotonMap = simclasses.I3CompressedPhotonSeriesMap() for modkey in photonDOMMap.keys(): mcpeList, photonList = generateMCPEList(photonDOMMap[modkey], modkey) omkey = OMKey(modkey.string, modkey.om, 0) if len(mcpeList) > 0: mcpeMap[omkey] = mcpeList succPhotonMap[modkey] = photonList frame["MCPESeriesMap"] = mcpeMap # only add frame to file if a hit was generated if passFrame(frame, mcpeMap.keys(), int(args.hitThresh), int(args.domThresh)): frame["SuccPhotonMap"] = succPhotonMap frame.Delete("I3Photons") outfile.push(frame) outfile.close()
def least_distance_to_polygon(fr): if fr.Has("I3Geometry"): geo_map = fr["I3Geometry"] else: print "ERROR: No I3Geometry in frame!" exit(1) #String numbers that defines the polygon. String 72 is repeated so that the polygon is closed when connecting those strings in order. if geometry == 'ic86': poly_strings = [72, 74, 50, 6, 1, 31, 75, 78] if geometry == 'ic79': poly_strings = [72, 74, 50, 6, 2, 41, 75, 78] # read in x,y coordinates from the gcd file for the polygon strings om = OMKey() gx = [] gy = [] for i in range(len(poly_strings)): om.string = poly_strings[i] om.om = 60 gx += [geo_map.omgeo[om].position.x] gy += [geo_map.omgeo[om].position.y] #print "polygon x coordinates: ", gx #print "polygon y coordinates: ", gy # pull the x,y coordinates of string 78, 72, and 74 for later usage x72 = gx[0] y72 = gy[0] x74 = gx[1] y74 = gy[1] x78 = gx[7] y78 = gy[7] # x,y coordinates for event vertex rx = fr[RecoVertex].x ry = fr[RecoVertex].y inside = point_in_polygon(gx, gy, rx, ry) if inside: print "Event vertex is inside the IC86 polygon. Now calculate the perpendicular distances to the polygon edges.." str_dist = [] event_dist = [] for i in range(1, len(poly_strings)): str_dist += [cal_distance(gx[i - 1], gy[i - 1], gx[i], gy[i])] event_dist += [cal_distance(rx, ry, gx[i - 1], gy[i - 1])] str_dist += [cal_distance(gx[-1], gy[-1], gx[0], gy[0]) ] # add the last polygon edge to close the polygon event_dist += [cal_distance(rx, ry, gx[-1], gy[-1]) ] # add the last polygon edge to close the polygon #print "str_dist: ", str_dist #print "event_dist: ", event_dist #event_to polystring_dist.pop() #remove the last repeated distances between event vertex and string 31 """ The perpendicular distances from an event vertex to one polygon edge is the height of the triangle formed by the event vertex and the two string which defines the polygon edge. According to Heron's theorem: area=sqrt(s(s-a)(s-b)(s-c)), semiperimeter s=1/2(a+b+c) Also, area=1/2*base*height. Hence, height=2*area/base=2*sqrt(s(s-a)(s-b)(s-c))/base. Here, the bases are the polygon edges. """ triad_heights = [] semiperimeters = [] for i in range(1, len(str_dist)): semiperimeters += [ 0.5 * (str_dist[i - 1] + event_dist[i - 1] + event_dist[i]) ] semiperimeters += [ 0.5 * (str_dist[-1] + event_dist[-1] + event_dist[0]) ] # add the last polygon edge element to close the polygon #print "semiperimeter: ", semiperimeters for i in range(1, len(str_dist)): if semiperimeters[i - 1] * (semiperimeters[i - 1] - event_dist[ i - 1]) * (semiperimeters[i - 1] - str_dist[i - 1]) * ( semiperimeters[i - 1] - event_dist[i]) < 0: triad_heights += [0] continue triad_heights += [ 2 * np.sqrt(semiperimeters[i - 1] * (semiperimeters[i - 1] - event_dist[i - 1]) * (semiperimeters[i - 1] - str_dist[i - 1]) * (semiperimeters[i - 1] - event_dist[i])) / str_dist[i - 1] ] if semiperimeters[-1] * (semiperimeters[-1] - event_dist[-1]) * ( semiperimeters[-1] - str_dist[-1]) * (semiperimeters[-1] - event_dist[0]) > 0: triad_heights += [ 2 * np.sqrt(semiperimeters[-1] * (semiperimeters[-1] - event_dist[-1]) * (semiperimeters[-1] - str_dist[-1]) * (semiperimeters[-1] - event_dist[0])) / str_dist[-1] ] # add the last polygon edge element to close the polygon else: triad_heights += [0] """ Now divide the polygon into three regions: region A: perpendicular distance to edge 78-72 is inside of the polygon; region B: perpendicular distances to both edges 78-72 and 72-74 are inside of the polygon; region C: perpendicular distance to edge 72-74 is inside of the polygon. These three regions are formed by two perpendicular lines through string 72, w.r.t. line 78-72 and line 72-74 respectively. The two lines deviding these regions are defined as: l_{AB} := -(x78-x72)/(y78-y72)(x-x72)+y72; l_{BC} := -(x74-x72)/(y74-y72)(x-x72)+y72 For points fall within region A, distance to edge 72-74 should not be considered as minimum distance to polygon edges. Likewise, points that fall within region B, both distances to edges 78-72 and 72-74 should not be considered, and for region C, distance to edge 78-72 should not be considered. """ # CAUTION: the following manipulation is dependent on the ordering of the triad_heights elements: distance to edge 72-74 is first element, while distance to edge 72-78 is last element. if (ry - y72 + (x78 - x72) / (y78 - y72) * (rx - x72)) >= 0: # point in region A #print "point in region A!" del triad_heights[0] #remove distance to edge 72-74 elif ((ry - y72 + (x78 - x72) / (y78 - y72) * (rx - x72)) < 0) and ( (ry - y72 + (x74 - x72) / (y74 - y72) * (rx - x72)) < 0): # point in region B #print "point in region B!" del triad_heights[0] del triad_heights[-1] elif (ry - y72 + (x74 - x72) / (y74 - y72) * (rx - x72)) >= 0: # point in region C #print "point in region C!" del triad_heights[-1] #print "Perpendicular distances to polygon edges: ", triad_heights print "Minimum perpendicular distance to polygon edges: ", min( triad_heights) print "Minimum distance to polygon corner strings: ", min( event_dist) least_dist_to_polygon = min(triad_heights) #if min(event_dist)<min(triad_heights): # least_dist_to_polygon=min(event_dist) fr["LeastDistanceToPolygon" + outputname] = dataclasses.I3Double(least_dist_to_polygon) fr["LeastDistanceToCornerString" + outputname] = dataclasses.I3Double(min(event_dist)) else: print "Event vertex is outside of the IC86 polygon.." fr["LeastDistanceToPolygon" + outputname] = dataclasses.I3Double(-1) fr["LeastDistanceToCornerString" + outputname] = dataclasses.I3Double(-1)
#!/usr/bin/env python # generated by create_forced_lc.py from icecube.icetray import OMKey # target doms for which we harvest vzp data targets = [(39,57),(32,57),(2,58), (31,58),(22,57),(73,58), (62,58),(64,58),(56,57), (1,57)] doms_to_plot = [] dom_targets = [] doms_to_plot.append( {'name':"S39-D57",'T':-10.650000,'inice': "39-57",'scale': 150,'atwd_spe': 20,'fadc_spe': 75000,'qpair': 5})#2.5 dom_targets.append(OMKey(39,55)) dom_targets.append(OMKey(39,56)) dom_targets.append(OMKey(39,57)) dom_targets.append(OMKey(39,58)) dom_targets.append(OMKey(39,59)) #doms_to_plot.append( {'name':"S32-D57",'T':-9.650000,'inice': "32-57",'scale': 150,'spe': 75000,'qpair': 5}) # dom_targets.append(OMKey(32,55)) # dom_targets.append(OMKey(32,56)) # dom_targets.append(OMKey(32,57)) # dom_targets.append(OMKey(32,58)) # dom_targets.append(OMKey(32,59)) doms_to_plot.append( {'name':"S02-D58",'T':-10.650000,'inice': "02-58",'scale': 150,'atwd_spe': 22, 'fadc_spe': 75000, 'qpair': 5})#2.6 dom_targets.append(OMKey(2,56)) dom_targets.append(OMKey(2,57))
import os from icecube.icetray import OMKey from icecube.simclasses import I3CylinderMap import numpy as np source_directory = os.environ['I3_SRC'] file = open(source_directory + "/ppc/resources/ice/dx.dat") contents = [] for line in file: contents += [line.split()] DOMs = [] for key in contents: DOMs.append( [OMKey( int(key[0]) , int(key[1]) ) , float(key[2])] ) # i contains string , OM_number , orientation of cable , and error on orientation class AddCylinder(icetray.I3Module): def __init__(self,context): icetray.I3Module.__init__(self,context) self.AddParameter( "TopCylinder" , "Position of top of cylinder" , dataclasses.I3Position( 0 , 0 , 500 )) self.AddParameter( "BottomCylinder" , "Position of the bottom of cylinder" , dataclasses.I3Position( 0 , 0 , -500 )) self.AddParameter( "Radius" , "Radius of Cylinder" , 10) def Configure(self): self.top = self.GetParameter('TopCylinder') self.bottom = self.GetParameter('BottomCylinder') self.radius = self.GetParameter('Radius')
break elif (np.log10(frame['MCPrimary'].energy) < 7) & (frame['MCPrimary'].dir.zenith * 180 / np.pi > 10): continue eventinfo = {} for omkey in frame['WaveformInfo'].keys(): eventinfo[omkey] = {} eventinfo[omkey]['run_number'] = frame['I3EventHeader'].run_id eventinfo[omkey]['event_number'] = frame['I3EventHeader'].event_id eventinfo[omkey]['zenith'] = frame['MCPrimary'].dir.zenith eventinfo[omkey]['azimuth'] = frame['MCPrimary'].dir.azimuth eventinfo[omkey]['energy'] = np.log10(frame['MCPrimary'].energy) dom = int(omkey.split(',')[1]) string = int(omkey.split(',')[0].split('(')[1]) position = frame['I3Geometry'].omgeo[OMKey(string, dom)].position eventinfo[omkey]['x'] = position.x eventinfo[omkey]['y'] = position.y eventinfo[omkey]['z'] = position.z eventinfo[omkey]['ShowerCOG_x'] = frame['Laputop'].pos.x eventinfo[omkey]['ShowerCOG_y'] = frame['Laputop'].pos.y eventinfo[omkey]['ShowerCOG_z'] = frame['Laputop'].pos.z eventinfo[omkey]['ShowerCOG_time'] = frame['ShowerCOG'].time eventinfo[omkey]['ShowerCOG_zen'] = frame['ShowerPlane'].dir.zenith eventinfo[omkey]['ShowerCOG_az'] = frame['ShowerPlane'].dir.azimuth eventinfo[omkey]['m'] = frame['WaveformInfo'][omkey]['m'] eventinfo[omkey]['s'] = frame['WaveformInfo'][omkey]['s'] eventinfo[omkey]['charge'] = frame['WaveformInfo'][omkey]['Charge'] eventinfo[omkey]['chargePe'] = frame['WaveformInfo'][omkey][ 'Charge_PE'] eventinfo[omkey]['chargeVEM'] = frame['LaputopHLCVEM'][OMKey(
# generated by create_forced_lc.py from icecube.icetray import OMKey doms_to_plot = [] dom_targets = [] doms_to_plot.append({ 'name': "S59-D08", 'T': -30.349997, 'inice': "59-08", 'scale': 150, 'spe': 75000, 'qpair': 5 }) dom_targets.append(OMKey(59, 6)) dom_targets.append(OMKey(59, 7)) dom_targets.append(OMKey(59, 8)) dom_targets.append(OMKey(59, 9)) dom_targets.append(OMKey(59, 10)) doms_to_plot.append({ 'name': "S75-D07", 'T': -29.650000, 'inice': "75-07", 'scale': 150, 'spe': 75000, 'qpair': 5 }) dom_targets.append(OMKey(75, 5)) dom_targets.append(OMKey(75, 6))
def fillDT(frame, Streams2=[icetray.I3Frame.DAQ]): if 'ATWDPortiaPulse' not in frame: print 'no pulse' return False # Get ATWD info calib_atwd = frame['CalibratedATWD'] cleanData = frame['CleanInIceRawData'] # Get lumi point lumi_point = checkTimes(frame) if lumi_point < 0: return False # Loop over OM Keys and get calibrated ATWD # Set SC pulses SC_DOMs = [OMKey(55,d) for d in SCDoms] for i in range(len(SCDoms)): # Make OMKey key = OMKey(55,i) # Get DOM launch domlaunchs = cleanData.get(key) # Get Earliest time DOM launch domTime = -1 passLC = False for launch in domlaunchs: if domTime < launch.GetStartTime(): domTime = launch.GetStartTime() passLC = launch.GetLCBit() # Do not look at events where LCBit fail if not passLC: return False if domTime < 0: return False # Now we have start time, loop over calibrated # waveforms and keep the waveform that has shortest # time waveForms = calib_atwd.get(key) dT = -999 maxV = -999 for waveform in waveForms: if waveform.time <= domTime: # This is it, record info binSize = waveform.GetBinWidth() startT = waveform.GetStartTime() voltages = waveform.GetWaveform() for i in range(len(voltages)): if maxV < voltages[i]: maxV = voltages[i] dT = (i*binSize)/I3Units.ns break # Now save the wavetime, if non-negative if dT < 0: return False # Fill h_dT_perDom_perLumi[i][lumi_point]->Fill(dT) # end loop over doms return True
def cutwavetime(frame, Streams6=[icetray.I3Frame.DAQ]): if 'ATWDPortiaPulse' not in frame: print 'no pulse' return False pulses = frame['ATWDPortiaPulse'] domlaunch = frame['CleanInIceRawData'] calib_atwd = frame['CalibratedATWD'] # Get the point for a given luminosity based # on the timing information lumi_point = checkTimes(frame) # Define the SC string doms near_sc = [OMKey(55,d) for d in range(37, 51)] # Check if have enough pulses. 400 is from # Aya's code, so I will check why... h_npulse.Fill( len(pulses) ) if lumi_point >= 0: h_npulse_perLumi[lumi_point].Fill( len(pulses) ) if len(pulses) < 400: return False counter = 0 max_time_diff = 0.0 max_amp = 0 m_NPE = 0 m_LCBit = 0 LEThres = 0.01 max_time_largestV = 0 for omkey, portiapulse in pulses: if omkey in near_sc: # Load variables for plotting amplitude = portiapulse.GetAmplitude() / I3Units.volt NPE = portiapulse.GetEstimatedNPE() letime = portiapulse.GetLETime() waveform_series = calib_atwd.get(omkey) m_LCBit = portiapulse.GetLCBit() # Count above amplitude if amplitude > LEThres: counter += 1 # Fill hists for timing info h_amp.Fill(amplitude) if lumi_point >= 0: h_amp_perLumi[lumi_point].Fill(amplitude) # Examine Time DIfference stuff for waveform in waveform_series: wavetime = waveform.time if wavetime < letime: time_diff = (letime-wavetime) / I3Units.nanosecond h_tDiff.Fill(time_diff) if lumi_point >=0: h_tDiff_perLumi[lumi_point].Fill(time_diff) if time_diff > max_time_diff: max_time_diff = time_diff m_NPE = NPE if amplitude > max_amp: max_amp = amplitude max_time_largestV = time_diff # Actually place the cut now if counter < 14 : return False h_maxTDiff.Fill( max_time_diff ) h_maxTDiff_vs_NPE.Fill(max_time_diff, m_NPE) if lumi_point >=0: h_maxTDiff_perLumi[lumi_point].Fill(max_time_diff) h_maxTDiff_vs_NPE_perLumi[lumi_point].Fill(max_time_diff, m_NPE) if m_LCBit !=0 : h_maxTDiff_passLCBit_perLumi[lumi_point].Fill(max_time_diff) h_nDOM_perLumi[lumi_point].Fill( counter ) h_nDOM_vs_maxTDiff_perLumi[lumi_point].Fill(counter, max_time_diff) h_maxTDiff_forMaxV_perLumi[lumi_point].Fill(max_time_largestV) # Hoping this will speed things up # by returning False... not really # any noticable increase in speed return False
def wavetimeCut(frame, Streams1=[icetray.I3Frame.DAQ]): global h_dt # Currently only works for SC2, will # always be true for SC1 if "SC1" in m_config.SC: return True # Only placing requirement for 30, # 51, and 100% filters lumis = ["30", "51", "100"] if m_config.lumi not in lumis: return True # Get ATWD and DOM launch info calib_atwd = frame['CalibratedATWD'] cleanData = frame['CleanInIceRawData'] # Loop over OM Keys and get calibrated ATWD nearestDOMs = [OMKey(55, d) for d in range(37, 51)] maxLETime = 0 for key, domlaunchs in cleanData: for i in range(len(nearestDOMs)): if key == nearestDOMs[i]: # Get earliest dom launch domTime = sys.float_info.max passLC = False for launch in domlaunchs: if launch.time < domTime: domTime = launch.time passLC = launch.lc_bit # Not considering DOM when LCBit failed if not passLC: continue if domTime < 0: continue # Now have start time. Loop over calibrated # waveforms and keep waveform that is closest # to domlaunch time. Waveforms = calib_atwd.get(key) for waveform in Waveforms: if waveform.time <= domTime: binSize = waveform.binWidth voltages = waveform.waveform for j in range(len(voltages)): Voltage = voltages[j] / I3Units.V if m_config.p_lumi.lumiVThresh( m_config.lumi) < Voltage: LETime = ((j * binSize)) / I3Units.ns if LETime > maxLETime: maxLETime = LETime break # done with loop since found waveform break # done with loop since found waveform # end loop over DOMs if maxLETime > m_config.p_lumi.lumiTimeCut(m_config.lumi): return False return True
def OfflineCalibration(tray, name, InIceOutput='InIcePulses', IceTopOutput='IceTopPulses', BadDOMList='BadDomsListSLC', WavedeformSPECorrections=False, pass2=False): """ Re-do calibration and feature extraction for those launches that were sent in raw form, unifying the results with the pulses sent as SuperDST only. Also performs bad-DOM cleaning on the final output pulses. :param InIceOutput: Name of output pulse series with in-ice pulses :param IceTopOutput: Name of output pulse series with IceTop pulses """ # Extract DOMLaunches and triggers from raw DAQ data tray.AddSegment(payload_parsing.I3DOMLaunchExtractor, name+'/domlaunchextractor', BufferID='I3DAQData', TriggerID='I3TriggerHierarchyTrimmed', SpecialDataID = "SpecialHits", SpecialDataOMs = [OMKey(0,1), OMKey(12,65), OMKey(12,66), OMKey(62,65), OMKey(62,66)] ) # Extract DOMLaunches and triggers from SDST seatbelted raw DAQ data # tray.AddModule('I3FrameBufferDecode', name+'/trimmeddecode', # BufferID='I3DAQDataTrimmed', If=lambda fr: not 'I3DAQData' in fr) tray.AddSegment(payload_parsing.I3DOMLaunchExtractor, name+'/domlaunchextractorTrimmedDecode', BufferID='I3DAQDataTrimmed', TriggerID='I3TriggerHierarchyTrimmed', SpecialDataID = "SpecialHits", SpecialDataOMs = [OMKey(0,1), OMKey(12,65), OMKey(12,66), OMKey(62,65), OMKey(62,66)], If = lambda fr: not 'I3DAQData' in fr ) def cleanuppointlessdaqdata(frame, data): if data in frame and len(frame[data]) == 0: del frame[data] tray.AddModule(cleanuppointlessdaqdata, name+'/pointlessInIceRawData', data='InIceRawData', Streams=[icetray.I3Frame.DAQ]) tray.AddModule(cleanuppointlessdaqdata, name+'/pointlessIceTopRawData', data='IceTopRawData', Streams=[icetray.I3Frame.DAQ]) if pass2: # PFDST files already have the extracted IceTop launches, and they # are apparently not included in I3DAQDataTrimmed. # As a result, the code above will have renamed the iceTopRawData # to IceTopRawData_orig, extracted a new, empty version, and then # deleted the new version for being empty. So, we rename the # original back. tray.AddModule("Rename",name+"/restore_PFDST_IceTop_launches", Keys=["IceTopRawData_orig","IceTopRawData"], If=lambda fr: not 'IceTopRawData' in fr) # Reextract pulses if necessary (and calibration errata for # reconstructions!) tray.AddModule('I3DOMLaunchCleaning', name + '/domlaunchcleaning', CleanedKeysList=BadDOMList) tray.AddSegment(InIceCalibration, name + '/inicecal', InputLaunches='CleanInIceRawData', OutputPulses='Reextracted' + InIceOutput, WavedeformSPECorrections=WavedeformSPECorrections) tray.AddSegment(IceTopCalibration, name + '/icetopcal', InputLaunches='CleanIceTopRawData', OutputPulses='Reextracted' + IceTopOutput) # Make the set of DST-only pulses for merging def SuperDSTOnlyPulses(frame, launches, inpulses, outpulses): mask = dataclasses.I3RecoPulseSeriesMapMask(frame, inpulses, lambda omkey, index, pulse: (not launches in frame or not omkey in frame[launches]) and not omkey in frame[BadDOMList]) if mask.any(): frame[outpulses] = mask tray.AddModule(SuperDSTOnlyPulses, name + '/inicedstonlypulses', launches = 'InIceRawData', inpulses = 'InIceDSTPulses', outpulses = 'InIceDSTOnlyPulses', Streams=[icetray.I3Frame.DAQ]) tray.AddModule(SuperDSTOnlyPulses, name + '/icetopdstonlypulses', launches = 'IceTopRawData', inpulses = 'IceTopDSTPulses', outpulses = 'IceTopDSTOnlyPulses', Streams=[icetray.I3Frame.DAQ]) # Merge DST-only and offline reconstructed pulses def dstofflinemerge(frame, Output='', Input=[]): rootpulses = [] for i in Input: if not i in frame: continue rootpulses.append(i) frame[Output] = dataclasses.I3RecoPulseSeriesMapUnion(frame, rootpulses) tray.AddModule(dstofflinemerge, name + '/dstofflineinicemerge', Output=InIceOutput, Input=['InIceDSTOnlyPulses', 'Reextracted' + InIceOutput], Streams=[icetray.I3Frame.DAQ]) tray.AddModule(dstofflinemerge, name + '/dstofflineicetopmerge', Output=IceTopOutput, Input=['IceTopDSTOnlyPulses', 'Reextracted' + IceTopOutput, 'Reextracted' + IceTopOutput + '_SLC'], Streams=[icetray.I3Frame.DAQ]) # Clean up miscellaneous garbage we either added or inherited from PNF tray.AddModule('Delete', name+'/cleanup', Keys=['I3TriggerHierarchyTrimmed', 'DrivingTime', 'I3EventHeader_orig', 'I3DAQDataTrimmed', 'I3DAQData'])
def get_fit(frame, tol): pass_value = True true_zen = frame['MCPrimary'].dir.zenith true_az = frame['MCPrimary'].dir.azimuth true_x, true_y, true_z = get_n_cos(true_zen, true_az) tc = frame['ShowerCOG'].time xc = frame['ShowerCOG'].pos.x yc = frame['ShowerCOG'].pos.y zc = frame['ShowerCOG'].pos.z zen_shower = frame['ShowerPlane'].dir.zenith az_shower = frame['ShowerPlane'].dir.azimuth x_start, y_start, z_start = get_n_cos(zen_shower, az_shower) a_start = 4.823 * 10**-4 b_start = 19.51 sigma_start = 83.5 x_o = [] y_o = [] z_o = [] r_o = [] t0_o = [] check = [] remove_index_list = [] count = 0 for omkey in frame['WaveformInfo'].keys(): dom = int(omkey.split(',')[1]) string = int(omkey.split(',')[0].split('(')[1]) position = frame['I3Geometry'].omgeo[OMKey(string, dom)].position x_o.append(position.x) y_o.append(position.y) z_o.append(position.z) r_o.append( ((position.x)**2.0 + (position.y)**2.0 + (position.z)**2.0)**0.5) t0_o.append(frame['WaveformInfo'][omkey]['t_0']) if frame['WaveformInfo'][omkey]['t_0'] == 0: check.append(False) remove_index_list.append(count) elif abs(frame['WaveformInfo'][omkey]['t_0'] - frame['WaveformInfo'][omkey]['StartTime']) > 50: check.append(False) remove_index_list.append(count) else: check.append(True) count += 1 x_o = np.array(x_o) y_o = np.array(y_o) z_o = np.array(z_o) r_o = np.array(r_o) t0_o = np.array(t0_o) get_t_new = partial(get_t, tc=tc, xc=xc, yc=yc, zc=zc) try: fit_original = curve_fit( get_t_new, (x_o, y_o, z_o, r_o), t0_o, p0=[x_start, y_start, z_start, a_start, b_start, sigma_start], bounds=((-1, -1, -1, 0, 0, 0), (1, 1, 0, 2e-3, 200, 500)), maxfev=3000, absolute_sigma=True) vector_list = [] fit_list = [] mag_list = [0] x, y, z = get_n(fit_original[0][0], fit_original[0][1], fit_original[0][2]) vector_list.append(np.array([x, y, z])) fit_list.append(fit_original) except RuntimeError: final_fit = None check1 = check fit_status = False pass_value = False count = 0 while pass_value: if count == 0: check1 = np.copy(check) else: check1[remove_index] = False fit_check = [] removed = [] vector_check_list = [] for i in np.array(range(len(check1))): check2 = np.copy(check1) check2[i] = False if (i in remove_index_list): continue x = x_o[check2] y = y_o[check2] z = z_o[check2] r = r_o[check2] t0 = t0_o[check2] try: fit = curve_fit(get_t_new, (x, y, z, r), t0, p0=[ fit_list[-1][0][0], fit_list[-1][0][1], fit_list[-1][0][2], fit_list[-1][0][3], fit_list[-1][0][4], fit_list[-1][0][5] ], bounds=((-1, -1, -1, 0, 0, 0), (1, 1, 0, 2e-3, 200, 500)), maxfev=5000, absolute_sigma=True) except RuntimeError: continue fit_check.append(fit) x, y, z = get_n(fit[0][0], fit[0][1], fit[0][2]) vector_check_list.append([x, y, z]) removed.append(i) x_1, y_1, z_1 = get_n(fit_list[-1][0][0], fit_list[-1][0][1], fit_list[-1][0][2]) theta = np.arctan(((x_1**2.0 + y_1**2.0)**0.5) / z_1) output = space_angle_diff(vector_list[-1], vector_check_list) mag = [ magnitude_spherical(theta, d_theta, d_phi)**0.5 for d_theta, d_phi in output ] remove_index = removed[np.argmax(mag)] remove_index_list.append(remove_index) fit_list.append(fit_check[np.argmax(mag)]) mag_list.append(mag[np.argmax(mag)]) vector1 = np.sum(vector_check_list, axis=0) / len(vector_check_list) vector2 = np.array([x_1, y_1, z_1]) bias = (len(vector_check_list) - 1) * (vector1 - vector2) count += 1 if (abs(mag_list[-1] - mag_list[-2]) < tol): check1[remove_index] = False final_fit = fit_check[np.argmax(mag)] x_final, y_final, z_final = get_n(final_fit[0][0], final_fit[0][1], final_fit[0][2]) ang_diff_final = get_ang_diff(x_final, y_final, z_final, true_x, true_y, true_z) fit_status = True break return final_fit, check1, fit_status