2014年3月13日星期四

Sextractor【2】MAP_WEIGHT and HOW it works.

The parameters are only breifly mentioned in the manual of Sextractor. However, you should be careful if you really want to change the paramters.

(1) Choose a right type of WEIGHT_TYPE
MAP_RMS is the most safe way to use weight image. It is the map showing the rms (you can call it error or variance.). Sextractor will select pixels with value higher than threshold*rms as a source (the value I mentioned here is background subtracted and smoothed). The error are also calculated based on the counts of object and the rms value.
MAP_WEIGHT is not the same as define in Multidrizzle or somewhere else. It can be a flat map, a exposure map. The Sextractor will convert it to rms map whatever your input is. What is most important and often missed is that it will scale the weight image according to the rms measure from the background. I think it just multiplies the rms value which is show in the output78.5964 in the following output.
(M+D) Background: 0          RMS: 78.5964    / Threshold: 78.5964 
So the weight image is used to tell which part of the image is more important than other parts. The arbitrary value is meaningless. The program will scale it and only use the related values!
MAP_VAR In the manual, "The data are converted to variance units (by defi- nition variance 1/weight), and scaled as for MAP VAR" However,  I have not used it! 
BACKGROUND The program will created a rms map based on the background measure my the program. This method are really not good. If you want to do real science, you should not choose it.
None Then every part of the image will be treated as the same weight, which means the regions which are not observed and are set to value 0 will also be treated as other region. The errors of objects in the corner will also be under-estimated. Notice that even you have set the MAP_WEIGHT, the overall errors are also probably under-estimated, because the rms is calculate from the image and the information of read noises and dark noises are missed.

(2) Detect and measure with different weight map.
People usually know that in dual model, we can define the MAP_TYPE to the detection image and measurement image separately. We can also set this in one image run.
"

All the weighting options listed in §7.1 can be applied separately to detection and measurement images (§3), — even if some combinations may not always make sense. For instance, the following set of configuration lines:
WEIGHT_IMAGE rms.fits,weight.fits 
WEIGHT_TYPE MAP_RMS,MAP_WEIGHT
will load the FITS file rms.fits and use it as an RMS map for adjusting the detection threshold and CLEANing, while the weight.fits weight map will only be used for scaling the error estimates on measurements. This can be done in single- as well as in dual-image mode (§3). WEIGHT IMAGEs can be ignored for BACKGROUND WEIGHT TYPEs. 
"

(3) Created you own weight and rms image.
The details will come later, you can check my other blog and also give me an email.




   

2014年3月12日星期三

PYTHON编程技巧总结【1】

Commands in this section:

name_len = map(len, ["hao", "chen", "coolshell"])
map(lambda x: x * x, range(9))
ps auwwx | awk '{print $2}' | sort -n | xargs echo


函数式编程

函数式编程的理念:把函数当成变量来用,关注于描述问题而不是怎么实现,这样可以让代码更易读。函数式编程的准则:不依赖于外部的数据,而且也不改变外部数据的值,而是返回一个新的值给你


Map & Reduce


在函数式编程中,我们不应该用循环迭代的方式,我们应该用更为高级的方法,如下所示的Python代码
1
2
3
name_len = map(len, ["hao", "chen", "coolshell"])
print name_len
# 输出 [3, 4, 9]
对于map我们别忘了lambda表达式:你可以简单地理解为这是一个inline的匿名函数。下面的lambda表达式相当于:def func(x): return x*x
1
2
3
squares = map(lambda x: x * x, range(9))
print squares
# 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64]
我们再来看看reduce怎么玩?(下面的lambda表达式中有两个参数,也就是说每次从列表中取两个值,计算结果后把这个值再放回去,下面的表达式相当于:((((1+2)+3)+4)+5) )
1
2
print reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
# 输出 15
Python中的除了map和reduce外,还有一些别的如filter, find, all, any的函数做辅助(其它函数式的语言也有),可以让你的代码更简洁,更易读。 我们再来看一个比较复杂的例子:

Declarative Programming vs Imperative Programming

