2 {-# LANGUAGE OverloadedStrings #-}
3 {-# LANGUAGE BangPatterns #-}
24 -- , DataFrameMeshH5Path(..)
31 #if __GLASGOW_HASKELL__
< 710
32 import Control
.Applicative
((<$>), (<*>))
34 import Control
.Concurrent
.Async
(mapConcurrently
)
35 import Control
.Monad
(forM_
, forever
, zipWithM_)
36 import Control
.Monad
.IO.Class
(liftIO
)
37 import Control
.Monad
.Morph
(hoist
)
38 import Control
.Monad
.Trans
.State
.Strict
(StateT
, get
, put
)
39 import Data
.Array.Repa
(Shape
, DIM1
, size
)
40 import Data
.Attoparsec
.Text
(parseOnly
)
41 import qualified Data
.ByteString
.Char8
as Char8
(pack
)
42 import qualified Data
.List
as List
(intercalate
, lookup)
43 import Data
.Maybe (fromMaybe)
44 import Data
.Text
(Text
)
45 import qualified Data
.Text
as Text
(unlines, pack
, intercalate
)
46 import Data
.Text
.IO (readFile)
47 import Data
.Vector
.Storable
(concat, head)
48 import Numeric
.LinearAlgebra
(fromList
)
49 import Numeric
.Units
.Dimensional
.Prelude
(meter
, nano
, (/~
), (*~
))
50 import System
.Exit
( ExitCode( ExitSuccess
) )
51 import System
.FilePath ((</>), dropExtension
, takeFileName
, takeDirectory
)
52 import System
.Process
( system )
53 import Text
.Printf
( printf
)
72 import Pipes
.Prelude
(toListM
)
73 import Pipes
.Safe
( MonadSafe
(..), runSafeT
, bracket )
81 import Hkl
.PyFAI
.PoniExt
88 type OutputBaseDir
= FilePath
89 type PoniGenerator
= Pose
-> Int -> IO PoniExt
90 type SampleName
= String
92 data Threshold
= Threshold
Int
95 data XrdRefSource
= XrdRefNxs Nxs
Int
96 | XrdRefEdf
FilePath FilePath
99 data XRDRef
= XRDRef SampleName OutputBaseDir XrdRefSource
102 data XRDSample
= XRDSample SampleName OutputBaseDir
[XrdNxs
] -- ^ nxss
105 data XrdSource
= XrdSourceNxs Nxs
106 | XrdSourceEdf
[FilePath]
109 data XrdNxs
= XrdNxs DIM1 DIM1 Threshold XrdSource
deriving (Show)
111 data Nxs
= Nxs
FilePath NxEntry DataFrameH5Path
deriving (Show)
113 data DifTomoFrame sh
=
114 DifTomoFrame
{ difTomoFrameNxs
:: Nxs
-- ^ nexus of the current frame
115 , difTomoFrameIdx
:: Int -- ^ index of the current frame
116 , difTomoFrameEOF
:: Bool -- ^ is it the eof of the stream
117 , difTomoFrameGeometry
:: Geometry
-- ^ diffractometer geometry
118 , difTomoFramePoniExt
:: PoniExt
-- ^ the ref poniext
122 len
:: t
-> IO (Maybe Int)
123 row
:: t
-> Int -> IO (DifTomoFrame DIM1
)
125 data DataFrameH5Path
=
126 DataFrameH5Path
{ h5pImage
:: DataItem
127 , h5pGamma
:: DataItem
128 , h5pDelta
:: DataItem
129 , h5pWavelength
:: DataItem
133 DataFrameH5
{ h5nxs
:: Nxs
136 , h5wavelength
:: Dataset
137 , ponigen
:: PoniGenerator
140 instance Frame DataFrameH5
where
141 len d
= lenH5Dataspace
(h5delta d
)
145 let eof
= n
- 1 == idx
151 gamma
<- get_position
(h5gamma d
) 0
152 delta
<- get_position
(h5delta d
) idx
153 wavelength
<- get_position
(h5wavelength d
) 0
154 let source
= Source
(head wavelength
*~ nano meter
)
155 let positions
= concat [mu
, komega
, kappa
, kphi
, gamma
, delta
]
156 let geometry
= Geometry K6c source positions Nothing
158 m
<- geometryDetectorRotationGet geometry detector
159 poniext
<- ponigen d
(MyMatrix HklB m
) idx
160 return DifTomoFrame
{ difTomoFrameNxs
= nxs
'
161 , difTomoFrameIdx
= idx
162 , difTomoFrameEOF
= eof
163 , difTomoFrameGeometry
= geometry
164 , difTomoFramePoniExt
= poniext
167 frames
:: (Frame a
) => Pipe a
(DifTomoFrame DIM1
) IO ()
170 (Just n
) <- lift
$ len d
171 forM_
[0..n
-1] (\i
' -> do
175 frames
' :: (Frame a
) => [Int] -> Pipe a
(DifTomoFrame DIM1
) IO ()
182 -- {-# ANN module "HLint: ignore Use camelCase" #-}
185 -- import Graphics.Rendering.Chart.Easy
186 -- import Graphics.Rendering.Chart.Backend.Diagrams
188 -- plotPonies :: FilePath -> [PoniEntry] -> IO ()
189 -- plotPonies f entries = toFile def f $ do
190 -- layout_title .= "Ponies"
191 -- setColors [opaque blue]
192 -- let values = map extract entries
193 -- plot (line "am" [values [0,(0.5)..400]])
194 -- -- plot (points "am points" (signal [0,7..400]))
196 -- extract (PoniEntry _ _ (Length poni1) _ _ _ _ _ _) = poni1
200 getMEdf
:: FilePath -> IO (MyMatrix
Double)
203 let mnes
= map Text
.pack
["_mu", "_keta", "_kap", "_kphi", "nu", "del"]
204 let source
= Source
(edf
'Lambda edf
)
205 let positions
= fromList
$ map (extract edf
) mnes
206 let geometry
= Geometry K6c source positions Nothing
208 m
<- geometryDetectorRotationGet geometry detector
209 return $ MyMatrix HklB m
211 extract
:: Edf
-> Text
-> Double
212 extract
(Edf _ ms
) key
= fromMaybe 0.0 (List
.lookup key ms
)
214 poniFromFile
:: FilePath -> IO Poni
215 poniFromFile filename
= do
216 content
<- readFile filename
217 return $ case parseOnly poniP content
of
218 Left _
-> error $ "Can not parse the " ++ filename
++ " poni file"
221 getPoniExtRef
:: XRDRef
-> IO PoniExt
222 getPoniExtRef
(XRDRef _ output
(XrdRefNxs nxs
'@(Nxs f _ _
) idx
)) = do
223 poniExtRefs
<- withH5File f
$ \h5file
->
224 runSafeT
$ toListM
( withDataFrameH5 h5file nxs
' (gen output f
) yield
225 >-> hoist lift
(frames
' [idx
]))
226 return $ difTomoFramePoniExt
(Prelude
.last poniExtRefs
)
228 gen
:: FilePath -> FilePath -> MyMatrix
Double -> Int -> IO PoniExt
229 gen root nxs
'' m idx
' = do
230 poni
<- poniFromFile
$ root
</> scandir
++ printf
"_%02d.poni" idx
'
231 return $ PoniExt poni m
233 scandir
= takeFileName nxs
''
234 getPoniExtRef
(XRDRef _ _
(XrdRefEdf e p
)) = do
235 poni
<- poniFromFile p
237 return $ PoniExt poni m
239 integrate
:: PoniExt
-> XRDSample
-> IO ()
240 integrate ref
(XRDSample _ output nxss
) = do
241 _
<- mapConcurrently
(integrate
' ref output
) nxss
244 integrate
' :: PoniExt
-> OutputBaseDir
-> XrdNxs
-> IO ()
245 integrate
' ref output
(XrdNxs b _ t
(XrdSourceNxs nxs
'@(Nxs f _ _
))) = do
247 withH5File f
$ \h5file
->
248 runSafeT
$ runEffect
$
249 withDataFrameH5 h5file nxs
' (gen ref
) yield
250 >-> hoist lift
(frames
251 >-> savePonies
(pgen output f
)
255 gen
:: PoniExt
-> Pose
-> Int -> IO PoniExt
256 gen ref
' m _idx
= return $ setPose ref
' m
258 pgen
:: OutputBaseDir
-> FilePath -> Int -> FilePath
259 pgen o nxs
'' idx
= o
</> scandir
</> scandir
++ printf
"_%02d.poni" idx
261 scandir
= (dropExtension
. takeFileName
) nxs
''
263 createPy
:: (Shape sh
) => DIM1
-> Threshold
-> (DifTomoFrame
' sh
) -> (Text
, FilePath)
264 createPy b
(Threshold t
) (DifTomoFrame
' f poniPath
) = (script
, output
)
266 script
= Text
.unlines $
267 map Text
.pack
["#!/bin/env python"
270 , "from h5py import File"
271 , "from pyFAI import load"
273 , "PONIFILE = " ++ show p
274 , "NEXUSFILE = " ++ show nxs
'
275 , "IMAGEPATH = " ++ show i
'
276 , "IDX = " ++ show idx
277 , "N = " ++ show (size b
)
278 , "OUTPUT = " ++ show output
279 , "WAVELENGTH = " ++ show (w
/~ meter
)
280 , "THRESHOLD = " ++ show t
282 , "ai = load(PONIFILE)"
283 , "ai.wavelength = WAVELENGTH"
284 , "ai._empty = numpy.nan"
285 , "mask_det = ai.detector.mask"
286 , "mask_module = numpy.zeros_like(mask_det, dtype=bool)"
287 , "mask_module[0:50, :] = True"
288 , "mask_module[910:960, :] = True"
289 , "mask_module[:,0:50] = True"
290 , "mask_module[:,510:560] = True"
291 , "with File(NEXUSFILE, mode='r') as f:"
292 , " img = f[IMAGEPATH][IDX]"
293 , " mask = numpy.where(img > THRESHOLD, True, False)"
294 , " mask = numpy.logical_or(mask, mask_det)"
295 , " mask = numpy.logical_or(mask, mask_module)"
296 , " ai.integrate1d(img, N, filename=OUTPUT, unit=\"2th_deg\", error_model=\"poisson\", correctSolidAngle=False, method=\"lut\", mask=mask)"
298 p
= takeFileName poniPath
299 (Nxs nxs
' _ h5path
') = difTomoFrameNxs f
300 (DataItem i
' _
) = h5pImage h5path
'
301 idx
= difTomoFrameIdx f
302 output
= (dropExtension
. takeFileName
) poniPath
++ ".dat"
303 (Geometry _
(Source w
) _ _
) = difTomoFrameGeometry f
307 withDataFrameH5
:: (MonadSafe m
) => File
-> Nxs
-> PoniGenerator
-> (DataFrameH5
-> m r
) -> m r
308 withDataFrameH5 h nxs
'@(Nxs _ _ d
) gen
= bracket (liftIO before
) (liftIO
. after
)
310 -- before :: File -> DataFrameH5Path -> m DataFrameH5
311 before
:: IO DataFrameH5
314 <*> openDataset
' h
(h5pGamma d
)
315 <*> openDataset
' h
(h5pDelta d
)
316 <*> openDataset
' h
(h5pWavelength d
)
319 -- after :: DataFrameH5 -> IO ()
321 closeDataset
(h5gamma d
')
322 closeDataset
(h5delta d
')
323 closeDataset
(h5wavelength d
')
325 -- openDataset' :: File -> DataItem -> IO Dataset
326 openDataset
' hid
(DataItem name _
) = openDataset hid
(Char8
.pack name
) Nothing
328 data DifTomoFrame
' sh
= DifTomoFrame
' { difTomoFrame
'DifTomoFrame
:: DifTomoFrame sh
329 , difTomoFrame
'PoniPath
:: FilePath
332 savePonies
:: (Shape sh
) => (Int -> FilePath) -> Pipe
(DifTomoFrame sh
) (DifTomoFrame
' sh
) IO ()
333 savePonies g
= forever
$ do
335 let filename
= g
(difTomoFrameIdx f
)
336 let (PoniExt p _
) = difTomoFramePoniExt f
337 lift
$ saveScript
(poniToText p
) filename
338 yield
$ DifTomoFrame
' { difTomoFrame
'DifTomoFrame
= f
339 , difTomoFrame
'PoniPath
= filename
342 data DifTomoFrame
'' sh
= DifTomoFrame
'' { difTomoFrame
''DifTomoFrame
' :: DifTomoFrame
' sh
343 , difTomoFrame
''PySCript
:: Text
344 , difTomoFrame
''PySCriptPath
:: FilePath
345 , difTomoFrame
''DataPath
:: FilePath
348 savePy
:: (Shape sh
) => DIM1
-> Threshold
-> Pipe
(DifTomoFrame
' sh
) (DifTomoFrame
'' sh
) IO ()
349 savePy b t
= forever
$ do
350 f
@(DifTomoFrame
' _difTomoFrame poniPath
) <- await
351 let directory
= takeDirectory poniPath
352 let scriptPath
= dropExtension poniPath
++ ".py"
353 let (script
, dataPath
) = createPy b t f
354 lift
$ saveScript script scriptPath
355 ExitSuccess
<- lift
$ system (unwords ["cd ", directory
, "&&", "python", scriptPath
])
356 yield
$ DifTomoFrame
'' { difTomoFrame
''DifTomoFrame
' = f
357 , difTomoFrame
''PySCript
= script
358 , difTomoFrame
''PySCriptPath
= scriptPath
359 , difTomoFrame
''DataPath
= dataPath
362 saveGnuplot
' :: (Shape sh
) => Consumer
(DifTomoFrame
'' sh
) (StateT
[FilePath] IO) r
363 saveGnuplot
' = forever
$ do
365 (DifTomoFrame
'' (DifTomoFrame
' _ poniPath
) _ _ dataPath
) <- await
366 let directory
= takeDirectory poniPath
367 let filename
= directory
</> "plot.gnuplot"
368 lift
. lift
$ saveScript
(new_content curves
) filename
369 lift
$ put
$! (curves
++ [dataPath
])
371 new_content
:: [FilePath] -> Text
372 new_content cs
= Text
.unlines (lines' cs
)
374 lines' :: [FilePath] -> [Text
]
375 lines' cs
= ["plot \\"]
376 ++ [Text
.intercalate
",\\\n" [ Text
.pack
(show (takeFileName c
) ++ " u 1:2 w l") | c
<- cs
]]
379 saveGnuplot
:: (Shape sh
) => Consumer
(DifTomoFrame
'' sh
) IO r
380 saveGnuplot
= evalStateP
[] saveGnuplot
'
382 -- | PyFAI MultiGeometry
384 integrateMulti
:: PoniExt
-> XRDSample
-> IO ()
385 integrateMulti ref
(XRDSample _ output nxss
) =
386 mapM_ (integrateMulti
' ref output
) nxss
388 integrateMulti
' :: PoniExt
-> OutputBaseDir
-> XrdNxs
-> IO ()
389 integrateMulti
' ref output
(XrdNxs _ mb t
(XrdSourceNxs nxs
'@(Nxs f _ _
))) = do
391 withH5File f
$ \h5file
->
392 runSafeT
$ runEffect
$
393 withDataFrameH5 h5file nxs
' (gen ref
) yield
394 >-> hoist lift
(frames
395 >-> savePonies
(pgen output f
)
396 >-> saveMultiGeometry mb t
)
398 gen
:: PoniExt
-> Pose
-> Int -> IO PoniExt
399 gen ref
' m _idx
= return $ setPose ref
' m
401 pgen
:: OutputBaseDir
-> FilePath -> Int -> FilePath
402 pgen o nxs
'' idx
= o
</> scandir
</> scandir
++ printf
"_%02d.poni" idx
404 scandir
= (dropExtension
. takeFileName
) nxs
''
405 integrateMulti
' ref output
(XrdNxs b _ t
(XrdSourceEdf fs
)) = do
406 -- generate all the ponies
407 zipWithM_ go fs ponies
409 -- generate the multi.py python script
410 let script
= createMultiPyEdf b t fs ponies
(output
</> "multi.dat")
411 saveScript script
(output
</> "multi.py")
413 ponies
= [(output
</> (dropExtension
. takeFileName
) f
++ ".poni") | f
<- fs
]
415 go
:: FilePath -> FilePath -> IO ()
418 let (PoniExt p _
) = setPose ref m
419 saveScript
(poniToText p
) o
421 createMultiPy
:: (Shape sh
) => DIM1
-> Threshold
-> (DifTomoFrame
' sh
) -> [FilePath] -> (Text
, FilePath)
422 createMultiPy b
(Threshold t
) (DifTomoFrame
' f _
) ponies
= (script
, output
)
424 script
= Text
.unlines $
425 map Text
.pack
["#!/bin/env python"
428 , "from h5py import File"
429 , "from pyFAI.multi_geometry import MultiGeometry"
431 , "NEXUSFILE = " ++ show nxs
'
432 , "IMAGEPATH = " ++ show i
'
433 , "BINS = " ++ show (size b
)
434 , "OUTPUT = " ++ show output
435 , "WAVELENGTH = " ++ show (w
/~ meter
)
436 , "THRESHOLD = " ++ show t
438 , "# Load all images"
439 , "PONIES = [" ++ (List
.intercalate
",\n" (map show ponies
)) ++ "]"
441 , "# Read all the images"
442 , "with File(NEXUSFILE, mode='r') as f:"
443 , " imgs = f[IMAGEPATH][:]"
445 , "# Compute the mask"
446 , "mask = numpy.zeros_like(imgs[0], dtype=bool)"
448 , " mask_t = numpy.where(img > THRESHOLD, True, False)"
449 , " mask = numpy.logical_or(mask, mask_t)"
451 , "# Integration multi-geometry 1D"
452 , "mg = MultiGeometry(PONIES, unit=\"2th_deg\", radial_range=(0,80))"
453 , "p = mg.integrate1d(imgs, BINS, lst_mask=mask)"
456 , "numpy.savetxt(OUTPUT, numpy.array(p).T)"
458 (Nxs nxs
' _ h5path
') = difTomoFrameNxs f
459 (DataItem i
' _
) = h5pImage h5path
'
461 (Geometry _
(Source w
) _ _
) = difTomoFrameGeometry f
463 createMultiPyEdf
:: DIM1
-> Threshold
-> [FilePath] -> [FilePath] -> FilePath -> Text
464 createMultiPyEdf b
(Threshold t
) edfs ponies output
= script
466 script
= Text
.unlines $
467 map Text
.pack
["#!/bin/env python"
470 , "from fabio import open"
471 , "from pyFAI.multi_geometry import MultiGeometry"
473 , "EDFS = [" ++ (List
.intercalate
",\n" (map show edfs
)) ++ "]"
474 , "PONIES = [" ++ (List
.intercalate
",\n" (map show ponies
)) ++ "]"
475 , "BINS = " ++ show (size b
)
476 , "OUTPUT = " ++ show output
477 , "THRESHOLD = " ++ show t
479 , "# Read all the images"
480 , "imgs = [open(edf).data for edf in EDFS]"
482 , "# Compute the mask"
483 , "mask = numpy.zeros_like(imgs[0], dtype=bool)"
485 , " mask_t = numpy.where(img > THRESHOLD, True, False)"
486 , " mask = numpy.logical_or(mask, mask_t)"
488 , "# Integration multi-geometry 1D"
489 , "mg = MultiGeometry(PONIES, unit=\"2th_deg\", radial_range=(0,80))"
490 , "p = mg.integrate1d(imgs, BINS, lst_mask=mask)"
493 , "numpy.savetxt(OUTPUT, numpy.array(p).T)"
496 saveMulti
' :: (Shape sh
) => DIM1
-> Threshold
-> Consumer
(DifTomoFrame
' sh
) (StateT
[FilePath] IO) r
497 saveMulti
' b t
= forever
$ do
499 f
'@(DifTomoFrame
' f poniPath
) <- await
500 let directory
= takeDirectory poniPath
501 let filename
= directory
</> "multi.py"
502 let (script
, _
) = createMultiPy b t f
' ponies
503 lift
. lift
$ saveScript script filename
504 lift
. lift
$ go directory filename
(difTomoFrameEOF f
)
505 lift
$ put
$! (ponies
++ [poniPath
])
507 go
:: FilePath -> FilePath -> Bool -> IO ()
509 ExitSuccess
<- system (unwords ["cd ", d
, "&&", "python", s
])
511 go _ _
False = return ()
513 saveMultiGeometry
:: (Shape sh
) => DIM1
-> Threshold
-> Consumer
(DifTomoFrame
' sh
) IO r
514 saveMultiGeometry b t
= evalStateP
[] (saveMulti
' b t
)
518 -- data DataFrameMeshH5Path =
519 -- DataFrameMeshH5Path { dataFrameMeshH5Path'Image :: DataItem
520 -- , dataFrameMeshH5Path'MeshX :: DataItem
521 -- , dataFrameMeshH5Path'MeshY :: DataItem
522 -- , dataFrameMeshH5Path'Gamma :: DataItem
523 -- , dataFrameMeshH5Path'Delta :: DataItem
524 -- , dataFrameMeshH5Path'Wavelength :: DataItem
527 -- data DataFrameH5' a =
528 -- DataFrameH5' { dataFrameH5'Nxs' :: Nxs' a
529 -- , dataFrameH5'MeshX :: Dataset
530 -- , dataFrameH5'MeshY :: Dataset
531 -- , dataFrameH5'Gamma :: Dataset
532 -- , dataFrameH5'Delta :: Dataset
533 -- , dataFrameH5'Wavelength :: Dataset
534 -- , dataFrameH5'Ponigen :: PoniGenerator
537 -- data XRDSample' a = XRDSample' SampleName OutputBaseDir [XrdNxs' a] -- ^ nxss
539 -- data XrdNxs' a = XrdNxs' DIM1 DIM1 Threshold (Nxs' a) deriving (Show)
541 -- data Nxs' a = Nxs' FilePath NxEntry a deriving (Show)
543 -- class DataSource t where
544 -- withDataSource :: (MonadSafe m) => File -> Nxs' t -> PoniGenerator -> (DataFrameH5' t -> m r) -> m r
546 -- data DifTomoFrameND sh =
547 -- DifTomoFrame2D { difTomoFrameND'Nxs :: Nxs -- ^ nexus of the current frame
548 -- , difTomoFrameND'Idxs :: sh -- ^ current index in the array
549 -- , difTomoFrameND'EOF :: Bool -- ^ is it the eof of the stream
550 -- , difTomoFrameND'Geometry :: Geometry -- ^ diffractometer geometry
551 -- , difTomoFrameND'PoniExt :: PoniExt -- ^ the ref poniext
554 -- class FrameND t where
555 -- lenND :: t -> IO (Maybe Int)
556 -- rowND :: Shape sh => t -> sh -> IO (DifTomoFrameND sh)
558 -- framesND :: (Frame a, Shape sh) => Pipe a (DifTomoFrameND sh) IO ()
561 -- (Just n) <- lift $ lenND d
562 -- forM_ [0..n-1] (\i' -> do
563 -- f <- lift $ rowND d idx
566 -- instance DataSource DataFrameMeshH5Path where
567 -- withDataSource h nxs'@(Nxs' _ _ d) gen = bracket (liftIO before) (liftIO . after)
569 -- -- before :: File -> DataFrameH5Path -> m DataFrameH5
570 -- before :: IO (DataFrameH5' DataFrameMeshH5Path)
571 -- before = DataFrameH5'
573 -- <*> openDataset' h (dataFrameMeshH5Path'MeshX d)
574 -- <*> openDataset' h (dataFrameMeshH5Path'MeshY d)
575 -- <*> openDataset' h (dataFrameMeshH5Path'Gamma d)
576 -- <*> openDataset' h (dataFrameMeshH5Path'Delta d)
577 -- <*> openDataset' h (dataFrameMeshH5Path'Wavelength d)
580 -- after :: DataFrameH5' DataFrameMeshH5Path -> IO ()
582 -- closeDataset (dataFrameH5'MeshX d')
583 -- closeDataset (dataFrameH5'MeshY d')
584 -- closeDataset (dataFrameH5'Gamma d')
585 -- closeDataset (dataFrameH5'Delta d')
586 -- closeDataset (dataFrameH5'Wavelength d')
588 -- openDataset' :: File -> DataItem -> IO Dataset
589 -- openDataset' hid (DataItem name _) = openDataset hid (Char8.pack name) Nothing
592 -- integrateMesh :: (DataSource a) => PoniExt -> XRDSample' a -> IO ()
593 -- integrateMesh ref (XRDSample' _ output nxss) =
594 -- mapM_ (integrateMesh' ref output) nxss
596 -- integrateMesh' :: (DataSource a) => PoniExt -> OutputBaseDir -> XrdNxs' a -> IO ()
597 -- integrateMesh' ref output (XrdNxs' _ mb t nxs'@(Nxs' f _ _)) = do
599 -- withH5File f $ \h5file ->
600 -- runSafeT $ runEffect $
601 -- withDataSource h5file nxs' (gen ref) yield
602 -- >-> hoist lift (framesND)
603 -- -- >-> savePonies (pgen output f)
604 -- -- >-> saveMultiGeometry mb t)
606 -- gen :: PoniExt -> Pose -> Int -> IO PoniExt
607 -- gen ref' m _idx = return $ setPose ref' m
609 -- pgen :: OutputBaseDir -> FilePath -> Int -> FilePath
610 -- pgen o nxs'' idx = o </> scandir </> scandir ++ printf "_%02d.poni" idx
612 -- scandir = (dropExtension . takeFileName) nxs''