def convertRun( inputTarFile, outputFileName ):
    
    # read file names from given path
    #fileNames = sorted( glob.glob( inputPath+'/mpx*.txt' ) )
    #nEvents = len( fileNames )

    inputFiles = []
    tar = tarfile.open( inputTarFile, 'r:gz' )
    for member in tar.getmembers():
        if not member.isfile():
            continue
        inputFiles.append( tar.extractfile(member) )
    
    # get run number from first file (same for the rest) assuming filename is this form: mpx-YYMMDD-HHmmSS-RUN_FRAME.txt
    runNumber = int( inputFiles[0].name.split('-')[-1].split('_')[0] )
    runNumber = int( inputTarFile.split('n')[-1].split('.')[0] )

    # define detector name
    detectorName = 'EUTelescope'

    # create a writer and open the output file
    writer = IOIMPL.LCFactory.getInstance().createLCWriter()
    writer.open( outputFileName, EVENT.LCIO.WRITE_NEW )

    print "Runnumber: " + str(runNumber)
    # create a run header and add it to the file
    run = IMPL.LCRunHeaderImpl()
    run.setRunNumber( runNumber )
    run.setDetectorName( detectorName )
    run.parameters().setValue  ( 'GeoID'            , 0 )
    run.parameters().setValues ( 'MaxX'             , std.vector(int)(6,1151) ) 
    run.parameters().setValues ( 'MaxY'             , std.vector(int)(6,575) )
    run.parameters().setValues ( 'MinX'             , std.vector(int)(6,0) ) 
    run.parameters().setValues ( 'MinY'             , std.vector(int)(6,0) )
    run.parameters().setValue  ( 'NoOfDetector'     , 6 )
    run.parameters().setValues ( 'AppliedProcessor' , std.vector('string')(1,'') )
    run.parameters().setValue  ( 'DAQHWName'        , 'EUDRB' )
    run.parameters().setValue  ( 'DAQSWName'        , 'EUDAQ' )
    run.parameters().setValue  ( 'DataType'         , 'SimData' )
    run.parameters().setValue  ( 'DateTime'         , '24.12.2000  23:59:59.000000000' )
    run.parameters().setValue  ( 'EUDRBDet'         , 'MIMOSA26' )
    run.parameters().setValue  ( 'EUDRBMode'        , 'ZS2' )
    writer.writeRunHeader( run )
  
    MAXEVENTS = 1000000
    NEVENTS   = 0

    # event loop
    for eventFile in inputFiles:

        if NEVENTS == MAXEVENTS: break
        NEVENTS += 1

        # get event number from file name ( i.e. frame ID ) assuming file name format above
        iEvent = int( eventFile.name.split('_')[-1].split('.')[0] )
        if ( NEVENTS%1000 == 0 ):
            print 'Events processed: %i ...' % NEVENTS

        # create an event and set its parameters
        event = IMPL.LCEventImpl()
        event.setEventNumber( iEvent )
        event.setDetectorName( detectorName )
        event.setRunNumber( runNumber )
        event.setTimeStamp( int( time() * 1000000000. ) )
        event.parameters().setValue( 'EventType', 2 )

        # parse input file
        telescopeData, DUTData = parseFrameFile( eventFile )

        # is there DUT data?
        containsDUT = False
        if len( DUTData ) > 0: 
            containsDUT = True 

        # if first event, create additional setup collection(s)
        if iEvent == 0:
            
            eudrbSetup = IMPL.LCCollectionVec( EVENT.LCIO.LCGENERICOBJECT )
            
            # collection parameters
            eudrbSetup.parameters().setValue( 'DataDescription', 'type:i,mode:i,spare1:i,spare2:i,spare3:i' )
            eudrbSetup.parameters().setValue( 'TypeName', 'Setup Description' )
            
            # create on setup object per Telescope plane
            for sensorID in sorted( telescopeData.iterkeys() ):
                                    
                setupObj = IMPL.LCGenericObjectImpl(5,0,0)
                setupObj.setIntVal( 0, 102 )
                setupObj.setIntVal( 1, 101 )     
                eudrbSetup.addElement( setupObj )

            event.addCollection ( eudrbSetup, 'eudrbSetup' )

            # check if there is a DUT
            if containsDUT:

                DUTSetup = IMPL.LCCollectionVec( EVENT.LCIO.LCGENERICOBJECT )
                event.addCollection ( DUTSetup, 'DUTSetup' )

        # ID encoder info
        encodingString = 'sensorID:7,sparsePixelType:5'

        # Telescope data collection
        trackerDataColl = IMPL.LCCollectionVec( EVENT.LCIO.TRACKERDATA )
        idEncoder_Telescope = UTIL.CellIDEncoder( IMPL.TrackerDataImpl )( encodingString, trackerDataColl )

        # check if there is a DUT
        if containsDUT:

            # DUT data collection
            DUTDataColl = IMPL.LCCollectionVec( EVENT.LCIO.TRACKERDATA )
            idEncoder_DUT = UTIL.CellIDEncoder( IMPL.TrackerDataImpl )( encodingString, DUTDataColl )

            REFDataColl = IMPL.LCCollectionVec( EVENT.LCIO.TRACKERDATA )
            idEncoder_REF = UTIL.CellIDEncoder( IMPL.TrackerDataImpl )( encodingString, REFDataColl )
            
            
            for i,sensorID in enumerate( sorted( DUTData.iterkeys() ) ):
            
                planeData = IMPL.TrackerDataImpl()
            
                idEncoder_DUT.reset()
                #idEncoder_DUT['sensorID'] = int( sensorID ) - 500 + 6 # cannot fit 500 in 5 bits!! FIXME
                idEncoder_DUT['sensorID'] = i+6 # cannot fit 500 in 5 bits!! FIXME
                idEncoder_DUT['sparsePixelType'] = 2
                idEncoder_DUT.setCellID( planeData )
            
                chargeVec = std.vector(float)()
                for val in DUTData[sensorID]:
                    chargeVec.push_back( val )
                    if val < 0:
                        print 'Negative number in Event %i' % iEvent

                planeData.setChargeValues( chargeVec )



                if int(sensorID) == 900 :
                    DUTDataColl.addElement( planeData )
                    event.addCollection( DUTDataColl, 'CMSPixelDUT' )
                elif int(sensorID) == 901 :
                    REFDataColl.addElement( planeData )
                    event.addCollection( REFDataColl, 'CMSPixelREF' )
                else:
                    print "Shit. Who am I? sensorID: " + str(int(sensorID))


        # fill telescope collection
        for sensorID in sorted( telescopeData.iterkeys() ):
            
            planeData = IMPL.TrackerDataImpl()

            idEncoder_Telescope.reset()
            idEncoder_Telescope['sensorID'] = int( sensorID ) - 300 # cannot fit 300 in 5 bits!! FIXME
            idEncoder_Telescope['sparsePixelType'] = 2
            idEncoder_Telescope.setCellID( planeData )
            
            # loop over hits
            chargeVec = std.vector(float)()
            for val in telescopeData[sensorID]:
                chargeVec.push_back( val )

            planeData.setChargeValues( chargeVec )

            trackerDataColl.addElement( planeData )

        event.addCollection( trackerDataColl, 'zsdata_m26' )

        writer.writeEvent( event )
    
    writer.flush()
    writer.close()