前面提到过多次的函数式编程关注的是:describe what to do, rather than how to do it. 于是,我们把以前的过程式的编程范式叫做 Imperative Programming – 指令式编程,而把函数式的这种范式叫做 Declarative Programming – 声明式编程。
下面我们看一下相关的示例(本示例来自这篇文章 )。
比如,我们有3辆车比赛,简单起见,我们分别给这3辆车有70%的概率可以往前走一步,一共有5次机会,我们打出每一次这3辆车的前行状态。
对于Imperative Programming来说,代码如下(Python):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from random import random
time = 5
car_positions = [1, 1, 1]
while time:
    # decrease time
    time -= 1
    print ''
    for i in range(len(car_positions)):
        # move car
        if random() > 0.3:
            car_positions[i] += 1
        # draw car
        print '-' * car_positions[i]
我们可以把这个两重循环变成一些函数模块,这样有利于我们更容易地阅读代码:
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
from random import random
def move_cars():
    for i, _ in enumerate(car_positions):
        if random() > 0.3:
            car_positions[i] += 1
def draw_car(car_position):
    print '-' * car_position
def run_step_of_race():
    global time
    time -= 1
    move_cars()
def draw():
    print ''
    for car_position in car_positions:
        draw_car(car_position)
time = 5
car_positions = [1, 1, 1]
while time:
    run_step_of_race()
    draw()
上面的代码,我们可以从主循环开始,我们可以很清楚地看到程序的主干,因为我们把程序的逻辑分成了几个函数,这样一来,我们的代码逻辑也会变得几个小碎片,于是我们读代码时要考虑的上下文就少了很多,阅读代码也会更容易。不像第一个示例,如果没有注释和说明,你还是需要花些时间理解一下。而把代码逻辑封装成了函数后,我们就相当于给每个相对独立的程序逻辑取了个名字,于是代码成了自解释的
但是,你会发现,封装成函数后,这些函数都会依赖于共享的变量来同步其状态。于是,我们在读代码的过程时,每当我们进入到函数里,一量读到访问了一个外部的变量,我们马上要去查看这个变量的上下文,然后还要在大脑里推演这个变量的状态, 我们才知道程序的真正逻辑。也就是说,这些函数间必需知道其它函数是怎么修改它们之间的共享变量的,所以,这些函数是有状态的
我们知道,有状态并不是一件很好的事情,无论是对代码重用,还是对代码的并行来说,都是有副作用的。因此,我们要想个方法把这些状态搞掉,于是出现了我们的 Functional Programming 的编程范式。下面,我们来看看函数式的方式应该怎么写?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from random import random
def move_cars(car_positions):
    return map(lambda x: x + 1 if random() > 0.3 else x,
               car_positions)
def output_car(car_position):
    return '-' * car_position
def run_step_of_race(state):
    return {'time': state['time'] - 1,
            'car_positions': move_cars(state['car_positions'])}
def draw(state):
    print ''
    print '\n'.join(map(output_car, state['car_positions']))
def race(state):
    draw(state)
    if state['time']:
        race(run_step_of_race(state))
race({'time': 5,
      'car_positions': [1, 1, 1]})
上面的代码依然把程序的逻辑分成了函数,不过这些函数都是functional的。因为它们有三个症状:
1)它们之间没有共享的变量。
2)函数间通过参数和返回值来传递数据。
3)在函数里没有临时变量。
我们还可以看到,for循环被递归取代了(见race函数)—— 递归是函数式编程中带用到的技术,正如前面所说的,递归的本质就是描述问题是什么。

Pipeline

pipeline 管道借鉴于Unix Shell的管道操作——把若干个命令串起来,前面命令的输出成为后面命令的输入,如此完成一个流式计算。(注:管道绝对是一个伟大的发明,他的设哲学就是KISS – 让每个功能就做一件事,并把这件事做到极致,软件或程序的拼装会变得更为简单和直观。这个设计理念影响非常深远,包括今天的Web Service,云计算,以及大数据的流式计算等等)
比如,我们如下的shell命令:
1
ps auwwx | awk '{print $2}' | sort -n | xargs echo
如果我们抽象成函数式的语言,就像下面这样:
1
xargs(  echo, sort(n, awk('print $2', ps(auwwx)))  )
也可以类似下面这个样子:
1
pids = for_each(result, [ps_auwwx, awk_p2, sort_n, xargs_echo])
好了,让我们来看看函数式编程的Pipeline怎么玩?
我们先来看一个如下的程序,这个程序的process()有三个步骤:
1)找出偶数。
2)乘以3
3)转成字符串返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def process(num):
    # filter out non-evens
    if num % 2 != 0:
        return
    num = num * 3
    num = 'The Number: %s' % num
    return num
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for num in nums:
    print process(num)
