func secondPassTHERMO(nc *lib.Nc, m *config.Map, cfg toml.Configtoml, files []string, optDebug *bool) {

	regdata := regexp.MustCompile(cfg.Thecsas.Data)

	fmt.Fprintf(lib.Echo, "Second pass ...\n")

	// initialize profile
	var nbProfile int = 0

	// loop over each files passed throw command line
	for _, file := range files {
		var line int = 0

		fid, err := os.Open(file)
		if err != nil {
			log.Fatal(err)
		}
		defer fid.Close()
		// fmt.Printf("Read %s\n", file)
		// increment slice index
		Profile := GetProfileNumber(nc, nbProfile)
		nc.Variables_1D["PROFILE"] = append(nc.Variables_1D["PROFILE"].([]float64), Profile)
		scanner := bufio.NewScanner(fid)
		for scanner.Scan() {
			str := scanner.Text()
			match := regdata.MatchString(str)
			if match {
				// fill map data with information contain in read line str
				DecodeData(nc, m, str, Profile, file, line)
				// fill 2D slice
				for _, key := range m.Hdr {
					if key != "PRFL" {
						//fmt.Println("Line: ", line, "key: ", key, " data: ", m.Data[key])
						lib.SetData(nc.Variables_2D[key], nbProfile, line, config.GetData(m.Data[key]))
					}
				}

				line++
			}

		}

		if err := scanner.Err(); err != nil {
			log.Fatal(err)
		}
		nbProfile += 1

		var t = lib.NewTimeFromString("Jan 02 2006 15:04:05", nc.Extras_s[fmt.Sprintf("Starttime:%d", int(Profile))])
		v := t.Time2JulianDec()
		nc.Variables_1D["TIME"] = append(nc.Variables_1D["TIME"].([]float64), v)

		if v, err := lib.Position2Decimal(nc.Extras_s[fmt.Sprintf("Startlongpos:%d", int(Profile))]); err == nil {
			nc.Variables_1D["LONGITUDE"] = append(nc.Variables_1D["LONGITUDE"].([]float64), v)
		}
		if v, err := lib.Position2Decimal(nc.Extras_s[fmt.Sprintf("Startlatpos:%d", int(Profile))]); err == nil {
			nc.Variables_1D["LATITUDE"] = append(nc.Variables_1D["LATITUDE"].([]float64), v)
		}
	}

}
// extract data from the line read in str with order gave by hash map_var
// values:  1318 81.583900 3.000 2.983 29.5431 29.5464 5 ...
// map_var: PRES:2 DEPTH:3 PSAL:21 DOX2:18 ...
func DecodeData(nc *lib.Nc, m *config.Map, str string, profile float64, file string, line int) {

	var timestop string
	var Poslatstop string
	var Poslongstop string

	// split the string str using coma characters
	values := strings.Split(str, ",")
	nb_value := len(values)

	//extract time
	date := values[2]
	time := values[3]

	//extract pos
	lat_s := values[4]
	lat_deg := values[5]
	lat_min := values[6]
	long_s := values[7]
	long_deg := values[8]
	long_min := values[9]

	timestop = lib.ConvertDate(date + " " + time)
	Poslatstop = lat_deg + " " + lat_min + " " + lat_s
	Poslongstop = long_deg + " " + long_min + " " + long_s

	// for each physical parameter, extract its data from the rigth column
	// and save it in map data
	for key, column := range m.Map_var {

		if column > nb_value {
			log.Fatal(fmt.Sprintf("Error in func DecodeData() "+
				"configuration mismatch\nFound %d values, and we try to use column %d",
				nb_value, column))
		}

		if v, err := strconv.ParseFloat(values[column], 64); err == nil {
			m.Data[key] = v
		} else {
			log.Printf("Can't parse line: %d in file: %s\n", line, file)
			log.Fatal(err)
		}
	}
	if line == 0 {
		nc.Extras_s[fmt.Sprintf("Starttime:%d", int(profile))] = timestop
		nc.Extras_s[fmt.Sprintf("Startlatpos:%d", int(profile))] = Poslatstop
		nc.Extras_s[fmt.Sprintf("Startlongpos:%d", int(profile))] = Poslongstop
	}

	m.Data["PRFL"] = profile
	if v, err := lib.Position2Decimal(Poslatstop); err == nil {
		m.Data["LAT"] = v
	}
	if v, err := lib.Position2Decimal(Poslongstop); err == nil {
		m.Data["LONG"] = v
	}

	nc.Extras_s[fmt.Sprintf("Stopttime:%d", int(profile))] = timestop
	nc.Extras_s[fmt.Sprintf("Stoplatpos:%d", int(profile))] = Poslatstop
	nc.Extras_s[fmt.Sprintf("Stoplongpos:%d", int(profile))] = Poslongstop
}
func WriteAscii(nc *lib.Nc, cfg toml.Configtoml, map_format map[string]string, hdr []string, inst string, prefixAll string) {
	// define 2 files, profiles header and data
	var asciiFilename string
	var lat2 string
	var latdecimal float64
	var longdecimal float64
	var long2 string

	// build filenames
	str := nc.Attributes["cycle_mesure"]
	str = strings.Replace(str, "\r", "", -1)
	headerFilename := fmt.Sprintf(cfg.Outputfile+"%s."+inst, strings.ToLower(str))
	asciiFilename = fmt.Sprintf(cfg.Outputfile+"%s%s_"+inst, strings.ToLower(str), prefixAll)
	//fmt.Println(headerFilename)
	//fmt.Println(asciiFilename)

	// open header file for writing result
	fid_hdr, err := os.Create(headerFilename)
	if err != nil {
		log.Fatal(err)
	}
	defer fid_hdr.Close()

	// use buffered mode for writing
	fbuf_hdr := bufio.NewWriter(fid_hdr)

	// open ASCII file for writing result
	fid_ascii, err := os.Create(asciiFilename)
	if err != nil {
		log.Fatal(err)
	}
	defer fid_ascii.Close()

	// use buffered mode for writing
	fbuf_ascii := bufio.NewWriter(fid_ascii)

	// write header to string
	str = fmt.Sprintf("%s  %s  %s  %s %s  %s\n",
		nc.Attributes["cycle_mesure"],
		nc.Attributes["plateforme"],
		nc.Attributes["institute"],
		nc.Attributes["type_instrument"],
		nc.Attributes["instrument_number"],
		nc.Attributes["pi"])

	// write first line header on header file and ascii file
	fmt.Fprintf(fbuf_hdr, str)
	fmt.Fprintf(fbuf_ascii, str)

	// display on screen
	fmt.Printf("%s", str)

	// write physical parameters in second line
	str = ""
	for _, key := range hdr {
		fmt.Fprintf(fbuf_ascii, "%s   ", key)
		fmt.Fprintf(lib.Debug, "%s   ", key)
	}
	// append new line
	//fmt.Fprintln(fbuf_ascii, "\n")

	// write second line header on ascii file
	fmt.Fprintln(fbuf_ascii, str)

	// display on screen
	fmt.Printf("%s", str)

	// get data (slices) from nc struct
	len_1D := nc.Dimensions["TIME"]
	len_2D := nc.Dimensions["DEPTH"]
	time := nc.Variables_1D["TIME"].([]float64)
	lat := nc.Variables_1D["LATITUDE"].([]float64)
	lon := nc.Variables_1D["LONGITUDE"].([]float64)
	profile := nc.Variables_1D["PROFILE"].([]float64)

	// loop over each profile
	for x := 0; x < len_1D; x++ {
		str = ""
		// write profile informations to ASCII data file with DEPTH = -1
		t1 := lib.NewTimeFromJulian(time[x])
		var t = lib.NewTimeFromString("Jan 02 2006 15:04:05", nc.Extras_s[fmt.Sprintf("Stopttime:%d", int(profile[x]))])
		t2 := lib.NewTimeFromJulian(t.Time2JulianDec())
		// TODOS: adapt profile format to stationPrefixLength
		fmt.Fprintf(fbuf_ascii, "%05.0f %4d %f %f %f %s",
			profile[x],
			codeForProfile,
			t1.JulianDayOfYear(),
			lat[x],
			lon[x],
			t1.Format("20060102150405"))

		if longdecimal, err := lib.Position2Decimal(nc.Extras_s[fmt.Sprintf("Stoplongpos:%d", int(profile[x]))]); err == nil {
			long2 = lib.DecimalPosition2String(longdecimal, 0)
		}
		if latdecimal, err := lib.Position2Decimal(nc.Extras_s[fmt.Sprintf("Stoplatpos:%d", int(profile[x]))]); err == nil {
			lat2 = lib.DecimalPosition2String(latdecimal, 0)
		}

		// write profile informations to header file
		str = fmt.Sprintf("%05.0f %s %s %s %s %s %s %s %s\n",
			profile[x],
			t1.Format("02/01/2006 15:04:05"),
			t2.Format("02/01/2006 15:04:05"),
			lib.DecimalPosition2String(lat[x], 0),
			lib.DecimalPosition2String(lon[x], 0),
			lat2,
			long2,
			nc.Extras_s[fmt.Sprintf("TYPECAST:%s", int(profile[x]))],
			nc.Extras_s[fmt.Sprintf("PRFL_NAME:%d", int(profile[x]))]+cfg.Thermo.CruisePrefix)

		// write profile information to header file
		fmt.Fprintf(fbuf_hdr, str)

		// display on screen
		fmt.Printf("%s", str)

		// fill last header columns with 1e36
		for i := 0; i < len(hdr)-6; i++ {
			fmt.Fprintf(fbuf_ascii, " %g", 1e36)
		}
		fmt.Fprintln(fbuf_ascii) // add newline

		// loop over each level
		for y := 0; y < len_2D; y++ {
			// goto next profile when max depth reach
			if lib.GetData(nc.Variables_2D["LAT"])[x][y] ==
				latdecimal && lib.GetData(nc.Variables_2D["LONG"])[x][y] == longdecimal {
				continue
			}
			fmt.Fprintf(fbuf_ascii, "%05.0f ", profile[x])
			// loop over each physical parameter (key) in the rigth order
			for _, key := range hdr {
				// if key not in map, goto next key
				if _, ok := nc.Variables_2D[key]; ok {
					// fill 2D slice
					data := lib.GetData(nc.Variables_2D[key])[x][y]
					// print data with it's format, change format for FillValue
					if data == 1e36 {
						fmt.Fprintf(fbuf_ascii, "%g ", data)
					} else {
						if strings.ContainsAny(map_format[key], "lf") {
							res := strings.Split(map_format[key], "l")
							map_format[key] = strings.Join(res, "")
						}
						fmt.Fprintf(fbuf_ascii, map_format[key], data)
					}
				}
			}
			fmt.Fprintf(fbuf_ascii, "\n")

		}
		fbuf_ascii.Flush()
		fbuf_hdr.Flush()
	}
}
func DecodeHeader(nc *lib.Nc, cfg toml.Configtoml, str string, profile float64, optDebug *bool) {

	regCruise := regexp.MustCompile(cfg.Seabird.Cruise)
	regShip := regexp.MustCompile(cfg.Seabird.Ship)
	regStation := regexp.MustCompile(cfg.Seabird.Station)
	regType := regexp.MustCompile(cfg.Seabird.Type)
	regOperator := regexp.MustCompile(cfg.Seabird.Operator)
	regBottomDepth := regexp.MustCompile(cfg.Seabird.BottomDepth)
	regDummyBottomDepth := regexp.MustCompile(cfg.Seabird.DummyBottomDepth)
	regSystemTime := regexp.MustCompile(cfg.Seabird.SystemTime)
	regNmeaLatitude := regexp.MustCompile(cfg.Seabird.Latitude)
	regNmeaLongitude := regexp.MustCompile(cfg.Seabird.Longitude)

	switch {
	// decode Systeme Upload Time
	case regSystemTime.MatchString(str):
		res := regSystemTime.FindStringSubmatch(str)
		value := res[1]
		fmt.Fprintf(lib.Debug, "%s -> ", value)
		// create new Time object, see tools.go
		var t = lib.NewTimeFromString("Jan 02 2006 15:04:05", value)
		v := t.Time2JulianDec()
		nc.Variables_1D["TIME"] = append(nc.Variables_1D["TIME"].([]float64), v)

	case regNmeaLatitude.MatchString(str):
		if v, err := lib.Position2Decimal(str); err == nil {
			nc.Variables_1D["LATITUDE"] = append(nc.Variables_1D["LATITUDE"].([]float64), v)
		} else {
			nc.Variables_1D["LATITUDE"] = append(nc.Variables_1D["LATITUDE"].([]float64), 1e36)
		}

	case regNmeaLongitude.MatchString(str):
		if v, err := lib.Position2Decimal(str); err == nil {
			nc.Variables_1D["LONGITUDE"] = append(nc.Variables_1D["LONGITUDE"].([]float64), v)
		} else {
			nc.Variables_1D["LONGITUDE"] = append(nc.Variables_1D["LONGITUDE"].([]float64), 1e36)
		}

	case regCruise.MatchString(str):
		res := regCruise.FindStringSubmatch(str)
		value := res[1]
		fmt.Fprintln(lib.Debug, value)
		nc.Attributes["cycle_mesure"] = value

	case regShip.MatchString(str):
		res := regShip.FindStringSubmatch(str)
		value := res[1]
		fmt.Fprintln(lib.Debug, value)
		nc.Attributes["plateforme"] = value

	case regStation.MatchString(str):
		res := regStation.FindStringSubmatch(str)
		value := res[1]
		if v, err := strconv.ParseFloat(value, 64); err == nil {
			fmt.Fprintln(lib.Debug, v)
			// ch
			//			format := "%0" + cfg.Ctd.StationPrefixLength + ".0f"
			//			p := fmt.Sprintf(format, profile)
			//			//s := fmt.Sprintf(format, v)
			//			fmt.Println(p, v)
			//			if p != v {
			//				fmt.Printf("Warning: profile for header differ from file name: %s <=> %s\n", p, v)
			//			}
			nc.Variables_1D["PROFILE"] = append(nc.Variables_1D["PROFILE"].([]float64), profile)
		} else {
			nc.Variables_1D["PROFILE"] = append(nc.Variables_1D["PROFILE"].([]float64), 1e36)
		}
		fmt.Println(value)

	case regBottomDepth.MatchString(str):
		res := regBottomDepth.FindStringSubmatch(str)
		value := res[1]
		if v, err := strconv.ParseFloat(value, 64); err == nil {
			fmt.Fprintf(lib.Debug, "Bath: %f\n", v)
			nc.Variables_1D["BATH"] = append(nc.Variables_1D["BATH"].([]float64), v)
		} else {
			fmt.Fprintf(lib.Debug, "Bath: %f\n", v)
			nc.Variables_1D["BATH"] = append(nc.Variables_1D["BATH"].([]float64), 1e36)
		}

	case regDummyBottomDepth.MatchString(str): //?
		nc.Variables_1D["BATH"] = append(nc.Variables_1D["BATH"].([]float64), 1e36)
		fmt.Fprintf(lib.Debug, "Bath: %g\n", 1e36)
		fmt.Println("1e36")

	case regOperator.MatchString(str):
		res := regOperator.FindStringSubmatch(str)
		value := res[1]
		nc.Attributes["operator"] = value

		// TODOS: uncomment, add optionnal value from seabird header

	case regType.MatchString(str):
		res := regType.FindStringSubmatch(str)
		value := strings.ToUpper(res[1]) // convert to upper case
		var v float64
		switch value {
		case "PHY":
			v = float64(lib.PHY)
		case "GEO":
			v = float64(lib.GEO)
		case "BIO":
			v = float64(lib.BIO)
		default:
			v = float64(lib.UNKNOW)
		}
		nc.Variables_1D["TYPECAST"] = append(nc.Variables_1D["TYPECAST"].([]float64), v)

		nc.Extras_s[fmt.Sprintf("TYPECAST:%s", int(profile))] = value

	}
}