def convertRun(inputFileName, outputFileName, runNumber, nplanes=7):

    # define detector name
    detectorName = 'FEI4Tel'

    # create a writer and open the output file
    writer = IOIMPL.LCFactory.getInstance().createLCWriter()
    writer.open(outputFileName, EVENT.LCIO.WRITE_NEW)

    # create a run header and add it to the file
    run = IMPL.LCRunHeaderImpl()
    run.setRunNumber(runNumber)
    run.setDetectorName(detectorName)
    run.parameters().setValue('GeoID', 0)
    run.parameters().setValues('MaxX', std.vector(int)(nplanes, 335))
    run.parameters().setValues('MaxY', std.vector(int)(nplanes, 79))
    run.parameters().setValues('MinX', std.vector(int)(nplanes, 0))
    run.parameters().setValues('MinY', std.vector(int)(nplanes, 0))
    run.parameters().setValue('NoOfDetector', nplanes)
    run.parameters().setValues('AppliedProcessor', std.vector('string')(1, ''))
    run.parameters().setValue('DAQHWName', 'EUDRB')
    run.parameters().setValue('DAQSWName', 'EUDAQ')
    run.parameters().setValue('DataType', 'Data')
    run.parameters().setValue('DateTime', '24.12.2000  23:59:59.000000000')
    run.parameters().setValue('EUDRBDet', 'MIMOSA26')
    run.parameters().setValue('EUDRBMode', 'ZS2')
    writer.writeRunHeader(run)

    aDataSet = JudithData(inputFileName, nplanes)

    MAXEVENTS = aDataSet.GetNEvents()
    #MAXEVENTS = 500

    NEVENTS = 0

    # event loop

    for eventnr in range(MAXEVENTS):

        if (eventnr % 1000 == 0):
            print 'Events processed: %i ...' % eventnr

        # create an event and set its parameters
        event = IMPL.LCEventImpl()
        event.setEventNumber(eventnr)
        event.setDetectorName(detectorName)
        event.setRunNumber(runNumber)
        event.setTimeStamp(int(time() * 1000000000.))
        event.parameters().setValue('EventType', 2)

        # parse input file
        telescopeData = aDataSet.GetEvent(eventnr)
        #aDataSet.PrintEvent(eventnr)

        # if first event, create additional setup collection(s)
        if eventnr == 0:

            eudrbSetup = IMPL.LCCollectionVec(EVENT.LCIO.LCGENERICOBJECT)

            # collection parameters
            eudrbSetup.parameters().setValue(
                'DataDescription', 'type:i,mode:i,spare1:i,spare2:i,spare3:i')
            eudrbSetup.parameters().setValue('TypeName', 'Setup Description')

            # create on setup object per Telescope plane
            for sensorID in range(nplanes):

                setupObj = IMPL.LCGenericObjectImpl(5, 0, 0)
                setupObj.setIntVal(0, 102)
                setupObj.setIntVal(1, 101)
                eudrbSetup.addElement(setupObj)

            event.addCollection(eudrbSetup, 'eudrbSetup')

        # ID encoder info
        encodingString = 'sensorID:5,sparsePixelType:5'

        # Telescope data collection
        trackerDataColl = IMPL.LCCollectionVec(EVENT.LCIO.TRACKERDATA)
        idEncoder_Telescope = UTIL.CellIDEncoder(IMPL.TrackerDataImpl)(
            encodingString, trackerDataColl)

        # fill telescope collection
        for sensorID in range(nplanes):

            planeData = IMPL.TrackerDataImpl()

            idEncoder_Telescope.reset()
            idEncoder_Telescope['sensorID'] = int(
                sensorID)  # cannot fit 300 in 5 bits!! FIXME
            plane_tmp = int(sensorID)

            idEncoder_Telescope['sparsePixelType'] = 2
            idEncoder_Telescope.setCellID(planeData)

            # loop over hits
            chargeVec = std.vector(float)()
            for hit in telescopeData[sensorID]:
                for j, val in enumerate(hit):
                    chargeVec.push_back(val)

            planeData.setChargeValues(chargeVec)

            trackerDataColl.addElement(planeData)

        event.addCollection(trackerDataColl, 'zsdata_FEI4')

        writer.writeEvent(event)

    writer.flush()
    writer.close()