# 输出:
# None
# The Number: 6
# None
# The Number: 12
# None
# The Number: 18
# None
# The Number: 24
# None
# The Number: 30
我们可以看到,输出的并不够完美,另外,代码阅读上如果没有注释,你也会比较晕。下面,我们来看看函数式的pipeline(第一种方式)应该怎么写?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def even_filter(nums):
    for num in nums:
        if num % 2 == 0:
            yield num
def multiply_by_three(nums):
    for num in nums:
        yield num * 3
def convert_to_string(nums):
    for num in nums:
        yield 'The Number: %s' % num
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pipeline = convert_to_string(multiply_by_three(even_filter(nums)))
for num in pipeline:
    print num
# 输出:
# The Number: 6
# The Number: 12
# The Number: 18
# The Number: 24
# The Number: 30
我们动用了Python的关键字 yield,这个关键字主要是返回一个Generator,yield 是一个类似 return 的关键字,只是这个函数返回的是个Generator-生成器。所谓生成器的意思是,yield返回的是一个可迭代的对象,并没有真正的执行函数。也就是说,只有其返回的迭代对象被真正迭代时,yield函数才会正真的运行,运行到yield语句时就会停住,然后等下一次的迭代。(这个是个比较诡异的关键字)这就是lazy evluation。
好了,根据前面的原则——“使用Map & Reduce,不要使用循环”,那我们用比较纯朴的Map & Reduce吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def even_filter(nums):
    return filter(lambda x: x%2==0, nums)
def multiply_by_three(nums):
    return map(lambda x: x*3, nums)
def convert_to_string(nums):
    return map(lambda x: 'The Number: %s' % x,  nums)
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pipeline = convert_to_string(
               multiply_by_three(
                   even_filter(nums)
               )
            )
for num in pipeline:
    print num
但是他们的代码需要嵌套使用函数,这个有点不爽,如果我们能像下面这个样子就好了(第二种方式)。
1
2
3
pipeline_func(nums, [even_filter,
                     multiply_by_three,
                     convert_to_string])
那么,pipeline_func 实现如下:
1
2
3
4
def pipeline_func(data, fns):
    return reduce(lambda a, x: x(a),
                  fns,
                  data)
好了,在读过这么多的程序后,你可以回头看一下这篇文章的开头对函数式编程的描述,可能你就更有感觉了。
最后,我希望这篇浅显易懂的文章能让你感受到函数式编程的思想,就像OO编程,泛型编程,过程式编程一样,我们不用太纠结是不是我们的程序就是OO,就是functional的,我们重要的品味其中的味道

参考

补充:评论中redraiment这个评论大家也可以读一读。
感谢谢网友S142857 提供的shell风格的python pipeline:
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
class Pipe(object):
    def __init__(self, func):
        self.func = func
    def __ror__(self, other):
        def generator():
            for obj in other:
                if obj is not None:
                    yield self.func(obj)
        return generator()
@Pipe
def even_filter(num):
    return num if num % 2 == 0 else None
@Pipe
def multiply_by_three(num):
    return num*3
@Pipe
def convert_to_string(num):
    return 'The Number: %s' % num
@Pipe
def echo(item):
    print item
    return item
def force(sqs):
    for item in sqs: pass
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
force(nums | even_filter | multiply_by_three | convert_to_string | echo)
(全文完)
(转载本站文章请注明作者和出处 酷 壳 – CoolShell.cn ,请勿用于任何商业用途)
——=== 访问 酷壳404页面 寻找遗失儿童。 ===——