packages feed

flowsim (empty) → 0.2.6

raw patch · 12 files changed

+928/−0 lines, 12 filesdep +MonadRandomdep +arraydep +basesetup-changed

Dependencies added: MonadRandom, array, base, bio, bytestring, cmdargs, containers, directory, random

Files

+ Setup.hs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ flowsim.cabal view
@@ -0,0 +1,35 @@+Name:           flowsim+Version:        0.2.6+License:        GPL++Author:         Ketil Malde+Maintainer:     Ketil Malde <ketil@malde.org>++Category:       Bioinformatics+Synopsis:       Simulate 454 pyrosequencing+Description:    pyrosim - a simulator for 454 pyrosequencing data+                Simulate shotgun sequencing with Roche's 454 sequencing technology.+                .+                The Darcs repository is at <http://malde.org/~ketil/biohaskell/pyrosim>.++HomePage:       http://bhlog.malde.org/+Build-Depends:  bio >= 0.4.4, base >= 4 && <= 5, array >= 0.1, bytestring >= 0.9.1, random, MonadRandom, cmdargs, containers, directory+Build-Type:     Simple+Tested-with:    GHC==6.8.2++ -- Data-files:     README+Executable:     flowsim+Main-Is:        FlowSim.hs+Other-Modules:  Statistics, Config, EmpFile+		Generations.GenBase, Generations.GS20, +		Generations.Titanium, Generations.Empirical+Hs-Source-Dirs: src++Executable:     hplc+Main-Is:        HPLCount.hs+Ghc-Options:    -main-is HPLCount+Hs-Source-Dirs: src++Executable:	clonesim+Main-Is:	CloneSim.hs+Hs-Source-Dirs: src
+ src/CloneSim.hs view
@@ -0,0 +1,82 @@+{- | CloneSim - fragment a genome sequence to simulate cloning+     Factored out from flowsim in order to separate clone generation+     from flow simulation and base calling.+-}++{-# Language DeriveDataTypeable #-}++module Main where++import Bio.Sequence hiding ((!))+import Statistics++import System.IO (stdin,stdout,stderr,hPutStrLn)+import Control.Monad (forM)+import qualified Data.ByteString.Lazy as B+import Data.Int (Int64)+import System.Console.CmdArgs+import Data.Array++type Dist    = String+data Conf = Conf +            { lengths :: Dist+            , count :: Int+            , input :: [FilePath]+            } deriving (Data,Typeable,Show)++modes :: Mode Conf+modes = mode $ Conf {  +    lengths = "Uniform 400 800" &= text "model for clone lengths" & typ "DIST"+  , count = 10                &= text "number of reads to generate" & typ "INT"+  , input = def &= args & typFile+  } &= prog "clonesim"+    & text "simulate sequence cloning"+    & helpSuffix ["Available distributions (DIST):" +                 ,"    Uniform a b, Normal mu sigma, LogNormal mu sigma"]++version :: String+version = "clonesim v0.2.6, copyright 2010 Ketil Malde" ++data Dir   = Fwd | Rev deriving (Eq,Enum,Bounded)++instance Random Dir where +  random g = let (b,g') = random g in (if b then Fwd else Rev,g')+  randomR = error "randomR is undefined for Dir"++main :: IO ()+main = do+  conf <- cmdArgs version [modes]+  -- print conf+  let inf = case input conf of +        []  -> hPutStrLn stderr "clonesim: reading from stdin" >> hReadFasta stdin+        [x] -> readFasta x+        _   -> error "Please specify only a single input file"+  ss <- map (defragSeq . castToNuc) `fmap` inf+  let sa = listArray (0,length ss-1) ss+  hWriteFasta stdout =<< evalRandIO (simulate conf sa)+  +type SeqArray = Array Int (Sequence Nuc)++-- | the real 'main'+simulate :: RandomGen g => Conf -> SeqArray -> Rand g [Sequence Nuc]+simulate conf sa = do+  let ldist   = read $ lengths conf+      (_,asz) = bounds sa+  forM [1..count conf] $ const +    (do i <- floor `fmap` sample (Uniform 0 $ 1+fromIntegral asz) -- inclusive?+        let s = sa!i+        p <- round `fmap` sample (Uniform 0 $ fromIntegral (seqlength s-1))+        l <- round `fmap` sample ldist+        dir <- getRandom+        return (mkClone dir p l s))+    +mkClone :: Dir -> Int64 -> Int64 -> Sequence Nuc -> Sequence Nuc+mkClone dir pos len (Seq h s mq) = +  Seq (fromStr (toStr h++" "++show pos++case dir of Fwd -> "+"; Rev -> "-"))+      sd+      qual+    where sd = B.take len+               . (case dir of Fwd -> snd; Rev -> revcompl' . fst) +               . B.splitAt pos $ s+          qual = B.take len `fmap` case dir of Fwd -> fst; Rev -> snd +                 `fmap` B.splitAt pos `fmap` mq
+ src/Config.hs view
@@ -0,0 +1,147 @@+{-| Module Config - replaces Options, use CmdArgs instead -}+{-# LANGUAGE DeriveDataTypeable #-}++module Config (Config(..), mkconf+              ,inform, whenLoud, whenNotQuiet) where++import Data.Char (toLower)+import Data.List (isPrefixOf, intersperse)+import System.Console.CmdArgs+import System.Directory (doesFileExist)+import Control.Monad (when)+import System.IO (hPutStrLn, stderr, stdin)+import EmpFile++import Bio.Sequence++import Generations.GenBase+import Generations.GS20+import Generations.Titanium+import Generations.Empirical++version :: String+version = "flowsim v0.2.6, copyright 2010 Ketil Malde"++-- data GenName = Titanium | FLX | GS20 deriving (Typeable, Data, Show, Eq)+type GenName = String+type Dist    = String++data Config = Conf { generation :: GenName+                   , degradation:: Dist+                   , model  :: FilePath+                   , qualmethod  :: GenName+                   , discardfilters :: [String]+                   , trimfilters :: [String]+                   , flowkey :: String+                   , hplinput :: FilePath+                   , flowlength :: Int+                   , flowcycle :: String+                   , inputs :: [FilePath]+                   , output :: FilePath+                   } deriving (Typeable, Data, Show, Read)++modes :: Mode Config+modes = mode $ Conf +  { generation     = "Titanium" &= text "454 generation to simulate"           & typ "GEN"   & flag "G"+  , degradation    = def &= text "model for degradation of the flow model" & typ "DIST"+  , model          = def &= text "empirical distribution for flow generation" & typFile+  , qualmethod     = def &= text "method for calculating quality"          & typ "STRING"+  , discardfilters = def &= text "discarding filters to apply"             & typ "DFILT"+  , trimfilters    = def &= text "trimming filters to apply"               & typ "TFILT"+  , flowkey        = def &= text "sequence key to start each read (TCAG)"+  , hplinput       = def &= text "input genome for HPL count estimate" & typFile+  , flowlength     = def &= text "number of flow cycles to run"+  , flowcycle      = def &= text "sequence nucleotides in each flow cycle (TACG)"+  , inputs         = def &= args & typFile+  , output         = def &= text "output file"+  } &= prog "flowsim"+    & text "simulate 454 pyrosequencing."+    & helpSuffix hs+      where     +        hs = ["Generations (GEN): "++concat (intersperse ", " $ map fst generations)+             , "Distributions (DIST): Uniform a b, Normal mu sigma, LogNormal mu sigma"+             , "Discarding filters (DFILT): ...."+             , "Trimming filters (TFILT): ...."]+    +mkconf :: IO (Generation,IO [Sequence Nuc],HPLprob,FilePath)+mkconf = do+  cf <- cmdArgs version [modes]+  let inp = map castToNuc `fmap` if null (inputs cf) then hReadFasta stdin else concat `fmap` mapM readFasta (inputs cf)+  gen <- mkgen cf+  whenLoud $ inform ("Generation: "++generation cf ++ "\n" ++ show gen)+  when (null $ output cf) $ error "Please specify an output file with -o"+  hplc <- case hplinput cf of +    []   -> return default_hplc+    file -> (mkHPLprobs . freqtable . concatMap (hpls (f_cycle gen) . seqdata)) `fmap` readFasta file+  return (gen, inp, hplc, output cf)+  +default_hplc :: HPLprob+default_hplc _ l = 3/4**fromIntegral l++generations :: [(GenName,Generation)]+generations = [("GS20", gs20), ("Titanium",titanium),("EmpTitanium",tiEmp)]++lookupGen :: String -> Generation +lookupGen g = case map snd . filter (isPrefixOf (map toLower g) . map toLower . fst) $ generations of+  [x] -> x+  _ -> error ("Generation '"++g++"' is non-existing or ambigous\nAvailable generations are: "++show (map fst generations))++-- if non-null, pick field f from generation str, else pick it from the default+setFromGen :: Generation -> (Generation -> field) -> String -> field+setFromGen dflt f str = if null str then f dflt else f (lookupGen str)++-- similar, but use Read to parse the string+setFromStr :: (Read a) => Generation -> (Generation -> a) -> String -> a+setFromStr dflt f str = if null str then f dflt else read str+  +mkgen :: Config -> IO Generation  +mkgen (Conf g deg fm qm df tf fk hpl fl fc _inputs _output) = do+  let gen = lookupGen g+      setG = setFromGen gen+      setD = setFromStr gen +      setF fs | null fs   = disc_filters gen+              | otherwise = concatMap (maybe [] id) $ map (flip lookup filterlist) fs+      setT fs | null fs   = trim_filters gen+              | otherwise = concatMap (maybe [] id) $ map (flip lookup trimlist) fs+      my_qcall = if null qm then qcall gen +                 else case qm of +                   "gs20tab" -> qual_gs20_tab+                   "dexact"  -> qual_exact_decreasing+                   "fexact"  -> qual_exact_fixed +                   _ -> error ("No such quality call method:"++show qm+                               ++"\nAvailable methods: gs20tab, dexact, fexact.")+  my_model <- if null fm then return (models gen)+              else do+                f <- doesFileExist fm+                ms <- if f then readPdf fm else return (parse_models fm)+                return $ combine_models (models gen) ms+  return $ gen  +          { qcall        = my_qcall+          , degrade      = setD degrade deg+          , models       = my_model+          , disc_filters = setF df +          , trim_filters = setT tf+          , f_key        = setG f_key fk+          , f_len        = if fl > 0 then fl else f_len gen+          , f_cycle      = setG f_cycle fc+          }++parse_models :: String -> [Distribution]+parse_models str = read ("["++str++"]")++-- filterlist :: [DiscardFilter]+filterlist = [] -- todo: export from SFF_filters++-- trimlist  :: [Trimfilter]+trimlist   = [] ++-- Logging+inform :: String -> IO ()+inform = hPutStrLn stderr++whenLoud, whenNotQuiet :: IO () -> IO ()+whenLoud action = flip when action =<< isLoud+-- note that isQuiet = return False in CmdArgs!+whenNotQuiet action = do  n <- isNormal+                          l <- isLoud+                          when (n || l) action
+ src/EmpFile.hs view
@@ -0,0 +1,25 @@+module EmpFile where++import Statistics+import Control.Monad (when)++readPdf :: FilePath -> IO [Distribution]+readPdf f = do +  cs <- lines `fmap` readFile f+  return (parsePdf ("file '"++f++"'") cs)  +  +parsePdf :: String -> [String] -> [Distribution]+parsePdf f cs = +  let (_:fs:vss) = transpose (map words cs)+  in if (or $ zipWith (/=) [0..] (map read fs))+     then error ("Flow index from "++f++" isn't [0..]!")+     else map (fromPdf 0 0.01 . map (P . read)) vss++transpose xs = let r0 = map head xs  +                   rest = map tail xs+               in if any null rest then [r0] else r0 : transpose rest++-- currently this only works for a single model+combine_models :: [Int -> Distribution] -> [Distribution] -> [Int -> Distribution]+combine_models [f] ds = [\i -> if i < length ds then ds!!i else f i]+combine_models _ _ = error "Can't combine multiple models"
+ src/FlowSim.hs view
@@ -0,0 +1,186 @@+{- | FlowSim - simulate 454 flowgrams from a reference genome ++   Flow values are modelled from a log-normal noise, and a sequence of+   normal distributions, one for each homopolymer length.  These distributions+   can be estimated from real data.++   Todo:+   * Paired ends models B-linker-A+   * Support multiple sequences:+      - scan seqs + lenghts+      - gen n numbers (0..total length), transform to deltas (cf. rselect)+      - sort and generate++-}+{-# options -XParallelListComp #-}++module Main where++import Bio.Sequence+import Bio.Sequence.SFF++import qualified Data.ByteString.Lazy.Char8 as B+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString as BS2++import Data.Char (toUpper)+import Data.Int++import Statistics+import Generations.GenBase+import Config++import Control.Monad (when)++-- ------------------------------------------------------------+-- picking random postions/directions for reads++data Dir   = Fwd | Rev deriving (Eq,Enum,Bounded)++instance Random Dir where +  random g = let (b,g') = random g in (if b then Fwd else Rev,g')+  randomR = error "randomR is undefined for Dir"++main :: IO ()+main = do+  (gen,is,hplc,o) <- mkconf+  +  ss <- is+  case ss of [] -> error ("Input appears to be empty?")+             _ -> return ()+  sff <- evalRandIO $ sim454 gen hplc ss+  n <- writeSFF' o sff+  whenLoud $ inform ("Wrote "++show n++" reads to '"++o++"'.")++-- testing+test_s :: Sequence Nuc+test_s = Seq (fromStr "foo") (fromStr "aacacattcgtggtnagctacggaacacattcgtggtnagctacggaacacattcgtggtnagctacggaacacattcgtggtnagctacgg") Nothing++-- | Heavy lifting.  Building an SFF file from the specified information+sim454 :: RandomGen g => Generation -> HPLprob -> [Sequence Nuc] -> Rand g SFF+sim454 gen hplc ss = do+  let ch = makeCommonHeader gen+      tf r = foldr ($) r $ trim_filters gen +      df r = and $ zipWith ($) (disc_filters gen) (repeat r)+  rbs <- map tf `fmap` filter df `fmap` mapM (\s -> makeReadBlock gen hplc s ch) ss+  return (SFF ch rbs)++-- Generate a sequence of models+-- The generation specifies a series of initial models, this function+-- uses these with the degradation to generate a progression of models to use  +makeModels :: RandomGen g => Generation -> Rand g [Model]  +makeModels gen = case models gen of+  [m] -> iterativeWorsen (f_len gen) (degrade gen) m+  im@(_:_) -> do+    let ns = f_len gen `div` length im+    return $ concat $ map (replicate ns) im++iterativeWorsen :: RandomGen g => Int -> Distribution -> Model -> Rand g [Model]+iterativeWorsen 0 _ _ = return []+iterativeWorsen count deg m = do +  ps <- perturbs 1 count+  return $ zipWith (fmap . worsen) ps $ replicate count m+    where perturbs _   0 = return []+          perturbs cur n = do +            w <- sample deg+            let new = cur+w+            rest <- perturbs new (n-1)+            return (new : rest)++-- --------------------------------------------------+-- Generate the flow values++-- generate the "absolute" flow values from the cycle and the origin sequence data+makeFlows :: [Char] -> SeqData -> [(Char,Int)]+makeFlows c s | B.null s = []+              | otherwise = let (c1,s1) = makeCycle [] (take 4 c) s +                                s2 = case B.uncons s1 of Just (x,_) -> if not (toUpper x `elem` "ACGT") then B.tail s1 else s1; _ -> s1+                            in c1 ++ makeFlows c s2++makeCycle :: [(Char,Int)] -> [Char] -> SeqData -> ([(Char,Int)],SeqData)+makeCycle acc []     s = (reverse acc, s)+makeCycle acc (c:cs) s = let (this,rest) = B.span ((==toUpper c).toUpper) s+                         in makeCycle ((c,fromIntegral $ B.length this):acc) cs rest++-- | Takes a sequence of flows with exact homopolymer lengths, +-- permutes and calls them.  Next step is prepareData+permuteAndCall :: RandomGen g => Generation -> HPLprob -> [(Char,Int)] -> +                  Rand g [(Flow,[Char],[Qual])]+permuteAndCall gen hplc fs = do+  -- when (trace (show fs) False) (return ())+  let n  = fromIntegral $ f_len gen+      flow_cont = drop (length fs `mod` length (f_cycle gen)) $ cycle (f_cycle gen)+      xs = fs ++ zip flow_cont (replicate (n-length fs) 0)+  ms <- makeModels gen+  -- if and $ zipWith (==) (map fst xs) (cycle $ f_cycle gen) then return () +  -- else error (map fst xs ++ "\n don't cycle: "++f_cycle gen)+  sequence $ take n $ zipWith (my_call (qcall gen) hplc) ms xs++-- Titanium base/quality calling+my_call :: RandomGen g => QualMethod -> HPLprob -> Model -> (Char,Int) -> +           Rand g (Flow,[Char],[Qual])+my_call qm ft md (c,hpl) = do+  f <- sample (md hpl)+  let fi = max 0 . round . (100*) $ f+      n = fromIntegral ((fi+50) `div` 100)+      cs = replicate n c+      qs = qm ft md (c,fi)+  when (length qs /= n) $ error ("Qual mismatch: "++show (f,fi,n,cs,qs))+  return (fi, cs, qs)++-- | Somewhat advanced unzip, calculating the index in the process.+--   Also replace three consequtive empty lists with Ns+convertCalls :: [(Flow,[Char],[Qual])] -> ([Flow],[Char],[Qual],[Int])+convertCalls = go 0 . addDots+  where go _ [] = ([],[],[],[])+        go p ((f,cs,qs):fs) +          | null cs = let (f',c',q',i') = go (p+1) fs+                      in (f:f',c',q',i')+          | otherwise = let (f',c',q',i') = go 0 fs+                        in (f:f',cs++c',qs++q',(p+1):replicate (length cs-1) 0 ++ i')+        +        addDots ((f1,cs1,qs1):(f2,cs2,qs2):(f3,cs3,qs3):(f4,cs4,qs4):rest)+            | null cs1 && null cs2 && null cs3 && not (null cs4) = (f1,cs1,qs1):(f2,cs2,qs2):(f3,"N",[0]):addDots ((f4,cs4,qs4):rest)+            | otherwise = (f1,cs1,qs1) : addDots ((f2,cs2,qs2):(f3,cs3,qs3):(f4,cs4,qs4):rest)+        addDots fewerThanThree = fewerThanThree++-- | Generate a ReadBlock+--   direction and position chosen at random, and encoded in the read name+makeReadBlock :: RandomGen g => Generation -> HPLprob -> Sequence Nuc -> CommonHeader -> Rand g ReadBlock+makeReadBlock g hplc sq ch = do+       let sdata = seqdata sq+           rn = BS.concat $ BL.toChunks $ seqlabel sq+           fs = makeFlows (BS.unpack $ flow ch) $ BL.concat [BL.fromChunks [key ch], {- B.take (floor cl) $ -} sdata]+       (pfs,cs,qs,is) <- convertCalls `fmap` permuteAndCall g hplc fs+       return $ verifyRB (flow_length ch) $ ReadBlock {+                           read_header = ReadHeader {+                                           name_length                 = fromIntegral $ BS.length rn -- :: Int16+                                         , num_bases                   = fromIntegral $ length cs    -- :: Int32+                                         , clip_qual_left              = 5                           -- :: Int16+                                         , clip_qual_right             = fromIntegral $ length cs    -- :: Int16+                                         , clip_adapter_left           = 0 -- :: Int16+                                         , clip_adapter_right          = 0 -- :: Int16+                                         , read_name                   = rn -- :: ByteString+                                         }+                         -- The data block+                          , flow_data        = packFlows pfs    -- :: [Flow]+                          , flow_index       = BS2.pack $ map fromIntegral is -- :: ByteString+                          , bases            = fromStr cs -- :: SeqData+                          , quality          = BL.pack qs -- :: QualData+                          }++-- | Consistency check on generated ReadBlocks.+verifyRB :: Int16 -> ReadBlock -> ReadBlock+verifyRB fl rb +            | name_length rh == 0  = err "name_length is zero"+            | num_bases rh == 0    = err "num_bases is zero"+--            | clip_qual_left rh > clip_qual_right rh = err "clipping gives negative sequence"+            | BS2.length (read_name rh) /= (fromIntegral $ name_length rh)  = err "read_name has incorrect length"+            | BS.length (flow_data rb) `div` 2 /= fromIntegral fl  = err ("Number of flows ("++show (BS.length (flow_data rb) `div` 2)++")do not match flow_length of "++show fl++" in CommonHeader")+            | BS.length (flow_data rb) `div` 2 < (fromIntegral $ sum $ BS2.unpack $ flow_index rb) = err "flow_index longer than flows"+            | B.length (bases rb) /= (fromIntegral $ BS.length $ flow_index rb) = err ("bases ("++show (B.length (bases rb))++") and flow_index ("++show (BS.length $ flow_index rb)++") have different lengths")+            | B.length (quality rb) /= (fromIntegral $ BS.length $ flow_index rb) = err ("quality ("++show (B.length (quality rb))++") and flow_index ("++show (BS.length $ flow_index rb)++") have different lengths")+            | otherwise = rb+    where rh = read_header rb +          err str = error (str ++ "\n" ++ show rb)
+ src/Generations/Empirical.hs view

file too large to diff

+ src/Generations/GS20.hs view
@@ -0,0 +1,157 @@+module Generations.GS20 where++import Generations.GenBase++import Data.Array+import qualified Data.ByteString.Char8 as BC+import qualified Data.ByteString as B+import Control.Monad (when)++type QualTable = Array Flow B.ByteString++-- | Wrapper around 'array' that interpolates missing values+--   Todo: make this more sophisticated!+mkQualTable :: (Flow,Flow) -> [(Flow,B.ByteString)] -> QualTable+mkQualTable is = array is . map extend . interpolate++interpolate :: [(Flow,B.ByteString)] -> [(Flow,B.ByteString)]+interpolate ((x1,y1):(x2,y2):rest)+              = [(x,y1) | x <- [x1..x2-1]]++interpolate ((x2,y2):rest)+interpolate xs = xs++extend :: (Flow,B.ByteString)-> (Flow,B.ByteString)+extend (x,y) = let delta = ((x+50) `div` 100) - fromIntegral (B.length y)+               in (x,B.concat [y,B.replicate (fromIntegral delta) 1])++gs20 :: Generation+gs20 = Gen {+         name     = "GS20"+       , models    = [\h -> let h' = fromIntegral h +                            in if h == 0 then LogNormal (negate 2.5) 0.2 else Normal h' (0.04+0.06*h')]+       , qcall = qual_gs20_tab+       , degrade  = Normal 0.005 0.002+       , disc_filters = [filter_key,filter_empty]+       , trim_filters = []+      +       , f_key        = "TCAG"+       , f_len        = 168 -- :: Int16+       , f_cycle      = "TACG"+       }+++qual_gs20_tab :: QualMethod+qual_gs20_tab _ _ (_,fi) = B.unpack (gs20qt!fi)++gs20qt :: QualTable+gs20qt = mkQualTable (0,3100) $ map (\(x,y) -> (x,BC.pack y)) [+             (0,""),(1,""),(2,""),(3,""),(4,""),(5,""),(6,""),(7,""),(8,""),(9,""),(10,"")+            ,(11,""),(12,""),(13,""),(14,""),(15,""),(16,""),(17,""),(18,""),(19,""),(20,"")+            ,(21,""),(22,""),(23,""),(24,""),(25,""),(26,""),(27,""),(28,""),(29,""),(30,"")+            ,(31,""),(32,""),(33,""),(34,""),(35,""),(36,""),(37,""),(38,""),(39,"")+            ,(40,""),(41,""),(42,""),(43,""),(44,""),(45,""),(46,""),(47,""),(48,""),(49,"")+            ,(50,"\b"),(51,"\b"),(52,"\b"),(53,"\t"),(54,"\t"),(55,"\n"),(56,"\n"),(57,"\n"),(58,"\n"),(59,"\v")+            ,(60,"\v"),(61,"\f"),(62,"\r"),(63,"\r"),(64,"\r"),(65,"\r"),(66,"\SO"),(67,"\SI"),(68,"\SI"),(69,"\DLE")+            ,(70,"\DLE"),(71,"\DC1"),(72,"\DC1"),(73,"\DC1"),(74,"\DC2"),(75,"\DC3"),(76,"\DC3"),(77,"\DC3"),(78,"\DC4"),(79,"\NAK")+            ,(80,"\NAK"),(81,"\NAK"),(82,"\SYN"),(83,"\ETB"),(84,"\ETB"),(85,"\ETB"),(86,"\CAN"),(87,"\CAN"),(88,"\EM"),(89,"\EM")+            ,(90,"\SUB"),(91,"\SUB"),(92,"\SUB"),(93,"\SUB"),(94,"\ESC"),(95,"\ESC"),(96,"\ESC"),(97,"\ESC"),(98,"\FS"),(99,"\FS")+            ,(100,"\FS"),(101,"\FS"),(102,"\FS"),(103,"\FS"),(104,"\FS"),(105,"\FS"),(106,"\FS"),(107,"\FS"),(108,"\FS"),(109,"\FS")+            ,(110,"\FS"),(111,"\FS"),(112,"\ESC"),(113,"\ESC"),(114,"\ESC"),(115,"\SUB"),(116,"\SUB"),(117,"\SUB"),(118,"\EM"),(119,"\EM")+            ,(120,"\CAN"),(121,"\CAN"),(122,"\CAN"),(123,"\ETB"),(124,"\ETB"),(125,"\ETB"),(126,"\SYN"),(127,"\SYN"),(128,"\SYN"),(129,"\SYN")+            ,(130,"\NAK"),(131,"\NAK"),(132,"\NAK"),(133,"\DC4"),(134,"\DC4"),(135,"\DC4"),(136,"\DC4"),(137,"\DC4"),(138,"\DC4"),(139,"\DC3")+            ,(140,"\DC3"),(141,"\DC3"),(142,"\DC3"),(143,"\DC3"),(144,"\DC3"),(145,"\DC3"),(146,"\DC3"),(147,"\DC3"),(148,"\DC4"),(149,"\DC4")+            ,(150,"\DC4\EOT"),(151,"\DC4\ENQ"),(152,"\DC4\ENQ"),(153,"\DC4\ENQ"),(154,"\NAK\ACK"),(155,"\NAK\ACK"),(156,"\NAK\a"),(157,"\NAK\a"),(158,"\SYN\b"),(159,"\SYN\b")+            ,(160,"\SYN\b"),(161,"\ETB\t"),(162,"\ETB\t"),(163,"\CAN\n"),(164,"\CAN\v"),(165,"\CAN\v"),(166,"\EM\f"),(167,"\EM\f"),(168,"\EM\f"),(169,"\SUB\r")+            ,(170,"\SUB\r"),(171,"\SUB\SO"),(172,"\ESC\SI"),(173,"\ESC\SI"),(174,"\FS\DLE"),(175,"\FS\DLE"),(176,"\FS\DC1"),(177,"\GS\DC1"),(178,"\GS\DC1"),(179,"\GS\DC2")+            ,(180,"\RS\DC2"),(181,"\RS\DC2"),(182,"\RS\DC3"),(183,"\US\DC4"),(184,"\US\DC4"),(185,"\US\DC4"),(186,"\US\NAK"),(187," \NAK"),(188," \NAK"),(189," \SYN")+            ,(190," \SYN"),(191,"!\ETB"),(192,"!\ETB"),(193,"!\ETB"),(194,"!\ETB"),(195,"\"\CAN"),(196,"\"\CAN"),(197,"\"\CAN"),(198,"\"\CAN"),(199,"\"\EM")+            ,(200,"\"\EM"),(201,"#\EM"),(202,"#\EM"),(203,"#\EM"),(204,"#\SUB"),(205,"#\SUB"),(206,"#\SUB"),(207,"#\SUB"),(208,"#\SUB"),(209,"#\SUB")+            ,(210,"#\SUB"),(211,"#\SUB"),(212,"#\SUB"),(213,"#\SUB"),(214,"#\SUB"),(215,"#\SUB"),(216,"#\SUB"),(217,"#\SUB"),(218,"#\SUB"),(219,"#\SUB")+            ,(220,"#\SUB"),(221,"#\SUB"),(222,"#\SUB"),(223,"#\SUB"),(224,"#\SUB"),(225,"#\SUB"),(226,"#\SUB"),(227,"\"\SUB"),(228,"\"\SUB"),(229,"\"\SUB")+            ,(230,"\"\SUB"),(231,"\"\SUB"),(232,"\"\SUB"),(233,"\"\SUB"),(234,"\"\SUB"),(235,"\"\SUB"),(236,"\"\SUB"),(237,"!\SUB"),(238,"!\EM"),(239,"!\EM")+            ,(240,"!\EM"),(241,"!\EM"),(242,"!\EM"),(243,"!\EM"),(244,"!\EM"),(245,"!\EM"),(246,"!\EM"),(247,"!\EM"),(248,"!\EM"),(249,"!\EM")+            ,(250,"!\EM\SOH"),(251,"!\EM\SOH"),(252,"!\EM\SOH"),(253,"!\EM\SOH"),(254,"!\EM\STX"),(255,"!\EM\STX"),(256,"!\EM\STX"),(257,"!\EM\STX"),(258,"!\EM\STX"),(259,"!\EM\STX")+            ,(260,"!\SUB\ETX"),(261,"!\SUB\ETX"),(262,"!\SUB\ETX"),(263,"!\SUB\ETX"),(264,"!\SUB\ETX"),(265,"!\SUB\EOT"),(266,"!\SUB\EOT"),(267,"!\SUB\EOT"),(268,"!\SUB\EOT"),(269,"\"\ESC\ENQ")+            ,(270,"\"\ESC\ENQ"),(271,"\"\ESC\ENQ"),(272,"\"\ESC\ENQ"),(273,"\"\ESC\ACK"),(274,"\"\ESC\ACK"),(275,"#\FS\ACK"),(276,"#\FS\ACK"),(277,"#\FS\a"),(278,"#\FS\a"),(279,"#\FS\a")+            ,(280,"#\FS\a"),(281,"#\FS\b"),(282,"#\FS\b"),(283,"$\GS\b"),(284,"$\GS\b"),(285,"$\GS\t"),(286,"$\GS\t"),(287,"$\GS\t"),(288,"$\RS\t"),(289,"$\RS\t")+            ,(290,"%\RS\n"),(291,"%\RS\n"),(292,"%\RS\n"),(293,"%\RS\n"),(294,"%\RS\n"),(295,"%\RS\v"),(296,"%\RS\v"),(297,"%\US\v"),(298,"%\US\v"),(299,"&\US\f")+            ,(300,"&\US\f"),(301,"&\US\f"),(302,"&\US\f"),(303,"&\US\f"),(304,"&\US\f"),(305,"&\US\r"),(306,"&\US\r"),(307,"&\US\r"),(308,"& \r"),(309,"& \r")+            ,(310,"& \r"),(311,"& \r"),(312,"& \SO"),(313,"& \SO"),(314,"& \SO"),(315,"& \SO"),(316,"& \SO"),(317,"' \SO"),(318,"' \SO"),(319,"' \SO")+            ,(320,"' \SO"),(321,"' \SO"),(322,"' \SI"),(323,"' \SI"),(324,"' \SI"),(325,"& \SI"),(326,"& \SI"),(327,"& \SI"),(328,"& \SI"),(329,"& \SI")+            ,(330,"& \SI"),(331,"& \SI"),(332,"& \SI"),(333,"& \SI"),(334,"& \SI"),(335,"& \SI"),(336,"& \SI"),(337,"& \SI"),(338,"& \SI"),(339,"& \SI")+            ,(340,"& \SI"),(341,"& \SI"),(342,"& \SI"),(343,"&\US\SI"),(344,"&\US\SI"),(345,"&\US\SI"),(346,"&\US\SI"),(347,"&\US\DLE"),(348,"&\US\DLE"),(349,"&\US\DLE")+            ,(350,"&\US\DLE"),(351,"&\US\DLE\SOH"),(352,"&\US\DLE\SOH"),(353,"&\US\DLE\SOH"),(354,"&\US\DLE\SOH"),(355,"&\US\DLE\SOH"),(356,"&\US\DLE\SOH"),(357,"&\US\DLE\SOH"),(358,"&\US\DLE\SOH"),(359,"&\US\DLE\SOH")+            ,(360,"&\US\DLE\STX"),(361,"&\US\DLE\STX"),(362,"&\US\DLE\STX"),(363,"&\US\DLE\STX"),(364,"&\US\DLE\STX"),(365,"&\US\DLE\STX"),(366,"& \DLE\STX"),(367,"& \DLE\STX"),(368,"& \DC1\STX"),(369,"& \DC1\ETX")+            ,(370,"& \DC1\ETX"),(371,"& \DC1\ETX"),(372,"& \DC1\ETX"),(373,"& \DC1\ETX"),(374,"& \DC1\ETX"),(375,"& \DC1\ETX"),(376,"' \DC1\EOT"),(377,"' \DC1\EOT"),(378,"' \DC1\EOT"),(379,"' \DC1\EOT")+            ,(380,"' \DC1\EOT"),(381,"' \DC2\EOT"),(382,"' \DC2\EOT"),(383,"' \DC2\EOT"),(384,"' \DC2\EOT"),(385,"' \DC2\EOT"),(386,"' \DC2\ENQ"),(387,"' \DC2\ENQ"),(388,"'!\DC2\ENQ"),(389,"'!\DC2\ENQ")+            ,(390,"'!\DC2\ENQ"),(391,"'!\DC2\ENQ"),(392,"'!\DC2\ENQ"),(393,"'!\DC3\ACK"),(394,"(!\DC3\ACK"),(395,"(!\DC3\ACK"),(396,"(!\DC3\ACK"),(397,"(!\DC3\ACK"),(398,"(!\DC3\ACK"),(399,"(!\DC3\ACK")+            ,(400,"(!\DC3\ACK"),(401,"(!\DC3\a"),(402,"(!\DC3\a"),(403,"(!\DC3\a"),(404,"(!\DC3\a"),(405,"(!\DC4\a"),(406,"(!\DC4\a"),(407,"(!\DC4\a"),(408,"(!\DC4\a"),(409,"(!\DC4\a")+            ,(410,"(\"\DC4\b"),(411,"(\"\DC4\b"),(412,"(\"\DC4\b"),(413,"(\"\DC4\b"),(414,"(\"\DC4\b"),(415,"(\"\DC4\b"),(416,"(\"\DC4\b"),(417,"(\"\DC4\b"),(418,"(\"\DC4\b"),(419,")\"\DC4\b")+            ,(420,")\"\DC4\t"),(421,")\"\DC4\t"),(422,")\"\DC4\t"),(423,")\"\DC4\t"),(424,")\"\DC4\t"),(425,")\"\DC4\t"),(426,")\"\NAK\t"),(427,")\"\NAK\t"),(428,")\"\NAK\t"),(429,")\"\NAK\t")+            ,(430,")\"\NAK\t"),(431,")\"\NAK\t"),(432,")\"\NAK\t"),(433,")\"\NAK\t"),(434,")\"\NAK\n"),(435,")\"\NAK\n"),(436,")\"\NAK\n"),(437,")\"\NAK\n"),(438,")\"\NAK\n"),(439,")\"\NAK\n")+            ,(440,")\"\NAK\n"),(441,")\"\NAK\n"),(442,")\"\NAK\n"),(443,")\"\NAK\n"),(444,")\"\NAK\n"),(445,")\"\NAK\n"),(446,")\"\NAK\n"),(447,")\"\NAK\n"),(448,")\"\NAK\n"),(449,")\"\NAK\n")+            ,(450,")\"\NAK\n"),(451,")\"\NAK\n\SOH"),(452,")\"\NAK\n\SOH"),(453,")\"\NAK\n\SOH"),(454,")\"\NAK\v\SOH"),(455,")\"\NAK\v\SOH"),(456,")\"\NAK\v\SOH"),(457,")\"\NAK\v\SOH"),(458,")\"\NAK\v\SOH"),(459,")\"\NAK\v\SOH")+            ,(460,")\"\NAK\v\SOH"),(461,")\"\NAK\v\SOH"),(462,")\"\NAK\v\SOH"),(463,")\"\NAK\v\SOH"),(464,")\"\NAK\v\SOH"),(465,")\"\NAK\v\SOH"),(466,")\"\NAK\v\SOH"),(467,")\"\NAK\v\SOH"),(468,")!\NAK\v\SOH"),(469,")!\NAK\v\SOH")+            ,(470,")!\NAK\v\SOH"),(471,")!\NAK\v\SOH"),(472,")!\NAK\v\SOH"),(473,")!\NAK\v\STX"),(474,")\"\NAK\v\STX"),(475,")\"\NAK\v\STX"),(476,")\"\NAK\v\STX"),(477,")\"\NAK\v\STX"),(478,")\"\NAK\f\STX"),(479,")\"\NAK\f\STX")+            ,(480,")\"\NAK\f\STX"),(481,")\"\NAK\f\STX"),(482,")\"\NAK\f\STX"),(483,")\"\NAK\f\STX"),(484,")\"\NAK\f\STX"),(485,")\"\NAK\f\STX"),(486,")\"\NAK\f\STX"),(487,")\"\NAK\f\STX"),(488,")\"\SYN\f\ETX"),(489,")\"\SYN\f\ETX")+            ,(490,")\"\SYN\f\ETX"),(491,")\"\SYN\f\ETX"),(492,")\"\SYN\f\ETX"),(493,")\"\SYN\f\ETX"),(494,")\"\SYN\f\ETX"),(495,")\"\SYN\f\ETX"),(496,")\"\SYN\f\ETX"),(497,")\"\SYN\r\ETX"),(498,")\"\SYN\r\ETX"),(499,")\"\SYN\r\ETX")+            ,(500,")\"\SYN\r\ETX"),(501,")\"\SYN\r\EOT"),(502,")\"\SYN\r\EOT"),(503,")\"\SYN\r\EOT"),(504,")\"\SYN\r\EOT"),(505,")\"\SYN\r\EOT"),(506,")\"\SYN\r\EOT"),(507,")\"\SYN\r\EOT"),(508,")\"\SYN\r\EOT"),(509,")\"\SYN\r\EOT")+            ,(510,")\"\SYN\r\EOT"),(511,")\"\SYN\r\EOT"),(512,")\"\SYN\r\EOT"),(513,")\"\SYN\r\EOT"),(514,")\"\SYN\r\EOT"),(515,"*\"\SYN\r\ENQ"),(516,"*\"\SYN\r\ENQ"),(517,"*\"\SYN\r\ENQ"),(518,"*\"\SYN\r\ENQ"),(519,"*\"\SYN\SO\ENQ")+            ,(520,"*\"\SYN\SO\ENQ"),(521,"*\"\SYN\SO\ENQ"),(522,"*\"\SYN\SO\ENQ"),(523,"*\"\SYN\SO\ENQ"),(524,"*\"\SYN\SO\ENQ"),(525,"*\"\SYN\SO\ENQ"),(526,"*\"\SYN\SO\ENQ"),(527,"*\"\SYN\SO\ENQ"),(528,"*\"\SYN\SO\ENQ"),(529,"*\"\SYN\SO\ENQ")+            ,(530,"*\"\SYN\SO\ENQ"),(531,"*\"\SYN\SO\ACK"),(532,"*\"\SYN\SO\ACK"),(533,"*\"\SYN\SO\ACK"),(534,"*\"\SYN\SO\ACK"),(535,"*\"\SYN\SO\ACK"),(536,"*\"\SYN\SO\ACK"),(537,"*\"\SYN\SO\ACK"),(538,"*\"\SYN\SO\ACK"),(539,"*\"\SYN\SO\ACK")+            ,(540,"*\"\SYN\SO\ACK"),(541,"*\"\SYN\SO\ACK"),(542,"*\"\SYN\SO\ACK"),(543,"*\"\SYN\SO\ACK"),(544,"*\"\SYN\SO\ACK"),(545,"*\"\SYN\SO\ACK"),(546,"*\"\SYN\SO\ACK"),(547,"*\"\SYN\SO\ACK"),(548,"*\"\SYN\SO\ACK"),(549,"*\"\SYN\SO\ACK")+            ,(550,"*\"\SYN\SO\ACK\SOH"),(551,"*\"\SYN\SO\a\SOH"),(552,"*\"\SYN\SO\a\SOH"),(553,"*\"\SYN\SO\a\SOH"),(554,"*\"\SYN\SO\a\SOH"),(555,"*\"\SYN\SO\a\SOH"),(556,"*\"\SYN\SO\a\SOH"),(557,"*\"\SYN\SO\a\SOH"),(558,"*\"\SYN\SO\a\SOH"),(559,"*\"\SYN\SO\a\SOH")+            ,(560,"*\"\SYN\SO\a\SOH"),(561,"*\"\SYN\SI\a\SOH"),(562,"*\"\SYN\SI\a\SOH"),(563,"*\"\SYN\SI\a\SOH"),(564,"*\"\SYN\SI\a\SOH"),(565,"*\"\SYN\SI\a\SOH"),(566,"*\"\SYN\SI\a\SOH"),(567,"*\"\SYN\SI\a\SOH"),(568,"*\"\SYN\SI\a\SOH"),(569,"*!\SYN\SI\a\SOH")+            ,(570,"*!\SYN\SI\a\SOH"),(571,"*!\SYN\SI\a\SOH"),(572,"*!\SYN\SI\a\SOH"),(573,"*!\SYN\SI\a\SOH"),(574,"*!\SYN\SI\a\SOH"),(575,"*!\SYN\SI\a\SOH"),(576,"*!\SYN\SI\a\SOH"),(577,"*!\SYN\SI\b\SOH"),(578,"*!\SYN\SI\b\SOH"),(579,"*!\SYN\SI\b\SOH")+            ,(580,"*!\SYN\SI\b\SOH"),(581,"*!\SYN\SI\b\SOH"),(582,"*!\SYN\SI\b\SOH"),(583,"*!\SYN\SI\b\SOH"),(584,"*!\SYN\SI\b\SOH"),(585,"*!\SYN\SI\b\SOH"),(586,"*!\SYN\SI\b\SOH"),(587,"*!\SYN\SI\b\SOH"),(588,"*!\SYN\SI\b\STX"),(589,"*!\SYN\SI\b\STX")+            ,(590,"*!\SYN\SI\b\STX"),(591,"*!\SYN\SI\b\STX"),(592,"*!\SYN\SI\b\STX"),(593,"*!\SYN\SI\b\STX"),(594,"*!\SYN\SI\b\STX"),(595,"*!\SYN\SI\b\STX"),(596,"*!\SYN\SI\b\STX"),(597,"*!\SYN\SI\b\STX"),(598,"*!\SYN\SI\b\STX"),(599,"*!\SYN\SI\b\STX")+            ,(600,"*!\SYN\SI\b\STX"),(601,"*!\SYN\SI\b\STX"),(602,"*!\SYN\SI\b\STX"),(603,"*!\SYN\SI\b\STX"),(604,"*!\SYN\SI\b\STX"),(605,"*!\SYN\SI\b\STX"),(606,"*!\SYN\SI\t\STX"),(607,"*!\SYN\SI\t\STX"),(608,"*!\SYN\SI\t\STX"),(609,"*!\SYN\SI\t\STX")+            ,(610,"*!\SYN\SI\t\STX"),(611,"*!\SYN\SI\t\ETX"),(612,"*!\SYN\SI\t\ETX"),(613,"*!\SYN\SI\t\ETX"),(614,"*!\SYN\SI\t\ETX"),(615,"*!\SYN\SI\t\ETX"),(616,"*!\SYN\SI\t\ETX"),(617,"*!\SYN\SI\t\ETX"),(618,"*!\SYN\SI\t\ETX"),(619,"*!\SYN\SI\t\ETX")+            ,(620,"*!\SYN\SI\t\ETX"),(621,"*!\SYN\SI\t\ETX"),(622,"*!\SYN\SI\t\ETX"),(623,"*!\SYN\SI\t\ETX"),(624,"*!\SYN\SI\t\ETX"),(625,"*!\SYN\SI\t\ETX"),(626,"*!\SYN\SI\t\ETX"),(627,"*!\SYN\SI\t\ETX"),(628,"*!\SYN\SI\t\ETX"),(629,"*!\SYN\SI\t\ETX")+            ,(630,"*!\SYN\SI\t\ETX"),(631,"*!\SYN\SI\t\ETX"),(632,"*!\SYN\SI\t\ETX"),(633,"*!\SYN\SI\t\ETX"),(634,"*!\SYN\SI\t\EOT"),(635,"*!\SYN\SI\t\EOT"),(636,"*!\SYN\SI\t\EOT"),(637,"*!\SYN\SI\t\EOT"),(638,"*!\SYN\SI\t\EOT"),(639,"*!\SYN\DLE\t\EOT")+            ,(640,"*!\SYN\DLE\n\EOT"),(641,"*!\SYN\DLE\n\EOT"),(642,"*!\SYN\DLE\n\EOT"),(643,"*!\SYN\DLE\n\EOT"),(644,"*!\SYN\DLE\n\EOT"),(645,"*!\SYN\DLE\n\EOT"),(646,"*!\SYN\DLE\n\EOT"),(647,"*!\SYN\DLE\n\EOT"),(648,"*!\SYN\DLE\n\EOT"),(649,"*!\SYN\DLE\n\EOT")+            ,(650,"*!\SYN\DLE\n\EOT\SOH"),(651,"*!\SYN\DLE\n\EOT\SOH"),(652,"*!\SYN\DLE\n\EOT\SOH"),(653,"*!\SYN\DLE\n\EOT\SOH"),(654,"*!\SYN\DLE\n\EOT\SOH"),(655,"*!\SYN\DLE\n\EOT\SOH"),(656,"*!\SYN\DLE\n\EOT\SOH"),(657,"*!\SYN\DLE\n\EOT\SOH"),(658,"*!\SYN\DLE\n\EOT\SOH"),(659,"*!\SYN\DLE\n\EOT\SOH")+            ,(660,"*!\SYN\DLE\n\EOT\SOH"),(661,"*!\SYN\DLE\n\EOT\SOH"),(662,"*!\SYN\DLE\n\EOT\SOH"),(663,"*!\SYN\DLE\n\ENQ\SOH"),(664,"*!\SYN\DLE\n\ENQ\SOH"),(665,"*!\SYN\DLE\n\ENQ\SOH"),(666,"*!\SYN\DLE\n\ENQ\SOH"),(667,"*!\SYN\DLE\n\ENQ\SOH"),(668,"*!\SYN\DLE\n\ENQ\SOH"),(669,"*!\SYN\DLE\n\ENQ\SOH")+            ,(670,"*!\SYN\DLE\n\ENQ\SOH"),(671,"*!\SYN\DLE\n\ENQ\SOH"),(672,"* \SYN\DLE\n\ENQ\SOH"),(673,"* \SYN\DLE\n\ENQ\SOH"),(674,"* \SYN\DLE\n\ENQ\SOH"),(675,"* \SYN\DLE\n\ENQ\SOH"),(676,"* \SYN\DLE\n\ENQ\SOH"),(677,"* \SYN\DLE\n\ENQ\SOH"),(678,"* \SYN\DLE\n\ENQ\SOH"),(679,"* \SYN\DLE\n\ENQ\SOH")+            ,(680,"* \SYN\DLE\n\ENQ\SOH"),(681,"* \SYN\DLE\n\ENQ\SOH"),(682,"* \SYN\DLE\n\ENQ\SOH"),(683,"* \SYN\DLE\n\ENQ\SOH"),(684,"* \SYN\DLE\n\ENQ\SOH"),(685,"* \SYN\DLE\n\ENQ\SOH"),(686,"* \SYN\DLE\n\ENQ\SOH"),(687,"* \SYN\DLE\n\ENQ\SOH"),(688,"* \SYN\DLE\n\ENQ\SOH"),(689,"* \SYN\DLE\n\ENQ\SOH")+            ,(690,"* \SYN\DLE\n\ENQ\SOH"),(691,"* \SYN\DLE\n\ENQ\SOH"),(692,"* \SYN\DLE\n\ENQ\SOH"),(693,"* \SYN\DLE\n\ENQ\SOH"),(694,"* \SYN\DLE\n\ENQ\SOH"),(695,"* \SYN\DLE\n\ENQ\SOH"),(696,"* \SYN\DLE\n\ENQ\SOH"),(697,"* \SYN\DLE\n\ENQ\SOH"),(698,"* \SYN\DLE\n\ENQ\SOH"),(699,"* \SYN\DLE\n\ENQ\SOH")+            ,(700,"* \SYN\DLE\n\ACK\SOH"),(701,"* \SYN\DLE\n\ACK\SOH"),(702,"* \SYN\DLE\n\ACK\SOH"),(703,"* \SYN\DLE\n\ACK\SOH"),(704,"* \SYN\DLE\n\ACK\SOH"),(705,"* \SYN\DLE\n\ACK\SOH"),(706,"* \SYN\DLE\n\ACK\SOH"),(707,"* \SYN\DLE\n\ACK\SOH"),(708,"* \SYN\DLE\n\ACK\SOH"),(709,"* \SYN\DLE\n\ACK\SOH")+            ,(710,"* \SYN\DLE\n\ACK\SOH"),(711,"* \SYN\DLE\n\ACK\SOH"),(712,"* \SYN\DLE\n\ACK\SOH"),(713,"* \SYN\DLE\n\ACK\STX"),(714,"* \SYN\DLE\n\ACK\STX"),(715,"* \SYN\DLE\v\ACK\STX"),(716,"* \SYN\DLE\v\ACK\STX"),(717,"* \SYN\DLE\v\ACK\STX"),(718,"* \SYN\DLE\v\ACK\STX"),(719,"* \SYN\DLE\v\ACK\STX")+            ,(720,"* \SYN\DLE\v\ACK\STX"),(721,"* \SYN\DLE\v\ACK\STX"),(722,"* \SYN\DLE\v\ACK\STX"),(723,"* \SYN\DLE\v\ACK\STX"),(724,"* \SYN\DLE\v\ACK\STX"),(725,"* \SYN\DLE\v\ACK\STX"),(726,"* \SYN\DLE\v\ACK\STX"),(727,"* \SYN\DLE\v\ACK\STX"),(728,"* \SYN\DLE\v\ACK\STX"),(729,"* \SYN\DLE\v\ACK\STX")+            ,(730,"* \SYN\SI\v\ACK\STX"),(731,"* \SYN\SI\v\ACK\STX"),(732,"* \SYN\SI\v\ACK\STX"),(733,"* \SYN\SI\v\ACK\STX"),(734,"* \SYN\SI\v\ACK\STX"),(735,"* \SYN\SI\v\ACK\STX"),(736,"* \SYN\SI\v\ACK\STX"),(737,"* \SYN\SI\v\ACK\STX"),(738,"* \SYN\SI\v\ACK\STX"),(739,"* \SYN\SI\v\ACK\STX")+            ,(740,"*\US\SYN\SI\v\ACK\STX"),(741,"*\US\SYN\SI\v\ACK\STX"),(742,"*\US\NAK\SI\v\ACK\STX"),(743,"*\US\NAK\SI\v\ACK\STX"),(744,"*\US\NAK\SI\v\ACK\STX"),(745,"*\US\NAK\SI\v\ACK\STX"),(746,"*\US\NAK\SI\v\ACK\STX"),(747,"*\US\NAK\SI\v\ACK\STX"),(748,"*\US\NAK\SI\v\a\STX"),(749,"*\US\NAK\SI\v\a\ETX")+            ,(750,"*\US\NAK\SI\v\a\ETX"),(751,"*\US\NAK\SI\v\a\ETX\SOH"),(752,"*\US\NAK\SI\v\a\ETX\SOH"),(753,"*\US\NAK\SI\v\a\ETX\SOH"),(754,"*\US\NAK\SI\v\a\ETX\SOH"),(755,"*\US\NAK\SI\v\a\ETX\SOH"),(756,"*\US\NAK\SI\v\a\ETX\SOH"),(757,"*\US\NAK\SI\v\a\ETX\SOH"),(758,"*\US\NAK\SI\v\a\ETX\SOH"),(759,"*\US\NAK\SI\v\a\ETX\SOH")+            ,(760,"*\US\NAK\SI\v\a\ETX\SOH"),(761,"*\US\NAK\SI\v\a\ETX\SOH"),(762,"*\US\NAK\SI\v\a\ETX\SOH"),(763,"*\US\NAK\SI\v\a\ETX\SOH"),(764,"*\US\NAK\SI\v\a\ETX\SOH"),(765,"*\US\NAK\SI\v\a\ETX\SOH"),(766,"*\US\NAK\SI\v\a\ETX\SOH"),(767,"*\US\NAK\SI\v\a\ETX\SOH"),(768,"*\US\NAK\SI\v\a\ETX\SOH"),(769,"*\US\NAK\SI\v\a\ETX\SOH")+            ,(770,"*\US\NAK\SI\v\a\ETX\SOH"),(771,"*\US\NAK\SI\v\a\ETX\SOH"),(772,"*\US\NAK\SI\v\a\ETX\SOH"),(773,"*\US\NAK\SI\v\a\ETX\SOH"),(774,"*\US\NAK\SI\v\a\ETX\SOH"),(775,"*\US\NAK\SI\v\a\ETX\SOH"),(776,"*\US\NAK\SI\v\a\ETX\SOH"),(777,"*\US\NAK\SI\v\a\ETX\SOH"),(778,"*\US\NAK\SI\v\a\ETX\SOH"),(779,"*\US\NAK\SI\v\a\ETX\SOH")+            ,(780,"*\US\NAK\SI\v\a\ETX\SOH"),(781,"*\US\NAK\SI\v\a\ETX\SOH"),(782,"*\US\NAK\SI\v\a\ETX\SOH"),(783,"*\US\NAK\SI\v\a\ETX\SOH"),(784,"*\US\NAK\SI\v\a\ETX\SOH"),(785,"*\US\NAK\SI\v\a\ETX\SOH"),(786,"*\US\NAK\SI\v\a\ETX\SOH"),(787,"*\US\NAK\SI\v\a\ETX\SOH"),(788,"*\US\NAK\SI\v\a\ETX\SOH"),(789,"*\US\NAK\SI\v\a\ETX\SOH")+            ,(790,"*\US\NAK\SI\v\a\ETX\SOH"),(791,"*\US\NAK\SI\v\a\ETX\SOH"),(792,"*\US\NAK\SI\v\a\ETX\SOH"),(793,"*\US\NAK\SI\v\a\ETX\SOH"),(794,"*\US\NAK\SI\v\a\ETX\SOH"),(795,"*\US\NAK\SI\v\a\ETX\SOH"),(796,"*\US\NAK\SI\v\a\ETX\SOH"),(797,"*\US\NAK\SI\v\a\ETX\SOH"),(798,"*\US\NAK\SI\v\a\EOT\SOH"),(799,"*\RS\NAK\SI\v\a\EOT\SOH")+            ,(800,"*\RS\NAK\SI\v\a\EOT\SOH"),(801,"*\RS\NAK\SI\v\a\EOT\SOH"),(802,"*\RS\NAK\SI\v\a\EOT\SOH"),(803,"*\RS\NAK\SI\v\a\EOT\SOH"),(804,"*\RS\NAK\SI\v\a\EOT\SOH"),(805,"*\RS\NAK\SI\v\a\EOT\SOH"),(806,"*\RS\NAK\SI\v\a\EOT\SOH"),(807,"*\RS\NAK\SI\v\a\EOT\SOH"),(808,"*\RS\NAK\SI\v\a\EOT\SOH"),(809,"*\RS\NAK\SI\v\a\EOT\SOH")+            ,(810,"*\RS\NAK\SI\v\a\EOT\SOH"),(811,"*\RS\NAK\SI\v\a\EOT\SOH"),(812,"*\RS\NAK\SI\v\a\EOT\SOH"),(813,"*\RS\NAK\SI\v\a\EOT\SOH"),(814,"*\RS\NAK\SI\v\a\EOT\SOH"),(815,"*\RS\NAK\SI\v\a\EOT\SOH"),(816,"*\RS\NAK\SI\v\a\EOT\SOH"),(817,"*\RS\DC4\SI\v\a\EOT\SOH"),(818,"*\RS\DC4\SI\v\a\EOT\SOH"),(819,"*\RS\DC4\SI\v\a\EOT\SOH")+            ,(820,"*\RS\DC4\SI\v\a\EOT\SOH"),(821,"*\RS\DC4\SI\v\a\EOT\SOH"),(822,"*\RS\DC4\SI\v\a\EOT\SOH"),(823,"*\RS\DC4\SI\v\a\EOT\SOH"),(824,"*\RS\DC4\SI\v\a\EOT\SOH"),(825,"*\RS\DC4\SI\v\a\EOT\SOH"),(826,"*\RS\DC4\SI\v\a\EOT\SOH"),(827,"*\RS\DC4\SI\v\a\EOT\SOH"),(828,"*\RS\DC4\SI\v\a\EOT\SOH"),(829,"*\RS\DC4\SI\v\a\EOT\SOH")+            ,(830,"*\RS\DC4\SI\v\a\EOT\SOH"),(831,"*\RS\DC4\SI\v\a\EOT\SOH"),(832,"*\RS\DC4\SI\v\a\EOT\SOH"),(833,"*\RS\DC4\SI\v\a\EOT\SOH"),(834,"*\RS\DC4\SI\v\a\EOT\SOH"),(835,"*\RS\DC4\SI\v\a\EOT\SOH"),(836,"*\RS\DC4\SI\v\a\EOT\SOH"),(837,"*\RS\DC4\SI\v\a\EOT\SOH"),(838,"*\RS\DC4\SI\v\a\EOT\SOH"),(839,"*\RS\DC4\SI\v\a\EOT\SOH")+            ,(840,"*\RS\DC4\SI\v\a\EOT\SOH"),(841,"*\RS\DC4\SI\v\a\EOT\SOH"),(842,"*\RS\DC4\SI\v\a\EOT\SOH"),(843,"*\RS\DC4\SI\v\a\EOT\SOH"),(844,"*\RS\DC4\SI\v\a\EOT\SOH"),(845,"*\RS\DC4\SI\v\a\EOT\SOH"),(846,"*\RS\DC4\SI\v\a\EOT\SOH"),(847,"*\RS\DC4\SI\v\a\EOT\SOH"),(848,"*\RS\DC4\SI\v\a\EOT\SOH"),(849,"*\RS\DC4\SI\v\a\EOT\SOH")+            ,(850,"*\RS\DC4\SI\v\a\EOT\SOH\SOH"),(851,"*\RS\DC4\SO\v\a\EOT\SOH\SOH"),(852,"*\GS\DC4\SO\v\a\EOT\STX\SOH"),(853,"*\GS\DC4\SO\v\a\EOT\STX\SOH"),(854,"*\GS\DC4\SO\v\a\EOT\STX\SOH"),(855,"*\GS\DC4\SO\v\a\EOT\STX\SOH"),(856,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(857,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(858,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(859,"*\GS\DC4\SO\n\a\EOT\STX\SOH")+            ,(860,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(861,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(862,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(863,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(864,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(865,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(866,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(867,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(868,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(869,"*\GS\DC4\SO\n\a\EOT\STX\SOH")+            ,(870,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(871,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(872,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(873,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(874,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(875,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(876,"*\GS\DC4\SO\n\a\EOT\STX\SOH"),(877,"*\GS\DC4\SO\n\a\ENQ\STX\SOH"),(878,"*\GS\DC4\SO\n\a\ENQ\STX\SOH"),(879,"*\GS\DC4\SO\n\a\ENQ\STX\SOH")+            ,(880,"*\GS\DC4\SO\n\a\ENQ\STX\SOH"),(881,"*\GS\DC4\SO\n\a\ENQ\STX\SOH"),(882,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(883,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(884,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(885,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(886,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(887,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(888,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(889,"*\GS\DC3\SO\n\a\ENQ\STX\SOH")+            ,(890,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(891,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(892,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(893,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(894,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(895,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(896,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(897,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(898,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(899,"*\GS\DC3\SO\n\a\ENQ\STX\SOH")+            ,(900,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(901,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(902,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(903,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(904,"*\GS\DC3\SO\n\a\ENQ\STX\SOH"),(905,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(906,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(907,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(908,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(909,"*\FS\DC3\SO\n\a\ENQ\STX\SOH")+            ,(910,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(911,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(912,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(913,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(914,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(915,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(916,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(917,"*\FS\DC3\SO\n\a\ENQ\STX\SOH"),(918,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(919,")\FS\DC3\SO\n\a\ENQ\STX\SOH")+            ,(920,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(921,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(922,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(923,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(924,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(925,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(926,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(927,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(928,")\FS\DC3\SO\n\a\ENQ\STX\SOH"),(929,")\FS\DC3\r\n\a\ENQ\STX\SOH")+            ,(930,")\FS\DC3\r\n\a\ENQ\STX\SOH"),(931,")\FS\DC3\r\n\a\ENQ\STX\SOH"),(932,")\FS\DC3\r\n\a\ENQ\STX\SOH"),(933,")\FS\DC3\r\n\a\ENQ\ETX\SOH"),(934,")\FS\DC3\r\n\a\ENQ\ETX\SOH"),(935,")\FS\DC3\r\n\a\ENQ\ETX\SOH"),(936,")\FS\DC3\r\n\a\ENQ\ETX\SOH"),(937,")\FS\DC3\r\n\a\ENQ\ETX\SOH"),(938,")\FS\DC3\r\n\a\ENQ\ETX\SOH"),(939,")\FS\DC3\r\n\a\ENQ\ETX\SOH")+            ,(940,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(941,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(942,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(943,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(944,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(945,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(946,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(947,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(948,")\FS\DC2\r\n\a\ENQ\ETX\SOH"),(949,")\FS\DC2\r\n\a\ENQ\ETX\SOH")+            ,(950,")\FS\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(951,")\FS\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(952,")\FS\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(953,")\FS\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(954,")\FS\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(955,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(956,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(957,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(958,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(959,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH")+            ,(960,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(961,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(962,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(963,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(964,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(965,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(966,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(967,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(968,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(969,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH")+            ,(970,")\ESC\DC2\r\n\a\ENQ\ETX\SOH\SOH"),(971,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(972,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(973,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(974,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(975,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(976,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(977,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(978,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(979,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH")+            ,(980,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(981,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(982,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(983,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(984,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(985,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(986,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(987,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(988,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(989,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(991,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(992,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(993,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(994,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(995,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(996,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(997,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(998,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH"),(999,")\ESC\DC2\r\t\a\ENQ\ETX\SOH\SOH")+            ,(1000,")\ESC\DC1\r\t\a\ENQ\ETX\SOH\SOH"),(1001,")\ESC\DC1\r\t\a\ENQ\ETX\SOH\SOH"),(1002,")\ESC\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1003,")\ESC\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1004,")\ESC\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1005,")\ESC\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1006,")\ESC\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1007,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1008,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1009,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH")+            ,(1010,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1011,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1012,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1013,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1014,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1015,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1016,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1017,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1018,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1019,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1021,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1022,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1024,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1025,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1026,")\SUB\DC1\f\t\a\ENQ\ETX\SOH\SOH"),(1028,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1029,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1031,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1033,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1034,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1035,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1037,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1038,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1039,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH")+            ,(1040,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1041,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1042,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1043,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1044,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1045,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1046,")\SUB\DC1\f\t\ACK\ENQ\ETX\SOH\SOH"),(1047,")\SUB\DC1\f\t\ACK\EOT\ETX\SOH\SOH"),(1049,")\SUB\DC1\f\t\ACK\EOT\ETX\SOH\SOH"),(1051,")\SUB\DC1\f\t\ACK\EOT\ETX\SOH\SOH\SOH"),(1052,")\SUB\DC1\f\t\ACK\EOT\ETX\SOH\SOH\SOH"),(1053,")\SUB\DC1\f\t\ACK\EOT\ETX\SOH\SOH\SOH"),(1054,")\SUB\DC1\f\t\ACK\EOT\ETX\SOH\SOH\SOH"),(1055,")\SUB\DC1\f\t\ACK\EOT\ETX\SOH\SOH\SOH"),(1057,")\EM\DLE\f\b\ACK\EOT\ETX\SOH\SOH\SOH"),(1058,")\EM\DLE\f\b\ACK\EOT\ETX\SOH\SOH\SOH")+            ,(1060,")\EM\DLE\f\b\ACK\EOT\ETX\SOH\SOH\SOH"),(1062,")\EM\DLE\f\b\ACK\EOT\ETX\STX\SOH\SOH"),(1063,")\EM\DLE\f\b\ACK\EOT\ETX\STX\SOH\SOH"),(1064,")\EM\DLE\f\b\ACK\EOT\ETX\STX\SOH\SOH"),(1065,")\EM\DLE\f\b\ACK\EOT\ETX\STX\SOH\SOH"),(1066,")\EM\DLE\f\b\ACK\EOT\ETX\STX\SOH\SOH"),(1067,")\EM\DLE\f\b\ACK\EOT\ETX\STX\SOH\SOH"),(1068,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1069,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH")+            ,(1070,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1072,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1073,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1075,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1076,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1078,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1079,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH")+            ,(1080,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1081,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1082,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1083,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1084,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1085,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1086,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1087,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1088,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1089,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1091,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1092,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1094,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1095,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1096,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1097,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1098,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1101,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1102,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1103,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1105,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1107,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1108,")\EM\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1112,")\CAN\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1113,")\CAN\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1115,")\CAN\DLE\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1117,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1119,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH")+            ,(1120,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1125,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1126,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1127,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1128,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1129,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1132,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1133,")\CAN\SI\v\b\ACK\EOT\ETX\STX\SOH\SOH"),(1134,")\CAN\SI\v\b\ENQ\EOT\ETX\STX\SOH\SOH"),(1135,")\CAN\SI\v\b\ENQ\EOT\ETX\STX\SOH\SOH"),(1136,")\CAN\SI\v\b\ENQ\EOT\ETX\STX\SOH\SOH"),(1141,")\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH"),(1142,")\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH"),(1143,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH"),(1144,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH"),(1147,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH"),(1152,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1153,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1154,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1156,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1157,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1158,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1159,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH")+            ,(1160,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1165,"(\CAN\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1169,"(\ETB\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1171,"(\ETB\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1175,"(\ETB\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1177,"(\ETB\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH"),(1178,"(\ETB\SI\n\a\ENQ\EOT\ETX\STX\SOH\SOH\SOH")+            ,(1180,"(\ETB\SO\n\a\ENQ\EOT\STX\STX\SOH\SOH\SOH"),(1181,"(\ETB\SO\n\a\ENQ\EOT\STX\STX\SOH\SOH\SOH"),(1183,"(\ETB\SO\n\a\ENQ\EOT\STX\STX\SOH\SOH\SOH"),(1185,"(\ETB\SO\n\a\ENQ\EOT\STX\STX\SOH\SOH\SOH"),(1195,"(\ETB\SO\n\a\ENQ\EOT\STX\STX\SOH\SOH\SOH"),(1198,"(\ETB\SO\n\a\ENQ\EOT\STX\STX\SOH\SOH\SOH"),(1201,"(\ETB\SO\n\a\ENQ\ETX\STX\SOH\SOH\SOH\SOH"),(1203,"(\ETB\SO\n\a\ENQ\ETX\STX\SOH\SOH\SOH\SOH"),(1205,"(\ETB\SO\n\a\ENQ\ETX\STX\SOH\SOH\SOH\SOH"),(1219,"(\ETB\SO\t\a\ENQ\ETX\STX\SOH\SOH\SOH\SOH"),(1225,"(\ETB\SO\t\ACK\ENQ\ETX\STX\SOH\SOH\SOH\SOH"),(1227,"(\ETB\SO\t\ACK\ENQ\ETX\STX\SOH\SOH\SOH\SOH"),(1238,"(\SYN\SO\t\ACK\ENQ\ETX\STX\SOH\SOH\SOH\SOH"),(1253,"(\SYN\r\t\ACK\EOT\ETX\STX\SOH\SOH\SOH\SOH\SOH"),(1262,"(\SYN\r\t\ACK\EOT\ETX\STX\SOH\SOH\SOH\SOH\SOH")+            ,(1270,"(\SYN\r\t\ACK\EOT\ETX\STX\SOH\SOH\SOH\SOH\SOH")+            ,(1280,"(\SYN\r\t\ACK\EOT\ETX\STX\SOH\SOH\SOH\SOH\SOH"),(1295,"(\NAK\r\b\ACK\EOT\ETX\STX\SOH\SOH\SOH\SOH\SOH"),(1321,"(\NAK\r\b\ACK\EOT\ETX\STX\SOH\SOH\SOH\SOH\SOH"),(1322,"(\NAK\r\b\ACK\EOT\ETX\STX\SOH\SOH\SOH\SOH\SOH")+            ,(3100,"9\SO\a\ETX\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH\SOH")]
+ src/Generations/GenBase.hs view
@@ -0,0 +1,79 @@+module Generations.GenBase ( Model, QualMethod+                           , Generation(..), makeCommonHeader+                           , qual_exact_fixed, qual_exact_decreasing+                           , module Bio.Sequence.SFF+                           , module Bio.Sequence.SFF_filters+                           , module Statistics +                           , module HPLCount+                           ) where++import qualified Data.ByteString.Char8 as BC+import Bio.Sequence.SFF+import Bio.Sequence.SFF_filters++import Debug.Trace (trace)++import Statistics+import HPLCount hiding (main)++type Model = Int -> Distribution -- ^ each hpl length has its own distribution of flow values++type QualMethod = HPLprob -> Model -> (Char,Flow) -> [Qual]++data Generation = Gen {+      name     :: String+    , qcall    :: QualMethod -- ^ use the current model and hpl lenght to generate qual data+    , models   :: [Model]  -- ^ a progression of initial models for the sequence of flows+    , degrade  :: Distribution         -- the amount to increase a stdev multiplier each position+    , disc_filters :: [DiscardFilter]+    , trim_filters :: [TrimFilter]+    -- stuff to build the commonheader from+    , f_key :: String+    , f_len   :: Int+    , f_cycle :: String+    --    readblock :: [ReadBlock] ?+    }++instance Show Generation where+  show g = "Config:\n" ++ unlines (map ("  "++)+           ["key: "++f_key g+           ,"flowlength: "++show (f_len g), "flow cycle: "++show (f_cycle g)+           ])+--           ,"flow distributions:"])+--           ++ unlines ["    "++show i++": "++show (model g i) | i <- [0..6]]++-- | Calculate exact qualities from model using Bayes' theorem+--   This should emulate Marguiles et al.'s method.  +qual_exact_decreasing :: HPLprob -> Model -> (Char,Flow) -> [Qual]+qual_exact_decreasing ft m (c,flow) = +  let f = fromIntegral flow / 100+      prob hpl | hpl > 20  = error "can't handle hpls > 20" +               | otherwise = ft c hpl * pdf (m hpl) f / sum [pdf (m x) f * ft c x | x <- [0..20]]+      probs = drop 1 $ scanl (+) 0 $ map prob [0..20]+      quals = map (round . max 0 . min 60 . ((-10)*) . logBase 10) $ probs+  in -- trace ("#"++show (c,flow) ++"\n"++show probs ++"\n"++show quals) $+     take (fromIntegral $ (flow+50) `div` 100) $ quals+     +-- | Using Bayes, but only calculating the probablity of the call lenght+--   being correct.  Should be similar to Titanium (but is it?)+qual_exact_fixed :: HPLprob -> Model -> (Char,Flow) -> [Qual]+qual_exact_fixed ft m (c,flow) = +  let f = fromIntegral flow / 100+      hpl = fromIntegral $ (flow+50) `div` 100+      prob = ft c hpl * pdf (m hpl) f / sum [pdf (m x) f * ft c x | x <- [0..20]]+  in replicate hpl (round $ max 0 . min 60 $ (-10) * logBase 10 (1-prob))++-- --------------------------------------------------+-- Putting it together+makeCommonHeader :: Generation -> CommonHeader+makeCommonHeader g = CommonHeader+    { index_offset = 0+    , index_length = 0+    , key_length = fromIntegral $ length $ f_key g+    , flowgram_fmt = 1+    , key = BC.pack $ f_key g++    , num_reads = 0 -- fromIntegral $ n_reads g+    , flow_length = fromIntegral $ f_len g+    , flow = BC.pack $ concat $ replicate (f_len g `div` (length $ f_cycle g)) $ f_cycle g+    }
+ src/Generations/Titanium.hs view
@@ -0,0 +1,16 @@+module Generations.Titanium where+import Generations.GenBase++titanium :: Generation+titanium = Gen+       { name     = "Titanium"+       , qcall     = qual_exact_fixed+       , models   = [\h -> let h' = fromIntegral h +                           in if h == 0 then LogNormal (negate 2.5) 0.2 else Normal h' (0.04+0.05*h')]+       , degrade  = Normal 0.001 0.001+       , disc_filters = [filter_key,filter_empty]+       , trim_filters = []+       , f_key        = "TCAG"+       , f_len        = 800 -- :: Int16+       , f_cycle      = "TACG"+       }
+ src/HPLCount.hs view
@@ -0,0 +1,44 @@+-- count homopolymer distributions in a fasta file+module HPLCount where++import Bio.Sequence+import qualified Data.ByteString.Lazy.Char8 as B+import qualified Data.Map as M+import Text.Printf+import Data.Char (toUpper)+import Data.List (intersperse)+import Data.Maybe (fromJust)+import System.Environment++type HPLprob = Char -> Int -> Double++-- lookup and return probability of this hpl length for this letter+mkHPLprobs :: M.Map (Char,Int) Int -> HPLprob+mkHPLprobs ft = let totals = [(c, fromIntegral $ sum [M.findWithDefault 0 (c,x) ft | x <- [0..50]]) | c <- "ACGT" ]+                in \ch n -> fromIntegral (M.findWithDefault 0 (ch,n) ft) / fromJust (lookup ch totals)++main = do+  [f] <- getArgs+  display "tacg" . freqtable . concatMap (hpls "tacg" . seqdata) =<< readFasta f++display :: [Char] -> M.Map (Char,Int) Int -> IO ()+display fs m = let imax = maximum $ map snd $ M.keys m+                   header = concat ("len\t   " : intersperse "\t   " (map (return . toUpper) fs))+               in putStrLn $ unlines (header : [ printf "%3d" i ++ concat [ printf "\t%5d" (M.findWithDefault 0 (c,i) m) |  c <- map toUpper fs ] | i <- [0..imax]])++freqtable :: [(Char,Int)] -> M.Map (Char,Int) Int+freqtable = go M.empty +  where+    go m [] = m+    go m (i:is) = let v = M.findWithDefault 0 i m +                      v' = v+1+                      m' = M.insert i v' m+                  in v' `seq` m' `seq` go m' is+  +hpls :: [Char] -> SeqData -> [(Char,Int)]+hpls xs = go (cycle xs')+  where xs' = map toUpper xs+        go (f:fs) sd | B.null sd = []+                     | not (elem (toUpper $ B.head sd) xs') = go (f:fs) (B.tail sd)+                     | otherwise = let (this,rest) = B.span ((==f).toUpper) sd+                                   in (f,fromIntegral (B.length this)) : go fs rest
+ src/Statistics.hs view
@@ -0,0 +1,154 @@+{-# LANGUAGE ForeignFunctionInterface #-}++-- | Yet another simple module for implementing statistics stuff.+module Statistics (sample, samples, normal, normals+                  , stdnormal, stdnormals, Distribution(..), Prob(..)+                  , pdf, pvalue, fromPdf, invcum, worsen+                  , module Control.Monad.Random+                  ) where++import Control.Monad.Random+import Data.Array.Unboxed++foreign import ccall "erf" erf :: Double -> Double++newtype Prob = P Double deriving Show++instance Random Prob where+    random g = let (a,g') = randomR (0,1) g in (P a,g')+    randomR  = error "Specifying a range for a probability makes no sense."++-- Todo: implement+data Distribution = Normal Double Double     -- ^ mu and sigma+                  | LogNormal Double Double  -- ^ mu and sigma+                  | Uniform Double Double    -- ^ from/to inclusive+                  | Empirical Double Double (UArray Int Double) +                    -- ^ Stores a cumulative distribution, centered on first +                    -- param (ref. 'worsen'), and second param is step size+                  deriving (Show,Read)+                  -- add more: StudentsT, SkewNormal, SkewT++-- dummy to make deriving Read work+instance Read (UArray i d) where++-- | Build an empirical probablility distribution by mapping the given probabilities+--   to uniformly spaced points starting at 'start' with 'step' points per unit.+--   Automatically center on pvalue = 50.  +fromPdf :: Double -> Double -> [Prob] -> Distribution+fromPdf start h ps = let    ps' = acc 0 $ map ((/scale) . unprob) $ ps+                            mu = start+(fromIntegral . length . takeWhile (<0.5)) ps'*h-h/2+                            a = floor ((start-mu)/h)+                            b = a+length ps'+                            scale = sum [ x | P x <- ps]+                            unprob (P x) = x+                            acc _ [] = [1]+                            acc c (x:xs) = let v = c+x+                                           in if v >= 1 then [1] else v : acc v xs+                        in Empirical mu h $ listArray (a,b) (0:ps')++invcum :: Distribution -> Prob -> Double+invcum (Normal mu sigma) (P z) = invcumnorm mu sigma z+invcum (LogNormal mu sigma) (P z) = exp $ invcum (Normal mu sigma) (P z)+invcum (Uniform a b) (P z) = a+(b-a)*z+invcum (Empirical mu h cd) (P z) = let (a,b) = bounds cd in mu+bisect ((cd!).round) (fromIntegral a) (fromIntegral b) z * h+++-- | Calculate probability of sampling less than x+--   (i.e. the cumulative distribution's value in x)+pvalue :: Distribution -> Double -> Prob+pvalue (Normal mu sigma) x = P (cumnorm mu sigma x)+pvalue (Uniform a b) x | x <= a    = P 0 +                       | x >= b    = P 1+                       | otherwise = P ((x-a)/(b-a))+pvalue (LogNormal mu sigma) x | x<1e-10   = P 0 -- not sufficient!+                              | otherwise = P (cumlognorm mu sigma x)+pvalue (Empirical mu h cd) x = let (a,b) = bounds cd+                                   x' = (x-mu)/h+                               in if x' < fromIntegral a then P 0+                                  else if x' >= fromIntegral b then P 1+                                    else let x1 = floor x'+                                             x2 = x1+1+                                             y1 = cd!x1+                                             y2 = cd!x2+                                         in P (y1 + (y2-y1)*(x'-fromIntegral x1))++-- general functions for sampling++sample :: RandomGen g => Distribution -> Rand g Double+sample d = invcum d `fmap` getRandom++-- sample (Uniform a b) = getRandomR (a,b)+-- todo: replace with general function:+samples  :: RandomGen g => Distribution -> Rand g [Double]+samples (Normal mu sigma) = normals mu sigma+samples (LogNormal mu sigma) = map exp `fmap` samples (Normal mu sigma)+samples (Uniform a b) = getRandomRs (a,b)+samples (Empirical _mu _h _cds) = error "todo: implement 'samples' for Empirical distributions"++-- | The probability density function+pdf :: Distribution -> Double -> Double -- Prob?+pdf (Normal mu sigma) x = exp(negate(square (x-mu)/(2*square sigma)))/(sigma*sqrt(2*pi))+pdf (LogNormal mu sigma) x+    | x>0 = exp(negate(square (log x-mu)/(2*square sigma)))/(x*sigma*sqrt(2*pi))+    | otherwise = 0+pdf (Uniform a b) x+    | x<b && x>= a = 1/(b-a)  -- interval is open on the right, to work correctly with empirical below+    | otherwise = 0+pdf (Empirical mu h cd) x = let (a,b) = bounds cd+                                x' = (x-mu)/h+                            in if x' < fromIntegral a then 0+                               else if x' >= fromIntegral b then 0+                                 else let x1 = floor x'+                                          x2 = x1+1+                                          y1 = cd!x1+                                          y2 = cd!x2+                                      in (y2-y1)/h+-- ------------------------------+-- Specifics+-- ------------------------------+square :: Double -> Double+square x = x * x++stdnormal :: RandomGen g => Rand g Double+stdnormal = normal 0 1++stdnormals :: RandomGen g => Rand g [Double]+stdnormals = normals 0 1++normal :: RandomGen g => Double -> Double -> Rand g Double+normal mu sigma = do x <- getRandomR (0,1)+                     return (invcumnorm mu sigma x)++normals :: RandomGen g => Double -> Double -> Rand g [Double]+normals mu sigma = do x <- normal mu sigma+                      xs <- normals mu sigma+                      return (x : xs)++-- support+invcumnorm :: Double -> Double -> Double -> Double+invcumnorm mu sigma z = mu + bisect (cumnorm 0 sigma) (-limit*sigma) (limit*sigma) z++bisect :: (Double -> Double) -> Double -> Double -> Double -> Double+bisect f a b z = let c = (a+b)/2+                     cn = f c+                 in if abs (z - cn) < 10*epsilon || abs (a-b) < epsilon then c+                    else if cn > z then bisect f a c z+                         else bisect f c b z++cumnorm :: Double -> Double -> Double -> Double+cumnorm mu sigma x = 0.5*(1+erf((x-mu)/(sigma*sqrt 2)))++cumlognorm :: Double -> Double -> Double -> Double+cumlognorm mu sigma x = 0.5+0.5*erf ((log x-mu)/(sigma*sqrt 2))++epsilon, limit :: Double+epsilon = 0.0000000001+limit = 4.4++-- | Make a distribution wider by expanding (or contracting, if less than 1) +--   its stdev by some factor+worsen :: Double -> Distribution -> Distribution+worsen d (Normal mu sigma) = Normal mu (sigma*d)+worsen d (LogNormal mu sigma) = LogNormal mu (sigma*d)+worsen d (Uniform a b) = Uniform (a*(1-d)) (b*d) -- assumption alert?+worsen d (Empirical mu h ds) = Empirical mu (h*d) ds