File: fiera_config.cpp

package info (click to toggle)
cpl-plugin-vimos 3.2.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 23,188 kB
  • sloc: ansic: 169,153; cpp: 14,555; sh: 4,250; python: 1,423; makefile: 899; perl: 10
file content (265 lines) | stat: -rw-r--r-- 10,343 bytes parent folder | download | duplicates (7)
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*
 * This file is part of the FORS Data Reduction Pipeline
 * Copyright (C) 2002-2010 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * fiera_ccd.cpp
 *
 *  Created on: 2013 11 25
 *      Author: cgarcia
 */

#include <cpl.h>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include "fiera_config.h"

namespace mosca 
{

fiera_config::fiera_config(const cpl_propertylist * header)
{
    if(header == NULL)
        std::invalid_argument("empty header");
    
    char * keyname;
    size_t n_ports = 1;

    if (cpl_propertylist_has(header, "ESO DET OUTPUTS"))
        n_ports = cpl_propertylist_get_int(header, "ESO DET OUTPUTS");

    if(n_ports !=1 && n_ports !=4)
        std::invalid_argument("Setup nor supported: Fiera detectors with "
                "only 1 or 4 ports are supported");

    //Binning 
    m_binning_factor_x = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX"); 
    m_binning_factor_y = cpl_propertylist_get_int(header, "ESO DET WIN1 BINY");
    
    //Pixel size
    m_pixel_size = cpl_propertylist_get_double(header, "ESO DET CHIP1 PSZX");

    //Chip name
    m_chip_id = 
         std::string(cpl_propertylist_get_string(header, "ESO DET CHIP1 ID"));

    //Chip dimensions
    //int det_nx = 
    //        cpl_propertylist_get_int(header, "ESO DET CHIP1 NX");
    //int det_ny = 
    //        cpl_propertylist_get_int(header, "ESO DET CHIP1 NY");

    //Image dimensions
    int ima_nx = 
            cpl_propertylist_get_int(header, "NAXIS1");
    int ima_ny = 
            cpl_propertylist_get_int(header, "NAXIS2");

    //Relative positions of the ports readouts with respect to the whole chip
    std::vector<int> port_xpos(n_ports);
    std::vector<int> port_ypos(n_ports);
    for(size_t i = 0; i < n_ports; i++) 
    {
        keyname = cpl_sprintf("ESO DET OUT%zu X", i+1);
        port_xpos[i] = 
            cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu Y", i+1);
        port_ypos[i] = 
            cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
    }
    //This is the left lower corner of the final image with respect to the
    //whole chip
    int min_port_xpos = *std::min_element(port_xpos.begin(), port_xpos.end());
    int min_port_ypos = *std::min_element(port_ypos.begin(), port_ypos.end());
    
    //Loop on the ports to get their configuration
    for(size_t i = 0; i < n_ports; i++)
    {
        keyname = cpl_sprintf("ESO DET OUT%zu GAIN", i+1);
        double nom_gain = 
            cpl_propertylist_get_double(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu RON", i+1);
        double nom_ron = 
            cpl_propertylist_get_double(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu NX", i+1);
        
        int port_nx = 
            cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu NY", i+1);
        int port_ny = 
            cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu PRSCX", i+1);
        int pre_x= 
            cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu PRSCY", i+1);
        int pre_y = 0;
        if (cpl_propertylist_has(header, keyname))
            pre_y = cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu OVSCX", i+1);
        int ovs_x= 
            cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
        keyname = cpl_sprintf("ESO DET OUT%zu OVSCY", i+1);
        int ovs_y = 0; 
        if (cpl_propertylist_has(header, keyname))
            ovs_y = cpl_propertylist_get_int(header, keyname);
        cpl_free(keyname);
        
        if(pre_x != 0 && pre_y !=0)
            std::invalid_argument("Two prescan regions are not supported");
        if(ovs_x != 0 && ovs_y !=0)
            std::invalid_argument("Two overscan regions are not supported");
        
        //Get the port offset with respect to the final image
        int port_off_x;
        if(port_xpos[i] == 1)
            port_off_x = port_xpos[i] - min_port_xpos;
        else 
            port_off_x = ima_nx - port_nx - pre_x - ovs_x;

        int port_off_y;
        if(port_ypos[i] == 1)
            port_off_y = port_ypos[i] - min_port_ypos;
        else 
            port_off_y = ima_ny - port_ny - pre_y - ovs_y;
        
        //Computing Prescan region
        rect_region prescan_reg;
        if(pre_x != 0) 
        {
            //Prescan is before any other real pixel
            if(port_xpos[i] == 1)
                prescan_reg = rect_region(port_off_x + 0, 
                                          port_off_y + 0, 
                                          port_off_x + pre_x - 1, 
                                          port_off_y + port_ny - 1);
            //Prescan is after other real pixels because the port is read
            //opposite to the normal direction
            else
                prescan_reg = rect_region(port_off_x + port_nx + ovs_x, 
                                          port_off_y + 0, 
                                          port_off_x + port_nx + pre_x + ovs_x - 1, 
                                          port_off_y + port_ny - 1);
        }
        
        if(pre_y != 0)
        {
            if(port_ypos[i] == 1)
                prescan_reg = rect_region(port_off_x + 0, 
                                          port_off_y + 0, 
                                          port_off_x + port_nx - 1, 
                                          port_off_y + pre_y - 1);
            else
                prescan_reg = rect_region(port_off_x + 0,
                                          port_off_y + port_ny + ovs_y, 
                                          port_off_x + port_nx - 1, 
                                          port_off_y + port_ny + pre_y + ovs_y - 1); 
        }

        rect_region overscan_reg;
        if(ovs_x != 0)
        {
            //Overscan is at the end of any real pixel. The image might
            //also contain prescan, so this has to be taken into account
            if(port_xpos[i] == 1)
                overscan_reg = rect_region(port_off_x + port_nx + pre_x, 
                                           port_off_y + 0, 
                                           port_off_x + port_nx + pre_x + ovs_x - 1, 
                                           port_off_y + port_ny - 1);
            else
                overscan_reg = rect_region(port_off_x + 0, 
                                           port_off_y + 0, 
                                           port_off_x + pre_x - 1, 
                                           port_off_y + port_ny - 1);
        }
        
        if(ovs_y != 0)
        {
            if(port_ypos[i] == 1)
                overscan_reg = rect_region(port_off_x + 0,
                                           port_off_y + port_ny + pre_y, 
                                           port_off_x + port_nx - 1,
                                           port_off_y + port_ny + pre_y + ovs_y - 1);
            else 
                overscan_reg = rect_region(port_off_x + 0, 
                                           port_off_y + 0, 
                                           port_off_x + port_nx - 1,
                                           port_off_y + pre_y - 1);
        }

        rect_region validpix_reg;
        if(port_ypos[i] == 1)
            if(port_xpos[i] == 1)
                validpix_reg = rect_region(port_off_x + pre_x, 
                                           port_off_y + pre_y, 
                                           port_off_x + port_nx + pre_x - 1, 
                                           port_off_y + port_ny + pre_y - 1); 
            else
                validpix_reg = rect_region(port_off_x + ovs_x, 
                                           port_off_y + pre_y, 
                                           port_off_x + port_nx + ovs_x - 1, 
                                           port_off_y + port_ny + pre_y - 1); 
        else
            if(port_xpos[i] == 1)
                validpix_reg = rect_region(port_off_x + pre_x, 
                                           port_off_y + ovs_y, 
                                           port_off_x + port_nx + pre_x - 1, 
                                           port_off_y + port_ny + ovs_y - 1); 
            else
                validpix_reg = rect_region(port_off_x + ovs_x, 
                                           port_off_y + ovs_y, 
                                           port_off_x + port_nx + ovs_x - 1, 
                                           port_off_y + port_ny + ovs_y - 1); 
                
        //The convention for the regions is to start from 0 for the first pixel.
        port_config config;
        config.nominal_gain    = nom_gain;
        config.nominal_ron     = nom_ron;
        config.computed_gain   = 0.;
        config.computed_ron    = 0.;
        config.overscan_region = overscan_reg;
        config.prescan_region  = prescan_reg;
        config.validpix_region = validpix_reg;
        
        if(validpix_reg.is_empty())
            std::invalid_argument("Port with empty valid pixel area");
        
        //Add to the port configurations
        m_port_configs.push_back(config); 
    }
    
}

fiera_config::fiera_config()
{
}

fiera_config::~fiera_config()
{
}

} /* namespace mosca */